forked from enlightenment/efl
Fix entrance and perhaps exquisite too.
SVN revision: 36545
This commit is contained in:
parent
3a2ab6069d
commit
632615fd1f
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -26,17 +26,23 @@
|
|||
# include <winsock2.h>
|
||||
#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)
|
||||
|
||||
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;
|
||||
/* TCP */
|
||||
if (!ecore_con_info_tcp_listen(svr, _ecore_con_cb_tcp_listen, svr)) goto error;
|
||||
}
|
||||
else if (type == ECORE_CON_REMOTE_MCAST)
|
||||
else if (type == ECORE_CON_REMOTE_MCAST || type == ECORE_CON_REMOTE_UDP)
|
||||
{
|
||||
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;
|
||||
/* UDP and MCAST */
|
||||
if (!ecore_con_info_udp_listen(svr, _ecore_con_cb_udp_listen, svr)) goto error;
|
||||
}
|
||||
|
||||
#if USE_OPENSSL
|
||||
if (compl_type & ECORE_CON_SSL)
|
||||
{
|
||||
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);
|
||||
}
|
||||
#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)
|
||||
{
|
||||
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;
|
||||
if(cl->server && cl->server->type == ECORE_CON_REMOTE_UDP)
|
||||
{
|
||||
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;
|
||||
}
|
||||
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 sockaddr_in socket_addr;
|
||||
int curstate = 0;
|
||||
char buf[64];
|
||||
uint32_t ip;
|
||||
Ecore_Con_Server *svr;
|
||||
struct linger lin;
|
||||
|
||||
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)
|
||||
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 (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 =
|
||||
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_cl_handler, svr, NULL, NULL);
|
||||
|
||||
_ecore_con_svr_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;
|
||||
}
|
||||
|
||||
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_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(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)
|
||||
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 (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_FD_WRITE,
|
||||
_ecore_con_cl_udp_handler, svr, NULL, NULL);
|
||||
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);
|
||||
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_udp_connect(void *data, Ecore_Con_Info *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);
|
||||
|
||||
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
|
||||
|
|
|
@ -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 <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;
|
||||
|
||||
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;
|
||||
}
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue