introducinggggggggggggggg <drum roll>:

ECORE-CON-SOCKS! SOCKS ON!!!!

now ecore_con supports socks (v4 and v4a only, so no ipv6) connections natively for making remote connections
for those of you who want their apps to start proxying immediately, just update and export this handy environment variable:
ECORE_CON_SOCKS_V4=[user@]PROXY_IP_ADDRESS:PROXY_PORT[:1] <--use :1 here to enable dns lookups on the proxy


SVN revision: 65934
This commit is contained in:
Mike Blumenkrantz 2011-12-06 03:32:16 +00:00
parent 9935288eaa
commit 0099b08234
10 changed files with 252 additions and 41 deletions

View File

@ -380,3 +380,7 @@
2011-12-04 Mike Blumenkrantz
* added ecore_timer_reset()
2011-12-05 Mike Blumenkrantz
* added ecore_con_socks api

View File

@ -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()

View File

@ -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"

View File

@ -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);
/**
* @}
*/

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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));

View File

@ -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;

View File

@ -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);