Beispiel #1
0
        internal void SendConnectionEstablished()
        {
            NetOutgoingMessage om = m_peer.CreateMessage(0);

            om.m_messageType = NetMessageType.ConnectionEstablished;
            om.Write((float)NetTime.Now);
            m_peer.SendLibrary(om, m_remoteEndpoint);

            m_handshakeAttempts = 0;

            InitializePing();
            if (m_status != NetConnectionStatus.Connected)
            {
                SetStatus(NetConnectionStatus.Connected, "Connected to " + NetUtility.ToHexString(m_remoteUniqueIdentifier));
            }
        }
        private void InitializeNetwork()
        {
            lock (m_initializeLock)
            {
                m_configuration.Lock();

                if (m_status == NetPeerStatus.Running)
                {
                    return;
                }

                if (m_configuration.m_enableUPnP)
                {
                    m_upnp = new NetUPnP(this);
                }

                InitializePools();

                m_releasedIncomingMessages.Clear();
                m_unsentUnconnectedMessages.Clear();
                m_handshakes.Clear();

                // bind to socket
                IPEndPoint iep = null;

                iep = new IPEndPoint(m_configuration.LocalAddress, m_configuration.Port);
                EndPoint ep = (EndPoint)iep;

                m_socket = new PlatformSocket();
                m_socket.ReceiveBufferSize = m_configuration.ReceiveBufferSize;
                m_socket.SendBufferSize    = m_configuration.SendBufferSize;
                m_socket.Blocking          = false;
                m_socket.Bind(ep);
                m_socket.Setup();

                IPEndPoint boundEp = m_socket.LocalEndPoint as IPEndPoint;
                LogDebug("Socket bound to " + boundEp + ": " + m_socket.IsBound);
                m_listenPort = boundEp.Port;

                m_receiveBuffer            = new byte[m_configuration.ReceiveBufferSize];
                m_sendBuffer               = new byte[m_configuration.SendBufferSize];
                m_readHelperMessage        = new NetIncomingMessage(NetIncomingMessageType.Error);
                m_readHelperMessage.m_data = m_receiveBuffer;

                byte[] macBytes = new byte[8];
                NetRandom.Instance.NextBytes(macBytes);

#if IS_FULL_NET_AVAILABLE
                try
                {
                    System.Net.NetworkInformation.PhysicalAddress pa = NetUtility.GetMacAddress();
                    if (pa != null)
                    {
                        macBytes = pa.GetAddressBytes();
                        LogVerbose("Mac address is " + NetUtility.ToHexString(macBytes));
                    }
                    else
                    {
                        LogWarning("Failed to get Mac address");
                    }
                }
                catch (NotSupportedException)
                {
                    // not supported; lets just keep the random bytes set above
                }
#endif
                byte[] epBytes  = BitConverter.GetBytes(boundEp.GetHashCode());
                byte[] combined = new byte[epBytes.Length + macBytes.Length];
                Array.Copy(epBytes, 0, combined, 0, epBytes.Length);
                Array.Copy(macBytes, 0, combined, epBytes.Length, macBytes.Length);
#if WINDOWS_PHONE
                SHA1 s = new SHA1Managed();
                m_uniqueIdentifier = BitConverter.ToInt64(s.ComputeHash(combined), 0);
#else
                m_uniqueIdentifier = BitConverter.ToInt64(SHA1.Create().ComputeHash(combined), 0);
#endif

                m_status = NetPeerStatus.Running;
            }
        }
