public void ParsePack(byte[] bPack) { switch (this.Phase) { case Socks5Request.Socks5Phase.spGreeting: if (bPack[0] != 5) { throw new ProxyAuthException(403, "Only Socks5 response are supported"); } if (bPack[1] == 0xFF) { throw new ProxyAuthException(0xFF, "Authentication method not supported"); } if (this.Anonymous = bPack[1] == 0) { this.Phase = Socks5Request.Socks5Phase.spConnecting; } else { this.Phase = Socks5Request.Socks5Phase.spAuthenticating; } break; case Socks5Request.Socks5Phase.spAuthenticating: if (bPack[0] != 1) { throw new ProxyAuthException(403, "Only Socks5 response are supported"); } this.Phase = Socks5Request.Socks5Phase.spConnecting; this.Status = (ResponseStatus)bPack[1]; if (this.Status != ResponseStatus.Success) { throw new ProxyAuthException((int)this.Status, this.Status.ToDescription()); } break; case Socks5Request.Socks5Phase.spConnecting: if (bPack[0] != 5) { throw new ProxyAuthException(403, "Only Socks5 response are supported"); } int offset = 4; IPEndPoint ipe; Socks4Request.PackOut(bPack, ref offset, out ipe); this.RemoteEndPoint = ipe; break; } }
public void ParsePack(byte[] bPack) { if (bPack[0] != 0x00) { throw new ProxyAuthException(403, "Only Socks4/4a response are supported"); } var response = this; response.Status = (ResponseStatus)bPack[1]; int offset = 2; IPEndPoint ipe; Socks4Request.PackOut(bPack, ref offset, out ipe, false); response.RemoteEndPoint = ipe; if (response.Status != Socks4Response.ResponseStatus.RequestGranted) { throw new ProxyAuthException((int)response.Status, response.Status.ToDescription()); } }
private void UdpDirectReceive(object state) { var controlClient = (TcpClient)state; if (!controlClient.Connected) { return; } IPEndPoint remoteIpe = null; try { var currentState = this.GetUdpClientState(controlClient); //Udp无连接先发送后接收 currentState.WaitOnce(); var tunnel = this.CreateTunnel(TunnelCommand.UdpReceive, controlClient); tunnel.SendReceiveTimeout = Timeout.Infinite; var response = tunnel.GetResponse(webResponse => { var pushStream = webResponse.GetResponseStream(); byte[] data = new byte[(int)BufferSizeof.MaxSocket]; //00 00 00 01 data[3] = 1; while (controlClient.Connected && pushStream.CanRead) { try { int offset = 4; int read = pushStream.Read(data, offset, data.Length - offset); if (read == 0 || !(controlClient.Connected && pushStream.CanRead)) { break; } //4-10 中间6字节为remoteIpe Socks4Request.PackOut(data, ref offset, out remoteIpe); if (!currentState.HasRemoteEndPoint(remoteIpe)) { this.OutWrite("Udp Receive Discard {0} {1}bytes.", remoteIpe, read); App.LogInfo("Udp Receive Discard 非法远程端点."); continue; } int length = 4 + read; int sent = currentState.Client.Send(data, length, currentState.LocalEndPoint); if (length != sent) { throw new InvalidOperationException("Udp数据包错误"); } this.OutWrite("Udp {0} Receive {1}\t{2}bytes.", currentState.LocalEndPoint, remoteIpe, read); } catch (ObjectDisposedException ex) { #if DEBUG App.LogInfo(string.Format("Predictable objectDisposed exception: {0}", ex.StackTrace)); #endif return; } catch (IOException ex) { TunnelExceptionHandler.Handle(ex, controlClient.Client, string.Format("UdpDirectReceive={0}", remoteIpe)); } catch (SocketException ex) { TunnelExceptionHandler.Handle(ex, controlClient.Client, string.Format("UdpDirectReceive={0}", remoteIpe)); } } }); response.Close(); } catch (WebException ex) { bool isRejected; TunnelExceptionHandler.Handle(ex, string.Format("UdpDirectReceive={0}", remoteIpe), _output, out isRejected); if (isRejected) { this.OnServerRejected(); } } catch (Exception ex) { TunnelExceptionHandler.Handle(ex, string.Format("UdpDirectReceive={0}", remoteIpe)); } }
private void UdpDirectSend(object state) { var controlClient = (TcpClient)state; if (!controlClient.Connected) { return; } string destIpe = null; try { var currentState = this.GetUdpClientState(controlClient); while (controlClient.Connected) { try { var localIpe = new IPEndPoint(IPAddress.Any, IPEndPoint.MinPort); byte[] data = currentState.Client.Receive(ref localIpe); if (!controlClient.Connected) { break; } if (data.IsNullOrEmpty() || !(data[0] == 0 && data[1] == 0 && data[2] == 0)) { this.OutWrite("Udp Send Discard {0} {1}bytes.", localIpe, data == null ? -1 : data.Length); App.LogInfo("Udp Send Discard 非法数据包."); continue; } else if (!currentState.LocalEndPoint.Equals(localIpe)) { this.OutWrite("Udp Send Discard {0} {1}bytes.", localIpe, data == null ? -1 : data.Length); App.LogInfo("Udp Send Discard 非法本地端点."); continue; } int offset = 4; if (data[3] == 3) { DnsEndPoint de; Socks4Request.PackOut(data, ref offset, out de); currentState.AddRemoteEndPoint(de); destIpe = string.Format("{0}:{1}", de.Host, de.Port); } else { IPEndPoint ipe; Socks4Request.PackOut(data, ref offset, out ipe); currentState.AddRemoteEndPoint(ipe); destIpe = ipe.ToString(); } var tunnel = this.CreateTunnel(TunnelCommand.UdpSend, controlClient); tunnel.Headers[xHttpHandler.AgentDirect] = destIpe; var outStream = new MemoryStream(data, offset, data.Length - offset); #if DEBUG tunnel.Form[xHttpHandler.AgentChecksum] = CryptoManaged.MD5Hash(outStream).ToString(); outStream.Position = 0L; #endif tunnel.Files.Add(new HttpFileContent(xHttpHandler.AgentDirect, xHttpHandler.AgentDirect, outStream)); var response = tunnel.GetResponse(); if (response.GetResponseText() != "1") { this.OutWrite("Udp {0} Send {1}\t{2}bytes failure.", currentState.LocalEndPoint, destIpe, outStream.Length); return; } this.OutWrite("Udp {0} Send {1}\t{2}bytes.", currentState.LocalEndPoint, destIpe, outStream.Length); //开始接收数据 currentState.SetOnce(); } catch (ObjectDisposedException ex) { #if DEBUG App.LogInfo(string.Format("Predictable objectDisposed exception: {0}", ex.StackTrace)); #endif } catch (WebException ex) { bool isRejected; if (TunnelExceptionHandler.Handle(ex, string.Format("UdpDirectSend={0}", destIpe), _output, out isRejected)) { controlClient.Client.Close(); } if (isRejected) { this.OnServerRejected(); } } catch (SocketException ex) { if (ex.SocketErrorCode == SocketError.Interrupted) { #if DEBUG App.LogInfo(string.Format("Predictable interrupted exception: {0}", ex.Message)); #endif return; } TunnelExceptionHandler.Handle(ex, controlClient.Client, string.Format("UdpDirectSend={0}", destIpe)); } } } catch (Exception ex) { TunnelExceptionHandler.Handle(ex, string.Format("UdpDirectSend={0}", destIpe)); } }
public void ParsePack(byte[] bPack) { switch (this.Phase) { case Socks5Phase.spGreeting: { if (bPack[0] != 5) { throw new ProxyAuthException(403, "Only Socks5 request are supported"); } //要求匿名代理 if (bPack[1] == 1 && bPack[2] == 0) { this.Credential = null; this.Phase = Socks5Phase.spConnecting; } //要求匿名或用户名密码代理 else { this.Credential = new NetworkCredential(); this.Phase = Socks5Phase.spAuthenticating; } } break; case Socks5Phase.spAuthenticating: { if (bPack[0] != 1) { throw new ProxyAuthException(403, "Only Socks5 request are supported"); } if (this.Credential == null) { throw new ProxyAuthException(403, "Socks5Phase.spAuthenticating"); } int length = Convert.ToInt32(bPack[1]); this.Credential.UserName = Encoding.ASCII.GetString(bPack, 2, length); int offset = 2 + length; length = Convert.ToInt32(bPack[offset]); this.Credential.Password = Encoding.ASCII.GetString(bPack, offset + 1, length); this.Phase = Socks5Phase.spConnecting; } break; case Socks5Phase.spConnecting: { if (bPack[0] != 5 || bPack[2] != 0) { throw new ProxyAuthException(403, "Only Socks5 request are supported"); } this.Command = (Socks5Command)bPack[1]; int offset = 4; if (bPack[3] == 3) { DnsEndPoint de; Socks4Request.PackOut(bPack, ref offset, out de); this.EndPoint = de; } else { IPEndPoint ipe; Socks4Request.PackOut(bPack, ref offset, out ipe); this.EndPoint = ipe; } } break; } }