Skip to content
This repository was archived by the owner on Jul 9, 2023. It is now read-only.

Commit 8323f79

Browse files
committed
socks5 refactored + small fies
1 parent 270c57c commit 8323f79

File tree

8 files changed

+265
-281
lines changed

8 files changed

+265
-281
lines changed

src/Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs

Lines changed: 35 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -395,40 +395,41 @@ private async Task<TcpServerConnection> createServerConnection(string remoteHost
395395
tcpServerSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
396396
}
397397

398-
var connectTask = socks
399-
? ProxySocketConnectionTaskFactory.CreateTask((ProxySocket.ProxySocket)tcpServerSocket, ipAddress, port)
400-
: SocketConnectionTaskFactory.CreateTask(tcpServerSocket, ipAddress, port);
401-
402-
await Task.WhenAny(connectTask, Task.Delay(proxyServer.ConnectTimeOutSeconds * 1000, cancellationToken));
403-
if (!connectTask.IsCompleted || !tcpServerSocket.Connected)
404-
{
405-
// here we can just do some cleanup and let the loop continue since
406-
// we will either get a connection or wind up with a null tcpClient
407-
// which will throw
408-
try
409-
{
410-
connectTask.Dispose();
411-
}
412-
catch
413-
{
414-
// ignore
415-
}
416-
try
417-
{
418-
#if NET45
419-
tcpServerSocket?.Close();
420-
#else
421-
tcpServerSocket?.Dispose();
422-
#endif
423-
tcpServerSocket = null;
424-
}
425-
catch
426-
{
427-
// ignore
428-
}
429-
430-
continue;
431-
}
398+
((ProxySocket.ProxySocket)tcpServerSocket).Connect(ipAddress, port);
399+
// var connectTask = socks
400+
// ? ProxySocketConnectionTaskFactory.CreateTask((ProxySocket.ProxySocket)tcpServerSocket, ipAddress, port)
401+
// : SocketConnectionTaskFactory.CreateTask(tcpServerSocket, ipAddress, port);
402+
403+
// await Task.WhenAny(connectTask, Task.Delay(proxyServer.ConnectTimeOutSeconds * 1000, cancellationToken));
404+
// if (!connectTask.IsCompleted || !tcpServerSocket.Connected)
405+
// {
406+
// // here we can just do some cleanup and let the loop continue since
407+
// // we will either get a connection or wind up with a null tcpClient
408+
// // which will throw
409+
// try
410+
// {
411+
// connectTask.Dispose();
412+
// }
413+
// catch
414+
// {
415+
// // ignore
416+
// }
417+
// try
418+
// {
419+
//#if NET45
420+
// tcpServerSocket?.Close();
421+
//#else
422+
// tcpServerSocket?.Dispose();
423+
//#endif
424+
// tcpServerSocket = null;
425+
// }
426+
// catch
427+
// {
428+
// // ignore
429+
// }
430+
431+
// continue;
432+
// }
432433

433434
break;
434435
}

src/Titanium.Web.Proxy/ProxySocket/Authentication/AuthMethod.cs

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -90,45 +90,20 @@ protected Socket Server
9090
/// Gets or sets a byt array that can be used to store data.
9191
/// </summary>
9292
/// <value>A byte array to store data.</value>
93-
protected byte[] Buffer
94-
{
95-
get
96-
{
97-
return _buffer;
98-
}
99-
set
100-
{
101-
_buffer = value;
102-
}
103-
}
93+
protected byte[] Buffer { get; set; }
10494

10595
/// <summary>
10696
/// Gets or sets the number of bytes that have been received from the remote proxy server.
10797
/// </summary>
10898
/// <value>An integer that holds the number of bytes that have been received from the remote proxy server.</value>
109-
protected int Received
110-
{
111-
get
112-
{
113-
return _received;
114-
}
115-
set
116-
{
117-
_received = value;
118-
}
119-
}
99+
protected int Received { get; set; }
120100

121101
// private variables
122-
/// <summary>Holds the value of the Buffer property.</summary>
123-
private byte[] _buffer;
124102

125103
/// <summary>Holds the value of the Server property.</summary>
126104
private Socket _server;
127105

128106
/// <summary>Holds the address of the method to call when the proxy has authenticated the client.</summary>
129107
protected HandShakeComplete CallBack;
130-
131-
/// <summary>Holds the value of the Received property.</summary>
132-
private int _received;
133108
}
134109
}

