Пример #1
0
        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;
            }
        }