Exemple #1
0
        private void Process(byte[] data, int length, IPEndPoint receiveAddress)
        {
            if (length < 16)
            {
                Console.WriteLine($"Rejecting short message from {receiveAddress}");
                return;
            }
            if (data[0] != 68 || data[1] != 84 || data[2] != 84 || data[3] != 50)
            {
                Console.WriteLine($"Rejecting non TCPTunnel traffic from {receiveAddress}");
                return;
            }
            int   connectionID    = BitConverter.ToInt32(data, 4);
            short messageType     = BitConverter.ToInt16(data, 8);
            short messageLength   = BitConverter.ToInt16(data, 10);
            short messageSequence = BitConverter.ToInt16(data, 12);
            short messageACK      = BitConverter.ToInt16(data, 14);

            if (BitConverter.IsLittleEndian)
            {
                connectionID    = IPAddress.NetworkToHostOrder(connectionID);
                messageType     = IPAddress.NetworkToHostOrder(messageType);
                messageLength   = IPAddress.NetworkToHostOrder(messageLength);
                messageSequence = IPAddress.NetworkToHostOrder(messageSequence);
                messageACK      = IPAddress.NetworkToHostOrder(messageACK);
            }
            if (messageLength != length - 16)
            {
                Console.WriteLine($"Rejecting bad payload TCPTunnel traffic from {receiveAddress}");
                return;
            }
            //Payload is limited to 500 bytes
            if (messageLength > 500)
            {
                Console.WriteLine($"Broken payload from {connectionID}");
                return;
            }
            if (!connections.ContainsKey(connectionID))
            {
                //We're the server so we need to grab a new tcp connection for this client
                if (ConnectLocalTCPConnection != null)
                {
                    TcpClient newClient = ConnectLocalTCPConnection();
                    if (newClient == null)
                    {
                        //Server down?
                        Console.WriteLine($"Unable to connect to {settings.tcpPort}, is the server down?");
                        return;
                    }
                    Bucket     newBucket     = new Bucket(settings.connectionUpload, settings.connectionUpload, globalLimit);
                    Connection newConnection = new Connection(connectionID, settings, newClient, this, newBucket);
                    newConnection.sendEndpoint = receiveAddress;
                    connections[connectionID]  = newConnection;
                    Console.WriteLine($"New connection {connectionID} from {receiveAddress} mapped to {newClient.Client.LocalEndPoint}");
                }
                else
                {
                    //We can't do anything client side if we don't have an existing TCP connection, ignore the messages
                    Console.WriteLine($"Unknown UDP connection {connectionID} in client mode");
                    return;
                }
            }
            Connection c       = connections[connectionID];
            ByteArray  payload = null;

            if (messageLength > 0)
            {
                payload = Recycler.Grab();
                Array.Copy(data, 16, payload.data, 0, messageLength);
                payload.length = messageLength;
            }
            c.HandleUDPData(messageType, messageLength, messageSequence, messageACK, payload, receiveAddress);
        }
Exemple #2
0
 public Connection(int connectionID, TunnelSettings settings, TcpClient tcpClient, UDPServer udpServer, Bucket uploadBucket, Statistics statistics)
 {
     this.connectionID = connectionID;
     this.tcpClient    = tcpClient;
     this.udpServer    = udpServer;
     this.uploadBucket = uploadBucket;
     this.settings     = settings;
     this.statistics   = statistics;
     tcpSendTask       = new Thread(new ThreadStart(SendLoop));
     tcpSendTask.Name  = "Connection.SendLoop." + connectionID;
     tcpSendTask.Start();
     tcpReceiveTask      = new Thread(new ThreadStart(ReceiveLoop));
     tcpReceiveTask.Name = "Connection.ReceiveLoop." + connectionID;
     tcpReceiveTask.Start();
     disconnectTime = DateTime.UtcNow.Ticks + (TimeSpan.TicksPerSecond * 5);
 }