forked from enlightenment/efl
Starting work for IPv6 support of ecore_con. Use getaddrinfo and getnameinfo instead of gethostbyname.
Patch from Arnaud de Turckheim. SVN revision: 36475
This commit is contained in:
parent
1cef991ffd
commit
554ad88eff
|
@ -69,10 +69,11 @@
|
|||
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,
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -28,6 +28,10 @@
|
|||
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue