Accept TCP FIN packets in SYN-RECEIVED state.
parent
ab4593ea6c
commit
38afc64f61
|
@ -1,6 +1,8 @@
|
|||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
#![allow(unused_mut)]
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use std as core;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
extern crate smoltcp;
|
||||
|
@ -13,6 +15,7 @@ extern crate getopts;
|
|||
#[allow(dead_code)]
|
||||
mod utils;
|
||||
|
||||
use core::str;
|
||||
use smoltcp::Error;
|
||||
use smoltcp::phy::Loopback;
|
||||
use smoltcp::wire::{EthernetAddress, IpAddress};
|
||||
|
@ -126,13 +129,14 @@ fn main() {
|
|||
let socket: &mut TcpSocket = socket_set.get_mut(server_handle).as_socket();
|
||||
if !socket.is_active() && !socket.is_listening() {
|
||||
if !did_listen {
|
||||
debug!("listening");
|
||||
socket.listen(1234).unwrap();
|
||||
did_listen = true;
|
||||
}
|
||||
}
|
||||
|
||||
if socket.can_recv() {
|
||||
debug!("got {:?}", socket.recv(32).unwrap());
|
||||
debug!("got {:?}", str::from_utf8(socket.recv(32).unwrap()).unwrap());
|
||||
socket.close();
|
||||
done = true;
|
||||
}
|
||||
|
@ -142,6 +146,7 @@ fn main() {
|
|||
let socket: &mut TcpSocket = socket_set.get_mut(client_handle).as_socket();
|
||||
if !socket.is_open() {
|
||||
if !did_connect {
|
||||
debug!("connecting");
|
||||
socket.connect((IpAddress::v4(127, 0, 0, 1), 1234),
|
||||
(IpAddress::Unspecified, 65000)).unwrap();
|
||||
did_connect = true;
|
||||
|
@ -149,6 +154,7 @@ fn main() {
|
|||
}
|
||||
|
||||
if socket.can_send() {
|
||||
debug!("sending");
|
||||
socket.send_slice(b"0123456789abcdef").unwrap();
|
||||
socket.close();
|
||||
}
|
||||
|
@ -162,7 +168,9 @@ fn main() {
|
|||
clock.advance(1);
|
||||
}
|
||||
|
||||
if !done {
|
||||
error!("this is taking too long, bailing out");
|
||||
if done {
|
||||
info!("done")
|
||||
} else {
|
||||
error!("this is taking too long, bailing out")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -852,6 +852,15 @@ impl<'a> TcpSocket<'a> {
|
|||
self.retransmit.reset();
|
||||
}
|
||||
|
||||
// FIN packets in the SYN-RECEIVED state change it to CLOSE-WAIT.
|
||||
// It's not obvious from RFC 793 that this is permitted, but
|
||||
// 7th and 8th steps in the "SEGMENT ARRIVES" event describe this behavior.
|
||||
(State::SynReceived, TcpRepr { control: TcpControl::Fin, .. }) => {
|
||||
self.remote_seq_no += 1;
|
||||
self.set_state(State::CloseWait);
|
||||
self.retransmit.reset();
|
||||
}
|
||||
|
||||
// SYN|ACK packets in the SYN-SENT state change it to ESTABLISHED.
|
||||
(State::SynSent, TcpRepr {
|
||||
control: TcpControl::Syn, seq_number, ack_number: Some(_),
|
||||
|
@ -1498,7 +1507,7 @@ mod test {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn test_syn_received_syn_ack() {
|
||||
fn test_syn_received_ack() {
|
||||
let mut s = socket_syn_received();
|
||||
recv!(s, [TcpRepr {
|
||||
control: TcpControl::Syn,
|
||||
|
@ -1516,6 +1525,30 @@ mod test {
|
|||
sanity!(s, socket_established());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_syn_received_fin() {
|
||||
let mut s = socket_syn_received();
|
||||
recv!(s, [TcpRepr {
|
||||
control: TcpControl::Syn,
|
||||
seq_number: LOCAL_SEQ,
|
||||
ack_number: Some(REMOTE_SEQ + 1),
|
||||
max_seg_size: Some(1480),
|
||||
..RECV_TEMPL
|
||||
}]);
|
||||
send!(s, TcpRepr {
|
||||
control: TcpControl::Fin,
|
||||
seq_number: REMOTE_SEQ + 1,
|
||||
ack_number: Some(LOCAL_SEQ + 1),
|
||||
payload: &b"abcdef"[..],
|
||||
..SEND_TEMPL
|
||||
});
|
||||
assert_eq!(s.state, State::CloseWait);
|
||||
sanity!(s, TcpSocket {
|
||||
remote_last_ack: REMOTE_SEQ + 1,
|
||||
..socket_close_wait()
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_syn_received_rst() {
|
||||
let mut s = socket_syn_received();
|
||||
|
|
Loading…
Reference in New Issue