diff --git a/legacy/ecore/ChangeLog b/legacy/ecore/ChangeLog index 019b5a0c6c..793a600668 100644 --- a/legacy/ecore/ChangeLog +++ b/legacy/ecore/ChangeLog @@ -380,3 +380,7 @@ 2011-12-04 Mike Blumenkrantz * added ecore_timer_reset() + +2011-12-05 Mike Blumenkrantz + + * added ecore_con_socks api diff --git a/legacy/ecore/NEWS b/legacy/ecore/NEWS index df034e6c33..6fff5308d6 100644 --- a/legacy/ecore/NEWS +++ b/legacy/ecore/NEWS @@ -6,6 +6,8 @@ Changes since Ecore 1.1.0: Additions: * ecore - ecore_timer_reset() + * ecore_con + - ecore_con_socks api * ecore_x: - ecore_x_randr_output_backlight_available() diff --git a/legacy/ecore/configure.ac b/legacy/ecore/configure.ac index 41ebbf1273..60c7636fe2 100644 --- a/legacy/ecore/configure.ac +++ b/legacy/ecore/configure.ac @@ -1190,7 +1190,7 @@ esac # ecore_con -AC_CHECK_HEADERS([arpa/inet.h arpa/nameser.h netinet/tcp.h netinet/in.h sys/socket.h sys/un.h ws2tcpip.h netdb.h]) +AC_CHECK_HEADERS([arpa/inet.h arpa/nameser.h netinet/tcp.h net/if.h netinet/in.h sys/socket.h sys/un.h ws2tcpip.h netdb.h]) if test "x${ac_cv_header_netdb_h}" = "xyes" ; then have_addrinfo="yes" diff --git a/legacy/ecore/src/lib/ecore_con/Ecore_Con.h b/legacy/ecore/src/lib/ecore_con/Ecore_Con.h index e3b68c4a98..66c8c26c02 100644 --- a/legacy/ecore/src/lib/ecore_con/Ecore_Con.h +++ b/legacy/ecore/src/lib/ecore_con/Ecore_Con.h @@ -233,6 +233,13 @@ typedef struct _Ecore_Con_Server Ecore_Con_Server; */ typedef struct _Ecore_Con_Client Ecore_Con_Client; +/** + * @typedef Ecore_Con_Socks + * An object representing a SOCKS proxy + * @ingroup Ecore_Con_Socks_Group + */ +typedef struct Ecore_Con_Socks Ecore_Con_Socks; + /** * @typedef Ecore_Con_Url * A handle to an http upload/download object @@ -324,6 +331,13 @@ typedef struct _Ecore_Con_Event_Client_Write Ecore_Con_Event_Client_Write; */ typedef struct _Ecore_Con_Event_Server_Write Ecore_Con_Event_Server_Write; +/** + * @typedef Ecore_Con_Event_Proxy_Bind + * Used as the @p data param for the corresponding event + * @since 1.2 + */ +typedef struct _Ecore_Con_Event_Proxy_Bind Ecore_Con_Event_Proxy_Bind; + /** * @typedef Ecore_Con_Event_Url_Data * Used as the @p data param for the corresponding event @@ -463,6 +477,18 @@ struct _Ecore_Con_Event_Server_Write int size; /**< the length of the data sent */ }; +/** + * @struct _Ecore_Con_Event_Proxy_Bind + * Used as the @p data param for the @ref ECORE_CON_EVENT_PROXY_BIND event + * @ingroup Ecore_Con_Socks_Group + */ +struct _Ecore_Con_Event_Proxy_Bind +{ + Ecore_Con_Server *server; /**< the server object connected to the proxy */ + const char *ip; /**< the proxy-bound ip address */ + int port; /**< the proxy-bound port */ +}; + /** * @struct _Ecore_Con_Event_Url_Data * Used as the @p data param for the @ref ECORE_CON_EVENT_URL_DATA event @@ -542,6 +568,10 @@ EAPI extern int ECORE_CON_EVENT_SERVER_WRITE; EAPI extern int ECORE_CON_EVENT_CLIENT_DATA; /** A server connection object has data */ EAPI extern int ECORE_CON_EVENT_SERVER_DATA; +/** A server connection has successfully negotiated an ip:port binding + * @since 1.2 + */ +EAPI extern int ECORE_CON_EVENT_PROXY_BIND; /** A URL object has data */ EAPI extern int ECORE_CON_EVENT_URL_DATA; /** A URL object has completed its transfer to and from the server and can be reused */ @@ -682,6 +712,18 @@ EAPI Eina_Bool ecore_con_ssl_client_upgrade(Ecore_Con_Client *cl, Ecore_ * @} */ +EAPI Ecore_Con_Socks *ecore_con_socks4_remote_add(const char *ip, int port, const char *username); +EAPI void ecore_con_socks4_lookup_set(Ecore_Con_Socks *ecs, Eina_Bool enable); +EAPI Eina_Bool ecore_con_socks4_lookup_get(Ecore_Con_Socks *ecs); +EAPI Eina_Bool ecore_con_socks4_remote_exists(const char *ip, int port, const char *username); +EAPI void ecore_con_socks4_remote_del(const char *ip, int port, const char *username); +EAPI void ecore_con_socks_bind_set(Ecore_Con_Socks *ecs, Eina_Bool is_bind); +EAPI Eina_Bool ecore_con_socks_bind_get(Ecore_Con_Socks *ecs); +EAPI unsigned int ecore_con_socks_version_get(Ecore_Con_Socks *ecs); +EAPI void ecore_con_socks_remote_del(Ecore_Con_Socks *ecs); +EAPI void ecore_con_socks_apply_once(Ecore_Con_Socks *ecs); +EAPI void ecore_con_socks_apply_always(Ecore_Con_Socks *ecs); + /** * @defgroup Ecore_Con_Server_Group Ecore Connection Server Functions * @@ -1185,6 +1227,8 @@ EAPI Eina_Bool ecore_con_client_connected_get(Ecore_Con_Client *cl); */ EAPI int ecore_con_client_port_get(Ecore_Con_Client *cl); + + /** * @} */ diff --git a/legacy/ecore/src/lib/ecore_con/Makefile.am b/legacy/ecore/src/lib/ecore_con/Makefile.am index 300586dd10..929b30e9c4 100644 --- a/legacy/ecore/src/lib/ecore_con/Makefile.am +++ b/legacy/ecore/src/lib/ecore_con/Makefile.am @@ -19,6 +19,7 @@ includesdir = $(includedir)/ecore-@VMAJ@ libecore_con_la_SOURCES = \ ecore_con.c \ +ecore_con_socks.c \ ecore_con_ssl.c \ ecore_con_url.c \ ecore_con_alloc.c diff --git a/legacy/ecore/src/lib/ecore_con/ecore_con.c b/legacy/ecore/src/lib/ecore_con/ecore_con.c index a05f7b3009..4d22bbad54 100644 --- a/legacy/ecore/src/lib/ecore_con/ecore_con.c +++ b/legacy/ecore/src/lib/ecore_con/ecore_con.c @@ -114,11 +114,14 @@ EAPI int ECORE_CON_EVENT_CLIENT_WRITE = 0; EAPI int ECORE_CON_EVENT_SERVER_WRITE = 0; EAPI int ECORE_CON_EVENT_CLIENT_ERROR = 0; EAPI int ECORE_CON_EVENT_SERVER_ERROR = 0; +EAPI int ECORE_CON_EVENT_PROXY_BIND = 0; static Eina_List *servers = NULL; static int _ecore_con_init_count = 0; static int _ecore_con_event_count = 0; int _ecore_con_log_dom = -1; +Ecore_Con_Socks *_ecore_con_proxy_once = NULL; +Ecore_Con_Socks *_ecore_con_proxy_global = NULL; EAPI int ecore_con_init(void) @@ -156,6 +159,7 @@ ecore_con_init(void) ECORE_CON_EVENT_SERVER_WRITE = ecore_event_type_new(); ECORE_CON_EVENT_CLIENT_ERROR = ecore_event_type_new(); ECORE_CON_EVENT_SERVER_ERROR = ecore_event_type_new(); + ECORE_CON_EVENT_PROXY_BIND = ecore_event_type_new(); eina_magic_string_set(ECORE_MAGIC_CON_SERVER, "Ecore_Con_Server"); @@ -163,6 +167,7 @@ ecore_con_init(void) eina_magic_string_set(ECORE_MAGIC_CON_URL, "Ecore_Con_Url"); /* TODO Remember return value, if it fails, use gethostbyname() */ + ecore_con_socks_init(); ecore_con_ssl_init(); ecore_con_info_init(); @@ -190,6 +195,7 @@ ecore_con_shutdown(void) _ecore_con_server_free(svr); } + ecore_con_socks_shutdown(); if (!_ecore_con_event_count) ecore_con_mempool_shutdown(); ecore_con_info_shutdown(); @@ -400,11 +406,30 @@ ecore_con_server_connect(Ecore_Con_Type compl_type, svr->reject_excess_clients = EINA_FALSE; svr->clients = NULL; svr->client_limit = -1; - if (ecore_con_ssl_server_prepare(svr, compl_type & ECORE_CON_SSL)) - goto error; type = compl_type & ECORE_CON_TYPE; + if (type > ECORE_CON_LOCAL_ABSTRACT) + { + /* never use proxies on local connections */ + if (_ecore_con_proxy_once) + svr->ecs = _ecore_con_proxy_once; + else if (_ecore_con_proxy_global) + svr->ecs = _ecore_con_proxy_global; + _ecore_con_proxy_once = NULL; + if (svr->ecs) + { + if ((!svr->ecs->lookup) && + (!ecore_con_lookup(svr->name, (Ecore_Con_Dns_Cb)ecore_con_socks_dns_cb, svr))) + goto error; + if (svr->ecs->lookup) + svr->ecs_state = ECORE_CON_SOCKS_STATE_RESOLVED; + } + + } + if (ecore_con_ssl_server_prepare(svr, compl_type & ECORE_CON_SSL)) + goto error; + if (((type == ECORE_CON_REMOTE_TCP) || (type == ECORE_CON_REMOTE_NODELAY) || (type == ECORE_CON_REMOTE_UDP) || @@ -939,6 +964,25 @@ ecore_con_client_fd_get(Ecore_Con_Client *cl) * @} */ +void +ecore_con_event_proxy_bind(Ecore_Con_Server *svr) +{ + Ecore_Con_Event_Proxy_Bind *e; + int ev = ECORE_CON_EVENT_PROXY_BIND; + + e = ecore_con_event_proxy_bind_alloc(); + EINA_SAFETY_ON_NULL_RETURN(e); + + svr->event_count = eina_list_append(svr->event_count, e); + _ecore_con_server_timer_update(svr); + e->server = svr; + e->ip = svr->proxyip; + e->port = svr->proxyport; + ecore_event_add(ev, e, + _ecore_con_event_server_add_free, NULL); + _ecore_con_event_count++; +} + void ecore_con_event_server_add(Ecore_Con_Server *svr) { @@ -949,6 +993,8 @@ ecore_con_event_server_add(Ecore_Con_Server *svr) e = ecore_con_event_server_add_alloc(); EINA_SAFETY_ON_NULL_RETURN(e); + svr->connecting = EINA_FALSE; + svr->start_time = ecore_time_get(); svr->event_count = eina_list_append(svr->event_count, e); _ecore_con_server_timer_update(svr); e->server = svr; @@ -1212,6 +1258,9 @@ _ecore_con_server_free(Ecore_Con_Server *svr) eina_stringshare_del(svr->ip); + if (svr->ecs_buf) eina_binbuf_free(svr->ecs_buf); + if (svr->ecs_recvbuf) eina_binbuf_free(svr->ecs_recvbuf); + if (svr->fd_handler) ecore_main_fd_handler_del(svr->fd_handler); @@ -1288,7 +1337,7 @@ _ecore_con_client_free(Ecore_Con_Client *cl) return; } -static void +void _ecore_con_server_kill(Ecore_Con_Server *svr) { if (!svr->delete_me) @@ -1666,7 +1715,8 @@ _ecore_con_cb_tcp_connect(void *data, goto error; } - svr->ip = eina_stringshare_add(net_info->ip); + if ((!svr->ecs) || (svr->ecs->lookup)) + svr->ip = eina_stringshare_add(net_info->ip); return; @@ -1739,7 +1789,8 @@ _ecore_con_cb_udp_connect(void *data, goto error; } - svr->ip = eina_stringshare_add(net_info->ip); + if ((!svr->ecs) || (svr->ecs->lookup)) + svr->ip = eina_stringshare_add(net_info->ip); return; @@ -1783,9 +1834,13 @@ svr_try_connect_plain(Ecore_Con_Server *svr) if ((!svr->delete_me) && (!svr->handshaking) && svr->connecting) { - svr->connecting = EINA_FALSE; - svr->start_time = ecore_time_get(); - ecore_con_event_server_add(svr); + if (svr->ecs) + { + if (ecore_con_socks_svr_init(svr)) + return ECORE_CON_INPROGRESS; + } + else + ecore_con_event_server_add(svr); } if (svr->fd_handler && (!svr->buf)) @@ -1936,11 +1991,12 @@ _ecore_con_svr_tcp_handler(void *data, static void _ecore_con_cl_read(Ecore_Con_Server *svr) { - DBG("svr=%p", svr); int num = 0; Eina_Bool lost_server = EINA_TRUE; unsigned char buf[READBUFSIZ]; + DBG("svr=%p", svr); + /* only possible with non-ssl connections */ if (svr->connecting && (svr_try_connect_plain(svr) != ECORE_CON_CONNECTED)) return; @@ -1971,7 +2027,12 @@ _ecore_con_cl_read(Ecore_Con_Server *svr) } if ((!svr->delete_me) && (num > 0)) - ecore_con_event_server_data(svr, buf, num, EINA_TRUE); + { + if (svr->ecs_state) + ecore_con_socks_read(svr, buf, num); + else + ecore_con_event_server_data(svr, buf, num, EINA_TRUE); + } if (lost_server) _ecore_con_server_kill(svr); @@ -1994,7 +2055,7 @@ _ecore_con_cl_handler(void *data, want_read = ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ); want_write = ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE); - if (svr->handshaking && (want_read || want_write)) + if ((!svr->ecs_state) && svr->handshaking && (want_read || want_write)) { DBG("Continuing ssl handshake: preparing to %s...", want_read ? "read" : "write"); #ifdef ISCOMFITOR @@ -2013,17 +2074,23 @@ _ecore_con_cl_handler(void *data, } else if (!svr->ssl_state) - { - svr->connecting = EINA_FALSE; - svr->start_time = ecore_time_get(); - ecore_con_event_server_add(svr); - } + ecore_con_event_server_add(svr); + return ECORE_CALLBACK_RENEW; } - else if (want_read) + if (svr->ecs && svr->ecs_state && (svr->ecs_state < ECORE_CON_SOCKS_STATE_READ) && (!svr->ecs_buf)) + { + if (svr->ecs_state < ECORE_CON_SOCKS_STATE_INIT) + { + INF("PROXY STATE++"); + svr->ecs_state++; + } + if (ecore_con_socks_svr_init(svr)) return ECORE_CALLBACK_RENEW; + } + if (want_read) _ecore_con_cl_read(svr); else if (want_write) /* only possible with non-ssl connections */ { - if (svr->connecting && (!svr_try_connect_plain(svr))) + if (svr->connecting && (!svr_try_connect_plain(svr)) && (!svr->ecs_state)) return ECORE_CALLBACK_RENEW; _ecore_con_server_flush(svr); @@ -2238,19 +2305,24 @@ static void _ecore_con_server_flush(Ecore_Con_Server *svr) { int count, num; + size_t buf_len, buf_offset; + const void *buf; #ifdef _WIN32 if (ecore_con_local_win32_server_flush(svr)) return; #endif - if ((!svr->buf) && svr->fd_handler) + if ((!svr->buf) && (!svr->ecs_buf) && svr->fd_handler) { ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ); return; } - num = eina_binbuf_length_get(svr->buf) - svr->write_buf_offset; + buf = svr->buf ? eina_binbuf_string_get(svr->buf) : eina_binbuf_string_get(svr->ecs_buf); + buf_len = svr->buf ? eina_binbuf_length_get(svr->buf) : eina_binbuf_length_get(svr->ecs_buf); + buf_offset = svr->buf ? svr->write_buf_offset : svr->ecs_buf_offset; + num = buf_len - buf_offset; /* check whether we need to write anything at all. * we must not write zero bytes with SSL_write() since it @@ -2271,9 +2343,9 @@ _ecore_con_server_flush(Ecore_Con_Server *svr) } if (!(svr->type & ECORE_CON_SSL)) - count = write(svr->fd, eina_binbuf_string_get(svr->buf) + svr->write_buf_offset, num); + count = write(svr->fd, buf + buf_offset, num); else - count = ecore_con_ssl_server_write(svr, eina_binbuf_string_get(svr->buf) + svr->write_buf_offset, num); + count = ecore_con_ssl_server_write(svr, buf + buf_offset, num); if (count < 0) { @@ -2285,13 +2357,28 @@ _ecore_con_server_flush(Ecore_Con_Server *svr) return; } - if (count) ecore_con_event_server_write(svr, count); - svr->write_buf_offset += count; - if (svr->write_buf_offset >= eina_binbuf_length_get(svr->buf)) + if (count && (!svr->ecs_state)) ecore_con_event_server_write(svr, count); + if (svr->ecs_buf) + buf_offset = svr->ecs_buf_offset += count; + else + buf_offset = svr->write_buf_offset += count; + if (buf_offset >= buf_len) { - svr->write_buf_offset = 0; - eina_binbuf_free(svr->buf); - svr->buf = NULL; + if (svr->ecs_buf) + { + svr->ecs_buf_offset = 0; + eina_binbuf_free(svr->ecs_buf); + svr->ecs_buf = NULL; + INF("PROXY STATE++"); + svr->ecs_state++; + } + else + { + svr->write_buf_offset = 0; + eina_binbuf_free(svr->buf); + svr->buf = NULL; + } + if (svr->fd_handler) ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ); } diff --git a/legacy/ecore/src/lib/ecore_con/ecore_con_alloc.c b/legacy/ecore/src/lib/ecore_con/ecore_con_alloc.c index 206948b77d..d922f204d1 100644 --- a/legacy/ecore/src/lib/ecore_con/ecore_con_alloc.c +++ b/legacy/ecore/src/lib/ecore_con/ecore_con_alloc.c @@ -40,6 +40,7 @@ GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Add, ecore_con_event_server_add); GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Del, ecore_con_event_server_del); GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Write, ecore_con_event_server_write); GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Data, ecore_con_event_server_data); +GENERIC_ALLOC_FREE(Ecore_Con_Event_Proxy_Bind, ecore_con_event_proxy_bind); static Ecore_Con_Mempool *mempool_array[] = { &ecore_con_event_client_add_mp, @@ -51,7 +52,8 @@ static Ecore_Con_Mempool *mempool_array[] = { &ecore_con_event_server_add_mp, &ecore_con_event_server_del_mp, &ecore_con_event_server_write_mp, - &ecore_con_event_server_data_mp + &ecore_con_event_server_data_mp, + &ecore_con_event_proxy_bind_mp }; void diff --git a/legacy/ecore/src/lib/ecore_con/ecore_con_ares.c b/legacy/ecore/src/lib/ecore_con/ecore_con_ares.c index dd5a212546..3738e852ab 100644 --- a/legacy/ecore/src/lib/ecore_con/ecore_con_ares.c +++ b/legacy/ecore/src/lib/ecore_con/ecore_con_ares.c @@ -309,7 +309,7 @@ ecore_con_info_get(Ecore_Con_Server *svr, memcpy(&cares->hints, hints, sizeof(struct addrinfo)); } - if (inet_pton(AF_INET, svr->name, &cares->addr.v4) == 1) + if (inet_pton(AF_INET, svr->ecs : svr->ecs->ip : svr->name, &cares->addr.v4) == 1) { cares->byaddr = EINA_TRUE; cares->isv6 = EINA_FALSE; @@ -320,7 +320,7 @@ ecore_con_info_get(Ecore_Con_Server *svr, cares); } #ifdef HAVE_IPV6 - else if (inet_pton(AF_INET6, svr->name, &cares->addr.v6) == 1) + else if (inet_pton(AF_INET6, svr->ecs : svr->ecs->ip : svr->name, &cares->addr.v6) == 1) { cares->byaddr = EINA_TRUE; cares->isv6 = EINA_TRUE; @@ -334,7 +334,7 @@ ecore_con_info_get(Ecore_Con_Server *svr, else { cares->byaddr = EINA_FALSE; - ares_gethostbyname(info_channel, svr->name, ai_family, + ares_gethostbyname(info_channel, svr->ecs : svr->ecs->ip : svr->name, ai_family, (ares_host_callback)_ecore_con_info_ares_host_cb, cares); } @@ -457,7 +457,7 @@ _ecore_con_info_ares_host_cb(Ecore_Con_CAres *arg, goto on_mem_error; addri->sin_family = AF_INET; - addri->sin_port = htons(arg->svr->port); + addri->sin_port = htons(arg->svr->ecs : svr->ecs->port : svr->port); memcpy(&addri->sin_addr.s_addr, hostent->h_addr_list[0], sizeof(struct in_addr)); @@ -477,7 +477,7 @@ _ecore_con_info_ares_host_cb(Ecore_Con_CAres *arg, goto on_mem_error; addri6->sin6_family = AF_INET6; - addri6->sin6_port = htons(arg->svr->port); + addri6->sin6_port = htons(arg->svr->ecs : svr->ecs->port : svr->port); addri6->sin6_flowinfo = 0; addri6->sin6_scope_id = 0; @@ -516,7 +516,7 @@ _ecore_con_info_ares_host_cb(Ecore_Con_CAres *arg, goto on_mem_error; addri6->sin6_family = AF_INET6; - addri6->sin6_port = htons(arg->svr->port); + addri6->sin6_port = htons(arg->svr->ecs : svr->ecs->port : svr->port); addri6->sin6_flowinfo = 0; addri6->sin6_scope_id = 0; @@ -537,7 +537,7 @@ _ecore_con_info_ares_host_cb(Ecore_Con_CAres *arg, goto on_mem_error; addri->sin_family = AF_INET; - addri->sin_port = htons(arg->svr->port); + addri->sin_port = htons(arg->svr->ecs : svr->ecs->port : svr->port); memcpy(&addri->sin_addr.s_addr, &arg->addr.v4, sizeof(struct in_addr)); diff --git a/legacy/ecore/src/lib/ecore_con/ecore_con_info.c b/legacy/ecore/src/lib/ecore_con/ecore_con_info.c index 4ece6b00c1..f451f6ab26 100644 --- a/legacy/ecore/src/lib/ecore_con/ecore_con_info.c +++ b/legacy/ecore/src/lib/ecore_con/ecore_con_info.c @@ -246,9 +246,9 @@ ecore_con_info_get(Ecore_Con_Server *svr, int canonname_len = 0; int err; - eina_convert_itoa(svr->port, service); + eina_convert_itoa(svr->ecs ? svr->ecs->port : svr->port, service); /* CHILD */ - if (!getaddrinfo(svr->name, service, hints, &result) && result) + if (!getaddrinfo(svr->ecs ? svr->ecs->ip : svr->name, service, hints, &result) && result) { if (result->ai_canonname) canonname_len = strlen(result->ai_canonname) + 1; diff --git a/legacy/ecore/src/lib/ecore_con/ecore_con_private.h b/legacy/ecore/src/lib/ecore_con/ecore_con_private.h index af7ffbd0e8..532c1a837c 100644 --- a/legacy/ecore/src/lib/ecore_con/ecore_con_private.h +++ b/legacy/ecore/src/lib/ecore_con/ecore_con_private.h @@ -56,7 +56,8 @@ extern int _ecore_con_log_dom; typedef struct _Ecore_Con_Lookup Ecore_Con_Lookup; typedef struct _Ecore_Con_Info Ecore_Con_Info; - +typedef struct Ecore_Con_Socks_v4 Ecore_Con_Socks_v4; +typedef struct Ecore_Con_Socks_v5 Ecore_Con_Socks_v5; typedef void (*Ecore_Con_Info_Cb)(void *data, Ecore_Con_Info *infos); typedef enum _Ecore_Con_State @@ -82,6 +83,14 @@ typedef enum _Ecore_Con_Ssl_Handshake ECORE_CON_SSL_STATE_INIT } Ecore_Con_Ssl_State; +typedef enum Ecore_Con_Socks_State +{ + ECORE_CON_SOCKS_STATE_DONE = 0, + ECORE_CON_SOCKS_STATE_RESOLVED, + ECORE_CON_SOCKS_STATE_INIT, + ECORE_CON_SOCKS_STATE_READ +} Ecore_Con_Socks_State; + struct _Ecore_Con_Client { ECORE_MAGIC; @@ -130,6 +139,17 @@ struct _Ecore_Con_Server Eina_List *event_count; int client_limit; pid_t ppid; + /* socks */ + Ecore_Con_Socks *ecs; + Ecore_Con_Socks_State ecs_state; + int ecs_addrlen; + unsigned char ecs_addr[16]; + unsigned int ecs_buf_offset; + Eina_Binbuf *ecs_buf; + Eina_Binbuf *ecs_recvbuf; + const char *proxyip; + int proxyport; + /* endsocks */ #if USE_GNUTLS gnutls_session_t session; gnutls_anon_client_credentials_t anoncred_c; @@ -206,8 +226,58 @@ struct _Ecore_Con_Lookup const void *data; }; +#define ECORE_CON_SOCKS_CAST_ELSE(X) \ + Ecore_Con_Socks_v4 *v4 = NULL; \ + Ecore_Con_Socks_v5 *v5 = NULL; \ + if ((X) && ((X)->version == 4)) \ + v4 = (Ecore_Con_Socks_v4*)(X); \ + else if ((X) && ((X)->version == 5)) \ + v5 = (Ecore_Con_Socks_v5*)(X); \ + else + +struct Ecore_Con_Socks +{ + unsigned char version; + + const char *ip; + int port; + const char *username; + Eina_Bool lookup : 1; + Eina_Bool bind : 1; +}; + +struct Ecore_Con_Socks_v4 +{ + unsigned char version; + + const char *ip; + int port; + const char *username; + Eina_Bool lookup : 1; + Eina_Bool bind : 1; +}; + +struct Ecore_Con_Socks_v5 +{ + unsigned char version; + + const char *ip; + int port; + const char *username; + Eina_Bool lookup : 1; + Eina_Bool bind : 1; +}; + +extern Ecore_Con_Socks *_ecore_con_proxy_once; +extern Ecore_Con_Socks *_ecore_con_proxy_global; +void ecore_con_socks_init(void); +void ecore_con_socks_shutdown(void); +Eina_Bool ecore_con_socks_svr_init(Ecore_Con_Server *svr); +void ecore_con_socks_read(Ecore_Con_Server *svr, unsigned char *buf, int num); +void ecore_con_socks_dns_cb(const char *canonname, const char *ip, struct sockaddr *addr, int addrlen, Ecore_Con_Server *svr); /* from ecore_con.c */ void ecore_con_server_infos_del(Ecore_Con_Server *svr, void *info); +void ecore_con_event_proxy_bind(Ecore_Con_Server *svr); void ecore_con_event_server_data(Ecore_Con_Server *svr, unsigned char *buf, int num, Eina_Bool duplicate); void ecore_con_event_server_del(Ecore_Con_Server *svr); void ecore_con_event_server_error(Ecore_Con_Server *svr, const char *error); @@ -215,7 +285,7 @@ void ecore_con_event_client_add(Ecore_Con_Client *cl); void ecore_con_event_client_data(Ecore_Con_Client *cl, unsigned char *buf, int num, Eina_Bool duplicate); void ecore_con_event_client_del(Ecore_Con_Client *cl); void ecore_con_event_client_error(Ecore_Con_Client *cl, const char *error); - +void _ecore_con_server_kill(Ecore_Con_Server *svr); /* from ecore_local_win32.c */ #ifdef _WIN32 Eina_Bool ecore_con_local_listen(Ecore_Con_Server *svr); @@ -306,6 +376,7 @@ GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Server_Add, ecore_con_event_server_add GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Server_Del, ecore_con_event_server_del); GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Server_Write, ecore_con_event_server_write); GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Server_Data, ecore_con_event_server_data); +GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Proxy_Bind, ecore_con_event_proxy_bind); void ecore_con_mempool_init(void); void ecore_con_mempool_shutdown(void);