1 /* socks5.c -- generated by Trunnel v1.5.3.
2 * https://gitweb.torproject.org/trunnel.git
3 * You probably shouldn't edit this file.
6 #include "trunnel-impl.h"
10 #define TRUNNEL_SET_ERROR_CODE(obj) \
12 (obj)->trunnel_error_code_ = 1; \
15 #if defined(__COVERITY__) || defined(__clang_analyzer__)
16 /* If we're running a static analysis tool, we don't want it to complain
17 * that some of our remaining-bytes checks are dead-code. */
18 int socks_deadcode_dummy__
= 0;
19 #define OR_DEADCODE_DUMMY || socks_deadcode_dummy__
21 #define OR_DEADCODE_DUMMY
24 #define CHECK_REMAINING(nbytes, label) \
26 if (remaining < (nbytes) OR_DEADCODE_DUMMY) { \
34 domainname_t
*val
= trunnel_calloc(1, sizeof(domainname_t
));
40 /** Release all storage held inside 'obj', but do not free 'obj'.
43 domainname_clear(domainname_t
*obj
)
46 TRUNNEL_DYNARRAY_WIPE(&obj
->name
);
47 TRUNNEL_DYNARRAY_CLEAR(&obj
->name
);
51 domainname_free(domainname_t
*obj
)
55 domainname_clear(obj
);
56 trunnel_memwipe(obj
, sizeof(domainname_t
));
61 domainname_get_len(const domainname_t
*inp
)
66 domainname_set_len(domainname_t
*inp
, uint8_t val
)
72 domainname_getlen_name(const domainname_t
*inp
)
74 return TRUNNEL_DYNARRAY_LEN(&inp
->name
);
78 domainname_get_name(domainname_t
*inp
, size_t idx
)
80 return TRUNNEL_DYNARRAY_GET(&inp
->name
, idx
);
84 domainname_getconst_name(const domainname_t
*inp
, size_t idx
)
86 return domainname_get_name((domainname_t
*)inp
, idx
);
89 domainname_set_name(domainname_t
*inp
, size_t idx
, char elt
)
91 TRUNNEL_DYNARRAY_SET(&inp
->name
, idx
, elt
);
95 domainname_add_name(domainname_t
*inp
, char elt
)
97 #if SIZE_MAX >= UINT8_MAX
98 if (inp
->name
.n_
== UINT8_MAX
)
99 goto trunnel_alloc_failed
;
101 TRUNNEL_DYNARRAY_ADD(char, &inp
->name
, elt
, {});
103 trunnel_alloc_failed
:
104 TRUNNEL_SET_ERROR_CODE(inp
);
109 domainname_getarray_name(domainname_t
*inp
)
111 return inp
->name
.elts_
;
114 domainname_getconstarray_name(const domainname_t
*inp
)
116 return (const char *)domainname_getarray_name((domainname_t
*)inp
);
119 domainname_setlen_name(domainname_t
*inp
, size_t newlen
)
121 #if UINT8_MAX < SIZE_MAX
122 if (newlen
> UINT8_MAX
)
123 goto trunnel_alloc_failed
;
125 return trunnel_string_setlen(&inp
->name
, newlen
,
126 &inp
->trunnel_error_code_
);
127 trunnel_alloc_failed
:
128 TRUNNEL_SET_ERROR_CODE(inp
);
132 domainname_getstr_name(domainname_t
*inp
)
134 return trunnel_string_getstr(&inp
->name
);
137 domainname_setstr0_name(domainname_t
*inp
, const char *val
, size_t len
)
139 #if UINT8_MAX < SIZE_MAX
140 if (len
> UINT8_MAX
) {
141 TRUNNEL_SET_ERROR_CODE(inp
);
145 return trunnel_string_setstr0(&inp
->name
, val
, len
, &inp
->trunnel_error_code_
);
148 domainname_setstr_name(domainname_t
*inp
, const char *val
)
150 return domainname_setstr0_name(inp
, val
, strlen(val
));
153 domainname_check(const domainname_t
*obj
)
156 return "Object was NULL";
157 if (obj
->trunnel_error_code_
)
158 return "A set function failed on this object";
159 if (TRUNNEL_DYNARRAY_LEN(&obj
->name
) != obj
->len
)
160 return "Length mismatch for name";
165 domainname_encoded_len(const domainname_t
*obj
)
169 if (NULL
!= domainname_check(obj
))
173 /* Length of u8 len */
176 /* Length of char name[len] */
177 result
+= TRUNNEL_DYNARRAY_LEN(&obj
->name
);
181 domainname_clear_errors(domainname_t
*obj
)
183 int r
= obj
->trunnel_error_code_
;
184 obj
->trunnel_error_code_
= 0;
188 domainname_encode(uint8_t *output
, const size_t avail
, const domainname_t
*obj
)
192 uint8_t *ptr
= output
;
194 #ifdef TRUNNEL_CHECK_ENCODED_LEN
195 const ssize_t encoded_len
= domainname_encoded_len(obj
);
198 if (NULL
!= (msg
= domainname_check(obj
)))
201 #ifdef TRUNNEL_CHECK_ENCODED_LEN
202 trunnel_assert(encoded_len
>= 0);
206 trunnel_assert(written
<= avail
);
207 if (avail
- written
< 1)
209 trunnel_set_uint8(ptr
, (obj
->len
));
210 written
+= 1; ptr
+= 1;
212 /* Encode char name[len] */
214 size_t elt_len
= TRUNNEL_DYNARRAY_LEN(&obj
->name
);
215 trunnel_assert(obj
->len
== elt_len
);
216 trunnel_assert(written
<= avail
);
217 if (avail
- written
< elt_len
)
220 memcpy(ptr
, obj
->name
.elts_
, elt_len
);
221 written
+= elt_len
; ptr
+= elt_len
;
225 trunnel_assert(ptr
== output
+ written
);
226 #ifdef TRUNNEL_CHECK_ENCODED_LEN
228 trunnel_assert(encoded_len
>= 0);
229 trunnel_assert((size_t)encoded_len
== written
);
244 trunnel_assert(result
< 0);
248 /** As domainname_parse(), but do not allocate the output object.
251 domainname_parse_into(domainname_t
*obj
, const uint8_t *input
, const size_t len_in
)
253 const uint8_t *ptr
= input
;
254 size_t remaining
= len_in
;
259 CHECK_REMAINING(1, truncated
);
260 obj
->len
= (trunnel_get_uint8(ptr
));
261 remaining
-= 1; ptr
+= 1;
263 /* Parse char name[len] */
264 CHECK_REMAINING(obj
->len
, truncated
);
265 if (domainname_setstr0_name(obj
, (const char*)ptr
, obj
->len
))
267 ptr
+= obj
->len
; remaining
-= obj
->len
;
268 trunnel_assert(ptr
+ remaining
== input
+ len_in
);
269 return len_in
- remaining
;
279 domainname_parse(domainname_t
**output
, const uint8_t *input
, const size_t len_in
)
282 *output
= domainname_new();
285 result
= domainname_parse_into(*output
, input
, len_in
);
287 domainname_free(*output
);
292 socks4_client_request_t
*
293 socks4_client_request_new(void)
295 socks4_client_request_t
*val
= trunnel_calloc(1, sizeof(socks4_client_request_t
));
299 val
->command
= CMD_BIND
;
303 /** Release all storage held inside 'obj', but do not free 'obj'.
306 socks4_client_request_clear(socks4_client_request_t
*obj
)
309 trunnel_wipestr(obj
->username
);
310 trunnel_free(obj
->username
);
311 trunnel_wipestr(obj
->socks4a_addr_hostname
);
312 trunnel_free(obj
->socks4a_addr_hostname
);
316 socks4_client_request_free(socks4_client_request_t
*obj
)
320 socks4_client_request_clear(obj
);
321 trunnel_memwipe(obj
, sizeof(socks4_client_request_t
));
326 socks4_client_request_get_version(const socks4_client_request_t
*inp
)
331 socks4_client_request_set_version(socks4_client_request_t
*inp
, uint8_t val
)
333 if (! ((val
== 4))) {
334 TRUNNEL_SET_ERROR_CODE(inp
);
341 socks4_client_request_get_command(const socks4_client_request_t
*inp
)
346 socks4_client_request_set_command(socks4_client_request_t
*inp
, uint8_t val
)
348 if (! ((val
== CMD_BIND
|| val
== CMD_CONNECT
|| val
== CMD_RESOLVE
|| val
== CMD_RESOLVE_PTR
))) {
349 TRUNNEL_SET_ERROR_CODE(inp
);
356 socks4_client_request_get_port(const socks4_client_request_t
*inp
)
361 socks4_client_request_set_port(socks4_client_request_t
*inp
, uint16_t val
)
367 socks4_client_request_get_addr(const socks4_client_request_t
*inp
)
372 socks4_client_request_set_addr(socks4_client_request_t
*inp
, uint32_t val
)
378 socks4_client_request_get_username(const socks4_client_request_t
*inp
)
380 return inp
->username
;
383 socks4_client_request_set_username(socks4_client_request_t
*inp
, const char *val
)
385 trunnel_free(inp
->username
);
386 if (NULL
== (inp
->username
= trunnel_strdup(val
))) {
387 TRUNNEL_SET_ERROR_CODE(inp
);
393 socks4_client_request_get_socks4a_addr_hostname(const socks4_client_request_t
*inp
)
395 return inp
->socks4a_addr_hostname
;
398 socks4_client_request_set_socks4a_addr_hostname(socks4_client_request_t
*inp
, const char *val
)
400 trunnel_free(inp
->socks4a_addr_hostname
);
401 if (NULL
== (inp
->socks4a_addr_hostname
= trunnel_strdup(val
))) {
402 TRUNNEL_SET_ERROR_CODE(inp
);
408 socks4_client_request_check(const socks4_client_request_t
*obj
)
411 return "Object was NULL";
412 if (obj
->trunnel_error_code_
)
413 return "A set function failed on this object";
414 if (! (obj
->version
== 4))
415 return "Integer out of bounds";
416 if (! (obj
->command
== CMD_BIND
|| obj
->command
== CMD_CONNECT
|| obj
->command
== CMD_RESOLVE
|| obj
->command
== CMD_RESOLVE_PTR
))
417 return "Integer out of bounds";
418 if (NULL
== obj
->username
)
419 return "Missing username";
677 if (NULL
== obj
->socks4a_addr_hostname
)
678 return "Missing socks4a_addr_hostname";
688 socks4_client_request_encoded_len(const socks4_client_request_t
*obj
)
692 if (NULL
!= socks4_client_request_check(obj
))
696 /* Length of u8 version IN [4] */
699 /* Length of u8 command IN [CMD_BIND, CMD_CONNECT, CMD_RESOLVE, CMD_RESOLVE_PTR] */
702 /* Length of u16 port */
705 /* Length of u32 addr */
708 /* Length of nulterm username */
709 result
+= strlen(obj
->username
) + 1;
968 /* Length of nulterm socks4a_addr_hostname */
969 result
+= strlen(obj
->socks4a_addr_hostname
) + 1;
978 socks4_client_request_clear_errors(socks4_client_request_t
*obj
)
980 int r
= obj
->trunnel_error_code_
;
981 obj
->trunnel_error_code_
= 0;
985 socks4_client_request_encode(uint8_t *output
, const size_t avail
, const socks4_client_request_t
*obj
)
989 uint8_t *ptr
= output
;
991 #ifdef TRUNNEL_CHECK_ENCODED_LEN
992 const ssize_t encoded_len
= socks4_client_request_encoded_len(obj
);
995 if (NULL
!= (msg
= socks4_client_request_check(obj
)))
998 #ifdef TRUNNEL_CHECK_ENCODED_LEN
999 trunnel_assert(encoded_len
>= 0);
1002 /* Encode u8 version IN [4] */
1003 trunnel_assert(written
<= avail
);
1004 if (avail
- written
< 1)
1006 trunnel_set_uint8(ptr
, (obj
->version
));
1007 written
+= 1; ptr
+= 1;
1009 /* Encode u8 command IN [CMD_BIND, CMD_CONNECT, CMD_RESOLVE, CMD_RESOLVE_PTR] */
1010 trunnel_assert(written
<= avail
);
1011 if (avail
- written
< 1)
1013 trunnel_set_uint8(ptr
, (obj
->command
));
1014 written
+= 1; ptr
+= 1;
1016 /* Encode u16 port */
1017 trunnel_assert(written
<= avail
);
1018 if (avail
- written
< 2)
1020 trunnel_set_uint16(ptr
, trunnel_htons(obj
->port
));
1021 written
+= 2; ptr
+= 2;
1023 /* Encode u32 addr */
1024 trunnel_assert(written
<= avail
);
1025 if (avail
- written
< 4)
1027 trunnel_set_uint32(ptr
, trunnel_htonl(obj
->addr
));
1028 written
+= 4; ptr
+= 4;
1030 /* Encode nulterm username */
1032 size_t len
= strlen(obj
->username
);
1033 trunnel_assert(written
<= avail
);
1034 if (avail
- written
< len
+ 1)
1036 memcpy(ptr
, obj
->username
, len
+ 1);
1037 ptr
+= len
+ 1; written
+= len
+ 1;
1040 /* Encode union socks4a_addr[addr] */
1041 trunnel_assert(written
<= avail
);
1042 switch (obj
->addr
) {
1300 /* Encode nulterm socks4a_addr_hostname */
1302 size_t len
= strlen(obj
->socks4a_addr_hostname
);
1303 trunnel_assert(written
<= avail
);
1304 if (avail
- written
< len
+ 1)
1306 memcpy(ptr
, obj
->socks4a_addr_hostname
, len
+ 1);
1307 ptr
+= len
+ 1; written
+= len
+ 1;
1316 trunnel_assert(ptr
== output
+ written
);
1317 #ifdef TRUNNEL_CHECK_ENCODED_LEN
1319 trunnel_assert(encoded_len
>= 0);
1320 trunnel_assert((size_t)encoded_len
== written
);
1335 trunnel_assert(result
< 0);
1339 /** As socks4_client_request_parse(), but do not allocate the output
1343 socks4_client_request_parse_into(socks4_client_request_t
*obj
, const uint8_t *input
, const size_t len_in
)
1345 const uint8_t *ptr
= input
;
1346 size_t remaining
= len_in
;
1350 /* Parse u8 version IN [4] */
1351 CHECK_REMAINING(1, truncated
);
1352 obj
->version
= (trunnel_get_uint8(ptr
));
1353 remaining
-= 1; ptr
+= 1;
1354 if (! (obj
->version
== 4))
1357 /* Parse u8 command IN [CMD_BIND, CMD_CONNECT, CMD_RESOLVE, CMD_RESOLVE_PTR] */
1358 CHECK_REMAINING(1, truncated
);
1359 obj
->command
= (trunnel_get_uint8(ptr
));
1360 remaining
-= 1; ptr
+= 1;
1361 if (! (obj
->command
== CMD_BIND
|| obj
->command
== CMD_CONNECT
|| obj
->command
== CMD_RESOLVE
|| obj
->command
== CMD_RESOLVE_PTR
))
1364 /* Parse u16 port */
1365 CHECK_REMAINING(2, truncated
);
1366 obj
->port
= trunnel_ntohs(trunnel_get_uint16(ptr
));
1367 remaining
-= 2; ptr
+= 2;
1369 /* Parse u32 addr */
1370 CHECK_REMAINING(4, truncated
);
1371 obj
->addr
= trunnel_ntohl(trunnel_get_uint32(ptr
));
1372 remaining
-= 4; ptr
+= 4;
1374 /* Parse nulterm username */
1376 uint8_t *eos
= (uint8_t*)memchr(ptr
, 0, remaining
);
1380 trunnel_assert(eos
>= ptr
);
1381 trunnel_assert((size_t)(eos
- ptr
) < SIZE_MAX
- 1);
1382 memlen
= ((size_t)(eos
- ptr
)) + 1;
1383 if (!(obj
->username
= trunnel_malloc(memlen
)))
1385 memcpy(obj
->username
, ptr
, memlen
);
1386 remaining
-= memlen
; ptr
+= memlen
;
1389 /* Parse union socks4a_addr[addr] */
1390 switch (obj
->addr
) {
1648 /* Parse nulterm socks4a_addr_hostname */
1650 uint8_t *eos
= (uint8_t*)memchr(ptr
, 0, remaining
);
1654 trunnel_assert(eos
>= ptr
);
1655 trunnel_assert((size_t)(eos
- ptr
) < SIZE_MAX
- 1);
1656 memlen
= ((size_t)(eos
- ptr
)) + 1;
1657 if (!(obj
->socks4a_addr_hostname
= trunnel_malloc(memlen
)))
1659 memcpy(obj
->socks4a_addr_hostname
, ptr
, memlen
);
1660 remaining
-= memlen
; ptr
+= memlen
;
1667 trunnel_assert(ptr
+ remaining
== input
+ len_in
);
1668 return len_in
- remaining
;
1678 socks4_client_request_parse(socks4_client_request_t
**output
, const uint8_t *input
, const size_t len_in
)
1681 *output
= socks4_client_request_new();
1682 if (NULL
== *output
)
1684 result
= socks4_client_request_parse_into(*output
, input
, len_in
);
1686 socks4_client_request_free(*output
);
1691 socks4_server_reply_t
*
1692 socks4_server_reply_new(void)
1694 socks4_server_reply_t
*val
= trunnel_calloc(1, sizeof(socks4_server_reply_t
));
1700 /** Release all storage held inside 'obj', but do not free 'obj'.
1703 socks4_server_reply_clear(socks4_server_reply_t
*obj
)
1709 socks4_server_reply_free(socks4_server_reply_t
*obj
)
1713 socks4_server_reply_clear(obj
);
1714 trunnel_memwipe(obj
, sizeof(socks4_server_reply_t
));
1719 socks4_server_reply_get_version(const socks4_server_reply_t
*inp
)
1721 return inp
->version
;
1724 socks4_server_reply_set_version(socks4_server_reply_t
*inp
, uint8_t val
)
1726 if (! ((val
== 0 || val
== 4))) {
1727 TRUNNEL_SET_ERROR_CODE(inp
);
1734 socks4_server_reply_get_status(const socks4_server_reply_t
*inp
)
1739 socks4_server_reply_set_status(socks4_server_reply_t
*inp
, uint8_t val
)
1745 socks4_server_reply_get_port(const socks4_server_reply_t
*inp
)
1750 socks4_server_reply_set_port(socks4_server_reply_t
*inp
, uint16_t val
)
1756 socks4_server_reply_get_addr(const socks4_server_reply_t
*inp
)
1761 socks4_server_reply_set_addr(socks4_server_reply_t
*inp
, uint32_t val
)
1767 socks4_server_reply_check(const socks4_server_reply_t
*obj
)
1770 return "Object was NULL";
1771 if (obj
->trunnel_error_code_
)
1772 return "A set function failed on this object";
1773 if (! (obj
->version
== 0 || obj
->version
== 4))
1774 return "Integer out of bounds";
1779 socks4_server_reply_encoded_len(const socks4_server_reply_t
*obj
)
1783 if (NULL
!= socks4_server_reply_check(obj
))
1787 /* Length of u8 version IN [0, 4] */
1790 /* Length of u8 status */
1793 /* Length of u16 port */
1796 /* Length of u32 addr */
1801 socks4_server_reply_clear_errors(socks4_server_reply_t
*obj
)
1803 int r
= obj
->trunnel_error_code_
;
1804 obj
->trunnel_error_code_
= 0;
1808 socks4_server_reply_encode(uint8_t *output
, const size_t avail
, const socks4_server_reply_t
*obj
)
1812 uint8_t *ptr
= output
;
1814 #ifdef TRUNNEL_CHECK_ENCODED_LEN
1815 const ssize_t encoded_len
= socks4_server_reply_encoded_len(obj
);
1818 if (NULL
!= (msg
= socks4_server_reply_check(obj
)))
1821 #ifdef TRUNNEL_CHECK_ENCODED_LEN
1822 trunnel_assert(encoded_len
>= 0);
1825 /* Encode u8 version IN [0, 4] */
1826 trunnel_assert(written
<= avail
);
1827 if (avail
- written
< 1)
1829 trunnel_set_uint8(ptr
, (obj
->version
));
1830 written
+= 1; ptr
+= 1;
1832 /* Encode u8 status */
1833 trunnel_assert(written
<= avail
);
1834 if (avail
- written
< 1)
1836 trunnel_set_uint8(ptr
, (obj
->status
));
1837 written
+= 1; ptr
+= 1;
1839 /* Encode u16 port */
1840 trunnel_assert(written
<= avail
);
1841 if (avail
- written
< 2)
1843 trunnel_set_uint16(ptr
, trunnel_htons(obj
->port
));
1844 written
+= 2; ptr
+= 2;
1846 /* Encode u32 addr */
1847 trunnel_assert(written
<= avail
);
1848 if (avail
- written
< 4)
1850 trunnel_set_uint32(ptr
, trunnel_htonl(obj
->addr
));
1851 written
+= 4; ptr
+= 4;
1854 trunnel_assert(ptr
== output
+ written
);
1855 #ifdef TRUNNEL_CHECK_ENCODED_LEN
1857 trunnel_assert(encoded_len
>= 0);
1858 trunnel_assert((size_t)encoded_len
== written
);
1873 trunnel_assert(result
< 0);
1877 /** As socks4_server_reply_parse(), but do not allocate the output
1881 socks4_server_reply_parse_into(socks4_server_reply_t
*obj
, const uint8_t *input
, const size_t len_in
)
1883 const uint8_t *ptr
= input
;
1884 size_t remaining
= len_in
;
1888 /* Parse u8 version IN [0, 4] */
1889 CHECK_REMAINING(1, truncated
);
1890 obj
->version
= (trunnel_get_uint8(ptr
));
1891 remaining
-= 1; ptr
+= 1;
1892 if (! (obj
->version
== 0 || obj
->version
== 4))
1895 /* Parse u8 status */
1896 CHECK_REMAINING(1, truncated
);
1897 obj
->status
= (trunnel_get_uint8(ptr
));
1898 remaining
-= 1; ptr
+= 1;
1900 /* Parse u16 port */
1901 CHECK_REMAINING(2, truncated
);
1902 obj
->port
= trunnel_ntohs(trunnel_get_uint16(ptr
));
1903 remaining
-= 2; ptr
+= 2;
1905 /* Parse u32 addr */
1906 CHECK_REMAINING(4, truncated
);
1907 obj
->addr
= trunnel_ntohl(trunnel_get_uint32(ptr
));
1908 remaining
-= 4; ptr
+= 4;
1909 trunnel_assert(ptr
+ remaining
== input
+ len_in
);
1910 return len_in
- remaining
;
1920 socks4_server_reply_parse(socks4_server_reply_t
**output
, const uint8_t *input
, const size_t len_in
)
1923 *output
= socks4_server_reply_new();
1924 if (NULL
== *output
)
1926 result
= socks4_server_reply_parse_into(*output
, input
, len_in
);
1928 socks4_server_reply_free(*output
);
1933 socks5_client_userpass_auth_t
*
1934 socks5_client_userpass_auth_new(void)
1936 socks5_client_userpass_auth_t
*val
= trunnel_calloc(1, sizeof(socks5_client_userpass_auth_t
));
1943 /** Release all storage held inside 'obj', but do not free 'obj'.
1946 socks5_client_userpass_auth_clear(socks5_client_userpass_auth_t
*obj
)
1949 TRUNNEL_DYNARRAY_WIPE(&obj
->username
);
1950 TRUNNEL_DYNARRAY_CLEAR(&obj
->username
);
1951 TRUNNEL_DYNARRAY_WIPE(&obj
->passwd
);
1952 TRUNNEL_DYNARRAY_CLEAR(&obj
->passwd
);
1956 socks5_client_userpass_auth_free(socks5_client_userpass_auth_t
*obj
)
1960 socks5_client_userpass_auth_clear(obj
);
1961 trunnel_memwipe(obj
, sizeof(socks5_client_userpass_auth_t
));
1966 socks5_client_userpass_auth_get_version(const socks5_client_userpass_auth_t
*inp
)
1968 return inp
->version
;
1971 socks5_client_userpass_auth_set_version(socks5_client_userpass_auth_t
*inp
, uint8_t val
)
1973 if (! ((val
== 1))) {
1974 TRUNNEL_SET_ERROR_CODE(inp
);
1981 socks5_client_userpass_auth_get_username_len(const socks5_client_userpass_auth_t
*inp
)
1983 return inp
->username_len
;
1986 socks5_client_userpass_auth_set_username_len(socks5_client_userpass_auth_t
*inp
, uint8_t val
)
1988 inp
->username_len
= val
;
1992 socks5_client_userpass_auth_getlen_username(const socks5_client_userpass_auth_t
*inp
)
1994 return TRUNNEL_DYNARRAY_LEN(&inp
->username
);
1998 socks5_client_userpass_auth_get_username(socks5_client_userpass_auth_t
*inp
, size_t idx
)
2000 return TRUNNEL_DYNARRAY_GET(&inp
->username
, idx
);
2004 socks5_client_userpass_auth_getconst_username(const socks5_client_userpass_auth_t
*inp
, size_t idx
)
2006 return socks5_client_userpass_auth_get_username((socks5_client_userpass_auth_t
*)inp
, idx
);
2009 socks5_client_userpass_auth_set_username(socks5_client_userpass_auth_t
*inp
, size_t idx
, char elt
)
2011 TRUNNEL_DYNARRAY_SET(&inp
->username
, idx
, elt
);
2015 socks5_client_userpass_auth_add_username(socks5_client_userpass_auth_t
*inp
, char elt
)
2017 #if SIZE_MAX >= UINT8_MAX
2018 if (inp
->username
.n_
== UINT8_MAX
)
2019 goto trunnel_alloc_failed
;
2021 TRUNNEL_DYNARRAY_ADD(char, &inp
->username
, elt
, {});
2023 trunnel_alloc_failed
:
2024 TRUNNEL_SET_ERROR_CODE(inp
);
2029 socks5_client_userpass_auth_getarray_username(socks5_client_userpass_auth_t
*inp
)
2031 return inp
->username
.elts_
;
2034 socks5_client_userpass_auth_getconstarray_username(const socks5_client_userpass_auth_t
*inp
)
2036 return (const char *)socks5_client_userpass_auth_getarray_username((socks5_client_userpass_auth_t
*)inp
);
2039 socks5_client_userpass_auth_setlen_username(socks5_client_userpass_auth_t
*inp
, size_t newlen
)
2041 #if UINT8_MAX < SIZE_MAX
2042 if (newlen
> UINT8_MAX
)
2043 goto trunnel_alloc_failed
;
2045 return trunnel_string_setlen(&inp
->username
, newlen
,
2046 &inp
->trunnel_error_code_
);
2047 trunnel_alloc_failed
:
2048 TRUNNEL_SET_ERROR_CODE(inp
);
2052 socks5_client_userpass_auth_getstr_username(socks5_client_userpass_auth_t
*inp
)
2054 return trunnel_string_getstr(&inp
->username
);
2057 socks5_client_userpass_auth_setstr0_username(socks5_client_userpass_auth_t
*inp
, const char *val
, size_t len
)
2059 #if UINT8_MAX < SIZE_MAX
2060 if (len
> UINT8_MAX
) {
2061 TRUNNEL_SET_ERROR_CODE(inp
);
2065 return trunnel_string_setstr0(&inp
->username
, val
, len
, &inp
->trunnel_error_code_
);
2068 socks5_client_userpass_auth_setstr_username(socks5_client_userpass_auth_t
*inp
, const char *val
)
2070 return socks5_client_userpass_auth_setstr0_username(inp
, val
, strlen(val
));
2073 socks5_client_userpass_auth_get_passwd_len(const socks5_client_userpass_auth_t
*inp
)
2075 return inp
->passwd_len
;
2078 socks5_client_userpass_auth_set_passwd_len(socks5_client_userpass_auth_t
*inp
, uint8_t val
)
2080 inp
->passwd_len
= val
;
2084 socks5_client_userpass_auth_getlen_passwd(const socks5_client_userpass_auth_t
*inp
)
2086 return TRUNNEL_DYNARRAY_LEN(&inp
->passwd
);
2090 socks5_client_userpass_auth_get_passwd(socks5_client_userpass_auth_t
*inp
, size_t idx
)
2092 return TRUNNEL_DYNARRAY_GET(&inp
->passwd
, idx
);
2096 socks5_client_userpass_auth_getconst_passwd(const socks5_client_userpass_auth_t
*inp
, size_t idx
)
2098 return socks5_client_userpass_auth_get_passwd((socks5_client_userpass_auth_t
*)inp
, idx
);
2101 socks5_client_userpass_auth_set_passwd(socks5_client_userpass_auth_t
*inp
, size_t idx
, char elt
)
2103 TRUNNEL_DYNARRAY_SET(&inp
->passwd
, idx
, elt
);
2107 socks5_client_userpass_auth_add_passwd(socks5_client_userpass_auth_t
*inp
, char elt
)
2109 #if SIZE_MAX >= UINT8_MAX
2110 if (inp
->passwd
.n_
== UINT8_MAX
)
2111 goto trunnel_alloc_failed
;
2113 TRUNNEL_DYNARRAY_ADD(char, &inp
->passwd
, elt
, {});
2115 trunnel_alloc_failed
:
2116 TRUNNEL_SET_ERROR_CODE(inp
);
2121 socks5_client_userpass_auth_getarray_passwd(socks5_client_userpass_auth_t
*inp
)
2123 return inp
->passwd
.elts_
;
2126 socks5_client_userpass_auth_getconstarray_passwd(const socks5_client_userpass_auth_t
*inp
)
2128 return (const char *)socks5_client_userpass_auth_getarray_passwd((socks5_client_userpass_auth_t
*)inp
);
2131 socks5_client_userpass_auth_setlen_passwd(socks5_client_userpass_auth_t
*inp
, size_t newlen
)
2133 #if UINT8_MAX < SIZE_MAX
2134 if (newlen
> UINT8_MAX
)
2135 goto trunnel_alloc_failed
;
2137 return trunnel_string_setlen(&inp
->passwd
, newlen
,
2138 &inp
->trunnel_error_code_
);
2139 trunnel_alloc_failed
:
2140 TRUNNEL_SET_ERROR_CODE(inp
);
2144 socks5_client_userpass_auth_getstr_passwd(socks5_client_userpass_auth_t
*inp
)
2146 return trunnel_string_getstr(&inp
->passwd
);
2149 socks5_client_userpass_auth_setstr0_passwd(socks5_client_userpass_auth_t
*inp
, const char *val
, size_t len
)
2151 #if UINT8_MAX < SIZE_MAX
2152 if (len
> UINT8_MAX
) {
2153 TRUNNEL_SET_ERROR_CODE(inp
);
2157 return trunnel_string_setstr0(&inp
->passwd
, val
, len
, &inp
->trunnel_error_code_
);
2160 socks5_client_userpass_auth_setstr_passwd(socks5_client_userpass_auth_t
*inp
, const char *val
)
2162 return socks5_client_userpass_auth_setstr0_passwd(inp
, val
, strlen(val
));
2165 socks5_client_userpass_auth_check(const socks5_client_userpass_auth_t
*obj
)
2168 return "Object was NULL";
2169 if (obj
->trunnel_error_code_
)
2170 return "A set function failed on this object";
2171 if (! (obj
->version
== 1))
2172 return "Integer out of bounds";
2173 if (TRUNNEL_DYNARRAY_LEN(&obj
->username
) != obj
->username_len
)
2174 return "Length mismatch for username";
2175 if (TRUNNEL_DYNARRAY_LEN(&obj
->passwd
) != obj
->passwd_len
)
2176 return "Length mismatch for passwd";
2181 socks5_client_userpass_auth_encoded_len(const socks5_client_userpass_auth_t
*obj
)
2185 if (NULL
!= socks5_client_userpass_auth_check(obj
))
2189 /* Length of u8 version IN [1] */
2192 /* Length of u8 username_len */
2195 /* Length of char username[username_len] */
2196 result
+= TRUNNEL_DYNARRAY_LEN(&obj
->username
);
2198 /* Length of u8 passwd_len */
2201 /* Length of char passwd[passwd_len] */
2202 result
+= TRUNNEL_DYNARRAY_LEN(&obj
->passwd
);
2206 socks5_client_userpass_auth_clear_errors(socks5_client_userpass_auth_t
*obj
)
2208 int r
= obj
->trunnel_error_code_
;
2209 obj
->trunnel_error_code_
= 0;
2213 socks5_client_userpass_auth_encode(uint8_t *output
, const size_t avail
, const socks5_client_userpass_auth_t
*obj
)
2217 uint8_t *ptr
= output
;
2219 #ifdef TRUNNEL_CHECK_ENCODED_LEN
2220 const ssize_t encoded_len
= socks5_client_userpass_auth_encoded_len(obj
);
2223 if (NULL
!= (msg
= socks5_client_userpass_auth_check(obj
)))
2226 #ifdef TRUNNEL_CHECK_ENCODED_LEN
2227 trunnel_assert(encoded_len
>= 0);
2230 /* Encode u8 version IN [1] */
2231 trunnel_assert(written
<= avail
);
2232 if (avail
- written
< 1)
2234 trunnel_set_uint8(ptr
, (obj
->version
));
2235 written
+= 1; ptr
+= 1;
2237 /* Encode u8 username_len */
2238 trunnel_assert(written
<= avail
);
2239 if (avail
- written
< 1)
2241 trunnel_set_uint8(ptr
, (obj
->username_len
));
2242 written
+= 1; ptr
+= 1;
2244 /* Encode char username[username_len] */
2246 size_t elt_len
= TRUNNEL_DYNARRAY_LEN(&obj
->username
);
2247 trunnel_assert(obj
->username_len
== elt_len
);
2248 trunnel_assert(written
<= avail
);
2249 if (avail
- written
< elt_len
)
2252 memcpy(ptr
, obj
->username
.elts_
, elt_len
);
2253 written
+= elt_len
; ptr
+= elt_len
;
2256 /* Encode u8 passwd_len */
2257 trunnel_assert(written
<= avail
);
2258 if (avail
- written
< 1)
2260 trunnel_set_uint8(ptr
, (obj
->passwd_len
));
2261 written
+= 1; ptr
+= 1;
2263 /* Encode char passwd[passwd_len] */
2265 size_t elt_len
= TRUNNEL_DYNARRAY_LEN(&obj
->passwd
);
2266 trunnel_assert(obj
->passwd_len
== elt_len
);
2267 trunnel_assert(written
<= avail
);
2268 if (avail
- written
< elt_len
)
2271 memcpy(ptr
, obj
->passwd
.elts_
, elt_len
);
2272 written
+= elt_len
; ptr
+= elt_len
;
2276 trunnel_assert(ptr
== output
+ written
);
2277 #ifdef TRUNNEL_CHECK_ENCODED_LEN
2279 trunnel_assert(encoded_len
>= 0);
2280 trunnel_assert((size_t)encoded_len
== written
);
2295 trunnel_assert(result
< 0);
2299 /** As socks5_client_userpass_auth_parse(), but do not allocate the
2303 socks5_client_userpass_auth_parse_into(socks5_client_userpass_auth_t
*obj
, const uint8_t *input
, const size_t len_in
)
2305 const uint8_t *ptr
= input
;
2306 size_t remaining
= len_in
;
2310 /* Parse u8 version IN [1] */
2311 CHECK_REMAINING(1, truncated
);
2312 obj
->version
= (trunnel_get_uint8(ptr
));
2313 remaining
-= 1; ptr
+= 1;
2314 if (! (obj
->version
== 1))
2317 /* Parse u8 username_len */
2318 CHECK_REMAINING(1, truncated
);
2319 obj
->username_len
= (trunnel_get_uint8(ptr
));
2320 remaining
-= 1; ptr
+= 1;
2322 /* Parse char username[username_len] */
2323 CHECK_REMAINING(obj
->username_len
, truncated
);
2324 if (socks5_client_userpass_auth_setstr0_username(obj
, (const char*)ptr
, obj
->username_len
))
2326 ptr
+= obj
->username_len
; remaining
-= obj
->username_len
;
2328 /* Parse u8 passwd_len */
2329 CHECK_REMAINING(1, truncated
);
2330 obj
->passwd_len
= (trunnel_get_uint8(ptr
));
2331 remaining
-= 1; ptr
+= 1;
2333 /* Parse char passwd[passwd_len] */
2334 CHECK_REMAINING(obj
->passwd_len
, truncated
);
2335 if (socks5_client_userpass_auth_setstr0_passwd(obj
, (const char*)ptr
, obj
->passwd_len
))
2337 ptr
+= obj
->passwd_len
; remaining
-= obj
->passwd_len
;
2338 trunnel_assert(ptr
+ remaining
== input
+ len_in
);
2339 return len_in
- remaining
;
2349 socks5_client_userpass_auth_parse(socks5_client_userpass_auth_t
**output
, const uint8_t *input
, const size_t len_in
)
2352 *output
= socks5_client_userpass_auth_new();
2353 if (NULL
== *output
)
2355 result
= socks5_client_userpass_auth_parse_into(*output
, input
, len_in
);
2357 socks5_client_userpass_auth_free(*output
);
2362 socks5_client_version_t
*
2363 socks5_client_version_new(void)
2365 socks5_client_version_t
*val
= trunnel_calloc(1, sizeof(socks5_client_version_t
));
2372 /** Release all storage held inside 'obj', but do not free 'obj'.
2375 socks5_client_version_clear(socks5_client_version_t
*obj
)
2378 TRUNNEL_DYNARRAY_WIPE(&obj
->methods
);
2379 TRUNNEL_DYNARRAY_CLEAR(&obj
->methods
);
2383 socks5_client_version_free(socks5_client_version_t
*obj
)
2387 socks5_client_version_clear(obj
);
2388 trunnel_memwipe(obj
, sizeof(socks5_client_version_t
));
2393 socks5_client_version_get_version(const socks5_client_version_t
*inp
)
2395 return inp
->version
;
2398 socks5_client_version_set_version(socks5_client_version_t
*inp
, uint8_t val
)
2400 if (! ((val
== 5))) {
2401 TRUNNEL_SET_ERROR_CODE(inp
);
2408 socks5_client_version_get_n_methods(const socks5_client_version_t
*inp
)
2410 return inp
->n_methods
;
2413 socks5_client_version_set_n_methods(socks5_client_version_t
*inp
, uint8_t val
)
2415 inp
->n_methods
= val
;
2419 socks5_client_version_getlen_methods(const socks5_client_version_t
*inp
)
2421 return TRUNNEL_DYNARRAY_LEN(&inp
->methods
);
2425 socks5_client_version_get_methods(socks5_client_version_t
*inp
, size_t idx
)
2427 return TRUNNEL_DYNARRAY_GET(&inp
->methods
, idx
);
2431 socks5_client_version_getconst_methods(const socks5_client_version_t
*inp
, size_t idx
)
2433 return socks5_client_version_get_methods((socks5_client_version_t
*)inp
, idx
);
2436 socks5_client_version_set_methods(socks5_client_version_t
*inp
, size_t idx
, uint8_t elt
)
2438 TRUNNEL_DYNARRAY_SET(&inp
->methods
, idx
, elt
);
2442 socks5_client_version_add_methods(socks5_client_version_t
*inp
, uint8_t elt
)
2444 #if SIZE_MAX >= UINT8_MAX
2445 if (inp
->methods
.n_
== UINT8_MAX
)
2446 goto trunnel_alloc_failed
;
2448 TRUNNEL_DYNARRAY_ADD(uint8_t, &inp
->methods
, elt
, {});
2450 trunnel_alloc_failed
:
2451 TRUNNEL_SET_ERROR_CODE(inp
);
2456 socks5_client_version_getarray_methods(socks5_client_version_t
*inp
)
2458 return inp
->methods
.elts_
;
2461 socks5_client_version_getconstarray_methods(const socks5_client_version_t
*inp
)
2463 return (const uint8_t *)socks5_client_version_getarray_methods((socks5_client_version_t
*)inp
);
2466 socks5_client_version_setlen_methods(socks5_client_version_t
*inp
, size_t newlen
)
2469 #if UINT8_MAX < SIZE_MAX
2470 if (newlen
> UINT8_MAX
)
2471 goto trunnel_alloc_failed
;
2473 newptr
= trunnel_dynarray_setlen(&inp
->methods
.allocated_
,
2474 &inp
->methods
.n_
, inp
->methods
.elts_
, newlen
,
2475 sizeof(inp
->methods
.elts_
[0]), (trunnel_free_fn_t
) NULL
,
2476 &inp
->trunnel_error_code_
);
2477 if (newlen
!= 0 && newptr
== NULL
)
2478 goto trunnel_alloc_failed
;
2479 inp
->methods
.elts_
= newptr
;
2481 trunnel_alloc_failed
:
2482 TRUNNEL_SET_ERROR_CODE(inp
);
2486 socks5_client_version_check(const socks5_client_version_t
*obj
)
2489 return "Object was NULL";
2490 if (obj
->trunnel_error_code_
)
2491 return "A set function failed on this object";
2492 if (! (obj
->version
== 5))
2493 return "Integer out of bounds";
2494 if (TRUNNEL_DYNARRAY_LEN(&obj
->methods
) != obj
->n_methods
)
2495 return "Length mismatch for methods";
2500 socks5_client_version_encoded_len(const socks5_client_version_t
*obj
)
2504 if (NULL
!= socks5_client_version_check(obj
))
2508 /* Length of u8 version IN [5] */
2511 /* Length of u8 n_methods */
2514 /* Length of u8 methods[n_methods] */
2515 result
+= TRUNNEL_DYNARRAY_LEN(&obj
->methods
);
2519 socks5_client_version_clear_errors(socks5_client_version_t
*obj
)
2521 int r
= obj
->trunnel_error_code_
;
2522 obj
->trunnel_error_code_
= 0;
2526 socks5_client_version_encode(uint8_t *output
, const size_t avail
, const socks5_client_version_t
*obj
)
2530 uint8_t *ptr
= output
;
2532 #ifdef TRUNNEL_CHECK_ENCODED_LEN
2533 const ssize_t encoded_len
= socks5_client_version_encoded_len(obj
);
2536 if (NULL
!= (msg
= socks5_client_version_check(obj
)))
2539 #ifdef TRUNNEL_CHECK_ENCODED_LEN
2540 trunnel_assert(encoded_len
>= 0);
2543 /* Encode u8 version IN [5] */
2544 trunnel_assert(written
<= avail
);
2545 if (avail
- written
< 1)
2547 trunnel_set_uint8(ptr
, (obj
->version
));
2548 written
+= 1; ptr
+= 1;
2550 /* Encode u8 n_methods */
2551 trunnel_assert(written
<= avail
);
2552 if (avail
- written
< 1)
2554 trunnel_set_uint8(ptr
, (obj
->n_methods
));
2555 written
+= 1; ptr
+= 1;
2557 /* Encode u8 methods[n_methods] */
2559 size_t elt_len
= TRUNNEL_DYNARRAY_LEN(&obj
->methods
);
2560 trunnel_assert(obj
->n_methods
== elt_len
);
2561 trunnel_assert(written
<= avail
);
2562 if (avail
- written
< elt_len
)
2565 memcpy(ptr
, obj
->methods
.elts_
, elt_len
);
2566 written
+= elt_len
; ptr
+= elt_len
;
2570 trunnel_assert(ptr
== output
+ written
);
2571 #ifdef TRUNNEL_CHECK_ENCODED_LEN
2573 trunnel_assert(encoded_len
>= 0);
2574 trunnel_assert((size_t)encoded_len
== written
);
2589 trunnel_assert(result
< 0);
2593 /** As socks5_client_version_parse(), but do not allocate the output
2597 socks5_client_version_parse_into(socks5_client_version_t
*obj
, const uint8_t *input
, const size_t len_in
)
2599 const uint8_t *ptr
= input
;
2600 size_t remaining
= len_in
;
2604 /* Parse u8 version IN [5] */
2605 CHECK_REMAINING(1, truncated
);
2606 obj
->version
= (trunnel_get_uint8(ptr
));
2607 remaining
-= 1; ptr
+= 1;
2608 if (! (obj
->version
== 5))
2611 /* Parse u8 n_methods */
2612 CHECK_REMAINING(1, truncated
);
2613 obj
->n_methods
= (trunnel_get_uint8(ptr
));
2614 remaining
-= 1; ptr
+= 1;
2616 /* Parse u8 methods[n_methods] */
2617 CHECK_REMAINING(obj
->n_methods
, truncated
);
2618 TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj
->methods
, obj
->n_methods
, {});
2619 obj
->methods
.n_
= obj
->n_methods
;
2621 memcpy(obj
->methods
.elts_
, ptr
, obj
->n_methods
);
2622 ptr
+= obj
->n_methods
; remaining
-= obj
->n_methods
;
2623 trunnel_assert(ptr
+ remaining
== input
+ len_in
);
2624 return len_in
- remaining
;
2628 trunnel_alloc_failed
:
2636 socks5_client_version_parse(socks5_client_version_t
**output
, const uint8_t *input
, const size_t len_in
)
2639 *output
= socks5_client_version_new();
2640 if (NULL
== *output
)
2642 result
= socks5_client_version_parse_into(*output
, input
, len_in
);
2644 socks5_client_version_free(*output
);
2649 socks5_server_method_t
*
2650 socks5_server_method_new(void)
2652 socks5_server_method_t
*val
= trunnel_calloc(1, sizeof(socks5_server_method_t
));
2659 /** Release all storage held inside 'obj', but do not free 'obj'.
2662 socks5_server_method_clear(socks5_server_method_t
*obj
)
2668 socks5_server_method_free(socks5_server_method_t
*obj
)
2672 socks5_server_method_clear(obj
);
2673 trunnel_memwipe(obj
, sizeof(socks5_server_method_t
));
2678 socks5_server_method_get_version(const socks5_server_method_t
*inp
)
2680 return inp
->version
;
2683 socks5_server_method_set_version(socks5_server_method_t
*inp
, uint8_t val
)
2685 if (! ((val
== 5))) {
2686 TRUNNEL_SET_ERROR_CODE(inp
);
2693 socks5_server_method_get_method(const socks5_server_method_t
*inp
)
2698 socks5_server_method_set_method(socks5_server_method_t
*inp
, uint8_t val
)
2704 socks5_server_method_check(const socks5_server_method_t
*obj
)
2707 return "Object was NULL";
2708 if (obj
->trunnel_error_code_
)
2709 return "A set function failed on this object";
2710 if (! (obj
->version
== 5))
2711 return "Integer out of bounds";
2716 socks5_server_method_encoded_len(const socks5_server_method_t
*obj
)
2720 if (NULL
!= socks5_server_method_check(obj
))
2724 /* Length of u8 version IN [5] */
2727 /* Length of u8 method */
2732 socks5_server_method_clear_errors(socks5_server_method_t
*obj
)
2734 int r
= obj
->trunnel_error_code_
;
2735 obj
->trunnel_error_code_
= 0;
2739 socks5_server_method_encode(uint8_t *output
, const size_t avail
, const socks5_server_method_t
*obj
)
2743 uint8_t *ptr
= output
;
2745 #ifdef TRUNNEL_CHECK_ENCODED_LEN
2746 const ssize_t encoded_len
= socks5_server_method_encoded_len(obj
);
2749 if (NULL
!= (msg
= socks5_server_method_check(obj
)))
2752 #ifdef TRUNNEL_CHECK_ENCODED_LEN
2753 trunnel_assert(encoded_len
>= 0);
2756 /* Encode u8 version IN [5] */
2757 trunnel_assert(written
<= avail
);
2758 if (avail
- written
< 1)
2760 trunnel_set_uint8(ptr
, (obj
->version
));
2761 written
+= 1; ptr
+= 1;
2763 /* Encode u8 method */
2764 trunnel_assert(written
<= avail
);
2765 if (avail
- written
< 1)
2767 trunnel_set_uint8(ptr
, (obj
->method
));
2768 written
+= 1; ptr
+= 1;
2771 trunnel_assert(ptr
== output
+ written
);
2772 #ifdef TRUNNEL_CHECK_ENCODED_LEN
2774 trunnel_assert(encoded_len
>= 0);
2775 trunnel_assert((size_t)encoded_len
== written
);
2790 trunnel_assert(result
< 0);
2794 /** As socks5_server_method_parse(), but do not allocate the output
2798 socks5_server_method_parse_into(socks5_server_method_t
*obj
, const uint8_t *input
, const size_t len_in
)
2800 const uint8_t *ptr
= input
;
2801 size_t remaining
= len_in
;
2805 /* Parse u8 version IN [5] */
2806 CHECK_REMAINING(1, truncated
);
2807 obj
->version
= (trunnel_get_uint8(ptr
));
2808 remaining
-= 1; ptr
+= 1;
2809 if (! (obj
->version
== 5))
2812 /* Parse u8 method */
2813 CHECK_REMAINING(1, truncated
);
2814 obj
->method
= (trunnel_get_uint8(ptr
));
2815 remaining
-= 1; ptr
+= 1;
2816 trunnel_assert(ptr
+ remaining
== input
+ len_in
);
2817 return len_in
- remaining
;
2827 socks5_server_method_parse(socks5_server_method_t
**output
, const uint8_t *input
, const size_t len_in
)
2830 *output
= socks5_server_method_new();
2831 if (NULL
== *output
)
2833 result
= socks5_server_method_parse_into(*output
, input
, len_in
);
2835 socks5_server_method_free(*output
);
2840 socks5_server_userpass_auth_t
*
2841 socks5_server_userpass_auth_new(void)
2843 socks5_server_userpass_auth_t
*val
= trunnel_calloc(1, sizeof(socks5_server_userpass_auth_t
));
2850 /** Release all storage held inside 'obj', but do not free 'obj'.
2853 socks5_server_userpass_auth_clear(socks5_server_userpass_auth_t
*obj
)
2859 socks5_server_userpass_auth_free(socks5_server_userpass_auth_t
*obj
)
2863 socks5_server_userpass_auth_clear(obj
);
2864 trunnel_memwipe(obj
, sizeof(socks5_server_userpass_auth_t
));
2869 socks5_server_userpass_auth_get_version(const socks5_server_userpass_auth_t
*inp
)
2871 return inp
->version
;
2874 socks5_server_userpass_auth_set_version(socks5_server_userpass_auth_t
*inp
, uint8_t val
)
2876 if (! ((val
== 1))) {
2877 TRUNNEL_SET_ERROR_CODE(inp
);
2884 socks5_server_userpass_auth_get_status(const socks5_server_userpass_auth_t
*inp
)
2889 socks5_server_userpass_auth_set_status(socks5_server_userpass_auth_t
*inp
, uint8_t val
)
2895 socks5_server_userpass_auth_check(const socks5_server_userpass_auth_t
*obj
)
2898 return "Object was NULL";
2899 if (obj
->trunnel_error_code_
)
2900 return "A set function failed on this object";
2901 if (! (obj
->version
== 1))
2902 return "Integer out of bounds";
2907 socks5_server_userpass_auth_encoded_len(const socks5_server_userpass_auth_t
*obj
)
2911 if (NULL
!= socks5_server_userpass_auth_check(obj
))
2915 /* Length of u8 version IN [1] */
2918 /* Length of u8 status */
2923 socks5_server_userpass_auth_clear_errors(socks5_server_userpass_auth_t
*obj
)
2925 int r
= obj
->trunnel_error_code_
;
2926 obj
->trunnel_error_code_
= 0;
2930 socks5_server_userpass_auth_encode(uint8_t *output
, const size_t avail
, const socks5_server_userpass_auth_t
*obj
)
2934 uint8_t *ptr
= output
;
2936 #ifdef TRUNNEL_CHECK_ENCODED_LEN
2937 const ssize_t encoded_len
= socks5_server_userpass_auth_encoded_len(obj
);
2940 if (NULL
!= (msg
= socks5_server_userpass_auth_check(obj
)))
2943 #ifdef TRUNNEL_CHECK_ENCODED_LEN
2944 trunnel_assert(encoded_len
>= 0);
2947 /* Encode u8 version IN [1] */
2948 trunnel_assert(written
<= avail
);
2949 if (avail
- written
< 1)
2951 trunnel_set_uint8(ptr
, (obj
->version
));
2952 written
+= 1; ptr
+= 1;
2954 /* Encode u8 status */
2955 trunnel_assert(written
<= avail
);
2956 if (avail
- written
< 1)
2958 trunnel_set_uint8(ptr
, (obj
->status
));
2959 written
+= 1; ptr
+= 1;
2962 trunnel_assert(ptr
== output
+ written
);
2963 #ifdef TRUNNEL_CHECK_ENCODED_LEN
2965 trunnel_assert(encoded_len
>= 0);
2966 trunnel_assert((size_t)encoded_len
== written
);
2981 trunnel_assert(result
< 0);
2985 /** As socks5_server_userpass_auth_parse(), but do not allocate the
2989 socks5_server_userpass_auth_parse_into(socks5_server_userpass_auth_t
*obj
, const uint8_t *input
, const size_t len_in
)
2991 const uint8_t *ptr
= input
;
2992 size_t remaining
= len_in
;
2996 /* Parse u8 version IN [1] */
2997 CHECK_REMAINING(1, truncated
);
2998 obj
->version
= (trunnel_get_uint8(ptr
));
2999 remaining
-= 1; ptr
+= 1;
3000 if (! (obj
->version
== 1))
3003 /* Parse u8 status */
3004 CHECK_REMAINING(1, truncated
);
3005 obj
->status
= (trunnel_get_uint8(ptr
));
3006 remaining
-= 1; ptr
+= 1;
3007 trunnel_assert(ptr
+ remaining
== input
+ len_in
);
3008 return len_in
- remaining
;
3018 socks5_server_userpass_auth_parse(socks5_server_userpass_auth_t
**output
, const uint8_t *input
, const size_t len_in
)
3021 *output
= socks5_server_userpass_auth_new();
3022 if (NULL
== *output
)
3024 result
= socks5_server_userpass_auth_parse_into(*output
, input
, len_in
);
3026 socks5_server_userpass_auth_free(*output
);
3031 socks5_client_request_t
*
3032 socks5_client_request_new(void)
3034 socks5_client_request_t
*val
= trunnel_calloc(1, sizeof(socks5_client_request_t
));
3038 val
->command
= CMD_BIND
;
3042 /** Release all storage held inside 'obj', but do not free 'obj'.
3045 socks5_client_request_clear(socks5_client_request_t
*obj
)
3048 domainname_free(obj
->dest_addr_domainname
);
3049 obj
->dest_addr_domainname
= NULL
;
3053 socks5_client_request_free(socks5_client_request_t
*obj
)
3057 socks5_client_request_clear(obj
);
3058 trunnel_memwipe(obj
, sizeof(socks5_client_request_t
));
3063 socks5_client_request_get_version(const socks5_client_request_t
*inp
)
3065 return inp
->version
;
3068 socks5_client_request_set_version(socks5_client_request_t
*inp
, uint8_t val
)
3070 if (! ((val
== 5))) {
3071 TRUNNEL_SET_ERROR_CODE(inp
);
3078 socks5_client_request_get_command(const socks5_client_request_t
*inp
)
3080 return inp
->command
;
3083 socks5_client_request_set_command(socks5_client_request_t
*inp
, uint8_t val
)
3085 if (! ((val
== CMD_BIND
|| val
== CMD_CONNECT
|| val
== CMD_RESOLVE
|| val
== CMD_RESOLVE_PTR
|| val
== CMD_UDP_ASSOCIATE
))) {
3086 TRUNNEL_SET_ERROR_CODE(inp
);
3093 socks5_client_request_get_reserved(const socks5_client_request_t
*inp
)
3095 return inp
->reserved
;
3098 socks5_client_request_set_reserved(socks5_client_request_t
*inp
, uint8_t val
)
3100 if (! ((val
== 0))) {
3101 TRUNNEL_SET_ERROR_CODE(inp
);
3104 inp
->reserved
= val
;
3108 socks5_client_request_get_atype(const socks5_client_request_t
*inp
)
3113 socks5_client_request_set_atype(socks5_client_request_t
*inp
, uint8_t val
)
3119 socks5_client_request_get_dest_addr_ipv4(const socks5_client_request_t
*inp
)
3121 return inp
->dest_addr_ipv4
;
3124 socks5_client_request_set_dest_addr_ipv4(socks5_client_request_t
*inp
, uint32_t val
)
3126 inp
->dest_addr_ipv4
= val
;
3130 socks5_client_request_getlen_dest_addr_ipv6(const socks5_client_request_t
*inp
)
3132 (void)inp
; return 16;
3136 socks5_client_request_get_dest_addr_ipv6(socks5_client_request_t
*inp
, size_t idx
)
3138 trunnel_assert(idx
< 16);
3139 return inp
->dest_addr_ipv6
[idx
];
3143 socks5_client_request_getconst_dest_addr_ipv6(const socks5_client_request_t
*inp
, size_t idx
)
3145 return socks5_client_request_get_dest_addr_ipv6((socks5_client_request_t
*)inp
, idx
);
3148 socks5_client_request_set_dest_addr_ipv6(socks5_client_request_t
*inp
, size_t idx
, uint8_t elt
)
3150 trunnel_assert(idx
< 16);
3151 inp
->dest_addr_ipv6
[idx
] = elt
;
3156 socks5_client_request_getarray_dest_addr_ipv6(socks5_client_request_t
*inp
)
3158 return inp
->dest_addr_ipv6
;
3161 socks5_client_request_getconstarray_dest_addr_ipv6(const socks5_client_request_t
*inp
)
3163 return (const uint8_t *)socks5_client_request_getarray_dest_addr_ipv6((socks5_client_request_t
*)inp
);
3165 struct domainname_st
*
3166 socks5_client_request_get_dest_addr_domainname(socks5_client_request_t
*inp
)
3168 return inp
->dest_addr_domainname
;
3170 const struct domainname_st
*
3171 socks5_client_request_getconst_dest_addr_domainname(const socks5_client_request_t
*inp
)
3173 return socks5_client_request_get_dest_addr_domainname((socks5_client_request_t
*) inp
);
3176 socks5_client_request_set_dest_addr_domainname(socks5_client_request_t
*inp
, struct domainname_st
*val
)
3178 if (inp
->dest_addr_domainname
&& inp
->dest_addr_domainname
!= val
)
3179 domainname_free(inp
->dest_addr_domainname
);
3180 return socks5_client_request_set0_dest_addr_domainname(inp
, val
);
3183 socks5_client_request_set0_dest_addr_domainname(socks5_client_request_t
*inp
, struct domainname_st
*val
)
3185 inp
->dest_addr_domainname
= val
;
3189 socks5_client_request_get_dest_port(const socks5_client_request_t
*inp
)
3191 return inp
->dest_port
;
3194 socks5_client_request_set_dest_port(socks5_client_request_t
*inp
, uint16_t val
)
3196 inp
->dest_port
= val
;
3200 socks5_client_request_check(const socks5_client_request_t
*obj
)
3203 return "Object was NULL";
3204 if (obj
->trunnel_error_code_
)
3205 return "A set function failed on this object";
3206 if (! (obj
->version
== 5))
3207 return "Integer out of bounds";
3208 if (! (obj
->command
== CMD_BIND
|| obj
->command
== CMD_CONNECT
|| obj
->command
== CMD_RESOLVE
|| obj
->command
== CMD_RESOLVE_PTR
|| obj
->command
== CMD_UDP_ASSOCIATE
))
3209 return "Integer out of bounds";
3210 if (! (obj
->reserved
== 0))
3211 return "Integer out of bounds";
3212 switch (obj
->atype
) {
3220 case ATYPE_DOMAINNAME
:
3223 if (NULL
!= (msg
= domainname_check(obj
->dest_addr_domainname
)))
3229 return "Bad tag for union";
3236 socks5_client_request_encoded_len(const socks5_client_request_t
*obj
)
3240 if (NULL
!= socks5_client_request_check(obj
))
3244 /* Length of u8 version IN [5] */
3247 /* Length of u8 command IN [CMD_BIND, CMD_CONNECT, CMD_RESOLVE, CMD_RESOLVE_PTR, CMD_UDP_ASSOCIATE] */
3250 /* Length of u8 reserved IN [0] */
3253 /* Length of u8 atype */
3255 switch (obj
->atype
) {
3259 /* Length of u32 dest_addr_ipv4 */
3265 /* Length of u8 dest_addr_ipv6[16] */
3269 case ATYPE_DOMAINNAME
:
3271 /* Length of struct domainname dest_addr_domainname */
3272 result
+= domainname_encoded_len(obj
->dest_addr_domainname
);
3280 /* Length of u16 dest_port */
3285 socks5_client_request_clear_errors(socks5_client_request_t
*obj
)
3287 int r
= obj
->trunnel_error_code_
;
3288 obj
->trunnel_error_code_
= 0;
3292 socks5_client_request_encode(uint8_t *output
, const size_t avail
, const socks5_client_request_t
*obj
)
3296 uint8_t *ptr
= output
;
3298 #ifdef TRUNNEL_CHECK_ENCODED_LEN
3299 const ssize_t encoded_len
= socks5_client_request_encoded_len(obj
);
3302 if (NULL
!= (msg
= socks5_client_request_check(obj
)))
3305 #ifdef TRUNNEL_CHECK_ENCODED_LEN
3306 trunnel_assert(encoded_len
>= 0);
3309 /* Encode u8 version IN [5] */
3310 trunnel_assert(written
<= avail
);
3311 if (avail
- written
< 1)
3313 trunnel_set_uint8(ptr
, (obj
->version
));
3314 written
+= 1; ptr
+= 1;
3316 /* Encode u8 command IN [CMD_BIND, CMD_CONNECT, CMD_RESOLVE, CMD_RESOLVE_PTR, CMD_UDP_ASSOCIATE] */
3317 trunnel_assert(written
<= avail
);
3318 if (avail
- written
< 1)
3320 trunnel_set_uint8(ptr
, (obj
->command
));
3321 written
+= 1; ptr
+= 1;
3323 /* Encode u8 reserved IN [0] */
3324 trunnel_assert(written
<= avail
);
3325 if (avail
- written
< 1)
3327 trunnel_set_uint8(ptr
, (obj
->reserved
));
3328 written
+= 1; ptr
+= 1;
3330 /* Encode u8 atype */
3331 trunnel_assert(written
<= avail
);
3332 if (avail
- written
< 1)
3334 trunnel_set_uint8(ptr
, (obj
->atype
));
3335 written
+= 1; ptr
+= 1;
3337 /* Encode union dest_addr[atype] */
3338 trunnel_assert(written
<= avail
);
3339 switch (obj
->atype
) {
3343 /* Encode u32 dest_addr_ipv4 */
3344 trunnel_assert(written
<= avail
);
3345 if (avail
- written
< 4)
3347 trunnel_set_uint32(ptr
, trunnel_htonl(obj
->dest_addr_ipv4
));
3348 written
+= 4; ptr
+= 4;
3353 /* Encode u8 dest_addr_ipv6[16] */
3354 trunnel_assert(written
<= avail
);
3355 if (avail
- written
< 16)
3357 memcpy(ptr
, obj
->dest_addr_ipv6
, 16);
3358 written
+= 16; ptr
+= 16;
3361 case ATYPE_DOMAINNAME
:
3363 /* Encode struct domainname dest_addr_domainname */
3364 trunnel_assert(written
<= avail
);
3365 result
= domainname_encode(ptr
, avail
- written
, obj
->dest_addr_domainname
);
3367 goto fail
; /* XXXXXXX !*/
3368 written
+= result
; ptr
+= result
;
3376 /* Encode u16 dest_port */
3377 trunnel_assert(written
<= avail
);
3378 if (avail
- written
< 2)
3380 trunnel_set_uint16(ptr
, trunnel_htons(obj
->dest_port
));
3381 written
+= 2; ptr
+= 2;
3384 trunnel_assert(ptr
== output
+ written
);
3385 #ifdef TRUNNEL_CHECK_ENCODED_LEN
3387 trunnel_assert(encoded_len
>= 0);
3388 trunnel_assert((size_t)encoded_len
== written
);
3403 trunnel_assert(result
< 0);
3407 /** As socks5_client_request_parse(), but do not allocate the output
3411 socks5_client_request_parse_into(socks5_client_request_t
*obj
, const uint8_t *input
, const size_t len_in
)
3413 const uint8_t *ptr
= input
;
3414 size_t remaining
= len_in
;
3418 /* Parse u8 version IN [5] */
3419 CHECK_REMAINING(1, truncated
);
3420 obj
->version
= (trunnel_get_uint8(ptr
));
3421 remaining
-= 1; ptr
+= 1;
3422 if (! (obj
->version
== 5))
3425 /* Parse u8 command IN [CMD_BIND, CMD_CONNECT, CMD_RESOLVE, CMD_RESOLVE_PTR, CMD_UDP_ASSOCIATE] */
3426 CHECK_REMAINING(1, truncated
);
3427 obj
->command
= (trunnel_get_uint8(ptr
));
3428 remaining
-= 1; ptr
+= 1;
3429 if (! (obj
->command
== CMD_BIND
|| obj
->command
== CMD_CONNECT
|| obj
->command
== CMD_RESOLVE
|| obj
->command
== CMD_RESOLVE_PTR
|| obj
->command
== CMD_UDP_ASSOCIATE
))
3432 /* Parse u8 reserved IN [0] */
3433 CHECK_REMAINING(1, truncated
);
3434 obj
->reserved
= (trunnel_get_uint8(ptr
));
3435 remaining
-= 1; ptr
+= 1;
3436 if (! (obj
->reserved
== 0))
3439 /* Parse u8 atype */
3440 CHECK_REMAINING(1, truncated
);
3441 obj
->atype
= (trunnel_get_uint8(ptr
));
3442 remaining
-= 1; ptr
+= 1;
3444 /* Parse union dest_addr[atype] */
3445 switch (obj
->atype
) {
3449 /* Parse u32 dest_addr_ipv4 */
3450 CHECK_REMAINING(4, truncated
);
3451 obj
->dest_addr_ipv4
= trunnel_ntohl(trunnel_get_uint32(ptr
));
3452 remaining
-= 4; ptr
+= 4;
3457 /* Parse u8 dest_addr_ipv6[16] */
3458 CHECK_REMAINING(16, truncated
);
3459 memcpy(obj
->dest_addr_ipv6
, ptr
, 16);
3460 remaining
-= 16; ptr
+= 16;
3463 case ATYPE_DOMAINNAME
:
3465 /* Parse struct domainname dest_addr_domainname */
3466 result
= domainname_parse(&obj
->dest_addr_domainname
, ptr
, remaining
);
3469 trunnel_assert((size_t)result
<= remaining
);
3470 remaining
-= result
; ptr
+= result
;
3478 /* Parse u16 dest_port */
3479 CHECK_REMAINING(2, truncated
);
3480 obj
->dest_port
= trunnel_ntohs(trunnel_get_uint16(ptr
));
3481 remaining
-= 2; ptr
+= 2;
3482 trunnel_assert(ptr
+ remaining
== input
+ len_in
);
3483 return len_in
- remaining
;
3488 trunnel_assert(result
< 0);
3496 socks5_client_request_parse(socks5_client_request_t
**output
, const uint8_t *input
, const size_t len_in
)
3499 *output
= socks5_client_request_new();
3500 if (NULL
== *output
)
3502 result
= socks5_client_request_parse_into(*output
, input
, len_in
);
3504 socks5_client_request_free(*output
);
3509 socks5_server_reply_t
*
3510 socks5_server_reply_new(void)
3512 socks5_server_reply_t
*val
= trunnel_calloc(1, sizeof(socks5_server_reply_t
));
3519 /** Release all storage held inside 'obj', but do not free 'obj'.
3522 socks5_server_reply_clear(socks5_server_reply_t
*obj
)
3525 domainname_free(obj
->bind_addr_domainname
);
3526 obj
->bind_addr_domainname
= NULL
;
3530 socks5_server_reply_free(socks5_server_reply_t
*obj
)
3534 socks5_server_reply_clear(obj
);
3535 trunnel_memwipe(obj
, sizeof(socks5_server_reply_t
));
3540 socks5_server_reply_get_version(const socks5_server_reply_t
*inp
)
3542 return inp
->version
;
3545 socks5_server_reply_set_version(socks5_server_reply_t
*inp
, uint8_t val
)
3547 if (! ((val
== 5))) {
3548 TRUNNEL_SET_ERROR_CODE(inp
);
3555 socks5_server_reply_get_reply(const socks5_server_reply_t
*inp
)
3560 socks5_server_reply_set_reply(socks5_server_reply_t
*inp
, uint8_t val
)
3566 socks5_server_reply_get_reserved(const socks5_server_reply_t
*inp
)
3568 return inp
->reserved
;
3571 socks5_server_reply_set_reserved(socks5_server_reply_t
*inp
, uint8_t val
)
3573 if (! ((val
== 0))) {
3574 TRUNNEL_SET_ERROR_CODE(inp
);
3577 inp
->reserved
= val
;
3581 socks5_server_reply_get_atype(const socks5_server_reply_t
*inp
)
3586 socks5_server_reply_set_atype(socks5_server_reply_t
*inp
, uint8_t val
)
3592 socks5_server_reply_get_bind_addr_ipv4(const socks5_server_reply_t
*inp
)
3594 return inp
->bind_addr_ipv4
;
3597 socks5_server_reply_set_bind_addr_ipv4(socks5_server_reply_t
*inp
, uint32_t val
)
3599 inp
->bind_addr_ipv4
= val
;
3603 socks5_server_reply_getlen_bind_addr_ipv6(const socks5_server_reply_t
*inp
)
3605 (void)inp
; return 16;
3609 socks5_server_reply_get_bind_addr_ipv6(socks5_server_reply_t
*inp
, size_t idx
)
3611 trunnel_assert(idx
< 16);
3612 return inp
->bind_addr_ipv6
[idx
];
3616 socks5_server_reply_getconst_bind_addr_ipv6(const socks5_server_reply_t
*inp
, size_t idx
)
3618 return socks5_server_reply_get_bind_addr_ipv6((socks5_server_reply_t
*)inp
, idx
);
3621 socks5_server_reply_set_bind_addr_ipv6(socks5_server_reply_t
*inp
, size_t idx
, uint8_t elt
)
3623 trunnel_assert(idx
< 16);
3624 inp
->bind_addr_ipv6
[idx
] = elt
;
3629 socks5_server_reply_getarray_bind_addr_ipv6(socks5_server_reply_t
*inp
)
3631 return inp
->bind_addr_ipv6
;
3634 socks5_server_reply_getconstarray_bind_addr_ipv6(const socks5_server_reply_t
*inp
)
3636 return (const uint8_t *)socks5_server_reply_getarray_bind_addr_ipv6((socks5_server_reply_t
*)inp
);
3638 struct domainname_st
*
3639 socks5_server_reply_get_bind_addr_domainname(socks5_server_reply_t
*inp
)
3641 return inp
->bind_addr_domainname
;
3643 const struct domainname_st
*
3644 socks5_server_reply_getconst_bind_addr_domainname(const socks5_server_reply_t
*inp
)
3646 return socks5_server_reply_get_bind_addr_domainname((socks5_server_reply_t
*) inp
);
3649 socks5_server_reply_set_bind_addr_domainname(socks5_server_reply_t
*inp
, struct domainname_st
*val
)
3651 if (inp
->bind_addr_domainname
&& inp
->bind_addr_domainname
!= val
)
3652 domainname_free(inp
->bind_addr_domainname
);
3653 return socks5_server_reply_set0_bind_addr_domainname(inp
, val
);
3656 socks5_server_reply_set0_bind_addr_domainname(socks5_server_reply_t
*inp
, struct domainname_st
*val
)
3658 inp
->bind_addr_domainname
= val
;
3662 socks5_server_reply_get_bind_port(const socks5_server_reply_t
*inp
)
3664 return inp
->bind_port
;
3667 socks5_server_reply_set_bind_port(socks5_server_reply_t
*inp
, uint16_t val
)
3669 inp
->bind_port
= val
;
3673 socks5_server_reply_check(const socks5_server_reply_t
*obj
)
3676 return "Object was NULL";
3677 if (obj
->trunnel_error_code_
)
3678 return "A set function failed on this object";
3679 if (! (obj
->version
== 5))
3680 return "Integer out of bounds";
3681 if (! (obj
->reserved
== 0))
3682 return "Integer out of bounds";
3683 switch (obj
->atype
) {
3691 case ATYPE_DOMAINNAME
:
3694 if (NULL
!= (msg
= domainname_check(obj
->bind_addr_domainname
)))
3700 return "Bad tag for union";
3707 socks5_server_reply_encoded_len(const socks5_server_reply_t
*obj
)
3711 if (NULL
!= socks5_server_reply_check(obj
))
3715 /* Length of u8 version IN [5] */
3718 /* Length of u8 reply */
3721 /* Length of u8 reserved IN [0] */
3724 /* Length of u8 atype */
3726 switch (obj
->atype
) {
3730 /* Length of u32 bind_addr_ipv4 */
3736 /* Length of u8 bind_addr_ipv6[16] */
3740 case ATYPE_DOMAINNAME
:
3742 /* Length of struct domainname bind_addr_domainname */
3743 result
+= domainname_encoded_len(obj
->bind_addr_domainname
);
3751 /* Length of u16 bind_port */
3756 socks5_server_reply_clear_errors(socks5_server_reply_t
*obj
)
3758 int r
= obj
->trunnel_error_code_
;
3759 obj
->trunnel_error_code_
= 0;
3763 socks5_server_reply_encode(uint8_t *output
, const size_t avail
, const socks5_server_reply_t
*obj
)
3767 uint8_t *ptr
= output
;
3769 #ifdef TRUNNEL_CHECK_ENCODED_LEN
3770 const ssize_t encoded_len
= socks5_server_reply_encoded_len(obj
);
3773 if (NULL
!= (msg
= socks5_server_reply_check(obj
)))
3776 #ifdef TRUNNEL_CHECK_ENCODED_LEN
3777 trunnel_assert(encoded_len
>= 0);
3780 /* Encode u8 version IN [5] */
3781 trunnel_assert(written
<= avail
);
3782 if (avail
- written
< 1)
3784 trunnel_set_uint8(ptr
, (obj
->version
));
3785 written
+= 1; ptr
+= 1;
3787 /* Encode u8 reply */
3788 trunnel_assert(written
<= avail
);
3789 if (avail
- written
< 1)
3791 trunnel_set_uint8(ptr
, (obj
->reply
));
3792 written
+= 1; ptr
+= 1;
3794 /* Encode u8 reserved IN [0] */
3795 trunnel_assert(written
<= avail
);
3796 if (avail
- written
< 1)
3798 trunnel_set_uint8(ptr
, (obj
->reserved
));
3799 written
+= 1; ptr
+= 1;
3801 /* Encode u8 atype */
3802 trunnel_assert(written
<= avail
);
3803 if (avail
- written
< 1)
3805 trunnel_set_uint8(ptr
, (obj
->atype
));
3806 written
+= 1; ptr
+= 1;
3808 /* Encode union bind_addr[atype] */
3809 trunnel_assert(written
<= avail
);
3810 switch (obj
->atype
) {
3814 /* Encode u32 bind_addr_ipv4 */
3815 trunnel_assert(written
<= avail
);
3816 if (avail
- written
< 4)
3818 trunnel_set_uint32(ptr
, trunnel_htonl(obj
->bind_addr_ipv4
));
3819 written
+= 4; ptr
+= 4;
3824 /* Encode u8 bind_addr_ipv6[16] */
3825 trunnel_assert(written
<= avail
);
3826 if (avail
- written
< 16)
3828 memcpy(ptr
, obj
->bind_addr_ipv6
, 16);
3829 written
+= 16; ptr
+= 16;
3832 case ATYPE_DOMAINNAME
:
3834 /* Encode struct domainname bind_addr_domainname */
3835 trunnel_assert(written
<= avail
);
3836 result
= domainname_encode(ptr
, avail
- written
, obj
->bind_addr_domainname
);
3838 goto fail
; /* XXXXXXX !*/
3839 written
+= result
; ptr
+= result
;
3847 /* Encode u16 bind_port */
3848 trunnel_assert(written
<= avail
);
3849 if (avail
- written
< 2)
3851 trunnel_set_uint16(ptr
, trunnel_htons(obj
->bind_port
));
3852 written
+= 2; ptr
+= 2;
3855 trunnel_assert(ptr
== output
+ written
);
3856 #ifdef TRUNNEL_CHECK_ENCODED_LEN
3858 trunnel_assert(encoded_len
>= 0);
3859 trunnel_assert((size_t)encoded_len
== written
);
3874 trunnel_assert(result
< 0);
3878 /** As socks5_server_reply_parse(), but do not allocate the output
3882 socks5_server_reply_parse_into(socks5_server_reply_t
*obj
, const uint8_t *input
, const size_t len_in
)
3884 const uint8_t *ptr
= input
;
3885 size_t remaining
= len_in
;
3889 /* Parse u8 version IN [5] */
3890 CHECK_REMAINING(1, truncated
);
3891 obj
->version
= (trunnel_get_uint8(ptr
));
3892 remaining
-= 1; ptr
+= 1;
3893 if (! (obj
->version
== 5))
3896 /* Parse u8 reply */
3897 CHECK_REMAINING(1, truncated
);
3898 obj
->reply
= (trunnel_get_uint8(ptr
));
3899 remaining
-= 1; ptr
+= 1;
3901 /* Parse u8 reserved IN [0] */
3902 CHECK_REMAINING(1, truncated
);
3903 obj
->reserved
= (trunnel_get_uint8(ptr
));
3904 remaining
-= 1; ptr
+= 1;
3905 if (! (obj
->reserved
== 0))
3908 /* Parse u8 atype */
3909 CHECK_REMAINING(1, truncated
);
3910 obj
->atype
= (trunnel_get_uint8(ptr
));
3911 remaining
-= 1; ptr
+= 1;
3913 /* Parse union bind_addr[atype] */
3914 switch (obj
->atype
) {
3918 /* Parse u32 bind_addr_ipv4 */
3919 CHECK_REMAINING(4, truncated
);
3920 obj
->bind_addr_ipv4
= trunnel_ntohl(trunnel_get_uint32(ptr
));
3921 remaining
-= 4; ptr
+= 4;
3926 /* Parse u8 bind_addr_ipv6[16] */
3927 CHECK_REMAINING(16, truncated
);
3928 memcpy(obj
->bind_addr_ipv6
, ptr
, 16);
3929 remaining
-= 16; ptr
+= 16;
3932 case ATYPE_DOMAINNAME
:
3934 /* Parse struct domainname bind_addr_domainname */
3935 result
= domainname_parse(&obj
->bind_addr_domainname
, ptr
, remaining
);
3938 trunnel_assert((size_t)result
<= remaining
);
3939 remaining
-= result
; ptr
+= result
;
3947 /* Parse u16 bind_port */
3948 CHECK_REMAINING(2, truncated
);
3949 obj
->bind_port
= trunnel_ntohs(trunnel_get_uint16(ptr
));
3950 remaining
-= 2; ptr
+= 2;
3951 trunnel_assert(ptr
+ remaining
== input
+ len_in
);
3952 return len_in
- remaining
;
3957 trunnel_assert(result
< 0);
3965 socks5_server_reply_parse(socks5_server_reply_t
**output
, const uint8_t *input
, const size_t len_in
)
3968 *output
= socks5_server_reply_new();
3969 if (NULL
== *output
)
3971 result
= socks5_server_reply_parse_into(*output
, input
, len_in
);
3973 socks5_server_reply_free(*output
);