From 9ffcb1b89fac9b6c493315fd4a25c36e917036cb Mon Sep 17 00:00:00 2001 From: cedric Date: Thu, 9 Oct 2008 12:30:19 +0000 Subject: [PATCH] Fix entrance and perhaps exquisite too. git-svn-id: http://svn.enlightenment.org/svn/e/trunk/ecore@36545 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- src/lib/ecore_con/Ecore_Con.h | 40 +- src/lib/ecore_con/Makefile.am | 2 + src/lib/ecore_con/ecore_con.c | 661 +++++++++++++++++++--------------- src/lib/ecore_con/ecore_con_info.c | 299 +++++++++++++++ src/lib/ecore_con/ecore_con_private.h | 16 + 5 files changed, 707 insertions(+), 311 deletions(-) create mode 100644 src/lib/ecore_con/ecore_con_info.c diff --git a/src/lib/ecore_con/Ecore_Con.h b/src/lib/ecore_con/Ecore_Con.h index a1ab4d4..d5e0f2c 100644 --- a/src/lib/ecore_con/Ecore_Con.h +++ b/src/lib/ecore_con/Ecore_Con.h @@ -44,15 +44,15 @@ * There are two main objects in the @c Ecore_Con library: the @c * Ecore_Con_Server and the @c Ecore_Con_Client. * - * The @c Ecore_Con_Server represents a server that can be connected to. - * It is used regardless of whether the program is acting as a server or + * The @c Ecore_Con_Server represents a server that can be connected to. + * It is used regardless of whether the program is acting as a server or * client itself. * * To create a listening server, call @c ecore_con_server_add(). * * To connect to a server, call @c ecore_con_server_connect(). Data can * then be sent to the server using the @c ecore_con_server_send(). - * + * * Whenever a client connection is made to an @c Ecore_Con_Server, a * @c ECORE_CON_CLIENT_ADD event is emitted. Any event callbacks that are * called receive a @c Ecore_Con_Client object, which represents a @@ -68,11 +68,14 @@ #ifdef __cplusplus 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_Info Ecore_Con_Info; + + typedef void (*Ecore_Con_Info_Cb)(void *data, Ecore_Con_Info *infos); + typedef enum _Ecore_Con_Type { ECORE_CON_LOCAL_USER, @@ -125,28 +128,28 @@ extern "C" { { Ecore_Con_Server *server; }; - + struct _Ecore_Con_Event_Client_Data { Ecore_Con_Client *client; void *data; int size; }; - + struct _Ecore_Con_Event_Server_Data { Ecore_Con_Server *server; void *data; int size; }; - + struct _Ecore_Con_Event_Url_Data { Ecore_Con_Url *url_con; int size; unsigned char data[1]; }; - + struct _Ecore_Con_Event_Url_Complete { Ecore_Con_Url *url_con; @@ -175,12 +178,12 @@ extern "C" { EAPI extern int ECORE_CON_EVENT_URL_DATA; EAPI extern int ECORE_CON_EVENT_URL_COMPLETE; EAPI extern int ECORE_CON_EVENT_URL_PROGRESS; - + EAPI int ecore_con_init(void); EAPI int ecore_con_shutdown(void); - + EAPI Ecore_Con_Server *ecore_con_server_add(Ecore_Con_Type type, const char *name, int port, const void *data); - + EAPI Ecore_Con_Server *ecore_con_server_connect(Ecore_Con_Type type, const char *name, int port, const void *data); EAPI void *ecore_con_server_del(Ecore_Con_Server *svr); EAPI void *ecore_con_server_data_get(Ecore_Con_Server *svr); @@ -190,7 +193,7 @@ extern "C" { EAPI void ecore_con_server_client_limit_set(Ecore_Con_Server *svr, int client_limit, char reject_excess_clients); EAPI char *ecore_con_server_ip_get(Ecore_Con_Server *svr); EAPI void ecore_con_server_flush(Ecore_Con_Server *svr); - + EAPI int ecore_con_client_send(Ecore_Con_Client *cl, const void *data, int size); EAPI Ecore_Con_Server *ecore_con_client_server_get(Ecore_Con_Client *cl); EAPI void *ecore_con_client_del(Ecore_Con_Client *cl); @@ -198,7 +201,7 @@ extern "C" { EAPI void *ecore_con_client_data_get(Ecore_Con_Client *cl); EAPI char *ecore_con_client_ip_get(Ecore_Con_Client *cl); EAPI void ecore_con_client_flush(Ecore_Con_Client *cl); - + EAPI int ecore_con_ssl_available_get(void); EAPI int ecore_con_url_init(void); @@ -217,8 +220,9 @@ extern "C" { EAPI int ecore_con_dns_lookup(const char *name, void (*done_cb)(void *data, struct hostent *hostent), void *data); + EAPI int ecore_con_info_get(Ecore_Con_Server *svr, Ecore_Con_Info_Cb done_cb, void *data, struct addrinfo *hints); #endif - + EAPI int ecore_con_url_ftp_upload(Ecore_Con_Url *url_con, char *filename, char *user, char *pass, char *upload_dir); EAPI void ecore_con_url_verbose_set(Ecore_Con_Url *url_con, int verbose); EAPI void ecore_con_url_ftp_use_epsv_set(Ecore_Con_Url *url_con, int use_epsv); diff --git a/src/lib/ecore_con/Makefile.am b/src/lib/ecore_con/Makefile.am index aa2e9b8..b434a88 100644 --- a/src/lib/ecore_con/Makefile.am +++ b/src/lib/ecore_con/Makefile.am @@ -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 @@ -33,5 +34,6 @@ endif EXTRA_DIST = \ ecore_con.c \ ecore_con_dns.c \ +ecore_con_info.c \ ecore_con_url.c \ ecore_con_private.h diff --git a/src/lib/ecore_con/ecore_con.c b/src/lib/ecore_con/ecore_con.c index 0589ab5..b0d1efe 100644 --- a/src/lib/ecore_con/ecore_con.c +++ b/src/lib/ecore_con/ecore_con.c @@ -26,17 +26,23 @@ # include #endif -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_Info *info); +static void _ecore_con_cb_udp_connect(void *data, Ecore_Con_Info *info); +static void _ecore_con_cb_tcp_listen(void *data, Ecore_Con_Info *info); +static void _ecore_con_cb_udp_listen(void *data, Ecore_Con_Info *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); static int _ecore_con_cl_handler(void *data, Ecore_Fd_Handler *fd_handler); static int _ecore_con_cl_udp_handler(void *data, Ecore_Fd_Handler *fd_handler); -static int _ecore_con_mcast_handler(void *data, Ecore_Fd_Handler *fd_handler); +static int _ecore_con_svr_udp_handler(void *data, Ecore_Fd_Handler *fd_handler); static int _ecore_con_svr_cl_handler(void *data, Ecore_Fd_Handler *fd_handler); + static void _ecore_con_server_flush(Ecore_Con_Server *svr); static void _ecore_con_client_flush(Ecore_Con_Client *cl); + static void _ecore_con_event_client_add_free(void *data, void *ev); static void _ecore_con_event_client_del_free(void *data, void *ev); static void _ecore_con_event_client_data_free(void *data, void *ev); @@ -53,8 +59,26 @@ EAPI int ECORE_CON_EVENT_SERVER_DATA = 0; static Ecore_List *servers = NULL; static int init_count = 0; + #if USE_OPENSSL static int ssl_init_count = 0; +static int _ecore_con_init_ssl(Ecore_Con_Server *svr); +static int _ecore_con_shutdown_ssl(Ecore_Con_Server *svr); +static int _ecore_con_free_ssl(Ecore_Con_Server *svr); + +# define INIT_SSL(svr) _ecore_con_init_ssl(svr) +# define SHUTDOWN_SSL(svr) _ecore_con_shutdown_ssl(svr) +# define FREE_SSL(svr) _ecore_con_free_ssl(svr) +# define UNSET_SSL(svr) \ + do { \ + svr->ssl = NULL; \ + svr->ssl_ctx = NULL; \ + } while (0) +#else +# define INIT_SSL(svr) 0 +# define SHUTDOWN_SSL(svr) 0 +# define FREE_SSL(svr) 0 +# define UNSET_SSL(svr) 0 #endif #define LENGTH_OF_SOCKADDR_UN(s) (strlen((s)->sun_path) + (size_t)(((struct sockaddr_un *)NULL)->sun_path)) @@ -88,6 +112,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 +135,7 @@ ecore_con_shutdown(void) ecore_list_destroy(servers); servers = NULL; + ecore_con_info_shutdown(); ecore_con_dns_shutdown(); ecore_shutdown(); @@ -157,10 +183,9 @@ ecore_con_server_add(Ecore_Con_Type compl_type, const char *name, int port, Ecore_Con_Type type; struct sockaddr_in socket_addr; struct sockaddr_un socket_unix; - struct ip_mreq mreq; struct linger lin; char buf[4096]; - const int on=1; + mode_t pmode; if (port < 0) return NULL; /* local user socket: FILE: ~/.ecore/[name]/[port] */ @@ -169,18 +194,27 @@ ecore_con_server_add(Ecore_Con_Type compl_type, const char *name, int port, svr = calloc(1, sizeof(Ecore_Con_Server)); if (!svr) return NULL; - type = compl_type; -#if USE_OPENSSL - /* unset the SSL flag for the following checks */ - type &= ECORE_CON_TYPE; -#endif + svr->name = strdup(name); + if (!svr->name) goto error; + svr->type = compl_type; + svr->port = port; + svr->data = (void *)data; + svr->created = 1; + svr->reject_excess_clients = 0; + svr->client_limit = -1; + svr->clients = ecore_list_new(); + svr->ppid = getpid(); + /* Set ssl and ssl_ctx fields to NULL */ + UNSET_SSL(svr); + + type = compl_type & ECORE_CON_TYPE; if ((type == ECORE_CON_LOCAL_USER) || (type == ECORE_CON_LOCAL_SYSTEM) || (type == ECORE_CON_LOCAL_ABSTRACT)) { const char *homedir; struct stat st; - mode_t pmode, mask; + mode_t mask; int socket_unix_len; if (!name) goto error; @@ -217,28 +251,12 @@ ecore_con_server_add(Ecore_Con_Type compl_type, const char *name, int port, pmode = umask(mask); start: svr->fd = socket(AF_UNIX, SOCK_STREAM, 0); - if (svr->fd < 0) - { - umask(pmode); - goto error; - } - if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) - { - umask(pmode); - goto error; - } - if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) - { - umask(pmode); - goto error; - } + if (svr->fd < 0) goto error_umask; + if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error_umask; + if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error_umask; lin.l_onoff = 1; lin.l_linger = 0; - if (setsockopt(svr->fd, SOL_SOCKET, SO_LINGER, &lin, sizeof(struct linger)) < 0) - { - umask(pmode); - goto error; - } + if (setsockopt(svr->fd, SOL_SOCKET, SO_LINGER, &lin, sizeof(struct linger)) < 0) goto error_umask; socket_unix.sun_family = AF_UNIX; if (type == ECORE_CON_LOCAL_ABSTRACT) { @@ -250,8 +268,7 @@ ecore_con_server_add(Ecore_Con_Type compl_type, const char *name, int port, socket_unix_len = LENGTH_OF_ABSTRACT_SOCKADDR_UN(&socket_unix, name); #else fprintf(stderr, "Your system does not support abstract sockets!\n"); - umask(pmode); - goto error; + goto error_umask; #endif } else @@ -261,135 +278,43 @@ ecore_con_server_add(Ecore_Con_Type compl_type, const char *name, int port, } if (bind(svr->fd, (struct sockaddr *)&socket_unix, socket_unix_len) < 0) { - if (connect(svr->fd, (struct sockaddr *)&socket_unix, - socket_unix_len) < 0) - { - if ((type == ECORE_CON_LOCAL_USER) || - (type == ECORE_CON_LOCAL_SYSTEM)) - { - if (unlink(buf) < 0) - { - umask(pmode); - goto error; - } - else - goto start; - } - else - { - umask(pmode); - goto error; - } - } - else - { - umask(pmode); - goto error; - } - } - if (listen(svr->fd, 4096) < 0) - { - umask(pmode); - goto error; + if ((type == ECORE_CON_LOCAL_USER) || (type == ECORE_CON_LOCAL_SYSTEM) && + (connect(svr->fd, (struct sockaddr *)&socket_unix, socket_unix_len) < 0) && + (unlink(buf) >= 0)) + goto start; + else + goto error_umask; } + if (listen(svr->fd, 4096) < 0) goto error_umask; svr->path = strdup(buf); - if (!svr->path) - { - umask(pmode); - goto error; - } - svr->fd_handler = + if (!svr->path) goto error_umask; + svr->fd_handler = ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ, _ecore_con_svr_handler, svr, NULL, NULL); umask(pmode); if (!svr->fd_handler) goto error; + + INIT_SSL(svr); } - else if (type == ECORE_CON_REMOTE_TCP) - { - svr->fd = socket(AF_INET, SOCK_STREAM, 0); - 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, (struct sockaddr *)&socket_addr, sizeof(struct sockaddr_in)) < 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; - } - else if (type == ECORE_CON_REMOTE_MCAST) + + if (type == ECORE_CON_REMOTE_TCP) { - svr->fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); - if(svr->fd < 0) goto error; - mreq.imr_multiaddr.s_addr = inet_addr(name); - mreq.imr_interface.s_addr = htonl(INADDR_ANY); - if (setsockopt(svr->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,sizeof(mreq)) != 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; - socket_addr.sin_family = AF_INET; - socket_addr.sin_port = htons(port); - socket_addr.sin_addr.s_addr = inet_addr(name); - if (bind(svr->fd, (struct sockaddr *)&socket_addr,sizeof(struct sockaddr_in)) < 0) goto error; - svr->fd_handler = - ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ, - _ecore_con_mcast_handler, svr, NULL, NULL); - if (!svr->fd_handler) goto error; + /* TCP */ + if (!ecore_con_info_tcp_listen(svr, _ecore_con_cb_tcp_listen, svr)) goto error; } - -#if USE_OPENSSL - if (compl_type & ECORE_CON_SSL) + else if (type == ECORE_CON_REMOTE_MCAST || type == ECORE_CON_REMOTE_UDP) { - if (!ssl_init_count) - { - SSL_library_init(); - SSL_load_error_strings(); - } - ssl_init_count++; - - switch (compl_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); + /* UDP and MCAST */ + if (!ecore_con_info_udp_listen(svr, _ecore_con_cb_udp_listen, svr)) goto error; } -#endif - svr->name = strdup(name); - if (!svr->name) goto error; - svr->type = type; - svr->port = port; - svr->data = (void *)data; - svr->created = 1; - svr->reject_excess_clients = 0; - svr->client_limit = -1; - svr->clients = ecore_list_new(); - svr->ppid = getpid(); ecore_list_append(servers, svr); ECORE_MAGIC_SET(svr, ECORE_MAGIC_CON_SERVER); + return svr; + error_umask: + umask(pmode); error: if (svr->name) free(svr->name); if (svr->path) free(svr->path); @@ -397,10 +322,7 @@ ecore_con_server_add(Ecore_Con_Type compl_type, const char *name, int port, if (svr->fd_handler) ecore_main_fd_handler_del(svr->fd_handler); if (svr->write_buf) free(svr->write_buf); if (svr->ip) free(svr->ip); -#if USE_OPENSSL - if (svr->ssl) SSL_free(svr->ssl); - if (svr->ssl_ctx) SSL_CTX_free(svr->ssl_ctx); -#endif + FREE_SSL(svr); free(svr); return NULL; } @@ -449,11 +371,19 @@ ecore_con_server_connect(Ecore_Con_Type compl_type, const char *name, int port, svr = calloc(1, sizeof(Ecore_Con_Server)); if (!svr) return NULL; - type = compl_type; -#if USE_OPENSSL - /* unset the SSL flag for the following checks */ - type &= ECORE_CON_TYPE; -#endif + svr->name = strdup(name); + if (!svr->name) goto error; + svr->type = compl_type; + svr->port = port; + svr->data = (void *)data; + svr->created = 0; + svr->reject_excess_clients = 0; + svr->client_limit = -1; + svr->clients = ecore_list_new(); + UNSET_SSL(svr); + + type = compl_type & ECORE_CON_TYPE; + if ((type == ECORE_CON_REMOTE_TCP || type == ECORE_CON_REMOTE_UDP) && (port < 0)) return NULL; if ((type == ECORE_CON_LOCAL_USER) || (type == ECORE_CON_LOCAL_SYSTEM) || @@ -514,10 +444,14 @@ ecore_con_server_connect(Ecore_Con_Type compl_type, const char *name, int port, socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix); } - if (connect(svr->fd, (struct sockaddr *)&socket_unix, socket_unix_len) < 0) goto error; + if (connect(svr->fd, (struct sockaddr *)&socket_unix, socket_unix_len) < 0) + { + perror("connect()"); + goto error; + } svr->path = strdup(buf); if (!svr->path) goto error; - svr->fd_handler = + 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; @@ -538,29 +472,20 @@ ecore_con_server_connect(Ecore_Con_Type compl_type, const char *name, int port, } } - svr->name = strdup(name); - if (!svr->name) goto error; - svr->type = compl_type; - svr->port = port; - svr->data = (void *)data; - svr->created = 0; - svr->reject_excess_clients = 0; - svr->client_limit = -1; - svr->clients = ecore_list_new(); - ecore_list_append(servers, svr); - ECORE_MAGIC_SET(svr, ECORE_MAGIC_CON_SERVER); - if (type == ECORE_CON_REMOTE_TCP) { - if (!ecore_con_dns_lookup(svr->name, _ecore_con_cb_dns_lookup, svr)) - goto error; + /* TCP */ + 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; + /* UDP and MCAST */ + if (!ecore_con_info_udp_connect(svr, _ecore_con_cb_udp_connect, svr)) goto error; } + ecore_list_append(servers, svr); + ECORE_MAGIC_SET(svr, ECORE_MAGIC_CON_SERVER); + return svr; error: @@ -568,10 +493,7 @@ ecore_con_server_connect(Ecore_Con_Type compl_type, const char *name, int port, if (svr->path) free(svr->path); if (svr->fd >= 0) close(svr->fd); if (svr->fd_handler) ecore_main_fd_handler_del(svr->fd_handler); -#if USE_OPENSSL - if (svr->ssl) SSL_free(svr->ssl); - if (svr->ssl_ctx) SSL_CTX_free(svr->ssl_ctx); -#endif + FREE_SSL(svr); free(svr); return NULL; } @@ -806,15 +728,20 @@ ecore_con_client_send(Ecore_Con_Client *cl, const void *data, int size) if (size < 1) return 0; if (cl->fd_handler) ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE); - if (cl->buf) + + if(cl->server && cl->server->type == ECORE_CON_REMOTE_UDP) { - unsigned char *newbuf; + sendto(cl->server->fd, data, size, 0, (struct sockaddr *) cl->data, sizeof(struct sockaddr_in)); + } + else if (cl->buf) + { + unsigned char *newbuf; - newbuf = realloc(cl->buf, cl->buf_size + size); - if (newbuf) cl->buf = newbuf; - else return 0; - memcpy(cl->buf + cl->buf_size, data, size); - cl->buf_size += size; + newbuf = realloc(cl->buf, cl->buf_size + size); + if (newbuf) cl->buf = newbuf; + else return 0; + memcpy(cl->buf + cl->buf_size, data, size); + cl->buf_size += size; } else { @@ -853,14 +780,20 @@ ecore_con_client_server_get(Ecore_Con_Client *cl) EAPI void * ecore_con_client_del(Ecore_Con_Client *cl) { - void *data; + void *data = NULL; if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) { ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_del"); return NULL; } - data = cl->data; + + if(cl->data && cl->server && (cl->server->type == ECORE_CON_REMOTE_UDP || + cl->server->type == ECORE_CON_REMOTE_MCAST)) + free(cl->data); + else + data = cl->data; + cl->data = NULL; cl->delete_me = 1; if (cl->event_count > 0) @@ -991,17 +924,11 @@ _ecore_con_server_free(Ecore_Con_Server *svr) while (!ecore_list_empty_is(svr->clients)) _ecore_con_client_free(ecore_list_first_remove(svr->clients)); ecore_list_destroy(svr->clients); - if ((svr->created) && (svr->path) && (svr->ppid == getpid())) + if ((svr->created) && (svr->path) && (svr->ppid == getpid())) unlink(svr->path); if (svr->fd >= 0) close(svr->fd); -#if USE_OPENSSL - if (svr->ssl) - { - SSL_shutdown(svr->ssl); - SSL_free(svr->ssl); - } - if (svr->ssl_ctx) SSL_CTX_free(svr->ssl_ctx); -#endif + SHUTDOWN_SSL(svr); + FREE_SSL(svr); if (svr->name) free(svr->name); if (svr->path) free(svr->path); if (svr->ip) free(svr->ip); @@ -1076,7 +1003,7 @@ _ecore_con_svr_handler(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__) fcntl(new_fd, F_SETFD, FD_CLOEXEC); cl->fd = new_fd; cl->server = svr; - cl->fd_handler = + cl->fd_handler = ecore_main_fd_handler_add(cl->fd, ECORE_FD_READ, _ecore_con_svr_cl_handler, cl, NULL, NULL); ECORE_MAGIC_SET(cl, ECORE_MAGIC_CON_CLIENT); @@ -1165,132 +1092,170 @@ kill_server(Ecore_Con_Server *svr) } static void -_ecore_con_cb_dns_lookup(void *data, struct hostent *he) +_ecore_con_cb_tcp_listen(void *data, Ecore_Con_Info *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; + 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 (INIT_SSL(svr)) + goto error; + + return; + + error: + FREE_SSL(svr); + kill_server(svr); +} + +static void +_ecore_con_cb_udp_listen(void *data, Ecore_Con_Info *net_info) +{ + Ecore_Con_Server *svr; + Ecore_Con_Type type; + struct ip_mreq mreq; + struct ipv6_mreq mreq6; + const int on = 1; + + svr = data; + type = svr->type; + type &= ECORE_CON_TYPE; + + 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 (type == ECORE_CON_REMOTE_MCAST) + { + 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; + svr->ip = strdup(net_info->ip); + + if (INIT_SSL(svr)) + goto error; + + return; + + error: + FREE_SSL(svr); + kill_server(svr); +} + +static void +_ecore_con_cb_tcp_connect(void *data, Ecore_Con_Info *net_info) { Ecore_Con_Server *svr; struct sockaddr_in socket_addr; int curstate = 0; char buf[64]; - uint32_t ip; svr = data; - if (!he) goto error; - svr->fd = socket(AF_INET, SOCK_STREAM, 0); + 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) + if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, &curstate, sizeof(curstate)) < 0) goto error; - socket_addr.sin_family = AF_INET; - socket_addr.sin_port = htons(svr->port); - memcpy((struct in_addr *)&socket_addr.sin_addr, - he->h_addr, sizeof(struct in_addr)); - if (connect(svr->fd, (struct sockaddr *)&socket_addr, sizeof(struct sockaddr_in)) < 0) + 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 = + 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 = + 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; - ip = socket_addr.sin_addr.s_addr; - snprintf(buf, sizeof(buf), - "%i.%i.%i.%i", - (ip ) & 0xff, - (ip >> 8 ) & 0xff, - (ip >> 16) & 0xff, - (ip >> 24) & 0xff); - svr->ip = strdup(buf); - -#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; - } + svr->ip = strdup(net_info->ip); - if (!(svr->ssl = SSL_new(svr->ssl_ctx))) - goto error; - - SSL_set_fd(svr->ssl, svr->fd); - } -#endif + if (INIT_SSL(svr)) + goto error; return; error: + FREE_SSL(svr); kill_server(svr); } static void -_ecore_con_cb_udp_dns_lookup(void *data, struct hostent *he) +_ecore_con_cb_udp_connect(void *data, Ecore_Con_Info *net_info) { Ecore_Con_Server *svr; struct sockaddr_in socket_addr; int curstate = 0; char buf[64]; - uint32_t ip; svr = data; - if (!he) goto error; - svr->fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); + 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) + if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, &curstate, sizeof(curstate)) < 0) goto error; - socket_addr.sin_family = AF_INET; - socket_addr.sin_port = htons(svr->port); - memcpy((struct in_addr *)&socket_addr.sin_addr, - he->h_addr, sizeof(struct in_addr)); - if (connect(svr->fd, (struct sockaddr *)&socket_addr, sizeof(struct sockaddr_in)) < 0) + if (connect(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen) < 0) goto error; else - svr->fd_handler = + 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; - ip = socket_addr.sin_addr.s_addr; - snprintf(buf, sizeof(buf), - "%i.%i.%i.%i", - (ip ) & 0xff, - (ip >> 8 ) & 0xff, - (ip >> 16) & 0xff, - (ip >> 24) & 0xff); - svr->ip = strdup(buf); + svr->ip = strdup(net_info->ip); + + if (INIT_SSL(svr)) + goto error; return; error: + FREE_SSL(svr); kill_server(svr); } @@ -1504,7 +1469,7 @@ _ecore_con_cl_udp_handler(void *data, Ecore_Fd_Handler *fd_handler) { unsigned char buf[65536]; int num = 0; - + errno = 0; num = read(svr->fd, buf, 65536); if (num > 0) @@ -1535,41 +1500,78 @@ _ecore_con_cl_udp_handler(void *data, Ecore_Fd_Handler *fd_handler) } else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE)) _ecore_con_server_flush(svr); - + return 1; } static int -_ecore_con_mcast_handler(void *data, Ecore_Fd_Handler *fd_handler) +_ecore_con_svr_udp_handler(void *data, Ecore_Fd_Handler *fd_handler) { - Ecore_Con_Client *cl; + Ecore_Con_Server *svr; + Ecore_Con_Client *cl; - cl = data; - if (cl->dead) return 1; - if (cl->delete_me) return 1; + svr = data; + if (svr->dead) return 1; + if (svr->delete_me) return 1; if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) { - unsigned char buf[65536]; - int num; + unsigned char buf[READBUFSIZ]; + struct sockaddr_in client_addr; + int num, client_addr_len = sizeof(client_addr); errno = 0; - num = read(cl->fd, buf, 65536); + num = recvfrom(svr->fd, buf, sizeof(buf), MSG_DONTWAIT, (struct sockaddr*) &client_addr, &client_addr_len); + if (num > 0) { - if (!cl->delete_me) + if (!svr->delete_me) { Ecore_Con_Event_Client_Data *e; unsigned char *inbuf; + uint32_t ip; + char ipbuf[64]; + + /* Create a new client for use in the client data event */ + cl = calloc(1, sizeof(Ecore_Con_Client)); + if(cl == NULL) + return 1; + cl->buf = NULL; + cl->fd = 0; + cl->fd_handler = NULL; + cl->server = svr; + cl->data = calloc(1, sizeof(client_addr)); + if(cl->data == NULL) + { + free(cl); + return 1; + } + memcpy(cl->data, &client_addr, sizeof(client_addr)); + ECORE_MAGIC_SET(cl, ECORE_MAGIC_CON_CLIENT); + ecore_list_append(svr->clients, cl); + + ip = client_addr.sin_addr.s_addr; + snprintf(ipbuf, sizeof(ipbuf), + "%i.%i.%i.%i", + (ip ) & 0xff, + (ip >> 8 ) & 0xff, + (ip >> 16) & 0xff, + (ip >> 24) & 0xff); + cl->ip = strdup(ipbuf); inbuf = malloc(num); if(inbuf == NULL) - return 1; + { + free(cl->data); + free(cl); + return 1; + } + memcpy(inbuf, buf, num); - + e = calloc(1, sizeof(Ecore_Con_Event_Client_Data)); if (e) { - cl->event_count++; + svr->event_count++; e->client = cl; e->data = inbuf; e->size = num; @@ -1577,30 +1579,44 @@ _ecore_con_mcast_handler(void *data, Ecore_Fd_Handler *fd_handler) _ecore_con_event_client_data_free, NULL); } + + if(!cl->delete_me) + { + Ecore_Con_Event_Client_Add *add; + + add = calloc(1, sizeof(Ecore_Con_Event_Client_Add)); + if(add) + { + /*cl->event_count++;*/ + add->client = cl; + ecore_event_add(ECORE_CON_EVENT_CLIENT_ADD, add, + _ecore_con_event_client_add_free, NULL); + } + } } if ((errno == EIO) || (errno == EBADF) || (errno == EPIPE) || (errno == EINVAL) || (errno == ENOSPC) || (num == 0)/* is num == 0 right? */) { - if (!cl->delete_me) + if (!svr->delete_me) { /* we lost our client! */ Ecore_Con_Event_Client_Del *e; - + e = calloc(1, sizeof(Ecore_Con_Event_Client_Del)); if (e) { - cl->event_count++; + svr->event_count++; e->client = cl; ecore_event_add(ECORE_CON_EVENT_CLIENT_DEL, e, _ecore_con_event_client_del_free, NULL); } } - cl->dead = 1; - if (cl->fd_handler) - ecore_main_fd_handler_del(cl->fd_handler); - cl->fd_handler = NULL; + svr->dead = 1; + if (svr->fd_handler) + ecore_main_fd_handler_del(svr->fd_handler); + svr->fd_handler = NULL; } } } @@ -1700,9 +1716,9 @@ _ecore_con_server_flush(Ecore_Con_Server *svr) if (!svr->write_buf) return; /* check whether we need to write anything at all. - * we must not write zero bytes with SSL_write() since it - * causes undefined behaviour - */ + * we must not write zero bytes with SSL_write() since it + * causes undefined behaviour + */ if (svr->write_buf_size == svr->write_buf_offset) return; @@ -1842,7 +1858,9 @@ _ecore_con_event_client_data_free(void *data __UNUSED__, void *ev) e = ev; e->client->event_count--; if (e->data) free(e->data); - if ((e->client->event_count == 0) && (e->client->delete_me)) + if ((e->client->event_count == 0) && (e->client->delete_me) || + (e->client->server && (e->client->server->type == ECORE_CON_REMOTE_UDP || + e->client->server->type == ECORE_CON_REMOTE_MCAST))) ecore_con_client_del(e->client); free(e); } @@ -1883,3 +1901,60 @@ _ecore_con_event_server_data_free(void *data __UNUSED__, void *ev) ecore_con_server_del(e->server); free(e); } + +#if USE_OPENSSL + +static int +_ecore_con_init_ssl(Ecore_Con_Server *svr) +{ + 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()))) + return 1; + break; + case ECORE_CON_USE_SSL3: + if (!(svr->ssl_ctx = SSL_CTX_new(SSLv3_client_method()))) + return 1; + break; + case ECORE_CON_USE_TLS: + if (!(svr->ssl_ctx = SSL_CTX_new(TLSv1_client_method()))) + return 1; + break; + } + + if (!(svr->ssl = SSL_new(svr->ssl_ctx))) + return 1; + + SSL_set_fd(svr->ssl, svr->fd); + } + return 0; +} + +static int +_ecore_con_shutdown_ssl(Ecore_Con_Server *svr) +{ + if (svr->ssl) SSL_shutdown(svr->ssl); + return 0; +} + +static int +_ecore_con_free_ssl(Ecore_Con_Server *svr) +{ + if (svr->ssl) SSL_free(svr->ssl); + if (svr->ssl_ctx) SSL_CTX_free(svr->ssl_ctx); + UNSET_SSL(svr); + + return 0; +} + +#endif diff --git a/src/lib/ecore_con/ecore_con_info.c b/src/lib/ecore_con/ecore_con_info.c new file mode 100644 index 0000000..c47711a --- /dev/null +++ b/src/lib/ecore_con/ecore_con_info.c @@ -0,0 +1,299 @@ +/* + * 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 +#include +#include +#include +#include +#include + +typedef struct _CB_Data CB_Data; + +struct _CB_Data +{ + Ecore_List2 __list_data; + Ecore_Con_Info_Cb cb_done; + void *data; + Ecore_Fd_Handler *fdh; + pid_t pid; + Ecore_Event_Handler *handler; + int fd2; +}; + + +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; + +EAPI int +ecore_con_info_init(void) +{ + info_init++; + return info_init; +} + +EAPI 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, + Ecore_Con_Info_Cb done_cb, + void *data) +{ + struct addrinfo hints; + + 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, &hints); +} + +int +ecore_con_info_tcp_listen(Ecore_Con_Server *svr, + Ecore_Con_Info_Cb done_cb, + void *data) +{ + struct addrinfo hints; + + 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, &hints); +} + +int +ecore_con_info_udp_connect(Ecore_Con_Server *svr, + Ecore_Con_Info_Cb done_cb, + void *data) +{ + struct addrinfo hints; + + 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, &hints); +} + +int +ecore_con_info_udp_listen(Ecore_Con_Server *svr, + Ecore_Con_Info_Cb done_cb, + void *data) +{ + struct addrinfo hints; + + 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, &hints); +} + +int +ecore_con_info_mcast_listen(Ecore_Con_Server *svr, + Ecore_Con_Info_Cb done_cb, + void *data) +{ + struct addrinfo hints; + + 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, &hints); +} + +EAPI int +ecore_con_info_get(Ecore_Con_Server *svr, + Ecore_Con_Info_Cb done_cb, + void *data, + struct addrinfo *hints) +{ + 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_Info 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)); + memset(container.ip, 0, sizeof(container.ip)); + memset(container.service, 0, sizeof(container.service)); + 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)); + } + write(fd[1], &container, sizeof(Ecore_Con_Info)); + } + 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_Info container; + ssize_t size; + + size = read(ecore_main_fd_handler_fd_get(cbdata->fdh), &container, + sizeof(Ecore_Con_Info)); + if (size == sizeof(Ecore_Con_Info)) + { + 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; +} diff --git a/src/lib/ecore_con/ecore_con_private.h b/src/lib/ecore_con/ecore_con_private.h index c656097..2ea0d33 100644 --- a/src/lib/ecore_con/ecore_con_private.h +++ b/src/lib/ecore_con/ecore_con_private.h @@ -95,7 +95,23 @@ struct _Ecore_Con_Url }; #endif +struct _Ecore_Con_Info +{ + 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); +/* from ecore_con_info.c */ +int ecore_con_info_init(void); +int ecore_con_info_shutdown(void); +int ecore_con_info_tcp_connect(Ecore_Con_Server *svr, Ecore_Con_Info_Cb done_cb, void *data); +int ecore_con_info_tcp_listen(Ecore_Con_Server *svr, Ecore_Con_Info_Cb done_cb, void *data); +int ecore_con_info_udp_connect(Ecore_Con_Server *svr, Ecore_Con_Info_Cb done_cb, void *data); +int ecore_con_info_mcast_listen(Ecore_Con_Server *svr, Ecore_Con_Info_Cb done_cb, void *data); + #endif -- 2.7.4