protected void OnConnectionAccepted(ForwardingConnection con) { if (ConnectionAccepted != null) { ConnectionAccepted(con); } }
private void con_ConnectionAborted(ConnectionData data, bool fromClient, Exception ex) { ForwardingConnection con = data.Connection; // This event can be raised multiple times (or the connection may already be closed), // therefore we need to to this check if (!data.IsAbortedOrClosed) { data.IsAbortedOrClosed = true; connectionCount--; RefreshConnectionCount(); string reason = Environment.NewLine + GetExceptionText(ex); string logStr = "Connection aborted from " + (fromClient ? "client" : "server") + " \u2013 Data Offset: 0x" + data.DataCountLocal.ToString("X") + ". Reason: " + reason; AddLogEntry(logClient, con.ConId, logStr); logStr = "Connection aborted from " + (fromClient ? "client" : "server") + " \u2013 Data Offset: 0x" + data.DataCountRemote.ToString("X") + ". Reason: " + reason; AddLogEntry(logServer, con.ConId, logStr); if (logDataToFile) { if (data.fileIncoming != null) { data.fileIncoming.Dispose(); } if (data.fileOutgoing != null) { data.fileOutgoing.Dispose(); } } } }
private void con_DataReceivedRemote(ConnectionData data, byte[] buf, int offset, int count) { ForwardingConnection con = data.Connection; if (!data.IsAbortedOrClosed) { if (checkLogDataEvents.IsChecked.Value) { AddLogEntry(logServer, con.ConId, "Data - Offset: 0x" + data.DataCountRemote.ToString("X") + ", Count: 0x" + count.ToString("X") + "."); } if (logDataContents && buf != null) { AddDataLog(logServer, buf, offset, count); } data.DataCountRemote += count; currentDLCount += count; if (logDataToFile) { data.fileOutgoing.Write(buf, offset, count); data.fileOutgoing.Flush(); } } }
private void con_DataForwardedRemote(ConnectionData data) { ForwardingConnection con = data.Connection; if (!data.IsAbortedOrClosed) { if (checkLogDataEvents.IsChecked.Value) { AddLogEntry(logServer, con.ConId, "Data forwarding completed."); } } }
private void con_RemoteConnectionEstablished(ConnectionData data, bool usedIpv6, IPEndPoint remoteLocalEndpoint, IPEndPoint remoteRemoteEndpoint) { ForwardingConnection con = data.Connection; AddLogEntry(logServer, con.ConId, "Remote connection established using IPv" + (usedIpv6 ? "6" : "4") + " from local endpoint \"" + remoteLocalEndpoint.ToString() + "\" to remote endpoint \"" + remoteRemoteEndpoint.ToString() + "\"." + (forwarder.RemoteSslHost != null ? "\r\nAuthenticating..." : "")); if (logDataToFile) { // Create new Filestream for outgoing connection. data.fileOutgoing = CreateDataLogFileStream(false, con.ConId); } }
private void con_LocalConnectionAuthenticated(ConnectionData data, System.Security.Authentication.SslProtocols protocol, System.Security.Authentication.CipherAlgorithmType cipherAlgorithmType, int cipherAlgorithmStrength, System.Security.Authentication.HashAlgorithmType hashAlgorithmType, int hashAlgorithmStrength, System.Security.Authentication.ExchangeAlgorithmType exchangeAlgorithmType, int exchangeAlgorithmStrength) { ForwardingConnection con = data.Connection; AddLogEntry(logClient, con.ConId, "Local connection authenticated. Protocol: " + protocol.ToString() + ", Cipher: " + cipherAlgorithmType.ToString() + " (" + cipherAlgorithmStrength + " Bit), " + "Hash: " + hashAlgorithmType.ToString() + " (" + hashAlgorithmStrength + " Bit), Exchange: " + exchangeAlgorithmType + " (" + exchangeAlgorithmStrength + " Bit)"); AddLogEntry(logServer, con.ConId, "Connecting..."); }
private void con_ConnectionClosedCompletely(ConnectionData data) { ForwardingConnection con = data.Connection; // Fully closed. // This event can be raised multiple times (or the connection may already be aborted by one thread), // therefore we need to to this check if (!data.IsAbortedOrClosed) { data.IsAbortedOrClosed = true; connectionCount--; RefreshConnectionCount(); } }
private void con_RemoteConnectionClosed(ConnectionData data) { ForwardingConnection con = data.Connection; if (!data.IsAbortedOrClosed) { int count = data.CloseCount++; AddLogEntry(logServer, con.ConId, "Remote connection closed (" + (count + 1) + ") \u2013 Data Offset: 0x" + data.DataCountRemote.ToString("X") + "."); if (logDataToFile) { data.fileOutgoing.Dispose(); } } }
private void con_LocalConnectionClosed(ConnectionData data) { ForwardingConnection con = data.Connection; if (!data.IsAbortedOrClosed) { int count = data.CloseCount++; AddLogEntry(logClient, con.ConId, "Local connection closed (" + (count + 1) + ") \u2013 Data Offset: 0x" + data.DataCountLocal.ToString("X") + "."); if (logDataToFile) { data.fileIncoming.Dispose(); } } }
private void con_RemoteConnectionAuthenticated(ConnectionData data, System.Security.Authentication.SslProtocols protocol, System.Security.Cryptography.X509Certificates.X509Certificate2 remoteCertificate, System.Security.Authentication.CipherAlgorithmType cipherAlgorithmType, int cipherAlgorithmStrength, System.Security.Authentication.HashAlgorithmType hashAlgorithmType, int hashAlgorithmStrength, System.Security.Authentication.ExchangeAlgorithmType exchangeAlgorithmType, int exchangeAlgorithmStrength) { ForwardingConnection con = data.Connection; AddLogEntry(logServer, con.ConId, "Remote connection authenticated. Protocol: " + protocol.ToString() + ", Cipher: " + cipherAlgorithmType.ToString() + " (" + cipherAlgorithmStrength + " Bit), " + "Hash: " + hashAlgorithmType.ToString() + " (" + hashAlgorithmStrength + " Bit), Exchange: " + exchangeAlgorithmType + " (" + exchangeAlgorithmStrength + " Bit)\r\n" + "Certiticate Subject: " + remoteCertificate.Subject + "\r\n" + "Certificate Issuer: " + remoteCertificate.Issuer + "\r\n" + "Valid: Not before " + new DateTimeOffset(remoteCertificate.NotBefore).ToString() + ", not after " + new DateTimeOffset(remoteCertificate.NotAfter).ToString() + "\r\n" + "Fingerprint: " + remoteCertificate.Thumbprint); }
private void forwarder_ConnectionAccepted(ConnectionData data) { ForwardingConnection con = data.Connection; connectionCount++; RefreshConnectionCount(); AddLogEntry(logClient, con.ConId, "Local connection established from remote endpoint \"" + con.LocalRemoteIPEndpoint.ToString() + "\" to local endpoint \"" + con.LocalLocalIPEndpoint.ToString() + "\"." + (forwarder.LocalSslCertificate != null ? "\r\nAuthenticating..." : "")); if (forwarder.LocalSslCertificate == null) { AddLogEntry(logServer, con.ConId, "Connecting..."); } if (logDataToFile) { // Create new Filestream for incoming connection. data.fileIncoming = CreateDataLogFileStream(true, con.ConId); } }
//internal void DeregisterConnection(ForwardingConnection con) { // lock (connections) { // connections.Remove(con.ConId); // } //} public async Task RunAsync() { // Ensure that exceptions thrown by listener.Start() are thrown in this thread // TODO: make the number of backlog queue configurable listener.Start(1000); while (true) { // Wait for the concurrent connections semaphore. await concurrentConnectionsSemaphore.WaitAsync(); TcpClient client; try { client = await listener.AcceptTcpClientAsync(); } catch (ObjectDisposedException ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); // Listener has been stopped. // Ignore return; } BigInteger conId = nextConId++; Func <SemaphoreSlim, Task> waitForSendingDelegate = sem => ConnectionWaitForSending(sem, true); Func <SemaphoreSlim, Task> waitForReceivingDelegate = sem => ConnectionWaitForSending(sem, false); IPAddress[] bindAndConnectAddresses = new IPAddress[2]; if (RemoteHost == "[localhost-random]") { for (int i = 0; i < bindAndConnectAddresses.Length; i++) { // Generate two random addresses in the range 127.0.0.1-127.255.255.254. // Bind to one of these addresses as local endpoint and use the other one for the remote endpoint. // This ensures that if a lot of connections are opened and closed in a very short time, that we do not // get errors that an address+port has been used multiple times when opening new connections (as the TCP/IP standard // defines that between consecutive connections using the same combination of a specific local endpoint (adr+port) and a specific remote endpoint (adr+port) // some time must pass, to minimize data corruption). // If we use random addresses in the above range we are minimizing the risk of using the same adr+port again in a short time interval. byte[] adr; adr = new byte[4]; adr[0] = 127; // TODO: Currently, for the last byte only numbers in the range 1-254 are generated although a address like // 127.2.3.255 would be OK (but 127.255.255-255 wouldn't). for (int x = 1; x < adr.Length; x++) { adr[x] = (byte)(localhostAddressRNG.Next(254 + (x != 3 ? 2 : 0)) + (x == 3 ? 1 : 0)); } bindAndConnectAddresses[i] = new IPAddress(adr); } } ForwardingConnection con = new ForwardingConnection(this, client, conId, bindAndConnectAddresses[0], bindAndConnectAddresses[1], waitForSendingDelegate, waitForReceivingDelegate, concurrentConnectionsSemaphore); //lock (connections) { // connections.Add(con.ConId, con); //} OnConnectionAccepted(con); // TODO maybe save the Task somewhere. Task t = ExceptionUtils.WrapTaskForHandlingUnhandledExceptions(async() => await con.Run()); } }