You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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:
Host sends a disconnect to the client
The client does not ACK to the first transmission, and enet_host_service times out without a response
Loop calls enet_host_service again. Still no response, so it hits the enet_wait function.
The ack arrives so there is something to receive on the sock, so we restart the loop
We run send_outgoing before receive_incoming based off the order of calls
the last disconnect we sent has timed out. retransmit it (however at this point, the client has already acked the disconnect)
This returns out of enet_host_service
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)
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?
The text was updated successfully, but these errors were encountered:
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:
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:
enet_host_service
times out without a responseenet_host_service
again. Still no response, so it hits theenet_wait
function.send_outgoing
beforereceive_incoming
based off the order of callsdisconnect
we sent has timed out. retransmit it (however at this point, the client has already acked the disconnect)enet_host_service
enet_host_service
then finally actually runsreceive_incoming_message
, which actually fully tears down the enet peer from the host (including clearing all of the queues)disconnect
we sent has already been sent, and then we get anICMP destination unreachable
, which causes the nextenet_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). Whileenet_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 toreceive_incoming_commands
first if the socket signals that there is data to listen to?The text was updated successfully, but these errors were encountered: