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