2004-04-25 08:42:57 -07:00
|
|
|
/*
|
2004-10-19 09:50:27 -07:00
|
|
|
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
|
2004-04-25 08:42:57 -07:00
|
|
|
*/
|
|
|
|
|
2009-01-31 10:33:39 -08:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include <config.h>
|
|
|
|
#endif
|
|
|
|
|
2010-01-04 15:43:16 -08:00
|
|
|
#include <stdio.h>
|
2010-01-16 05:44:25 -08:00
|
|
|
#include <string.h>
|
2009-11-20 02:58:19 -08:00
|
|
|
#include <sys/types.h>
|
2003-09-23 01:09:32 -07:00
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <errno.h>
|
2009-01-31 10:33:39 -08:00
|
|
|
#include <unistd.h>
|
|
|
|
#include <fcntl.h>
|
2006-03-13 00:50:26 -08:00
|
|
|
|
2010-02-20 11:12:52 -08:00
|
|
|
#ifdef HAVE_ARPA_INET_H
|
2010-02-20 10:01:50 -08:00
|
|
|
# include <arpa/inet.h>
|
2010-02-20 11:12:52 -08:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_NETINET_TCP_H
|
2010-02-20 10:01:50 -08:00
|
|
|
# include <netinet/tcp.h>
|
|
|
|
#endif
|
2006-01-06 09:58:12 -08:00
|
|
|
|
|
|
|
#ifdef HAVE_NETINET_IN_H
|
2008-01-25 21:40:53 -08:00
|
|
|
# include <netinet/in.h>
|
|
|
|
#endif
|
2006-01-06 09:58:12 -08:00
|
|
|
|
2010-02-20 11:12:52 -08:00
|
|
|
#ifdef HAVE_SYS_SOCKET_H
|
|
|
|
# include <sys/socket.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_SYS_UN_H
|
|
|
|
# include <sys/un.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_WS2TCPIP_H
|
|
|
|
# include <ws2tcpip.h>
|
|
|
|
#endif
|
|
|
|
|
2010-02-20 10:01:50 -08:00
|
|
|
#ifdef HAVE_EVIL
|
|
|
|
# include <Evil.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "Ecore.h"
|
|
|
|
#include "ecore_private.h"
|
|
|
|
#include "Ecore_Con.h"
|
|
|
|
#include "ecore_con_private.h"
|
|
|
|
|
2008-10-09 05:30:19 -07:00
|
|
|
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);
|
|
|
|
|
2003-09-23 01:09:32 -07:00
|
|
|
static void _ecore_con_server_free(Ecore_Con_Server *svr);
|
|
|
|
static void _ecore_con_client_free(Ecore_Con_Client *cl);
|
2008-10-09 05:30:19 -07:00
|
|
|
|
2003-09-23 01:09:32 -07:00
|
|
|
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);
|
2008-09-25 03:14:31 -07:00
|
|
|
static int _ecore_con_cl_udp_handler(void *data, Ecore_Fd_Handler *fd_handler);
|
2008-10-09 05:30:19 -07:00
|
|
|
static int _ecore_con_svr_udp_handler(void *data, Ecore_Fd_Handler *fd_handler);
|
2003-09-23 01:09:32 -07:00
|
|
|
static int _ecore_con_svr_cl_handler(void *data, Ecore_Fd_Handler *fd_handler);
|
2008-10-09 05:30:19 -07:00
|
|
|
|
2003-09-23 01:09:32 -07:00
|
|
|
static void _ecore_con_server_flush(Ecore_Con_Server *svr);
|
|
|
|
static void _ecore_con_client_flush(Ecore_Con_Client *cl);
|
2008-10-09 05:30:19 -07:00
|
|
|
|
2006-03-19 21:53:12 -08:00
|
|
|
static void _ecore_con_event_client_add_free(void *data, void *ev);
|
|
|
|
static void _ecore_con_event_client_del_free(void *data, void *ev);
|
2003-09-23 01:09:32 -07:00
|
|
|
static void _ecore_con_event_client_data_free(void *data, void *ev);
|
2006-03-19 21:53:12 -08:00
|
|
|
static void _ecore_con_event_server_add_free(void *data, void *ev);
|
|
|
|
static void _ecore_con_event_server_del_free(void *data, void *ev);
|
2003-09-23 01:09:32 -07:00
|
|
|
static void _ecore_con_event_server_data_free(void *data, void *ev);
|
|
|
|
|
2006-01-06 09:58:12 -08:00
|
|
|
EAPI int ECORE_CON_EVENT_CLIENT_ADD = 0;
|
|
|
|
EAPI int ECORE_CON_EVENT_CLIENT_DEL = 0;
|
|
|
|
EAPI int ECORE_CON_EVENT_SERVER_ADD = 0;
|
|
|
|
EAPI int ECORE_CON_EVENT_SERVER_DEL = 0;
|
|
|
|
EAPI int ECORE_CON_EVENT_CLIENT_DATA = 0;
|
|
|
|
EAPI int ECORE_CON_EVENT_SERVER_DATA = 0;
|
2003-09-23 01:09:32 -07:00
|
|
|
|
* estickies,
* etk,
* PROTO/exalt,
* E-MODULES-EXTRA/diskio,
* E-MODULES-EXTRA/drawer,
* E-MODULES-EXTRA/penguins,
* E-MODULES-EXTRA/slideshow,
* E-MODULES-EXTRA/mail,
* E-MODULES-EXTRA/forecasts,
* E-MODULES-EXTRA/iiirk,
* E-MODULES-EXTRA/places,
* e,
* ewl,
* ecore,
* elitaire,
* entrance,
* e_dbus,
* efreet: Here we go, move from Ecore_List to Eina_List.
NOTE: This patch is huge, I did test it a lot, and I hope nothing is
broken. But if you think something change after this commit, please
contact me ASAP.
SVN revision: 39200
2009-02-25 03:03:47 -08:00
|
|
|
static Eina_List *servers = NULL;
|
2009-10-09 22:28:43 -07:00
|
|
|
static int _ecore_con_init_count = 0;
|
2009-12-21 09:32:19 -08:00
|
|
|
int _ecore_con_log_dom = -1;
|
2003-09-23 01:09:32 -07:00
|
|
|
|
2004-09-22 01:17:15 -07:00
|
|
|
/**
|
|
|
|
* @defgroup Ecore_Con_Lib_Group Ecore Connection Library Functions
|
|
|
|
*
|
|
|
|
* Utility functions that set up and shut down the Ecore Connection
|
|
|
|
* library.
|
|
|
|
*/
|
|
|
|
|
2003-09-23 01:09:32 -07:00
|
|
|
/**
|
2004-07-15 06:43:15 -07:00
|
|
|
* Initialises the Ecore_Con library.
|
2004-09-22 01:17:15 -07:00
|
|
|
* @return Number of times the library has been initialised without being
|
|
|
|
* shut down.
|
|
|
|
* @ingroup Ecore_Con_Lib_Group
|
2003-09-23 01:09:32 -07:00
|
|
|
*/
|
2006-01-06 09:58:12 -08:00
|
|
|
EAPI int
|
2003-09-23 01:09:32 -07:00
|
|
|
ecore_con_init(void)
|
|
|
|
{
|
2009-10-09 22:28:43 -07:00
|
|
|
if (++_ecore_con_init_count != 1)
|
|
|
|
return _ecore_con_init_count;
|
|
|
|
|
2010-01-14 23:44:27 -08:00
|
|
|
#ifdef HAVE_EVIL
|
|
|
|
if (!evil_init())
|
|
|
|
return --_ecore_con_init_count;
|
|
|
|
#endif
|
|
|
|
|
2009-10-09 22:28:43 -07:00
|
|
|
if (!ecore_init())
|
|
|
|
return --_ecore_con_init_count;
|
2005-09-07 02:06:06 -07:00
|
|
|
|
2010-01-06 16:30:05 -08:00
|
|
|
_ecore_con_log_dom = eina_log_domain_register("EcoreCon", ECORE_CON_DEFAULT_LOG_COLOR);
|
2009-12-21 09:32:19 -08:00
|
|
|
if(_ecore_con_log_dom < 0)
|
|
|
|
{
|
2010-01-28 08:07:33 -08:00
|
|
|
EINA_LOG_ERR("Impossible to create a log domain for Ecore Con.");
|
2009-12-21 09:32:19 -08:00
|
|
|
ecore_shutdown();
|
|
|
|
return --_ecore_con_init_count;
|
|
|
|
}
|
2005-09-07 02:06:06 -07:00
|
|
|
ECORE_CON_EVENT_CLIENT_ADD = ecore_event_type_new();
|
|
|
|
ECORE_CON_EVENT_CLIENT_DEL = ecore_event_type_new();
|
|
|
|
ECORE_CON_EVENT_SERVER_ADD = ecore_event_type_new();
|
|
|
|
ECORE_CON_EVENT_SERVER_DEL = ecore_event_type_new();
|
|
|
|
ECORE_CON_EVENT_CLIENT_DATA = ecore_event_type_new();
|
|
|
|
ECORE_CON_EVENT_SERVER_DATA = ecore_event_type_new();
|
2004-03-31 08:47:45 -08:00
|
|
|
|
2005-09-07 02:06:06 -07:00
|
|
|
/* TODO Remember return value, if it fails, use gethostbyname() */
|
2008-10-30 08:26:11 -07:00
|
|
|
ecore_con_ssl_init();
|
2008-10-09 05:30:19 -07:00
|
|
|
ecore_con_info_init();
|
2005-09-07 02:06:06 -07:00
|
|
|
|
2009-10-09 22:28:43 -07:00
|
|
|
return _ecore_con_init_count;
|
2003-09-23 01:09:32 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2004-07-15 06:43:15 -07:00
|
|
|
* Shuts down the Ecore_Con library.
|
2004-09-22 01:17:15 -07:00
|
|
|
* @return Number of times the library has been initialised without being
|
|
|
|
* shut down.
|
|
|
|
* @ingroup Ecore_Con_Lib_Group
|
2003-09-23 01:09:32 -07:00
|
|
|
*/
|
2006-01-06 09:58:12 -08:00
|
|
|
EAPI int
|
2003-09-23 01:09:32 -07:00
|
|
|
ecore_con_shutdown(void)
|
|
|
|
{
|
2009-10-09 22:28:43 -07:00
|
|
|
if (--_ecore_con_init_count != 0)
|
|
|
|
return _ecore_con_init_count;
|
2010-01-28 08:07:33 -08:00
|
|
|
|
* estickies,
* etk,
* PROTO/exalt,
* E-MODULES-EXTRA/diskio,
* E-MODULES-EXTRA/drawer,
* E-MODULES-EXTRA/penguins,
* E-MODULES-EXTRA/slideshow,
* E-MODULES-EXTRA/mail,
* E-MODULES-EXTRA/forecasts,
* E-MODULES-EXTRA/iiirk,
* E-MODULES-EXTRA/places,
* e,
* ewl,
* ecore,
* elitaire,
* entrance,
* e_dbus,
* efreet: Here we go, move from Ecore_List to Eina_List.
NOTE: This patch is huge, I did test it a lot, and I hope nothing is
broken. But if you think something change after this commit, please
contact me ASAP.
SVN revision: 39200
2009-02-25 03:03:47 -08:00
|
|
|
while (servers)
|
|
|
|
_ecore_con_server_free(eina_list_data_get(servers));
|
2005-09-07 02:06:06 -07:00
|
|
|
|
2008-10-09 05:30:19 -07:00
|
|
|
ecore_con_info_shutdown();
|
2008-10-30 08:26:11 -07:00
|
|
|
ecore_con_ssl_shutdown();
|
2009-12-21 09:32:19 -08:00
|
|
|
eina_log_domain_unregister(_ecore_con_log_dom);
|
|
|
|
_ecore_con_log_dom = -1;
|
2006-01-19 01:11:30 -08:00
|
|
|
ecore_shutdown();
|
2010-01-14 23:44:27 -08:00
|
|
|
#ifdef HAVE_EVIL
|
|
|
|
evil_shutdown();
|
|
|
|
#endif
|
2007-08-26 04:17:21 -07:00
|
|
|
|
2009-10-09 22:28:43 -07:00
|
|
|
return _ecore_con_init_count;
|
2003-09-23 01:09:32 -07:00
|
|
|
}
|
|
|
|
|
2004-09-22 01:17:15 -07:00
|
|
|
/**
|
|
|
|
* @defgroup Ecore_Con_Server_Group Ecore Connection Server Functions
|
|
|
|
*
|
|
|
|
* Functions that operate on Ecore server objects.
|
|
|
|
*/
|
|
|
|
|
2003-09-23 01:09:32 -07:00
|
|
|
/**
|
2004-07-15 06:43:15 -07:00
|
|
|
* Creates a server to listen for connections.
|
2003-09-23 01:09:32 -07:00
|
|
|
*
|
2004-07-15 06:43:15 -07:00
|
|
|
* The socket on which the server listens depends on the connection
|
|
|
|
* type:
|
|
|
|
* @li If @a compl_type is @c ECORE_CON_LOCAL_USER, the server will listen on
|
|
|
|
* the Unix socket "~/.ecore/[name]/[port]".
|
|
|
|
* @li If @a compl_type is @c ECORE_CON_LOCAL_SYSTEM, the server will listen
|
|
|
|
* on Unix socket "/tmp/.ecore_service|[name]|[port]".
|
2008-09-25 04:37:01 -07:00
|
|
|
* @li If @a compl_type is @c ECORE_CON_REMOTE_TCP, the server will listen
|
2004-07-15 06:43:15 -07:00
|
|
|
* on TCP port @c port.
|
|
|
|
*
|
|
|
|
* @param compl_type The connection type.
|
|
|
|
* @param name Name to associate with the socket. It is used when
|
|
|
|
* generating the socket name of a Unix socket. Though
|
|
|
|
* it is not used for the TCP socket, it still needs to
|
|
|
|
* be a valid character array. @c NULL will not be
|
|
|
|
* accepted.
|
|
|
|
* @param port Number to identify socket. When a Unix socket is used,
|
|
|
|
* it becomes part of the socket name. When a TCP socket
|
|
|
|
* is used, it is used as the TCP port.
|
|
|
|
* @param data Data to associate with the created Ecore_Con_Server
|
|
|
|
* object.
|
|
|
|
* @return A new Ecore_Con_Server.
|
2004-09-22 01:17:15 -07:00
|
|
|
* @ingroup Ecore_Con_Server_Group
|
2003-09-23 01:09:32 -07:00
|
|
|
*/
|
2006-01-06 09:58:12 -08:00
|
|
|
EAPI Ecore_Con_Server *
|
2007-11-30 00:21:37 -08:00
|
|
|
ecore_con_server_add(Ecore_Con_Type compl_type, const char *name, int port,
|
2003-09-23 01:09:32 -07:00
|
|
|
const void *data)
|
|
|
|
{
|
|
|
|
Ecore_Con_Server *svr;
|
2004-04-14 01:51:19 -07:00
|
|
|
Ecore_Con_Type type;
|
2007-08-26 04:17:21 -07:00
|
|
|
|
2010-01-28 07:35:29 -08:00
|
|
|
if (port < 0 || !name) return NULL;
|
2003-09-23 01:09:32 -07:00
|
|
|
/* local user socket: FILE: ~/.ecore/[name]/[port] */
|
|
|
|
/* local system socket: FILE: /tmp/.ecore_service|[name]|[port] */
|
|
|
|
/* remote system socket: TCP/IP: [name]:[port] */
|
|
|
|
svr = calloc(1, sizeof(Ecore_Con_Server));
|
|
|
|
if (!svr) return NULL;
|
|
|
|
|
2008-10-09 05:30:19 -07:00
|
|
|
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;
|
2008-12-11 05:55:47 -08:00
|
|
|
svr->clients = NULL;
|
2008-10-09 05:30:19 -07:00
|
|
|
svr->ppid = getpid();
|
2008-10-30 08:26:11 -07:00
|
|
|
ecore_con_ssl_server_prepare(svr);
|
2008-10-09 05:30:19 -07:00
|
|
|
|
|
|
|
type = compl_type & ECORE_CON_TYPE;
|
2007-08-26 04:17:21 -07:00
|
|
|
|
2010-05-15 20:04:18 -07:00
|
|
|
if ((type == ECORE_CON_LOCAL_USER) ||
|
|
|
|
(type == ECORE_CON_LOCAL_SYSTEM) ||
|
2006-09-24 00:53:47 -07:00
|
|
|
(type == ECORE_CON_LOCAL_ABSTRACT))
|
2003-09-23 01:09:32 -07:00
|
|
|
{
|
2010-01-04 11:35:21 -08:00
|
|
|
/* Local */
|
|
|
|
if (!ecore_con_local_listen(svr, _ecore_con_svr_handler, svr)) goto error;
|
2003-09-23 01:09:32 -07:00
|
|
|
}
|
2010-05-15 20:04:18 -07:00
|
|
|
|
|
|
|
if ((type == ECORE_CON_REMOTE_TCP) ||
|
|
|
|
(type == ECORE_CON_REMOTE_NODELAY))
|
2008-09-17 08:08:48 -07:00
|
|
|
{
|
2008-10-09 05:30:19 -07:00
|
|
|
/* TCP */
|
|
|
|
if (!ecore_con_info_tcp_listen(svr, _ecore_con_cb_tcp_listen, svr)) goto error;
|
2004-04-14 01:51:19 -07:00
|
|
|
}
|
2010-05-15 20:04:18 -07:00
|
|
|
else if ((type == ECORE_CON_REMOTE_MCAST) ||
|
|
|
|
(type == ECORE_CON_REMOTE_UDP))
|
2008-10-08 17:46:29 -07:00
|
|
|
{
|
2008-10-09 05:30:19 -07:00
|
|
|
/* UDP and MCAST */
|
|
|
|
if (!ecore_con_info_udp_listen(svr, _ecore_con_cb_udp_listen, svr)) goto error;
|
2008-10-08 17:46:29 -07:00
|
|
|
}
|
2010-05-15 20:04:18 -07:00
|
|
|
|
* estickies,
* etk,
* PROTO/exalt,
* E-MODULES-EXTRA/diskio,
* E-MODULES-EXTRA/drawer,
* E-MODULES-EXTRA/penguins,
* E-MODULES-EXTRA/slideshow,
* E-MODULES-EXTRA/mail,
* E-MODULES-EXTRA/forecasts,
* E-MODULES-EXTRA/iiirk,
* E-MODULES-EXTRA/places,
* e,
* ewl,
* ecore,
* elitaire,
* entrance,
* e_dbus,
* efreet: Here we go, move from Ecore_List to Eina_List.
NOTE: This patch is huge, I did test it a lot, and I hope nothing is
broken. But if you think something change after this commit, please
contact me ASAP.
SVN revision: 39200
2009-02-25 03:03:47 -08:00
|
|
|
servers = eina_list_append(servers, svr);
|
2008-10-08 17:46:29 -07:00
|
|
|
ECORE_MAGIC_SET(svr, ECORE_MAGIC_CON_SERVER);
|
2008-10-09 05:30:19 -07:00
|
|
|
|
2003-09-23 01:09:32 -07:00
|
|
|
return svr;
|
2007-08-26 04:17:21 -07:00
|
|
|
|
2003-09-23 01:09:32 -07:00
|
|
|
error:
|
|
|
|
if (svr->name) free(svr->name);
|
|
|
|
if (svr->path) free(svr->path);
|
2010-01-14 23:44:27 -08:00
|
|
|
#ifndef _WIN32
|
2003-09-23 01:09:32 -07:00
|
|
|
if (svr->fd >= 0) close(svr->fd);
|
|
|
|
if (svr->fd_handler) ecore_main_fd_handler_del(svr->fd_handler);
|
2004-04-03 07:03:33 -08:00
|
|
|
if (svr->write_buf) free(svr->write_buf);
|
2006-03-19 23:45:58 -08:00
|
|
|
if (svr->ip) free(svr->ip);
|
2010-01-14 23:44:27 -08:00
|
|
|
#endif
|
2008-10-30 08:26:11 -07:00
|
|
|
ecore_con_ssl_server_shutdown(svr);
|
2003-09-23 01:09:32 -07:00
|
|
|
free(svr);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2004-07-15 06:43:15 -07:00
|
|
|
* Creates a server object to represent the server listening at the
|
|
|
|
* given port.
|
|
|
|
*
|
|
|
|
* The socket to which the server connects depends on the connection type:
|
|
|
|
* @li If @a compl_type is @c ECORE_CON_LOCAL_USER, the function will
|
|
|
|
* connect to the server listening on the Unix socket
|
|
|
|
* "~/.ecore/[name]/[port]".
|
|
|
|
* @li If @a compl_type is @c ECORE_CON_LOCAL_SYSTEM, the function will
|
|
|
|
* connect to the server listening on the Unix socket
|
|
|
|
* "/tmp/.ecore_service|[name]|[port]".
|
2008-09-25 04:37:01 -07:00
|
|
|
* @li If @a compl_type is @c ECORE_CON_REMOTE_TCP, the function will
|
2004-07-15 06:43:15 -07:00
|
|
|
* connect to the server listening on the TCP port "[name]:[port]".
|
2003-09-23 01:09:32 -07:00
|
|
|
*
|
2004-07-15 06:43:15 -07:00
|
|
|
* @param compl_type The connection type.
|
|
|
|
* @param name Name used when determining what socket to connect to.
|
|
|
|
* It is used to generate the socket name when the socket
|
|
|
|
* is a Unix socket. It is used as the hostname when
|
|
|
|
* connecting with a TCP socket.
|
2004-07-22 06:07:25 -07:00
|
|
|
* @param port Number to identify the socket to connect to. Used when
|
2004-07-15 06:43:15 -07:00
|
|
|
* generating the socket name for a Unix socket, or as the
|
|
|
|
* TCP port when connecting to a TCP socket.
|
|
|
|
* @param data Data to associate with the created Ecore_Con_Server
|
|
|
|
* object.
|
|
|
|
* @return A new Ecore_Con_Server.
|
2004-09-22 01:17:15 -07:00
|
|
|
* @ingroup Ecore_Con_Server_Group
|
2003-09-23 01:09:32 -07:00
|
|
|
*/
|
2006-01-06 09:58:12 -08:00
|
|
|
EAPI Ecore_Con_Server *
|
2007-11-30 00:21:37 -08:00
|
|
|
ecore_con_server_connect(Ecore_Con_Type compl_type, const char *name, int port,
|
2003-09-23 01:09:32 -07:00
|
|
|
const void *data)
|
|
|
|
{
|
|
|
|
Ecore_Con_Server *svr;
|
2004-04-14 01:51:19 -07:00
|
|
|
Ecore_Con_Type type;
|
2003-09-23 01:09:32 -07:00
|
|
|
|
|
|
|
if (!name) return NULL;
|
|
|
|
/* local user socket: FILE: ~/.ecore/[name]/[port] */
|
|
|
|
/* local system socket: FILE: /tmp/.ecore_service|[name]|[port] */
|
|
|
|
/* remote system socket: TCP/IP: [name]:[port] */
|
|
|
|
svr = calloc(1, sizeof(Ecore_Con_Server));
|
|
|
|
if (!svr) return NULL;
|
2007-08-26 04:17:21 -07:00
|
|
|
|
2008-10-09 05:30:19 -07:00
|
|
|
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;
|
2008-12-11 05:55:47 -08:00
|
|
|
svr->clients = NULL;
|
2008-10-09 05:30:19 -07:00
|
|
|
svr->client_limit = -1;
|
2008-10-30 08:26:11 -07:00
|
|
|
ecore_con_ssl_server_prepare(svr);
|
2008-10-09 05:30:19 -07:00
|
|
|
|
|
|
|
type = compl_type & ECORE_CON_TYPE;
|
|
|
|
|
2010-05-15 20:04:18 -07:00
|
|
|
if (((type == ECORE_CON_REMOTE_TCP) ||
|
|
|
|
(type == ECORE_CON_REMOTE_NODELAY) ||
|
|
|
|
(type == ECORE_CON_REMOTE_UDP) ||
|
|
|
|
(type == ECORE_CON_REMOTE_BROADCAST)) &&
|
|
|
|
(port < 0))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
if ((type == ECORE_CON_LOCAL_USER) ||
|
|
|
|
(type == ECORE_CON_LOCAL_SYSTEM) ||
|
2006-09-24 00:53:47 -07:00
|
|
|
(type == ECORE_CON_LOCAL_ABSTRACT))
|
2003-09-23 01:09:32 -07:00
|
|
|
{
|
2010-01-04 11:35:21 -08:00
|
|
|
/* Local */
|
|
|
|
if (!ecore_con_local_connect(svr, _ecore_con_cl_handler, svr, _ecore_con_event_server_add_free)) goto error;
|
2003-09-23 01:09:32 -07:00
|
|
|
}
|
2004-03-31 08:47:45 -08:00
|
|
|
|
2010-05-15 20:04:18 -07:00
|
|
|
if ((type == ECORE_CON_REMOTE_TCP) ||
|
|
|
|
(type == ECORE_CON_REMOTE_NODELAY))
|
2006-01-19 01:11:30 -08:00
|
|
|
{
|
2008-10-09 05:30:19 -07:00
|
|
|
/* TCP */
|
|
|
|
if (!ecore_con_info_tcp_connect(svr, _ecore_con_cb_tcp_connect, svr)) goto error;
|
2006-01-19 01:11:30 -08:00
|
|
|
}
|
2010-05-15 20:04:18 -07:00
|
|
|
else if ((type == ECORE_CON_REMOTE_UDP) ||
|
|
|
|
(type == ECORE_CON_REMOTE_BROADCAST))
|
2008-09-25 03:14:31 -07:00
|
|
|
{
|
2008-10-09 05:30:19 -07:00
|
|
|
/* UDP and MCAST */
|
|
|
|
if (!ecore_con_info_udp_connect(svr, _ecore_con_cb_udp_connect, svr)) goto error;
|
2008-09-25 03:14:31 -07:00
|
|
|
}
|
2005-09-02 20:07:29 -07:00
|
|
|
|
* estickies,
* etk,
* PROTO/exalt,
* E-MODULES-EXTRA/diskio,
* E-MODULES-EXTRA/drawer,
* E-MODULES-EXTRA/penguins,
* E-MODULES-EXTRA/slideshow,
* E-MODULES-EXTRA/mail,
* E-MODULES-EXTRA/forecasts,
* E-MODULES-EXTRA/iiirk,
* E-MODULES-EXTRA/places,
* e,
* ewl,
* ecore,
* elitaire,
* entrance,
* e_dbus,
* efreet: Here we go, move from Ecore_List to Eina_List.
NOTE: This patch is huge, I did test it a lot, and I hope nothing is
broken. But if you think something change after this commit, please
contact me ASAP.
SVN revision: 39200
2009-02-25 03:03:47 -08:00
|
|
|
servers = eina_list_append(servers, svr);
|
2008-10-09 05:30:19 -07:00
|
|
|
ECORE_MAGIC_SET(svr, ECORE_MAGIC_CON_SERVER);
|
|
|
|
|
2003-09-23 01:09:32 -07:00
|
|
|
return svr;
|
2007-08-26 04:17:21 -07:00
|
|
|
|
2003-09-23 01:09:32 -07:00
|
|
|
error:
|
|
|
|
if (svr->name) free(svr->name);
|
|
|
|
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);
|
2008-10-30 08:26:11 -07:00
|
|
|
ecore_con_ssl_server_shutdown(svr);
|
2003-09-23 01:09:32 -07:00
|
|
|
free(svr);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2004-07-15 06:43:15 -07:00
|
|
|
* Closes the connection and frees the given server.
|
2004-09-22 01:17:15 -07:00
|
|
|
* @param svr The given server.
|
|
|
|
* @return Data associated with the server when it was created.
|
|
|
|
* @ingroup Ecore_Con_Server_Group
|
2003-09-23 01:09:32 -07:00
|
|
|
*/
|
2006-01-06 09:58:12 -08:00
|
|
|
EAPI void *
|
2003-09-23 01:09:32 -07:00
|
|
|
ecore_con_server_del(Ecore_Con_Server *svr)
|
|
|
|
{
|
|
|
|
void *data;
|
|
|
|
|
|
|
|
if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
|
|
|
|
{
|
2007-11-30 00:21:37 -08:00
|
|
|
ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_del");
|
2003-09-23 01:09:32 -07:00
|
|
|
return NULL;
|
2006-03-19 21:53:12 -08:00
|
|
|
}
|
* estickies,
* etk,
* PROTO/exalt,
* E-MODULES-EXTRA/diskio,
* E-MODULES-EXTRA/drawer,
* E-MODULES-EXTRA/penguins,
* E-MODULES-EXTRA/slideshow,
* E-MODULES-EXTRA/mail,
* E-MODULES-EXTRA/forecasts,
* E-MODULES-EXTRA/iiirk,
* E-MODULES-EXTRA/places,
* e,
* ewl,
* ecore,
* elitaire,
* entrance,
* e_dbus,
* efreet: Here we go, move from Ecore_List to Eina_List.
NOTE: This patch is huge, I did test it a lot, and I hope nothing is
broken. But if you think something change after this commit, please
contact me ASAP.
SVN revision: 39200
2009-02-25 03:03:47 -08:00
|
|
|
if (svr->delete_me) return NULL;
|
|
|
|
|
2003-09-23 01:09:32 -07:00
|
|
|
data = svr->data;
|
2006-03-19 21:59:21 -08:00
|
|
|
svr->data = NULL;
|
2006-06-02 01:06:46 -07:00
|
|
|
svr->delete_me = 1;
|
2006-03-19 21:53:12 -08:00
|
|
|
if (svr->event_count > 0)
|
2006-06-02 00:01:49 -07:00
|
|
|
{
|
|
|
|
if (svr->fd_handler)
|
|
|
|
{
|
|
|
|
ecore_main_fd_handler_del(svr->fd_handler);
|
|
|
|
svr->fd_handler = NULL;
|
|
|
|
}
|
|
|
|
}
|
2006-03-19 21:53:12 -08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
_ecore_con_server_free(svr);
|
|
|
|
}
|
2003-09-23 01:09:32 -07:00
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2004-07-15 06:43:15 -07:00
|
|
|
* Retrieves the data associated with the given server.
|
2004-09-22 01:17:15 -07:00
|
|
|
* @param svr The given server.
|
|
|
|
* @return The associated data.
|
|
|
|
* @ingroup Ecore_Con_Server_Group
|
2003-09-23 01:09:32 -07:00
|
|
|
*/
|
2006-01-06 09:58:12 -08:00
|
|
|
EAPI void *
|
2003-09-23 01:09:32 -07:00
|
|
|
ecore_con_server_data_get(Ecore_Con_Server *svr)
|
|
|
|
{
|
|
|
|
if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
|
|
|
|
{
|
2007-11-30 00:21:37 -08:00
|
|
|
ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_data_get");
|
2003-09-23 01:09:32 -07:00
|
|
|
return NULL;
|
2007-08-26 04:17:21 -07:00
|
|
|
}
|
2003-09-23 01:09:32 -07:00
|
|
|
return svr->data;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2004-07-15 06:43:15 -07:00
|
|
|
* Retrieves whether the given server is currently connected.
|
|
|
|
* @todo Check that this function does what the documenter believes it does.
|
2004-09-22 01:17:15 -07:00
|
|
|
* @param svr The given server.
|
|
|
|
* @return @c 1 if the server is connected. @c 0 otherwise.
|
|
|
|
* @ingroup Ecore_Con_Server_Group
|
2003-09-23 01:09:32 -07:00
|
|
|
*/
|
2006-01-06 09:58:12 -08:00
|
|
|
EAPI int
|
2003-09-23 01:09:32 -07:00
|
|
|
ecore_con_server_connected_get(Ecore_Con_Server *svr)
|
|
|
|
{
|
|
|
|
if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
|
|
|
|
{
|
2007-11-30 00:21:37 -08:00
|
|
|
ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_connected_get");
|
2003-09-23 01:09:32 -07:00
|
|
|
return 0;
|
2007-08-26 04:17:21 -07:00
|
|
|
}
|
2003-09-23 01:09:32 -07:00
|
|
|
if (svr->connecting) return 0;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2006-03-29 22:48:45 -08:00
|
|
|
/**
|
|
|
|
* Retrieves the current list of clients.
|
|
|
|
* @param svr The given server.
|
|
|
|
* @return The list of clients on this server.
|
|
|
|
* @ingroup Ecore_Con_Server_Group
|
|
|
|
*/
|
2008-12-11 05:55:47 -08:00
|
|
|
EAPI Eina_List *
|
2006-03-29 22:48:45 -08:00
|
|
|
ecore_con_server_clients_get(Ecore_Con_Server *svr)
|
|
|
|
{
|
|
|
|
if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
|
|
|
|
{
|
2007-11-30 00:21:37 -08:00
|
|
|
ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_clients_get");
|
2006-03-29 22:48:45 -08:00
|
|
|
return NULL;
|
2007-08-26 04:17:21 -07:00
|
|
|
}
|
2006-03-29 22:48:45 -08:00
|
|
|
return svr->clients;
|
|
|
|
}
|
|
|
|
|
2003-09-23 01:09:32 -07:00
|
|
|
/**
|
2004-07-15 06:43:15 -07:00
|
|
|
* Sends the given data to the given server.
|
2004-09-22 01:17:15 -07:00
|
|
|
* @param svr The given server.
|
|
|
|
* @param data The given data.
|
|
|
|
* @param size Length of the data, in bytes, to send.
|
|
|
|
* @return The number of bytes sent. @c 0 will be returned if there is an
|
|
|
|
* error.
|
|
|
|
* @ingroup Ecore_Con_Server_Group
|
2003-09-23 01:09:32 -07:00
|
|
|
*/
|
2006-01-06 09:58:12 -08:00
|
|
|
EAPI int
|
2006-11-05 08:49:55 -08:00
|
|
|
ecore_con_server_send(Ecore_Con_Server *svr, const void *data, int size)
|
2003-09-23 01:09:32 -07:00
|
|
|
{
|
|
|
|
if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
|
|
|
|
{
|
2007-11-30 00:21:37 -08:00
|
|
|
ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_send");
|
2003-09-23 01:09:32 -07:00
|
|
|
return 0;
|
2007-08-26 04:17:21 -07:00
|
|
|
}
|
2004-04-23 00:24:40 -07:00
|
|
|
if (svr->dead) return 0;
|
2003-09-23 01:09:32 -07:00
|
|
|
if (!data) return 0;
|
|
|
|
if (size < 1) return 0;
|
2005-09-22 22:46:56 -07:00
|
|
|
if (svr->fd_handler)
|
|
|
|
ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE);
|
2004-04-03 07:03:33 -08:00
|
|
|
if (svr->write_buf)
|
2003-09-23 01:09:32 -07:00
|
|
|
{
|
|
|
|
unsigned char *newbuf;
|
2007-08-26 04:17:21 -07:00
|
|
|
|
2004-04-03 07:03:33 -08:00
|
|
|
newbuf = realloc(svr->write_buf, svr->write_buf_size + size);
|
|
|
|
if (newbuf) svr->write_buf = newbuf;
|
2003-09-23 01:09:32 -07:00
|
|
|
else return 0;
|
2004-04-03 07:03:33 -08:00
|
|
|
memcpy(svr->write_buf + svr->write_buf_size, data, size);
|
|
|
|
svr->write_buf_size += size;
|
2003-09-23 01:09:32 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-04-03 07:03:33 -08:00
|
|
|
svr->write_buf = malloc(size);
|
|
|
|
if (!svr->write_buf) return 0;
|
|
|
|
svr->write_buf_size = size;
|
|
|
|
memcpy(svr->write_buf, data, size);
|
2003-09-23 01:09:32 -07:00
|
|
|
}
|
2004-04-23 00:24:40 -07:00
|
|
|
return size;
|
2003-09-23 01:09:32 -07:00
|
|
|
}
|
2004-09-22 01:17:15 -07:00
|
|
|
|
2005-04-28 21:51:31 -07:00
|
|
|
/**
|
|
|
|
* Sets a limit on the number of clients that can be handled concurrently
|
|
|
|
* by the given server, and a policy on what to do if excess clients try to
|
|
|
|
* connect.
|
|
|
|
* Beware that if you set this once ecore is already running, you may
|
|
|
|
* already have pending CLIENT_ADD events in your event queue. Those
|
|
|
|
* clients have already connected and will not be affected by this call.
|
|
|
|
* Only clients subsequently trying to connect will be affected.
|
|
|
|
* @param svr The given server.
|
|
|
|
* @param client_limit The maximum number of clients to handle
|
2007-08-26 04:17:21 -07:00
|
|
|
* concurrently. -1 means unlimited (default). 0
|
2005-04-28 21:51:31 -07:00
|
|
|
* effectively disables the server.
|
|
|
|
* @param reject_excess_clients Set to 1 to automatically disconnect
|
|
|
|
* excess clients as soon as they connect if you are
|
|
|
|
* already handling client_limit clients. Set to 0
|
|
|
|
* (default) to just hold off on the "accept()"
|
|
|
|
* system call until the number of active clients
|
|
|
|
* drops. This causes the kernel to queue up to 4096
|
|
|
|
* connections (or your kernel's limit, whichever is
|
|
|
|
* lower).
|
|
|
|
* @ingroup Ecore_Con_Server_Group
|
|
|
|
*/
|
2006-01-06 09:58:12 -08:00
|
|
|
EAPI void
|
2005-04-28 21:51:31 -07:00
|
|
|
ecore_con_server_client_limit_set(Ecore_Con_Server *svr, int client_limit, char reject_excess_clients)
|
|
|
|
{
|
|
|
|
if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
|
|
|
|
{
|
2007-11-30 00:21:37 -08:00
|
|
|
ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_client_limit_set");
|
2005-04-28 21:51:31 -07:00
|
|
|
return;
|
2007-08-26 04:17:21 -07:00
|
|
|
}
|
2005-04-28 21:51:31 -07:00
|
|
|
svr->client_limit = client_limit;
|
|
|
|
svr->reject_excess_clients = reject_excess_clients;
|
|
|
|
}
|
|
|
|
|
2006-03-19 23:45:58 -08:00
|
|
|
/**
|
|
|
|
* Gets the IP address of a server that has been connected to.
|
2007-08-26 04:17:21 -07:00
|
|
|
*
|
2006-03-19 23:45:58 -08:00
|
|
|
* @param svr The given server.
|
|
|
|
* @return A pointer to an internal string that contains the IP address of
|
|
|
|
* the connected server in the form "XXX.YYY.ZZZ.AAA" IP notation.
|
|
|
|
* This string should not be modified or trusted to stay valid after
|
|
|
|
* deletion for the @p svr object. If no IP is known NULL is returned.
|
|
|
|
* @ingroup Ecore_Con_Server_Group
|
|
|
|
*/
|
|
|
|
EAPI char *
|
|
|
|
ecore_con_server_ip_get(Ecore_Con_Server *svr)
|
|
|
|
{
|
|
|
|
if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
|
|
|
|
{
|
2007-11-30 00:21:37 -08:00
|
|
|
ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_ip_get");
|
2006-03-19 23:45:58 -08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return svr->ip;
|
|
|
|
}
|
|
|
|
|
2007-02-16 10:12:38 -08:00
|
|
|
/**
|
|
|
|
* Flushes all pending data to the given server. Will return when done.
|
2007-08-26 04:17:21 -07:00
|
|
|
*
|
2007-02-16 10:12:38 -08:00
|
|
|
* @param svr The given server.
|
|
|
|
* @ingroup Ecore_Con_Server_Group
|
|
|
|
*/
|
|
|
|
EAPI void
|
|
|
|
ecore_con_server_flush(Ecore_Con_Server *svr)
|
|
|
|
{
|
|
|
|
if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
|
|
|
|
{
|
2007-11-30 00:21:37 -08:00
|
|
|
ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_flush");
|
2007-02-16 10:12:38 -08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
_ecore_con_server_flush(svr);
|
|
|
|
}
|
|
|
|
|
2004-09-22 01:17:15 -07:00
|
|
|
/**
|
|
|
|
* @defgroup Ecore_Con_Client_Group Ecore Connection Client Functions
|
|
|
|
*
|
|
|
|
* Functions that operate on Ecore connection client objects.
|
|
|
|
*/
|
|
|
|
|
2003-09-23 01:09:32 -07:00
|
|
|
/**
|
2004-07-15 06:43:15 -07:00
|
|
|
* Sends the given data to the given client.
|
2004-09-22 01:17:15 -07:00
|
|
|
* @param cl The given client.
|
|
|
|
* @param data The given data.
|
|
|
|
* @param size Length of the data, in bytes, to send.
|
|
|
|
* @return The number of bytes sent. @c 0 will be returned if there is an
|
|
|
|
* error.
|
|
|
|
* @ingroup Ecore_Con_Client_Group
|
2003-09-23 01:09:32 -07:00
|
|
|
*/
|
2006-01-06 09:58:12 -08:00
|
|
|
EAPI int
|
2007-10-21 08:16:14 -07:00
|
|
|
ecore_con_client_send(Ecore_Con_Client *cl, const void *data, int size)
|
2003-09-23 01:09:32 -07:00
|
|
|
{
|
|
|
|
if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
|
|
|
|
{
|
2007-11-30 00:21:37 -08:00
|
|
|
ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_send");
|
2003-09-23 01:09:32 -07:00
|
|
|
return 0;
|
2007-08-26 04:17:21 -07:00
|
|
|
}
|
2003-09-23 01:09:32 -07:00
|
|
|
if (cl->dead) return 0;
|
|
|
|
if (!data) return 0;
|
|
|
|
if (size < 1) return 0;
|
2005-09-22 22:46:56 -07:00
|
|
|
if (cl->fd_handler)
|
|
|
|
ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE);
|
2008-10-09 05:30:19 -07:00
|
|
|
|
|
|
|
if(cl->server && cl->server->type == ECORE_CON_REMOTE_UDP)
|
2008-10-06 02:28:15 -07:00
|
|
|
{
|
2010-01-28 07:35:29 -08:00
|
|
|
sendto(cl->server->fd, data, size, 0, (struct sockaddr *) cl->client_addr, cl->client_addr_len);
|
2008-10-09 05:30:19 -07:00
|
|
|
}
|
|
|
|
else if (cl->buf)
|
|
|
|
{
|
|
|
|
unsigned char *newbuf;
|
2007-08-26 04:17:21 -07:00
|
|
|
|
2008-10-09 05:30:19 -07:00
|
|
|
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;
|
2003-09-23 01:09:32 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
cl->buf = malloc(size);
|
|
|
|
if (!cl->buf) return 0;
|
|
|
|
cl->buf_size = size;
|
|
|
|
memcpy(cl->buf, data, size);
|
|
|
|
}
|
2004-04-23 00:24:40 -07:00
|
|
|
return size;
|
2003-09-23 01:09:32 -07:00
|
|
|
}
|
2007-08-26 04:17:21 -07:00
|
|
|
|
2003-09-23 01:09:32 -07:00
|
|
|
/**
|
2004-07-15 06:43:15 -07:00
|
|
|
* Retrieves the server representing the socket the client has
|
|
|
|
* connected to.
|
2007-08-26 04:17:21 -07:00
|
|
|
* @param cl The given client.
|
2004-09-22 01:17:15 -07:00
|
|
|
* @return The server that the client connected to.
|
|
|
|
* @ingroup Ecore_Con_Client_Group
|
2003-09-23 01:09:32 -07:00
|
|
|
*/
|
2006-01-06 09:58:12 -08:00
|
|
|
EAPI Ecore_Con_Server *
|
2003-09-23 01:09:32 -07:00
|
|
|
ecore_con_client_server_get(Ecore_Con_Client *cl)
|
|
|
|
{
|
|
|
|
if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
|
|
|
|
{
|
2007-11-30 00:21:37 -08:00
|
|
|
ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_server_get");
|
2003-09-23 01:09:32 -07:00
|
|
|
return NULL;
|
2007-08-26 04:17:21 -07:00
|
|
|
}
|
2003-09-23 01:09:32 -07:00
|
|
|
return cl->server;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2004-07-15 06:43:15 -07:00
|
|
|
* Closes the connection and frees memory allocated to the given client.
|
2004-09-22 01:17:15 -07:00
|
|
|
* @param cl The given client.
|
|
|
|
* @return Data associated with the client.
|
|
|
|
* @ingroup Ecore_Con_Client_Group
|
2003-09-23 01:09:32 -07:00
|
|
|
*/
|
2006-01-06 09:58:12 -08:00
|
|
|
EAPI void *
|
2003-09-23 01:09:32 -07:00
|
|
|
ecore_con_client_del(Ecore_Con_Client *cl)
|
|
|
|
{
|
2008-10-09 05:30:19 -07:00
|
|
|
void *data = NULL;
|
2007-08-26 04:17:21 -07:00
|
|
|
|
2003-09-23 01:09:32 -07:00
|
|
|
if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
|
|
|
|
{
|
2007-11-30 00:21:37 -08:00
|
|
|
ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_del");
|
2003-09-23 01:09:32 -07:00
|
|
|
return NULL;
|
2007-08-26 04:17:21 -07:00
|
|
|
}
|
2008-10-09 05:30:19 -07:00
|
|
|
|
2009-11-27 06:36:43 -08:00
|
|
|
if(cl->client_addr && cl->server && (cl->server->type == ECORE_CON_REMOTE_UDP ||
|
2008-10-09 05:30:19 -07:00
|
|
|
cl->server->type == ECORE_CON_REMOTE_MCAST))
|
2009-11-27 06:36:43 -08:00
|
|
|
free(cl->client_addr);
|
|
|
|
|
|
|
|
data = cl->data;
|
2008-10-09 05:30:19 -07:00
|
|
|
|
2006-03-19 21:59:21 -08:00
|
|
|
cl->data = NULL;
|
2006-06-02 01:06:46 -07:00
|
|
|
cl->delete_me = 1;
|
2006-03-19 21:53:12 -08:00
|
|
|
if (cl->event_count > 0)
|
2006-06-02 00:01:49 -07:00
|
|
|
{
|
|
|
|
if (cl->fd_handler)
|
|
|
|
{
|
|
|
|
ecore_main_fd_handler_del(cl->fd_handler);
|
|
|
|
cl->fd_handler = NULL;
|
|
|
|
}
|
|
|
|
}
|
2006-03-19 21:53:12 -08:00
|
|
|
else
|
|
|
|
{
|
2009-10-07 04:59:26 -07:00
|
|
|
if (cl->server)
|
|
|
|
cl->server->clients = eina_list_remove(cl->server->clients, cl);
|
2006-03-19 21:53:12 -08:00
|
|
|
_ecore_con_client_free(cl);
|
|
|
|
}
|
2003-11-19 15:05:08 -08:00
|
|
|
return data;
|
2003-09-23 01:09:32 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2004-07-15 06:43:15 -07:00
|
|
|
* Sets the data associated with the given client to @p data.
|
2004-09-22 01:17:15 -07:00
|
|
|
* @param cl The given client.
|
|
|
|
* @param data What to set the data to.
|
|
|
|
* @ingroup Ecore_Con_Client_Group
|
2003-09-23 01:09:32 -07:00
|
|
|
*/
|
2006-01-06 09:58:12 -08:00
|
|
|
EAPI void
|
2003-09-23 01:09:32 -07:00
|
|
|
ecore_con_client_data_set(Ecore_Con_Client *cl, const void *data)
|
|
|
|
{
|
|
|
|
if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
|
|
|
|
{
|
2007-11-30 00:21:37 -08:00
|
|
|
ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_data_set");
|
2003-09-23 01:09:32 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
cl->data = (void *)data;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2004-07-15 06:43:15 -07:00
|
|
|
* Retrieves the data associated with the given client.
|
2004-09-22 01:17:15 -07:00
|
|
|
* @param cl The given client.
|
|
|
|
* @return The data associated with @p cl.
|
|
|
|
* @ingroup Ecore_Con_Client_Group
|
2003-09-23 01:09:32 -07:00
|
|
|
*/
|
2006-01-06 09:58:12 -08:00
|
|
|
EAPI void *
|
2003-09-23 01:09:32 -07:00
|
|
|
ecore_con_client_data_get(Ecore_Con_Client *cl)
|
|
|
|
{
|
|
|
|
if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
|
|
|
|
{
|
2007-11-30 00:21:37 -08:00
|
|
|
ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_data_get");
|
2003-09-23 01:09:32 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return cl->data;
|
|
|
|
}
|
|
|
|
|
2006-03-19 23:45:58 -08:00
|
|
|
/**
|
|
|
|
* Gets the IP address of a cleint that has connected.
|
2007-08-26 04:17:21 -07:00
|
|
|
*
|
2006-03-19 23:45:58 -08:00
|
|
|
* @param cl The given client.
|
|
|
|
* @return A pointer to an internal string that contains the IP address of
|
|
|
|
* the connected client in the form "XXX.YYY.ZZZ.AAA" IP notation.
|
|
|
|
* This string should not be modified or trusted to stay valid after
|
|
|
|
* deletion for the @p cl object. If no IP is known NULL is returned.
|
|
|
|
* @ingroup Ecore_Con_Client_Group
|
|
|
|
*/
|
|
|
|
EAPI char *
|
|
|
|
ecore_con_client_ip_get(Ecore_Con_Client *cl)
|
|
|
|
{
|
|
|
|
if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
|
|
|
|
{
|
2007-11-30 00:21:37 -08:00
|
|
|
ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_ip_get");
|
2006-03-19 23:45:58 -08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return cl->ip;
|
|
|
|
}
|
|
|
|
|
2007-02-16 10:12:38 -08:00
|
|
|
/**
|
|
|
|
* Flushes all pending data to the given client. Will return when done.
|
2007-08-26 04:17:21 -07:00
|
|
|
*
|
2007-02-16 10:12:38 -08:00
|
|
|
* @param cl The given client.
|
|
|
|
* @ingroup Ecore_Con_Client_Group
|
|
|
|
*/
|
|
|
|
EAPI void
|
|
|
|
ecore_con_client_flush(Ecore_Con_Client *cl)
|
|
|
|
{
|
|
|
|
if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
|
|
|
|
{
|
2007-11-30 00:21:37 -08:00
|
|
|
ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_flush");
|
2007-02-16 10:12:38 -08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
_ecore_con_client_flush(cl);
|
|
|
|
}
|
|
|
|
|
2003-09-23 01:09:32 -07:00
|
|
|
static void
|
|
|
|
_ecore_con_server_free(Ecore_Con_Server *svr)
|
|
|
|
{
|
2008-12-11 05:55:47 -08:00
|
|
|
Ecore_Con_Client *cl;
|
2006-05-18 20:52:24 -07:00
|
|
|
double t_start, t;
|
2007-08-26 04:17:21 -07:00
|
|
|
|
|
|
|
ECORE_MAGIC_SET(svr, ECORE_MAGIC_NONE);
|
2006-05-18 20:52:24 -07:00
|
|
|
t_start = ecore_time_get();
|
|
|
|
while ((svr->write_buf) && (!svr->dead))
|
|
|
|
{
|
|
|
|
_ecore_con_server_flush(svr);
|
|
|
|
t = ecore_time_get();
|
2006-06-02 00:01:49 -07:00
|
|
|
if ((t - t_start) > 0.5)
|
2006-05-18 20:52:24 -07:00
|
|
|
{
|
2009-12-21 09:32:19 -08:00
|
|
|
WRN("ECORE_CON: EEK - stuck in _ecore_con_server_free() trying\n"
|
|
|
|
" to flush data out from the server, and have been for\n"
|
|
|
|
" %1.1f seconds. This is taking too long. Aborting flush.",
|
|
|
|
(t - t_start));
|
2006-05-18 20:52:24 -07:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2004-04-03 07:03:33 -08:00
|
|
|
if (svr->write_buf) free(svr->write_buf);
|
* estickies,
* etk,
* PROTO/exalt,
* E-MODULES-EXTRA/diskio,
* E-MODULES-EXTRA/drawer,
* E-MODULES-EXTRA/penguins,
* E-MODULES-EXTRA/slideshow,
* E-MODULES-EXTRA/mail,
* E-MODULES-EXTRA/forecasts,
* E-MODULES-EXTRA/iiirk,
* E-MODULES-EXTRA/places,
* e,
* ewl,
* ecore,
* elitaire,
* entrance,
* e_dbus,
* efreet: Here we go, move from Ecore_List to Eina_List.
NOTE: This patch is huge, I did test it a lot, and I hope nothing is
broken. But if you think something change after this commit, please
contact me ASAP.
SVN revision: 39200
2009-02-25 03:03:47 -08:00
|
|
|
EINA_LIST_FREE(svr->clients, cl)
|
2008-12-11 05:55:47 -08:00
|
|
|
_ecore_con_client_free(cl);
|
2008-10-09 05:30:19 -07:00
|
|
|
if ((svr->created) && (svr->path) && (svr->ppid == getpid()))
|
2007-11-30 00:21:37 -08:00
|
|
|
unlink(svr->path);
|
2003-09-23 01:09:32 -07:00
|
|
|
if (svr->fd >= 0) close(svr->fd);
|
2008-10-30 08:26:11 -07:00
|
|
|
ecore_con_ssl_server_shutdown(svr);
|
2003-09-23 01:09:32 -07:00
|
|
|
if (svr->name) free(svr->name);
|
|
|
|
if (svr->path) free(svr->path);
|
2006-03-19 23:45:58 -08:00
|
|
|
if (svr->ip) free(svr->ip);
|
2003-09-23 01:09:32 -07:00
|
|
|
if (svr->fd_handler) ecore_main_fd_handler_del(svr->fd_handler);
|
* estickies,
* etk,
* PROTO/exalt,
* E-MODULES-EXTRA/diskio,
* E-MODULES-EXTRA/drawer,
* E-MODULES-EXTRA/penguins,
* E-MODULES-EXTRA/slideshow,
* E-MODULES-EXTRA/mail,
* E-MODULES-EXTRA/forecasts,
* E-MODULES-EXTRA/iiirk,
* E-MODULES-EXTRA/places,
* e,
* ewl,
* ecore,
* elitaire,
* entrance,
* e_dbus,
* efreet: Here we go, move from Ecore_List to Eina_List.
NOTE: This patch is huge, I did test it a lot, and I hope nothing is
broken. But if you think something change after this commit, please
contact me ASAP.
SVN revision: 39200
2009-02-25 03:03:47 -08:00
|
|
|
servers = eina_list_remove(servers, svr);
|
2003-09-23 01:09:32 -07:00
|
|
|
free(svr);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_ecore_con_client_free(Ecore_Con_Client *cl)
|
|
|
|
{
|
2006-05-18 20:52:24 -07:00
|
|
|
double t_start, t;
|
2007-08-26 04:17:21 -07:00
|
|
|
|
|
|
|
ECORE_MAGIC_SET(cl, ECORE_MAGIC_NONE);
|
2006-05-18 20:52:24 -07:00
|
|
|
t_start = ecore_time_get();
|
|
|
|
while ((cl->buf) && (!cl->dead))
|
|
|
|
{
|
|
|
|
_ecore_con_client_flush(cl);
|
|
|
|
t = ecore_time_get();
|
2006-06-02 00:01:49 -07:00
|
|
|
if ((t - t_start) > 0.5)
|
2006-05-18 20:52:24 -07:00
|
|
|
{
|
2009-12-21 09:32:19 -08:00
|
|
|
WRN("EEK - stuck in _ecore_con_client_free() trying\n"
|
|
|
|
" to flush data out from the client, and have been for\n"
|
|
|
|
" %1.1f seconds. This is taking too long. Aborting flush.",
|
|
|
|
(t - t_start));
|
2006-05-18 20:52:24 -07:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2003-09-23 01:09:32 -07:00
|
|
|
if (cl->buf) free(cl->buf);
|
|
|
|
if (cl->fd >= 0) close(cl->fd);
|
|
|
|
if (cl->fd_handler) ecore_main_fd_handler_del(cl->fd_handler);
|
2006-03-19 23:45:58 -08:00
|
|
|
if (cl->ip) free(cl->ip);
|
2003-09-23 01:09:32 -07:00
|
|
|
free(cl);
|
|
|
|
}
|
|
|
|
|
2004-04-25 08:42:57 -07:00
|
|
|
static void
|
|
|
|
kill_server(Ecore_Con_Server *svr)
|
|
|
|
{
|
2006-06-02 00:24:04 -07:00
|
|
|
if (!svr->delete_me)
|
2005-03-03 00:54:09 -08:00
|
|
|
{
|
2006-06-02 00:24:04 -07:00
|
|
|
Ecore_Con_Event_Server_Del *e;
|
2007-08-26 04:17:21 -07:00
|
|
|
|
2006-06-02 00:24:04 -07:00
|
|
|
e = calloc(1, sizeof(Ecore_Con_Event_Server_Del));
|
|
|
|
if (e)
|
|
|
|
{
|
|
|
|
svr->event_count++;
|
|
|
|
e->server = svr;
|
|
|
|
ecore_event_add(ECORE_CON_EVENT_SERVER_DEL, e,
|
|
|
|
_ecore_con_event_server_del_free, NULL);
|
|
|
|
}
|
2005-03-03 00:54:09 -08:00
|
|
|
}
|
2007-08-26 04:17:21 -07:00
|
|
|
|
2004-04-25 08:42:57 -07:00
|
|
|
svr->dead = 1;
|
2005-08-16 06:15:24 -07:00
|
|
|
if (svr->fd_handler) ecore_main_fd_handler_del(svr->fd_handler);
|
2004-04-25 08:42:57 -07:00
|
|
|
svr->fd_handler = NULL;
|
|
|
|
}
|
|
|
|
|
2008-10-06 02:41:39 -07:00
|
|
|
static void
|
2008-10-09 05:30:19 -07:00
|
|
|
_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;
|
2010-02-20 10:01:50 -08:00
|
|
|
if (setsockopt(svr->fd, SOL_SOCKET, SO_LINGER, (const void *)&lin, sizeof(struct linger)) < 0) goto error;
|
2009-11-20 02:58:19 -08:00
|
|
|
if (svr->type == ECORE_CON_REMOTE_NODELAY)
|
|
|
|
{
|
|
|
|
int flag = 1;
|
|
|
|
|
|
|
|
if (setsockopt(svr->fd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int)) < 0)
|
|
|
|
goto error;
|
|
|
|
}
|
2008-10-09 05:30:19 -07:00
|
|
|
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;
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
error:
|
2008-10-30 08:26:11 -07:00
|
|
|
ecore_con_ssl_server_shutdown(svr);
|
2008-10-09 05:30:19 -07:00
|
|
|
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);
|
2010-02-20 10:01:50 -08:00
|
|
|
if (setsockopt(svr->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const void *)&mreq,sizeof(mreq)) != 0) goto error;
|
2008-10-09 05:30:19 -07:00
|
|
|
}
|
|
|
|
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);
|
2010-02-20 10:01:50 -08:00
|
|
|
if (setsockopt(svr->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const void *)&mreq6,sizeof(mreq6)) != 0) goto error;
|
2008-10-09 05:30:19 -07:00
|
|
|
}
|
2010-02-20 10:01:50 -08:00
|
|
|
if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof(on)) != 0) goto error;
|
2008-10-09 05:30:19 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
error:
|
2008-10-30 08:26:11 -07:00
|
|
|
ecore_con_ssl_server_shutdown(svr);
|
2008-10-09 05:30:19 -07:00
|
|
|
kill_server(svr);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_ecore_con_cb_tcp_connect(void *data, Ecore_Con_Info *net_info)
|
2008-10-06 02:41:39 -07:00
|
|
|
{
|
|
|
|
Ecore_Con_Server *svr;
|
2010-02-20 10:01:50 -08:00
|
|
|
int res;
|
2008-10-06 02:41:39 -07:00
|
|
|
int curstate = 0;
|
|
|
|
|
|
|
|
svr = data;
|
|
|
|
|
2008-10-09 05:30:19 -07:00
|
|
|
if (!net_info) goto error;
|
|
|
|
svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype, net_info->info.ai_protocol);
|
2008-10-06 02:41:39 -07:00
|
|
|
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;
|
2010-02-20 10:01:50 -08:00
|
|
|
if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&curstate, sizeof(curstate)) < 0)
|
2008-10-06 02:41:39 -07:00
|
|
|
goto error;
|
2009-11-20 02:58:19 -08:00
|
|
|
if (svr->type == ECORE_CON_REMOTE_NODELAY)
|
|
|
|
{
|
|
|
|
int flag = 1;
|
|
|
|
|
|
|
|
if (setsockopt(svr->fd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int)) < 0)
|
|
|
|
goto error;
|
|
|
|
}
|
2010-02-20 10:01:50 -08:00
|
|
|
res = connect(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen);
|
|
|
|
#ifdef _WIN32
|
|
|
|
if (res == SOCKET_ERROR)
|
|
|
|
{
|
|
|
|
if (WSAGetLastError() != WSAEINPROGRESS)
|
|
|
|
goto error;
|
|
|
|
#else
|
|
|
|
if (res < 0)
|
2008-10-06 02:41:39 -07:00
|
|
|
{
|
2008-10-30 08:26:11 -07:00
|
|
|
if (errno != EINPROGRESS)
|
|
|
|
goto error;
|
2010-02-20 10:01:50 -08:00
|
|
|
#endif
|
2008-10-30 08:26:11 -07:00
|
|
|
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);
|
2008-10-06 02:41:39 -07:00
|
|
|
}
|
|
|
|
else
|
2008-10-09 05:30:19 -07:00
|
|
|
svr->fd_handler =
|
2008-10-30 08:26:11 -07:00
|
|
|
ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
|
|
|
|
_ecore_con_cl_handler, svr, NULL, NULL);
|
|
|
|
|
|
|
|
if (svr->type & ECORE_CON_SSL)
|
|
|
|
if (ecore_con_ssl_server_init(svr))
|
|
|
|
goto error;
|
2008-10-06 02:41:39 -07:00
|
|
|
|
|
|
|
if (!svr->fd_handler) goto error;
|
2008-10-09 05:30:19 -07:00
|
|
|
svr->ip = strdup(net_info->ip);
|
2008-10-08 17:46:29 -07:00
|
|
|
|
2008-10-06 02:41:39 -07:00
|
|
|
return;
|
|
|
|
|
|
|
|
error:
|
2008-10-30 08:26:11 -07:00
|
|
|
ecore_con_ssl_server_shutdown(svr);
|
2008-10-06 02:41:39 -07:00
|
|
|
kill_server(svr);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2008-10-09 05:30:19 -07:00
|
|
|
_ecore_con_cb_udp_connect(void *data, Ecore_Con_Info *net_info)
|
2008-10-06 02:41:39 -07:00
|
|
|
{
|
2010-06-07 06:05:49 -07:00
|
|
|
char test[INET6_ADDRSTRLEN];
|
|
|
|
char *tmp;
|
2008-10-06 02:41:39 -07:00
|
|
|
Ecore_Con_Server *svr;
|
|
|
|
int curstate = 0;
|
2009-08-12 04:24:33 -07:00
|
|
|
int broadcast = 1;
|
2008-10-06 02:41:39 -07:00
|
|
|
svr = data;
|
|
|
|
|
2008-10-09 05:30:19 -07:00
|
|
|
if (!net_info) goto error;
|
|
|
|
svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype, net_info->info.ai_protocol);
|
2008-10-06 02:41:39 -07:00
|
|
|
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;
|
2009-08-12 04:24:33 -07:00
|
|
|
|
|
|
|
if(svr->type == ECORE_CON_REMOTE_BROADCAST)
|
|
|
|
{
|
2010-02-20 10:01:50 -08:00
|
|
|
if (setsockopt(svr->fd, SOL_SOCKET, SO_BROADCAST, (const void *)&broadcast, sizeof(broadcast)) < 0) goto error;
|
2009-08-12 04:24:33 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-02-20 10:01:50 -08:00
|
|
|
if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&curstate, sizeof(curstate)) < 0) goto error;
|
2009-08-12 04:24:33 -07:00
|
|
|
}
|
|
|
|
|
2008-10-09 05:30:19 -07:00
|
|
|
if (connect(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen) < 0)
|
2008-10-06 02:41:39 -07:00
|
|
|
goto error;
|
|
|
|
else
|
2008-10-09 05:30:19 -07:00
|
|
|
svr->fd_handler =
|
2008-10-06 02:41:39 -07:00
|
|
|
ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ | ECORE_FD_WRITE,
|
|
|
|
_ecore_con_cl_udp_handler, svr, NULL, NULL);
|
2008-10-08 17:46:29 -07:00
|
|
|
if (!svr->fd_handler) goto error;
|
2008-10-09 05:30:19 -07:00
|
|
|
svr->ip = strdup(net_info->ip);
|
|
|
|
|
2008-10-06 02:41:39 -07:00
|
|
|
return;
|
|
|
|
|
|
|
|
error:
|
2008-10-30 08:26:11 -07:00
|
|
|
ecore_con_ssl_server_shutdown(svr);
|
2008-10-06 02:41:39 -07:00
|
|
|
kill_server(svr);
|
|
|
|
}
|
|
|
|
|
2008-10-01 08:27:52 -07:00
|
|
|
static Ecore_Con_State
|
2004-05-09 13:23:23 -07:00
|
|
|
svr_try_connect_plain(Ecore_Con_Server *svr)
|
2004-04-03 07:03:33 -08:00
|
|
|
{
|
2010-02-20 10:01:50 -08:00
|
|
|
int res;
|
|
|
|
int so_err = 0;
|
2005-08-16 02:25:02 -07:00
|
|
|
unsigned int size = sizeof(int);
|
2004-04-03 07:03:33 -08:00
|
|
|
|
2010-02-20 10:01:50 -08:00
|
|
|
res = getsockopt(svr->fd, SOL_SOCKET, SO_ERROR, (void *)&so_err, &size);
|
|
|
|
#ifdef _WIN32
|
|
|
|
if (res == SOCKET_ERROR)
|
|
|
|
so_err = -1;
|
|
|
|
|
|
|
|
if (so_err == WSAEINPROGRESS && !svr->dead)
|
|
|
|
return ECORE_CON_INPROGRESS;
|
|
|
|
#else
|
|
|
|
if (res < 0)
|
2004-04-14 01:51:19 -07:00
|
|
|
so_err = -1;
|
2007-08-26 04:17:21 -07:00
|
|
|
|
2008-10-01 08:27:52 -07:00
|
|
|
if (so_err == EINPROGRESS && !svr->dead)
|
|
|
|
return ECORE_CON_INPROGRESS;
|
2010-02-20 10:01:50 -08:00
|
|
|
#endif
|
2008-10-01 08:27:52 -07:00
|
|
|
|
2004-04-14 01:51:19 -07:00
|
|
|
if (so_err != 0)
|
|
|
|
{
|
|
|
|
/* we lost our server! */
|
2004-04-25 08:42:57 -07:00
|
|
|
kill_server(svr);
|
2008-10-01 08:27:52 -07:00
|
|
|
return ECORE_CON_DISCONNECTED;
|
2004-04-14 01:51:19 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-06-02 00:24:04 -07:00
|
|
|
if (!svr->delete_me)
|
2004-04-14 01:51:19 -07:00
|
|
|
{
|
2006-06-02 00:24:04 -07:00
|
|
|
/* we got our server! */
|
|
|
|
Ecore_Con_Event_Server_Add *e;
|
2007-08-26 04:17:21 -07:00
|
|
|
|
2006-06-02 00:24:04 -07:00
|
|
|
svr->connecting = 0;
|
|
|
|
e = calloc(1, sizeof(Ecore_Con_Event_Server_Add));
|
|
|
|
if (e)
|
|
|
|
{
|
|
|
|
svr->event_count++;
|
|
|
|
e->server = svr;
|
|
|
|
ecore_event_add(ECORE_CON_EVENT_SERVER_ADD, e,
|
|
|
|
_ecore_con_event_server_add_free, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (svr->fd_handler)
|
|
|
|
{
|
|
|
|
if (!svr->write_buf)
|
|
|
|
ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
|
2004-04-14 01:51:19 -07:00
|
|
|
}
|
|
|
|
}
|
2008-10-01 08:27:52 -07:00
|
|
|
|
|
|
|
if (!svr->dead)
|
|
|
|
return ECORE_CON_CONNECTED;
|
|
|
|
else
|
|
|
|
return ECORE_CON_DISCONNECTED;
|
2004-04-03 07:03:33 -08:00
|
|
|
}
|
|
|
|
|
2004-05-09 13:23:23 -07:00
|
|
|
/* returns 1 on success, 0 on failure */
|
2008-10-01 08:27:52 -07:00
|
|
|
static Ecore_Con_State svr_try_connect(Ecore_Con_Server *svr)
|
2004-05-09 13:23:23 -07:00
|
|
|
{
|
2008-10-30 08:26:11 -07:00
|
|
|
if (!(svr->type & ECORE_CON_SSL))
|
|
|
|
return svr_try_connect_plain(svr);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
switch (ecore_con_ssl_server_try(svr)) {
|
2008-10-01 08:27:52 -07:00
|
|
|
case ECORE_CON_CONNECTED:
|
2007-11-30 00:21:37 -08:00
|
|
|
return svr_try_connect_plain(svr);
|
2008-10-01 08:27:52 -07:00
|
|
|
case ECORE_CON_DISCONNECTED:
|
2007-11-30 00:21:37 -08:00
|
|
|
kill_server(svr);
|
2008-10-01 12:51:29 -07:00
|
|
|
return ECORE_CON_DISCONNECTED;
|
2007-11-30 00:21:37 -08:00
|
|
|
default:
|
2008-10-01 12:51:29 -07:00
|
|
|
return ECORE_CON_INPROGRESS;
|
2008-10-30 08:26:11 -07:00
|
|
|
}
|
|
|
|
}
|
2004-05-09 13:23:23 -07:00
|
|
|
}
|
|
|
|
|
2010-01-31 03:58:37 -08:00
|
|
|
static char *
|
|
|
|
_ecore_con_pretty_ip(struct sockaddr *client_addr, socklen_t size)
|
|
|
|
{
|
|
|
|
char ipbuf[INET6_ADDRSTRLEN + 1];
|
|
|
|
|
|
|
|
/* show v4mapped address in pretty form */
|
|
|
|
if (client_addr->sa_family == AF_INET6)
|
|
|
|
{
|
|
|
|
struct sockaddr_in6 *sa6;
|
|
|
|
|
|
|
|
sa6 = (struct sockaddr_in6 *) client_addr;
|
|
|
|
if (IN6_IS_ADDR_V4MAPPED(&sa6->sin6_addr))
|
|
|
|
{
|
|
|
|
snprintf(ipbuf, sizeof (ipbuf), "%u.%u.%u.%u",
|
2010-02-04 02:34:08 -08:00
|
|
|
sa6->sin6_addr.s6_addr[12],
|
|
|
|
sa6->sin6_addr.s6_addr[13],
|
|
|
|
sa6->sin6_addr.s6_addr[14],
|
|
|
|
sa6->sin6_addr.s6_addr[15]);
|
2010-01-31 03:58:37 -08:00
|
|
|
return strdup(ipbuf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (getnameinfo(client_addr, size,
|
|
|
|
ipbuf, sizeof (ipbuf), NULL, 0, NI_NUMERICHOST))
|
|
|
|
return strdup("0.0.0.0");
|
|
|
|
|
|
|
|
ipbuf[sizeof (ipbuf) - 1] = 0;
|
|
|
|
return strdup(ipbuf);
|
|
|
|
}
|
|
|
|
|
2008-10-30 08:26:11 -07:00
|
|
|
static int
|
|
|
|
_ecore_con_svr_handler(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__)
|
|
|
|
{
|
|
|
|
Ecore_Con_Server *svr;
|
|
|
|
int new_fd;
|
2010-01-31 03:58:37 -08:00
|
|
|
unsigned char incoming[256];
|
2008-10-30 08:26:11 -07:00
|
|
|
size_t size_in;
|
|
|
|
|
|
|
|
svr = data;
|
|
|
|
if (svr->dead) return 1;
|
|
|
|
if (svr->delete_me) return 1;
|
|
|
|
if ((svr->client_limit >= 0) && (!svr->reject_excess_clients))
|
|
|
|
{
|
2010-02-28 15:27:47 -08:00
|
|
|
if (eina_list_count(svr->clients) >= (unsigned int)svr->client_limit)
|
|
|
|
return 1;
|
2008-10-30 08:26:11 -07:00
|
|
|
}
|
|
|
|
/* a new client */
|
2010-01-31 03:58:37 -08:00
|
|
|
size_in = sizeof(incoming);
|
2008-10-30 08:26:11 -07:00
|
|
|
|
2010-01-14 23:44:27 -08:00
|
|
|
memset(&incoming, 0, size_in);
|
2008-10-30 08:26:11 -07:00
|
|
|
new_fd = accept(svr->fd, (struct sockaddr *)&incoming, (socklen_t *)&size_in);
|
|
|
|
if (new_fd >= 0)
|
|
|
|
{
|
|
|
|
Ecore_Con_Client *cl;
|
|
|
|
|
|
|
|
if ((svr->client_limit >= 0) && (svr->reject_excess_clients))
|
|
|
|
{
|
2010-02-28 15:27:47 -08:00
|
|
|
if (eina_list_count(svr->clients) >= (unsigned int)svr->client_limit)
|
2010-01-28 08:05:34 -08:00
|
|
|
{
|
|
|
|
close(new_fd);
|
|
|
|
return 1;
|
|
|
|
}
|
2008-10-30 08:26:11 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
cl = calloc(1, sizeof(Ecore_Con_Client));
|
|
|
|
if (!cl)
|
|
|
|
{
|
|
|
|
close(new_fd);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
fcntl(new_fd, F_SETFL, O_NONBLOCK);
|
|
|
|
fcntl(new_fd, F_SETFD, FD_CLOEXEC);
|
|
|
|
cl->fd = new_fd;
|
|
|
|
cl->server = svr;
|
|
|
|
|
|
|
|
if ((svr->type & ECORE_CON_SSL) &&
|
|
|
|
(ecore_con_ssl_client_init(cl)))
|
|
|
|
{
|
|
|
|
close(new_fd);
|
2008-12-15 09:59:19 -08:00
|
|
|
ecore_con_ssl_client_shutdown(cl);
|
2008-10-30 08:26:11 -07:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
2009-01-06 08:30:33 -08:00
|
|
|
svr->clients = eina_list_append(svr->clients, cl);
|
2008-10-30 08:26:11 -07:00
|
|
|
if (!svr->path)
|
2010-01-31 03:58:37 -08:00
|
|
|
cl->ip = _ecore_con_pretty_ip((struct sockaddr *) &incoming, size_in);
|
2008-10-30 08:26:11 -07:00
|
|
|
if (!cl->delete_me)
|
|
|
|
{
|
|
|
|
Ecore_Con_Event_Client_Add *e;
|
|
|
|
|
|
|
|
e = calloc(1, sizeof(Ecore_Con_Event_Client_Add));
|
|
|
|
if (e)
|
|
|
|
{
|
|
|
|
cl->event_count++;
|
|
|
|
e->client = cl;
|
|
|
|
ecore_event_add(ECORE_CON_EVENT_CLIENT_ADD, e,
|
|
|
|
_ecore_con_event_client_add_free, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
2004-04-03 07:03:33 -08:00
|
|
|
|
2003-09-23 01:09:32 -07:00
|
|
|
static int
|
|
|
|
_ecore_con_cl_handler(void *data, Ecore_Fd_Handler *fd_handler)
|
|
|
|
{
|
|
|
|
Ecore_Con_Server *svr;
|
2007-08-26 04:17:21 -07:00
|
|
|
|
2003-09-23 01:09:32 -07:00
|
|
|
svr = data;
|
|
|
|
if (svr->dead) return 1;
|
2006-06-02 00:08:16 -07:00
|
|
|
if (svr->delete_me) return 1;
|
2003-09-23 01:09:32 -07:00
|
|
|
if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
|
|
|
|
{
|
|
|
|
unsigned char *inbuf = NULL;
|
|
|
|
int inbuf_num = 0;
|
2010-06-08 04:02:57 -07:00
|
|
|
int tries;
|
2004-04-03 07:03:33 -08:00
|
|
|
|
2008-10-01 08:27:52 -07:00
|
|
|
if (svr->connecting && (svr_try_connect(svr) != ECORE_CON_CONNECTED))
|
2004-05-09 13:23:23 -07:00
|
|
|
return 1;
|
|
|
|
|
2010-06-08 04:02:57 -07:00
|
|
|
for (tries = 0; tries < 16; tries++)
|
2003-09-23 01:09:32 -07:00
|
|
|
{
|
2008-10-30 08:26:11 -07:00
|
|
|
int num;
|
|
|
|
int lost_server = 1;
|
2008-12-15 09:59:19 -08:00
|
|
|
unsigned char buf[READBUFSIZ];
|
2008-10-30 08:26:11 -07:00
|
|
|
|
|
|
|
if (!(svr->type & ECORE_CON_SSL))
|
|
|
|
{
|
|
|
|
if (((num = read(svr->fd, buf, READBUFSIZ)) < 0) &&
|
|
|
|
(errno == EAGAIN))
|
|
|
|
lost_server = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
if (!(num = ecore_con_ssl_server_read(svr, buf, READBUFSIZ)))
|
|
|
|
lost_server = 0;
|
|
|
|
|
|
|
|
if (num < 1)
|
|
|
|
{
|
|
|
|
if (inbuf && !svr->delete_me)
|
|
|
|
{
|
|
|
|
Ecore_Con_Event_Server_Data *e;
|
|
|
|
|
|
|
|
e = calloc(1, sizeof(Ecore_Con_Event_Server_Data));
|
|
|
|
if (e)
|
|
|
|
{
|
|
|
|
svr->event_count++;
|
|
|
|
e->server = svr;
|
|
|
|
e->data = inbuf;
|
|
|
|
e->size = inbuf_num;
|
|
|
|
ecore_event_add(ECORE_CON_EVENT_SERVER_DATA, e,
|
|
|
|
_ecore_con_event_server_data_free,
|
|
|
|
NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (lost_server) kill_server(svr);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
inbuf = realloc(inbuf, inbuf_num + num);
|
|
|
|
memcpy(inbuf + inbuf_num, buf, num);
|
|
|
|
inbuf_num += num;
|
2003-09-23 01:09:32 -07:00
|
|
|
}
|
2004-03-31 08:47:45 -08:00
|
|
|
|
2008-10-30 08:26:11 -07:00
|
|
|
/* #if USE_OPENSSL */
|
2009-03-22 06:27:24 -07:00
|
|
|
/* if (svr->fd_handler) */
|
|
|
|
/* { */
|
|
|
|
/* if (svr->ssl && ssl_err == SSL_ERROR_WANT_READ) */
|
|
|
|
/* ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ); */
|
|
|
|
/* else if (svr->ssl && ssl_err == SSL_ERROR_WANT_WRITE) */
|
|
|
|
/* ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE); */
|
|
|
|
/* } */
|
2008-10-30 08:26:11 -07:00
|
|
|
/* #endif */
|
2003-09-23 01:09:32 -07:00
|
|
|
}
|
2004-04-14 01:51:19 -07:00
|
|
|
else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE))
|
|
|
|
{
|
2004-05-09 13:23:23 -07:00
|
|
|
if (svr->connecting && !svr_try_connect (svr))
|
|
|
|
return 1;
|
2004-04-14 01:51:19 -07:00
|
|
|
_ecore_con_server_flush(svr);
|
|
|
|
}
|
2004-04-03 07:03:33 -08:00
|
|
|
|
2003-09-23 01:09:32 -07:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2008-09-25 03:14:31 -07:00
|
|
|
static int
|
|
|
|
_ecore_con_cl_udp_handler(void *data, Ecore_Fd_Handler *fd_handler)
|
|
|
|
{
|
|
|
|
Ecore_Con_Server *svr;
|
|
|
|
|
|
|
|
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 = 0;
|
2008-10-09 05:30:19 -07:00
|
|
|
|
2008-09-25 03:14:31 -07:00
|
|
|
errno = 0;
|
|
|
|
num = read(svr->fd, buf, 65536);
|
2010-06-07 06:05:49 -07:00
|
|
|
if (num >= 0)
|
2008-09-25 03:14:31 -07:00
|
|
|
{
|
|
|
|
if (!svr->delete_me)
|
|
|
|
{
|
|
|
|
Ecore_Con_Event_Server_Data *e;
|
|
|
|
unsigned char *inbuf;
|
|
|
|
|
|
|
|
inbuf = malloc(num);
|
|
|
|
if(inbuf == NULL)
|
|
|
|
return 1;
|
|
|
|
memcpy(inbuf, buf, num);
|
|
|
|
|
|
|
|
e = calloc(1, sizeof(Ecore_Con_Event_Server_Data));
|
|
|
|
if (e)
|
|
|
|
{
|
|
|
|
svr->event_count++;
|
|
|
|
e->server = svr;
|
|
|
|
e->data = inbuf;
|
|
|
|
e->size = num;
|
|
|
|
ecore_event_add(ECORE_CON_EVENT_SERVER_DATA, e,
|
|
|
|
_ecore_con_event_server_data_free,
|
|
|
|
NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-06-07 06:05:49 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
if ((errno == EIO) || (errno == EBADF) ||
|
|
|
|
(errno == EPIPE) || (errno == EINVAL) ||
|
|
|
|
(errno == ENOSPC) || (errno == ECONNREFUSED))
|
|
|
|
{
|
|
|
|
kill_server(svr);
|
|
|
|
}
|
|
|
|
}
|
2008-09-25 03:14:31 -07:00
|
|
|
}
|
|
|
|
else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE))
|
|
|
|
_ecore_con_server_flush(svr);
|
2008-10-09 05:30:19 -07:00
|
|
|
|
2008-09-25 03:14:31 -07:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2008-09-17 08:08:48 -07:00
|
|
|
static int
|
2008-10-09 05:30:19 -07:00
|
|
|
_ecore_con_svr_udp_handler(void *data, Ecore_Fd_Handler *fd_handler)
|
2008-09-17 08:08:48 -07:00
|
|
|
{
|
2008-10-09 05:30:19 -07:00
|
|
|
Ecore_Con_Server *svr;
|
* estickies,
* etk,
* PROTO/exalt,
* E-MODULES-EXTRA/diskio,
* E-MODULES-EXTRA/drawer,
* E-MODULES-EXTRA/penguins,
* E-MODULES-EXTRA/slideshow,
* E-MODULES-EXTRA/mail,
* E-MODULES-EXTRA/forecasts,
* E-MODULES-EXTRA/iiirk,
* E-MODULES-EXTRA/places,
* e,
* ewl,
* ecore,
* elitaire,
* entrance,
* e_dbus,
* efreet: Here we go, move from Ecore_List to Eina_List.
NOTE: This patch is huge, I did test it a lot, and I hope nothing is
broken. But if you think something change after this commit, please
contact me ASAP.
SVN revision: 39200
2009-02-25 03:03:47 -08:00
|
|
|
Ecore_Con_Client *cl = NULL;
|
2008-09-17 08:08:48 -07:00
|
|
|
|
2008-10-09 05:30:19 -07:00
|
|
|
svr = data;
|
|
|
|
if (svr->dead) return 1;
|
|
|
|
if (svr->delete_me) return 1;
|
2008-09-17 08:08:48 -07:00
|
|
|
if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
|
|
|
|
{
|
2008-10-09 05:30:19 -07:00
|
|
|
unsigned char buf[READBUFSIZ];
|
2010-01-28 07:35:29 -08:00
|
|
|
unsigned char client_addr[256];
|
2008-10-27 02:49:25 -07:00
|
|
|
unsigned int client_addr_len = sizeof(client_addr);
|
|
|
|
int num;
|
2008-09-17 08:08:48 -07:00
|
|
|
|
|
|
|
errno = 0;
|
2010-02-20 10:01:50 -08:00
|
|
|
#ifdef _WIN32
|
|
|
|
num = fcntl(svr->fd, F_SETFL, O_NONBLOCK);
|
|
|
|
if (num >= 0)
|
|
|
|
num = recvfrom(svr->fd, buf, sizeof(buf), 0, (struct sockaddr*) &client_addr, &client_addr_len);
|
|
|
|
#else
|
2008-10-09 05:30:19 -07:00
|
|
|
num = recvfrom(svr->fd, buf, sizeof(buf), MSG_DONTWAIT, (struct sockaddr*) &client_addr, &client_addr_len);
|
2010-02-20 10:01:50 -08:00
|
|
|
#endif
|
2008-10-09 05:30:19 -07:00
|
|
|
|
2010-06-07 06:05:49 -07:00
|
|
|
if (num >= 0)
|
2008-09-17 08:08:48 -07:00
|
|
|
{
|
2008-10-09 05:30:19 -07:00
|
|
|
if (!svr->delete_me)
|
2008-09-17 08:08:48 -07:00
|
|
|
{
|
|
|
|
Ecore_Con_Event_Client_Data *e;
|
|
|
|
unsigned char *inbuf;
|
2008-10-09 05:30:19 -07:00
|
|
|
|
|
|
|
/* 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;
|
2010-01-28 07:35:29 -08:00
|
|
|
cl->client_addr = calloc(1, client_addr_len);
|
|
|
|
cl->client_addr_len = client_addr_len;
|
2009-11-27 06:36:43 -08:00
|
|
|
if(cl->client_addr == NULL)
|
2008-10-09 05:30:19 -07:00
|
|
|
{
|
|
|
|
free(cl);
|
|
|
|
return 1;
|
|
|
|
}
|
2010-01-28 07:35:29 -08:00
|
|
|
memcpy(cl->client_addr, &client_addr, client_addr_len);
|
2008-10-09 05:30:19 -07:00
|
|
|
ECORE_MAGIC_SET(cl, ECORE_MAGIC_CON_CLIENT);
|
2009-01-06 08:30:33 -08:00
|
|
|
svr->clients = eina_list_append(svr->clients, cl);
|
2008-10-09 05:30:19 -07:00
|
|
|
|
2010-01-31 03:58:37 -08:00
|
|
|
cl->ip = _ecore_con_pretty_ip(cl->client_addr, cl->client_addr_len);
|
2008-09-17 08:08:48 -07:00
|
|
|
|
|
|
|
inbuf = malloc(num);
|
|
|
|
if(inbuf == NULL)
|
2008-10-09 05:30:19 -07:00
|
|
|
{
|
2009-11-27 06:36:43 -08:00
|
|
|
free(cl->client_addr);
|
2008-10-09 05:30:19 -07:00
|
|
|
free(cl);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2008-09-17 08:08:48 -07:00
|
|
|
memcpy(inbuf, buf, num);
|
2008-10-09 05:30:19 -07:00
|
|
|
|
2008-09-17 08:08:48 -07:00
|
|
|
e = calloc(1, sizeof(Ecore_Con_Event_Client_Data));
|
|
|
|
if (e)
|
|
|
|
{
|
2008-10-09 05:30:19 -07:00
|
|
|
svr->event_count++;
|
2008-09-17 08:08:48 -07:00
|
|
|
e->client = cl;
|
|
|
|
e->data = inbuf;
|
|
|
|
e->size = num;
|
|
|
|
ecore_event_add(ECORE_CON_EVENT_CLIENT_DATA, e,
|
|
|
|
_ecore_con_event_client_data_free,
|
|
|
|
NULL);
|
|
|
|
}
|
2008-10-09 05:30:19 -07:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
2008-09-17 08:08:48 -07:00
|
|
|
}
|
2010-06-07 06:05:49 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ((errno == EIO) || (errno == EBADF) ||
|
2008-09-17 08:08:48 -07:00
|
|
|
(errno == EPIPE) || (errno == EINVAL) ||
|
2010-06-07 06:05:49 -07:00
|
|
|
(errno == ENOSPC) || (errno == ECONNREFUSED))
|
2008-09-17 08:08:48 -07:00
|
|
|
{
|
2008-10-09 05:30:19 -07:00
|
|
|
if (!svr->delete_me)
|
2008-09-17 08:08:48 -07:00
|
|
|
{
|
|
|
|
/* we lost our client! */
|
|
|
|
Ecore_Con_Event_Client_Del *e;
|
2008-10-09 05:30:19 -07:00
|
|
|
|
2008-09-17 08:08:48 -07:00
|
|
|
e = calloc(1, sizeof(Ecore_Con_Event_Client_Del));
|
|
|
|
if (e)
|
|
|
|
{
|
2008-10-09 05:30:19 -07:00
|
|
|
svr->event_count++;
|
2008-09-17 08:08:48 -07:00
|
|
|
e->client = cl;
|
|
|
|
ecore_event_add(ECORE_CON_EVENT_CLIENT_DEL, e,
|
|
|
|
_ecore_con_event_client_del_free,
|
|
|
|
NULL);
|
|
|
|
}
|
|
|
|
}
|
2008-10-09 05:30:19 -07:00
|
|
|
svr->dead = 1;
|
|
|
|
if (svr->fd_handler)
|
|
|
|
ecore_main_fd_handler_del(svr->fd_handler);
|
|
|
|
svr->fd_handler = NULL;
|
2008-09-17 08:08:48 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE))
|
|
|
|
_ecore_con_client_flush(cl);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2003-09-23 01:09:32 -07:00
|
|
|
static int
|
|
|
|
_ecore_con_svr_cl_handler(void *data, Ecore_Fd_Handler *fd_handler)
|
|
|
|
{
|
|
|
|
Ecore_Con_Client *cl;
|
2007-08-26 04:17:21 -07:00
|
|
|
|
2003-09-23 01:09:32 -07:00
|
|
|
cl = data;
|
|
|
|
if (cl->dead) return 1;
|
2006-06-02 00:08:16 -07:00
|
|
|
if (cl->delete_me) return 1;
|
2003-09-23 01:09:32 -07:00
|
|
|
if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
|
|
|
|
{
|
|
|
|
unsigned char *inbuf = NULL;
|
|
|
|
int inbuf_num = 0;
|
2008-10-30 08:26:11 -07:00
|
|
|
int lost_client = 1;
|
2010-06-08 04:02:57 -07:00
|
|
|
int tries;
|
2007-08-26 04:17:21 -07:00
|
|
|
|
2010-06-08 04:02:57 -07:00
|
|
|
for (tries = 0; tries < 16; tries++)
|
2003-09-23 01:09:32 -07:00
|
|
|
{
|
2008-12-15 09:59:19 -08:00
|
|
|
unsigned char buf[65536];
|
2003-09-23 01:09:32 -07:00
|
|
|
int num;
|
2007-08-26 04:17:21 -07:00
|
|
|
|
2003-09-23 01:09:32 -07:00
|
|
|
errno = 0;
|
2008-10-30 08:26:11 -07:00
|
|
|
|
|
|
|
if (!(cl->server->type & ECORE_CON_SSL))
|
|
|
|
{
|
|
|
|
if (((num = read(cl->fd, buf, 65536)) < 0) &&
|
|
|
|
(errno == EAGAIN))
|
|
|
|
lost_client = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
if (!(num = ecore_con_ssl_client_read(cl, buf, 65536)))
|
|
|
|
lost_client = 0;
|
|
|
|
|
2010-06-07 06:05:49 -07:00
|
|
|
if (num < 0)
|
2003-09-23 01:09:32 -07:00
|
|
|
{
|
2008-10-30 08:26:11 -07:00
|
|
|
if (inbuf && !cl->delete_me)
|
2003-09-23 01:09:32 -07:00
|
|
|
{
|
2008-10-30 08:26:11 -07:00
|
|
|
Ecore_Con_Event_Client_Data *e;
|
2009-03-22 06:27:24 -07:00
|
|
|
|
2008-10-30 08:26:11 -07:00
|
|
|
e = calloc(1, sizeof(Ecore_Con_Event_Client_Data));
|
|
|
|
if (e)
|
|
|
|
{
|
|
|
|
cl->event_count++;
|
|
|
|
e->client = cl;
|
|
|
|
e->data = inbuf;
|
|
|
|
e->size = inbuf_num;
|
|
|
|
ecore_event_add(ECORE_CON_EVENT_CLIENT_DATA, e,
|
|
|
|
_ecore_con_event_client_data_free,
|
|
|
|
NULL);
|
|
|
|
}
|
2003-09-23 01:09:32 -07:00
|
|
|
}
|
2008-10-30 08:26:11 -07:00
|
|
|
|
|
|
|
if (lost_client)
|
2003-09-23 01:09:32 -07:00
|
|
|
{
|
2006-06-02 00:24:04 -07:00
|
|
|
if (!cl->delete_me)
|
2003-09-23 01:09:32 -07:00
|
|
|
{
|
2006-06-02 00:24:04 -07:00
|
|
|
/* we lost our client! */
|
|
|
|
Ecore_Con_Event_Client_Del *e;
|
2007-08-26 04:17:21 -07:00
|
|
|
|
2006-06-02 00:24:04 -07:00
|
|
|
e = calloc(1, sizeof(Ecore_Con_Event_Client_Del));
|
|
|
|
if (e)
|
|
|
|
{
|
|
|
|
cl->event_count++;
|
|
|
|
e->client = cl;
|
2007-08-26 04:17:21 -07:00
|
|
|
ecore_event_add(ECORE_CON_EVENT_CLIENT_DEL, e,
|
2006-06-02 00:24:04 -07:00
|
|
|
_ecore_con_event_client_del_free,
|
|
|
|
NULL);
|
|
|
|
}
|
2003-09-23 01:09:32 -07:00
|
|
|
}
|
|
|
|
cl->dead = 1;
|
2007-08-26 04:17:21 -07:00
|
|
|
if (cl->fd_handler)
|
2006-06-02 00:24:04 -07:00
|
|
|
ecore_main_fd_handler_del(cl->fd_handler);
|
2003-09-23 01:09:32 -07:00
|
|
|
cl->fd_handler = NULL;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
inbuf = realloc(inbuf, inbuf_num + num);
|
|
|
|
memcpy(inbuf + inbuf_num, buf, num);
|
|
|
|
inbuf_num += num;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE))
|
|
|
|
_ecore_con_client_flush(cl);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_ecore_con_server_flush(Ecore_Con_Server *svr)
|
|
|
|
{
|
2008-12-15 09:59:19 -08:00
|
|
|
int count, num;
|
2003-09-23 01:09:32 -07:00
|
|
|
|
2004-04-03 07:03:33 -08:00
|
|
|
if (!svr->write_buf) return;
|
2004-04-02 10:32:55 -08:00
|
|
|
|
|
|
|
/* check whether we need to write anything at all.
|
2008-10-09 05:30:19 -07:00
|
|
|
* we must not write zero bytes with SSL_write() since it
|
|
|
|
* causes undefined behaviour
|
|
|
|
*/
|
2004-04-03 07:03:33 -08:00
|
|
|
if (svr->write_buf_size == svr->write_buf_offset)
|
2004-04-02 10:32:55 -08:00
|
|
|
return;
|
2007-08-26 04:17:21 -07:00
|
|
|
|
2004-04-03 07:03:33 -08:00
|
|
|
num = svr->write_buf_size - svr->write_buf_offset;
|
2007-08-26 04:17:21 -07:00
|
|
|
|
2008-10-30 08:26:11 -07:00
|
|
|
if (!(svr->type & ECORE_CON_SSL))
|
|
|
|
count = write(svr->fd, svr->write_buf + svr->write_buf_offset, num);
|
|
|
|
else
|
|
|
|
count = ecore_con_ssl_server_write(svr, svr->write_buf + svr->write_buf_offset, num);
|
|
|
|
if (count < 0)
|
2004-04-14 01:51:19 -07:00
|
|
|
{
|
|
|
|
/* we lost our server! */
|
2004-04-25 08:42:57 -07:00
|
|
|
kill_server(svr);
|
2004-04-14 01:51:19 -07:00
|
|
|
return;
|
|
|
|
}
|
2004-04-02 10:32:55 -08:00
|
|
|
|
2004-04-03 07:03:33 -08:00
|
|
|
svr->write_buf_offset += count;
|
|
|
|
if (svr->write_buf_offset >= svr->write_buf_size)
|
2003-09-23 01:09:32 -07:00
|
|
|
{
|
2004-04-03 07:03:33 -08:00
|
|
|
svr->write_buf_size = 0;
|
|
|
|
svr->write_buf_offset = 0;
|
|
|
|
free(svr->write_buf);
|
|
|
|
svr->write_buf = NULL;
|
2006-06-02 00:24:04 -07:00
|
|
|
if (svr->fd_handler)
|
|
|
|
ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
|
2003-09-23 01:09:32 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_ecore_con_client_flush(Ecore_Con_Client *cl)
|
|
|
|
{
|
|
|
|
int count, num;
|
|
|
|
|
|
|
|
if (!cl->buf) return;
|
|
|
|
num = cl->buf_size - cl->buf_offset;
|
2008-10-30 08:26:11 -07:00
|
|
|
if (!(cl->server->type & ECORE_CON_SSL))
|
|
|
|
count = write(cl->fd, cl->buf + cl->buf_offset, num);
|
|
|
|
else
|
|
|
|
count = ecore_con_ssl_client_write(cl, cl->buf + cl->buf_offset, num);
|
2010-06-07 06:05:49 -07:00
|
|
|
if (count < 0)
|
2003-09-23 01:09:32 -07:00
|
|
|
{
|
|
|
|
if ((errno == EIO) || (errno == EBADF) || (errno == EPIPE) ||
|
2010-06-07 06:05:49 -07:00
|
|
|
(errno == EINVAL) || (errno == ENOSPC) || (errno == ECONNREFUSED))
|
2003-09-23 01:09:32 -07:00
|
|
|
{
|
2006-06-02 00:24:04 -07:00
|
|
|
if (!cl->delete_me)
|
2003-09-23 01:09:32 -07:00
|
|
|
{
|
2006-06-02 00:24:04 -07:00
|
|
|
/* we lost our client! */
|
|
|
|
Ecore_Con_Event_Client_Del *e;
|
2007-08-26 04:17:21 -07:00
|
|
|
|
2006-06-02 00:24:04 -07:00
|
|
|
e = calloc(1, sizeof(Ecore_Con_Event_Client_Del));
|
|
|
|
if (e)
|
|
|
|
{
|
|
|
|
cl->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;
|
2003-09-23 01:09:32 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
cl->buf_offset += count;
|
|
|
|
if (cl->buf_offset >= cl->buf_size)
|
|
|
|
{
|
|
|
|
cl->buf_size = 0;
|
|
|
|
cl->buf_offset = 0;
|
|
|
|
free(cl->buf);
|
|
|
|
cl->buf = NULL;
|
2006-06-02 00:24:04 -07:00
|
|
|
if (cl->fd_handler)
|
|
|
|
ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ);
|
2003-09-23 01:09:32 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-03-19 21:53:12 -08:00
|
|
|
static void
|
|
|
|
_ecore_con_event_client_add_free(void *data __UNUSED__, void *ev)
|
|
|
|
{
|
|
|
|
Ecore_Con_Event_Client_Add *e;
|
|
|
|
|
|
|
|
e = ev;
|
|
|
|
e->client->event_count--;
|
|
|
|
if ((e->client->event_count == 0) && (e->client->delete_me))
|
|
|
|
ecore_con_client_del(e->client);
|
|
|
|
free(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_ecore_con_event_client_del_free(void *data __UNUSED__, void *ev)
|
|
|
|
{
|
|
|
|
Ecore_Con_Event_Client_Del *e;
|
|
|
|
|
|
|
|
e = ev;
|
|
|
|
e->client->event_count--;
|
|
|
|
if ((e->client->event_count == 0) && (e->client->delete_me))
|
|
|
|
ecore_con_client_del(e->client);
|
|
|
|
free(e);
|
|
|
|
}
|
|
|
|
|
2003-09-23 01:09:32 -07:00
|
|
|
static void
|
2005-03-01 23:06:44 -08:00
|
|
|
_ecore_con_event_client_data_free(void *data __UNUSED__, void *ev)
|
2003-09-23 01:09:32 -07:00
|
|
|
{
|
|
|
|
Ecore_Con_Event_Client_Data *e;
|
|
|
|
|
|
|
|
e = ev;
|
2006-03-19 21:53:12 -08:00
|
|
|
e->client->event_count--;
|
2003-09-23 01:09:32 -07:00
|
|
|
if (e->data) free(e->data);
|
2008-10-26 09:32:45 -07:00
|
|
|
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))))
|
2006-03-19 21:53:12 -08:00
|
|
|
ecore_con_client_del(e->client);
|
|
|
|
free(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_ecore_con_event_server_add_free(void *data __UNUSED__, void *ev)
|
|
|
|
{
|
|
|
|
Ecore_Con_Event_Server_Add *e;
|
|
|
|
|
|
|
|
e = ev;
|
|
|
|
e->server->event_count--;
|
|
|
|
if ((e->server->event_count == 0) && (e->server->delete_me))
|
2009-05-02 13:12:41 -07:00
|
|
|
_ecore_con_server_free(e->server);
|
2006-03-19 21:53:12 -08:00
|
|
|
free(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_ecore_con_event_server_del_free(void *data __UNUSED__, void *ev)
|
|
|
|
{
|
|
|
|
Ecore_Con_Event_Server_Del *e;
|
|
|
|
|
|
|
|
e = ev;
|
|
|
|
e->server->event_count--;
|
|
|
|
if ((e->server->event_count == 0) && (e->server->delete_me))
|
2009-05-02 13:12:41 -07:00
|
|
|
_ecore_con_server_free(e->server);
|
2003-09-23 01:09:32 -07:00
|
|
|
free(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2005-03-01 23:06:44 -08:00
|
|
|
_ecore_con_event_server_data_free(void *data __UNUSED__, void *ev)
|
2003-09-23 01:09:32 -07:00
|
|
|
{
|
|
|
|
Ecore_Con_Event_Server_Data *e;
|
|
|
|
|
|
|
|
e = ev;
|
2006-03-19 21:53:12 -08:00
|
|
|
e->server->event_count--;
|
2003-09-23 01:09:32 -07:00
|
|
|
if (e->data) free(e->data);
|
2006-03-19 21:53:12 -08:00
|
|
|
if ((e->server->event_count == 0) && (e->server->delete_me))
|
2009-05-02 13:12:41 -07:00
|
|
|
_ecore_con_server_free(e->server);
|
2003-09-23 01:09:32 -07:00
|
|
|
free(e);
|
|
|
|
}
|