internal void ClientDisconnected(ProxyClient client) { lock (this.routingClients) for (int i = 0; i < this.routingClients.Count; i++) { if (this.routingClients[i].ParentClient == null || this.routingClients[i].ParentClient.Equals(client)) { this.routingClients.RemoveAt(i); i--; } } lock (this.ConnectedClients) if (this.ConnectedClients.Contains(client)) { this.ConnectedClients.Remove(client); } }
/// <summary> /// Render the error message on the specified Proxy Client /// </summary> /// <param name="client"> /// The client. /// </param> /// <param name="title"> /// The title. /// </param> /// <param name="message"> /// The message. /// </param> /// <param name="code"> /// The HTTP code. /// </param> /// <param name="sslStream"> /// The SSL stream if any. /// </param> /// <returns> /// <see cref="bool" /> showing if the process ended successfully. /// </returns> public bool RenderError( ProxyClient client, string title, string message, HttpHeaderCode code = HttpHeaderCode.C500ServerError, SslStream sslStream = null) { try { if (client.RequestAddress == string.Empty) { return(false); } Uri url; if (!Uri.TryCreate(client.RequestAddress, UriKind.Absolute, out url)) { return(false); } bool https = false; if (url.Scheme.Equals("HTTP", StringComparison.OrdinalIgnoreCase)) { if (!this.EnableOnHttp) { return(false); } } else if (url.Scheme.Equals("HTTPS", StringComparison.OrdinalIgnoreCase) || url.Scheme.Equals("SOCKS", StringComparison.OrdinalIgnoreCase)) { if (!((this.EnableOnPort80 && url.Port == 80) || (this.EnableOnPort443 && url.Port == 443))) { return(false); } https = url.Port == 443; } else { return(false); } if (client.IsReceivingStarted || !client.IsSendingStarted) { return(false); } string html = Resources.HTTPErrorTemplate; html = html.Replace("%VERSION", Assembly.GetEntryAssembly().GetName().Version.ToString()); html = html.Replace("%TITLE", title); html = html.Replace("%MESSAGE", Common.ConvertToHtmlEntities(message)); string conString = "Not Connected"; if (client.Controller.ActiveServer != null) { conString = client.Controller.ActiveServer.ToString(); } List <string> args = new List <string>(); if (client.Controller.SmartPear.ForwarderHttpEnable) { args.Add("P:HTTP"); } if (client.Controller.SmartPear.ForwarderHttpsEnable) { args.Add("P:HTTPS"); } if (client.Controller.SmartPear.ForwarderSocksEnable && client.Controller.SmartPear.ForwarderHttpsEnable) { args.Add("P:SOCKS"); } if (args.Count > 0) { conString = args.Aggregate(conString + " (", (current, arg) => current + (" " + arg + "; ")) + ")"; } html = html.Replace("%CONSTRING", conString); string statusCode; switch (code) { case HttpHeaderCode.C200Ok: statusCode = "200 OK"; break; case HttpHeaderCode.C501NotImplemented: statusCode = "501 Not Implemented"; break; case HttpHeaderCode.C502BadGateway: statusCode = "502 Bad Gateway"; break; case HttpHeaderCode.C504GatewayTimeout: statusCode = "504 Gateway Timeout"; break; case HttpHeaderCode.C417ExpectationFailed: statusCode = "417 Expectation Failed"; break; case HttpHeaderCode.C404NotFound: statusCode = "404 Not Found"; break; default: statusCode = "500 Internal Server Error"; break; } const string NewLineSep = "\r\n"; string header = "HTTP/1.1 " + statusCode + NewLineSep + "Server: PeaRoxy Error Renderer" + NewLineSep + "Content-Length: " + html.Length + NewLineSep + "Connection: close" + NewLineSep + "Content-Type: text/html;" + NewLineSep + NewLineSep; byte[] db = Encoding.ASCII.GetBytes(header + html); if (!Common.IsSocketConnected(client.UnderlyingSocket)) { return(false); } if (https) { string certAddress = url.DnsSafeHost; if (!Common.IsIpAddress(certAddress)) { if (string.IsNullOrEmpty(certAddress)) { return(false); } } certAddress = GetCertForDomain(certAddress); if (string.IsNullOrEmpty(certAddress)) { return(false); } try { X509Certificate certificate = new X509Certificate2(certAddress, string.Empty); if (sslStream == null) { client.UnderlyingSocket.Blocking = true; Stream stream = new NetworkStream(client.UnderlyingSocket); sslStream = new SslStream(stream) { ReadTimeout = 30 * 1000, WriteTimeout = 30 * 1000 }; sslStream.AuthenticateAsServer(certificate); } sslStream.BeginWrite( db, 0, db.Length, delegate(IAsyncResult ar) { try { sslStream.EndWrite(ar); sslStream.Flush(); sslStream.Close(); client.UnderlyingSocket.Close(); } catch (Exception) { } }, null); } catch { } } else { client.UnderlyingSocket.BeginSend( db, 0, db.Length, SocketFlags.None, delegate(IAsyncResult ar) { try { client.UnderlyingSocket.EndSend(ar); client.UnderlyingSocket.Close(); } catch (Exception) { } }, null); } return(true); } catch (Exception e) { ProxyController.LogIt(e.Message + " - " + e.StackTrace); } return(false); }
internal void Accepting() { try { if (this.DnsResolverSupported && this.dnsTcpListenerSocket.Poll(0, SelectMode.SelectRead)) { ProxyClient c = new ProxyClient(this.dnsTcpListenerSocket.Accept(), this.parent) { ReceivePacketSize = this.parent .ReceivePacketSize, SendPacketSize = this.parent .SendPacketSize, NoDataTimeOut = 10, RequestType = ProxyClient .RequestTypes .Dns, IsSendingStarted = true, }; lock (this.parent.ConnectedClients) this.parent.ConnectedClients.Add(c); this.parent.ActiveServer.Clone().Establish(this.DnsResolverServerIp.ToString(), 53, c); } if (this.DnsResolverSupported && this.DnsResolverUdpSupported) { if (this.dnsUdpListenerSocket == null) { this.dnsUdpListenerSocket = new Socket( AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp) { EnableBroadcast = true }; this.dnsUdpListenerSocket.Bind(this.localDnsIp); } try { if (this.dnsUdpListenerSocket.Poll(0, SelectMode.SelectRead)) { byte[] globalBuffer = new byte[500]; EndPoint remoteEp = new IPEndPoint(IPAddress.Any, 0); int i = this.dnsUdpListenerSocket.ReceiveFrom(globalBuffer, ref remoteEp); byte[] buffer = new byte[i + 2]; Array.Copy(globalBuffer, 0, buffer, 2, i); Task.Factory.StartNew( delegate { try { buffer[0] = (byte)Math.Floor((double)i / 256); buffer[1] = (byte)(i % 256); IPAddress ip = this.parent.Ip; // Connecting to our self on same port, But TCP if (ip.Equals(IPAddress.Any)) { ip = IPAddress.Loopback; } Socket tcpLinkForUdp = new Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); tcpLinkForUdp.Connect(ip, 53); tcpLinkForUdp.Send(buffer); buffer = new byte[tcpLinkForUdp.ReceiveBufferSize]; i = tcpLinkForUdp.Receive(buffer); if (i != 0) { int neededBytes = (buffer[0] * 256) + buffer[1] + 2; Array.Resize(ref buffer, Math.Max(i, neededBytes)); if (i < neededBytes) { int timeout = Environment.TickCount + 2000; int received = i; while (received < neededBytes && timeout > Environment.TickCount && Common.IsSocketConnected(tcpLinkForUdp)) { i = tcpLinkForUdp.Receive( buffer, received, buffer.Length - received, SocketFlags.None); received += i; if (i == 0) { break; } Thread.Sleep(16); } } } this.dnsUdpListenerSocket.SendTo( buffer, 2, buffer.Length - 2, SocketFlags.None, remoteEp); } catch (Exception e) { ProxyController.LogIt("DNS Resolver UDP Error: " + e.Message); } }); } } catch (Exception) { this.dnsUdpListenerSocket.Close(); this.dnsUdpListenerSocket = null; } } } catch { } }