ObjFW  Diff

Differences From Artifact [fa4c8cce5e]:

To Artifact [a16701d00f]:


25
26
27
28
29
30
31
32

33
34
35
36


37
38
39


40
41
42
43
44
45
46
47
48
49
50
51


52
53
54
55


56
57
58

59
60

61
62
63
64
65

66
67
68


69
70
71
72
73
74
75
76
77
78
79
80
81
82


83
84
85
86


87
88
89
90


91
92
93
94
95
96
97
98
99
100
101
102
25
26
27
28
29
30
31

32
33
34


35
36
37


38
39
40
41
42
43
44
45
46
47
48
49


50
51
52
53


54
55
56
57

58
59

60
61
62
63
64

65
66


67
68
69
70
71
72
73
74
75
76
77
78
79
80


81
82
83
84


85
86
87
88


89
90
91
92
93
94
95
96
97
98
99
100
101
102







-
+


-
-
+
+

-
-
+
+










-
-
+
+


-
-
+
+


-
+

-
+




-
+

-
-
+
+












-
-
+
+


-
-
+
+


-
-
+
+













@implementation OFTCPSocket (SOCKS5)
- (void)_SOCKS5ConnectToHost: (OFString*)host
			port: (uint16_t)port
{
	const char request[] = { 5, 1, 0, 3 };
	char reply[256];
	BOOL oldBuffersWrites;
	BOOL oldWriteBufferEnabled;

	/* 5 1 0 -> no authentication */
	[self writeNBytes: 3
	       fromBuffer: request];
	[self writeBuffer: request
		   length: 3];

	[self readExactlyNBytes: 2
		     intoBuffer: reply];
	[self readIntoBuffer: reply
		 exactLength: 2];

	if (reply[0] != 5 || reply[1] != 0) {
		[self close];
		@throw [OFConnectionFailedException
		    exceptionWithClass: isa
				socket: self
				  host: host
				  port: port];
	}

	oldBuffersWrites = [self buffersWrites];
	[self setBuffersWrites: YES];
	oldWriteBufferEnabled = [self writeBufferEnabled];
	[self setWriteBufferEnabled: YES];

	/* CONNECT request */
	[self writeNBytes: 4
	       fromBuffer: request];
	[self writeBuffer: request
		   length: 4];
	[self writeInt8:
	    [host cStringLengthWithEncoding: OF_STRING_ENCODING_NATIVE]];
	[self writeNBytes: [host cStringLengthWithEncoding:
	[self writeBuffer: [host cStringWithEncoding:
			       OF_STRING_ENCODING_NATIVE]
	       fromBuffer: [host cStringWithEncoding:
		   length: [host cStringLengthWithEncoding:
			       OF_STRING_ENCODING_NATIVE]];
	[self writeBigEndianInt16: port];

	[self flushWriteBuffer];
	[self setBuffersWrites: oldBuffersWrites];
	[self setWriteBufferEnabled: oldWriteBufferEnabled];

	[self readExactlyNBytes: 4
		     intoBuffer: reply];
	[self readIntoBuffer: reply
		 exactLength: 4];

	if (reply[0] != 5 || reply[1] != 0 || reply[2] != 0) {
		[self close];
		@throw [OFConnectionFailedException exceptionWithClass: isa
								socket: self
								  host: host
								  port: port];
	}

	/* Skip the rest of the reply */
	switch (reply[3]) {
	case 1: /* IPv4 */
		[self readExactlyNBytes: 4
			     intoBuffer: reply];
		[self readIntoBuffer: reply
			 exactLength: 4];
		break;
	case 3: /* Domainname */
		[self readExactlyNBytes: [self readInt8]
			     intoBuffer: reply];
		[self readIntoBuffer: reply
			 exactLength: [self readInt8]];
		break;
	case 4: /* IPv6 */
		[self readExactlyNBytes: 16
			     intoBuffer: reply];
		[self readIntoBuffer: reply
			 exactLength: 16];
		break;
	default:
		[self close];
		@throw [OFConnectionFailedException exceptionWithClass: isa
								socket: self
								  host: host
								  port: port];
	}

	[self readBigEndianInt16];
}
@end