Beispiel #3
0
        internal void ReceivedHandshake(double now, NetMessageType tp, int ptr, int payloadLength)
        {
            m_peer.VerifyNetworkThread();

            byte[] hail;
            switch (tp)
            {
            case NetMessageType.Connect:
                if (m_status == NetConnectionStatus.None)
                {
                    // Whee! Server full has already been checked
                    bool ok = ValidateHandshakeData(ptr, payloadLength, out hail);
                    if (ok)
                    {
                        if (hail != null)
                        {
                            m_remoteHailMessage            = m_peer.CreateIncomingMessage(NetIncomingMessageType.Data, hail);
                            m_remoteHailMessage.LengthBits = (hail.Length * 8);
                        }
                        else
                        {
                            m_remoteHailMessage = null;
                        }

                        if (m_peerConfiguration.IsMessageTypeEnabled(NetIncomingMessageType.ConnectionApproval))
                        {
                            // ok, let's not add connection just yet
                            NetIncomingMessage appMsg = m_peer.CreateIncomingMessage(NetIncomingMessageType.ConnectionApproval, (m_remoteHailMessage == null ? 0 : m_remoteHailMessage.LengthBytes));
                            appMsg.m_receiveTime      = now;
                            appMsg.m_senderConnection = this;
                            appMsg.m_senderEndpoint   = this.m_remoteEndpoint;
                            if (m_remoteHailMessage != null)
                            {
                                appMsg.Write(m_remoteHailMessage.m_data, 0, m_remoteHailMessage.LengthBytes);
                            }
                            m_peer.ReleaseMessage(appMsg);
                            return;
                        }

                        SendConnectResponse((float)now, true);
                    }
                    return;
                }
                if (m_status == NetConnectionStatus.RespondedConnect)
                {
                    // our ConnectResponse must have been lost
                    SendConnectResponse((float)now, true);
                    return;
                }
                m_peer.LogDebug("Unhandled Connect: " + tp + ", status is " + m_status + " length: " + payloadLength);
                break;

            case NetMessageType.ConnectResponse:
                switch (m_status)
                {
                case NetConnectionStatus.InitiatedConnect:
                    // awesome
                    bool ok = ValidateHandshakeData(ptr, payloadLength, out hail);
                    if (ok)
                    {
                        if (hail != null)
                        {
                            m_remoteHailMessage            = m_peer.CreateIncomingMessage(NetIncomingMessageType.Data, hail);
                            m_remoteHailMessage.LengthBits = (hail.Length * 8);
                        }
                        else
                        {
                            m_remoteHailMessage = null;
                        }

                        m_peer.AcceptConnection(this);
                        SendConnectionEstablished();
                        return;
                    }
                    break;

                case NetConnectionStatus.RespondedConnect:
                    // hello, wtf?
                    break;

                case NetConnectionStatus.Disconnecting:
                case NetConnectionStatus.Disconnected:
                case NetConnectionStatus.None:
                    // wtf? anyway, bye!
                    break;

                case NetConnectionStatus.Connected:
                    // my ConnectionEstablished must have been lost, send another one
                    SendConnectionEstablished();
                    return;
                }
                break;

            case NetMessageType.ConnectionEstablished:
                switch (m_status)
                {
                case NetConnectionStatus.Connected:
                    // ok...
                    break;

                case NetConnectionStatus.Disconnected:
                case NetConnectionStatus.Disconnecting:
                case NetConnectionStatus.None:
                    // too bad, almost made it
                    break;

                case NetConnectionStatus.InitiatedConnect:
                    // weird, should have been ConnectResponse...
                    break;

                case NetConnectionStatus.RespondedConnect:
                    // awesome

                    NetIncomingMessage msg = m_peer.SetupReadHelperMessage(ptr, payloadLength);
                    InitializeRemoteTimeOffset(msg.ReadSingle());

                    m_peer.AcceptConnection(this);
                    InitializePing();
                    SetStatus(NetConnectionStatus.Connected, "Connected to " + NetUtility.ToHexString(m_remoteUniqueIdentifier));
                    return;
                }
                break;

            case NetMessageType.Disconnect:
                // ouch
                string reason = "Ouch";
                try
                {
                    NetIncomingMessage inc = m_peer.SetupReadHelperMessage(ptr, payloadLength);
                    reason = inc.ReadString();
                }
                catch
                {
                }
                ExecuteDisconnect(reason, false);
                break;

            case NetMessageType.Discovery:
                m_peer.HandleIncomingDiscoveryRequest(now, m_remoteEndpoint, ptr, payloadLength);
                return;

            case NetMessageType.DiscoveryResponse:
                m_peer.HandleIncomingDiscoveryResponse(now, m_remoteEndpoint, ptr, payloadLength);
                return;

            case NetMessageType.Ping:
                // silently ignore
                return;

            default:
                m_peer.LogDebug("Unhandled type during handshake: " + tp + " length: " + payloadLength);
                break;
            }
        }