Beispiel #1
0
        /// <summary>
        /// Handles a connect packet
        /// </summary>
        /// <param name="connect">Connect.</param>
        private void HandleConnect(UdpConnect connect, EndPoint endpoint)
        {
            var ipEndpoint = (IPEndPoint)endpoint;

            //var address = ipEndpoint.Address;

            if (availablePorts.Count == 0) // no available ports
            {
                Send(new UdpDisconnect(connect.clientSalt, UdpDisconnectReason.ServerFull), endpoint);
                return;
            }

            if (connections.TryGetValue(ipEndpoint, out var connection))
            {
                Send(new UdpDisconnect(connect.clientSalt, UdpDisconnectReason.ExistingConnection), endpoint);
                return;
            }

            var state = CreateConnectionRequest(connect.clientSalt, ipEndpoint);

            requestStates[ipEndpoint] = state;

            var saltSolution = Udp.CreateSalt(state.clientSalt, state.serverSalt);

            Send(new UdpChallenge(state.clientSalt, state.serverSalt), endpoint);
        }
Beispiel #2
0
        /// <summary>
        /// Handles a solution packet
        /// </summary>
        /// <param name="solution">Solution.</param>
        private void HandleSolution(UdpSolution solution, EndPoint endpoint)
        {
            var ipEndpoint = (IPEndPoint)endpoint;
            var address    = ipEndpoint.Address;

            if (connections.TryGetValue(ipEndpoint, out var oldcon))
            {
                if (oldcon.salt != solution.salt)
                {
                    Log.Write("New connection failed: already an existing connection");
                    return;
                }

                Send(new UdpConnected(oldcon.salt, (ushort)oldcon.LocalPort), endpoint);
                return;
            }

            if (!requestStates.TryGetValue(ipEndpoint, out var state))
            {
                Log.Write("New connection failed: no request state found");
                return;
            }

            var saltSolution = Udp.CreateSalt(state.clientSalt, state.serverSalt);

            if (solution.salt != saltSolution)
            {
                Log.Write("New connection failed: salt solution invalid");
                return;
            }

            if (!requestStates.TryRemove(ipEndpoint, out state))
            {
                Log.Write("New connection failed: no request state to remove");
                return;
            }

            if (!availablePorts.TryDequeue(out int port))
            {
                Log.Write("New connection failed: failed to assign port");
                return;
            }

            var connection = (TCon)Activator.CreateInstance(typeof(TCon));

            if (!connections.TryAdd(ipEndpoint, connection))
            {
                availablePorts.Enqueue(port); // return port
                connection.Disconnect(UdpDisconnectReason.Custom, true, "Failed to add connection");
                Log.Write("New connection failed: failed to add connection");
                return;
            }

            connection.SetConnectedTo(endpoint, saltSolution, port);
            connection.OnDisconnect += ClientDisconnected;
            HandleConnection(connection);
            connection.StartRead();

            Send(new UdpConnected(saltSolution, (ushort)port), endpoint);
        }
Beispiel #3
0
 /// <summary>
 /// Responds to a challenge packet received from the remote server
 /// </summary>
 /// <param name="challenge">Challenge.</param>
 private void HandleChallenge(UdpChallenge challenge)
 {
     if (challenge.clientSalt != localSalt)
     {
         return;                                    // salt mismatch, could be spoofed sender
     }
     if (!SetConnectionState(ConnectionState.AwaitingConnected, ConnectionState.AwaitingChallenge))
     {
         return;
     }
     remoteSalt = challenge.serverSalt;
     salt       = Udp.CreateSalt(localSalt, remoteSalt);
     retryCount = 0;
     SendSolution();
 }