Skip to content

Commit 8fa656c

Browse files
eeeeetacvengler
authored andcommitted
Allow withholding the SYN|ACK packet by user code
In certain use cases, it's desirable to not send a SYN|ACK packet immediately after receiving a SYN -- for example, a TCP proxy that doesn't want to do so until it's connected to the end destination, because the outgoing connection might get refused. (Currently, you have to send a SYN|ACK and then reset the connection afterwards in this case.) To fix this, add a simple `synack_paused` flag, controllable by user code, that withholds SYN|ACK packets in `SynReceived` state until it is unset.
1 parent e2b75e3 commit 8fa656c

File tree

1 file changed

+17
-0
lines changed

1 file changed

+17
-0
lines changed

src/socket/tcp.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,9 @@ pub struct Socket<'a> {
527527
/// Used for rate-limiting: No more challenge ACKs will be sent until this instant.
528528
challenge_ack_timer: Instant,
529529

530+
/// If this is set, we will not send a SYN|ACK until this is unset.
531+
synack_paused: bool,
532+
530533
/// Nagle's Algorithm enabled.
531534
nagle: bool,
532535

@@ -601,6 +604,7 @@ impl<'a> Socket<'a> {
601604
tsval_generator: None,
602605
last_remote_tsval: 0,
603606
congestion_controller: congestion::AnyController::new(),
607+
synack_paused: false,
604608

605609
#[cfg(feature = "async")]
606610
rx_waker: WakerRegistration::new(),
@@ -724,6 +728,15 @@ impl<'a> Socket<'a> {
724728
self.nagle
725729
}
726730

731+
/// Pause sending of SYN|ACK packets.
732+
///
733+
/// When this flag is set, the socket will get stuck in `SynReceived` state without sending
734+
/// any SYN|ACK packets back, until this flag is unset. This is useful for certain niche TCP
735+
/// proxy usecases.
736+
pub fn pause_synack(&mut self, pause: bool) {
737+
self.synack_paused = pause;
738+
}
739+
727740
/// Return the current window field value, including scaling according to RFC 1323.
728741
///
729742
/// Used in internal calculations as well as packet generation.
@@ -2372,6 +2385,10 @@ impl<'a> Socket<'a> {
23722385
.on_retransmit(cx.now());
23732386
}
23742387

2388+
if matches!(self.state, State::SynReceived) && self.synack_paused {
2389+
return Ok(());
2390+
}
2391+
23752392
// Decide whether we're sending a packet.
23762393
if self.seq_to_transmit(cx) {
23772394
// If we have data to transmit and it fits into partner's window, do it.

0 commit comments

Comments
 (0)