src/Titanium.Web.Proxy/ProxySocket/HttpsHandler.cs

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public HttpsHandler(Socket server, string user, string pass) : base(server, user
7373
/// <returns>An array of bytes that has to be sent when the user wants to connect to a specific IPEndPoint.</returns>
7474
private byte[] GetConnectBytes(string host, int port)
7575
{
76-
StringBuilder sb = new StringBuilder();
76+
var sb = new StringBuilder();
7777
sb.AppendLine(string.Format("CONNECT {0}:{1} HTTP/1.1", host, port));
7878
sb.AppendLine(string.Format("Host: {0}:{1}", host, port));
7979
if (!string.IsNullOrEmpty(Username))
@@ -92,12 +92,14 @@ private byte[] GetConnectBytes(string host, int port)
9292
/// Verifies that proxy server successfully connected to requested host
9393
/// </summary>
9494
/// <param name="buffer">Input data array</param>
95-
private void VerifyConnectHeader(byte[] buffer)
95+
/// <param name="length">The data count in the buffer</param>
96+
private void VerifyConnectHeader(byte[] buffer, int length)
9697
{
97-
string header = Encoding.ASCII.GetString(buffer);
98+
string header = Encoding.ASCII.GetString(buffer, 0, length);
9899
if ((!header.StartsWith("HTTP/1.1 ", StringComparison.OrdinalIgnoreCase) &&
99100
!header.StartsWith("HTTP/1.0 ", StringComparison.OrdinalIgnoreCase)) || !header.EndsWith(" "))
100101
throw new ProtocolViolationException();
102+
101103
string code = header.Substring(9, 3);
102104
if (code != "200")
103105
throw new ProxyException("Invalid HTTP status. Code: " + code);
@@ -134,20 +136,21 @@ public override void Negotiate(string host, int port)
134136
{
135137
if (host == null)
136138
throw new ArgumentNullException();
139+
137140
if (port <= 0 || port > 65535 || host.Length > 255)
138141
throw new ArgumentException();
142+
139143
byte[] buffer = GetConnectBytes(host, port);
140144
if (Server.Send(buffer, 0, buffer.Length, SocketFlags.None) < buffer.Length)
141145
{
142146
throw new SocketException(10054);
143147
}
144148

145-
buffer = ReadBytes(13);
146-
VerifyConnectHeader(buffer);
149+
ReadBytes(buffer, 13); // buffer is always longer than 13 bytes. Check the code in GetConnectBytes
150+
VerifyConnectHeader(buffer, 13);
147151

148152
// Read bytes 1 by 1 until we reach "\r\n\r\n"
149153
int receivedNewlineChars = 0;
150-
buffer = new byte[1];
151154
while (receivedNewlineChars < 4)
152155
{
153156
int recv = Server.Receive(buffer, 0, 1, SocketFlags.None);
@@ -209,7 +212,7 @@ private void OnConnect(IAsyncResult ar)
209212
}
210213
catch (Exception e)
211214
{
212-
ProtocolComplete(e);
215+
OnProtocolComplete(e);
213216
return;
214217
}
215218

@@ -220,7 +223,7 @@ private void OnConnect(IAsyncResult ar)
220223
}
221224
catch (Exception e)
222225
{
223-
ProtocolComplete(e);
226+
OnProtocolComplete(e);
224227
}
225228
}
226229

@@ -239,7 +242,7 @@ private void OnConnectSent(IAsyncResult ar)
239242
}
240243
catch (Exception e)
241244
{
242-
ProtocolComplete(e);
245+
OnProtocolComplete(e);
243246
}
244247
}
245248

@@ -255,7 +258,7 @@ private void OnConnectReceive(IAsyncResult ar)
255258
}
256259
catch (Exception e)
257260
{
258-
ProtocolComplete(e);
261+
OnProtocolComplete(e);
259262
return;
260263
}
261264

@@ -268,13 +271,13 @@ private void OnConnectReceive(IAsyncResult ar)
268271
}
269272
else
270273
{
271-
VerifyConnectHeader(Buffer);
274+
VerifyConnectHeader(Buffer, 13);
272275
ReadUntilHeadersEnd(true);
273276
}
274277
}
275278
catch (Exception e)
276279
{
277-
ProtocolComplete(e);
280+
OnProtocolComplete(e);
278281
}
279282
}
280283

@@ -303,7 +306,7 @@ private void ReadUntilHeadersEnd(bool readFirstByte)
303306

304307
if (_receivedNewlineChars == 4)
305308
{
306-
ProtocolComplete(null);
309+
OnProtocolComplete(null);
307310
}
308311
else
309312
{
@@ -327,10 +330,16 @@ private void OnEndHeadersReceive(IAsyncResult ar)
327330
}
328331
catch (Exception e)
329332
{
330-
ProtocolComplete(e);
333+
OnProtocolComplete(e);
331334
}
332335
}
333336

