Expose TCP socket options (#610)

This is done by exposing the options provided by net2 directly instead of implementing `TcpStreamExt`. Read & write timeout accessors are omitted given that the sockets are assumed to be in non-blocking mode. These accessors can be added later if they are needed.
diff --git a/src/net/tcp.rs b/src/net/tcp.rs
index f0aba98..936570f 100644
--- a/src/net/tcp.rs
+++ b/src/net/tcp.rs
@@ -10,6 +10,7 @@
 
 use std::io::{Read, Write};
 use std::net::{self, SocketAddr, SocketAddrV4, SocketAddrV6, Ipv4Addr, Ipv6Addr};
+use std::time::Duration;
 
 use net2::TcpBuilder;
 use iovec::IoVec;
@@ -179,6 +180,41 @@
         self.sys.nodelay()
     }
 
+    /// Sets the value of the `SO_RCVBUF` option on this socket.
+    ///
+    /// Changes the size of the operating system's receive buffer associated
+    /// with the socket.
+    pub fn set_recv_buffer_size(&self, size: usize) -> io::Result<()> {
+        self.sys.set_recv_buffer_size(size)
+    }
+
+    /// Gets the value of the `SO_RCVBUF` option on this socket.
+    ///
+    /// For more information about this option, see
+    /// [`set_recv_buffer_size`][link].
+    ///
+    /// [link]: #tymethod.set_recv_buffer_size
+    pub fn recv_buffer_size(&self) -> io::Result<usize> {
+        self.sys.recv_buffer_size()
+    }
+
+    /// Sets the value of the `SO_SNDBUF` option on this socket.
+    ///
+    /// Changes the size of the operating system's send buffer associated with
+    /// the socket.
+    pub fn set_send_buffer_size(&self, size: usize) -> io::Result<()> {
+        self.sys.set_send_buffer_size(size)
+    }
+
+    /// Gets the value of the `SO_SNDBUF` option on this socket.
+    ///
+    /// For more information about this option, see [`set_send_buffer`][link].
+    ///
+    /// [link]: #tymethod.set_send_buffer
+    pub fn send_buffer_size(&self) -> io::Result<usize> {
+        self.sys.send_buffer_size()
+    }
+
     /// Sets whether keepalive messages are enabled to be sent on this socket.
     ///
     /// On Unix, this option will set the `SO_KEEPALIVE` as well as the
@@ -186,23 +222,23 @@
     /// On Windows, this will set the `SIO_KEEPALIVE_VALS` option.
     ///
     /// If `None` is specified then keepalive messages are disabled, otherwise
-    /// the number of milliseconds specified will be the time to remain idle
-    /// before sending a TCP keepalive probe.
+    /// the duration specified will be the time to remain idle before sending a
+    /// TCP keepalive probe.
     ///
-    /// Some platforms specify this value in seconds, so sub-second millisecond
+    /// Some platforms specify this value in seconds, so sub-second
     /// specifications may be omitted.
