private void HandleConnectResponse(int offset, int payloadLength) { switch (Status) { case NetConnectionStatus.InitiatedConnect: var(success, hail, hailLength) = ValidateHandshakeData(offset, payloadLength); if (success) { if (hail != null) { RemoteHailMessage = Peer.CreateIncomingMessage(NetIncomingMessageType.Data); RemoteHailMessage.SetBuffer(hail, true); RemoteHailMessage.ByteLength = hailLength; } else { RemoteHailMessage = null; } Peer.AcceptConnection(this); SendConnectionEstablished(); return; } break; case NetConnectionStatus.RespondedConnect: // hello? break; case NetConnectionStatus.Disconnecting: case NetConnectionStatus.Disconnected: case NetConnectionStatus.ReceivedInitiation: case NetConnectionStatus.None: // anyway, bye! break; case NetConnectionStatus.Connected: // my ConnectionEstablished must have been lost, send another one SendConnectionEstablished(); return; } }
internal void ReceivedHandshake(TimeSpan now, NetMessageType type, int offset, int payloadLength) { Peer.AssertIsOnLibraryThread(); switch (type) { case NetMessageType.Connect: if (Status == NetConnectionStatus.ReceivedInitiation) { // Whee! Server full has already been checked var(success, hail, hailLength) = ValidateHandshakeData(offset, payloadLength); if (success) { if (hail != null) { RemoteHailMessage = Peer.CreateIncomingMessage(NetIncomingMessageType.Data); RemoteHailMessage.SetBuffer(hail, true); RemoteHailMessage.ByteLength = hailLength; } else { RemoteHailMessage = null; } if (_peerConfiguration.IsMessageTypeEnabled(NetIncomingMessageType.ConnectionApproval)) { // ok, let's not add connection just yet var appMsg = Peer.CreateIncomingMessage(NetIncomingMessageType.ConnectionApproval); appMsg.ReceiveTime = now; appMsg.SenderConnection = this; appMsg.SenderEndPoint = RemoteEndPoint; if (RemoteHailMessage != null) { appMsg.Write(RemoteHailMessage.GetBuffer().AsSpan(0, RemoteHailMessage.ByteLength)); } SetStatus(NetConnectionStatus.RespondedAwaitingApproval); Peer.ReleaseMessage(appMsg); return; } SendConnectResponse(now, true); } return; } if (Status == NetConnectionStatus.RespondedAwaitingApproval) { Peer.LogWarning(new NetLogMessage(NetLogCode.IgnoringMultipleConnects, endPoint: this)); return; } if (Status == NetConnectionStatus.RespondedConnect) { // our ConnectResponse must have been lost SendConnectResponse(now, true); return; } Peer.LogDebug(NetLogMessage.FromValues(NetLogCode.UnhandledConnect, endPoint: this, value: (int)Status)); break; case NetMessageType.ConnectResponse: HandleConnectResponse(offset, payloadLength); break; case NetMessageType.ConnectionEstablished: switch (Status) { case NetConnectionStatus.Connected: // ok... break; case NetConnectionStatus.Disconnected: case NetConnectionStatus.Disconnecting: case NetConnectionStatus.None: // too bad, almost made it break; case NetConnectionStatus.ReceivedInitiation: // uh, a little premature... ignore break; case NetConnectionStatus.InitiatedConnect: // weird, should have been RespondedConnect... break; case NetConnectionStatus.RespondedConnect: // awesome NetIncomingMessage msg = Peer.SetupReadHelperMessage(offset, payloadLength); InitializeRemoteTimeOffset(msg.ReadTimeSpan()); Peer.AcceptConnection(this); InitializePing(); SetStatus(NetConnectionStatus.Connected); return; } break; case NetMessageType.InvalidHandshake: case NetMessageType.WrongAppIdentifier: case NetMessageType.ConnectTimedOut: case NetMessageType.TimedOut: case NetMessageType.Disconnect: NetOutgoingMessage?reason = null; try { reason = Peer.CreateReadHelperOutMessage(offset, payloadLength); } catch { } ExecuteDisconnect(reason, false); break; case NetMessageType.Discovery: Peer.HandleIncomingDiscoveryRequest(now, RemoteEndPoint, offset, payloadLength); return; case NetMessageType.DiscoveryResponse: Peer.HandleIncomingDiscoveryResponse(now, RemoteEndPoint, offset, payloadLength); return; case NetMessageType.Ping: // silently ignore return; default: Peer.LogDebug(NetLogMessage.FromValues(NetLogCode.UnhandledHandshakeMessage, value: (int)Status)); break; } }