1 /* socks5.c -- generated by Trunnel v1.5.2.
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
));
1701 /** Release all storage held inside 'obj', but do not free 'obj'.
1704 socks4_server_reply_clear(socks4_server_reply_t
*obj
)
1710 socks4_server_reply_free(socks4_server_reply_t
*obj
)
1714 socks4_server_reply_clear(obj
);
1715 trunnel_memwipe(obj
, sizeof(socks4_server_reply_t
));
1720 socks4_server_reply_get_version(const socks4_server_reply_t
*inp
)
1722 return inp
->version
;
1725 socks4_server_reply_set_version(socks4_server_reply_t
*inp
, uint8_t val
)
1727 if (! ((val
== 4))) {
1728 TRUNNEL_SET_ERROR_CODE(inp
);
1735 socks4_server_reply_get_status(const socks4_server_reply_t
*inp
)
1740 socks4_server_reply_set_status(socks4_server_reply_t
*inp
, uint8_t val
)
1746 socks4_server_reply_get_port(const socks4_server_reply_t
*inp
)
1751 socks4_server_reply_set_port(socks4_server_reply_t
*inp
, uint16_t val
)
1757 socks4_server_reply_get_addr(const socks4_server_reply_t
*inp
)
1762 socks4_server_reply_set_addr(socks4_server_reply_t
*inp
, uint32_t val
)
1768 socks4_server_reply_check(const socks4_server_reply_t
*obj
)
1771 return "Object was NULL";
1772 if (obj
->trunnel_error_code_
)
1773 return "A set function failed on this object";
1774 if (! (obj
->version
== 4))
1775 return "Integer out of bounds";
1780 socks4_server_reply_encoded_len(const socks4_server_reply_t
*obj
)
1784 if (NULL
!= socks4_server_reply_check(obj
))
1788 /* Length of u8 version IN [4] */
1791 /* Length of u8 status */
1794 /* Length of u16 port */
1797 /* Length of u32 addr */
1802 socks4_server_reply_clear_errors(socks4_server_reply_t
*obj
)
1804 int r
= obj
->trunnel_error_code_
;
1805 obj
->trunnel_error_code_
= 0;
1809 socks4_server_reply_encode(uint8_t *output
, const size_t avail
, const socks4_server_reply_t
*obj
)
1813 uint8_t *ptr
= output
;
1815 #ifdef TRUNNEL_CHECK_ENCODED_LEN
1816 const ssize_t encoded_len
= socks4_server_reply_encoded_len(obj
);
1819 if (NULL
!= (msg
= socks4_server_reply_check(obj
)))
1822 #ifdef TRUNNEL_CHECK_ENCODED_LEN
1823 trunnel_assert(encoded_len
>= 0);
1826 /* Encode u8 version IN [4] */
1827 trunnel_assert(written
<= avail
);
1828 if (avail
- written
< 1)
1830 trunnel_set_uint8(ptr
, (obj
->version
));
1831 written
+= 1; ptr
+= 1;
1833 /* Encode u8 status */
1834 trunnel_assert(written
<= avail
);
1835 if (avail
- written
< 1)
1837 trunnel_set_uint8(ptr
, (obj
->status
));
1838 written
+= 1; ptr
+= 1;
1840 /* Encode u16 port */
1841 trunnel_assert(written
<= avail
);
1842 if (avail
- written
< 2)
1844 trunnel_set_uint16(ptr
, trunnel_htons(obj
->port
));
1845 written
+= 2; ptr
+= 2;
1847 /* Encode u32 addr */
1848 trunnel_assert(written
<= avail
);
1849 if (avail
- written
< 4)
1851 trunnel_set_uint32(ptr
, trunnel_htonl(obj
->addr
));
1852 written
+= 4; ptr
+= 4;
1855 trunnel_assert(ptr
== output
+ written
);
1856 #ifdef TRUNNEL_CHECK_ENCODED_LEN
1858 trunnel_assert(encoded_len
>= 0);
1859 trunnel_assert((size_t)encoded_len
== written
);
1874 trunnel_assert(result
< 0);
1878 /** As socks4_server_reply_parse(), but do not allocate the output
1882 socks4_server_reply_parse_into(socks4_server_reply_t
*obj
, const uint8_t *input
, const size_t len_in
)
1884 const uint8_t *ptr
= input
;
1885 size_t remaining
= len_in
;
1889 /* Parse u8 version IN [4] */
1890 CHECK_REMAINING(1, truncated
);
1891 obj
->version
= (trunnel_get_uint8(ptr
));
1892 remaining
-= 1; ptr
+= 1;
1893 if (! (obj
->version
== 4))
1896 /* Parse u8 status */
1897 CHECK_REMAINING(1, truncated
);
1898 obj
->status
= (trunnel_get_uint8(ptr
));
1899 remaining
-= 1; ptr
+= 1;
1901 /* Parse u16 port */
1902 CHECK_REMAINING(2, truncated
);
1903 obj
->port
= trunnel_ntohs(trunnel_get_uint16(ptr
));
1904 remaining
-= 2; ptr
+= 2;
1906 /* Parse u32 addr */
1907 CHECK_REMAINING(4, truncated
);
1908 obj
->addr
= trunnel_ntohl(trunnel_get_uint32(ptr
));
1909 remaining
-= 4; ptr
+= 4;
1910 trunnel_assert(ptr
+ remaining
== input
+ len_in
);
1911 return len_in
- remaining
;
1921 socks4_server_reply_parse(socks4_server_reply_t
**output
, const uint8_t *input
, const size_t len_in
)
1924 *output
= socks4_server_reply_new();
1925 if (NULL
== *output
)
1927 result
= socks4_server_reply_parse_into(*output
, input
, len_in
);
1929 socks4_server_reply_free(*output
);
1934 socks5_client_userpass_auth_t
*
1935 socks5_client_userpass_auth_new(void)
1937 socks5_client_userpass_auth_t
*val
= trunnel_calloc(1, sizeof(socks5_client_userpass_auth_t
));
1944 /** Release all storage held inside 'obj', but do not free 'obj'.
1947 socks5_client_userpass_auth_clear(socks5_client_userpass_auth_t
*obj
)
1950 TRUNNEL_DYNARRAY_WIPE(&obj
->username
);
1951 TRUNNEL_DYNARRAY_CLEAR(&obj
->username
);
1952 TRUNNEL_DYNARRAY_WIPE(&obj
->passwd
);
1953 TRUNNEL_DYNARRAY_CLEAR(&obj
->passwd
);
1957 socks5_client_userpass_auth_free(socks5_client_userpass_auth_t
*obj
)
1961 socks5_client_userpass_auth_clear(obj
);
1962 trunnel_memwipe(obj
, sizeof(socks5_client_userpass_auth_t
));
1967 socks5_client_userpass_auth_get_version(const socks5_client_userpass_auth_t
*inp
)
1969 return inp
->version
;
1972 socks5_client_userpass_auth_set_version(socks5_client_userpass_auth_t
*inp
, uint8_t val
)
1974 if (! ((val
== 1))) {
1975 TRUNNEL_SET_ERROR_CODE(inp
);
1982 socks5_client_userpass_auth_get_username_len(const socks5_client_userpass_auth_t
*inp
)
1984 return inp
->username_len
;
1987 socks5_client_userpass_auth_set_username_len(socks5_client_userpass_auth_t
*inp
, uint8_t val
)
1989 inp
->username_len
= val
;
1993 socks5_client_userpass_auth_getlen_username(const socks5_client_userpass_auth_t
*inp
)
1995 return TRUNNEL_DYNARRAY_LEN(&inp
->username
);
1999 socks5_client_userpass_auth_get_username(socks5_client_userpass_auth_t
*inp
, size_t idx
)
2001 return TRUNNEL_DYNARRAY_GET(&inp
->username
, idx
);
2005 socks5_client_userpass_auth_getconst_username(const socks5_client_userpass_auth_t
*inp
, size_t idx
)
2007 return socks5_client_userpass_auth_get_username((socks5_client_userpass_auth_t
*)inp
, idx
);
2010 socks5_client_userpass_auth_set_username(socks5_client_userpass_auth_t
*inp
, size_t idx
, char elt
)
2012 TRUNNEL_DYNARRAY_SET(&inp
->username
, idx
, elt
);
2016 socks5_client_userpass_auth_add_username(socks5_client_userpass_auth_t
*inp
, char elt
)
2018 #if SIZE_MAX >= UINT8_MAX
2019 if (inp
->username
.n_
== UINT8_MAX
)
2020 goto trunnel_alloc_failed
;
2022 TRUNNEL_DYNARRAY_ADD(char, &inp
->username
, elt
, {});
2024 trunnel_alloc_failed
:
2025 TRUNNEL_SET_ERROR_CODE(inp
);
2030 socks5_client_userpass_auth_getarray_username(socks5_client_userpass_auth_t
*inp
)
2032 return inp
->username
.elts_
;
2035 socks5_client_userpass_auth_getconstarray_username(const socks5_client_userpass_auth_t
*inp
)
2037 return (const char *)socks5_client_userpass_auth_getarray_username((socks5_client_userpass_auth_t
*)inp
);
2040 socks5_client_userpass_auth_setlen_username(socks5_client_userpass_auth_t
*inp
, size_t newlen
)
2042 #if UINT8_MAX < SIZE_MAX
2043 if (newlen
> UINT8_MAX
)
2044 goto trunnel_alloc_failed
;
2046 return trunnel_string_setlen(&inp
->username
, newlen
,
2047 &inp
->trunnel_error_code_
);
2048 trunnel_alloc_failed
:
2049 TRUNNEL_SET_ERROR_CODE(inp
);
2053 socks5_client_userpass_auth_getstr_username(socks5_client_userpass_auth_t
*inp
)
2055 return trunnel_string_getstr(&inp
->username
);
2058 socks5_client_userpass_auth_setstr0_username(socks5_client_userpass_auth_t
*inp
, const char *val
, size_t len
)
2060 #if UINT8_MAX < SIZE_MAX
2061 if (len
> UINT8_MAX
) {
2062 TRUNNEL_SET_ERROR_CODE(inp
);
2066 return trunnel_string_setstr0(&inp
->username
, val
, len
, &inp
->trunnel_error_code_
);
2069 socks5_client_userpass_auth_setstr_username(socks5_client_userpass_auth_t
*inp
, const char *val
)
2071 return socks5_client_userpass_auth_setstr0_username(inp
, val
, strlen(val
));
2074 socks5_client_userpass_auth_get_passwd_len(const socks5_client_userpass_auth_t
*inp
)
2076 return inp
->passwd_len
;
2079 socks5_client_userpass_auth_set_passwd_len(socks5_client_userpass_auth_t
*inp
, uint8_t val
)
2081 inp
->passwd_len
= val
;
2085 socks5_client_userpass_auth_getlen_passwd(const socks5_client_userpass_auth_t
*inp
)
2087 return TRUNNEL_DYNARRAY_LEN(&inp
->passwd
);
2091 socks5_client_userpass_auth_get_passwd(socks5_client_userpass_auth_t
*inp
, size_t idx
)
2093 return TRUNNEL_DYNARRAY_GET(&inp
->passwd
, idx
);
2097 socks5_client_userpass_auth_getconst_passwd(const socks5_client_userpass_auth_t
*inp
, size_t idx
)
2099 return socks5_client_userpass_auth_get_passwd((socks5_client_userpass_auth_t
*)inp
, idx
);
2102 socks5_client_userpass_auth_set_passwd(socks5_client_userpass_auth_t
*inp
, size_t idx
, char elt
)
2104 TRUNNEL_DYNARRAY_SET(&inp
->passwd
, idx
, elt
);
2108 socks5_client_userpass_auth_add_passwd(socks5_client_userpass_auth_t
*inp
, char elt
)
2110 #if SIZE_MAX >= UINT8_MAX
2111 if (inp
->passwd
.n_
== UINT8_MAX
)
2112 goto trunnel_alloc_failed
;
2114 TRUNNEL_DYNARRAY_ADD(char, &inp
->passwd
, elt
, {});
2116 trunnel_alloc_failed
:
2117 TRUNNEL_SET_ERROR_CODE(inp
);
2122 socks5_client_userpass_auth_getarray_passwd(socks5_client_userpass_auth_t
*inp
)
2124 return inp
->passwd
.elts_
;
2127 socks5_client_userpass_auth_getconstarray_passwd(const socks5_client_userpass_auth_t
*inp
)
2129 return (const char *)socks5_client_userpass_auth_getarray_passwd((socks5_client_userpass_auth_t
*)inp
);
2132 socks5_client_userpass_auth_setlen_passwd(socks5_client_userpass_auth_t
*inp
, size_t newlen
)
2134 #if UINT8_MAX < SIZE_MAX
2135 if (newlen
> UINT8_MAX
)
2136 goto trunnel_alloc_failed
;
2138 return trunnel_string_setlen(&inp
->passwd
, newlen
,
2139 &inp
->trunnel_error_code_
);
2140 trunnel_alloc_failed
:
2141 TRUNNEL_SET_ERROR_CODE(inp
);
2145 socks5_client_userpass_auth_getstr_passwd(socks5_client_userpass_auth_t
*inp
)
2147 return trunnel_string_getstr(&inp
->passwd
);
2150 socks5_client_userpass_auth_setstr0_passwd(socks5_client_userpass_auth_t
*inp
, const char *val
, size_t len
)
2152 #if UINT8_MAX < SIZE_MAX
2153 if (len
> UINT8_MAX
) {
2154 TRUNNEL_SET_ERROR_CODE(inp
);
2158 return trunnel_string_setstr0(&inp
->passwd
, val
, len
, &inp
->trunnel_error_code_
);
2161 socks5_client_userpass_auth_setstr_passwd(socks5_client_userpass_auth_t
*inp
, const char *val
)
2163 return socks5_client_userpass_auth_setstr0_passwd(inp
, val
, strlen(val
));
2166 socks5_client_userpass_auth_check(const socks5_client_userpass_auth_t
*obj
)
2169 return "Object was NULL";
2170 if (obj
->trunnel_error_code_
)
2171 return "A set function failed on this object";
2172 if (! (obj
->version
== 1))
2173 return "Integer out of bounds";
2174 if (TRUNNEL_DYNARRAY_LEN(&obj
->username
) != obj
->username_len
)
2175 return "Length mismatch for username";
2176 if (TRUNNEL_DYNARRAY_LEN(&obj
->passwd
) != obj
->passwd_len
)
2177 return "Length mismatch for passwd";
2182 socks5_client_userpass_auth_encoded_len(const socks5_client_userpass_auth_t
*obj
)
2186 if (NULL
!= socks5_client_userpass_auth_check(obj
))
2190 /* Length of u8 version IN [1] */
2193 /* Length of u8 username_len */
2196 /* Length of char username[username_len] */
2197 result
+= TRUNNEL_DYNARRAY_LEN(&obj
->username
);
2199 /* Length of u8 passwd_len */
2202 /* Length of char passwd[passwd_len] */
2203 result
+= TRUNNEL_DYNARRAY_LEN(&obj
->passwd
);
2207 socks5_client_userpass_auth_clear_errors(socks5_client_userpass_auth_t
*obj
)
2209 int r
= obj
->trunnel_error_code_
;
2210 obj
->trunnel_error_code_
= 0;
2214 socks5_client_userpass_auth_encode(uint8_t *output
, const size_t avail
, const socks5_client_userpass_auth_t
*obj
)
2218 uint8_t *ptr
= output
;
2220 #ifdef TRUNNEL_CHECK_ENCODED_LEN
2221 const ssize_t encoded_len
= socks5_client_userpass_auth_encoded_len(obj
);
2224 if (NULL
!= (msg
= socks5_client_userpass_auth_check(obj
)))
2227 #ifdef TRUNNEL_CHECK_ENCODED_LEN
2228 trunnel_assert(encoded_len
>= 0);
2231 /* Encode u8 version IN [1] */
2232 trunnel_assert(written
<= avail
);
2233 if (avail
- written
< 1)
2235 trunnel_set_uint8(ptr
, (obj
->version
));
2236 written
+= 1; ptr
+= 1;
2238 /* Encode u8 username_len */
2239 trunnel_assert(written
<= avail
);
2240 if (avail
- written
< 1)
2242 trunnel_set_uint8(ptr
, (obj
->username_len
));
2243 written
+= 1; ptr
+= 1;
2245 /* Encode char username[username_len] */
2247 size_t elt_len
= TRUNNEL_DYNARRAY_LEN(&obj
->username
);
2248 trunnel_assert(obj
->username_len
== elt_len
);
2249 trunnel_assert(written
<= avail
);
2250 if (avail
- written
< elt_len
)
2253 memcpy(ptr
, obj
->username
.elts_
, elt_len
);
2254 written
+= elt_len
; ptr
+= elt_len
;
2257 /* Encode u8 passwd_len */
2258 trunnel_assert(written
<= avail
);
2259 if (avail
- written
< 1)
2261 trunnel_set_uint8(ptr
, (obj
->passwd_len
));
2262 written
+= 1; ptr
+= 1;
2264 /* Encode char passwd[passwd_len] */
2266 size_t elt_len
= TRUNNEL_DYNARRAY_LEN(&obj
->passwd
);
2267 trunnel_assert(obj
->passwd_len
== elt_len
);
2268 trunnel_assert(written
<= avail
);
2269 if (avail
- written
< elt_len
)
2272 memcpy(ptr
, obj
->passwd
.elts_
, elt_len
);
2273 written
+= elt_len
; ptr
+= elt_len
;
2277 trunnel_assert(ptr
== output
+ written
);
2278 #ifdef TRUNNEL_CHECK_ENCODED_LEN
2280 trunnel_assert(encoded_len
>= 0);
2281 trunnel_assert((size_t)encoded_len
== written
);
2296 trunnel_assert(result
< 0);
2300 /** As socks5_client_userpass_auth_parse(), but do not allocate the
2304 socks5_client_userpass_auth_parse_into(socks5_client_userpass_auth_t
*obj
, const uint8_t *input
, const size_t len_in
)
2306 const uint8_t *ptr
= input
;
2307 size_t remaining
= len_in
;
2311 /* Parse u8 version IN [1] */
2312 CHECK_REMAINING(1, truncated
);
2313 obj
->version
= (trunnel_get_uint8(ptr
));
2314 remaining
-= 1; ptr
+= 1;
2315 if (! (obj
->version
== 1))
2318 /* Parse u8 username_len */
2319 CHECK_REMAINING(1, truncated
);
2320 obj
->username_len
= (trunnel_get_uint8(ptr
));
2321 remaining
-= 1; ptr
+= 1;
2323 /* Parse char username[username_len] */
2324 CHECK_REMAINING(obj
->username_len
, truncated
);
2325 if (socks5_client_userpass_auth_setstr0_username(obj
, (const char*)ptr
, obj
->username_len
))
2327 ptr
+= obj
->username_len
; remaining
-= obj
->username_len
;
2329 /* Parse u8 passwd_len */
2330 CHECK_REMAINING(1, truncated
);
2331 obj
->passwd_len
= (trunnel_get_uint8(ptr
));
2332 remaining
-= 1; ptr
+= 1;
2334 /* Parse char passwd[passwd_len] */
2335 CHECK_REMAINING(obj
->passwd_len
, truncated
);
2336 if (socks5_client_userpass_auth_setstr0_passwd(obj
, (const char*)ptr
, obj
->passwd_len
))
2338 ptr
+= obj
->passwd_len
; remaining
-= obj
->passwd_len
;
2339 trunnel_assert(ptr
+ remaining
== input
+ len_in
);
2340 return len_in
- remaining
;
2350 socks5_client_userpass_auth_parse(socks5_client_userpass_auth_t
**output
, const uint8_t *input
, const size_t len_in
)
2353 *output
= socks5_client_userpass_auth_new();
2354 if (NULL
== *output
)
2356 result
= socks5_client_userpass_auth_parse_into(*output
, input
, len_in
);
2358 socks5_client_userpass_auth_free(*output
);
2363 socks5_client_version_t
*
2364 socks5_client_version_new(void)
2366 socks5_client_version_t
*val
= trunnel_calloc(1, sizeof(socks5_client_version_t
));
2373 /** Release all storage held inside 'obj', but do not free 'obj'.
2376 socks5_client_version_clear(socks5_client_version_t
*obj
)
2379 TRUNNEL_DYNARRAY_WIPE(&obj
->methods
);
2380 TRUNNEL_DYNARRAY_CLEAR(&obj
->methods
);
2384 socks5_client_version_free(socks5_client_version_t
*obj
)
2388 socks5_client_version_clear(obj
);
2389 trunnel_memwipe(obj
, sizeof(socks5_client_version_t
));
2394 socks5_client_version_get_version(const socks5_client_version_t
*inp
)
2396 return inp
->version
;
2399 socks5_client_version_set_version(socks5_client_version_t
*inp
, uint8_t val
)
2401 if (! ((val
== 5))) {
2402 TRUNNEL_SET_ERROR_CODE(inp
);
2409 socks5_client_version_get_n_methods(const socks5_client_version_t
*inp
)
2411 return inp
->n_methods
;
2414 socks5_client_version_set_n_methods(socks5_client_version_t
*inp
, uint8_t val
)
2416 inp
->n_methods
= val
;
2420 socks5_client_version_getlen_methods(const socks5_client_version_t
*inp
)
2422 return TRUNNEL_DYNARRAY_LEN(&inp
->methods
);
2426 socks5_client_version_get_methods(socks5_client_version_t
*inp
, size_t idx
)
2428 return TRUNNEL_DYNARRAY_GET(&inp
->methods
, idx
);
2432 socks5_client_version_getconst_methods(const socks5_client_version_t
*inp
, size_t idx
)
2434 return socks5_client_version_get_methods((socks5_client_version_t
*)inp
, idx
);
2437 socks5_client_version_set_methods(socks5_client_version_t
*inp
, size_t idx
, uint8_t elt
)
2439 TRUNNEL_DYNARRAY_SET(&inp
->methods
, idx
, elt
);
2443 socks5_client_version_add_methods(socks5_client_version_t
*inp
, uint8_t elt
)
2445 #if SIZE_MAX >= UINT8_MAX
2446 if (inp
->methods
.n_
== UINT8_MAX
)
2447 goto trunnel_alloc_failed
;
2449 TRUNNEL_DYNARRAY_ADD(uint8_t, &inp
->methods
, elt
, {});
2451 trunnel_alloc_failed
:
2452 TRUNNEL_SET_ERROR_CODE(inp
);
2457 socks5_client_version_getarray_methods(socks5_client_version_t
*inp
)
2459 return inp
->methods
.elts_
;
2462 socks5_client_version_getconstarray_methods(const socks5_client_version_t
*inp
)
2464 return (const uint8_t *)socks5_client_version_getarray_methods((socks5_client_version_t
*)inp
);
2467 socks5_client_version_setlen_methods(socks5_client_version_t
*inp
, size_t newlen
)
2470 #if UINT8_MAX < SIZE_MAX
2471 if (newlen
> UINT8_MAX
)
2472 goto trunnel_alloc_failed
;
2474 newptr
= trunnel_dynarray_setlen(&inp
->methods
.allocated_
,
2475 &inp
->methods
.n_
, inp
->methods
.elts_
, newlen
,
2476 sizeof(inp
->methods
.elts_
[0]), (trunnel_free_fn_t
) NULL
,
2477 &inp
->trunnel_error_code_
);
2478 if (newlen
!= 0 && newptr
== NULL
)
2479 goto trunnel_alloc_failed
;
2480 inp
->methods
.elts_
= newptr
;
2482 trunnel_alloc_failed
:
2483 TRUNNEL_SET_ERROR_CODE(inp
);
2487 socks5_client_version_check(const socks5_client_version_t
*obj
)
2490 return "Object was NULL";
2491 if (obj
->trunnel_error_code_
)
2492 return "A set function failed on this object";
2493 if (! (obj
->version
== 5))
2494 return "Integer out of bounds";
2495 if (TRUNNEL_DYNARRAY_LEN(&obj
->methods
) != obj
->n_methods
)
2496 return "Length mismatch for methods";
2501 socks5_client_version_encoded_len(const socks5_client_version_t
*obj
)
2505 if (NULL
!= socks5_client_version_check(obj
))
2509 /* Length of u8 version IN [5] */
2512 /* Length of u8 n_methods */
2515 /* Length of u8 methods[n_methods] */
2516 result
+= TRUNNEL_DYNARRAY_LEN(&obj
->methods
);
2520 socks5_client_version_clear_errors(socks5_client_version_t
*obj
)
2522 int r
= obj
->trunnel_error_code_
;
2523 obj
->trunnel_error_code_
= 0;
2527 socks5_client_version_encode(uint8_t *output
, const size_t avail
, const socks5_client_version_t
*obj
)
2531 uint8_t *ptr
= output
;
2533 #ifdef TRUNNEL_CHECK_ENCODED_LEN
2534 const ssize_t encoded_len
= socks5_client_version_encoded_len(obj
);
2537 if (NULL
!= (msg
= socks5_client_version_check(obj
)))
2540 #ifdef TRUNNEL_CHECK_ENCODED_LEN
2541 trunnel_assert(encoded_len
>= 0);
2544 /* Encode u8 version IN [5] */
2545 trunnel_assert(written
<= avail
);
2546 if (avail
- written
< 1)
2548 trunnel_set_uint8(ptr
, (obj
->version
));
2549 written
+= 1; ptr
+= 1;
2551 /* Encode u8 n_methods */
2552 trunnel_assert(written
<= avail
);
2553 if (avail
- written
< 1)
2555 trunnel_set_uint8(ptr
, (obj
->n_methods
));
2556 written
+= 1; ptr
+= 1;
2558 /* Encode u8 methods[n_methods] */
2560 size_t elt_len
= TRUNNEL_DYNARRAY_LEN(&obj
->methods
);
2561 trunnel_assert(obj
->n_methods
== elt_len
);
2562 trunnel_assert(written
<= avail
);
2563 if (avail
- written
< elt_len
)
2566 memcpy(ptr
, obj
->methods
.elts_
, elt_len
);
2567 written
+= elt_len
; ptr
+= elt_len
;
2571 trunnel_assert(ptr
== output
+ written
);
2572 #ifdef TRUNNEL_CHECK_ENCODED_LEN
2574 trunnel_assert(encoded_len
>= 0);
2575 trunnel_assert((size_t)encoded_len
== written
);
2590 trunnel_assert(result
< 0);
2594 /** As socks5_client_version_parse(), but do not allocate the output
2598 socks5_client_version_parse_into(socks5_client_version_t
*obj
, const uint8_t *input
, const size_t len_in
)
2600 const uint8_t *ptr
= input
;
2601 size_t remaining
= len_in
;
2605 /* Parse u8 version IN [5] */
2606 CHECK_REMAINING(1, truncated
);
2607 obj
->version
= (trunnel_get_uint8(ptr
));
2608 remaining
-= 1; ptr
+= 1;
2609 if (! (obj
->version
== 5))
2612 /* Parse u8 n_methods */
2613 CHECK_REMAINING(1, truncated
);
2614 obj
->n_methods
= (trunnel_get_uint8(ptr
));
2615 remaining
-= 1; ptr
+= 1;
2617 /* Parse u8 methods[n_methods] */
2618 CHECK_REMAINING(obj
->n_methods
, truncated
);
2619 TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj
->methods
, obj
->n_methods
, {});
2620 obj
->methods
.n_
= obj
->n_methods
;
2622 memcpy(obj
->methods
.elts_
, ptr
, obj
->n_methods
);
2623 ptr
+= obj
->n_methods
; remaining
-= obj
->n_methods
;
2624 trunnel_assert(ptr
+ remaining
== input
+ len_in
);
2625 return len_in
- remaining
;
2629 trunnel_alloc_failed
:
2637 socks5_client_version_parse(socks5_client_version_t
**output
, const uint8_t *input
, const size_t len_in
)
2640 *output
= socks5_client_version_new();
2641 if (NULL
== *output
)
2643 result
= socks5_client_version_parse_into(*output
, input
, len_in
);
2645 socks5_client_version_free(*output
);
2650 socks5_server_method_t
*
2651 socks5_server_method_new(void)
2653 socks5_server_method_t
*val
= trunnel_calloc(1, sizeof(socks5_server_method_t
));
2660 /** Release all storage held inside 'obj', but do not free 'obj'.
2663 socks5_server_method_clear(socks5_server_method_t
*obj
)
2669 socks5_server_method_free(socks5_server_method_t
*obj
)
2673 socks5_server_method_clear(obj
);
2674 trunnel_memwipe(obj
, sizeof(socks5_server_method_t
));
2679 socks5_server_method_get_version(const socks5_server_method_t
*inp
)
2681 return inp
->version
;
2684 socks5_server_method_set_version(socks5_server_method_t
*inp
, uint8_t val
)
2686 if (! ((val
== 5))) {
2687 TRUNNEL_SET_ERROR_CODE(inp
);
2694 socks5_server_method_get_method(const socks5_server_method_t
*inp
)
2699 socks5_server_method_set_method(socks5_server_method_t
*inp
, uint8_t val
)
2705 socks5_server_method_check(const socks5_server_method_t
*obj
)
2708 return "Object was NULL";
2709 if (obj
->trunnel_error_code_
)
2710 return "A set function failed on this object";
2711 if (! (obj
->version
== 5))
2712 return "Integer out of bounds";
2717 socks5_server_method_encoded_len(const socks5_server_method_t
*obj
)
2721 if (NULL
!= socks5_server_method_check(obj
))
2725 /* Length of u8 version IN [5] */
2728 /* Length of u8 method */
2733 socks5_server_method_clear_errors(socks5_server_method_t
*obj
)
2735 int r
= obj
->trunnel_error_code_
;
2736 obj
->trunnel_error_code_
= 0;
2740 socks5_server_method_encode(uint8_t *output
, const size_t avail
, const socks5_server_method_t
*obj
)
2744 uint8_t *ptr
= output
;
2746 #ifdef TRUNNEL_CHECK_ENCODED_LEN
2747 const ssize_t encoded_len
= socks5_server_method_encoded_len(obj
);
2750 if (NULL
!= (msg
= socks5_server_method_check(obj
)))
2753 #ifdef TRUNNEL_CHECK_ENCODED_LEN
2754 trunnel_assert(encoded_len
>= 0);
2757 /* Encode u8 version IN [5] */
2758 trunnel_assert(written
<= avail
);
2759 if (avail
- written
< 1)
2761 trunnel_set_uint8(ptr
, (obj
->version
));
2762 written
+= 1; ptr
+= 1;
2764 /* Encode u8 method */
2765 trunnel_assert(written
<= avail
);
2766 if (avail
- written
< 1)
2768 trunnel_set_uint8(ptr
, (obj
->method
));
2769 written
+= 1; ptr
+= 1;
2772 trunnel_assert(ptr
== output
+ written
);
2773 #ifdef TRUNNEL_CHECK_ENCODED_LEN
2775 trunnel_assert(encoded_len
>= 0);
2776 trunnel_assert((size_t)encoded_len
== written
);
2791 trunnel_assert(result
< 0);
2795 /** As socks5_server_method_parse(), but do not allocate the output
2799 socks5_server_method_parse_into(socks5_server_method_t
*obj
, const uint8_t *input
, const size_t len_in
)
2801 const uint8_t *ptr
= input
;
2802 size_t remaining
= len_in
;
2806 /* Parse u8 version IN [5] */
2807 CHECK_REMAINING(1, truncated
);
2808 obj
->version
= (trunnel_get_uint8(ptr
));
2809 remaining
-= 1; ptr
+= 1;
2810 if (! (obj
->version
== 5))
2813 /* Parse u8 method */
2814 CHECK_REMAINING(1, truncated
);
2815 obj
->method
= (trunnel_get_uint8(ptr
));
2816 remaining
-= 1; ptr
+= 1;
2817 trunnel_assert(ptr
+ remaining
== input
+ len_in
);
2818 return len_in
- remaining
;
2828 socks5_server_method_parse(socks5_server_method_t
**output
, const uint8_t *input
, const size_t len_in
)
2831 *output
= socks5_server_method_new();
2832 if (NULL
== *output
)
2834 result
= socks5_server_method_parse_into(*output
, input
, len_in
);
2836 socks5_server_method_free(*output
);
2841 socks5_server_userpass_auth_t
*
2842 socks5_server_userpass_auth_new(void)
2844 socks5_server_userpass_auth_t
*val
= trunnel_calloc(1, sizeof(socks5_server_userpass_auth_t
));
2851 /** Release all storage held inside 'obj', but do not free 'obj'.
2854 socks5_server_userpass_auth_clear(socks5_server_userpass_auth_t
*obj
)
2860 socks5_server_userpass_auth_free(socks5_server_userpass_auth_t
*obj
)
2864 socks5_server_userpass_auth_clear(obj
);
2865 trunnel_memwipe(obj
, sizeof(socks5_server_userpass_auth_t
));
2870 socks5_server_userpass_auth_get_version(const socks5_server_userpass_auth_t
*inp
)
2872 return inp
->version
;
2875 socks5_server_userpass_auth_set_version(socks5_server_userpass_auth_t
*inp
, uint8_t val
)
2877 if (! ((val
== 1))) {
2878 TRUNNEL_SET_ERROR_CODE(inp
);
2885 socks5_server_userpass_auth_get_status(const socks5_server_userpass_auth_t
*inp
)
2890 socks5_server_userpass_auth_set_status(socks5_server_userpass_auth_t
*inp
, uint8_t val
)
2896 socks5_server_userpass_auth_check(const socks5_server_userpass_auth_t
*obj
)
2899 return "Object was NULL";
2900 if (obj
->trunnel_error_code_
)
2901 return "A set function failed on this object";
2902 if (! (obj
->version
== 1))
2903 return "Integer out of bounds";
2908 socks5_server_userpass_auth_encoded_len(const socks5_server_userpass_auth_t
*obj
)
2912 if (NULL
!= socks5_server_userpass_auth_check(obj
))
2916 /* Length of u8 version IN [1] */
2919 /* Length of u8 status */
2924 socks5_server_userpass_auth_clear_errors(socks5_server_userpass_auth_t
*obj
)
2926 int r
= obj
->trunnel_error_code_
;
2927 obj
->trunnel_error_code_
= 0;
2931 socks5_server_userpass_auth_encode(uint8_t *output
, const size_t avail
, const socks5_server_userpass_auth_t
*obj
)
2935 uint8_t *ptr
= output
;
2937 #ifdef TRUNNEL_CHECK_ENCODED_LEN
2938 const ssize_t encoded_len
= socks5_server_userpass_auth_encoded_len(obj
);
2941 if (NULL
!= (msg
= socks5_server_userpass_auth_check(obj
)))
2944 #ifdef TRUNNEL_CHECK_ENCODED_LEN
2945 trunnel_assert(encoded_len
>= 0);
2948 /* Encode u8 version IN [1] */
2949 trunnel_assert(written
<= avail
);
2950 if (avail
- written
< 1)
2952 trunnel_set_uint8(ptr
, (obj
->version
));
2953 written
+= 1; ptr
+= 1;
2955 /* Encode u8 status */
2956 trunnel_assert(written
<= avail
);
2957 if (avail
- written
< 1)
2959 trunnel_set_uint8(ptr
, (obj
->status
));
2960 written
+= 1; ptr
+= 1;
2963 trunnel_assert(ptr
== output
+ written
);
2964 #ifdef TRUNNEL_CHECK_ENCODED_LEN
2966 trunnel_assert(encoded_len
>= 0);
2967 trunnel_assert((size_t)encoded_len
== written
);
2982 trunnel_assert(result
< 0);
2986 /** As socks5_server_userpass_auth_parse(), but do not allocate the
2990 socks5_server_userpass_auth_parse_into(socks5_server_userpass_auth_t
*obj
, const uint8_t *input
, const size_t len_in
)
2992 const uint8_t *ptr
= input
;
2993 size_t remaining
= len_in
;
2997 /* Parse u8 version IN [1] */
2998 CHECK_REMAINING(1, truncated
);
2999 obj
->version
= (trunnel_get_uint8(ptr
));
3000 remaining
-= 1; ptr
+= 1;
3001 if (! (obj
->version
== 1))
3004 /* Parse u8 status */
3005 CHECK_REMAINING(1, truncated
);
3006 obj
->status
= (trunnel_get_uint8(ptr
));
3007 remaining
-= 1; ptr
+= 1;
3008 trunnel_assert(ptr
+ remaining
== input
+ len_in
);
3009 return len_in
- remaining
;
3019 socks5_server_userpass_auth_parse(socks5_server_userpass_auth_t
**output
, const uint8_t *input
, const size_t len_in
)
3022 *output
= socks5_server_userpass_auth_new();
3023 if (NULL
== *output
)
3025 result
= socks5_server_userpass_auth_parse_into(*output
, input
, len_in
);
3027 socks5_server_userpass_auth_free(*output
);
3032 socks5_client_request_t
*
3033 socks5_client_request_new(void)
3035 socks5_client_request_t
*val
= trunnel_calloc(1, sizeof(socks5_client_request_t
));
3039 val
->command
= CMD_BIND
;
3043 /** Release all storage held inside 'obj', but do not free 'obj'.
3046 socks5_client_request_clear(socks5_client_request_t
*obj
)
3049 domainname_free(obj
->dest_addr_domainname
);
3050 obj
->dest_addr_domainname
= NULL
;
3054 socks5_client_request_free(socks5_client_request_t
*obj
)
3058 socks5_client_request_clear(obj
);
3059 trunnel_memwipe(obj
, sizeof(socks5_client_request_t
));
3064 socks5_client_request_get_version(const socks5_client_request_t
*inp
)
3066 return inp
->version
;
3069 socks5_client_request_set_version(socks5_client_request_t
*inp
, uint8_t val
)
3071 if (! ((val
== 5))) {
3072 TRUNNEL_SET_ERROR_CODE(inp
);
3079 socks5_client_request_get_command(const socks5_client_request_t
*inp
)
3081 return inp
->command
;
3084 socks5_client_request_set_command(socks5_client_request_t
*inp
, uint8_t val
)
3086 if (! ((val
== CMD_BIND
|| val
== CMD_CONNECT
|| val
== CMD_RESOLVE
|| val
== CMD_RESOLVE_PTR
|| val
== CMD_UDP_ASSOCIATE
))) {
3087 TRUNNEL_SET_ERROR_CODE(inp
);
3094 socks5_client_request_get_reserved(const socks5_client_request_t
*inp
)
3096 return inp
->reserved
;
3099 socks5_client_request_set_reserved(socks5_client_request_t
*inp
, uint8_t val
)
3101 if (! ((val
== 0))) {
3102 TRUNNEL_SET_ERROR_CODE(inp
);
3105 inp
->reserved
= val
;
3109 socks5_client_request_get_atype(const socks5_client_request_t
*inp
)
3114 socks5_client_request_set_atype(socks5_client_request_t
*inp
, uint8_t val
)
3120 socks5_client_request_get_dest_addr_ipv4(const socks5_client_request_t
*inp
)
3122 return inp
->dest_addr_ipv4
;
3125 socks5_client_request_set_dest_addr_ipv4(socks5_client_request_t
*inp
, uint32_t val
)
3127 inp
->dest_addr_ipv4
= val
;
3131 socks5_client_request_getlen_dest_addr_ipv6(const socks5_client_request_t
*inp
)
3133 (void)inp
; return 16;
3137 socks5_client_request_get_dest_addr_ipv6(socks5_client_request_t
*inp
, size_t idx
)
3139 trunnel_assert(idx
< 16);
3140 return inp
->dest_addr_ipv6
[idx
];
3144 socks5_client_request_getconst_dest_addr_ipv6(const socks5_client_request_t
*inp
, size_t idx
)
3146 return socks5_client_request_get_dest_addr_ipv6((socks5_client_request_t
*)inp
, idx
);
3149 socks5_client_request_set_dest_addr_ipv6(socks5_client_request_t
*inp
, size_t idx
, uint8_t elt
)
3151 trunnel_assert(idx
< 16);
3152 inp
->dest_addr_ipv6
[idx
] = elt
;
3157 socks5_client_request_getarray_dest_addr_ipv6(socks5_client_request_t
*inp
)
3159 return inp
->dest_addr_ipv6
;
3162 socks5_client_request_getconstarray_dest_addr_ipv6(const socks5_client_request_t
*inp
)
3164 return (const uint8_t *)socks5_client_request_getarray_dest_addr_ipv6((socks5_client_request_t
*)inp
);
3166 struct domainname_st
*
3167 socks5_client_request_get_dest_addr_domainname(socks5_client_request_t
*inp
)
3169 return inp
->dest_addr_domainname
;
3171 const struct domainname_st
*
3172 socks5_client_request_getconst_dest_addr_domainname(const socks5_client_request_t
*inp
)
3174 return socks5_client_request_get_dest_addr_domainname((socks5_client_request_t
*) inp
);
3177 socks5_client_request_set_dest_addr_domainname(socks5_client_request_t
*inp
, struct domainname_st
*val
)
3179 if (inp
->dest_addr_domainname
&& inp
->dest_addr_domainname
!= val
)
3180 domainname_free(inp
->dest_addr_domainname
);
3181 return socks5_client_request_set0_dest_addr_domainname(inp
, val
);
3184 socks5_client_request_set0_dest_addr_domainname(socks5_client_request_t
*inp
, struct domainname_st
*val
)
3186 inp
->dest_addr_domainname
= val
;
3190 socks5_client_request_get_dest_port(const socks5_client_request_t
*inp
)
3192 return inp
->dest_port
;
3195 socks5_client_request_set_dest_port(socks5_client_request_t
*inp
, uint16_t val
)
3197 inp
->dest_port
= val
;
3201 socks5_client_request_check(const socks5_client_request_t
*obj
)
3204 return "Object was NULL";
3205 if (obj
->trunnel_error_code_
)
3206 return "A set function failed on this object";
3207 if (! (obj
->version
== 5))
3208 return "Integer out of bounds";
3209 if (! (obj
->command
== CMD_BIND
|| obj
->command
== CMD_CONNECT
|| obj
->command
== CMD_RESOLVE
|| obj
->command
== CMD_RESOLVE_PTR
|| obj
->command
== CMD_UDP_ASSOCIATE
))
3210 return "Integer out of bounds";
3211 if (! (obj
->reserved
== 0))
3212 return "Integer out of bounds";
3213 switch (obj
->atype
) {
3221 case ATYPE_DOMAINNAME
:
3224 if (NULL
!= (msg
= domainname_check(obj
->dest_addr_domainname
)))
3230 return "Bad tag for union";
3237 socks5_client_request_encoded_len(const socks5_client_request_t
*obj
)
3241 if (NULL
!= socks5_client_request_check(obj
))
3245 /* Length of u8 version IN [5] */
3248 /* Length of u8 command IN [CMD_BIND, CMD_CONNECT, CMD_RESOLVE, CMD_RESOLVE_PTR, CMD_UDP_ASSOCIATE] */
3251 /* Length of u8 reserved IN [0] */
3254 /* Length of u8 atype */
3256 switch (obj
->atype
) {
3260 /* Length of u32 dest_addr_ipv4 */
3266 /* Length of u8 dest_addr_ipv6[16] */
3270 case ATYPE_DOMAINNAME
:
3272 /* Length of struct domainname dest_addr_domainname */
3273 result
+= domainname_encoded_len(obj
->dest_addr_domainname
);
3281 /* Length of u16 dest_port */
3286 socks5_client_request_clear_errors(socks5_client_request_t
*obj
)
3288 int r
= obj
->trunnel_error_code_
;
3289 obj
->trunnel_error_code_
= 0;
3293 socks5_client_request_encode(uint8_t *output
, const size_t avail
, const socks5_client_request_t
*obj
)
3297 uint8_t *ptr
= output
;
3299 #ifdef TRUNNEL_CHECK_ENCODED_LEN
3300 const ssize_t encoded_len
= socks5_client_request_encoded_len(obj
);
3303 if (NULL
!= (msg
= socks5_client_request_check(obj
)))
3306 #ifdef TRUNNEL_CHECK_ENCODED_LEN
3307 trunnel_assert(encoded_len
>= 0);
3310 /* Encode u8 version IN [5] */
3311 trunnel_assert(written
<= avail
);
3312 if (avail
- written
< 1)
3314 trunnel_set_uint8(ptr
, (obj
->version
));
3315 written
+= 1; ptr
+= 1;
3317 /* Encode u8 command IN [CMD_BIND, CMD_CONNECT, CMD_RESOLVE, CMD_RESOLVE_PTR, CMD_UDP_ASSOCIATE] */
3318 trunnel_assert(written
<= avail
);
3319 if (avail
- written
< 1)
3321 trunnel_set_uint8(ptr
, (obj
->command
));
3322 written
+= 1; ptr
+= 1;
3324 /* Encode u8 reserved IN [0] */
3325 trunnel_assert(written
<= avail
);
3326 if (avail
- written
< 1)
3328 trunnel_set_uint8(ptr
, (obj
->reserved
));
3329 written
+= 1; ptr
+= 1;
3331 /* Encode u8 atype */
3332 trunnel_assert(written
<= avail
);
3333 if (avail
- written
< 1)
3335 trunnel_set_uint8(ptr
, (obj
->atype
));
3336 written
+= 1; ptr
+= 1;
3338 /* Encode union dest_addr[atype] */
3339 trunnel_assert(written
<= avail
);
3340 switch (obj
->atype
) {
3344 /* Encode u32 dest_addr_ipv4 */
3345 trunnel_assert(written
<= avail
);
3346 if (avail
- written
< 4)
3348 trunnel_set_uint32(ptr
, trunnel_htonl(obj
->dest_addr_ipv4
));
3349 written
+= 4; ptr
+= 4;
3354 /* Encode u8 dest_addr_ipv6[16] */
3355 trunnel_assert(written
<= avail
);
3356 if (avail
- written
< 16)
3358 memcpy(ptr
, obj
->dest_addr_ipv6
, 16);
3359 written
+= 16; ptr
+= 16;
3362 case ATYPE_DOMAINNAME
:
3364 /* Encode struct domainname dest_addr_domainname */
3365 trunnel_assert(written
<= avail
);
3366 result
= domainname_encode(ptr
, avail
- written
, obj
->dest_addr_domainname
);
3368 goto fail
; /* XXXXXXX !*/
3369 written
+= result
; ptr
+= result
;
3377 /* Encode u16 dest_port */
3378 trunnel_assert(written
<= avail
);
3379 if (avail
- written
< 2)
3381 trunnel_set_uint16(ptr
, trunnel_htons(obj
->dest_port
));
3382 written
+= 2; ptr
+= 2;
3385 trunnel_assert(ptr
== output
+ written
);
3386 #ifdef TRUNNEL_CHECK_ENCODED_LEN
3388 trunnel_assert(encoded_len
>= 0);
3389 trunnel_assert((size_t)encoded_len
== written
);
3404 trunnel_assert(result
< 0);
3408 /** As socks5_client_request_parse(), but do not allocate the output
3412 socks5_client_request_parse_into(socks5_client_request_t
*obj
, const uint8_t *input
, const size_t len_in
)
3414 const uint8_t *ptr
= input
;
3415 size_t remaining
= len_in
;
3419 /* Parse u8 version IN [5] */
3420 CHECK_REMAINING(1, truncated
);
3421 obj
->version
= (trunnel_get_uint8(ptr
));
3422 remaining
-= 1; ptr
+= 1;
3423 if (! (obj
->version
== 5))
3426 /* Parse u8 command IN [CMD_BIND, CMD_CONNECT, CMD_RESOLVE, CMD_RESOLVE_PTR, CMD_UDP_ASSOCIATE] */
3427 CHECK_REMAINING(1, truncated
);
3428 obj
->command
= (trunnel_get_uint8(ptr
));
3429 remaining
-= 1; ptr
+= 1;
3430 if (! (obj
->command
== CMD_BIND
|| obj
->command
== CMD_CONNECT
|| obj
->command
== CMD_RESOLVE
|| obj
->command
== CMD_RESOLVE_PTR
|| obj
->command
== CMD_UDP_ASSOCIATE
))
3433 /* Parse u8 reserved IN [0] */
3434 CHECK_REMAINING(1, truncated
);
3435 obj
->reserved
= (trunnel_get_uint8(ptr
));
3436 remaining
-= 1; ptr
+= 1;
3437 if (! (obj
->reserved
== 0))
3440 /* Parse u8 atype */
3441 CHECK_REMAINING(1, truncated
);
3442 obj
->atype
= (trunnel_get_uint8(ptr
));
3443 remaining
-= 1; ptr
+= 1;
3445 /* Parse union dest_addr[atype] */
3446 switch (obj
->atype
) {
3450 /* Parse u32 dest_addr_ipv4 */
3451 CHECK_REMAINING(4, truncated
);
3452 obj
->dest_addr_ipv4
= trunnel_ntohl(trunnel_get_uint32(ptr
));
3453 remaining
-= 4; ptr
+= 4;
3458 /* Parse u8 dest_addr_ipv6[16] */
3459 CHECK_REMAINING(16, truncated
);
3460 memcpy(obj
->dest_addr_ipv6
, ptr
, 16);
3461 remaining
-= 16; ptr
+= 16;
3464 case ATYPE_DOMAINNAME
:
3466 /* Parse struct domainname dest_addr_domainname */
3467 result
= domainname_parse(&obj
->dest_addr_domainname
, ptr
, remaining
);
3470 trunnel_assert((size_t)result
<= remaining
);
3471 remaining
-= result
; ptr
+= result
;
3479 /* Parse u16 dest_port */
3480 CHECK_REMAINING(2, truncated
);
3481 obj
->dest_port
= trunnel_ntohs(trunnel_get_uint16(ptr
));
3482 remaining
-= 2; ptr
+= 2;
3483 trunnel_assert(ptr
+ remaining
== input
+ len_in
);
3484 return len_in
- remaining
;
3489 trunnel_assert(result
< 0);
3497 socks5_client_request_parse(socks5_client_request_t
**output
, const uint8_t *input
, const size_t len_in
)
3500 *output
= socks5_client_request_new();
3501 if (NULL
== *output
)
3503 result
= socks5_client_request_parse_into(*output
, input
, len_in
);
3505 socks5_client_request_free(*output
);
3510 socks5_server_reply_t
*
3511 socks5_server_reply_new(void)
3513 socks5_server_reply_t
*val
= trunnel_calloc(1, sizeof(socks5_server_reply_t
));
3520 /** Release all storage held inside 'obj', but do not free 'obj'.
3523 socks5_server_reply_clear(socks5_server_reply_t
*obj
)
3526 domainname_free(obj
->bind_addr_domainname
);
3527 obj
->bind_addr_domainname
= NULL
;
3531 socks5_server_reply_free(socks5_server_reply_t
*obj
)
3535 socks5_server_reply_clear(obj
);
3536 trunnel_memwipe(obj
, sizeof(socks5_server_reply_t
));
3541 socks5_server_reply_get_version(const socks5_server_reply_t
*inp
)
3543 return inp
->version
;
3546 socks5_server_reply_set_version(socks5_server_reply_t
*inp
, uint8_t val
)
3548 if (! ((val
== 5))) {
3549 TRUNNEL_SET_ERROR_CODE(inp
);
3556 socks5_server_reply_get_reply(const socks5_server_reply_t
*inp
)
3561 socks5_server_reply_set_reply(socks5_server_reply_t
*inp
, uint8_t val
)
3567 socks5_server_reply_get_reserved(const socks5_server_reply_t
*inp
)
3569 return inp
->reserved
;
3572 socks5_server_reply_set_reserved(socks5_server_reply_t
*inp
, uint8_t val
)
3574 if (! ((val
== 0))) {
3575 TRUNNEL_SET_ERROR_CODE(inp
);
3578 inp
->reserved
= val
;
3582 socks5_server_reply_get_atype(const socks5_server_reply_t
*inp
)
3587 socks5_server_reply_set_atype(socks5_server_reply_t
*inp
, uint8_t val
)
3593 socks5_server_reply_get_bind_addr_ipv4(const socks5_server_reply_t
*inp
)
3595 return inp
->bind_addr_ipv4
;
3598 socks5_server_reply_set_bind_addr_ipv4(socks5_server_reply_t
*inp
, uint32_t val
)
3600 inp
->bind_addr_ipv4
= val
;
3604 socks5_server_reply_getlen_bind_addr_ipv6(const socks5_server_reply_t
*inp
)
3606 (void)inp
; return 16;
3610 socks5_server_reply_get_bind_addr_ipv6(socks5_server_reply_t
*inp
, size_t idx
)
3612 trunnel_assert(idx
< 16);
3613 return inp
->bind_addr_ipv6
[idx
];
3617 socks5_server_reply_getconst_bind_addr_ipv6(const socks5_server_reply_t
*inp
, size_t idx
)
3619 return socks5_server_reply_get_bind_addr_ipv6((socks5_server_reply_t
*)inp
, idx
);
3622 socks5_server_reply_set_bind_addr_ipv6(socks5_server_reply_t
*inp
, size_t idx
, uint8_t elt
)
3624 trunnel_assert(idx
< 16);
3625 inp
->bind_addr_ipv6
[idx
] = elt
;
3630 socks5_server_reply_getarray_bind_addr_ipv6(socks5_server_reply_t
*inp
)
3632 return inp
->bind_addr_ipv6
;
3635 socks5_server_reply_getconstarray_bind_addr_ipv6(const socks5_server_reply_t
*inp
)
3637 return (const uint8_t *)socks5_server_reply_getarray_bind_addr_ipv6((socks5_server_reply_t
*)inp
);
3639 struct domainname_st
*
3640 socks5_server_reply_get_bind_addr_domainname(socks5_server_reply_t
*inp
)
3642 return inp
->bind_addr_domainname
;
3644 const struct domainname_st
*
3645 socks5_server_reply_getconst_bind_addr_domainname(const socks5_server_reply_t
*inp
)
3647 return socks5_server_reply_get_bind_addr_domainname((socks5_server_reply_t
*) inp
);
3650 socks5_server_reply_set_bind_addr_domainname(socks5_server_reply_t
*inp
, struct domainname_st
*val
)
3652 if (inp
->bind_addr_domainname
&& inp
->bind_addr_domainname
!= val
)
3653 domainname_free(inp
->bind_addr_domainname
);
3654 return socks5_server_reply_set0_bind_addr_domainname(inp
, val
);
3657 socks5_server_reply_set0_bind_addr_domainname(socks5_server_reply_t
*inp
, struct domainname_st
*val
)
3659 inp
->bind_addr_domainname
= val
;
3663 socks5_server_reply_get_bind_port(const socks5_server_reply_t
*inp
)
3665 return inp
->bind_port
;
3668 socks5_server_reply_set_bind_port(socks5_server_reply_t
*inp
, uint16_t val
)
3670 inp
->bind_port
= val
;
3674 socks5_server_reply_check(const socks5_server_reply_t
*obj
)
3677 return "Object was NULL";
3678 if (obj
->trunnel_error_code_
)
3679 return "A set function failed on this object";
3680 if (! (obj
->version
== 5))
3681 return "Integer out of bounds";
3682 if (! (obj
->reserved
== 0))
3683 return "Integer out of bounds";
3684 switch (obj
->atype
) {
3692 case ATYPE_DOMAINNAME
:
3695 if (NULL
!= (msg
= domainname_check(obj
->bind_addr_domainname
)))
3701 return "Bad tag for union";
3708 socks5_server_reply_encoded_len(const socks5_server_reply_t
*obj
)
3712 if (NULL
!= socks5_server_reply_check(obj
))
3716 /* Length of u8 version IN [5] */
3719 /* Length of u8 reply */
3722 /* Length of u8 reserved IN [0] */
3725 /* Length of u8 atype */
3727 switch (obj
->atype
) {
3731 /* Length of u32 bind_addr_ipv4 */
3737 /* Length of u8 bind_addr_ipv6[16] */
3741 case ATYPE_DOMAINNAME
:
3743 /* Length of struct domainname bind_addr_domainname */
3744 result
+= domainname_encoded_len(obj
->bind_addr_domainname
);
3752 /* Length of u16 bind_port */
3757 socks5_server_reply_clear_errors(socks5_server_reply_t
*obj
)
3759 int r
= obj
->trunnel_error_code_
;
3760 obj
->trunnel_error_code_
= 0;
3764 socks5_server_reply_encode(uint8_t *output
, const size_t avail
, const socks5_server_reply_t
*obj
)
3768 uint8_t *ptr
= output
;
3770 #ifdef TRUNNEL_CHECK_ENCODED_LEN
3771 const ssize_t encoded_len
= socks5_server_reply_encoded_len(obj
);
3774 if (NULL
!= (msg
= socks5_server_reply_check(obj
)))
3777 #ifdef TRUNNEL_CHECK_ENCODED_LEN
3778 trunnel_assert(encoded_len
>= 0);
3781 /* Encode u8 version IN [5] */
3782 trunnel_assert(written
<= avail
);
3783 if (avail
- written
< 1)
3785 trunnel_set_uint8(ptr
, (obj
->version
));
3786 written
+= 1; ptr
+= 1;
3788 /* Encode u8 reply */
3789 trunnel_assert(written
<= avail
);
3790 if (avail
- written
< 1)
3792 trunnel_set_uint8(ptr
, (obj
->reply
));
3793 written
+= 1; ptr
+= 1;
3795 /* Encode u8 reserved IN [0] */
3796 trunnel_assert(written
<= avail
);
3797 if (avail
- written
< 1)
3799 trunnel_set_uint8(ptr
, (obj
->reserved
));
3800 written
+= 1; ptr
+= 1;
3802 /* Encode u8 atype */
3803 trunnel_assert(written
<= avail
);
3804 if (avail
- written
< 1)
3806 trunnel_set_uint8(ptr
, (obj
->atype
));
3807 written
+= 1; ptr
+= 1;
3809 /* Encode union bind_addr[atype] */
3810 trunnel_assert(written
<= avail
);
3811 switch (obj
->atype
) {
3815 /* Encode u32 bind_addr_ipv4 */
3816 trunnel_assert(written
<= avail
);
3817 if (avail
- written
< 4)
3819 trunnel_set_uint32(ptr
, trunnel_htonl(obj
->bind_addr_ipv4
));
3820 written
+= 4; ptr
+= 4;
3825 /* Encode u8 bind_addr_ipv6[16] */
3826 trunnel_assert(written
<= avail
);
3827 if (avail
- written
< 16)
3829 memcpy(ptr
, obj
->bind_addr_ipv6
, 16);
3830 written
+= 16; ptr
+= 16;
3833 case ATYPE_DOMAINNAME
:
3835 /* Encode struct domainname bind_addr_domainname */
3836 trunnel_assert(written
<= avail
);
3837 result
= domainname_encode(ptr
, avail
- written
, obj
->bind_addr_domainname
);
3839 goto fail
; /* XXXXXXX !*/
3840 written
+= result
; ptr
+= result
;
3848 /* Encode u16 bind_port */
3849 trunnel_assert(written
<= avail
);
3850 if (avail
- written
< 2)
3852 trunnel_set_uint16(ptr
, trunnel_htons(obj
->bind_port
));
3853 written
+= 2; ptr
+= 2;
3856 trunnel_assert(ptr
== output
+ written
);
3857 #ifdef TRUNNEL_CHECK_ENCODED_LEN
3859 trunnel_assert(encoded_len
>= 0);
3860 trunnel_assert((size_t)encoded_len
== written
);
3875 trunnel_assert(result
< 0);
3879 /** As socks5_server_reply_parse(), but do not allocate the output
3883 socks5_server_reply_parse_into(socks5_server_reply_t
*obj
, const uint8_t *input
, const size_t len_in
)
3885 const uint8_t *ptr
= input
;
3886 size_t remaining
= len_in
;
3890 /* Parse u8 version IN [5] */
3891 CHECK_REMAINING(1, truncated
);
3892 obj
->version
= (trunnel_get_uint8(ptr
));
3893 remaining
-= 1; ptr
+= 1;
3894 if (! (obj
->version
== 5))
3897 /* Parse u8 reply */
3898 CHECK_REMAINING(1, truncated
);
3899 obj
->reply
= (trunnel_get_uint8(ptr
));
3900 remaining
-= 1; ptr
+= 1;
3902 /* Parse u8 reserved IN [0] */
3903 CHECK_REMAINING(1, truncated
);
3904 obj
->reserved
= (trunnel_get_uint8(ptr
));
3905 remaining
-= 1; ptr
+= 1;
3906 if (! (obj
->reserved
== 0))
3909 /* Parse u8 atype */
3910 CHECK_REMAINING(1, truncated
);
3911 obj
->atype
= (trunnel_get_uint8(ptr
));
3912 remaining
-= 1; ptr
+= 1;
3914 /* Parse union bind_addr[atype] */
3915 switch (obj
->atype
) {
3919 /* Parse u32 bind_addr_ipv4 */
3920 CHECK_REMAINING(4, truncated
);
3921 obj
->bind_addr_ipv4
= trunnel_ntohl(trunnel_get_uint32(ptr
));
3922 remaining
-= 4; ptr
+= 4;
3927 /* Parse u8 bind_addr_ipv6[16] */
3928 CHECK_REMAINING(16, truncated
);
3929 memcpy(obj
->bind_addr_ipv6
, ptr
, 16);
3930 remaining
-= 16; ptr
+= 16;
3933 case ATYPE_DOMAINNAME
:
3935 /* Parse struct domainname bind_addr_domainname */
3936 result
= domainname_parse(&obj
->bind_addr_domainname
, ptr
, remaining
);
3939 trunnel_assert((size_t)result
<= remaining
);
3940 remaining
-= result
; ptr
+= result
;
3948 /* Parse u16 bind_port */
3949 CHECK_REMAINING(2, truncated
);
3950 obj
->bind_port
= trunnel_ntohs(trunnel_get_uint16(ptr
));
3951 remaining
-= 2; ptr
+= 2;
3952 trunnel_assert(ptr
+ remaining
== input
+ len_in
);
3953 return len_in
- remaining
;
3958 trunnel_assert(result
< 0);
3966 socks5_server_reply_parse(socks5_server_reply_t
**output
, const uint8_t *input
, const size_t len_in
)
3969 *output
= socks5_server_reply_new();
3970 if (NULL
== *output
)
3972 result
= socks5_server_reply_parse_into(*output
, input
, len_in
);
3974 socks5_server_reply_free(*output
);