Distinguish sockets by debug identifiers (socket set indexes).
This commit is contained in:
parent
40716a348d
commit
f126eab193
|
@ -49,7 +49,30 @@ pub enum Socket<'a, 'b: 'a> {
|
||||||
__Nonexhaustive
|
__Nonexhaustive
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! dispatch_socket {
|
||||||
|
($self_:expr, |$socket:ident [$( $mut_:tt )*]| $code:expr) => ({
|
||||||
|
match $self_ {
|
||||||
|
&$( $mut_ )* Socket::Udp(ref $( $mut_ )* $socket) => $code,
|
||||||
|
&$( $mut_ )* Socket::Tcp(ref $( $mut_ )* $socket) => $code,
|
||||||
|
&$( $mut_ )* Socket::__Nonexhaustive => unreachable!()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, 'b> Socket<'a, 'b> {
|
impl<'a, 'b> Socket<'a, 'b> {
|
||||||
|
/// Return the debug identifier.
|
||||||
|
pub fn debug_id(&self) -> usize {
|
||||||
|
dispatch_socket!(self, |socket []| socket.debug_id())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the debug identifier.
|
||||||
|
///
|
||||||
|
/// The debug identifier is a number printed in socket trace messages.
|
||||||
|
/// It could as well be used by the user code.
|
||||||
|
pub fn set_debug_id(&mut self, id: usize) {
|
||||||
|
dispatch_socket!(self, |socket [mut]| socket.set_debug_id(id))
|
||||||
|
}
|
||||||
|
|
||||||
/// Process a packet received from a network interface.
|
/// Process a packet received from a network interface.
|
||||||
///
|
///
|
||||||
/// This function checks if the packet contained in the payload matches the socket endpoint,
|
/// This function checks if the packet contained in the payload matches the socket endpoint,
|
||||||
|
@ -59,13 +82,7 @@ impl<'a, 'b> Socket<'a, 'b> {
|
||||||
/// This function is used internally by the networking stack.
|
/// This function is used internally by the networking stack.
|
||||||
pub fn process(&mut self, timestamp: u64, ip_repr: &IpRepr,
|
pub fn process(&mut self, timestamp: u64, ip_repr: &IpRepr,
|
||||||
payload: &[u8]) -> Result<(), Error> {
|
payload: &[u8]) -> Result<(), Error> {
|
||||||
match self {
|
dispatch_socket!(self, |socket [mut]| socket.process(timestamp, ip_repr, payload))
|
||||||
&mut Socket::Udp(ref mut socket) =>
|
|
||||||
socket.process(timestamp, ip_repr, payload),
|
|
||||||
&mut Socket::Tcp(ref mut socket) =>
|
|
||||||
socket.process(timestamp, ip_repr, payload),
|
|
||||||
&mut Socket::__Nonexhaustive => unreachable!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prepare a packet to be transmitted to a network interface.
|
/// Prepare a packet to be transmitted to a network interface.
|
||||||
|
@ -77,13 +94,7 @@ impl<'a, 'b> Socket<'a, 'b> {
|
||||||
/// This function is used internally by the networking stack.
|
/// This function is used internally by the networking stack.
|
||||||
pub fn dispatch<F, R>(&mut self, timestamp: u64, emit: &mut F) -> Result<R, Error>
|
pub fn dispatch<F, R>(&mut self, timestamp: u64, emit: &mut F) -> Result<R, Error>
|
||||||
where F: FnMut(&IpRepr, &IpPayload) -> Result<R, Error> {
|
where F: FnMut(&IpRepr, &IpPayload) -> Result<R, Error> {
|
||||||
match self {
|
dispatch_socket!(self, |socket [mut]| socket.dispatch(timestamp, emit))
|
||||||
&mut Socket::Udp(ref mut socket) =>
|
|
||||||
socket.dispatch(timestamp, emit),
|
|
||||||
&mut Socket::Tcp(ref mut socket) =>
|
|
||||||
socket.dispatch(timestamp, emit),
|
|
||||||
&mut Socket::__Nonexhaustive => unreachable!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,9 +29,10 @@ impl<'a, 'b: 'a, 'c: 'a + 'b> Set<'a, 'b, 'c> {
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
/// This function panics if the storage is fixed-size (not a `Vec`) and is full.
|
/// This function panics if the storage is fixed-size (not a `Vec`) and is full.
|
||||||
pub fn add(&mut self, socket: Socket<'b, 'c>) -> Handle {
|
pub fn add(&mut self, mut socket: Socket<'b, 'c>) -> Handle {
|
||||||
for (index, slot) in self.sockets.iter_mut().enumerate() {
|
for (index, slot) in self.sockets.iter_mut().enumerate() {
|
||||||
if slot.is_none() {
|
if slot.is_none() {
|
||||||
|
socket.set_debug_id(index);
|
||||||
*slot = Some(socket);
|
*slot = Some(socket);
|
||||||
return Handle { index: index }
|
return Handle { index: index }
|
||||||
}
|
}
|
||||||
|
@ -42,8 +43,10 @@ impl<'a, 'b: 'a, 'c: 'a + 'b> Set<'a, 'b, 'c> {
|
||||||
panic!("adding a socket to a full SocketSet")
|
panic!("adding a socket to a full SocketSet")
|
||||||
}
|
}
|
||||||
ManagedSlice::Owned(ref mut sockets) => {
|
ManagedSlice::Owned(ref mut sockets) => {
|
||||||
|
let index = sockets.len();
|
||||||
|
socket.set_debug_id(index);
|
||||||
sockets.push(Some(socket));
|
sockets.push(Some(socket));
|
||||||
Handle { index: sockets.len() - 1 }
|
Handle { index: index }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -247,7 +247,8 @@ pub struct TcpSocket<'a> {
|
||||||
remote_win_len: usize,
|
remote_win_len: usize,
|
||||||
retransmit: Retransmit,
|
retransmit: Retransmit,
|
||||||
rx_buffer: SocketBuffer<'a>,
|
rx_buffer: SocketBuffer<'a>,
|
||||||
tx_buffer: SocketBuffer<'a>
|
tx_buffer: SocketBuffer<'a>,
|
||||||
|
debug_id: usize
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TcpSocket<'a> {
|
impl<'a> TcpSocket<'a> {
|
||||||
|
@ -272,10 +273,24 @@ impl<'a> TcpSocket<'a> {
|
||||||
remote_win_len: 0,
|
remote_win_len: 0,
|
||||||
retransmit: Retransmit::new(),
|
retransmit: Retransmit::new(),
|
||||||
tx_buffer: tx_buffer.into(),
|
tx_buffer: tx_buffer.into(),
|
||||||
rx_buffer: rx_buffer.into()
|
rx_buffer: rx_buffer.into(),
|
||||||
|
debug_id: 0
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return the debug identifier.
|
||||||
|
pub fn debug_id(&self) -> usize {
|
||||||
|
self.debug_id
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the debug identifier.
|
||||||
|
///
|
||||||
|
/// The debug identifier is a number printed in socket trace messages.
|
||||||
|
/// It could as well be used by the user code.
|
||||||
|
pub fn set_debug_id(&mut self, id: usize) {
|
||||||
|
self.debug_id = id
|
||||||
|
}
|
||||||
|
|
||||||
/// Return the local endpoint.
|
/// Return the local endpoint.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn local_endpoint(&self) -> IpEndpoint {
|
pub fn local_endpoint(&self) -> IpEndpoint {
|
||||||
|
@ -436,8 +451,8 @@ impl<'a> TcpSocket<'a> {
|
||||||
let old_length = self.tx_buffer.len();
|
let old_length = self.tx_buffer.len();
|
||||||
let buffer = self.tx_buffer.enqueue(size);
|
let buffer = self.tx_buffer.enqueue(size);
|
||||||
if buffer.len() > 0 {
|
if buffer.len() > 0 {
|
||||||
net_trace!("tcp:{}:{}: tx buffer: enqueueing {} octets (now {})",
|
net_trace!("[{}]{}:{}: tx buffer: enqueueing {} octets (now {})",
|
||||||
self.local_endpoint, self.remote_endpoint,
|
self.debug_id, self.local_endpoint, self.remote_endpoint,
|
||||||
buffer.len(), old_length + buffer.len());
|
buffer.len(), old_length + buffer.len());
|
||||||
self.retransmit.reset();
|
self.retransmit.reset();
|
||||||
}
|
}
|
||||||
|
@ -471,8 +486,8 @@ impl<'a> TcpSocket<'a> {
|
||||||
let buffer = self.rx_buffer.dequeue(size);
|
let buffer = self.rx_buffer.dequeue(size);
|
||||||
self.remote_seq_no += buffer.len();
|
self.remote_seq_no += buffer.len();
|
||||||
if buffer.len() > 0 {
|
if buffer.len() > 0 {
|
||||||
net_trace!("tcp:{}:{}: rx buffer: dequeueing {} octets (now {})",
|
net_trace!("[{}]{}:{}: rx buffer: dequeueing {} octets (now {})",
|
||||||
self.local_endpoint, self.remote_endpoint,
|
self.debug_id, self.local_endpoint, self.remote_endpoint,
|
||||||
buffer.len(), old_length - buffer.len());
|
buffer.len(), old_length - buffer.len());
|
||||||
}
|
}
|
||||||
Ok(buffer)
|
Ok(buffer)
|
||||||
|
@ -501,11 +516,13 @@ impl<'a> TcpSocket<'a> {
|
||||||
fn set_state(&mut self, state: State) {
|
fn set_state(&mut self, state: State) {
|
||||||
if self.state != state {
|
if self.state != state {
|
||||||
if self.remote_endpoint.addr.is_unspecified() {
|
if self.remote_endpoint.addr.is_unspecified() {
|
||||||
net_trace!("tcp:{}: state={}=>{}",
|
net_trace!("[{}]{}: state={}=>{}",
|
||||||
self.local_endpoint, self.state, state);
|
self.debug_id, self.local_endpoint,
|
||||||
|
self.state, state);
|
||||||
} else {
|
} else {
|
||||||
net_trace!("tcp:{}:{}: state={}=>{}",
|
net_trace!("[{}]{}:{}: state={}=>{}",
|
||||||
self.local_endpoint, self.remote_endpoint, self.state, state);
|
self.debug_id, self.local_endpoint, self.remote_endpoint,
|
||||||
|
self.state, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.state = state
|
self.state = state
|
||||||
|
@ -534,25 +551,25 @@ impl<'a> TcpSocket<'a> {
|
||||||
match (self.state, repr) {
|
match (self.state, repr) {
|
||||||
// The initial SYN (or whatever) cannot contain an acknowledgement.
|
// The initial SYN (or whatever) cannot contain an acknowledgement.
|
||||||
(State::Listen, TcpRepr { ack_number: Some(_), .. }) => {
|
(State::Listen, TcpRepr { ack_number: Some(_), .. }) => {
|
||||||
net_trace!("tcp:{}:{}: ACK received by a socket in LISTEN state",
|
net_trace!("[{}]{}:{}: ACK received by a socket in LISTEN state",
|
||||||
self.local_endpoint, self.remote_endpoint);
|
self.debug_id, self.local_endpoint, self.remote_endpoint);
|
||||||
return Err(Error::Malformed)
|
return Err(Error::Malformed)
|
||||||
}
|
}
|
||||||
(State::Listen, TcpRepr { ack_number: None, .. }) => (),
|
(State::Listen, TcpRepr { ack_number: None, .. }) => (),
|
||||||
// An RST received in response to initial SYN is acceptable if it acknowledges
|
// An RST received in response to initial SYN is acceptable if it acknowledges
|
||||||
// the initial SYN.
|
// the initial SYN.
|
||||||
(State::SynSent, TcpRepr { control: TcpControl::Rst, ack_number: None, .. }) => {
|
(State::SynSent, TcpRepr { control: TcpControl::Rst, ack_number: None, .. }) => {
|
||||||
net_trace!("tcp:{}:{}: unacceptable RST (expecting RST|ACK) \
|
net_trace!("[{}]{}:{}: unacceptable RST (expecting RST|ACK) \
|
||||||
in response to initial SYN",
|
in response to initial SYN",
|
||||||
self.local_endpoint, self.remote_endpoint);
|
self.debug_id, self.local_endpoint, self.remote_endpoint);
|
||||||
return Err(Error::Malformed)
|
return Err(Error::Malformed)
|
||||||
}
|
}
|
||||||
(State::SynSent, TcpRepr {
|
(State::SynSent, TcpRepr {
|
||||||
control: TcpControl::Rst, ack_number: Some(ack_number), ..
|
control: TcpControl::Rst, ack_number: Some(ack_number), ..
|
||||||
}) => {
|
}) => {
|
||||||
if ack_number != self.local_seq_no {
|
if ack_number != self.local_seq_no {
|
||||||
net_trace!("tcp:{}:{}: unacceptable RST|ACK in response to initial SYN",
|
net_trace!("[{}]{}:{}: unacceptable RST|ACK in response to initial SYN",
|
||||||
self.local_endpoint, self.remote_endpoint);
|
self.debug_id, self.local_endpoint, self.remote_endpoint);
|
||||||
return Err(Error::Malformed)
|
return Err(Error::Malformed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -560,8 +577,8 @@ impl<'a> TcpSocket<'a> {
|
||||||
(_, TcpRepr { control: TcpControl::Rst, .. }) => (),
|
(_, TcpRepr { control: TcpControl::Rst, .. }) => (),
|
||||||
// Every packet after the initial SYN must be an acknowledgement.
|
// Every packet after the initial SYN must be an acknowledgement.
|
||||||
(_, TcpRepr { ack_number: None, .. }) => {
|
(_, TcpRepr { ack_number: None, .. }) => {
|
||||||
net_trace!("tcp:{}:{}: expecting an ACK",
|
net_trace!("[{}]{}:{}: expecting an ACK",
|
||||||
self.local_endpoint, self.remote_endpoint);
|
self.debug_id, self.local_endpoint, self.remote_endpoint);
|
||||||
return Err(Error::Malformed)
|
return Err(Error::Malformed)
|
||||||
}
|
}
|
||||||
// Every acknowledgement must be for transmitted but unacknowledged data.
|
// Every acknowledgement must be for transmitted but unacknowledged data.
|
||||||
|
@ -578,8 +595,8 @@ impl<'a> TcpSocket<'a> {
|
||||||
let unacknowledged = self.tx_buffer.len() + control_len;
|
let unacknowledged = self.tx_buffer.len() + control_len;
|
||||||
if !(ack_number >= self.local_seq_no &&
|
if !(ack_number >= self.local_seq_no &&
|
||||||
ack_number <= (self.local_seq_no + unacknowledged)) {
|
ack_number <= (self.local_seq_no + unacknowledged)) {
|
||||||
net_trace!("tcp:{}:{}: unacceptable ACK ({} not in {}...{})",
|
net_trace!("[{}]{}:{}: unacceptable ACK ({} not in {}...{})",
|
||||||
self.local_endpoint, self.remote_endpoint,
|
self.debug_id, self.local_endpoint, self.remote_endpoint,
|
||||||
ack_number, self.local_seq_no, self.local_seq_no + unacknowledged);
|
ack_number, self.local_seq_no, self.local_seq_no + unacknowledged);
|
||||||
return Err(Error::Dropped)
|
return Err(Error::Dropped)
|
||||||
}
|
}
|
||||||
|
@ -595,13 +612,13 @@ impl<'a> TcpSocket<'a> {
|
||||||
(_, TcpRepr { seq_number, .. }) => {
|
(_, TcpRepr { seq_number, .. }) => {
|
||||||
let next_remote_seq = self.remote_seq_no + self.rx_buffer.len();
|
let next_remote_seq = self.remote_seq_no + self.rx_buffer.len();
|
||||||
if seq_number > next_remote_seq {
|
if seq_number > next_remote_seq {
|
||||||
net_trace!("tcp:{}:{}: unacceptable SEQ ({} not in {}..)",
|
net_trace!("[{}]{}:{}: unacceptable SEQ ({} not in {}..)",
|
||||||
self.local_endpoint, self.remote_endpoint,
|
self.debug_id, self.local_endpoint, self.remote_endpoint,
|
||||||
seq_number, next_remote_seq);
|
seq_number, next_remote_seq);
|
||||||
return Err(Error::Dropped)
|
return Err(Error::Dropped)
|
||||||
} else if seq_number != next_remote_seq {
|
} else if seq_number != next_remote_seq {
|
||||||
net_trace!("tcp:{}:{}: duplicate SEQ ({} in ..{})",
|
net_trace!("[{}]{}:{}: duplicate SEQ ({} in ..{})",
|
||||||
self.local_endpoint, self.remote_endpoint,
|
self.debug_id, self.local_endpoint, self.remote_endpoint,
|
||||||
seq_number, next_remote_seq);
|
seq_number, next_remote_seq);
|
||||||
// If we've seen this sequence number already but the remote end is not aware
|
// If we've seen this sequence number already but the remote end is not aware
|
||||||
// of that, make sure we send the acknowledgement again.
|
// of that, make sure we send the acknowledgement again.
|
||||||
|
@ -620,8 +637,8 @@ impl<'a> TcpSocket<'a> {
|
||||||
|
|
||||||
// RSTs in SYN-RECEIVED flip the socket back to the LISTEN state.
|
// RSTs in SYN-RECEIVED flip the socket back to the LISTEN state.
|
||||||
(State::SynReceived, TcpRepr { control: TcpControl::Rst, .. }) => {
|
(State::SynReceived, TcpRepr { control: TcpControl::Rst, .. }) => {
|
||||||
net_trace!("tcp:{}:{}: received RST",
|
net_trace!("[{}]{}:{}: received RST",
|
||||||
self.local_endpoint, self.remote_endpoint);
|
self.debug_id, self.local_endpoint, self.remote_endpoint);
|
||||||
self.local_endpoint.addr = self.listen_address;
|
self.local_endpoint.addr = self.listen_address;
|
||||||
self.remote_endpoint = IpEndpoint::default();
|
self.remote_endpoint = IpEndpoint::default();
|
||||||
self.set_state(State::Listen);
|
self.set_state(State::Listen);
|
||||||
|
@ -630,8 +647,8 @@ impl<'a> TcpSocket<'a> {
|
||||||
|
|
||||||
// RSTs in any other state close the socket.
|
// RSTs in any other state close the socket.
|
||||||
(_, TcpRepr { control: TcpControl::Rst, .. }) => {
|
(_, TcpRepr { control: TcpControl::Rst, .. }) => {
|
||||||
net_trace!("tcp:{}:{}: received RST",
|
net_trace!("[{}]{}:{}: received RST",
|
||||||
self.local_endpoint, self.remote_endpoint);
|
self.debug_id, self.local_endpoint, self.remote_endpoint);
|
||||||
self.set_state(State::Closed);
|
self.set_state(State::Closed);
|
||||||
self.local_endpoint = IpEndpoint::default();
|
self.local_endpoint = IpEndpoint::default();
|
||||||
self.remote_endpoint = IpEndpoint::default();
|
self.remote_endpoint = IpEndpoint::default();
|
||||||
|
@ -642,8 +659,8 @@ impl<'a> TcpSocket<'a> {
|
||||||
(State::Listen, TcpRepr {
|
(State::Listen, TcpRepr {
|
||||||
src_port, dst_port, control: TcpControl::Syn, seq_number, ack_number: None, ..
|
src_port, dst_port, control: TcpControl::Syn, seq_number, ack_number: None, ..
|
||||||
}) => {
|
}) => {
|
||||||
net_trace!("tcp:{}: received SYN",
|
net_trace!("[{}]{}: received SYN",
|
||||||
self.local_endpoint);
|
self.debug_id, self.local_endpoint);
|
||||||
self.local_endpoint = IpEndpoint::new(ip_repr.dst_addr(), dst_port);
|
self.local_endpoint = IpEndpoint::new(ip_repr.dst_addr(), dst_port);
|
||||||
self.remote_endpoint = IpEndpoint::new(ip_repr.src_addr(), src_port);
|
self.remote_endpoint = IpEndpoint::new(ip_repr.src_addr(), src_port);
|
||||||
// FIXME: use something more secure here
|
// FIXME: use something more secure here
|
||||||
|
@ -710,8 +727,8 @@ impl<'a> TcpSocket<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
net_trace!("tcp:{}:{}: unexpected packet {}",
|
net_trace!("[{}]{}:{}: unexpected packet {}",
|
||||||
self.local_endpoint, self.remote_endpoint, repr);
|
self.debug_id, self.local_endpoint, self.remote_endpoint, repr);
|
||||||
return Err(Error::Malformed)
|
return Err(Error::Malformed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -720,8 +737,8 @@ impl<'a> TcpSocket<'a> {
|
||||||
if let Some(ack_number) = repr.ack_number {
|
if let Some(ack_number) = repr.ack_number {
|
||||||
let ack_length = ack_number - self.local_seq_no;
|
let ack_length = ack_number - self.local_seq_no;
|
||||||
if ack_length > 0 {
|
if ack_length > 0 {
|
||||||
net_trace!("tcp:{}:{}: tx buffer: dequeueing {} octets (now {})",
|
net_trace!("[{}]{}:{}: tx buffer: dequeueing {} octets (now {})",
|
||||||
self.local_endpoint, self.remote_endpoint,
|
self.debug_id, self.local_endpoint, self.remote_endpoint,
|
||||||
ack_length, self.tx_buffer.len() - ack_length);
|
ack_length, self.tx_buffer.len() - ack_length);
|
||||||
}
|
}
|
||||||
self.tx_buffer.advance(ack_length);
|
self.tx_buffer.advance(ack_length);
|
||||||
|
@ -730,8 +747,8 @@ impl<'a> TcpSocket<'a> {
|
||||||
|
|
||||||
// Enqueue payload octets, which is guaranteed to be in order, unless we already did.
|
// Enqueue payload octets, which is guaranteed to be in order, unless we already did.
|
||||||
if repr.payload.len() > 0 {
|
if repr.payload.len() > 0 {
|
||||||
net_trace!("tcp:{}:{}: rx buffer: enqueueing {} octets (now {})",
|
net_trace!("[{}]{}:{}: rx buffer: enqueueing {} octets (now {})",
|
||||||
self.local_endpoint, self.remote_endpoint,
|
self.debug_id, self.local_endpoint, self.remote_endpoint,
|
||||||
repr.payload.len(), self.rx_buffer.len() + repr.payload.len());
|
repr.payload.len(), self.rx_buffer.len() + repr.payload.len());
|
||||||
self.rx_buffer.enqueue_slice(repr.payload)
|
self.rx_buffer.enqueue_slice(repr.payload)
|
||||||
}
|
}
|
||||||
|
@ -782,8 +799,8 @@ impl<'a> TcpSocket<'a> {
|
||||||
// We transmit a SYN|ACK in the SYN-RECEIVED state.
|
// We transmit a SYN|ACK in the SYN-RECEIVED state.
|
||||||
State::SynReceived => {
|
State::SynReceived => {
|
||||||
repr.control = TcpControl::Syn;
|
repr.control = TcpControl::Syn;
|
||||||
net_trace!("tcp:{}:{}: sending SYN|ACK",
|
net_trace!("[{}]{}:{}: sending SYN|ACK",
|
||||||
self.local_endpoint, self.remote_endpoint);
|
self.debug_id, self.local_endpoint, self.remote_endpoint);
|
||||||
should_send = true;
|
should_send = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -791,8 +808,8 @@ impl<'a> TcpSocket<'a> {
|
||||||
State::SynSent => {
|
State::SynSent => {
|
||||||
repr.control = TcpControl::Syn;
|
repr.control = TcpControl::Syn;
|
||||||
repr.ack_number = None;
|
repr.ack_number = None;
|
||||||
net_trace!("tcp:{}:{}: sending SYN",
|
net_trace!("[{}]{}:{}: sending SYN",
|
||||||
self.local_endpoint, self.remote_endpoint);
|
self.debug_id, self.local_endpoint, self.remote_endpoint);
|
||||||
should_send = true;
|
should_send = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -816,8 +833,8 @@ impl<'a> TcpSocket<'a> {
|
||||||
let data = self.tx_buffer.peek(offset, size);
|
let data = self.tx_buffer.peek(offset, size);
|
||||||
if data.len() > 0 {
|
if data.len() > 0 {
|
||||||
// Send the extracted data.
|
// Send the extracted data.
|
||||||
net_trace!("tcp:{}:{}: tx buffer: peeking at {} octets (from {})",
|
net_trace!("[{}]{}:{}: tx buffer: peeking at {} octets (from {})",
|
||||||
self.local_endpoint, self.remote_endpoint,
|
self.debug_id, self.local_endpoint, self.remote_endpoint,
|
||||||
data.len(), offset);
|
data.len(), offset);
|
||||||
repr.seq_number += offset;
|
repr.seq_number += offset;
|
||||||
repr.payload = data;
|
repr.payload = data;
|
||||||
|
@ -832,8 +849,8 @@ impl<'a> TcpSocket<'a> {
|
||||||
State::FinWait1 | State::LastAck => {
|
State::FinWait1 | State::LastAck => {
|
||||||
// We should notify the other side that we've closed the transmit half
|
// We should notify the other side that we've closed the transmit half
|
||||||
// of the connection.
|
// of the connection.
|
||||||
net_trace!("tcp:{}:{}: sending FIN|ACK",
|
net_trace!("[{}]{}:{}: sending FIN|ACK",
|
||||||
self.local_endpoint, self.remote_endpoint);
|
self.debug_id, self.local_endpoint, self.remote_endpoint);
|
||||||
repr.control = TcpControl::Fin;
|
repr.control = TcpControl::Fin;
|
||||||
should_send = true;
|
should_send = true;
|
||||||
}
|
}
|
||||||
|
@ -850,15 +867,16 @@ impl<'a> TcpSocket<'a> {
|
||||||
let ack_number = self.remote_seq_no + self.rx_buffer.len();
|
let ack_number = self.remote_seq_no + self.rx_buffer.len();
|
||||||
if !should_send && self.remote_last_ack != ack_number {
|
if !should_send && self.remote_last_ack != ack_number {
|
||||||
// Acknowledge all data we have received, since it is all in order.
|
// Acknowledge all data we have received, since it is all in order.
|
||||||
net_trace!("tcp:{}:{}: sending ACK",
|
net_trace!("[{}]{}:{}: sending ACK",
|
||||||
self.local_endpoint, self.remote_endpoint);
|
self.debug_id, self.local_endpoint, self.remote_endpoint);
|
||||||
should_send = true;
|
should_send = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if should_send {
|
if should_send {
|
||||||
if self.retransmit.commit(timestamp) {
|
if self.retransmit.commit(timestamp) {
|
||||||
net_trace!("tcp:{}:{}: retransmit after {}ms",
|
net_trace!("[{}]{}:{}: retransmit after {}ms",
|
||||||
self.local_endpoint, self.remote_endpoint, self.retransmit.delay);
|
self.debug_id, self.local_endpoint, self.remote_endpoint,
|
||||||
|
self.retransmit.delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
repr.ack_number = Some(ack_number);
|
repr.ack_number = Some(ack_number);
|
||||||
|
|
|
@ -111,7 +111,8 @@ impl<'a, 'b> SocketBuffer<'a, 'b> {
|
||||||
pub struct UdpSocket<'a, 'b: 'a> {
|
pub struct UdpSocket<'a, 'b: 'a> {
|
||||||
endpoint: IpEndpoint,
|
endpoint: IpEndpoint,
|
||||||
rx_buffer: SocketBuffer<'a, 'b>,
|
rx_buffer: SocketBuffer<'a, 'b>,
|
||||||
tx_buffer: SocketBuffer<'a, 'b>
|
tx_buffer: SocketBuffer<'a, 'b>,
|
||||||
|
debug_id: usize
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b> UdpSocket<'a, 'b> {
|
impl<'a, 'b> UdpSocket<'a, 'b> {
|
||||||
|
@ -121,10 +122,24 @@ impl<'a, 'b> UdpSocket<'a, 'b> {
|
||||||
Socket::Udp(UdpSocket {
|
Socket::Udp(UdpSocket {
|
||||||
endpoint: IpEndpoint::default(),
|
endpoint: IpEndpoint::default(),
|
||||||
rx_buffer: rx_buffer,
|
rx_buffer: rx_buffer,
|
||||||
tx_buffer: tx_buffer
|
tx_buffer: tx_buffer,
|
||||||
|
debug_id: 0
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return the debug identifier.
|
||||||
|
pub fn debug_id(&self) -> usize {
|
||||||
|
self.debug_id
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the debug identifier.
|
||||||
|
///
|
||||||
|
/// The debug identifier is a number printed in socket trace messages.
|
||||||
|
/// It could as well be used by the user code.
|
||||||
|
pub fn set_debug_id(&mut self, id: usize) {
|
||||||
|
self.debug_id = id
|
||||||
|
}
|
||||||
|
|
||||||
/// Return the bound endpoint.
|
/// Return the bound endpoint.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn endpoint(&self) -> IpEndpoint {
|
pub fn endpoint(&self) -> IpEndpoint {
|
||||||
|
@ -155,8 +170,9 @@ 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:{}:{}: buffer to send {} octets",
|
net_trace!("[{}]{}:{}: buffer to send {} octets",
|
||||||
self.endpoint, packet_buf.endpoint, packet_buf.size);
|
self.debug_id, self.endpoint,
|
||||||
|
packet_buf.endpoint, packet_buf.size);
|
||||||
Ok(&mut packet_buf.as_mut()[..size])
|
Ok(&mut packet_buf.as_mut()[..size])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,8 +192,9 @@ impl<'a, 'b> UdpSocket<'a, 'b> {
|
||||||
/// This function returns `Err(())` if the receive buffer is empty.
|
/// This function returns `Err(())` if the receive buffer is empty.
|
||||||
pub fn recv(&mut self) -> Result<(&[u8], IpEndpoint), ()> {
|
pub fn recv(&mut self) -> Result<(&[u8], IpEndpoint), ()> {
|
||||||
let packet_buf = try!(self.rx_buffer.dequeue());
|
let packet_buf = try!(self.rx_buffer.dequeue());
|
||||||
net_trace!("udp:{}:{}: receive {} buffered octets",
|
net_trace!("[{}]{}:{}: receive {} buffered octets",
|
||||||
self.endpoint, packet_buf.endpoint, packet_buf.size);
|
self.debug_id, self.endpoint,
|
||||||
|
packet_buf.endpoint, packet_buf.size);
|
||||||
Ok((&packet_buf.as_ref()[..packet_buf.size], packet_buf.endpoint))
|
Ok((&packet_buf.as_ref()[..packet_buf.size], packet_buf.endpoint))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,8 +225,9 @@ 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:{}:{}: receiving {} octets",
|
net_trace!("[{}]{}:{}: receiving {} octets",
|
||||||
self.endpoint, packet_buf.endpoint, packet_buf.size);
|
self.debug_id, self.endpoint,
|
||||||
|
packet_buf.endpoint, packet_buf.size);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,8 +235,9 @@ impl<'a, 'b> UdpSocket<'a, 'b> {
|
||||||
pub fn dispatch<F, R>(&mut self, _timestamp: u64, emit: &mut F) -> Result<R, Error>
|
pub fn dispatch<F, R>(&mut self, _timestamp: u64, 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().map_err(|()| Error::Exhausted));
|
let packet_buf = try!(self.tx_buffer.dequeue().map_err(|()| Error::Exhausted));
|
||||||
net_trace!("udp:{}:{}: sending {} octets",
|
net_trace!("[{}]{}:{}: sending {} octets",
|
||||||
self.endpoint, packet_buf.endpoint, packet_buf.size);
|
self.debug_id, self.endpoint,
|
||||||
|
packet_buf.endpoint, packet_buf.size);
|
||||||
let repr = UdpRepr {
|
let repr = UdpRepr {
|
||||||
src_port: self.endpoint.port,
|
src_port: self.endpoint.port,
|
||||||
dst_port: packet_buf.endpoint.port,
|
dst_port: packet_buf.endpoint.port,
|
||||||
|
|
Loading…
Reference in New Issue