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;
53 get {
return this.client.
Client.Client.RemoteEndPoint.ToString(); }
65 if (!(this.streamId is
null))
67 this.server.UnregisterStream(this.streamId,
this);
87 private async Task<bool> Client_OnReceived(
object Sender,
byte[] Buffer,
int Offset,
int Count)
94 return await this.ParseIncoming(Buffer, Offset, Count);
105 private Task Client_OnError(
object Sender, Exception Exception)
108 return Task.CompletedTask;
111 private Task Client_OnDisconnected(
object Sender, EventArgs e)
114 return Task.CompletedTask;
117 private async Task<bool> ParseIncoming(
byte[] Buffer,
int Offset,
int Count)
123 b = Buffer[Offset++];
125 switch (this.inputState)
138 this.methods =
new byte[b];
142 this.inputState += 2;
143 if (!await this.SendAuthenticationMethod())
151 this.methods[this.methods.Length - this.nr] = b;
156 if (!await this.SendAuthenticationMethod())
180 switch (this.addrType = b)
184 this.addr =
new byte[4];
185 this.inputState += 2;
194 this.addr =
new byte[16];
195 this.inputState += 2;
206 this.addr =
new byte[b];
211 this.addr[this.addr.Length - this.nr] = b;
226 if (!await this.ExecuteCommand())
237 if (this.server.TryGetRemoteEndpoint(
this.streamId,
this, out Socks5Connection
RemoteEndpoint))
238 return await
RemoteEndpoint.client.SendAsync(Buffer, Offset - 1, Count + 1,
null,
null);
250 internal bool WaitingForActivation
252 get {
return this.inputState == 11; }
255 internal void Activate()
257 this.inputState = 12;
260 private Task<bool> SendAuthenticationMethod()
262 foreach (
byte b
in this.methods)
265 return this.client.
SendAsync(
new byte[] { 5, 0 },
null,
null);
268 return this.client.
SendAsync(
new byte[] { 5, 0xff }, (Sender, e) =>
271 return Task.CompletedTask;
275 private Task<bool> ExecuteCommand()
277 using (MemoryStream Response =
new MemoryStream())
279 Response.WriteByte(5);
281 if (this.addrType != 3)
282 Response.WriteByte(8);
283 else if (this.command != 1)
284 Response.WriteByte(7);
287 Response.WriteByte(0);
289 this.inputState = 11;
290 this.streamId = Encoding.ASCII.GetString(this.addr);
292 if (!this.server.RegisterConnection(
this.streamId,
this))
294 this.streamId =
null;
296 return Task.FromResult(
false);
300 Response.WriteByte(0);
301 Response.WriteByte(this.addrType);
303 if (this.addrType == 3)
304 Response.WriteByte((
byte)this.addr.Length);
306 Response.Write(this.addr, 0, this.addr.Length);
307 Response.WriteByte((
byte)(this.port >> 8));
308 Response.WriteByte((
byte)(this.port & 0xff));
310 return this.client.
SendAsync(Response.ToArray(),
null,
null);
Implements a binary TCP Client, by encapsulating a TcpClient. It also makes the use of TcpClient safe...
TcpClient Client
Underlying TcpClient object.
Task< bool > SendAsync(byte[] Packet)
Sends a binary packet.
static byte[] ToArray(byte[] Buffer, int Offset, int Count)
Converts a binary subset of a buffer into an array.
void DisposeWhenDone()
Disposes the client when done sending all data.
virtual void Dispose()
Disposes of the object. The underlying TcpClient is either disposed directly, or when asynchronous op...
Task Exception(Exception Exception)
Called to inform the viewer of an exception state.
bool HasSniffers
If there are sniffers registered on the object.
Task ReceiveBinary(byte[] Data)
Called when binary data has been received.
Class managing a connection.
void Dispose()
IDisposable.Dispose
Socks5Connection(BinaryTcpClient Client, Socks5Server Server)
Class managing a connection.
string RemoteEndpoint
Remote endpoint.
void CloseWhenDone()
Closes connection when done.
Socks5Server Server
SOCKS5 Server serving the client.