/// <summary> /// Called when we have an error on a socket. /// </summary> static internal void OnSocketUnhandledError(RUDPSocket rudp, RUDPSocketError error, RUDPSendIAsyncResult sendAsyncResult) { //---- Disconnect the socket OnDisconnected(rudp, DisconnectionReason.SocketError); //---- Handle the error and forward it to the socket if (rudp._status == RUDPSocketStatus.Connecting) rudp.OnEndConnect(error); else { // On Send Error if (sendAsyncResult != null) rudp.OnEndSend(error, sendAsyncResult); // ELSE ... HOW TO GET sendAsyncResult when NULL ????? // On Receive Error RUDPReceiveIAsyncResult receiveAsyncResult = null; Interlocked.Exchange<RUDPReceiveIAsyncResult>(ref receiveAsyncResult, rudp._asyncResultReceive); if (receiveAsyncResult != null) { Interlocked.Exchange<RUDPReceiveIAsyncResult>(ref rudp._asyncResultReceive, null); rudp.OnEndReceive(error, null, true, receiveAsyncResult); } } }
private static void SetPacketACKed(RUDPSocket rudp, RUDPOutgoingPacket packet, double currentRTT) { lock (packet) { if (packet.IsACKed) return; rudp._controlWindow.OnACK(packet, currentRTT); // Mark as ACKed packet.IsACKed = true; } Trace("Packet ACKed(" + rudp.Handle + "): " + packet.PacketId + " " + packet.Channel); //---- Ping ACK if ((packet.Channel == RUDPPacketChannel.Ping || packet.Channel == RUDPPacketChannel.PingRendezVous) && rudp._status == RUDPSocketStatus.Connecting) { rudp._status = RUDPSocketStatus.Connected; // MTU tuning if (rudp._usePMTUDiscovery) rudp._pmtuDiscovery.StartTuning(); // connection done rudp.OnEndConnect(RUDPSocketError.Success); return; } //---- Tear Down ACK : It was a tear down message, it has been received, we can close if (packet.Channel == RUDPPacketChannel.TearDown && rudp._status == RUDPSocketStatus.Closing) { rudp._status = RUDPSocketStatus.ClosingACKed; // Remove it to our list of "connected" sockets if (rudp._remoteEndPoint != null) { // Unregister for the stack UnregisterRUDPSocket(rudp); rudp._physical.UnregisterConnectedSocket(rudp); } } }