瀏覽代碼

Implement the userspace side of TCP sockets.

whitequark 8 年之前
父節點
當前提交
a8d19a1da4
共有 4 個文件被更改,包括 81 次插入14 次删除
  1. 2 1
      README.md
  2. 21 8
      examples/smoltcpserver.rs
  3. 53 0
      src/socket/tcp.rs
  4. 5 5
      src/socket/udp.rs

+ 2 - 1
README.md

@@ -106,7 +106,8 @@ cargo run --example smoltcpserver -- tap0
 It responds to:
 It responds to:
 
 
   * pings (`ping 192.168.69.1`),
   * pings (`ping 192.168.69.1`),
-  * UDP packets on port 6969 (`socat stdio udp4-connect:192.168.69.1:6969 <<<"abcdefg"`).
+  * UDP packets on port 6969 (`socat stdio udp4-connect:192.168.69.1:6969 <<<"abcdefg"`),
+  * TCP packets on port 6969 (`socat stdio tcp4-connect:192.168.69.1:6969 <<<"abcdefg"`),
 
 
 License
 License
 -------
 -------

+ 21 - 8
examples/smoltcpserver.rs

@@ -56,29 +56,42 @@ fn main() {
     loop {
     loop {
         match iface.poll() {
         match iface.poll() {
             Ok(()) => (),
             Ok(()) => (),
-            Err(e) => debug!("error {}", e)
+            Err(e) => debug!("poll error: {}", e)
         }
         }
 
 
         {
         {
-            let udp_socket: &mut UdpSocket = iface.sockets()[0].as_socket();
-            let udp_client = match udp_socket.recv() {
+            let socket: &mut UdpSocket = iface.sockets()[0].as_socket();
+            let client = match socket.recv() {
                 Ok((endpoint, data)) => {
                 Ok((endpoint, data)) => {
-                    debug!("data {:?} from {}", data, endpoint);
+                    debug!("udp recv data: {:?} from {}", data, endpoint);
                     Some(endpoint)
                     Some(endpoint)
                 }
                 }
                 Err(Error::Exhausted) => {
                 Err(Error::Exhausted) => {
                     None
                     None
                 }
                 }
                 Err(e) => {
                 Err(e) => {
-                    debug!("error {}", e);
+                    debug!("udp recv error: {}", e);
                     None
                     None
                 }
                 }
             };
             };
-            if let Some(endpoint) = udp_client {
-                udp_socket.send_slice(endpoint, "hihihi".as_bytes()).unwrap()
+            if let Some(endpoint) = client {
+                socket.send_slice(endpoint, b"yo dawg").unwrap()
             }
             }
         }
         }
 
 
-        let _tcp_socket: &mut TcpSocket = iface.sockets()[1].as_socket();
+        {
+            let socket: &mut TcpSocket = iface.sockets()[1].as_socket();
+            let data = {
+                let mut data = socket.recv(128).to_owned();
+                if data.len() > 0 {
+                    debug!("tcp recv data: {:?}", &data[..]);
+                    data = data.split(|&b| b == b'\n').next().unwrap().to_owned();
+                    data.reverse();
+                    data.extend(b"\n");
+                }
+                data
+            };
+            socket.send_slice(data.as_ref());
+        }
     }
     }
 }
 }

+ 53 - 0
src/socket/tcp.rs

@@ -244,6 +244,59 @@ impl<'a> TcpSocket<'a> {
         self.set_state(State::Listen);
         self.set_state(State::Listen);
     }
     }
 
 
+    /// Enqueue a sequence of octets to be sent, and return a pointer to it.
+    ///
+    /// This function may return a slice smaller than the requested size in case
+    /// there is not enough contiguous free space in the transmit buffer, down to
+    /// an empty slice.
+    pub fn send(&mut self, size: usize) -> &mut [u8] {
+        let buffer = self.tx_buffer.enqueue(size);
+        if buffer.len() > 0 {
+            net_trace!("tcp:{}:{}: buffer to send {} octets",
+                       self.local_endpoint, self.remote_endpoint, buffer.len());
+        }
+        buffer
+    }
+
+    /// Enqueue a sequence of octets to be sent, and fill it from a slice.
+    ///
+    /// This function returns the amount of bytes actually enqueued, which is limited
+    /// by the amount of free space in the transmit buffer; down to zero.
+    ///
+    /// See also [send](#method.send).
+    pub fn send_slice(&mut self, data: &[u8]) -> usize {
+        let buffer = self.send(data.len());
+        buffer.copy_from_slice(data);
+        buffer.len()
+    }
+
+    /// Dequeue a sequence of received octets, and return a pointer to it.
+    ///
+    /// This function may return a slice smaller than the requested size in case
+    /// there are not enough octets queued in the receive buffer, down to
+    /// an empty slice.
+    pub fn recv(&mut self, size: usize) -> &[u8] {
+        let buffer = self.rx_buffer.dequeue(size);
+        self.remote_seq_no += buffer.len() as i32;
+        if buffer.len() > 0 {
+            net_trace!("tcp:{}:{}: receive {} buffered octets",
+                       self.local_endpoint, self.remote_endpoint, buffer.len());
+        }
+        buffer
+    }
+
+    /// Dequeue a sequence of received octets, and fill a slice from it.
+    ///
+    /// This function returns the amount of bytes actually dequeued, which is limited
+    /// by the amount of free space in the transmit buffer; down to zero.
+    ///
+    /// See also [recv](#method.recv).
+    pub fn recv_slice(&mut self, data: &mut [u8]) -> usize {
+        let buffer = self.recv(data.len());
+        data[..buffer.len()].copy_from_slice(buffer);
+        buffer.len()
+    }
+
     /// See [Socket::collect](enum.Socket.html#method.collect).
     /// See [Socket::collect](enum.Socket.html#method.collect).
     pub fn collect(&mut self, ip_repr: &IpRepr, payload: &[u8]) -> Result<(), Error> {
     pub fn collect(&mut self, ip_repr: &IpRepr, payload: &[u8]) -> Result<(), Error> {
         if ip_repr.protocol() != IpProtocol::Tcp { return Err(Error::Rejected) }
         if ip_repr.protocol() != IpProtocol::Tcp { return Err(Error::Rejected) }

+ 5 - 5
src/socket/udp.rs

@@ -131,12 +131,12 @@ impl<'a, 'b> UdpSocket<'a, 'b> {
         let packet_buf = try!(self.tx_buffer.enqueue());
         let packet_buf = try!(self.tx_buffer.enqueue());
         packet_buf.endpoint = endpoint;
         packet_buf.endpoint = endpoint;
         packet_buf.size = size;
         packet_buf.size = size;
-        net_trace!("udp:{}:{}: send {} octets",
+        net_trace!("udp:{}:{}: buffer to send {} octets",
                    self.endpoint, packet_buf.endpoint, packet_buf.size);
                    self.endpoint, packet_buf.endpoint, packet_buf.size);
         Ok(&mut packet_buf.as_mut()[..size])
         Ok(&mut packet_buf.as_mut()[..size])
     }
     }
 
 
-    /// Enqueue a packete to be sent to a given remote endpoint, and fill it from a slice.
+    /// Enqueue a packet to be sent to a given remote endpoint, and fill it from a slice.
     ///
     ///
     /// See also [send](#method.send).
     /// See also [send](#method.send).
     pub fn send_slice(&mut self, endpoint: IpEndpoint, data: &[u8]) -> Result<(), Error> {
     pub fn send_slice(&mut self, endpoint: IpEndpoint, data: &[u8]) -> Result<(), Error> {
@@ -150,7 +150,7 @@ impl<'a, 'b> UdpSocket<'a, 'b> {
     /// This function returns `Err(Error::Exhausted)` if the receive buffer is empty.
     /// This function returns `Err(Error::Exhausted)` if the receive buffer is empty.
     pub fn recv(&mut self) -> Result<(IpEndpoint, &[u8]), Error> {
     pub fn recv(&mut self) -> Result<(IpEndpoint, &[u8]), Error> {
         let packet_buf = try!(self.rx_buffer.dequeue());
         let packet_buf = try!(self.rx_buffer.dequeue());
-        net_trace!("udp:{}:{}: recv {} octets",
+        net_trace!("udp:{}:{}: receive {} buffered octets",
                    self.endpoint, packet_buf.endpoint, packet_buf.size);
                    self.endpoint, packet_buf.endpoint, packet_buf.size);
         Ok((packet_buf.endpoint, &packet_buf.as_ref()[..packet_buf.size]))
         Ok((packet_buf.endpoint, &packet_buf.as_ref()[..packet_buf.size]))
     }
     }
@@ -183,7 +183,7 @@ impl<'a, 'b> UdpSocket<'a, 'b> {
         packet_buf.endpoint = IpEndpoint { addr: ip_repr.src_addr(), port: repr.src_port };
         packet_buf.endpoint = IpEndpoint { addr: ip_repr.src_addr(), port: repr.src_port };
         packet_buf.size = repr.payload.len();
         packet_buf.size = repr.payload.len();
         packet_buf.as_mut()[..repr.payload.len()].copy_from_slice(repr.payload);
         packet_buf.as_mut()[..repr.payload.len()].copy_from_slice(repr.payload);
-        net_trace!("udp:{}:{}: collect {} octets",
+        net_trace!("udp:{}:{}: receiving {} octets",
                    self.endpoint, packet_buf.endpoint, packet_buf.size);
                    self.endpoint, packet_buf.endpoint, packet_buf.size);
         Ok(())
         Ok(())
     }
     }
@@ -192,7 +192,7 @@ impl<'a, 'b> UdpSocket<'a, 'b> {
     pub fn dispatch<F, R>(&mut self, emit: &mut F) -> Result<R, Error>
     pub fn dispatch<F, R>(&mut self, emit: &mut F) -> Result<R, Error>
             where F: FnMut(&IpRepr, &IpPayload) -> Result<R, Error> {
             where F: FnMut(&IpRepr, &IpPayload) -> Result<R, Error> {
         let packet_buf = try!(self.tx_buffer.dequeue());
         let packet_buf = try!(self.tx_buffer.dequeue());
-        net_trace!("udp:{}:{}: dispatch {} octets",
+        net_trace!("udp:{}:{}: sending {} octets",
                    self.endpoint, packet_buf.endpoint, packet_buf.size);
                    self.endpoint, packet_buf.endpoint, packet_buf.size);
         let ip_repr = IpRepr::Unspecified {
         let ip_repr = IpRepr::Unspecified {
             src_addr: self.endpoint.addr,
             src_addr: self.endpoint.addr,