13 #ifdef HAVE_SYS_SOCKET_H
14 # include <sys/socket.h>
17 #ifdef HAVE_NETINET_TCP_H
18 # include <netinet/tcp.h>
25 /* if net/if.h is not found or if an older versions of net/if.h is provided
26 which does not define IF_NAMESIZE. We must define it ourselves */
29 # define IF_NAMESIZE IFNAMSIZ
31 # define IF_NAMESIZE 16
35 #ifdef HAVE_NETINET_IN_H
36 # include <netinet/in.h>
39 #ifdef HAVE_ARPA_INET_H
40 # include <arpa/inet.h>
47 #ifdef HAVE_WS2TCPIP_H
48 # include <ws2tcpip.h>
56 #include "ecore_private.h"
57 #include "Ecore_Con.h"
58 #include "ecore_con_private.h"
60 /* http://tools.ietf.org/html/rfc1928
61 o X'00' NO AUTHENTICATION REQUIRED
63 o X'02' USERNAME/PASSWORD
64 o X'03' to X'7F' IANA ASSIGNED
65 o X'80' to X'FE' RESERVED FOR PRIVATE METHODS
66 o X'FF' NO ACCEPTABLE METHODS
68 #define ECORE_CON_SOCKS_V5_METHOD_NONE 0
69 #define ECORE_CON_SOCKS_V5_METHOD_GSSAPI 1
70 #define ECORE_CON_SOCKS_V5_METHOD_USERPASS 2
72 static int ECORE_CON_SOCKS_V5_METHODS[] =
74 ECORE_CON_SOCKS_V5_METHOD_NONE,
75 // ECORE_CON_SOCKS_V5_METHOD_GSSAPI, TODO
76 ECORE_CON_SOCKS_V5_METHOD_USERPASS
79 #define ECORE_CON_SOCKS_V5_TOTAL_METHODS sizeof(ECORE_CON_SOCKS_V5_METHODS)
81 #define _ecore_con_server_kill(svr) do { \
82 DBG("KILL %p", (svr)); \
83 _ecore_con_server_kill((svr)); \
86 Eina_List *ecore_con_socks_proxies = NULL;
88 static Ecore_Con_Socks *
89 _ecore_con_socks_find(unsigned char version, const char *ip, int port, const char *username, size_t ulen, const char *password, size_t plen)
92 Ecore_Con_Socks_v5 *ecs;
94 if (!ecore_con_socks_proxies) return NULL;
96 EINA_LIST_FOREACH(ecore_con_socks_proxies, l, ecs)
98 if (ecs->version != version) continue;
99 if (strcmp(ecs->ip, ip)) continue;
100 if ((port != -1) && (port != ecs->port)) continue;
101 if (ulen != ecs->ulen) continue;
102 if (username && strcmp(ecs->username, username)) continue;
105 if (plen != ecs->plen) continue;
106 if (password && strcmp(ecs->password, password)) continue;
108 return (Ecore_Con_Socks*)ecs;
114 _ecore_con_socks_free(Ecore_Con_Socks *ecs)
116 ECORE_CON_SOCKS_CAST_ELSE(ecs) return;
118 if (_ecore_con_proxy_once == ecs) _ecore_con_proxy_once = NULL;
119 if (_ecore_con_proxy_global == ecs) _ecore_con_proxy_global = NULL;
120 eina_stringshare_del(ecs->ip);
121 eina_stringshare_del(ecs->username);
126 _ecore_con_socks_svr_init_v4(Ecore_Con_Server *svr, Ecore_Con_Socks_v4 *v4)
128 size_t addrlen, buflen, ulen = 1;
131 addrlen = v4->lookup ? strlen(svr->name) + 1 : 0;
132 if (v4->username) ulen += v4->ulen;
133 buflen = sizeof(char) * (8 + ulen + addrlen);
134 sbuf = malloc(buflen);
137 ecore_con_event_server_error(svr, "Memory allocation failure!");
138 _ecore_con_server_kill(svr);
141 /* http://en.wikipedia.org/wiki/SOCKS */
143 sbuf[1] = v4->bind ? 2 : 1;
144 sbuf[2] = svr->port >> 8;
145 sbuf[3] = svr->port & 0xff;
148 sbuf[4] = sbuf[5] = sbuf[6] = 0;
152 /* SOCKSv4 only handles IPV4, so addrlen is always 4 */
153 memcpy(sbuf + 4, svr->ecs_addr, 4);
155 memcpy(sbuf + 8, v4->username, ulen);
158 if (addrlen) memcpy(sbuf + 8 + ulen, svr->name, addrlen);
160 svr->ecs_buf = eina_binbuf_manage_new_length(sbuf, buflen);
165 _ecore_con_socks_svr_init_v5(Ecore_Con_Server *svr, Ecore_Con_Socks_v5 *v5)
172 buflen = sizeof(char) * (2 + ECORE_CON_SOCKS_V5_TOTAL_METHODS);
175 sbuf = malloc(buflen);
178 ecore_con_event_server_error(svr, "Memory allocation failure!");
179 _ecore_con_server_kill(svr);
182 /* http://en.wikipedia.org/wiki/SOCKS
183 * http://tools.ietf.org/html/rfc1928
188 sbuf[1] = ECORE_CON_SOCKS_V5_TOTAL_METHODS;
189 for (x = 2; x < 2 + ECORE_CON_SOCKS_V5_TOTAL_METHODS; x++)
190 sbuf[x] = ECORE_CON_SOCKS_V5_METHODS[x - 2];
195 sbuf[2] = ECORE_CON_SOCKS_V5_METHOD_NONE;
198 svr->ecs_buf = eina_binbuf_manage_new_length(sbuf, buflen);
202 #define ECORE_CON_SOCKS_READ(EXACT) \
205 if (!svr->ecs_recvbuf) svr->ecs_recvbuf = eina_binbuf_new(); \
206 if (!svr->ecs_recvbuf) goto error; \
207 eina_binbuf_append_length(svr->ecs_recvbuf, buf, num); \
208 /* the slowest connection on earth */ \
209 if (eina_binbuf_length_get(svr->ecs_recvbuf) != EXACT) return; \
210 data = eina_binbuf_string_get(svr->ecs_recvbuf); \
212 else if (num > EXACT) goto error; \
217 _ecore_con_socks_read_v4(Ecore_Con_Server *svr, Ecore_Con_Socks_v4 *v4 __UNUSED__, const unsigned char *buf, unsigned int num)
219 const unsigned char *data;
220 DBG("SOCKS: %d bytes", num);
221 ECORE_CON_SOCKS_READ(8);
223 /* http://ufasoft.com/doc/socks4_protocol.htm */
224 if (data[0]) goto error;
231 ecore_con_event_server_error(svr, "proxy request rejected or failed");
234 ecore_con_event_server_error(svr, "proxying SOCKS server could not perform authentication");
237 ecore_con_event_server_error(svr, "proxy request authentication rejected");
240 ecore_con_event_server_error(svr, "garbage data from proxy");
246 char naddr[IF_NAMESIZE];
248 memcpy(&nport, &data[2], 2);
249 svr->proxyport = ntohl(nport);
251 if (!inet_ntop(AF_INET, &data[4], naddr, sizeof(naddr))) goto error;
252 svr->proxyip = eina_stringshare_add(naddr);
253 ecore_con_event_proxy_bind(svr);
255 svr->ecs_state = ECORE_CON_PROXY_STATE_DONE;
256 INF("PROXY CONNECTED");
257 if (svr->ecs_recvbuf) eina_binbuf_free(svr->ecs_recvbuf);
258 svr->ecs_recvbuf = NULL;
259 svr->ecs_buf_offset = svr->ecs_addrlen = 0;
260 memset(svr->ecs_addr, 0, sizeof(svr->ecs_addr));
262 ecore_con_event_server_add(svr);
263 if (svr->ssl_state || (svr->buf && eina_binbuf_length_get(svr->buf)))
264 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE);
267 _ecore_con_server_kill(svr);
271 _ecore_con_socks_auth_v5(Ecore_Con_Server *svr, Ecore_Con_Socks_v5 *v5)
277 case ECORE_CON_SOCKS_V5_METHOD_NONE:
278 svr->ecs_state = ECORE_CON_PROXY_STATE_REQUEST;
280 case ECORE_CON_SOCKS_V5_METHOD_GSSAPI:
282 case ECORE_CON_SOCKS_V5_METHOD_USERPASS:
283 if (!v5->username) return EINA_FALSE;
284 if (!v5->password) v5->plen = 1;
285 /* http://tools.ietf.org/html/rfc1929 */
286 size = sizeof(char) * (3 + v5->ulen + v5->plen);
291 memcpy(&data[2], v5->username, v5->ulen);
292 data[1 + v5->ulen] = v5->plen;
294 memcpy(&data[2 + v5->ulen], v5->password, v5->plen);
296 data[2 + v5->ulen] = 0;
297 svr->ecs_buf = eina_binbuf_manage_new_length(data, size);
306 _ecore_con_socks_read_v5(Ecore_Con_Server *svr, Ecore_Con_Socks_v5 *v5, const unsigned char *buf, unsigned int num)
308 const unsigned char *data;
310 DBG("SOCKS: %d bytes", num);
311 switch (svr->ecs_state)
314 case ECORE_CON_PROXY_STATE_READ:
315 ECORE_CON_SOCKS_READ(2);
316 /* http://en.wikipedia.org/wiki/SOCKS */
317 if (data[0] != 5) goto error;
320 ecore_con_event_server_error(svr, "proxy authentication methods rejected");
323 v5->method = data[1];
324 if (!_ecore_con_socks_auth_v5(svr, v5)) goto error;
325 if (svr->ecs_state == ECORE_CON_PROXY_STATE_REQUEST)
327 /* run again to skip auth reading */
328 _ecore_con_socks_read_v5(svr, v5, NULL, 0);
331 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE);
332 svr->ecs_state = ECORE_CON_PROXY_STATE_AUTH;
334 case ECORE_CON_PROXY_STATE_AUTH:
335 ECORE_CON_SOCKS_READ(2);
338 case ECORE_CON_SOCKS_V5_METHOD_NONE:
339 CRIT("HOW DID THIS HAPPEN?????????");
341 case ECORE_CON_SOCKS_V5_METHOD_GSSAPI:
344 case ECORE_CON_SOCKS_V5_METHOD_USERPASS:
347 ecore_con_event_server_error(svr, "protocol error");
348 goto error; /* wrong version */
352 ecore_con_event_server_error(svr, "proxy request authentication rejected");
358 case ECORE_CON_PROXY_STATE_REQUEST:
360 size_t addrlen, buflen;
362 addrlen = v5->lookup ? strlen(svr->name) + 1 : (unsigned int)svr->ecs_addrlen;
363 buflen = sizeof(char) * (6 + addrlen);
364 sbuf = malloc(buflen);
367 ecore_con_event_server_error(svr, "Memory allocation failure!");
371 sbuf[1] = v5->bind ? 2 : 1; /* TODO: 0x03 for UDP port association */
373 if (v5->lookup) /* domain name */
376 sbuf[4] = addrlen - 1;
377 memcpy(sbuf + 5, svr->name, addrlen - 1);
381 sbuf[3] = (svr->ecs_addrlen == 4) ? 1 : 4;
382 memcpy(sbuf + 4, svr->ecs_addr, addrlen);
384 sbuf[addrlen + 4] = svr->port >> 8;
385 sbuf[addrlen + 5] = svr->port & 0xff;
387 svr->ecs_buf = eina_binbuf_manage_new_length(sbuf, buflen);
388 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE);
391 case ECORE_CON_PROXY_STATE_CONFIRM:
393 /* this is ugly because we have to read an exact number of bytes,
394 * but we don't know what that number is until we've already read
395 * at least 5 bytes to determine the length of the unknown stream.
398 size_t to_read, len = svr->ecs_recvbuf ? eina_binbuf_length_get(svr->ecs_recvbuf) : 0;
401 /* guarantees we get called again */
402 ECORE_CON_SOCKS_READ(5);
406 data = eina_binbuf_string_get(svr->ecs_recvbuf);
410 data = buf + 3 - len;
417 to_read = data[1] + 1;
421 /* lazy debugging stub comment */
424 ecore_con_event_server_error(svr, "protocol error");
427 /* at this point, we finally know exactly how much we need to read */
428 ECORE_CON_SOCKS_READ(6 + to_read);
432 ecore_con_event_server_error(svr, "protocol error");
433 goto error; /* wrong version */
440 ecore_con_event_server_error(svr, "general proxy failure");
443 ecore_con_event_server_error(svr, "connection not allowed by ruleset");
446 ecore_con_event_server_error(svr, "network unreachable");
449 ecore_con_event_server_error(svr, "host unreachable");
452 ecore_con_event_server_error(svr, "connection refused by destination host");
455 ecore_con_event_server_error(svr, "TTL expired");
458 ecore_con_event_server_error(svr, "command not supported / protocol error");
461 ecore_con_event_server_error(svr, "address type not supported");
467 ecore_con_event_server_error(svr, "protocol error");
470 memset(svr->ecs_addr, 0, sizeof(svr->ecs_addr));
472 ecore_con_event_server_add(svr);
473 if (svr->ssl_state || (svr->buf && eina_binbuf_length_get(svr->buf)))
474 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE);
475 svr->ecs_buf_offset = svr->ecs_addrlen = 0;
476 svr->ecs_state = ECORE_CON_PROXY_STATE_DONE;
477 INF("PROXY CONNECTED");
483 if (svr->ecs_recvbuf) eina_binbuf_free(svr->ecs_recvbuf);
484 svr->ecs_recvbuf = NULL;
488 _ecore_con_server_kill(svr);
491 /////////////////////////////////////////////////////////////////////////////////////
493 ecore_con_socks_shutdown(void)
495 Ecore_Con_Socks *ecs;
496 EINA_LIST_FREE(ecore_con_socks_proxies, ecs)
497 _ecore_con_socks_free(ecs);
498 _ecore_con_proxy_once = NULL;
499 _ecore_con_proxy_global = NULL;
503 ecore_con_socks_read(Ecore_Con_Server *svr, unsigned char *buf, int num)
505 ECORE_CON_SOCKS_CAST_ELSE(svr->ecs) return;
507 if (svr->ecs_state < ECORE_CON_PROXY_STATE_READ) return;
509 if (v4) _ecore_con_socks_read_v4(svr, v4, buf, (unsigned int)num);
510 else _ecore_con_socks_read_v5(svr, v5, buf, (unsigned int)num);
514 ecore_con_socks_svr_init(Ecore_Con_Server *svr)
516 ECORE_CON_SOCKS_CAST_ELSE(svr->ecs) return EINA_FALSE;
518 if (!svr->ip) return EINA_FALSE;
519 if (svr->ecs_buf) return EINA_FALSE;
520 if (svr->ecs_state != ECORE_CON_PROXY_STATE_INIT) return EINA_FALSE;
521 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE);
522 if (v4) return _ecore_con_socks_svr_init_v4(svr, v4);
523 return _ecore_con_socks_svr_init_v5(svr, v5);
527 ecore_con_socks_dns_cb(const char *canonname __UNUSED__, const char *ip, struct sockaddr *addr, int addrlen __UNUSED__, Ecore_Con_Server *svr)
529 svr->ip = eina_stringshare_add(ip);
531 if (addr->sa_family == AF_INET)
533 memcpy(svr->ecs_addr, &((struct sockaddr_in *)addr)->sin_addr.s_addr, 4);
534 svr->ecs_addrlen = 4;
539 memcpy(svr->ecs_addr, &((struct sockaddr_in6 *)addr)->sin6_addr.s6_addr, 16);
540 svr->ecs_addrlen = 16;
543 ecore_con_socks_svr_init(svr);
547 ecore_con_socks_init(void)
550 char *h, *p, *l, *u = NULL;
552 int port, lookup = 0;
553 Eina_Bool v5 = EINA_FALSE;
554 Ecore_Con_Socks *ecs;
555 unsigned char addr[sizeof(struct in_addr)];
557 unsigned char addr6[sizeof(struct in6_addr)];
560 /* ECORE_CON_SOCKS_V4=[user@]host-port:[1|0] */
561 socks = getenv("ECORE_CON_SOCKS_V4");
564 /* ECORE_CON_SOCKS_V5=[user@]host-port:[1|0] */
565 socks = getenv("ECORE_CON_SOCKS_V5");
568 if ((!socks) || (!socks[0]) || (strlen(socks) > 512)) return;
569 strncpy(buf, socks, sizeof(buf));
570 h = strchr(buf, '@');
572 if (h && (h - buf > 0)) *h++ = 0, u = buf;
575 /* host ip; I ain't resolvin shit here */
579 if (!inet_pton(AF_INET, h, addr))
583 if (!inet_pton(AF_INET6, h, addr6))
591 port = strtol(p, &l, 10);
592 if (errno || (port < 0) || (port > 65535)) return;
593 if (l && (l[0] == ':'))
594 lookup = (l[1] == '1');
596 ecs = ecore_con_socks5_remote_add(h, port, u, NULL);
598 ecs = ecore_con_socks4_remote_add(h, port, u);
600 ecore_con_socks_lookup_set(ecs, lookup);
601 ecore_con_socks_apply_always(ecs);
602 INF("Added global proxy server %s%s%s:%d - DNS lookup %s",
603 u ?: "", u ? "@" : "", h, port, lookup ? "ENABLED" : "DISABLED");
606 /////////////////////////////////////////////////////////////////////////////////////
609 * @defgroup Ecore_Con_Socks_Group Ecore Connection SOCKS functions
614 * Add a SOCKS v4 proxy to the proxy list
616 * Use this to create (or return, if previously added) a SOCKS proxy
617 * object which can be used by any ecore_con servers.
618 * @param ip The ip address of the proxy (NOT DOMAIN NAME. IP ADDRESS.)
619 * @param port The port to connect to on the proxy
620 * @param username The username to use for the proxy (OPTIONAL)
621 * @return An allocated proxy object, or NULL on failure
622 * @note This object NEVER needs to be explicitly freed.
625 EAPI Ecore_Con_Socks *
626 ecore_con_socks4_remote_add(const char *ip, int port, const char *username)
628 Ecore_Con_Socks *ecs;
631 if ((!ip) || (!ip[0]) || (port < 0) || (port > 65535)) return NULL;
635 ulen = strlen(username);
636 /* max length for protocol */
637 if ((!ulen) || (ulen > 255)) return NULL;
639 ecs = _ecore_con_socks_find(4, ip, port, username, ulen, NULL, 0);
642 ecs = calloc(1, sizeof(Ecore_Con_Socks_v4));
643 if (!ecs) return NULL;
646 ecs->ip = eina_stringshare_add(ip);
648 ecs->username = eina_stringshare_add(username);
650 ecore_con_socks_proxies = eina_list_append(ecore_con_socks_proxies, ecs);
655 * Find a SOCKS v4 proxy in the proxy list
657 * Use this to determine if a SOCKS proxy was previously added by checking
658 * the proxy list against the parameters given.
659 * @param ip The ip address of the proxy (NOT DOMAIN NAME. IP ADDRESS.)
660 * @param port The port to connect to on the proxy, or -1 to match the first proxy with @p ip
661 * @param username The username used for the proxy (OPTIONAL)
662 * @return true only if a proxy exists matching the given params
663 * @note This function matches slightly more loosely than ecore_con_socks4_remote_add(), and
664 * ecore_con_socks4_remote_add() should be used to return the actual object.
668 ecore_con_socks4_remote_exists(const char *ip, int port, const char *username)
670 if ((!ip) || (!ip[0]) || (port < -1) || (port > 65535) || (username && (!username[0])))
672 return !!_ecore_con_socks_find(4, ip, port, username, username ? strlen(username) : 0, NULL, 0);
676 * Remove a SOCKS v4 proxy from the proxy list and delete it
678 * Use this to remove a SOCKS proxy from the proxy list by checking
679 * the list against the parameters given. The proxy will then be deleted.
680 * @param ip The ip address of the proxy (NOT DOMAIN NAME. IP ADDRESS.)
681 * @param port The port to connect to on the proxy, or -1 to match the first proxy with @p ip
682 * @param username The username used for the proxy (OPTIONAL)
683 * @note This function matches in the same way as ecore_con_socks4_remote_exists().
684 * @warning Be aware that deleting a proxy which is being used WILL ruin your life.
688 ecore_con_socks4_remote_del(const char *ip, int port, const char *username)
690 Ecore_Con_Socks_v4 *v4;
692 if ((!ip) || (!ip[0]) || (port < -1) || (port > 65535) || (username && (!username[0]))) return;
693 if (!ecore_con_socks_proxies) return;
695 v4 = (Ecore_Con_Socks_v4*)_ecore_con_socks_find(4, ip, port, username, username ? strlen(username) : 0, NULL, 0);
697 ecore_con_socks_proxies = eina_list_remove(ecore_con_socks_proxies, v4);
698 _ecore_con_socks_free((Ecore_Con_Socks*)v4);
701 * Add a SOCKS v5 proxy to the proxy list
703 * Use this to create (or return, if previously added) a SOCKS proxy
704 * object which can be used by any ecore_con servers.
705 * @param ip The ip address of the proxy (NOT DOMAIN NAME. IP ADDRESS.)
706 * @param port The port to connect to on the proxy
707 * @param username The username to use for the proxy (OPTIONAL)
708 * @param password The password to use for the proxy (OPTIONAL)
709 * @return An allocated proxy object, or NULL on failure
710 * @note This object NEVER needs to be explicitly freed.
713 EAPI Ecore_Con_Socks *
714 ecore_con_socks5_remote_add(const char *ip, int port, const char *username, const char *password)
716 Ecore_Con_Socks_v5 *ecs5;
717 size_t ulen = 0, plen = 0;
719 if ((!ip) || (!ip[0]) || (port < 0) || (port > 65535)) return NULL;
723 ulen = strlen(username);
724 /* max length for protocol */
725 if ((!ulen) || (ulen > 255)) return NULL;
729 plen = strlen(password);
730 /* max length for protocol */
731 if ((!plen) || (plen > 255)) return NULL;
733 ecs5 = (Ecore_Con_Socks_v5*)_ecore_con_socks_find(5, ip, port, username, ulen, password, plen);
734 if (ecs5) return (Ecore_Con_Socks*)ecs5;
736 ecs5 = calloc(1, sizeof(Ecore_Con_Socks_v5));
737 if (!ecs5) return NULL;
740 ecs5->ip = eina_stringshare_add(ip);
742 ecs5->username = eina_stringshare_add(username);
744 ecs5->password = eina_stringshare_add(password);
746 ecore_con_socks_proxies = eina_list_append(ecore_con_socks_proxies, ecs5);
747 return (Ecore_Con_Socks*)ecs5;
751 * Find a SOCKS v5 proxy in the proxy list
753 * Use this to determine if a SOCKS proxy was previously added by checking
754 * the proxy list against the parameters given.
755 * @param ip The ip address of the proxy (NOT DOMAIN NAME. IP ADDRESS.)
756 * @param port The port to connect to on the proxy, or -1 to match the first proxy with @p ip
757 * @param username The username used for the proxy (OPTIONAL)
758 * @param password The password used for the proxy (OPTIONAL)
759 * @return true only if a proxy exists matching the given params
760 * @note This function matches slightly more loosely than ecore_con_socks5_remote_add(), and
761 * ecore_con_socks5_remote_add() should be used to return the actual object.
765 ecore_con_socks5_remote_exists(const char *ip, int port, const char *username, const char *password)
767 if ((!ip) || (!ip[0]) || (port < -1) || (port > 65535) || (username && (!username[0])) || (password && (!password[0])))
769 return !!_ecore_con_socks_find(5, ip, port, username, username ? strlen(username) : 0, password, password ? strlen(password) : 0);
773 * Remove a SOCKS v5 proxy from the proxy list and delete it
775 * Use this to remove a SOCKS proxy from the proxy list by checking
776 * the list against the parameters given. The proxy will then be deleted.
777 * @param ip The ip address of the proxy (NOT DOMAIN NAME. IP ADDRESS.)
778 * @param port The port to connect to on the proxy, or -1 to match the first proxy with @p ip
779 * @param username The username used for the proxy (OPTIONAL)
780 * @param password The password used for the proxy (OPTIONAL)
781 * @note This function matches in the same way as ecore_con_socks4_remote_exists().
782 * @warning Be aware that deleting a proxy which is being used WILL ruin your life.
786 ecore_con_socks5_remote_del(const char *ip, int port, const char *username, const char *password)
788 Ecore_Con_Socks_v5 *v5;
790 if ((!ip) || (!ip[0]) || (port < -1) || (port > 65535) || (username && (!username[0])) || (password && (!password[0])))
792 if (!ecore_con_socks_proxies) return;
794 v5 = (Ecore_Con_Socks_v5*)_ecore_con_socks_find(5, ip, port, username, username ? strlen(username) : 0, password, password ? strlen(password) : 0);
796 ecore_con_socks_proxies = eina_list_remove(ecore_con_socks_proxies, v5);
797 _ecore_con_socks_free((Ecore_Con_Socks*)v5);
801 * Set DNS lookup mode on an existing SOCKS proxy
803 * According to RFC, SOCKS v4 does not require that a proxy perform
804 * its own DNS lookups for addresses. SOCKS v4a specifies the protocol
805 * for this. SOCKS v5 allows DNS lookups.
806 * If you want to enable remote DNS lookup and are sure that your
807 * proxy supports it, use this function.
808 * @param ecs The proxy object
809 * @param enable If true, the proxy will perform the dns lookup
810 * @note By default, this setting is DISABLED.
814 ecore_con_socks_lookup_set(Ecore_Con_Socks *ecs, Eina_Bool enable)
816 ECORE_CON_SOCKS_CAST_ELSE(ecs) return;
817 ecs->lookup = !!enable;
821 * Get DNS lookup mode on an existing SOCKS proxy
823 * According to RFC, SOCKS v4 does not require that a proxy perform
824 * its own DNS lookups for addresses. SOCKS v4a specifies the protocol
825 * for this. SOCKS v5 allows DNS lookups.
826 * This function returns whether lookups are enabled on a proxy object.
827 * @param ecs The proxy object
828 * @return If true, the proxy will perform the dns lookup
829 * @note By default, this setting is DISABLED.
833 ecore_con_socks_lookup_get(Ecore_Con_Socks *ecs)
835 ECORE_CON_SOCKS_CAST_ELSE(ecs) return EINA_FALSE;
840 * Enable bind mode on a SOCKS proxy
842 * Use this function to enable binding a remote port for use with a remote server.
843 * For more information, see http://ufasoft.com/doc/socks4_protocol.htm
844 * @param ecs The proxy object
845 * @param is_bind If true, the connection established will be a port binding
846 * @warning Be aware that changing the operation mode of an active proxy may result in undefined behavior
850 ecore_con_socks_bind_set(Ecore_Con_Socks *ecs, Eina_Bool is_bind)
852 EINA_SAFETY_ON_NULL_RETURN(ecs);
853 ecs->bind = !!is_bind;
857 * Return bind mode of a SOCKS proxy
859 * Use this function to return bind mode of a proxy (binding a remote port for use with a remote server).
860 * For more information, see http://ufasoft.com/doc/socks4_protocol.htm
861 * @param ecs The proxy object
862 * @return If true, the connection established will be a port binding
866 ecore_con_socks_bind_get(Ecore_Con_Socks *ecs)
868 EINA_SAFETY_ON_NULL_RETURN_VAL(ecs, EINA_FALSE);
873 * Return SOCKS version of a SOCKS proxy
875 * Use this function to return the SOCKS protocol version of a proxy
876 * @param ecs The proxy object
877 * @return 0 on error, else 4/5
881 ecore_con_socks_version_get(Ecore_Con_Socks *ecs)
883 EINA_SAFETY_ON_NULL_RETURN_VAL(ecs, 0);
888 * Remove a SOCKS v4 proxy from the proxy list and delete it
890 * Use this to remove a SOCKS proxy from the proxy list by directly deleting the object given.
891 * @param ecs The proxy object to delete
892 * @warning Be aware that deleting a proxy which is being used WILL ruin your life.
896 ecore_con_socks_remote_del(Ecore_Con_Socks *ecs)
898 EINA_SAFETY_ON_NULL_RETURN(ecs);
899 if (!ecore_con_socks_proxies) return;
901 ecore_con_socks_proxies = eina_list_remove(ecore_con_socks_proxies, ecs);
902 _ecore_con_socks_free(ecs);
906 * Set a proxy object to be used with the next server created with ecore_con_server_connect()
908 * This function sets a proxy for the next ecore_con connection. After the next server is created,
909 * the proxy will NEVER be applied again unless explicitly enabled.
910 * @param ecs The proxy object
911 * @see ecore_con_socks_apply_always()
915 ecore_con_socks_apply_once(Ecore_Con_Socks *ecs)
917 _ecore_con_proxy_once = ecs;
921 * Set a proxy object to be used with all servers created with ecore_con_server_connect()
923 * This function sets a proxy for all ecore_con connections. It will always be used.
924 * @param ecs The proxy object
925 * @see ecore_con_socks_apply_once()
927 * @note ecore-con supports setting this through environment variables like so:
928 * ECORE_CON_SOCKS_V4=[user@]server-port:lookup
929 * ECORE_CON_SOCKS_V5=[user@]server-port:lookup
930 * user is the OPTIONAL string that would be passed to the proxy as the username
931 * server is the IP_ADDRESS of the proxy server
932 * port is the port to connect to on the proxy server
933 * lookup is 1 if the proxy should perform all DNS lookups, otherwise 0 or omitted
936 ecore_con_socks_apply_always(Ecore_Con_Socks *ecs)
938 _ecore_con_proxy_global = ecs;