Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enet_host_service problem #275

Open
aahn33 opened this issue Feb 14, 2025 · 0 comments
Open

enet_host_service problem #275

aahn33 opened this issue Feb 14, 2025 · 0 comments

Comments

@aahn33
Copy link

aahn33 commented Feb 14, 2025

I think there is a problem within the control flow of enet_host_service (in the case of low RTO).

From my understanding, given some non-zero event time-out x, the following occurs:

dispatch_incoming_commands

do {
  send_outgoing_commands
  receive_incoming_commands
  send_outgoing_commands
  dispatch_incoming_commands
  do {
     wait for socket
   } while wait condition met was interrupt
} while wait condition met was receive 

and along the way, if there is an event to return, or the timeout is hit, we break out and return.

I think that there are two potential problems with the control flow, and both have to do with when disconnects are initiated by the host, and it takes the client more than one RTO to ACK the disconnect

Suppose the following scenario:

  1. Host sends a disconnect to the client
  2. The client does not ACK to the first transmission, and enet_host_service times out without a response
  3. Loop calls enet_host_service again. Still no response, so it hits the enet_wait function.
  4. The ack arrives so there is something to receive on the sock, so we restart the loop
  5. We run send_outgoing before receive_incoming based off the order of calls
  6. the last disconnect we sent has timed out. retransmit it (however at this point, the client has already acked the disconnect)
  7. This returns out of enet_host_service
  8. The next call of enet_host_service then finally actually runs receive_incoming_message, which actually fully tears down the enet peer from the host (including clearing all of the queues)
  9. The last disconnect we sent has already been sent, and then we get an ICMP destination unreachable, which causes the next enet_host_service to return with -1.

TLDR: The way we reloop is conditioned on the socket having something to listen to, but then we call send_outgoing before we actually receive the incoming command. (this is fine usually, but in the case of disconnects, we don't want to be retransmitting when we received an ack for our last disconnect). While enet_host_service can be run with a lower event timeout to fix this, the larger issue is why send_outgoing runs before receive_incoming in the loop, when the event that triggers restarting the loop is that the socket is ready to receive from. Wouldn't it make more sense to receive_incoming_commands first if the socket signals that there is data to listen to?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant