public void DataCallback(ref SelectControl control, Socket socket, Buf safeBuffer) { int bytesReceived; try { bytesReceived = socket.Receive(safeBuffer.array); } catch (SocketException) { bytesReceived = -1; } if (bytesReceived <= 0) { socket.ShutdownSafe(); control.DisposeAndRemoveReceiveSocket(socket); } lineParser.Add(safeBuffer.array, 0, (uint)bytesReceived); while (true) { String line = lineParser.GetLine(); if (line == null) { break; } if (line[0] == 'd' || line[0] == 'D') { if (NfsServerLog.performanceLog == null) { writer.Write("Cannot dump performance log because it was not enabled"); } else { NfsServerLog.performanceLog.DumpLog(writer); } } else if (line[0] == 'h' || line[0] == 'H') { writer.WriteLine("Commands: dump, help"); } else if (line[0] == 'e' || line[0] == 'E') { socket.ShutdownSafe(); control.DisposeAndRemoveReceiveSocket(socket); } else { writer.WriteLine("UnknownCommand '{0}'", line); writer.WriteLine("Commands: dump, help, exit"); } SendPrompt(); } }
public void ReceiveHandler(ref SelectControl selectControl, Socket socket, Buf safeBuffer) { try { int bytesReceived = socket.Receive(safeBuffer.array); if (bytesReceived <= 0) { if (socket == client) { if (AppLayerProxy.Logger != null) { AppLayerProxy.Logger.WriteLine("{0} > {1} Client Disconnected", clientLogString, serverLogString); } selectControl.DisposeAndRemoveReceiveSocket(client); selectControl.ShutdownIfConnectedDisposeAndRemoveReceiveSocket(server); } else { if (AppLayerProxy.Logger != null) { AppLayerProxy.Logger.WriteLine("{0} > {1} Server Disconnected", clientLogString, serverLogString); } selectControl.DisposeAndRemoveReceiveSocket(server); selectControl.ShutdownIfConnectedDisposeAndRemoveReceiveSocket(client); } } else { if (socket == client) { if (AppLayerProxy.Logger != null) { AppLayerProxy.Logger.WriteLine("{0} > {1} {2} bytes", clientLogString, serverLogString, bytesReceived); } server.Send(safeBuffer.array, bytesReceived, SocketFlags.None); } else { if (AppLayerProxy.Logger != null) { AppLayerProxy.Logger.WriteLine("{0} < {1} {2} bytes", clientLogString, serverLogString, bytesReceived); } client.Send(safeBuffer.array, bytesReceived, SocketFlags.None); } } } catch (Exception) { selectControl.ShutdownIfConnectedDisposeAndRemoveReceiveSocket(client); selectControl.ShutdownIfConnectedDisposeAndRemoveReceiveSocket(server); } }
public void DataRecvHandler(ref SelectControl control, Socket sock, Buf safeBuffer) { Socket otherSocket = (sock == serverSocket) ? clientSocket : serverSocket; int bytesReceived = sock.ReceiveNoThrow(safeBuffer.array, 0, safeBuffer.array.Length, SocketFlags.None); if (bytesReceived <= 0) { if (otherSocket != null) { otherSocket.ShutdownSafe(); } control.RemoveReceiveSocket(sock); return; } if (otherSocket != null) { try { otherSocket.Send(safeBuffer.array, bytesReceived, SocketFlags.None); return; } catch (SocketException) { sock.ShutdownSafe(); control.DisposeAndRemoveReceiveSocket(sock); } } }
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 SocketReceiverHandler(ref SelectControl selectControl, Socket socket, Buf safeBuffer) { Int32 bytesRead; if (receivedKey == null) { bytesRead = socket.Receive(safeBuffer.array, 1, SocketFlags.None); if (bytesRead <= 0) { CloseHandler(); selectControl.DisposeAndRemoveReceiveSocket(socket); return; } receivedKey = new Byte[safeBuffer.array[0]]; receivedLength = 0; if (socket.Available <= 0) { return; } } if (receivedLength >= receivedKey.Length) { throw new InvalidOperationException("CodeBug: This SocketReceiveHandler should have been set to something else after the receivedKey was completely received"); } bytesRead = socket.Receive(receivedKey, receivedLength, receivedKey.Length - receivedLength, SocketFlags.None); if (bytesRead <= 0) { CloseHandler(); selectControl.DisposeAndRemoveReceiveSocket(socket); return; } receivedLength += (Byte)bytesRead; if (receivedLength >= receivedKey.Length) { TmpAccessorServer.ReceivedTunnelKey(ref selectControl, socket, receivedKey); } }
public void TcpRecvHandler(ref SelectControl control, Socket sock, Buf safeBuffer) { int bytesReceived = sock.ReceiveNoThrow(safeBuffer.array, 0, safeBuffer.array.Length, SocketFlags.None); if (bytesReceived <= 0) { if (serverSocket != null) { serverSocket.ShutdownSafe(); } control.RemoveReceiveSocket(sock); return; } if (serverSocket != null) { try { serverSocket.Send(safeBuffer.array, bytesReceived, SocketFlags.None); return; } catch (SocketException) { sock.ShutdownSafe(); control.DisposeAndRemoveReceiveSocket(sock); return; } } httpHeaderBuilders.Append(Encoding.ASCII.GetString(safeBuffer.array, 0, bytesReceived)); // // Check if you have received all the headers // Int32 totalLength = httpHeaderBuilders.Length; if (totalLength > 3) { if ( httpHeaderBuilders[totalLength - 1] == '\n' && ( (httpHeaderBuilders[totalLength - 2] == '\n') || (httpHeaderBuilders[totalLength - 2] == '\r' && httpHeaderBuilders[totalLength - 3] == '\n' && httpHeaderBuilders[totalLength - 4] == '\r')) ) { String headers = httpHeaderBuilders.ToString(); httpHeaderBuilders = null; HandleHeaders(ref control, sock, headers); } } }
public void ReceiveCallback(ref SelectControl control, Socket sock, Buf safeBuffer) { Socket other = (sock == a) ? b : a; int bytesReceived; try { bytesReceived = sock.Receive(safeBuffer.array); } catch (SocketException) { bytesReceived = -1; } if (bytesReceived <= 0) { other.ShutdownSafe(); control.DisposeAndRemoveReceiveSocket(sock); } else { try { other.Send(safeBuffer.array, bytesReceived, SocketFlags.None); if (pcapLogger != null) { //pcapLogger.Log(safeBuffer.array, 0, (uint)bytesReceived); } } catch (SocketException) { sock.ShutdownSafe(); control.DisposeAndRemoveReceiveSocket(sock); } } }
// Handler that receives data if all the headers were not in the initial receive void HeaderBuilderHandler(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 ({1} bytes received but did not finish HTTP headers)", clientLogString, clientBuffer.contentLength); } selectControl.DisposeAndRemoveReceiveSocket(clientSocket); return; } clientBuffer.Append(safeBuffer.array, 0, (uint)bytesReceived); CheckForEndOfHeadersAndHandle(ref selectControl, clientSocket, clientBuffer.bytes, 0, clientBuffer.contentLength); }
public void HandleData(ref SelectControl control, Socket sock, Buf safeBuffer) { int bytesReceived; try { bytesReceived = sock.Receive(safeBuffer.array); } catch (SocketException) { bytesReceived = -1; } if (bytesReceived <= 0) { sock.ShutdownSafe(); control.DisposeAndRemoveReceiveSocket(sock); return; } recordBuilder.HandleData(socket, safeBuffer.array, 0, (uint)bytesReceived); }
/* * public void SendCommand(Byte commandID, IReflector reflector, Object command, ByteBuffer sendBuffer) * { * Tmp.SerializeCommand( * Byte[] packet = Tmp.CreateCommandPacket(commandID, reflector, command, 0); * dataSender.HandleData(packet, 0, packet.Length); * } */ /* * void HandleHeartbeat() * { * Console.WriteLine("{0} [{1}] [TmpControl] Got heartbeat", DateTime.Now, remoteEndPoint); * } */ public void SocketReceiverHandler(ref SelectControl selectControl, Socket socket, Buf safeBuffer) { Int32 bytesRead = socket.Receive(safeBuffer.array); if (bytesRead <= 0) { selectControl.DisposeAndRemoveReceiveSocket(socket); Dispose(); return; } //Console.WriteLine("{0} [{1}] [Debug] Got {2} Bytes: {3}", DateTime.Now, remoteEndPoint, bytesRead, safeBuffer.array.ToHexString(0, bytesRead)); if (receiveDataFilter == null) { frameProtocolReceiveHandler.HandleData(safeBuffer.array, 0, (UInt32)bytesRead); } else { receiveDataFilter.FilterTo(frameProtocolReceiveHandler.HandleData, safeBuffer.array, 0, (UInt32)bytesRead); } }
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); } }