@@ -6,12 +6,11 @@ from dynlib import LibHandle, symAddr
6
6
7
7
const
8
8
v1sig = " PROXY" .cstring
9
- v2sig = " \c\n\c\n\x00\c\n QUIT\n "
10
-
11
- proc c_memcmp (a, b: pointer , size: csize ): cint {.importc : " memcmp" , header : " <string.h>" , noSideEffect .}
9
+ # v2 \c \n \c \n \0 \c \n Q U I T \n
10
+ v2sig = [0x 0D .byte , 0x 0A , 0x 0D , 0x 0A , 0x 00 , 0x 0D , 0x 0A , 0x 51 , 0x 55 , 0x 49 , 0x 54 , 0x 0A ]
12
11
13
12
type
14
- HeaderV2_IPV4 {. union .} = object
13
+ HeaderV2_IPV4 = object
15
14
src_addr: uint32
16
15
dst_addr: uint32
17
16
src_port: uint16
51
50
52
51
proc pp_handshake * (fd: SocketHandle , sa: ptr SockAddr , sl: ptr Socklen ): int =
53
52
var
54
- size: int
55
53
hdr: Header
54
+ src: Sockaddr_in
55
+ src6: Sockaddr_in6
56
56
57
57
while true :
58
58
result = recv (fd, addr hdr, sizeof (hdr), 0 )
@@ -61,21 +61,16 @@ proc pp_handshake*(fd: SocketHandle, sa: ptr SockAddr, sl: ptr Socklen): int =
61
61
if result == - 1 :
62
62
return if (errno == EAGAIN ): 0 else : - 1
63
63
64
- if result >= 16 and c_memcmp (addr hdr.v2, v2sig.cstring , 12 ) == 0 and (hdr.v2.ver_cmd and 0x F0 ) == 0x 20 :
65
- size = 16 + ntohs (hdr.v2.length).int
66
- if result < size:
67
- return - 1
64
+ if result >= 16 and hdr.v2.sig == v2sig and (hdr.v2.ver_cmd and 0x F0 ) == 0x 20 and result >= 16 + ntohs (hdr.v2.length).int :
68
65
case hdr.v2.ver_cmd and 0x F
69
66
of 0x 1 : # PROXY command
70
67
case hdr.v2.fam
71
68
of 0x 11 : # TCPv4
72
- var src: Sockaddr_in
73
69
src.sin_family = AF_INET .TSa_Family
74
70
src.sin_addr.s_addr = hdr.v2.address.ip4.src_addr
75
71
src.sin_port = hdr.v2.address.ip4.src_port
76
72
copyMem (sa, addr src, sl[])
77
73
of 0x 21 : # TCPv6
78
- var src6: Sockaddr_in6
79
74
src6.sin6_family = AF_INET6 .TSa_Family
80
75
copyMem (addr src6.sin6_addr, addr hdr.v2.address.ip6.src_addr, 16 )
81
76
src6.sin6_port = hdr.v2.address.ip6.src_port
@@ -86,7 +81,7 @@ proc pp_handshake*(fd: SocketHandle, sa: ptr SockAddr, sl: ptr Socklen): int =
86
81
return - 1
87
82
else :
88
83
return - 1
89
- elif result >= 8 and c_memcmp (addr hdr, v1sig, 5 ) == 0 :
84
+ elif result >= 8 and cmpMem (addr hdr, v1sig, 5 ) == 0 :
90
85
let backslash_r = hdr.v1.find ('\r ' )
91
86
if backslash_r == - 1 or hdr.v1[backslash_r + 1 ] != '\n ' :
92
87
return - 1
@@ -95,65 +90,59 @@ proc pp_handshake*(fd: SocketHandle, sa: ptr SockAddr, sl: ptr Socklen): int =
95
90
tmp: array [40 , char ]
96
91
step = SRC_IP
97
92
idx = 0
98
- zeroMem ( addr tmp, sizeof (tmp))
93
+ c: char
99
94
if hdr.v1[9 ] == '4' :
100
- var src: Sockaddr_in
101
95
src.sin_family = AF_INET .TSa_Family
102
96
for i in 11 .. backslash_r:
103
- var c = hdr.v1[i]
97
+ c = hdr.v1[i]
104
98
if c == ' ' or c == '\0 ' :
105
99
case step
106
100
of SRC_IP :
107
101
step = DST_IP
102
+ zeroMem (addr tmp, sizeof (tmp))
108
103
src.sin_addr.s_addr = cast [uint32 ](parseIPAddress ($ cast [cstring ](addr tmp)).address_v4)
109
- of DST_IP :
110
- # temporary ignore destination ip address
104
+ of DST_IP : # temporary ignore destination ip address
111
105
step = SRC_PORT
112
106
of SRC_PORT :
113
107
step = DST_PORT
108
+ zeroMem (addr tmp, sizeof (tmp))
114
109
src.sin_port = htons (parseInt ($ cast [cstring ](addr tmp)).uint16 )
115
110
copyMem (sa, addr src, sl[])
116
111
return backslash_r
117
- of DST_PORT :
118
- # temporary ignore destination port
112
+ of DST_PORT : # temporary ignore destination port
119
113
break
120
- zeroMem (addr tmp, sizeof (tmp))
121
114
idx = 0
122
115
else :
123
116
tmp[idx] = c
124
117
inc (idx)
125
118
elif hdr.v1[0 ] == '6' :
126
- var src6: Sockaddr_in6
127
119
src6.sin6_family = AF_INET6 .TSa_Family
128
120
for i in 11 .. backslash_r:
129
- var c = hdr.v1[i]
121
+ c = hdr.v1[i]
130
122
if c == ' ' or c == '\0 ' :
131
123
case step
132
124
of SRC_IP :
133
125
step = DST_IP
134
126
var ip = parseIPAddress ($ cast [cstring ](addr tmp))
127
+ zeroMem (addr tmp, sizeof (tmp))
135
128
copyMem (addr src6.sin6_addr, addr ip.address_v6, 16 )
136
- of DST_IP :
137
- # temporary ignore destination ip address
129
+ of DST_IP : # temporary ignore destination ip address
138
130
step = SRC_PORT
139
131
of SRC_PORT :
140
132
step = DST_PORT
141
133
src6.sin6_port = htons (parseInt ($ cast [cstring ](addr tmp)).uint16 )
134
+ zeroMem (addr tmp, sizeof (tmp))
142
135
copyMem (sa, addr src6, sl[])
143
136
return backslash_r
144
- of DST_PORT :
145
- # temporary ignore destination port
137
+ of DST_PORT : # temporary ignore destination port
146
138
break
147
- zeroMem (addr tmp, sizeof (tmp))
148
139
idx = 0
149
140
else :
150
141
tmp[idx] = c
151
142
inc (idx)
152
- else :
153
- # not supported protocol
143
+ else : # not supported protocol
154
144
return - 1
155
- else :
156
- # # Wrong protocol
145
+ else : # Wrong protocol
157
146
return - 1
158
147
159
148
when isMainModule :
0 commit comments