2 #define _POSIX_C_SOURCE 200809L
7 #include <stdlib.h> /* for atoi() */
10 #include "rocksock_internal.h"
12 #ifndef ROCKSOCK_FILENAME
13 #define ROCKSOCK_FILENAME __FILE__
17 socks5://user:password@proxy.domain.com:port
18 socks5://proxy.domain.com:port
19 socks4://proxy.domain.com:port
20 http://user:password@proxy.domain.com:port
21 http://proxy.domain.com:port
23 supplying port number is obligatory.
24 user:pass@ part is optional for http and socks5.
25 however, user:pass authentication is currently not implemented for http proxies.
27 #define MKERR(S, X) rocksock_seterror(S, RS_ET_OWN, X, ROCKSOCK_FILENAME, __LINE__)
28 int rocksock_add_proxy_fromstring(rocksock
* sock
, const char *proxystring
) {
31 if(!sock
->proxies
) return MKERR(sock
, RS_E_NO_PROXYSTORAGE
);
34 rs_proxyType proxytype
;
35 rs_proxy
* prx
= &sock
->proxies
[sock
->lastproxy
+1];
36 char *user_buf
= prx
->username
;
37 char *pass_buf
= prx
->password
;
38 char *host_buf
= prx
->hostinfo
.host
;
39 size_t next_token
= 6, ul
= 0, pl
= 0, hl
;
40 if(!proxystring
[0] || !proxystring
[1] || !proxystring
[2] || !proxystring
[3] || !proxystring
[4] || !proxystring
[5]) goto inv_string
;
41 if(*proxystring
== 's') {
42 switch(proxystring
[5]) {
43 case '5': proxytype
= RS_PT_SOCKS5
; break;
44 case '4': proxytype
= RS_PT_SOCKS4
; break;
45 default: goto inv_string
;
47 } else if(*proxystring
== 'h') {
48 proxytype
= RS_PT_HTTP
;
50 } else goto inv_string
;
52 proxystring
[next_token
++] != ':' ||
53 proxystring
[next_token
++] != '/' ||
54 proxystring
[next_token
++] != '/') goto inv_string
;
55 const char *at
= strchr(proxystring
+next_token
, '@');
57 if(proxytype
== RS_PT_SOCKS4
)
58 return MKERR(sock
, RS_E_SOCKS4_NOAUTH
);
59 p
= strchr(proxystring
+next_token
, ':');
60 if(!p
|| p
>= at
) goto inv_string
;
61 const char *u
= proxystring
+next_token
;
65 if(proxytype
== RS_PT_SOCKS5
&& (ul
> 255 || pl
> 255))
66 return MKERR(sock
, RS_E_SOCKS5_AUTH_EXCEEDSIZE
);
67 memcpy(user_buf
, u
, ul
);
69 memcpy(pass_buf
, p
, pl
);
71 next_token
+= 2+ul
+pl
;
76 const char* h
= proxystring
+next_token
;
78 if(!p
) goto inv_string
;
81 return MKERR(sock
, RS_E_HOSTNAME_TOO_LONG
);
82 memcpy(host_buf
, h
, hl
);
85 prx
->hostinfo
.port
= atoi(p
+1);
86 prx
->proxytype
= proxytype
;
87 return rocksock_seterror(sock
, RS_ET_OWN
, 0, NULL
, 0);
89 return MKERR(sock
, RS_E_INVALID_PROXY_URL
);