/// <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); }
/// <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); }
/// <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(); }