Beispiel #1
0
        static void AcceptCallback(ref SelectControl control, Socket listenSock, Buf safeBuffer)
        {
            Socket newSock = listenSock.Accept();

            if (log != null)
            {
                log.WriteLine("Accepted new client {0}", newSock.SafeRemoteEndPointString());
            }

            Socket clientSideSocket = new Socket(server.GetAddressFamilyForTcp(), SocketType.Stream, ProtocolType.Tcp);

            BufStruct leftOver = new BufStruct(safeBuffer.array);

            clientSideSocket.Connect(server, DnsPriority.IPv4ThenIPv6, ProxyConnectOptions.None, ref leftOver);
            if (leftOver.contentLength > 0)
            {
                newSock.Send(leftOver.buf, 0, (int)leftOver.contentLength, SocketFlags.None);
                if (pcapLogger != null)
                {
                    //pcapLogger.LogTcpData(leftOver.buf, 0, leftOver.contentLength);
                }
            }

            SelectSocketTunnel tunnel = new SelectSocketTunnel(newSock, clientSideSocket);

            control.AddReceiveSocket(newSock, tunnel.ReceiveCallback);
            control.AddReceiveSocket(clientSideSocket, tunnel.ReceiveCallback);
        }
Beispiel #2
0
        // TODO: catch and handle exceptions
        public void HandleAccept(ref SelectControl selectControl, Socket listenSocket, Buf safeBuffer)
        {
            Socket newClientSocket = listenSocket.Accept();

            Socket newRemoteServerSocket = new Socket(serverHost.directEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

            newRemoteServerSocket.ConnectTcpSocketThroughProxy(serverHost);

            TcpBridge bridge = new TcpBridge(newClientSocket.SafeRemoteEndPointString(), newClientSocket,
                                             newRemoteServerSocket.SafeRemoteEndPointString(), newRemoteServerSocket);

            selectControl.AddReceiveSocket(newClientSocket, bridge.ReceiveHandler);
            selectControl.AddReceiveSocket(newRemoteServerSocket, bridge.ReceiveHandler);
        }
        public static void AcceptProxyClient(ref SelectControl selectControl, Socket listenSocket, Buf safeBuffer)
        {
            Socket clientSocket = listenSocket.Accept();

            if (clientSocket.Connected)
            {
                String clientLogString = clientSocket.SafeRemoteEndPointString();

                if (AppLayerProxy.Logger != null)
                {
                    AppLayerProxy.Logger.WriteLine("Listener:{0} new client {1}", ListenPort, clientLogString);
                }

                ConnectionInitiator connectionInitiator = new ConnectionInitiator(clientSocket, clientLogString);
                selectControl.AddReceiveSocket(clientSocket, connectionInitiator.InitialReceiveHandler);
            }
            else
            {
                if (AppLayerProxy.Logger != null)
                {
                    AppLayerProxy.Logger.WriteLine("Listener:{0} new client was accepted but was not connected", ListenPort);
                }

                clientSocket.Close();
            }
        }
        public void AcceptCallback(ref SelectControl control, Socket listenSock, Buf safeBuffer)
        {
            Socket newSocket = listenSock.Accept();
            RpcServerConnectionHandler connection = new RpcServerConnectionHandler(this, newSocket);

            control.AddReceiveSocket(newSocket, connection.HandleData);
        }
Beispiel #5
0
        public void AcceptCallback(ref SelectControl control, Socket listenSock, Buf safeBuffer)
        {
            Socket newSock = listenSock.Accept();
            String clientEndPointString = newSock.SafeRemoteEndPointString();

            Console.WriteLine("[{0}] New Connection", clientEndPointString);
            //clients.Add(socket, newClient);
            control.AddReceiveSocket(newSock, new HttpToCdpClient(clientEndPointString, newSock, this).TcpRecvHandler);
        }
Beispiel #6
0
        public void AcceptCallback(ref SelectControl control, Socket listenSock, Buf safeBuffer)
        {
            Socket newSock = listenSock.Accept();

            DebugClientData clientData = new DebugClientData(newSock);

            control.AddReceiveSocket(newSock, clientData.DataCallback);
            clientData.SendPrompt();
        }
        static void AcceptCallback(ref SelectControl selectControl, Socket listenSocket, Buf safeBuffer)
        {
            Socket clientSocket = listenSocket.Accept();

            if (clientSocket.Connected)
            {
                String clientLogString = clientSocket.SafeRemoteEndPointString();
                Console.WriteLine("[{0}] NewClient", clientLogString);
                selectControl.AddReceiveSocket(clientSocket,
                                               new OpenHttpSocket(clientLogString).HeaderRecvHandler);
            }
            else
            {
                clientSocket.Close();
            }
        }
Beispiel #8
0
        public static void NpcAcceptCallback(ref SelectControl selectControl, Socket listenSocket, Buf safeBuffer)
        {
            Socket clientSocket = listenSocket.Accept();

            if (clientSocket.Connected)
            {
                String clientLogString = clientSocket.SafeRemoteEndPointString();

                var dataHandler = new NpcSocketHandler(clientLogString, NpcServerConsoleLoggerCallback.Instance,
                                                       NpcReflector, HtmlGenerator);
                selectControl.AddReceiveSocket(clientSocket, dataHandler.InitialRecvHandler);
            }
            else
            {
                clientSocket.Close();
            }
        }
Beispiel #9
0
        static Int32 Main(string[] args)
        {
            TunnelOptions optionsParser = new TunnelOptions();
            List <String> nonOptionArgs = optionsParser.Parse(args);

            if (nonOptionArgs.Count <= 0)
            {
                Console.WriteLine("Must give at least one listener");
                optionsParser.PrintUsage();
                return(-1);
            }

            SelectControl selectControl = new SelectControl(false);

            //
            // Parse listeners
            //
            int arg = 0;

            do
            {
                //
                // Get Command Line Arguments
                //
                String connector = nonOptionArgs[arg];
                arg++;
                if (arg >= nonOptionArgs.Count)
                {
                    Console.WriteLine("EndPoint '{0}' is missing a protocol 'tcp|udp' and a listen port set", connector);
                    optionsParser.PrintUsage();
                    return(-1);
                }
                //
                // Parse End Point
                //
                HostWithOptionalProxy forwardHost = ConnectorParser.ParseConnectorWithPortAndOptionalProxy(connector);

                //
                // Parse Protocol and Port Set
                //
                String protocolAndPortSet = nonOptionArgs[arg++];

                Boolean isTcp;
                if (protocolAndPortSet.StartsWith("tcp", StringComparison.CurrentCultureIgnoreCase))
                {
                    isTcp = true;
                }
                else if (protocolAndPortSet.StartsWith("udp", StringComparison.CurrentCultureIgnoreCase))
                {
                    isTcp = false;
                }
                else
                {
                    throw new InvalidOperationException(String.Format("Unknown protocol '{0}', expected 'tcp' or 'udp'",
                                                                      (protocolAndPortSet.Length < 3) ? protocolAndPortSet : protocolAndPortSet.Remove(3)));
                }

                if (protocolAndPortSet.Length < 4)
                {
                    Console.WriteLine("ProtocolAndPortSet '{0}' Protocol '{1}' is missing a listen port set", connector, protocolAndPortSet);
                    optionsParser.PrintUsage();
                    return(-1);
                }

                String portSetString = protocolAndPortSet.Substring(3);
                if (String.IsNullOrEmpty(portSetString))
                {
                    Console.WriteLine("EndPoint '{0}' Protocol '{1}' is missing a listen port set", connector, protocolAndPortSet);
                    optionsParser.PrintUsage();
                    return(-1);
                }

                PortSet portSet = ParseUtilities.ParsePortSet(portSetString);

                if (isTcp)
                {
                    TcpCallback tcpCallback = new TcpCallback(forwardHost);

                    for (int i = 0; i < portSet.Length; i++)
                    {
                        Socket listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                        listenSocket.Bind(new IPEndPoint(IPAddress.Any, portSet[i]));
                        listenSocket.Listen(optionsParser.socketBackLog.ArgValue);
                        selectControl.AddListenSocket(listenSocket, tcpCallback.HandleAccept);
                    }
                }
                else
                {
                    if (forwardHost.proxy == null)
                    {
                        IPEndPoint        serverEndPoint = forwardHost.directEndPoint.GetOrResolveToIPEndPoint();
                        DirectUdpCallback udpCallback    = new DirectUdpCallback(serverEndPoint, 30 * 60); // 30 minutes
                        for (int i = 0; i < portSet.Length; i++)
                        {
                            Socket udpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                            udpSocket.Bind(new IPEndPoint(IPAddress.Any, portSet[i]));
                            selectControl.AddReceiveSocket(udpSocket, udpCallback.ReceiveHandler);
                        }
                    }
                    else
                    {
                        throw new NotImplementedException();

                        /*
                         * UdpThroughProxyCallback udpCallback = new UdpThroughProxyCallback(serverEndPoint, proxyConnector,
                         *  1000 * 60 * 4, 1000 * 60 * 10);
                         * for (int i = 0; i < portSet.Length; i++)
                         * {
                         *  udpListenerList.Add(new UdpSelectListener(new IPEndPoint(IPAddress.Any, portSet[i]), udpCallback));
                         * }
                         */
                    }
                }
            } while (arg < nonOptionArgs.Count);

            SelectServer selectServer = new SelectServer(selectControl, new Buf(8192));

            selectServer.Run();

            return(-1);
        }
Beispiel #10
0
        void HandleHeaders(ref SelectControl control, Socket sock, String headers)
        {
            if (headers.StartsWith("CONNECT"))
            {
                UInt16 serverPort;
                String serverString = ParseConnectLine(headers.Remove(headers.IndexOfAny(newlineSet)), out serverPort);
                if (serverString == null)
                {
                    return;
                }

                //
                // Make the forward connection
                //
                if (HttpToCtpLogger.logger != null)
                {
                    HttpToCtpLogger.logger.WriteLine("[{0}] CONNECT {1}:{2}", clientEndPointString, serverString, serverPort);
                }

                //
                // Create and connect the socket
                //
                IPEndPoint serverEndPoint = new IPEndPoint(EndPoints.ParseIPOrResolveHost(serverString, DnsPriority.IPv4ThenIPv6), serverPort);

                serverSocket = new Socket(serverEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                //if (HttpToCtp.proxySelector == null)
                //{
                //    serverSocket.Connect(serverEndPoint);
                //}
                //else
                //{
                //    HttpToCtp.proxySelector.Connect(serverSocket, serverEndPoint);
                //}
                serverSocket.Connect(serverEndPoint);

                //
                // Send positive connect response
                //
                sock.Send(HttpToCtp.ConnectionEstablishedAsBytes);
            }
            else
            {
                //
                // Find the host header
                //
                //Console.Write("Original Headers '{0}'", headers);
                Int32 hostIndex = headers.IndexOf(hostHeaderSearchString);
                if (hostIndex < 0)
                {
                    if (HttpToCtpLogger.errorLogger != null)
                    {
                        HttpToCtpLogger.errorLogger.WriteLine("[{0}] Missing Host header '{1}'", clientEndPointString, headers);
                    }
                    sock.ShutdownSafe();
                    control.DisposeAndRemoveReceiveSocket(sock);
                    return;
                }
                hostIndex += hostHeaderSearchString.Length;

                Console.WriteLine("[Debug] hostIndex: {0}, endIndex: {1}", hostIndex, headers.IndexOfAny(newlineSet, hostIndex));
                String hostHeaderValue = headers.Substring(hostIndex, headers.IndexOfAny(newlineSet, hostIndex) - hostIndex);

                //
                // Remove the Proxy-Connection header
                //
                Int32 proxyConnectionIndex = headers.IndexOf(proxyConnectionHeaderSearchString);
                if (proxyConnectionIndex > 0)
                {
                    headers = headers.Remove(proxyConnectionIndex + 1,
                                             headers.IndexOf('\n', proxyConnectionIndex + proxyConnectionHeaderSearchString.Length) -
                                             proxyConnectionIndex);
                }

                String serverString = hostHeaderValue;
                UInt16 serverPort   = 80;

                if (serverString.StartsWith("http://"))
                {
                    serverString = serverString.Substring("http://".Length);
                }
                else if (serverString.StartsWith("https://"))
                {
                    serverString = serverString.Substring("https://".Length); serverPort = 443;
                }

                //
                // Parse Optional Port
                //
                int lastColonIndex = serverString.IndexOf(':');
                if (lastColonIndex >= 0)
                {
                    String portString = serverString.Substring(lastColonIndex + 1);
                    serverString = serverString.Substring(0, lastColonIndex);
                    if (!UInt16.TryParse(portString, out serverPort))
                    {
                        if (HttpToCtpLogger.errorLogger != null)
                        {
                            HttpToCtpLogger.errorLogger.WriteLine(
                                "[{0}] The HTTP Host header value '{1}' contained an invalid string after the colon in the host value. Expected a port number but got '{2}'",
                                clientEndPointString, hostHeaderValue, portString);
                        }
                        sock.ShutdownSafe();
                        control.DisposeAndRemoveReceiveSocket(sock);
                        return;
                    }
                }

                //
                // Make the forward connection
                //
                if (HttpToCtpLogger.logger != null)
                {
                    HttpToCtpLogger.logger.WriteLine("[{0}] Proxy to '{1}' on port {2}", clientEndPointString, serverString, serverPort);
                }

                //
                // Create and connect the socket
                //
                IPEndPoint serverEndPoint = new IPEndPoint(EndPoints.ParseIPOrResolveHost(serverString, DnsPriority.IPv4ThenIPv6), serverPort);

                serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //if (HttpToCtp.proxySelector == null)
                //{
                //    serverSocket.Connect(serverEndPoint);
                //}
                //else
                //{
                //    HttpToCtp.proxySelector.Connect(serverSocket, serverEndPoint);
                //}
                serverSocket.Connect(serverEndPoint);

                //Console.Write("New Headers '{0}'", headers);
                serverSocket.Send(Encoding.UTF8.GetBytes(headers));
            }


            if (HttpToCtpLogger.logger != null)
            {
                HttpToCtpLogger.logger.WriteLine("[{0}] Adding Server Socket '{1}'", clientEndPointString, serverSocket.RemoteEndPoint);
            }
            control.UpdateHandler(sock, DataRecvHandler);
            control.AddReceiveSocket(serverSocket, DataRecvHandler);
        }
Beispiel #11
0
        void GotHeaders(ref SelectControl selectControl, Socket clientSocket, Byte[] headers, UInt32 totalLength)
        {
            String serverIPOrHost = null;
            UInt16 serverPort     = 0;

            try
            {
                serverIPOrHost = GetServerFromHeaders(out serverPort, out isConnect,
                                                      headers, ref headersLength, ref totalLength, clientLogString);
            }
            catch (Exception e)
            {
                if (AppLayerProxy.ErrorLogger != null)
                {
                    AppLayerProxy.ErrorLogger.WriteLine("{0} Failed to get server from HTTP Headers: {1}", clientLogString, e);
                }
            }

            if (serverIPOrHost == null)
            {
                selectControl.ShutdownDisposeAndRemoveReceiveSocket(clientSocket);
                return;
            }

            this.serverLogString = serverIPOrHost + ":" + serverPort.ToString();

            Boolean needToConnect;

            if (AppLayerProxy.ForwardProxy == null)
            {
                // TODO: Fix so this does not block during DNS resolution
                IPAddress serverIP;
                try
                {
                    serverIP = EndPoints.ParseIPOrResolveHost(serverIPOrHost, DnsPriority.IPv4ThenIPv6);
                }
                catch (SocketException)
                {
                    if (AppLayerProxy.ErrorLogger != null)
                    {
                        AppLayerProxy.ErrorLogger.WriteLine("{0} Failed to resolve server hostname '{1}'",
                                                            clientLogString, serverIPOrHost);
                    }
                    selectControl.ShutdownDisposeAndRemoveReceiveSocket(clientSocket);
                    return;
                }
                IPEndPoint serverEndPoint = new IPEndPoint(serverIP, serverPort);

                serverSocket          = new Socket(serverEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                serverSocket.Blocking = false;
                needToConnect         = NonBlockingSocket.ConnectNonBlocking(serverSocket, serverEndPoint);
            }
            else
            {
                this.serverEndPointForProxy = new StringEndPoint(serverIPOrHost, serverPort);

                Console.WriteLine("[DEBUG] Connecting to proxy '{0}'", AppLayerProxy.ForwardProxy.host.CreateTargetString());
                serverSocket          = new Socket(AppLayerProxy.ForwardProxy.host.GetAddressFamilyForTcp(), SocketType.Stream, ProtocolType.Tcp);
                serverSocket.Blocking = false;
                throw new NotImplementedException();
                //needToConnect = NonBlockingSocket.ConnectNonBlocking(serverSocket, AppLayerProxy.ForwardProxy.endPoint);
            }

            //Console.WriteLine("[DEBUG] {0} > {1} Connecting...", clientLogString, serverLogString);
            if (needToConnect)
            {
                selectControl.RemoveReceiveSocket(clientSocket); // Remove the clientSocket from the read list
                                                                 // until the connection gets established or lost
                selectControl.AddConnectSocket(serverSocket, ServerSocketConnected);

                // Save Data
                if (isConnect)
                {
                    if (totalLength == headersLength)
                    {
                        clientBuffer = null; // Clean up the client buffer (if there is one)
                    }
                }
                else
                {
                    if (clientBuffer == null)
                    {
                        clientBuffer = new ByteBuilder(totalLength);
                        Array.Copy(headers, clientBuffer.bytes, totalLength);
                        clientBuffer.contentLength = totalLength;
                    }
                    else
                    {
                        // Data already in the client buffer
                    }
                }
            }
            else
            {
                if (AppLayerProxy.Logger != null)
                {
                    AppLayerProxy.Logger.WriteLine("{0} > {1} Connection Completed Synchronously (CornerCase)", clientLogString, serverLogString);
                }

                if (!clientSocket.Connected)
                {
                    selectControl.DisposeAndRemoveReceiveSocket(clientSocket);
                    if (serverSocket.Connected)
                    {
                        if (AppLayerProxy.Logger != null)
                        {
                            AppLayerProxy.Logger.WriteLine("{0} > {1} Server Connected but Client Disconnected...Closing Server", clientLogString, serverLogString);
                        }
                        try { serverSocket.Shutdown(SocketShutdown.Both); }
                        catch (Exception) { }
                    }
                    else
                    {
                        if (AppLayerProxy.Logger != null)
                        {
                            AppLayerProxy.Logger.WriteLine("{0} > {1} Client disconnected before server could connect", clientLogString, serverLogString);
                        }
                    }
                    serverSocket.Close();
                }
                else if (!serverSocket.Connected)
                {
                    if (AppLayerProxy.Logger != null)
                    {
                        AppLayerProxy.Logger.WriteLine("{0} > {1} Failed to connect to server..Closing Client", clientLogString, serverLogString);
                    }
                    selectControl.ShutdownDisposeAndRemoveReceiveSocket(clientSocket);
                    serverSocket.Close();
                }
                else
                {
                    if (AppLayerProxy.Logger != null)
                    {
                        AppLayerProxy.Logger.WriteLine("{0} > {1} Connected to Server", clientLogString, serverLogString);
                    }

                    if (isConnect)
                    {
                        uint extraChars = totalLength - headersLength;
                        FinishConnection(headers, headersLength, extraChars);
                    }
                    else
                    {
                        FinishConnection(headers, 0, totalLength);
                    }

                    TcpBridge bridge = new TcpBridge(clientLogString, clientSocket, serverLogString, serverSocket);
                    selectControl.UpdateHandler(clientSocket, bridge.ReceiveHandler);
                    selectControl.AddReceiveSocket(serverSocket, bridge.ReceiveHandler);
                }
            }
        }
Beispiel #12
0
        void ServerSocketConnected(ref SelectControl selectControl, Socket serverSocket, Buf safeBuffer)
        {
            try
            {
                if (!clientSocket.Connected)
                {
                    clientSocket.Close(); // Should already removed from selectControl
                    if (!selectControl.ConnectionError && serverSocket.Connected)
                    {
                        if (AppLayerProxy.Logger != null)
                        {
                            AppLayerProxy.Logger.WriteLine("{0} > {1} Server Connected but Client Disconnected...Closing Server", clientLogString, serverLogString);
                        }
                        try { serverSocket.Shutdown(SocketShutdown.Both); }
                        catch (Exception) { }
                    }
                    else
                    {
                        if (AppLayerProxy.Logger != null)
                        {
                            AppLayerProxy.Logger.WriteLine("{0} > {1} Client disconnected before server could connect", clientLogString, serverLogString);
                        }
                    }
                    selectControl.DisposeAndRemoveConnectSocket(serverSocket);
                }
                else if (selectControl.ConnectionError)
                {
                    if (AppLayerProxy.Logger != null)
                    {
                        if (AppLayerProxy.ForwardProxy == null)
                        {
                            AppLayerProxy.Logger.WriteLine("{0} > {1} Failed to connect to server..Closing Client", clientLogString, serverLogString);
                        }
                        else
                        {
                            AppLayerProxy.Logger.WriteLine("{0} > {1} Failed to connect to proxy server '{2}'..Closing Client",
                                                           clientLogString, serverLogString, AppLayerProxy.ForwardProxy.host.CreateTargetString());
                        }
                    }
                    clientSocket.ShutdownAndDispose(); // Should already removed from selectControl
                    selectControl.DisposeAndRemoveConnectSocket(serverSocket);
                }
                else if (!serverSocket.Connected)
                {
                    // Ignore.  Only do something if we are connected or get a ConnectionError
                }
                else
                {
                    if (AppLayerProxy.Logger != null)
                    {
                        AppLayerProxy.Logger.WriteLine("{0} > {1} Connected to Server", clientLogString, serverLogString);
                    }

                    if (isConnect)
                    {
                        if (clientBuffer == null)
                        {
                            FinishConnection(null, 0, 0);
                        }
                        else
                        {
                            uint extraChars = clientBuffer.contentLength - headersLength;
                            FinishConnection(clientBuffer.bytes, headersLength, extraChars);
                        }
                    }
                    else
                    {
                        // A NonConnect will always have buffered data to send
                        FinishConnection(clientBuffer.bytes, 0, clientBuffer.contentLength);
                    }

                    TcpBridge bridge = new TcpBridge(clientLogString, clientSocket, serverLogString, serverSocket);
                    selectControl.AddReceiveSocket(clientSocket, bridge.ReceiveHandler);
                    selectControl.UpdateConnectorToReceiver(serverSocket, bridge.ReceiveHandler);
                }
            }
            catch (Exception e)
            {
                if (AppLayerProxy.ErrorLogger != null)
                {
                    AppLayerProxy.ErrorLogger.WriteLine("{0} > {1} Failed to finish connection: {2}", clientLogString, serverLogString, e.Message);
                }
                selectControl.ShutdownIfConnectedDisposeAndRemoveReceiveSocket(clientSocket);
                selectControl.ShutdownIfConnectedDisposeAndRemoveReceiveSocket(serverSocket);
                selectControl.DisposeAndRemoveConnectSocket(serverSocket);
            }
        }
Beispiel #13
0
            public void AcceptClientHandler(ref SelectControl control, Socket listenSocket, Buf safeBuffer)
            //(Socket listenSocket, Socket socket, Buf safeBuffer)
            {
                //return tmpConnectionManager.AcceptAndInitiateTunnel(this, socket, safeBuffer);

                Socket clientSocket = listenSocket.Accept();

                Console.WriteLine("{0} [{1}] Received tunnel connection for server '{2}' to connect to target '{3}:{4}'",
                                  DateTime.Now, clientSocket.SafeRemoteEndPointString(), serverName, targetHost, targetPort);

                //
                // Check if server is connected
                //
                TmpControlConnection tmpControlConnection = TryGetTmpControlConnection(serverName);

                if (tmpControlConnection == null)
                {
                    Console.WriteLine("{0} [{1}] Server '{2}' is not currently connected", DateTime.Now, clientSocket.SafeRemoteEndPointString(), serverName);
                    clientSocket.ShutdownAndDispose();
                    return;
                }

                //
                // Generate a tunnel key
                //
                Int32 randomKey = random.Next();

                //
                // TODO: This would generate an infinite loop if every single key was taken up in the dictionary,
                //       however, I'm not sure if I should worry about this or not? Maybe there's a better way to do
                //       this?
                //
                while (true)
                {
                    if (!incompleteTunnels.ContainsKey(randomKey))
                    {
                        break;
                    }
                    randomKey++;
                }

                DisconnectedTunnel disconnectedTunnel = new DisconnectedTunnel(clientSocket);

                incompleteTunnels.Add(randomKey, disconnectedTunnel);

                Byte[] tunnelKey = new Byte[4];
                tunnelKey[0] = (Byte)(randomKey >> 24);
                tunnelKey[1] = (Byte)(randomKey >> 16);
                tunnelKey[2] = (Byte)(randomKey >> 8);
                tunnelKey[3] = (Byte)(randomKey);

                //
                // Send Open Tunnel command to TmpServer
                //
                OpenAccessorTunnelRequest request = new OpenAccessorTunnelRequest(0,
                                                                                  targetHostBytes, targetPort, tunnelKey);
                UInt32 commandLength = Tmp.SerializeCommand <OpenAccessorTunnelRequest>(OpenAccessorTunnelRequest.Serializer,
                                                                                        Tmp.ToServerOpenAccessorTunnelRequestID, request, safeBuffer, 0);

                tmpControlConnection.dataSender.HandleData(safeBuffer.array, 0, commandLength);

                //
                // Create a diconnected tunnel handler
                //
                control.AddReceiveSocket(clientSocket, disconnectedTunnel.ConnectedSocketReceiveHandler);
            }