Skip to content

Commit

Permalink
Merge pull request #841 from MabezDev/listen-noop
Browse files Browse the repository at this point in the history
Don't error when calling `listen` again on the same local endpoint.
  • Loading branch information
thvdveld authored Sep 20, 2023
2 parents e6dd013 + 00cde4e commit 280c938
Showing 1 changed file with 17 additions and 2 deletions.
19 changes: 17 additions & 2 deletions src/socket/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -744,7 +744,7 @@ impl<'a> Socket<'a> {

/// Start listening on the given endpoint.
///
/// This function returns `Err(Error::Illegal)` if the socket was already open
/// This function returns `Err(Error::InvalidState)` if the socket was already open
/// (see [is_open](#method.is_open)), and `Err(Error::Unaddressable)`
/// if the port in the given endpoint is zero.
pub fn listen<T>(&mut self, local_endpoint: T) -> Result<(), ListenError>
Expand All @@ -757,7 +757,19 @@ impl<'a> Socket<'a> {
}

if self.is_open() {
return Err(ListenError::InvalidState);
// If we were already listening to same endpoint there is nothing to do; exit early.
//
// In the past listening on an socket that was already listening was an error,
// however this makes writing an acceptor loop with multiple sockets impossible.
// Without this early exit, if you tried to listen on a socket that's already listening you'll
// immediately get an error. The only way around this is to abort the socket first
// before listening again, but this means that incoming connections can actually
// get aborted between the abort() and the next listen().
if matches!(self.state, State::Listen) && self.listen_endpoint == local_endpoint {
return Ok(());
} else {
return Err(ListenError::InvalidState);
}
}

self.reset();
Expand Down Expand Up @@ -2911,6 +2923,9 @@ mod test {
fn test_listen_twice() {
let mut s = socket();
assert_eq!(s.listen(80), Ok(()));
// multiple calls to listen are okay if its the same local endpoint and the state is still in listening
assert_eq!(s.listen(80), Ok(()));
s.set_state(State::SynReceived); // state change, simulate incoming connection
assert_eq!(s.listen(80), Err(ListenError::InvalidState));
}

Expand Down

0 comments on commit 280c938

Please sign in to comment.