Skip to content

Commit 1a618aa

Browse files
committedDec 27, 2016
Implement the TCP close operation.
1 parent 947e9eb commit 1a618aa

File tree

2 files changed

+158
-1
lines changed

2 files changed

+158
-1
lines changed
 

‎examples/smoltcpserver.rs

+2
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ fn main() {
121121
str::from_utf8(data.as_ref()).unwrap_or("(invalid utf8)"));
122122
socket.send_slice(&data[..]).unwrap();
123123
}
124+
} else if socket.can_send() {
125+
socket.close()
124126
}
125127
}
126128

‎src/socket/tcp.rs

+156-1
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,34 @@ impl<'a> TcpSocket<'a> {
257257
Ok(())
258258
}
259259

260+
/// Close the transmit half of the full-duplex connection.
261+
///
262+
/// Note that there is no corresponding function for the receive half of the full-duplex
263+
/// connection; only the remote end can close it. If you no longer wish to receive any
264+
/// data and would like to reuse the socket right away, use [abort](#method.abort).
265+
pub fn close(&mut self) {
266+
match self.state {
267+
// In the LISTEN state there is no established connection.
268+
State::Listen =>
269+
self.set_state(State::Closed),
270+
// In the SYN_SENT state the remote endpoint is not yet synchronized and, upon
271+
// receiving an RST, will abort the connection.
272+
State::SynSent =>
273+
self.set_state(State::Closed),
274+
// In the SYN_RECEIVED, ESTABLISHED and CLOSE_WAIT states the transmit half
275+
// of the connection is open, and needs to be explicitly closed with a FIN.
276+
State::SynReceived | State::Established =>
277+
self.set_state(State::FinWait1),
278+
State::CloseWait =>
279+
self.set_state(State::LastAck),
280+
// In the FIN_WAIT_1, FIN_WAIT_2, CLOSING, LAST_ACK, TIME_WAIT and CLOSED states,
281+
// the transmit half of the connection is already closed, and no further
282+
// action is needed.
283+
State::FinWait1 | State::FinWait2 | State::Closing |
284+
State::TimeWait | State::LastAck | State::Closed => ()
285+
}
286+
}
287+
260288
/// Return whether the socket is open.
261289
///
262290
/// This function returns true if the socket will process incoming or dispatch outgoing
@@ -854,14 +882,21 @@ mod test {
854882
#[test]
855883
fn test_closed() {
856884
let mut s = socket();
857-
assert_eq!(s.state(), State::Closed);
885+
assert_eq!(s.state, State::Closed);
858886

859887
send!(s, TcpRepr {
860888
control: TcpControl::Syn,
861889
..SEND_TEMPL
862890
}, Err(Error::Rejected));
863891
}
864892

893+
#[test]
894+
fn test_closed_close() {
895+
let mut s = socket();
896+
s.close();
897+
assert_eq!(s.state, State::Closed);
898+
}
899+
865900
// =========================================================================================//
866901
// Tests for the LISTEN state.
867902
// =========================================================================================//
@@ -895,6 +930,13 @@ mod test {
895930
}]);
896931
}
897932

933+
#[test]
934+
fn test_listen_close() {
935+
let mut s = socket_listen();
936+
s.close();
937+
assert_eq!(s.state, State::Closed);
938+
}
939+
898940
// =========================================================================================//
899941
// Tests for the SYN_RECEIVED state.
900942
// =========================================================================================//
@@ -922,6 +964,13 @@ mod test {
922964
assert_eq!(s.remote_endpoint, IpEndpoint::default());
923965
}
924966

967+
#[test]
968+
fn test_syn_received_close() {
969+
let mut s = socket_syn_received();
970+
s.close();
971+
assert_eq!(s.state, State::FinWait1);
972+
}
973+
925974
// =========================================================================================//
926975
// Tests for the SYN_SENT state.
927976
// =========================================================================================//
@@ -970,6 +1019,13 @@ mod test {
9701019
assert_eq!(s.state, State::SynSent);
9711020
}
9721021