-    pub fn set_keepalive_ms(&self, keepalive: Option<u32>) -> io::Result<()> {
-        self.sys.set_keepalive_ms(keepalive)
+    pub fn set_keepalive(&self, keepalive: Option<Duration>) -> io::Result<()> {
+        self.sys.set_keepalive(keepalive)
     }
 
     /// Returns whether keepalive messages are enabled on this socket, and if so
-    /// the amount of milliseconds between them.
+    /// the duration of time between them.
     ///
-    /// For more information about this option, see [`set_keepalive_ms`][link].
+    /// For more information about this option, see [`set_keepalive`][link].
     ///
-    /// [link]: #method.set_keepalive_ms
-    pub fn keepalive_ms(&self) -> io::Result<Option<u32>> {
-        self.sys.keepalive_ms()
+    /// [link]: #tymethod.set_keepalive
+    pub fn keepalive(&self) -> io::Result<Option<Duration>> {
+        self.sys.keepalive()
     }
 
     /// Sets the value for the `IP_TTL` option on this socket.
@@ -217,11 +253,60 @@
     ///
     /// For more information about this option, see [`set_ttl`][link].
     ///
-    /// [link]: #method.set_ttl
+    /// [link]: #tymethod.set_ttl
     pub fn ttl(&self) -> io::Result<u32> {
         self.sys.ttl()
     }
 
+    /// Sets the value for the `IPV6_V6ONLY` option on this socket.
+    ///
+    /// If this is set to `true` then the socket is restricted to sending and
+    /// receiving IPv6 packets only. In this case two IPv4 and IPv6 applications
+    /// can bind the same port at the same time.
+    ///
+    /// If this is set to `false` then the socket can be used to send and
+    /// receive packets from an IPv4-mapped IPv6 address.
+    pub fn set_only_v6(&self, only_v6: bool) -> io::Result<()> {
+        self.sys.set_only_v6(only_v6)
+    }
+
+    /// Gets the value of the `IPV6_V6ONLY` option for this socket.
+    ///
+    /// For more information about this option, see [`set_only_v6`][link].
+    ///
+    /// [link]: #tymethod.set_only_v6
+    pub fn only_v6(&self) -> io::Result<bool> {
+        self.sys.only_v6()
+    }
+
+    /// Sets the linger duration of this socket by setting the SO_LINGER option
+    pub fn set_linger(&self, dur: Option<Duration>) -> io::Result<()> {
+        self.sys.set_linger(dur)
+    }
+
+    /// reads the linger duration for this socket by getting the SO_LINGER option
+    pub fn linger(&self) -> io::Result<Option<Duration>> {
+        self.sys.linger()
+    }
+
+    #[deprecated(since = "0.6.9", note = "use set_keepalive")]
+    #[cfg(feature = "with-deprecated")]
+    #[doc(hidden)]
+    pub fn set_keepalive_ms(&self, keepalive: Option<u32>) -> io::Result<()> {
+        self.set_keepalive(keepalive.map(|v| Duration::from_millis(v as u64)))
+    }
+
+    #[deprecated(since = "0.6.9", note = "use keepalive")]
+    #[cfg(feature = "with-deprecated")]
+    #[doc(hidden)]
+    pub fn keepalive_ms(&self) -> io::Result<Option<u32>> {
+        self.keepalive().map(|v| {
+            v.map(|v| {
+                ::convert::millis(v) as u32
+            })
+        })
+    }
+
     /// Get the value of the `SO_ERROR` option on this socket.
     ///
     /// This will retrieve the stored error in the underlying socket, clearing
diff --git a/src/sys/unix/tcp.rs b/src/sys/unix/tcp.rs
index 7512e51..365214f 100644
--- a/src/sys/unix/tcp.rs
+++ b/src/sys/unix/tcp.rs
@@ -2,6 +2,7 @@
 use std::io::{Read, Write};
 use std::net::{self, SocketAddr};
 use std::os::unix::io::{RawFd, FromRawFd, IntoRawFd, AsRawFd};
+use std::time::Duration;
 
 use libc;
 use net2::TcpStreamExt;
@@ -73,12 +74,28 @@
         self.inner.nodelay()
     }
 
-    pub fn set_keepalive_ms(&self, millis: Option<u32>) -> io::Result<()> {
-        self.inner.set_keepalive_ms(millis)
+    pub fn set_recv_buffer_size(&self, size: usize) -> io::Result<()> {
+        self.inner.set_recv_buffer_size(size)
     }
 
-    pub fn keepalive_ms(&self) -> io::Result<Option<u32>> {
-        self.inner.keepalive_ms()
+    pub fn recv_buffer_size(&self) -> io::Result<usize> {
+        self.inner.recv_buffer_size()
+    }
+
+    pub fn set_send_buffer_size(&self, size: usize) -> io::Result<()> {
+        self.inner.set_send_buffer_size(size)
+    }
+
+    pub fn send_buffer_size(&self) -> io::Result<usize> {
+        self.inner.send_buffer_size()
+    }
+
+    pub fn set_keepalive(&self, keepalive: Option<Duration>) -> io::Result<()> {
+        self.inner.set_keepalive(keepalive)
+    }
+
+    pub fn keepalive(&self) -> io::Result<Option<Duration>> {
+        self.inner.keepalive()
     }
 
     pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
@@ -89,6 +106,22 @@
         self.inner.ttl()
     }
 
+    pub fn set_only_v6(&self, only_v6: bool) -> io::Result<()> {
+        self.inner.set_only_v6(only_v6)
+    }
+
+    pub fn only_v6(&self) -> io::Result<bool> {
+        self.inner.only_v6()
+    }
+
+    pub fn set_linger(&self, dur: Option<Duration>) -> io::Result<()> {
+        self.inner.set_linger(dur)
+    }
+
+    pub fn linger(&self) -> io::Result<Option<Duration>> {
+        self.inner.linger()
+    }
+
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
         self.inner.take_error()
     }
diff --git a/src/sys/windows/tcp.rs b/src/sys/windows/tcp.rs
index 074ddcb..8f490d1 100644
--- a/src/sys/windows/tcp.rs
+++ b/src/sys/windows/tcp.rs
@@ -4,6 +4,7 @@
 use std::net::{self, SocketAddr, Shutdown};
 use std::os::windows::prelude::*;
 use std::sync::{Mutex, MutexGuard};
+use std::time::Duration;
 
 use miow::iocp::CompletionStatus;
 use miow::net::*;
@@ -146,12 +147,28 @@
         self.imp.inner.socket.nodelay()
     }
 
-    pub fn set_keepalive_ms(&self, millis: Option<u32>) -> io::Result<()> {
-        self.imp.inner.socket.set_keepalive_ms(millis)
+    pub fn set_recv_buffer_size(&self, size: usize) -> io::Result<()> {
+        self.imp.inner.socket.set_recv_buffer_size(size)
     }
 
-    pub fn keepalive_ms(&self) -> io::Result<Option<u32>> {
-        self.imp.inner.socket.keepalive_ms()
+    pub fn recv_buffer_size(&self) -> io::Result<usize> {
+        self.imp.inner.socket.recv_buffer_size()
+    }
+
+    pub fn set_send_buffer_size(&self, size: usize) -> io::Result<()> {
+        self.imp.inner.socket.set_send_buffer_size(size)
+    }
+
+    pub fn send_buffer_size(&self) -> io::Result<usize> {
+        self.imp.inner.socket.send_buffer_size()
+    }
+
+    pub fn set_keepalive(&self, keepalive: Option<Duration>) -> io::Result<()> {
+        self.imp.inner.socket.set_keepalive(keepalive)
+    }
+
+    pub fn keepalive(&self) -> io::Result<Option<Duration>> {
+        self.imp.inner.socket.keepalive()
     }
 
     pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
@@ -162,6 +179,22 @@
         self.imp.inner.socket.ttl()
     }
 
+    pub fn set_only_v6(&self, only_v6: bool) -> io::Result<()> {
+        self.imp.inner.socket.set_only_v6(only_v6)
+    }
+
+    pub fn only_v6(&self) -> io::Result<bool> {
+        self.imp.inner.socket.only_v6()
+    }
+
+    pub fn set_linger(&self, dur: Option<Duration>) -> io::Result<()> {
+        self.imp.inner.socket.set_linger(dur)
+    }
+
+    pub fn linger(&self) -> io::Result<Option<Duration>> {
+        self.imp.inner.socket.linger()
+    }
+
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
         if let Some(e) = try!(self.imp.inner.socket.take_error()) {
             return Ok(Some(e))