Example #1
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);
        }
Example #2
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);
                }
            }
        }
Example #3
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);
            }
        }