4using System.Threading.Tasks;
15 private byte[] addr =
null;
16 private string streamId =
null;
17 private bool disposed =
false;
18 private int inputState = 0;
22 private byte addrType;
23 private byte[] methods;
35 this.client.OnDisconnected += this.Client_OnDisconnected;
36 this.client.OnError += this.Client_OnError;
37 this.client.OnReceived += this.Client_OnReceived;
56 [Obsolete(
"Use the DisposeAsync() method.")]
71 if (!(this.streamId is
null))
73 this.server.UnregisterStream(this.streamId,
this);
80 if (!(this.client is
null))
96 private async Task<bool> Client_OnReceived(
object _,
bool ConstantBuffer,
byte[] Buffer,
int Offset,
int Count)
101 this.server.
ReceiveBinary(ConstantBuffer, Buffer, Offset, Count);
103 return await this.ParseIncoming(ConstantBuffer, Buffer, Offset, Count);
114 private Task Client_OnError(
object Sender, Exception Exception)
119 private Task Client_OnDisconnected(
object Sender, EventArgs e)
124 private async Task<bool> ParseIncoming(
bool ConstantBuffer,
byte[] Buffer,
int Offset,
int Count)
130 b = Buffer[Offset++];
132 switch (this.inputState)
145 this.methods =
new byte[b];
149 this.inputState += 2;
150 if (!await this.SendAuthenticationMethod())
158 this.methods[^this.nr] = b;
163 if (!await this.SendAuthenticationMethod())
187 switch (this.addrType = b)
191 this.addr =
new byte[4];
192 this.inputState += 2;
201 this.addr =
new byte[16];
202 this.inputState += 2;
213 this.addr =
new byte[b];
218 this.addr[^this.nr] = b;
233 if (!await this.ExecuteCommand())
244 if (this.server.TryGetRemoteEndPoint(
this.streamId,
this, out Socks5Connection
RemoteEndPoint))
245 return await
RemoteEndPoint.client.SendAsync(ConstantBuffer, Buffer, Offset - 1, Count + 1,
null,
null);
257 internal bool WaitingForActivation
259 get {
return this.inputState == 11; }
262 internal void Activate()
264 this.inputState = 12;
267 private Task<bool> SendAuthenticationMethod()
269 foreach (
byte b
in this.methods)
272 return this.client.
SendAsync(
true,
new byte[] { 5, 0 },
null,
null);
275 return this.client.
SendAsync(
true,
new byte[] { 5, 0xff }, (Sender, e) =>
281 private async Task<bool> ExecuteCommand()
283 using MemoryStream Response =
new MemoryStream();
285 Response.WriteByte(5);
287 if (this.addrType != 3)
288 Response.WriteByte(8);
289 else if (this.command != 1)
290 Response.WriteByte(7);
293 Response.WriteByte(0);
295 this.inputState = 11;
296 this.streamId = Encoding.ASCII.GetString(this.addr);
298 if (!this.server.RegisterConnection(
this.streamId,
this))
300 this.streamId =
null;
306 Response.WriteByte(0);
307 Response.WriteByte(this.addrType);
309 if (this.addrType == 3)
310 Response.WriteByte((
byte)this.addr.Length);
312 Response.Write(this.addr, 0, this.addr.Length);
313 Response.WriteByte((
byte)(this.port >> 8));
314 Response.WriteByte((
byte)(this.port & 0xff));
316 return await this.client.
SendAsync(
true, Response.ToArray(),
null,
null);
Implements a binary TCP Client, by encapsulating a TcpClient. It also makes the use of TcpClient safe...
Task< bool > SendAsync(byte[] Packet)
Sends a binary packet.
string RemoteEndPoint
Remote End-point of connection. This corresponds to the IP Endpoint of the remote party in normal cas...
void DisposeWhenDone()
Disposes the client when done sending all data.
virtual Task DisposeAsync()
Disposes of the object asynchronously. The underlying TcpClient is either disposed directly,...
void Exception(Exception Exception)
Called to inform the viewer of an exception state.
bool HasSniffers
If there are sniffers registered on the object.
void ReceiveBinary(int Count)
Called when binary data has been received.
Class managing a connection.
void Dispose()
IDisposable.Dispose
Socks5Connection(BinaryTcpClient Client, Socks5Server Server)
Class managing a connection.
async Task DisposeAsync()
Closes the connection and disposes of all resources.
void CloseWhenDone()
Closes connection when done.
Socks5Server Server
SOCKS5 Server serving the client.
string RemoteEndPoint
Remote endpoint.