introducinggggggggggggggg <drum roll>:
authordiscomfitor <discomfitor@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Tue, 6 Dec 2011 03:32:16 +0000 (03:32 +0000)
committerdiscomfitor <discomfitor@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Tue, 6 Dec 2011 03:32:16 +0000 (03:32 +0000)
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

git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/ecore@65934 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

ChangeLog
NEWS
configure.ac
src/lib/ecore_con/Ecore_Con.h
src/lib/ecore_con/Makefile.am
src/lib/ecore_con/ecore_con.c
src/lib/ecore_con/ecore_con_alloc.c
src/lib/ecore_con/ecore_con_ares.c
src/lib/ecore_con/ecore_con_info.c
src/lib/ecore_con/ecore_con_private.h

index 019b5a0..793a600 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
 2011-12-04 Mike Blumenkrantz
 
         * added ecore_timer_reset()
+
+2011-12-05 Mike Blumenkrantz
+
+        * added ecore_con_socks api
diff --git a/NEWS b/NEWS
index df034e6..6fff530 100644 (file)
--- a/NEWS
+++ b/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()
 
index 41ebbf1..60c7636 100644 (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"
index e3b68c4..66c8c26 100644 (file)
@@ -234,6 +234,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
  * @ingroup Ecore_Con_Url_Group
@@ -325,6 +332,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
  * @ingroup Ecore_Con_Url_Group
@@ -464,6 +478,18 @@ struct _Ecore_Con_Event_Server_Write
 };
 
 /**
+ * @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
  * @ingroup Ecore_Con_Url_Group
@@ -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);
 
+
+
 /**
  * @}
  */
index 300586d..929b30e 100644 (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
index a05f7b3..4d22bba 100644 (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) ||
@@ -940,6 +965,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)
 {
     /* we got our server! */
@@ -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)
+          ecore_con_event_server_add(svr);
+        return ECORE_CALLBACK_RENEW;
+     }
+   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)
           {
-              svr->connecting = EINA_FALSE;
-              svr->start_time = ecore_time_get();
-              ecore_con_event_server_add(svr);
+             INF("PROXY STATE++");
+             svr->ecs_state++;
           }
+        if (ecore_con_socks_svr_init(svr)) return ECORE_CALLBACK_RENEW;
      }
-   else if (want_read)
+   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);
      }
index 206948b..d922f20 100644 (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
index dd5a212..3738e85 100644 (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));
index 4ece6b0..f451f6a 100644 (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;
index af7ffbd..532c1a8 100644 (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);