337+
protected override void OnProtocolComplete(Exception? exception)
338+
{
339+
// do not return the base Buffer
340+
ProtocolComplete(exception);
341+
}
342+
334343
/// <summary>
335344
/// Gets or sets the password to use when authenticating with the HTTPS server.
336345
/// </summary>

src/Titanium.Web.Proxy/ProxySocket/IAsyncProxyResult.cs

Lines changed: 10 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -42,73 +42,40 @@ internal class IAsyncProxyResult : IAsyncResult
4242
/// <param name="stateObject">An object that contains state information for this request.</param>
4343
internal IAsyncProxyResult(object stateObject = null)
4444
{
45-
_stateObject = stateObject;
46-
_completed = false;
47-
if (_waitHandle != null)
48-
_waitHandle.Reset();
45+
AsyncState = stateObject;
46+
IsCompleted = false;
47+
_waitHandle?.Reset();
4948

5049
}
5150

5251
/// <summary>Initializes the internal variables of this object</summary>
5352
internal void Reset()
5453
{
55-
_stateObject = null;
56-
_completed = true;
57-
if (_waitHandle != null)
58-
_waitHandle.Set();
54+
//AsyncState = null;
55+
IsCompleted = true;
56+
_waitHandle?.Set();
5957
}
6058

6159
/// <summary>Gets a value that indicates whether the server has completed processing the call. It is illegal for the server to use any client supplied resources outside of the agreed upon sharing semantics after it sets the IsCompleted property to "true". Thus, it is safe for the client to destroy the resources after IsCompleted property returns "true".</summary>
6260
/// <value>A boolean that indicates whether the server has completed processing the call.</value>
63-
public bool IsCompleted
64-
{
65-
get
66-
{
67-
return _completed;
68-
}
69-
}
61+
public bool IsCompleted { get; private set; }
7062

7163
/// <summary>Gets a value that indicates whether the BeginXXXX call has been completed synchronously. If this is detected in the AsyncCallback delegate, it is probable that the thread that called BeginInvoke is the current thread.</summary>
7264
/// <value>Returns false.</value>
73-
public bool CompletedSynchronously
74-
{
75-
get
76-
{
77-
return false;
78-
}
79-
}
65+
public bool CompletedSynchronously => false;
8066

8167
/// <summary>Gets an object that was passed as the state parameter of the BeginXXXX method call.</summary>
8268
/// <value>The object that was passed as the state parameter of the BeginXXXX method call.</value>
83-
public object AsyncState
84-
{
85-
get
86-
{
87-
return _stateObject;
88-
}
89-
}
69+
public object AsyncState { get; private set; }
9070

9171
/// <summary>
9272
/// The AsyncWaitHandle property returns the WaitHandle that can use to perform a WaitHandle.WaitOne or WaitAny or WaitAll. The object which implements IAsyncResult need not derive from the System.WaitHandle classes directly. The WaitHandle wraps its underlying synchronization primitive and should be signaled after the call is completed. This enables the client to wait for the call to complete instead polling. The Runtime supplies a number of waitable objects that mirror Win32 synchronization primitives e.g. ManualResetEvent, AutoResetEvent and Mutex.
9373
/// WaitHandle supplies methods that support waiting for such synchronization objects to become signaled with "any" or "all" semantics i.e. WaitHandle.WaitOne, WaitAny and WaitAll. Such methods are context aware to avoid deadlocks. The AsyncWaitHandle can be allocated eagerly or on demand. It is the choice of the IAsyncResult implementer.
9474
///</summary>
9575
/// <value>The WaitHandle associated with this asynchronous result.</value>
96-
public WaitHandle AsyncWaitHandle
97-
{
98-
get
99-
{
100-
if (_waitHandle == null)
101-
_waitHandle = new ManualResetEvent(false);
102-
return _waitHandle;
103-
}
104-
}
76+
public WaitHandle AsyncWaitHandle => _waitHandle ??= new ManualResetEvent(false);
10577

10678
// private variables
107-
/// <summary>Used internally to represent the state of the asynchronous request</summary>
108-
private bool _completed;
109-
110-
/// <summary>Holds the value of the StateObject property.</summary>
111-
private object _stateObject;
11279

11380
/// <summary>Holds the value of the WaitHandle property.</summary>
11481
private ManualResetEvent _waitHandle;

0 commit comments

Comments
 (0)