Starting work for IPv6 support of ecore_con. Use getaddrinfo and getnameinfo instead...
authorcedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Mon, 6 Oct 2008 09:41:39 +0000 (09:41 +0000)
committercedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Mon, 6 Oct 2008 09:41:39 +0000 (09:41 +0000)
Patch from Arnaud de Turckheim.

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

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_info.c [new file with mode: 0644]
src/lib/ecore_con/ecore_con_private.h

index a1ab4d4..6e81ac5 100644 (file)
 extern "C" {
 #endif
    
-   typedef struct _Ecore_Con_Server Ecore_Con_Server; /**< A connection handle */
-   typedef struct _Ecore_Con_Client Ecore_Con_Client; /**< A connection handle */
-   typedef struct _Ecore_Con_Url    Ecore_Con_Url;
-   
+   typedef struct _Ecore_Con_Server  Ecore_Con_Server; /**< A connection handle */
+   typedef struct _Ecore_Con_Client  Ecore_Con_Client; /**< A connection handle */
+   typedef struct _Ecore_Con_Url     Ecore_Con_Url;
+   typedef struct _Ecore_Con_Netinfo Ecore_Con_Netinfo;
+
    typedef enum _Ecore_Con_Type
      {
        ECORE_CON_LOCAL_USER,
index aa2e9b8..b526047 100644 (file)
@@ -16,6 +16,7 @@ Ecore_Con.h
 libecore_con_la_SOURCES = \
 ecore_con.c \
 ecore_con_dns.c \
+ecore_con_info.c \
 ecore_con_url.c \
 ecore_con_private.h
 
index 677e995..4c5d5e9 100644 (file)
 
 static void _ecore_con_cb_dns_lookup(void *data, struct hostent *he);
 static void _ecore_con_cb_udp_dns_lookup(void *data, struct hostent *he);
+static void _ecore_con_cb_tcp_connect(void *data, Ecore_Con_Netinfo *info);
+static void _ecore_con_cb_udp_connect(void *data, Ecore_Con_Netinfo *info);
+static void _ecore_con_cb_tcp_listen(void *data, Ecore_Con_Netinfo *info);
+static void _ecore_con_cb_udp_listen(void *data, Ecore_Con_Netinfo *info);
 static void _ecore_con_server_free(Ecore_Con_Server *svr);
 static void _ecore_con_client_free(Ecore_Con_Client *cl);
 static int _ecore_con_svr_handler(void *data, Ecore_Fd_Handler *fd_handler);
@@ -88,6 +92,7 @@ ecore_con_init(void)
 
    /* TODO Remember return value, if it fails, use gethostbyname() */
    ecore_con_dns_init();
+   ecore_con_info_init();
 
    servers = ecore_list_new();
 
@@ -110,6 +115,7 @@ ecore_con_shutdown(void)
    ecore_list_destroy(servers);
    servers = NULL;
 
+   ecore_con_info_shutdown();
    ecore_con_dns_shutdown();
 
    ecore_shutdown();
@@ -386,7 +392,7 @@ ecore_con_server_add(Ecore_Con_Type compl_type, const char *name, int port,
 
    svr->name = strdup(name);
    if (!svr->name) goto error;
-   svr->type = type;
+   svr->type = compl_type;
    svr->port = port;
    svr->data = (void *)data;
    svr->created = 1;
@@ -560,13 +566,11 @@ ecore_con_server_connect(Ecore_Con_Type compl_type, const char *name, int port,
 
    if (type == ECORE_CON_REMOTE_TCP)
      {
-       if (!ecore_con_dns_lookup(svr->name, _ecore_con_cb_dns_lookup, svr))
-         goto error;
+       if (!ecore_con_info_tcp_connect(svr, _ecore_con_cb_tcp_connect, svr)) goto error;
      }
    else if (type == ECORE_CON_REMOTE_UDP)
      {
-       if (!ecore_con_dns_lookup(svr->name, _ecore_con_cb_udp_dns_lookup, svr))
-        goto error;
+        if (!ecore_con_info_udp_connect(svr, _ecore_con_cb_udp_connect, svr)) goto error;
      }
 
    return svr;
@@ -1313,6 +1317,292 @@ _ecore_con_cb_udp_dns_lookup(void *data, struct hostent *he)
    kill_server(svr);
 }
 
+static void
+_ecore_con_cb_tcp_listen(void *data, Ecore_Con_Netinfo *net_info)
+{
+   Ecore_Con_Server *svr;
+   struct linger lin;
+
+   svr = data;
+
+   if(!net_info) goto error;
+
+   svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype, net_info->info.ai_protocol);
+   if (svr->fd < 0) goto error;
+   if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
+   if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
+   lin.l_onoff = 1;
+   lin.l_linger = 0;
+   if (setsockopt(svr->fd, SOL_SOCKET, SO_LINGER, &lin, sizeof(struct linger)) < 0) goto error;
+/*    socket_addr.sin_family = AF_INET; */
+/*    socket_addr.sin_port = htons(port); */
+/*    socket_addr.sin_addr.s_addr = htonl(INADDR_ANY); */
+   if (bind(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen) < 0) goto error;
+   if (listen(svr->fd, 4096) < 0) goto error;
+   svr->fd_handler =
+     ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
+                              _ecore_con_svr_handler, svr, NULL, NULL);
+   if (!svr->fd_handler) goto error;
+
+#if USE_OPENSSL
+   if (svr->type & ECORE_CON_SSL)
+     {
+       if (!ssl_init_count)
+         {
+            SSL_library_init();
+            SSL_load_error_strings();
+         }
+       ssl_init_count++;
+
+       switch (svr->type & ECORE_CON_SSL)
+         {
+          case ECORE_CON_USE_SSL2:
+             if (!(svr->ssl_ctx = SSL_CTX_new(SSLv2_client_method())))
+               goto error;
+             break;
+          case ECORE_CON_USE_SSL3:
+             if (!(svr->ssl_ctx = SSL_CTX_new(SSLv3_client_method())))
+               goto error;
+             break;
+          case ECORE_CON_USE_TLS:
+             if (!(svr->ssl_ctx = SSL_CTX_new(TLSv1_client_method())))
+               goto error;
+             break;
+         }
+
+       if (!(svr->ssl = SSL_new(svr->ssl_ctx)))
+         goto error;
+
+       SSL_set_fd(svr->ssl, svr->fd);
+     }
+#endif
+
+   return;
+
+   error:
+#if USE_OPENSSL
+   if (svr->ssl) SSL_free(svr->ssl);
+   if (svr->ssl_ctx) SSL_CTX_free(svr->ssl_ctx);
+#endif
+   kill_server(svr);
+}
+
+static void
+_ecore_con_cb_mcast_listen(void *data, Ecore_Con_Netinfo *net_info)
+{
+   Ecore_Con_Server *svr;
+   struct ip_mreq mreq;
+   struct ipv6_mreq mreq6;
+   const int on=1;
+
+   svr = data;
+
+   if (!net_info) goto error;
+
+   svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype, net_info->info.ai_protocol);
+   if(svr->fd < 0) goto error;
+   if (net_info->info.ai_family == AF_INET)
+     {
+       if (!inet_pton(net_info->info.ai_family, net_info->ip, &mreq.imr_multiaddr)) goto error;
+       mreq.imr_interface.s_addr = htonl(INADDR_ANY);
+       if (setsockopt(svr->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,sizeof(mreq)) != 0) goto error;
+     }
+   else if (net_info->info.ai_family == AF_INET6)
+     {
+       if (!inet_pton(net_info->info.ai_family, net_info->ip, &mreq6.ipv6mr_multiaddr)) goto error;
+       mreq6.ipv6mr_interface = htonl(INADDR_ANY);
+       if (setsockopt(svr->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq6,sizeof(mreq6)) != 0) goto error;
+     }
+   if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, &on,sizeof(on)) != 0) goto error;
+   if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
+   if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
+   if (bind(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen) < 0) goto error;
+   svr->fd_handler =
+     ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
+                              _ecore_con_svr_udp_handler, svr, NULL, NULL);
+   if (!svr->fd_handler) goto error;
+
+#if USE_OPENSSL
+   if (svr->type & ECORE_CON_SSL)
+     {
+       if (!ssl_init_count)
+         {
+            SSL_library_init();
+            SSL_load_error_strings();
+         }
+       ssl_init_count++;
+
+       switch (svr->type & ECORE_CON_SSL)
+         {
+          case ECORE_CON_USE_SSL2:
+             if (!(svr->ssl_ctx = SSL_CTX_new(SSLv2_client_method())))
+               goto error;
+             break;
+          case ECORE_CON_USE_SSL3:
+             if (!(svr->ssl_ctx = SSL_CTX_new(SSLv3_client_method())))
+               goto error;
+             break;
+          case ECORE_CON_USE_TLS:
+             if (!(svr->ssl_ctx = SSL_CTX_new(TLSv1_client_method())))
+               goto error;
+             break;
+         }
+
+       if (!(svr->ssl = SSL_new(svr->ssl_ctx)))
+         goto error;
+
+       SSL_set_fd(svr->ssl, svr->fd);
+     }
+#endif
+
+   return;
+
+   error:
+#if USE_OPENSSL
+   if (svr->ssl) SSL_free(svr->ssl);
+   if (svr->ssl_ctx) SSL_CTX_free(svr->ssl_ctx);
+#endif
+   kill_server(svr);
+}
+
+static void
+_ecore_con_cb_udp_listen(void *data, Ecore_Con_Netinfo *net_info)
+{
+   //FIXME SSL
+   Ecore_Con_Server   *svr;
+   struct sockaddr_in  socket_addr;
+   int                 curstate = 0;
+   char                buf[64];
+
+   svr = data;
+
+   if (!net_info) goto error;
+   svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype, net_info->info.ai_protocol);
+   if (svr->fd < 0) goto error;
+   if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
+   if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
+   if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, &curstate, sizeof(curstate)) < 0) 
+     goto error;
+   if (bind(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen) < 0)
+     goto error;
+   else
+     svr->fd_handler = 
+       ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ | ECORE_FD_WRITE,
+                                _ecore_con_cl_udp_handler, svr, NULL, NULL);
+   if (!svr->fd_handler) goto error;
+   svr->ip = strdup(net_info->ip);
+
+   return;
+
+   error:
+   kill_server(svr);
+}
+
+static void
+_ecore_con_cb_tcp_connect(void *data, Ecore_Con_Netinfo *net_info)
+{
+   Ecore_Con_Server   *svr;
+   struct sockaddr_in  socket_addr;
+   int                 curstate = 0;
+   char                buf[64];
+
+   svr = data;
+
+   if (!net_info) goto error;
+   svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype, net_info->info.ai_protocol);
+   if (svr->fd < 0) goto error;
+   if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
+   if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
+   if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, &curstate, sizeof(curstate)) < 0) 
+     goto error;
+   if (connect(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen) < 0)
+     {
+       if (errno != EINPROGRESS)
+         goto error;
+       svr->connecting = 1;
+       svr->fd_handler =
+         ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ | ECORE_FD_WRITE,
+                                   _ecore_con_cl_handler, svr, NULL, NULL);
+     }
+   else
+     svr->fd_handler =
+     ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
+                              _ecore_con_cl_handler, svr, NULL, NULL);
+
+   if (!svr->fd_handler) goto error;
+   svr->ip = strdup(net_info->ip);
+
+#if USE_OPENSSL
+   if (svr->type & ECORE_CON_SSL)
+     {
+       if (!ssl_init_count)
+         {
+            SSL_library_init();
+            SSL_load_error_strings();
+         }
+       ssl_init_count++;
+
+       switch (svr->type & ECORE_CON_SSL)
+         {
+          case ECORE_CON_USE_SSL2:
+             if (!(svr->ssl_ctx = SSL_CTX_new(SSLv2_client_method())))
+               goto error;
+             break;
+          case ECORE_CON_USE_SSL3:
+             if (!(svr->ssl_ctx = SSL_CTX_new(SSLv3_client_method())))
+               goto error;
+             break;
+          case ECORE_CON_USE_TLS:
+             if (!(svr->ssl_ctx = SSL_CTX_new(TLSv1_client_method())))
+               goto error;
+             break;
+         }
+
+       if (!(svr->ssl = SSL_new(svr->ssl_ctx)))
+         goto error;
+
+       SSL_set_fd(svr->ssl, svr->fd);
+     }
+#endif
+
+   return;
+
+   error:
+   kill_server(svr);
+}
+
+static void
+_ecore_con_cb_udp_connect(void *data, Ecore_Con_Netinfo *net_info)
+{
+   Ecore_Con_Server   *svr;
+   struct sockaddr_in  socket_addr;
+   int                 curstate = 0;
+   char                buf[64];
+
+   svr = data;
+
+   if (!net_info) goto error;
+   svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype, net_info->info.ai_protocol);
+   if (svr->fd < 0) goto error;
+   if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
+   if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
+   if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, &curstate, sizeof(curstate)) < 0) 
+     goto error;
+   if (connect(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen) < 0)
+     goto error;
+   else
+     svr->fd_handler = 
+       ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ | ECORE_FD_WRITE,
+                                _ecore_con_cl_udp_handler, svr, NULL, NULL);
+   if (!svr->fd_handler) goto error;
+   svr->ip = strdup(net_info->ip);
+
+   return;
+
+   error:
+   kill_server(svr);
+}
+
 static Ecore_Con_State
 svr_try_connect_plain(Ecore_Con_Server *svr)
 {
diff --git a/src/lib/ecore_con/ecore_con_info.c b/src/lib/ecore_con/ecore_con_info.c
new file mode 100644 (file)
index 0000000..3da72b8
--- /dev/null
@@ -0,0 +1,295 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+/*
+ * getaddrinfo with callback
+ *
+ * man getaddrinfo
+ *
+ */
+#include "ecore_private.h"
+#include "Ecore.h"
+#include "ecore_con_private.h"
+
+#include <ctype.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <netdb.h>
+
+typedef struct _CB_Data CB_Data;
+
+typedef void (*CB_Func)(void *data, Ecore_Con_Netinfo *infos);
+
+struct _CB_Data
+{
+   Ecore_List2 __list_data;
+   CB_Func cb_done;
+   void *data;
+   Ecore_Fd_Handler *fdh;
+   pid_t pid;
+   Ecore_Event_Handler *handler;
+   int fd2;
+};
+
+
+static int _ecore_con_info_get(Ecore_Con_Server *svr, CB_Func done_cb, void *data);
+static void _ecore_con_info_readdata(CB_Data *cbdata);
+static void _ecore_con_info_slave_free(CB_Data *cbdata);
+static int _ecore_con_info_data_handler(void *data, Ecore_Fd_Handler *fd_handler);
+static int _ecore_con_info_exit_handler(void *data, int type __UNUSED__, void *event);
+
+static int info_init = 0;
+static Ecore_List2 *info_slaves = NULL;
+static struct addrinfo hints;
+
+int
+ecore_con_info_init(void)
+{
+   info_init++;
+   return info_init;
+}
+
+int
+ecore_con_info_shutdown(void)
+{
+   info_init--;
+   if (info_init == 0)
+     {
+       while (info_slaves) _ecore_con_info_slave_free((CB_Data *)info_slaves);
+     }
+   return info_init;
+}
+
+int
+ecore_con_info_tcp_connect(Ecore_Con_Server *svr,
+                          CB_Func done_cb,
+                          void *data)
+{
+   memset(&hints, 0, sizeof(struct addrinfo));
+   hints.ai_family = AF_UNSPEC;
+   hints.ai_socktype = SOCK_STREAM;
+   hints.ai_flags = AI_CANONNAME;
+   hints.ai_protocol = IPPROTO_TCP;
+   hints.ai_canonname = NULL;
+   hints.ai_next = NULL;
+   hints.ai_addr = NULL;
+
+   return _ecore_con_info_get(svr, done_cb, data);
+}
+
+int
+ecore_con_info_tcp_listen(Ecore_Con_Server *svr,
+                         CB_Func done_cb,
+                         void *data)
+{
+   memset(&hints, 0, sizeof(struct addrinfo));
+   hints.ai_family = AF_UNSPEC;
+   hints.ai_socktype = SOCK_STREAM;
+   hints.ai_flags = AI_PASSIVE;
+   hints.ai_protocol = IPPROTO_TCP;
+   hints.ai_canonname = NULL;
+   hints.ai_next = NULL;
+   hints.ai_addr = NULL;
+
+   return _ecore_con_info_get(svr, done_cb, data);
+}
+
+int
+ecore_con_info_udp_connect(Ecore_Con_Server *svr,
+                          CB_Func done_cb,
+                          void *data)
+{
+   memset(&hints, 0, sizeof(struct addrinfo));
+   hints.ai_family = AF_UNSPEC;
+   hints.ai_socktype = SOCK_DGRAM;
+   hints.ai_flags = AI_CANONNAME;
+   hints.ai_protocol = IPPROTO_UDP;
+   hints.ai_canonname = NULL;
+   hints.ai_next = NULL;
+   hints.ai_addr = NULL;
+
+   return _ecore_con_info_get(svr, done_cb, data);
+}
+
+int
+ecore_con_info_udp_listen(Ecore_Con_Server *svr,
+                         CB_Func done_cb,
+                         void *data)
+{
+   memset(&hints, 0, sizeof(struct addrinfo));
+   hints.ai_family = AF_UNSPEC;
+   hints.ai_socktype = SOCK_DGRAM;
+   hints.ai_flags = AI_PASSIVE;
+   hints.ai_protocol = IPPROTO_UDP;
+   hints.ai_canonname = NULL;
+   hints.ai_next = NULL;
+   hints.ai_addr = NULL;
+
+   return _ecore_con_info_get(svr, done_cb, data);
+}
+
+int
+ecore_con_pre_mcast_listen(Ecore_Con_Server *svr,
+                          CB_Func done_cb,
+                          void *data)
+{
+   memset(&hints, 0, sizeof(struct addrinfo));
+   hints.ai_family = AF_UNSPEC;
+   hints.ai_socktype = SOCK_DGRAM;
+   hints.ai_flags = 0;
+   hints.ai_protocol = IPPROTO_UDP;
+   hints.ai_canonname = NULL;
+   hints.ai_next = NULL;
+   hints.ai_addr = NULL;
+
+   return _ecore_con_info_get(svr, done_cb, data);
+}
+
+static int
+_ecore_con_info_get(Ecore_Con_Server *svr,
+                   CB_Func done_cb,
+                   void *data)
+{
+   CB_Data *cbdata;
+   int fd[2];
+
+   if (pipe(fd) < 0) return 0;
+   cbdata = calloc(1, sizeof(CB_Data));
+   if (!cbdata)
+     {
+       close(fd[0]);
+       close(fd[1]);
+       return 0;
+     }
+   cbdata->cb_done = done_cb;
+   cbdata->data = data;
+   cbdata->fd2 = fd[1];
+   if (!(cbdata->fdh = ecore_main_fd_handler_add(fd[0], ECORE_FD_READ,
+                                                _ecore_con_info_data_handler,
+                                                cbdata,
+                                                NULL, NULL)))
+     {
+       free(cbdata);
+       close(fd[0]);
+       close(fd[1]);
+       return 0;
+     }
+
+   if ((cbdata->pid = fork()) == 0)
+     {
+        Ecore_Con_Netinfo container;
+       struct addrinfo *result;
+       char service[NI_MAXSERV];
+       char hbuf[NI_MAXHOST];
+       char sbuf[NI_MAXSERV];
+
+       /* FIXME with EINA */
+       snprintf(service, NI_MAXSERV, "%i", svr->port);
+       /* CHILD */
+       if (!getaddrinfo(svr->name, service, &hints, &result) && result)
+         {
+           memcpy(&container.info, result, sizeof(struct addrinfo));
+           container.info.ai_canonname = NULL;
+           container.info.ai_next = NULL;
+           memcpy(&container.addr, result->ai_addr, sizeof(struct sockaddr));
+           if (!getnameinfo(&container.addr, container.info.ai_addrlen,
+                            hbuf, sizeof(hbuf), sbuf, sizeof(sbuf),
+                            NI_NUMERICHOST | NI_NUMERICSERV))
+             {
+               memcpy(container.ip, hbuf, sizeof(container.ip));
+               memcpy(container.service, sbuf, sizeof(container.service));
+             }
+           else
+             {
+               memset(container.ip, 0, sizeof(container.ip));
+               memset(container.service, 0, sizeof(container.service));
+             }
+           write(fd[1], &container, sizeof(container));
+         }
+       else
+         write(fd[1], "", 1);
+
+       close(fd[1]);
+# ifdef __USE_ISOC99
+       _Exit(0);
+# else
+       _exit(0);
+# endif
+     }
+   /* PARENT */
+   cbdata->handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL, _ecore_con_info_exit_handler, cbdata);
+   close(fd[1]);
+   if (!cbdata->handler)
+     {
+       ecore_main_fd_handler_del(cbdata->fdh);
+       free(cbdata);
+       close(fd[0]);
+       return 0;
+     }
+   info_slaves = _ecore_list2_append(info_slaves, cbdata);
+   return 1;
+}
+
+static void
+_ecore_con_info_readdata(CB_Data *cbdata)
+{
+   Ecore_Con_Netinfo container;
+   ssize_t size;
+
+   size = read(ecore_main_fd_handler_fd_get(cbdata->fdh), &container,
+              sizeof(Ecore_Con_Netinfo));
+   if (size == sizeof(Ecore_Con_Netinfo))
+     {
+        container.info.ai_addr = &container.addr;
+       cbdata->cb_done(cbdata->data, &container);
+     }
+   else
+     cbdata->cb_done(cbdata->data, NULL);
+   cbdata->cb_done = NULL;
+}
+
+static void
+_ecore_con_info_slave_free(CB_Data *cbdata)
+{
+   info_slaves = _ecore_list2_remove(info_slaves, cbdata);
+   close(ecore_main_fd_handler_fd_get(cbdata->fdh));
+   ecore_main_fd_handler_del(cbdata->fdh);
+   ecore_event_handler_del(cbdata->handler);
+   free(cbdata);
+}
+
+static int
+_ecore_con_info_data_handler(void *data, Ecore_Fd_Handler *fd_handler)
+{
+   CB_Data *cbdata;
+
+   cbdata = data;
+   if (cbdata->cb_done)
+     {
+       if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
+         _ecore_con_info_readdata(cbdata);
+       else
+         {
+            cbdata->cb_done(cbdata->data, NULL);
+            cbdata->cb_done = NULL;
+         }
+     }
+   _ecore_con_info_slave_free(cbdata);
+   return 0;
+}
+
+static int
+_ecore_con_info_exit_handler(void *data, int type __UNUSED__, void *event)
+{
+   CB_Data *cbdata;
+   Ecore_Exe_Event_Del *ev;
+
+   ev = event;
+   cbdata = data;
+   if (cbdata->pid != ev->pid) return 1;
+   return 0;
+   _ecore_con_info_slave_free(cbdata);
+   return 0;
+}
index c656097..ceff35b 100644 (file)
@@ -95,6 +95,14 @@ struct _Ecore_Con_Url
 };
 #endif
 
+struct _Ecore_Con_Netinfo
+{
+   struct addrinfo info;
+   struct sockaddr addr;
+   char                   ip[NI_MAXHOST];
+   char                   service[NI_MAXSERV];
+};
+
 /* from ecore_con_dns.c */
 int ecore_con_dns_init(void);
 int ecore_con_dns_shutdown(void);