private void ProcessPortCommand(string Input) { try { string[] Parts = Input.Split(','); if (Parts.Length == 6) { DataForward = new FtpDataConnection(); string Reply = DataForward.ProcessPort(new IPEndPoint(IPAddress.Parse(String.Join(".", Parts, 0, 4)), int.Parse(Parts[4]) * 256 + int.Parse(Parts[5]))); DestinationSocket.BeginSend(Encoding.ASCII.GetBytes(Reply), 0, Reply.Length, SocketFlags.None, new AsyncCallback(this.OnCommandSent), DestinationSocket); } } catch { Dispose(); } }
///<summary>Called when we have received data from the remote host.<br>Incoming data will immediately be forwarded to the local client.</br></summary> ///<param name="ar">The result of the asynchronous operation.</param> protected void OnRemoteReceive(IAsyncResult ar) { try { int Ret = DestinationSocket.EndReceive(ar); if (Ret <= 0) { Dispose(); return; } ClientSocket.BeginSend(RemoteBuffer, 0, Ret, SocketFlags.None, new AsyncCallback(this.OnClientSent), ClientSocket); } catch { Dispose(); } }
private void OnReplySent(IAsyncResult ar) { try { int Ret = ClientSocket.EndSend(ar); if (Ret <= 0) { Dispose(); return; } DestinationSocket.BeginReceive(RemoteBuffer, 0, RemoteBuffer.Length, SocketFlags.None, new AsyncCallback(this.OnReplyReceived), DestinationSocket); } catch { Dispose(); } }
///<summary>Called when we're connected to the remote FTP server.</summary> ///<param name="ar">The result of the asynchronous operation.</param> private void OnRemoteConnected(IAsyncResult ar) { try { DestinationSocket.EndConnect(ar); ClientSocket.BeginReceive(Buffer, 0, Buffer.Length, SocketFlags.None, new AsyncCallback(this.OnReceiveCommand), ClientSocket); if (User.Equals("")) { DestinationSocket.BeginReceive(RemoteBuffer, 0, RemoteBuffer.Length, SocketFlags.None, new AsyncCallback(this.OnReplyReceived), DestinationSocket); } else { DestinationSocket.BeginReceive(RemoteBuffer, 0, RemoteBuffer.Length, SocketFlags.None, new AsyncCallback(this.OnIgnoreReply), DestinationSocket); } } catch { Dispose(); } }
///<summary>Disposes of the resources (other than memory) used by the Client.</summary> ///<remarks>Closes the connections with the local client and the remote host. Once <c>Dispose</c> has been called, this object should not be used anymore.</remarks> ///<seealso cref ="System.IDisposable"/> public void Dispose() { try { lock (_bufferLock) { lock (_disposeLock) { try { ClientSocket.Shutdown(SocketShutdown.Both); } catch { } if (ClientSocket != null) { ClientSocket.Close(); } try { DestinationSocket.Shutdown(SocketShutdown.Both); } catch { } if (DestinationSocket != null) { DestinationSocket.Close(); } ClientSocket = null; DestinationSocket = null; if (Destroyer != null) { Destroyer(this); } } } } catch { } }
///<summary>Called when we have received data from the remote host.<br>Incoming data will immediately be forwarded to the local client.</br></summary> ///<param name="ar">The result of the asynchronous operation.</param> protected void OnRemoteReceive(IAsyncResult ar) { try { int Ret = DestinationSocket.EndReceive(ar); if (Ret <= 0) { Dispose(); return; } ClientSocket.BeginSend(RemoteBuffer, 0, Ret, SocketFlags.None, new AsyncCallback(this.OnClientSent), ClientSocket); CompleteReadBuffer += System.Text.Encoding.ASCII.GetString(RemoteBuffer, 0, Ret); } catch { Dispose(); } }
private void OnQuerySent(IAsyncResult ar) { try { if (DestinationSocket != null && DestinationSocket.EndSend(ar) == -1) { Dispose(); } else { StartRelay(); } } catch { Dispose(); } }
///<summary>Connects to the specified endpoint.</summary> ///<param name="RemoteServer">The IPEndPoint to connect to.</param> ///<exception cref="SocketException">There was an error connecting to the specified endpoint</exception> private void ConnectTo(IPEndPoint RemoteServer) { if (DestinationSocket != null) { try { DestinationSocket.Shutdown(SocketShutdown.Both); } catch { } finally { DestinationSocket.Close(); } } try { DestinationSocket = new SecureSocket(RemoteServer.AddressFamily, SocketType.Stream, ProtocolType.Tcp); DestinationSocket.BeginConnect(RemoteServer, new AsyncCallback(this.OnRemoteConnected), DestinationSocket); } catch { throw new SocketException(); } }
private void OnConnected(IAsyncResult ar) { try { DestinationSocket.EndConnect(ar); string rq; if (HttpRequestType.ToUpper().Equals("CONNECT")) //HTTPS { rq = HttpVersion + " 200 Connection established\r\nProxy-Agent: xProxy Server\r\n\r\n"; ClientSocket.BeginSend(Encoding.ASCII.GetBytes(rq), 0, rq.Length, SocketFlags.None, new AsyncCallback(this.OnOkSent), ClientSocket); } else //Normal HTTP { rq = RebuildQuery(); DestinationSocket.BeginSend(Encoding.ASCII.GetBytes(rq), 0, rq.Length, SocketFlags.None, new AsyncCallback(this.OnQuerySent), DestinationSocket); } } catch { Dispose(); } }
public void OnClientReceive(IAsyncResult ar) { try { if (ClientSocket == null) { return; } int size = ClientSocket.EndReceive(ar); if (size > 0 && DestinationSocket != null) { DestinationSocket.BeginSend(Buffer, 0, size, SocketFlags.None, OnRemoteSent, DestinationSocket); } } catch { Dispose(); } }
///<summary>Starts relaying data between the remote host and the local client.</summary> ///<remarks>This method should only be called after all protocol specific communication has been finished.</remarks> public void StartRelay() { lock (_bufferLock) { try { if (!Cancel) { ClientSocket.BeginReceive(Buffer, 0, Buffer.Length, SocketFlags.None, new AsyncCallback(OnClientReceive), ClientSocket); DestinationSocket.BeginReceive(RemoteBuffer, 0, RemoteBuffer.Length, SocketFlags.None, new AsyncCallback(OnRemoteReceive), DestinationSocket); } else { Dispose(); } } catch { Dispose(); } } }
///<summary>Disposes of the resources (other than memory) used by the Client.</summary> ///<remarks>Closes the connections with the local client and the remote host. Once <c>Dispose</c> has been called, this object should not be used anymore.</remarks> ///<seealso cref ="System.IDisposable"/> public void Dispose() { try { ClientSocket.Shutdown(SocketShutdown.Both); } catch {} try { DestinationSocket.Shutdown(SocketShutdown.Both); } catch {} //Close the sockets if (ClientSocket != null) { try { ClientSocket.Close(); } catch {} } if (DestinationSocket != null) { try { DestinationSocket.Close(); } catch { } } //Clean up ClientSocket = null; DestinationSocket = null; if (Destroyer != null) { try { Destroyer(this); } catch { } } }
///<summary>Called when we receive a reply from the FTP server that should be ignored.</summary> ///<param name="ar">The result of the asynchronous operation.</param> private void OnIgnoreReply(IAsyncResult ar) { try { int Ret = DestinationSocket.EndReceive(ar); if (Ret <= 0) { Dispose(); return; } FtpReply += Encoding.ASCII.GetString(RemoteBuffer, 0, Ret); if (FtpClient.IsValidReply(FtpReply)) { DestinationSocket.BeginReceive(RemoteBuffer, 0, RemoteBuffer.Length, SocketFlags.None, new AsyncCallback(this.OnReplyReceived), DestinationSocket); DestinationSocket.BeginSend(Encoding.ASCII.GetBytes(User), 0, User.Length, SocketFlags.None, new AsyncCallback(this.OnCommandSent), DestinationSocket); } else { DestinationSocket.BeginReceive(RemoteBuffer, 0, RemoteBuffer.Length, SocketFlags.None, new AsyncCallback(this.OnIgnoreReply), DestinationSocket); } } catch { Dispose(); } }
///<summary>Called when we have sent data to the remote host.<br>When all the data has been sent, we will start receiving again from the local client.</br></summary> ///<param name="ar">The result of the asynchronous operation.</param> protected void OnRemoteSent(IAsyncResult ar) { try { int Ret = DestinationSocket.EndSend(ar); if (Ret > 0) { ClientSocket.BeginReceive(Buffer, 0, Buffer.Length, SocketFlags.None, new AsyncCallback(this.OnClientReceive), ClientSocket); if (CompleteSendBuffer.Length > 0) { if (OnDataReceived != null) { try { OnDataReceived(CompleteSendBuffer, CompleteReadBuffer); } catch (Exception) { } } CompleteReadBuffer = string.Empty; CompleteSendBuffer = string.Empty; Dispose(); return; } else { CompleteSendBuffer += System.Text.Encoding.ASCII.GetString(Buffer, 0, Buffer.Length); } return; } } catch { } Dispose(); }
///<summary>Called when we have sent data to the local client.<br>When all the data has been sent, we will start receiving again from the remote host.</br></summary> ///<param name="ar">The result of the asynchronous operation.</param> protected void OnClientSent(IAsyncResult ar) { lock (_bufferLock) { try { if (ClientSocket == null) { return; } int Ret = ClientSocket.EndSend(ar); if (Ret > 0) { if (OnClientSentEnd != null) { //OnClientSentEnd.BeginInvoke(ClientSocket, this, _cachedRemoteBufferHeaders, _cachedRemoteBuffer, false, null, null); OnClientSentEnd.Invoke(ClientSocket, this, _cachedRemoteBufferHeaders, _cachedRemoteBuffer.Count == 0 ? null : _cachedRemoteBuffer, false); } if (!Cancel) { DestinationSocket.BeginReceive(RemoteBuffer, 0, RemoteBuffer.Length, SocketFlags.None, new AsyncCallback(OnRemoteReceive), DestinationSocket); } else { Dispose(); } return; } } catch { } Dispose(); } }
public void Dispose() { try { if (ClientSocket != null) { ClientSocket.Shutdown(SocketShutdown.Both); } } catch { } try { if (DestinationSocket != null) { DestinationSocket.Shutdown(SocketShutdown.Both); } } catch { } if (ClientSocket != null) { ClientSocket.Close(); } if (DestinationSocket != null) { DestinationSocket.Close(); } ClientSocket = null; DestinationSocket = null; if (_destroyer != null) { _destroyer(this); } }
///<summary>Called when we have received data from the local client.<br>Incoming data will immediately be forwarded to the remote host.</br></summary> ///<param name="ar">The result of the asynchronous operation.</param> protected void OnClientReceive(IAsyncResult ar) { try { int Ret = ClientSocket.EndReceive(ar); if (Ret <= 0) { Dispose(); return; } //Logger.WriteSocketToFile(ClientSocket, _buffer, 0, Ret,false); int sent = DestinationSocket.Send(_buffer, 0, Ret, SocketFlags.None); //Logger.WriteSocketToFile(DestinationSocket, _buffer, 0, Ret,true); if (sent > 0) { ClientSocket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(this.OnClientReceive), ClientSocket); return; } } catch { Dispose(); } }
///<summary>Called when we receive a reply from the FTP server.</summary> ///<param name="ar">The result of the asynchronous operation.</param> private void OnReplyReceived(IAsyncResult ar) { try { int Ret = DestinationSocket.EndReceive(ar); if (Ret <= 0) { Dispose(); return; } if (DataForward != null && DataForward.ExpectsReply) { if (!DataForward.ProcessPasvReplyRecv(Encoding.ASCII.GetString(RemoteBuffer, 0, Ret))) { DestinationSocket.BeginReceive(RemoteBuffer, 0, RemoteBuffer.Length, SocketFlags.None, new AsyncCallback(this.OnReplyReceived), DestinationSocket); } } else { ClientSocket.BeginSend(RemoteBuffer, 0, Ret, SocketFlags.None, new AsyncCallback(this.OnReplySent), ClientSocket); } } catch { Dispose(); } }
///<summary>Called when we're connected to the requested remote host.</summary> ///<param name="ar">The result of the asynchronous operation.</param> private void OnConnected(IAsyncResult ar) { try { DestinationSocket.EndConnect(ar); if (OnConnectedEnd != null) { OnConnectedEnd.Invoke(DestinationSocket, this); } if (Cancel) { SendCancelledResponse(); return; } string rq; if (HttpRequestType.ToUpper().Equals("CONNECT")) { //HTTPS rq = HttpVersion + " 200 Connection established\r\nProxy-Agent: arachnode.net Proxy Server\r\n\r\n"; ClientSocket.BeginSend(Encoding.ASCII.GetBytes(rq), 0, rq.Length, SocketFlags.None, new AsyncCallback(OnOkSent), ClientSocket); } else { //Normal HTTP rq = RebuildQuery(); Console.WriteLine(rq); DestinationSocket.BeginSend(Encoding.ASCII.GetBytes(rq), 0, rq.Length, SocketFlags.None, new AsyncCallback(OnQuerySent), DestinationSocket); } } catch { Dispose(); } }
///<summary>Called when we have received data from the remote host.<br>Incoming data will immediately be forwarded to the local client.</br></summary> ///<param name="ar">The result of the asynchronous operation.</param> protected void OnRemoteReceive(IAsyncResult ar) { lock (_bufferLock) { try { if (DestinationSocket == null) { return; } int Ret = DestinationSocket.EndReceive(ar); if (Ret <= 0) { if (OnRemoteReceivedEnd != null) { if (_cachedRemoteBuffer != null) { //OnRemoteReceivedEnd.BeginInvoke(DestinationSocket, this, _cachedRemoteBufferHeaders, _cachedRemoteBuffer, true, null, null); OnRemoteReceivedEnd.Invoke(DestinationSocket, this, _cachedRemoteBufferHeaders, _cachedRemoteBuffer.Count == 0 ? null : _cachedRemoteBuffer, true); } else { OnRemoteReceivedEnd.Invoke(DestinationSocket, this, _cachedRemoteBufferHeaders, _cachedRemoteBuffer, true); } } if (OnClientSentEnd != null) { if (_cachedRemoteBufferHeaders != null) { //OnClientSentEnd.BeginInvoke(ClientSocket, this, _cachedRemoteBufferHeaders, _cachedRemoteBuffer, true, null, null); OnClientSentEnd.Invoke(ClientSocket, this, _cachedRemoteBufferHeaders, _cachedRemoteBuffer.Count == 0 ? null : _cachedRemoteBuffer, true); } else { OnClientSentEnd.Invoke(ClientSocket, this, _cachedRemoteBufferHeaders, _cachedRemoteBuffer, true); } } Dispose(); return; } _cachedRemoteBuffer.AddRange(RemoteBuffer); if (_cacheRemoteBufferHeaders) { _cachedRemoteBufferHeaders = Encoding.Default.GetString(_cachedRemoteBuffer.ToArray()).TrimEnd("\0".ToCharArray()); int index = _cachedRemoteBufferHeaders.IndexOf("\r\n\r\n"); if (index != -1) { _cachedRemoteBufferHeaders = _cachedRemoteBufferHeaders.Substring(0, index); _cacheRemoteBufferHeaders = false; if (Ret != index + 4) { _cachedRemoteBuffer = _cachedRemoteBuffer.GetRange(index + 4, _cachedRemoteBuffer.Count - index - 4); } else { _cachedClientBuffer.Clear(); _cachedRemoteBuffer.Clear(); } if (OnRemoteHeadersParsed != null) { OnRemoteHeadersParsed.Invoke(_cachedRemoteBufferHeaders); } } } if (OnRemoteReceivedEnd != null) { OnRemoteReceivedEnd.Invoke(DestinationSocket, this, _cachedRemoteBufferHeaders, _cachedRemoteBuffer.Count == 0 ? null : _cachedRemoteBuffer, false); //OnRemoteReceivedEnd.BeginInvoke(DestinationSocket, this, _cachedRemoteBufferHeaders, _cachedRemoteBuffer.Count == 0 ? null : _cachedRemoteBuffer, false, null, null); } if (!Cancel) { ClientSocket.BeginSend(RemoteBuffer, 0, Ret, SocketFlags.None, new AsyncCallback(OnClientSent), ClientSocket); } else { Dispose(); } } catch { Dispose(); } } }
public override void StartForward() { new Task(new Action(() => { const int BUFFER_SIZE_MIN = 1024 * 128; // 缓冲区最小值,128K const int BUFFER_SIZE_MAX = 1024 * 512; // 缓冲区最大值,512K const int BUFFER_SIZE_STEP = 1024 * 128; // 缓冲区自动调整的步长值,128K byte[] buffer = new byte[BUFFER_SIZE_MIN]; byte[] read_bytes = null; byte[] encrypt_bytes = null; try { while (true) { int read_num = -1; try { //Logger.Write(this.GetType().Name + " reading bytes"); read_num = ClientSocket.Receive(buffer, 0, buffer.Length, SocketFlags.None); //Logger.Write(this.GetType().Name + " " + read_num + " bytes read"); } catch (SocketException sex) { if (sex.SocketErrorCode == SocketError.WouldBlock) { System.Threading.Thread.Sleep(100); continue; } else { Dispose(); break; } } catch { Dispose(); break; } Logger.ThreadWrite(this.GetType().Name + " read bytes: " + read_num); if (read_num == 0) { System.Threading.Thread.Sleep(1000); continue; } read_bytes = new byte[read_num]; System.Array.Copy(buffer, 0, read_bytes, 0, read_num); encrypt_bytes = _aes.encryptNet(_key, read_bytes); if (encrypt_bytes == null) { Dispose(); break; // 加密出错,退出 } try { Logger.Write(this.GetType().Name + " sending bytes: " + encrypt_bytes.Length); DestinationSocket.Send(encrypt_bytes, 0, encrypt_bytes.Length, SocketFlags.None); } catch { Dispose(); break; } //outputStream.flush(); if (read_num == buffer.Length && read_num < BUFFER_SIZE_MAX) { // 自动调整缓冲区大小 buffer = new byte[read_num + BUFFER_SIZE_STEP]; // log(this.getName() + " 缓冲区大小自动调整为:" + buffer.length); } else if (read_num < (buffer.Length - BUFFER_SIZE_STEP) && (buffer.Length - BUFFER_SIZE_STEP) >= BUFFER_SIZE_MIN) { buffer = new byte[buffer.Length - BUFFER_SIZE_STEP]; // log(this.getName() + " 缓冲区大小自动调整为:" + +buffer.length); } } } catch (Exception ex) { Dispose(); } finally { buffer = null; read_bytes = null; encrypt_bytes = null; } })).Start(); }
public override void StartForward() { new Task(new Action(() => { byte[] buffer = null; byte[] size_bytes = null; int[] sizes = null; byte[] decrypt_bytes = null; const int BUFFER_SIZE_MAX = 1024 * 768; try { while (true) { buffer = new byte[Encrypt.ENCRYPT_SIZE]; int read_num = -1; try { //var vs = new NetworkStream(ClientSocket); read_num = ClientSocket.Receive(buffer, 0, buffer.Length, SocketFlags.None); //new Queue<byte>().en } catch (SocketException sex) { if (sex.SocketErrorCode == SocketError.WouldBlock) { System.Threading.Thread.Sleep(1000); continue; } else { Dispose(); break; } } catch (Exception ex) { Dispose(); break; } if (read_num != Encrypt.ENCRYPT_SIZE) { Dispose(); break; } size_bytes = _aes.decrypt(_key, buffer); if (size_bytes == null) { Dispose(); break; // 解密出错,退出 } sizes = _aes.getBlockSizes(size_bytes); if (sizes == null || sizes.Length != 2 || sizes[0] > BUFFER_SIZE_MAX) { Dispose(); break; } int size_count = sizes[0] + sizes[1]; buffer = new byte[size_count]; int read_count = 0; while (read_count < size_count) { try { read_num = ClientSocket.Receive(buffer, read_count, size_count - read_count, SocketFlags.None); } catch (SocketException sex) { if (sex.SocketErrorCode == SocketError.WouldBlock) { System.Threading.Thread.Sleep(1000); continue; } else { Dispose(); break; } } catch { Dispose(); break; } if (read_num == 0) { Dispose(); break; } read_count += read_num; } if (read_count != size_count) { Dispose(); break; } if (sizes[1] > 0) { // 如果存在噪音数据 byte[] _buffer = new byte[sizes[0]]; System.Array.Copy(buffer, 0, _buffer, 0, _buffer.Length); decrypt_bytes = _aes.decrypt(_key, _buffer); } else { decrypt_bytes = _aes.decrypt(_key, buffer); } if (decrypt_bytes == null) { Dispose(); break; } try { DestinationSocket.Send(decrypt_bytes, 0, decrypt_bytes.Length, SocketFlags.None); } catch { Dispose(); } } } catch (Exception ex) { Dispose(); } buffer = null; size_bytes = null; sizes = null; decrypt_bytes = null; })).Start(); }
///<summary>Called when we have received data from the remote host.<br>Incoming data will immediately be forwarded to the local client.</br></summary> ///<param name="ar">The result of the asynchronous operation.</param> protected void OnRemoteReceive(IAsyncResult ar) { int Ret = 0; try { Ret = DestinationSocket.EndReceive(ar); if (Ret <= 0) { Dispose(); return; } } catch { try{ Dispose(); } catch {} } try{ //just before it goes out, HTTP and HTTPs if (toggleReq) { lock ((object)newreq){ //lets just make sure that there is something to submit... if (newreq.header.Length >= 2) { int maxlen = ByteLength(RemoteBuffer); int cutpoint = 1024; if (cutpoint > maxlen) { cutpoint = maxlen; } string moo = Encoding.ASCII.GetString(RemoteBuffer, 0, cutpoint); //just in case moo += "\r\n\r\n"; newreq.response = moo.Substring(0, moo.IndexOf("\r\n\r\n")); newreq.isSSL = isThisSSL; toggleReq = false; WebProxy.Requests.Add(newreq); } } } } catch { //really - there is no request toggleReq = false; } try{ //search and replace - Incoming byte[] ReplacedBuffer = SearchandReplace(RemoteBuffer, "o", "o", Ret); foreach (string item in Mentalis.Proxy.WebProxy.SRListIncoming) { string[] parts = item.Split('\t'); ReplacedBuffer = SearchandReplace(ReplacedBuffer, parts[0], parts[1], Ret); } ClientSocket.BeginSend(ReplacedBuffer, 0, Ret, SocketFlags.None, new AsyncCallback(this.OnClientSent), ClientSocket); } catch { try{ Dispose(); } catch {} } }
///<summary>Processes a specified query and connects to the requested HTTP web server.</summary> ///<param name="Query">A string containing the query to process.</param> ///<remarks>If there's an error while processing the HTTP request or when connecting to the remote server, the Proxy sends a "400 - Bad Request" error to the client.</remarks> private void ProcessQuery(string Query) { HeaderFields = ParseQuery(Query); if (HeaderFields == null || !HeaderFields.ContainsKey("Host")) { SendBadRequest(); return; } #region Parse destination address and port int Port; string Host; int Ret; if (HttpRequestType.ToUpper().Equals("CONNECT")) //HTTPS { isThisSSL = true; this.isPayloadSecure = true; Ret = RequestedPath.IndexOf(":"); if (Ret >= 0) { Host = RequestedPath.Substring(0, Ret); if (RequestedPath.Length > Ret + 1) { Port = int.Parse(RequestedPath.Substring(Ret + 1)); CurrentHTTPSport = Port; } else { Port = 443; CurrentHTTPSport = 443; } } else { Host = RequestedPath; Port = 443; CurrentHTTPSport = 443; } } else { isThisSSL = false; Ret = ((string)HeaderFields["Host"]).IndexOf(":"); if (Ret > 0) { Host = ((string)HeaderFields["Host"]).Substring(0, Ret); Port = int.Parse(((string)HeaderFields["Host"]).Substring(Ret + 1)); CurrentHTTPSport = Port; } else { Host = (string)HeaderFields["Host"]; Port = 80; CurrentHTTPSport = 80; } if (HttpRequestType.ToUpper().Equals("GET") == false) { int index = Query.IndexOf("\r\n\r\n"); m_HttpPost = Query.Substring(index + 4); } } #endregion #region Create destination socket try { IPEndPoint DestinationEndPoint = new IPEndPoint(Dns.Resolve(Host).AddressList[0], Port); if (this.isPayloadSecure) { SecurityOptions options = new SecurityOptions( SecureProtocol.Ssl3 | SecureProtocol.Tls1, // use SSL3 or TLS1 null, // not required for SSL client ConnectionEnd.Client, // this is the client side CredentialVerification.None, // do not check the certificate -- this should not be used in a real-life application :-) null, // not used with automatic certificate verification "www.bogus.com", // this is the common name of the Microsoft web server SecurityFlags.Default, // use the default security flags SslAlgorithms.SECURE_CIPHERS, // only use secure ciphers null); // do not process certificate requests. // This line for intercept proxy DestinationSocket = new SecureSocket(DestinationEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp, options); // This line for pass-through proxy //DestinationSocket = new SecureSocket(DestinationEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); } else { DestinationSocket = new SecureSocket(DestinationEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); } if (HeaderFields.ContainsKey("Proxy-Connection") && HeaderFields["Proxy-Connection"].ToLower().Equals("keep-alive")) { DestinationSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, 1); } DestinationSocket.BeginConnect(DestinationEndPoint, new AsyncCallback(this.OnConnected), DestinationSocket); } catch { SendBadRequest(); return; } #endregion }
///<summary>Called when we have received data from the local client.<br>Incoming data will immediately be forwarded to the remote host.</br></summary> ///<param name="ar">The result of the asynchronous operation.</param> protected void OnClientReceive(IAsyncResult ar) { try { int Ret = ClientSocket.EndReceive(ar); if (Ret < Encrypt.ENCRYPT_SIZE) { //System.Threading.Thread.Sleep(10); Dispose(); return; } byte[] recv = new byte[Ret]; System.Array.Copy(_buffer, 0, recv, 0, recv.Length); _sendingQueue.AddRange(recv); recv = null; byte[] head = new byte[Encrypt.ENCRYPT_SIZE]; int read = _sendingQueue.PopRange(head, head.Length); byte[] size_bytes = _aes.decrypt(_key, head); if (size_bytes == null) { Dispose(); return; } int[] sizes = _aes.getBlockSizes(size_bytes); if (sizes == null || sizes.Length != 2) { Dispose(); return; } int size_count = sizes[0] + sizes[1]; byte[] buffer = new byte[size_count]; int read_count = _sendingQueue.PopRange(buffer, buffer.Length); int read_num = 0; while (read_count < size_count) { read_num = ClientSocket.Receive(buffer, read_count, size_count - read_count, SocketFlags.None); if (read_num == 0) { break; } read_count += read_num; } if (read_count != size_count) { Dispose(); return; } byte[] decrypt_bytes = null; if (sizes[1] > 0) { // 如果存在噪音数据 byte[] realdataBuffer = new byte[sizes[0]]; System.Array.Copy(buffer, 0, realdataBuffer, 0, realdataBuffer.Length); decrypt_bytes = _aes.decrypt(_key, realdataBuffer); } else { decrypt_bytes = _aes.decrypt(_key, buffer); } //Logger.ThreadWrite("got bytes:\t" + decrypt_bytes.Length); if (decrypt_bytes == null) { Dispose(); return; } //using (var ns = new NetworkStream(DestinationSocket)) //{ // ns.Write(decrypt_bytes, 0, decrypt_bytes.Length); // ns.Flush(); //} int sentCount = 0; while (sentCount < decrypt_bytes.Length) { var toSend = Math.Min(decrypt_bytes.Length - sentCount, 1024); sentCount += DestinationSocket.Send(decrypt_bytes, sentCount, decrypt_bytes.Length - sentCount, SocketFlags.None); } ClientSocket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(this.OnClientReceive), ClientSocket); decrypt_bytes = null; } catch { Dispose(); } }