1022+
#[test]
1023+
fn test_syn_sent_close() {
1024+
let mut s = socket();
1025+
s.close();
1026+
assert_eq!(s.state, State::Closed);
1027+
}
1028+
9731029
// =========================================================================================//
9741030
// Tests for the ESTABLISHED state.
9751031
// =========================================================================================//
@@ -1170,6 +1226,64 @@ mod test {
11701226
assert_eq!(s.state, State::Closed);
11711227
}
11721228

1229+
#[test]
1230+
fn test_established_close() {
1231+
let mut s = socket_established();
1232+
s.close();
1233+
assert_eq!(s.state, State::FinWait1);
1234+
}
1235+
1236+
// =========================================================================================//
1237+
// Tests for the FIN_WAIT_1 state.
1238+
// =========================================================================================//
1239+
fn socket_fin_wait_1() -> TcpSocket<'static> {
1240+
let mut s = socket_established();
1241+
s.state = State::FinWait1;
1242+
s
1243+
}
1244+
1245+
#[test]
1246+
fn test_fin_wait_1_close() {
1247+
let mut s = socket_fin_wait_1();
1248+
s.close();
1249+
assert_eq!(s.state, State::FinWait1);
1250+
}
1251+
1252+
// =========================================================================================//
1253+
// Tests for the FIN_WAIT_2 state.
1254+
// =========================================================================================//
1255+
fn socket_fin_wait_2() -> TcpSocket<'static> {
1256+
let mut s = socket_fin_wait_1();
1257+
s.state = State::FinWait2;
1258+
s.local_seq_no = LOCAL_SEQ + 1 + 1;
1259+
s
1260+
}
1261+
1262+
#[test]
1263+
fn test_fin_wait_2_close() {
1264+
let mut s = socket_fin_wait_2();
1265+
s.close();
1266+
assert_eq!(s.state, State::FinWait2);
1267+
}
1268+
1269+
// =========================================================================================//
1270+
// Tests for the CLOSING state.
1271+
// =========================================================================================//
1272+
fn socket_closing() -> TcpSocket<'static> {
1273+
let mut s = socket_fin_wait_1();
1274+
s.state = State::Closing;
1275+
s.remote_seq_no = REMOTE_SEQ + 1 + 1;
1276+
s.remote_last_ack = REMOTE_SEQ + 1 + 1;
1277+
s
1278+
}
1279+
1280+
#[test]
1281+
fn test_closing_close() {
1282+
let mut s = socket_closing();
1283+
s.close();
1284+
assert_eq!(s.state, State::Closing);
1285+
}
1286+
11731287
// =========================================================================================//
11741288
// Tests for the CLOSE_WAIT state.
11751289
// =========================================================================================//
@@ -1198,6 +1312,47 @@ mod test {
11981312
}]);
11991313
}
12001314

1315+
#[test]
1316+
fn test_close_wait_close() {
1317+
let mut s = socket_close_wait();
1318+
s.close();
1319+
assert_eq!(s.state, State::LastAck);
1320+
}
1321+
1322+
// =========================================================================================//
1323+
// Tests for the LAST_ACK state.
1324+
// =========================================================================================//
1325+
fn socket_last_ack() -> TcpSocket<'static> {
1326+
let mut s = socket_close_wait();
1327+
s.state = State::LastAck;
1328+
s
1329+
}
1330+
1331+
#[test]
1332+
fn test_last_ack_close() {
1333+
let mut s = socket_last_ack();
1334+
s.close();
1335+
assert_eq!(s.state, State::LastAck);
1336+
}
1337+
1338+
// =========================================================================================//
1339+
// Tests for the TIME_WAIT state.
1340+
// =========================================================================================//
1341+
fn socket_time_wait() -> TcpSocket<'static> {
1342+
let mut s = socket_fin_wait_2();
1343+
s.state = State::TimeWait;
1344+
s.remote_seq_no = REMOTE_SEQ + 1 + 1;
1345+
s.remote_last_ack = REMOTE_SEQ + 1 + 1;
1346+
s
1347+
}
1348+
1349+
#[test]
1350+
fn test_time_wait_close() {
1351+
let mut s = socket_time_wait();
1352+
s.close();
1353+
assert_eq!(s.state, State::TimeWait);
1354+
}
1355+
12011356
// =========================================================================================//
12021357
// Tests for transitioning through multiple states.
12031358
// =========================================================================================//

0 commit comments

Comments
 (0)
Please sign in to comment.