public void InitialReceiveHandler(ref SelectControl selectControl, Socket clientSocket, Buf safeBuffer) { int bytesReceived = clientSocket.Receive(safeBuffer.array); if (bytesReceived <= 0) { if (AppLayerProxy.Logger != null) { AppLayerProxy.Logger.WriteLine("{0} Closed (no data received)", clientLogString); } selectControl.DisposeAndRemoveReceiveSocket(clientSocket); return; } if (!CheckForEndOfHeadersAndHandle(ref selectControl, clientSocket, safeBuffer.array, 0, (uint)bytesReceived)) { if (AppLayerProxy.Logger != null) { AppLayerProxy.Logger.WriteLine("{0} Initial socket receive did not contain all headers. Need to copy partial header to a new buffer.", clientLogString); } clientBuffer = new ByteBuilder(InitialClientBufferLength + ((bytesReceived > InitialClientBufferLength) ? (uint)bytesReceived : 0)); Array.Copy(safeBuffer.array, clientBuffer.bytes, bytesReceived); clientBuffer.contentLength = (uint)bytesReceived; selectControl.UpdateHandler(clientSocket, HeaderBuilderHandler); } }
public void CompleteTunnel(ref SelectControl selectControl, Socket socket) { lock (connectedSocket) { if (connectedTunnel != null) { throw new InvalidOperationException("CodeBug: This tunnel has already been completed"); } // // Send all the buffered data // if (bufferLength > 0) { try { socket.Send(buffer.array, 0, bufferLength, SocketFlags.None); } catch (Exception) { selectControl.ShutdownDisposeAndRemoveReceiveSocket(connectedSocket); selectControl.ShutdownDisposeAndRemoveReceiveSocket(socket); return; } } connectedTunnel = new ConnectedTunnel(connectedSocket, socket); selectControl.UpdateHandler(socket, connectedTunnel.BToAHandler); } }
public void ConnectedSocketReceiveHandler(ref SelectControl selectControl, Socket socket, Buf safeBuffer) { // // Check if the connection has been made // if (this.connectedTunnel != null) { selectControl.UpdateHandler(socket, this.connectedTunnel.AToBHandler); this.connectedTunnel.AToBHandler(ref selectControl, socket, safeBuffer); return; } // // Put the data into the byte buffer // if (buffer == null) { buffer = new Buf(256, 256); bufferLength = 0; } else { buffer.EnsureCapacityCopyData(bufferLength + 256); } // // Receive the data into the buffer // Int32 bytesRead = socket.Receive(buffer.array, bufferLength, buffer.array.Length - bufferLength, SocketFlags.None); if (bytesRead > 0) { bufferLength += bytesRead; } else { Dispose(ref selectControl); } }
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); }
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); } } }
/* * public SimpleSelectHandler HandleConnectionFromTmpServer(Socket listenSocket, Socket socket, Buf safeBuffer) * { * Console.WriteLine("{0} [{1}] Accepted TmpServer Socket", DateTime.Now, socket.SafeRemoteEndPointString()); * return HandleInitialConnectionInfo; * } */ static void HandleInitialConnectionInfo(ref SelectControl selectControl, Socket socket, Buf safeBuffer) { Int32 bytesRead = socket.Receive(safeBuffer.array, 1, SocketFlags.None); if (bytesRead <= 0) { Console.WriteLine("{0} WARNING: Socket closed", DateTime.Now); selectControl.DisposeAndRemoveReceiveSocket(socket); return; } Byte connectionInfo = safeBuffer.array[0]; Boolean accessorRequiresTls, isTunnel; Tmp.ReadConnectionInfoFromTmpServer(connectionInfo, out accessorRequiresTls, out isTunnel); // // Determine if TLS should be set up // Boolean setupTls; if (accessorRequiresTls) { setupTls = true; } else if (!isTunnel) { // The TmpServer is waiting for a response to indicate whether it should setup TLS setupTls = GlobalTlsSettings.requireTlsForTmpConnections; socket.Send(new Byte[] { setupTls ? (Byte)1 : (Byte)0 }); } else { setupTls = false; } IDataHandler sendDataHandler = new SocketSendDataHandler(socket); IDataFilter receiveDataFilter = null; // // Setup TLS if necessary // if (setupTls) { // // Negotiate TLS, setup sendDataHandler and receiveDataFilter // Console.WriteLine("{0} [{1}] This connection requires tls but it is not currently supported", DateTime.Now, socket.SafeRemoteEndPointString()); selectControl.ShutdownDisposeAndRemoveReceiveSocket(socket); return; } IPEndPoint remoteEndPoint = (IPEndPoint)(socket.RemoteEndPoint); if (isTunnel) { Console.WriteLine("{0} [{1}] Is a Tunnel Connection", DateTime.Now, remoteEndPoint.ToString()); TmpServerSideTunnelKeyReceiver keyReceiver = new TmpServerSideTunnelKeyReceiver(); selectControl.UpdateHandler(socket, keyReceiver.SocketReceiverHandler); } else { Console.WriteLine("{0} [{1}] Is a Control Connection", DateTime.Now, remoteEndPoint.ToString()); TmpControlConnection tmpControlConnection = new TmpControlConnection(GlobalTlsSettings, remoteEndPoint, socket, sendDataHandler, receiveDataFilter); tmpControlConnections.Add(tmpControlConnection); selectControl.UpdateHandler(socket, tmpControlConnection.SocketReceiverHandler); } }