summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGustavo Sverzut Barbieri <barbieri@profusion.mobi>2016-12-07 13:34:28 -0200
committerGustavo Sverzut Barbieri <barbieri@profusion.mobi>2016-12-09 14:16:02 -0200
commit0d897e75bd15432418fb478525d1129b705dbe28 (patch)
treeb396bb4a2592fd3309844061e06e124a8e83f772
parentbf5a35cee908eca27d0039b6bac5670039a1365c (diff)
ecore_con: Ecore_Con_Server now on top of Efl_Net!devs/barbieri/jenkins
This is a major work and unfortunately couldn't be split into smaller pieces as old code was highly coupled. Ecore_Con_Server is now a wrapper around Efl_Net_Dialer_Simple (ecore_con_server_connect()) and Efl_Net_Server_Simple (ecore_con_server_add()), doing all that the original version did with some fixes so ecore_con_ssl_server_upgrade() and ecore_con_ssl_client_upgrade() are more usable -- see the examples and -t/--type=tcp+ssl. I tried to be bug-compatible, with code annotations where things doesn't make sense. This was based on ecore_con_suite tests and some manual experimenting with the examples, these can be helpful if you find regressions (report/assign to me).
-rw-r--r--src/Makefile_Ecore_Con.am8
-rw-r--r--src/lib/ecore_con/Ecore_Con.h130
-rw-r--r--src/lib/ecore_con/Ecore_Con_Eo.h5
-rw-r--r--src/lib/ecore_con/Ecore_Con_Legacy.h29
-rw-r--r--src/lib/ecore_con/ecore_con.c2862
-rw-r--r--src/lib/ecore_con/ecore_con_alloc.c4
-rw-r--r--src/lib/ecore_con/ecore_con_eet.c5
-rw-r--r--src/lib/ecore_con/ecore_con_eet_base.eo5
-rw-r--r--src/lib/ecore_con/ecore_con_info.c297
-rw-r--r--src/lib/ecore_con/ecore_con_legacy.c2507
-rw-r--r--src/lib/ecore_con/ecore_con_local.c287
-rw-r--r--src/lib/ecore_con/ecore_con_private.h283
-rw-r--r--src/lib/ecore_con/ecore_con_socks.c488
-rw-r--r--src/lib/ecore_con/ecore_con_ssl.c1963
-rw-r--r--src/lib/ecore_con/efl_network.eo201
-rw-r--r--src/lib/ecore_con/efl_network_client.eo30
-rw-r--r--src/lib/ecore_con/efl_network_connector.eo8
-rw-r--r--src/lib/ecore_con/efl_network_server.eo93
18 files changed, 2652 insertions, 6553 deletions
diff --git a/src/Makefile_Ecore_Con.am b/src/Makefile_Ecore_Con.am
index c3e51ae441..4b1a55e36c 100644
--- a/src/Makefile_Ecore_Con.am
+++ b/src/Makefile_Ecore_Con.am
@@ -2,10 +2,6 @@
2### Library 2### Library
3 3
4ecore_con_eolian_files = \ 4ecore_con_eolian_files = \
5 lib/ecore_con/efl_network.eo \
6 lib/ecore_con/efl_network_client.eo \
7 lib/ecore_con/efl_network_server.eo \
8 lib/ecore_con/efl_network_connector.eo \
9 lib/ecore_con/efl_net_socket.eo \ 5 lib/ecore_con/efl_net_socket.eo \
10 lib/ecore_con/efl_net_socket_simple.eo \ 6 lib/ecore_con/efl_net_socket_simple.eo \
11 lib/ecore_con/efl_net_socket_fd.eo \ 7 lib/ecore_con/efl_net_socket_fd.eo \
@@ -71,7 +67,6 @@ lib_LTLIBRARIES += lib/ecore_con/libecore_con.la
71installed_ecoreconmainheadersdir = $(includedir)/ecore-con-@VMAJ@ 67installed_ecoreconmainheadersdir = $(includedir)/ecore-con-@VMAJ@
72dist_installed_ecoreconmainheaders_DATA = \ 68dist_installed_ecoreconmainheaders_DATA = \
73lib/ecore_con/Ecore_Con.h \ 69lib/ecore_con/Ecore_Con.h \
74lib/ecore_con/Ecore_Con_Legacy.h \
75lib/ecore_con/Ecore_Con_Eo.h \ 70lib/ecore_con/Ecore_Con_Eo.h \
76lib/ecore_con/Ecore_Con_Eet.h \ 71lib/ecore_con/Ecore_Con_Eet.h \
77lib/ecore_con/Ecore_Con_Eet_Legacy.h \ 72lib/ecore_con/Ecore_Con_Eet_Legacy.h \
@@ -83,16 +78,15 @@ nodist_installed_ecoreconmainheaders_DATA = \
83lib_ecore_con_libecore_con_la_SOURCES = \ 78lib_ecore_con_libecore_con_la_SOURCES = \
84lib/ecore_con/ecore_con_alloc.c \ 79lib/ecore_con/ecore_con_alloc.c \
85lib/ecore_con/ecore_con.c \ 80lib/ecore_con/ecore_con.c \
81lib/ecore_con/ecore_con_legacy.c \
86lib/ecore_con/ecore_con_eet.c \ 82lib/ecore_con/ecore_con_eet.c \
87lib/ecore_con/ecore_con_socks.c \ 83lib/ecore_con/ecore_con_socks.c \
88lib/ecore_con/ecore_con_ssl.c \
89lib/ecore_con/ecore_con_url.c \ 84lib/ecore_con/ecore_con_url.c \
90lib/ecore_con/ecore_con_url_curl.c \ 85lib/ecore_con/ecore_con_url_curl.c \
91lib/ecore_con/ecore_con_url_curl.h \ 86lib/ecore_con/ecore_con_url_curl.h \
92static_libs/http-parser/http_parser.c \ 87static_libs/http-parser/http_parser.c \
93static_libs/http-parser/http_parser.h \ 88static_libs/http-parser/http_parser.h \
94lib/ecore_con/ecore_con_private.h \ 89lib/ecore_con/ecore_con_private.h \
95lib/ecore_con/ecore_con_info.c \
96lib/ecore_con/efl_net_socket.c \ 90lib/ecore_con/efl_net_socket.c \
97lib/ecore_con/efl_net_socket_simple.c \ 91lib/ecore_con/efl_net_socket_simple.c \
98lib/ecore_con/efl_net_socket_fd.c \ 92lib/ecore_con/efl_net_socket_fd.c \
diff --git a/src/lib/ecore_con/Ecore_Con.h b/src/lib/ecore_con/Ecore_Con.h
index 393b94c825..e8592f9580 100644
--- a/src/lib/ecore_con/Ecore_Con.h
+++ b/src/lib/ecore_con/Ecore_Con.h
@@ -227,7 +227,41 @@ extern "C" {
227#define ECORE_CON_USE_SSL ECORE_CON_USE_SSL2 227#define ECORE_CON_USE_SSL ECORE_CON_USE_SSL2
228#define ECORE_CON_REMOTE_SYSTEM ECORE_CON_REMOTE_TCP 228#define ECORE_CON_REMOTE_SYSTEM ECORE_CON_REMOTE_TCP
229 229
230typedef Eo Ecore_Con; 230/** Types for an ecore_con client/server object. A correct way to set this
231 * type is with an ECORE_CON_$TYPE, optionally OR'ed with an ECORE_CON_$USE if
232 * encryption is desired, and LOAD_CERT if the previously loaded certificate
233 * should be used.
234 *
235 * @ingroup Ecore_Con
236 */
237typedef enum
238{
239 ECORE_CON_LOCAL_USER = 0, /** Socket in "~/.ecore" */
240 ECORE_CON_LOCAL_SYSTEM = 1, /** Socket in /tmp */
241 ECORE_CON_LOCAL_ABSTRACT = 2, /** Abstract socket */
242 ECORE_CON_REMOTE_TCP = 3, /** Remote server using TCP */
243 ECORE_CON_REMOTE_MCAST = 4, /** Remote multicast UDP server (ecore_con_server_add() only) */
244 ECORE_CON_REMOTE_UDP = 5, /** Remote server using UDP */
245 ECORE_CON_REMOTE_BROADCAST = 6, /** Remote broadcast using UDP (ecore_con_server_connect() only) */
246 ECORE_CON_REMOTE_NODELAY = 7, /** Remote TCP connection sending packets
247 * immediately */
248 ECORE_CON_REMOTE_CORK = 8, /** Remote TCP connection sending data in large chunks
249 * Note: Only available on Linux
250 *
251 * @since 1.2 */
252 ECORE_CON_USE_SSL2 = 16 /* 1 << 4 */, /** Use SSL2: UNSUPPORTED. */
253 ECORE_CON_USE_SSL3 = 32 /* 1 << 5 */, /** Use SSL3: UNSUPPORTED. */
254 ECORE_CON_USE_TLS = 64 /* 1 << 6 */, /** Use TLS */
255 ECORE_CON_USE_MIXED = 96 /* Ecore.Con.Type.use_tls | Ecore.Con.Type.use_ssl3 */, /** Use both TLS and SSL3 */
256 ECORE_CON_LOAD_CERT = 128 /* 1 << 7 */, /** Attempt to use the loaded
257 * certificate */
258 ECORE_CON_NO_PROXY = 256 /* 1 << 8 */, /** Disable all types of proxy on the
259 * server Note: Only functional for
260 * clients
261 *
262 * @since 1.2 */
263 ECORE_CON_SOCKET_ACTIVATE = 512 /* 1 << 9 */
264} Ecore_Con_Type;
231 265
232/** 266/**
233 * @typedef Ecore_Con_Socks 267 * @typedef Ecore_Con_Socks
@@ -265,13 +299,38 @@ typedef void (*Ecore_Con_Dns_Cb)(const char *canonname,
265 299
266/** @} */ 300/** @} */
267 301
268#ifndef EFL_NOLEGACY_API_SUPPORT
269#include "Ecore_Con_Legacy.h"
270#endif
271#ifdef EFL_BETA_API_SUPPORT 302#ifdef EFL_BETA_API_SUPPORT
272#include "Ecore_Con_Eo.h" 303#include "Ecore_Con_Eo.h"
273#endif 304#endif
274 305
306/**
307 * @struct _Ecore_Con_Server
308 * Used to provide legacy ABI/ABI compatibility with non-Eo applications.
309 * @ingroup Ecore_Con_Server_Group
310 */
311struct _Ecore_Con_Server;
312
313/**
314 * @typedef Ecore_Con_Server
315 * Used to provide legacy API/ABI compatibility with non-Eo applications.
316 * @ingroup Ecore_Con_Server_Group
317 */
318typedef struct _Ecore_Con_Server Ecore_Con_Server;
319
320/**
321 * @struct _Ecore_Con_Client
322 * Used to provide legacy ABI/ABI compatibility with non-Eo applications.
323 * @ingroup Ecore_Con_Client_Group
324 */
325struct _Ecore_Con_Client;
326
327/**
328 * @typedef Ecore_Con_Client
329 * Used to provide legacy API/ABI compatibility with non-Eo applications.
330 * @ingroup Ecore_Con_Client_Group
331 */
332typedef struct _Ecore_Con_Client Ecore_Con_Client;
333
275 334
276/** 335/**
277 * @struct _Ecore_Con_Url 336 * @struct _Ecore_Con_Url
@@ -651,6 +710,26 @@ EAPI int ecore_con_init(void);
651EAPI int ecore_con_shutdown(void); 710EAPI int ecore_con_shutdown(void);
652 711
653/** 712/**
713 * @brief Do an asynchronous DNS lookup.
714 *
715 * This function performs a DNS lookup on the hostname specified by name, then
716 * calls done_cb with the result and the data given as parameter. The result
717 * will be given to the done_cb as follows:
718 *
719 * canonname - the canonical name of the address, ip - the resolved ip address,
720 * addr - a pointer to the socket address, addrlen - the length of the socket
721 * address, in bytes, data - the data pointer given as parameter.
722 *
723 * @param[in] name IP address or server name to translate.
724 * @param[in] done_cb Callback to notify when done.
725 * @param[in] data User data to be given to done_cb.
726 *
727 * @return @c true if the request did not fail to be set up, @c false
728 * otherwise.
729 */
730EAPI Eina_Bool ecore_con_lookup(const char *name, Ecore_Con_Dns_Cb done_cb, const void *data) EINA_ARG_NONNULL(1);
731
732/**
654 * @} 733 * @}
655 */ 734 */
656 735
@@ -1142,6 +1221,10 @@ EAPI char *ecore_con_local_path_new(Eina_Bool is_system, const char *name, int p
1142 * or changed with ecore_con_server_data_set(). 1221 * or changed with ecore_con_server_data_set().
1143 * 1222 *
1144 * @see ecore_con_local_path_new() 1223 * @see ecore_con_local_path_new()
1224 *
1225 * @note This API is deprecated and new code should use
1226 * #EFL_NET_SERVER_SIMPLE_CLASS.
1227 * See @li @ref efl_net_server_simple_example.c
1145 */ 1228 */
1146EAPI Ecore_Con_Server *ecore_con_server_add(Ecore_Con_Type type, 1229EAPI Ecore_Con_Server *ecore_con_server_add(Ecore_Con_Type type,
1147 const char *name, int port, 1230 const char *name, int port,
@@ -1194,6 +1277,10 @@ EAPI Ecore_Con_Server *ecore_con_server_add(Ecore_Con_Type type,
1194 * or changed with ecore_con_server_data_set(). 1277 * or changed with ecore_con_server_data_set().
1195 * 1278 *
1196 * @see ecore_con_local_path_new() 1279 * @see ecore_con_local_path_new()
1280 *
1281 * @note This API is deprecated and new code should use
1282 * #EFL_NET_DIALER_SIMPLE_CLASS.
1283 * See @li @ref efl_net_dialer_simple_example.c
1197 */ 1284 */
1198EAPI Ecore_Con_Server *ecore_con_server_connect(Ecore_Con_Type type, 1285EAPI Ecore_Con_Server *ecore_con_server_connect(Ecore_Con_Type type,
1199 const char *name, int port, 1286 const char *name, int port,
@@ -1211,6 +1298,18 @@ EAPI Ecore_Con_Server *ecore_con_server_connect(Ecore_Con_Type type,
1211EAPI void * ecore_con_server_del(Ecore_Con_Server *svr); 1298EAPI void * ecore_con_server_del(Ecore_Con_Server *svr);
1212 1299
1213/** 1300/**
1301 * @brief Retrieves the name of server.
1302 *
1303 * The name returned is the name used to connect on this server.
1304 *
1305 * @param svr The given server.
1306 * @return The name of the server.
1307 *
1308 * @ingroup Efl_Network_Server
1309 */
1310EAPI const char *ecore_con_server_name_get(const Ecore_Con_Server *svr);
1311
1312/**
1214 * @brief Retrieve the data associated with the given server. 1313 * @brief Retrieve the data associated with the given server.
1215 * 1314 *
1216 * @param svr The given server. 1315 * @param svr The given server.
@@ -1304,6 +1403,21 @@ EAPI int ecore_con_server_send(Ecore_Con_Server *svr,
1304EAPI void ecore_con_server_client_limit_set(Ecore_Con_Server *svr, 1403EAPI void ecore_con_server_client_limit_set(Ecore_Con_Server *svr,
1305 int client_limit, 1404 int client_limit,
1306 char reject_excess_clients); 1405 char reject_excess_clients);
1406
1407/**
1408 * @brief Retrieves the current list of clients.
1409 *
1410 * Each node in the returned list points to an @ref Efl_Network_Client. This
1411 * list cannot be modified or freed. It can also change if new clients are
1412 * connected or disconnected, and will become invalid when the server is
1413 * deleted/freed.
1414 *
1415 * @param svr The given server.
1416 * @return The list of clients on this server.
1417 *
1418 */
1419EAPI const Eina_List *ecore_con_server_clients_get(const Ecore_Con_Server *svr);
1420
1307/** 1421/**
1308 * @brief Get the IP address of a server that has been connected to. 1422 * @brief Get the IP address of a server that has been connected to.
1309 * 1423 *
@@ -1532,7 +1646,13 @@ EAPI Eina_Bool ecore_con_client_connected_get(const Ecore_Con_Client *cl
1532 */ 1646 */
1533EAPI int ecore_con_client_port_get(const Ecore_Con_Client *cl); 1647EAPI int ecore_con_client_port_get(const Ecore_Con_Client *cl);
1534 1648
1535 1649/**
1650 * @brief The server the client is connected to.
1651 *
1652 * @param cl The client
1653 * @return The server the client is connected to.
1654 */
1655EAPI Ecore_Con_Server *ecore_con_client_server_get(const Ecore_Con_Client *cl);
1536 1656
1537/** 1657/**
1538 * @} 1658 * @}
diff --git a/src/lib/ecore_con/Ecore_Con_Eo.h b/src/lib/ecore_con/Ecore_Con_Eo.h
index e919d4ccb9..76c6d304ec 100644
--- a/src/lib/ecore_con/Ecore_Con_Eo.h
+++ b/src/lib/ecore_con/Ecore_Con_Eo.h
@@ -1,8 +1,3 @@
1#include "efl_network.eo.h"
2#include "efl_network_server.eo.h"
3#include "efl_network_connector.eo.h"
4#include "efl_network_client.eo.h"
5
6#include "efl_net_socket.eo.h" 1#include "efl_net_socket.eo.h"
7#include "efl_net_dialer.eo.h" 2#include "efl_net_dialer.eo.h"
8#include "efl_net_server.eo.h" 3#include "efl_net_server.eo.h"
diff --git a/src/lib/ecore_con/Ecore_Con_Legacy.h b/src/lib/ecore_con/Ecore_Con_Legacy.h
deleted file mode 100644
index 1333eed935..0000000000
--- a/src/lib/ecore_con/Ecore_Con_Legacy.h
+++ /dev/null
@@ -1,29 +0,0 @@
1#ifndef _ECORE_CON_LEGACY_H
2#define _ECORE_CON_LEGACY_H
3#include <Eina.h>
4#include <Eo.h>
5
6#include "efl_network.eo.legacy.h"
7#include "efl_network_server.eo.legacy.h"
8#include "efl_network_connector.eo.legacy.h"
9#include "efl_network_client.eo.legacy.h"
10
11
12/********************************************************************
13 * ecore_con_base.eo.h
14 *******************************************************************/
15typedef Eo Ecore_Con_Base;
16
17
18/********************************************************************
19 * ecore_con_client.eo.h
20 *******************************************************************/
21typedef Eo Ecore_Con_Client;
22
23
24/********************************************************************
25 * ecore_con_server.eo.h
26 *******************************************************************/
27typedef Eo Ecore_Con_Server;
28
29#endif
diff --git a/src/lib/ecore_con/ecore_con.c b/src/lib/ecore_con/ecore_con.c
index e9dfd7621a..d603eae052 100644
--- a/src/lib/ecore_con/ecore_con.c
+++ b/src/lib/ecore_con/ecore_con.c
@@ -51,134 +51,11 @@
51#define MSG_NOSIGNAL 0 /* noop */ 51#define MSG_NOSIGNAL 0 /* noop */
52#endif 52#endif
53 53
54static Eina_Bool _ecore_con_client_timer(Ecore_Con_Client *cl);
55static void _ecore_con_cl_timer_update(Ecore_Con_Client *cl);
56static Eina_Bool _ecore_con_server_timer(Ecore_Con_Server *svr);
57static void _ecore_con_server_timer_update(Ecore_Con_Server *svr);
58
59static void _ecore_con_cb_tcp_connect(void *data,
60 Ecore_Con_Info *info);
61static void _ecore_con_cb_udp_connect(void *data,
62 Ecore_Con_Info *info);
63static void _ecore_con_cb_tcp_listen(void *data,
64 Ecore_Con_Info *info);
65static void _ecore_con_cb_udp_listen(void *data,
66 Ecore_Con_Info *info);
67
68static void _ecore_con_server_free(Ecore_Con_Server *svr);
69static void _ecore_con_client_free(Ecore_Con_Client *cl);
70
71static void _ecore_con_cl_read(Ecore_Con_Server *svr);
72static Eina_Bool _ecore_con_svr_tcp_handler(void *data,
73 Ecore_Fd_Handler *fd_handler);
74static Eina_Bool _ecore_con_cl_handler(void *data,
75 Ecore_Fd_Handler *fd_handler);
76static Eina_Bool _ecore_con_cl_udp_handler(void *data,
77 Ecore_Fd_Handler *fd_handler);
78static Eina_Bool _ecore_con_svr_udp_handler(void *data,
79 Ecore_Fd_Handler *fd_handler);
80
81static void _ecore_con_svr_cl_read(Ecore_Con_Client *cl);
82static Eina_Bool _ecore_con_svr_cl_handler(void *data,
83 Ecore_Fd_Handler *fd_handler);
84
85static void _ecore_con_server_flush(Ecore_Con_Server *svr);
86static void _ecore_con_client_flush(Ecore_Con_Client *obj);
87
88static void _ecore_con_event_client_add_free(Ecore_Con_Server *svr,
89 void *ev);
90static void _ecore_con_event_client_del_free(Ecore_Con_Server *svr,
91 void *ev);
92static void _ecore_con_event_client_data_free(Ecore_Con_Server *svr,
93 void *ev);
94static void _ecore_con_event_server_add_free(void *data,
95 void *ev);
96static void _ecore_con_event_server_del_free(void *data,
97 void *ev);
98static void _ecore_con_event_server_data_free(void *data,
99 void *ev);
100static void _ecore_con_event_server_error_free(void *data,
101 Ecore_Con_Event_Server_Error *e);
102static void _ecore_con_event_client_error_free(Ecore_Con_Server *svr,
103 Ecore_Con_Event_Client_Error *e);
104static void _ecore_con_event_server_write_free(void *data,
105 Ecore_Con_Event_Server_Write *e);
106static void _ecore_con_event_client_write_free(Ecore_Con_Server *svr,
107 Ecore_Con_Event_Client_Write *e);
108
109static void _ecore_con_lookup_done(void *data,
110 Ecore_Con_Info *infos);
111
112static const char *_ecore_con_pretty_ip(struct sockaddr *client_addr);
113
114#define EO_CONSTRUCTOR_CHECK_RETURN(obj) do { \
115 if (efl_finalized_get(obj)) \
116 { \
117 ERR("This function is only allowed during construction."); \
118 return; \
119 } \
120} while (0)
121
122#ifdef HAVE_SYSTEMD 54#ifdef HAVE_SYSTEMD
123int sd_fd_index = 0; 55int sd_fd_index = 0;
124int sd_fd_max = 0; 56int sd_fd_max = 0;
125#endif 57#endif
126 58
127void
128_ecore_con_client_kill(Ecore_Con_Client *obj)
129{
130 Efl_Network_Client_Data *cl = efl_data_scope_get(obj, EFL_NETWORK_CLIENT_CLASS);
131 if (cl->delete_me)
132 DBG("Multi kill request for client %p", cl);
133 else
134 {
135 ecore_con_event_client_del(obj);
136 if (cl->buf) return;
137 }
138 INF("Lost client %s", (cl->ip) ? cl->ip : "");
139 if (cl->fd_handler)
140 ecore_main_fd_handler_del(cl->fd_handler);
141
142 cl->fd_handler = NULL;
143}
144
145void
146_ecore_con_server_kill(Ecore_Con_Server *obj)
147{
148 Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
149 if (svr->delete_me)
150 DBG("Multi kill request for svr %p", svr);
151 else
152 ecore_con_event_server_del(obj);
153
154 if (svr->fd_handler)
155 ecore_main_fd_handler_del(svr->fd_handler);
156
157 svr->fd_handler = NULL;
158}
159
160#define _ecore_con_server_kill(svr) do { \
161 DBG("KILL %p", (svr)); \
162 _ecore_con_server_kill((svr)); \
163 } while (0)
164
165#define _ecore_con_client_kill(cl) do { \
166 DBG("KILL %p", (cl)); \
167 _ecore_con_client_kill((cl)); \
168 } while (0)
169
170EAPI int ECORE_CON_EVENT_CLIENT_ADD = 0;
171EAPI int ECORE_CON_EVENT_CLIENT_DEL = 0;
172EAPI int ECORE_CON_EVENT_SERVER_ADD = 0;
173EAPI int ECORE_CON_EVENT_SERVER_DEL = 0;
174EAPI int ECORE_CON_EVENT_CLIENT_DATA = 0;
175EAPI int ECORE_CON_EVENT_SERVER_DATA = 0;
176EAPI int ECORE_CON_EVENT_CLIENT_WRITE = 0;
177EAPI int ECORE_CON_EVENT_SERVER_WRITE = 0;
178EAPI int ECORE_CON_EVENT_CLIENT_ERROR = 0;
179EAPI int ECORE_CON_EVENT_SERVER_ERROR = 0;
180EAPI int ECORE_CON_EVENT_PROXY_BIND = 0;
181
182EWAPI Eina_Error EFL_NET_DIALER_ERROR_COULDNT_CONNECT = 0; 59EWAPI Eina_Error EFL_NET_DIALER_ERROR_COULDNT_CONNECT = 0;
183EWAPI Eina_Error EFL_NET_DIALER_ERROR_COULDNT_RESOLVE_PROXY = 0; 60EWAPI Eina_Error EFL_NET_DIALER_ERROR_COULDNT_RESOLVE_PROXY = 0;
184EWAPI Eina_Error EFL_NET_DIALER_ERROR_COULDNT_RESOLVE_HOST = 0; 61EWAPI Eina_Error EFL_NET_DIALER_ERROR_COULDNT_RESOLVE_HOST = 0;
@@ -189,12 +66,8 @@ EWAPI Eina_Error EFL_NET_SERVER_ERROR_COULDNT_RESOLVE_HOST = 0;
189EWAPI Eina_Error EFL_NET_SOCKET_SSL_ERROR_HANDSHAKE = 0; 66EWAPI Eina_Error EFL_NET_SOCKET_SSL_ERROR_HANDSHAKE = 0;
190EWAPI Eina_Error EFL_NET_SOCKET_SSL_ERROR_CERTIFICATE_VERIFY_FAILED = 0; 67EWAPI Eina_Error EFL_NET_SOCKET_SSL_ERROR_CERTIFICATE_VERIFY_FAILED = 0;
191 68
192static Eina_List *servers = NULL;
193static int _ecore_con_init_count = 0; 69static int _ecore_con_init_count = 0;
194static int _ecore_con_event_count = 0;
195int _ecore_con_log_dom = -1; 70int _ecore_con_log_dom = -1;
196Ecore_Con_Socks *_ecore_con_proxy_once = NULL;
197Ecore_Con_Socks *_ecore_con_proxy_global = NULL;
198 71
199typedef struct pxProxyFactory_ pxProxyFactory; 72typedef struct pxProxyFactory_ pxProxyFactory;
200typedef struct _Ecore_Con_Libproxy { 73typedef struct _Ecore_Con_Libproxy {
@@ -226,18 +99,7 @@ ecore_con_init(void)
226 goto ecore_con_log_error; 99 goto ecore_con_log_error;
227 100
228 ecore_con_mempool_init(); 101 ecore_con_mempool_init();
229 102 ecore_con_legacy_init();
230 ECORE_CON_EVENT_CLIENT_ADD = ecore_event_type_new();
231 ECORE_CON_EVENT_CLIENT_DEL = ecore_event_type_new();
232 ECORE_CON_EVENT_SERVER_ADD = ecore_event_type_new();
233 ECORE_CON_EVENT_SERVER_DEL = ecore_event_type_new();
234 ECORE_CON_EVENT_CLIENT_DATA = ecore_event_type_new();
235 ECORE_CON_EVENT_SERVER_DATA = ecore_event_type_new();
236 ECORE_CON_EVENT_CLIENT_WRITE = ecore_event_type_new();
237 ECORE_CON_EVENT_SERVER_WRITE = ecore_event_type_new();
238 ECORE_CON_EVENT_CLIENT_ERROR = ecore_event_type_new();
239 ECORE_CON_EVENT_SERVER_ERROR = ecore_event_type_new();
240 ECORE_CON_EVENT_PROXY_BIND = ecore_event_type_new();
241 103
242 EFL_NET_DIALER_ERROR_COULDNT_CONNECT = eina_error_msg_static_register("Couldn't connect to server"); 104 EFL_NET_DIALER_ERROR_COULDNT_CONNECT = eina_error_msg_static_register("Couldn't connect to server");
243 EFL_NET_DIALER_ERROR_COULDNT_RESOLVE_PROXY = eina_error_msg_static_register("Couldn't resolve proxy name"); 105 EFL_NET_DIALER_ERROR_COULDNT_RESOLVE_PROXY = eina_error_msg_static_register("Couldn't resolve proxy name");
@@ -249,16 +111,6 @@ ecore_con_init(void)
249 EFL_NET_SOCKET_SSL_ERROR_HANDSHAKE = eina_error_msg_static_register("Failed SSL handshake"); 111 EFL_NET_SOCKET_SSL_ERROR_HANDSHAKE = eina_error_msg_static_register("Failed SSL handshake");
250 EFL_NET_SOCKET_SSL_ERROR_CERTIFICATE_VERIFY_FAILED = eina_error_msg_static_register("Failed to verify peer's certificate"); 112 EFL_NET_SOCKET_SSL_ERROR_CERTIFICATE_VERIFY_FAILED = eina_error_msg_static_register("Failed to verify peer's certificate");
251 113
252 eina_magic_string_set(ECORE_MAGIC_CON_SERVER, "Ecore_Con_Server");
253 eina_magic_string_set(ECORE_MAGIC_CON_CLIENT, "Ecore_Con_Client");
254 eina_magic_string_set(ECORE_MAGIC_CON_URL, "Ecore_Con_Url");
255
256 /* TODO Remember return value, if it fails, use gethostbyname() */
257 ecore_con_socks_init();
258 ecore_con_ssl_init();
259 ecore_con_info_init();
260 ecore_con_local_init();
261
262#ifdef HAVE_SYSTEMD 114#ifdef HAVE_SYSTEMD
263 sd_fd_max = sd_listen_fds(0); 115 sd_fd_max = sd_listen_fds(0);
264#endif 116#endif
@@ -283,9 +135,6 @@ ecore_err:
283EAPI int 135EAPI int
284ecore_con_shutdown(void) 136ecore_con_shutdown(void)
285{ 137{
286 Eina_List *l, *l2;
287 Ecore_Con_Server *obj;
288
289 /* _ecore_con_init_count should not go below zero. */ 138 /* _ecore_con_init_count should not go below zero. */
290 if (_ecore_con_init_count < 1) 139 if (_ecore_con_init_count < 1)
291 { 140 {
@@ -310,26 +159,8 @@ ecore_con_shutdown(void)
310 EINA_LOG_STATE_START, 159 EINA_LOG_STATE_START,
311 EINA_LOG_STATE_SHUTDOWN); 160 EINA_LOG_STATE_SHUTDOWN);
312 161
313 EINA_LIST_FOREACH_SAFE(servers, l, l2, obj) 162 ecore_con_legacy_shutdown();
314 {
315 Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
316 Ecore_Con_Event_Server_Add *ev;
317
318 if (!svr) continue;
319 svr->delete_me = EINA_TRUE;
320 INF("svr %p is dead", svr);
321 /* some pointer hacks here to prevent double frees if people are being stupid */
322 EINA_LIST_FREE(svr->event_count, ev)
323 ev->server = NULL;
324 _ecore_con_server_free(obj);
325 }
326
327 ecore_con_socks_shutdown();
328 if (!_ecore_con_event_count) ecore_con_mempool_shutdown();
329 163
330 ecore_con_local_shutdown();
331 ecore_con_info_shutdown();
332 ecore_con_ssl_shutdown();
333 eina_log_domain_unregister(_ecore_con_log_dom); 164 eina_log_domain_unregister(_ecore_con_log_dom);
334 _ecore_con_log_dom = -1; 165 _ecore_con_log_dom = -1;
335 ecore_shutdown(); 166 ecore_shutdown();
@@ -340,2695 +171,18 @@ ecore_con_shutdown(void)
340 return _ecore_con_init_count; 171 return _ecore_con_init_count;
341} 172}
342 173
343EOLIAN static Eina_Bool
344_efl_network_lookup(Eo *kls_obj EINA_UNUSED, void *pd EINA_UNUSED, const char *name, Ecore_Con_Dns_Cb done_cb, const void *data)
345{
346 Ecore_Con_Server *obj;
347 Ecore_Con_Lookup *lk;
348 struct addrinfo hints;
349
350 if (!name || !done_cb)
351 return EINA_FALSE;
352
353 obj = efl_add(EFL_NETWORK_CONNECTOR_CLASS, NULL, efl_network_server_connection_type_set(efl_added, ECORE_CON_REMOTE_TCP), efl_network_server_name_set(efl_added, name), efl_network_port_set(efl_added, 1025));
354
355 lk = malloc(sizeof (Ecore_Con_Lookup));
356 if (!lk)
357 {
358 return EINA_FALSE;
359 }
360
361 lk->done_cb = done_cb;
362 lk->data = data;
363
364 ecore_con_server_data_set(obj, lk);
365
366 memset(&hints, 0, sizeof(struct addrinfo));
367 hints.ai_family = AF_UNSPEC;
368 hints.ai_socktype = SOCK_STREAM;
369 hints.ai_flags = AI_CANONNAME;
370 hints.ai_protocol = IPPROTO_TCP;
371 hints.ai_canonname = NULL;
372 hints.ai_next = NULL;
373 hints.ai_addr = NULL;
374
375 if (ecore_con_info_get(obj, _ecore_con_lookup_done, obj,
376 &hints))
377 return EINA_TRUE;
378
379 free(lk);
380 efl_del(obj);
381 return EINA_FALSE;
382}
383
384/**
385 * @addtogroup Ecore_Con_Server_Group Ecore Connection Server Functions
386 *
387 * Functions that operate on Ecore server objects.
388 *
389 * @{
390 */
391
392/**
393 * @example ecore_con_server_example.c
394 * Shows how to write a simple server using the Ecore_Con library.
395 */
396
397EAPI Ecore_Con_Server *
398ecore_con_server_add(Ecore_Con_Type compl_type,
399 const char *name,
400 int port,
401 const void *data)
402{
403 Ecore_Con_Server *obj;
404
405 /* local system socket: FILE: /tmp/.ecore_service|[name]|[port] */
406 /* remote system socket: TCP/IP: [name]:[port] */
407 obj = efl_add(EFL_NETWORK_SERVER_CLASS, NULL, efl_network_server_connection_type_set(efl_added, compl_type), efl_network_server_name_set(efl_added, name), efl_network_port_set(efl_added, port));
408
409 ecore_con_server_data_set(obj, (void *) data);
410
411 return obj;
412}
413
414EOLIAN static Eo *
415_efl_network_server_efl_object_constructor(Ecore_Con_Server *obj, Efl_Network_Server_Data *svr)
416{
417 obj = efl_constructor(efl_super(obj, EFL_NETWORK_SERVER_CLASS));
418
419 svr->fd = INVALID_SOCKET;
420 svr->reject_excess_clients = EINA_FALSE;
421 svr->client_limit = -1;
422 svr->clients = NULL;
423
424 return obj;
425}
426
427EOLIAN static Eo *
428_efl_network_server_efl_object_finalize(Ecore_Con_Server *obj, Efl_Network_Server_Data *svr)
429{
430 Ecore_Con_Type compl_type = svr->type;
431 Ecore_Con_Type type;
432
433 efl_finalize(efl_super(obj, EFL_NETWORK_SERVER_CLASS));
434
435 svr->created = EINA_TRUE;
436 svr->ppid = getpid();
437 svr->start_time = ecore_time_get();
438 svr->use_cert = (svr->type & ECORE_CON_SSL & ECORE_CON_LOAD_CERT) == ECORE_CON_LOAD_CERT;
439
440 servers = eina_list_append(servers, obj);
441
442 if (!svr->name)
443 goto error;
444
445 type = compl_type & ECORE_CON_TYPE;
446
447 EINA_SAFETY_ON_TRUE_GOTO(((type == ECORE_CON_REMOTE_TCP) ||
448 (type == ECORE_CON_REMOTE_NODELAY) ||
449 (type == ECORE_CON_REMOTE_CORK) ||
450 (type == ECORE_CON_REMOTE_UDP) ||
451 (type == ECORE_CON_REMOTE_BROADCAST)) &&
452 (svr->port < 0), error);
453
454 if (ecore_con_ssl_server_prepare(obj, compl_type & ECORE_CON_SSL))
455 goto error;
456
457 if ((type == ECORE_CON_LOCAL_USER) ||
458 (type == ECORE_CON_LOCAL_SYSTEM) ||
459 (type == ECORE_CON_LOCAL_ABSTRACT))
460 /* Local */
461#ifdef _WIN32
462 if (!ecore_con_local_listen(obj))
463 goto error;
464#else
465 if (!ecore_con_local_listen(obj, _ecore_con_svr_tcp_handler, obj))
466 goto error;
467#endif
468
469 if ((type == ECORE_CON_REMOTE_TCP) ||
470 (type == ECORE_CON_REMOTE_NODELAY) ||
471 (type == ECORE_CON_REMOTE_CORK))
472 {
473 /* TCP */
474 if (!ecore_con_info_tcp_listen(obj, _ecore_con_cb_tcp_listen,
475 obj))
476 goto error;
477 }
478 else if ((type == ECORE_CON_REMOTE_MCAST) ||
479 (type == ECORE_CON_REMOTE_UDP))
480 /* UDP and MCAST */
481 if (!ecore_con_info_udp_listen(obj, _ecore_con_cb_udp_listen,
482 obj))
483 goto error;
484
485 return obj;
486
487error:
488 if (svr->delete_me) return NULL;
489 _ecore_con_server_kill(obj);
490 return NULL;
491}
492
493EAPI Ecore_Con_Server *
494ecore_con_server_connect(Ecore_Con_Type compl_type,
495 const char *name,
496 int port,
497 const void *data)
498{
499 Ecore_Con_Server *obj;
500 /* local user socket: FILE: ~/.ecore/[name]/[port] */
501 /* local system socket: FILE: /tmp/.ecore_service|[name]|[port] */
502 /* remote system socket: TCP/IP: [name]:[port] */
503 obj = efl_add(EFL_NETWORK_CONNECTOR_CLASS, NULL, efl_network_server_connection_type_set(efl_added, compl_type), efl_network_server_name_set(efl_added, name), efl_network_port_set(efl_added, port));
504
505 ecore_con_server_data_set(obj, (void *) data);
506
507 return obj;
508}
509
510EOLIAN static Eo *
511_efl_network_connector_efl_object_finalize(Ecore_Con_Server *obj, void *pd EINA_UNUSED)
512{
513 Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
514 Ecore_Con_Type compl_type = svr->type;
515 Ecore_Con_Type type;
516
517 /* XXX: We intentionally put SERVER class here and not connector, as we'd
518 * like to skip that one. */
519 efl_finalize(efl_super(obj, EFL_NETWORK_SERVER_CLASS));
520
521 svr->use_cert = (compl_type & ECORE_CON_SSL & ECORE_CON_LOAD_CERT) == ECORE_CON_LOAD_CERT;
522 svr->disable_proxy = (compl_type & ECORE_CON_SUPER_SSL & ECORE_CON_NO_PROXY) == ECORE_CON_NO_PROXY;
523 servers = eina_list_append(servers, obj);
524
525 if (!svr->name || !(svr->name[0]))
526 goto error;
527
528 type = compl_type & ECORE_CON_TYPE;
529
530 if ((!svr->disable_proxy) && (type > ECORE_CON_LOCAL_ABSTRACT))
531 {
532 /* never use proxies on local connections */
533 if (_ecore_con_proxy_once)
534 svr->ecs = _ecore_con_proxy_once;
535 else if (_ecore_con_proxy_global)
536 svr->ecs = _ecore_con_proxy_global;
537 _ecore_con_proxy_once = NULL;
538 if (svr->ecs)
539 {
540 if ((!svr->ecs->lookup) &&
541 (!ecore_con_lookup(svr->name, (Ecore_Con_Dns_Cb)ecore_con_socks_dns_cb, svr)))
542 goto error;
543 if (svr->ecs->lookup)
544 svr->ecs_state = ECORE_CON_PROXY_STATE_RESOLVED;
545 }
546 }
547 EINA_SAFETY_ON_TRUE_GOTO(ecore_con_ssl_server_prepare(obj, compl_type & ECORE_CON_SSL), error);
548
549 EINA_SAFETY_ON_TRUE_GOTO(((type == ECORE_CON_REMOTE_TCP) ||
550 (type == ECORE_CON_REMOTE_NODELAY) ||
551 (type == ECORE_CON_REMOTE_CORK) ||
552 (type == ECORE_CON_REMOTE_UDP) ||
553 (type == ECORE_CON_REMOTE_BROADCAST)) &&
554 (svr->port < 0), error);
555
556 if ((type == ECORE_CON_LOCAL_USER) ||
557 (type == ECORE_CON_LOCAL_SYSTEM) ||
558 (type == ECORE_CON_LOCAL_ABSTRACT))
559 /* Local */
560#ifdef _WIN32
561 if (!ecore_con_local_connect(obj, _ecore_con_cl_handler)) goto error;
562#else
563 if (!ecore_con_local_connect(obj, _ecore_con_cl_handler, obj)) goto error;
564#endif
565
566 if ((type == ECORE_CON_REMOTE_TCP) ||
567 (type == ECORE_CON_REMOTE_NODELAY) ||
568 (type == ECORE_CON_REMOTE_CORK))
569 {
570 /* TCP */
571 EINA_SAFETY_ON_FALSE_GOTO(ecore_con_info_tcp_connect(obj, _ecore_con_cb_tcp_connect, obj), error);
572 }
573 else if ((type == ECORE_CON_REMOTE_UDP) || (type == ECORE_CON_REMOTE_BROADCAST))
574 /* UDP and MCAST */
575 EINA_SAFETY_ON_FALSE_GOTO(ecore_con_info_udp_connect(obj, _ecore_con_cb_udp_connect, obj), error);
576
577 return obj;
578
579error:
580 return NULL;
581}
582
583EAPI void
584ecore_con_server_timeout_set(Ecore_Con *obj, double timeout)
585{
586 efl_network_timeout_set((Ecore_Con *)obj, timeout);
587}
588
589EOLIAN static void
590_efl_network_server_efl_network_timeout_set(Eo *obj, Efl_Network_Server_Data *svr, double timeout)
591{
592 if (svr->created)
593 svr->client_disconnect_time = timeout;
594 else
595 svr->disconnect_time = timeout;
596
597 _ecore_con_server_timer_update(obj);
598}
599
600EAPI double
601ecore_con_server_timeout_get(const Ecore_Con *obj)
602{
603 return efl_network_timeout_get((Ecore_Con *)obj);
604}
605
606EOLIAN static double
607_efl_network_server_efl_network_timeout_get(Eo *obj EINA_UNUSED, Efl_Network_Server_Data *svr)
608{
609 return svr->created ? svr->client_disconnect_time : svr->disconnect_time;
610}
611
612EAPI void *
613ecore_con_server_del(Ecore_Con_Server *obj)
614{
615 if (!obj) return NULL;
616 Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
617
618 if (!svr || svr->delete_me)
619 return NULL;
620
621#ifdef _WIN32
622 WSASendDisconnect(svr->fd, NULL);
623#endif
624 _ecore_con_server_kill(obj);
625 return svr->data;
626}
627
628EAPI void *
629ecore_con_server_data_get(Ecore_Con_Server *obj)
630{
631 Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
632 if (!svr)
633 return NULL;
634
635 return svr->data;
636}
637
638EAPI void *
639ecore_con_server_data_set(Ecore_Con_Server *obj,
640 void *data)
641{
642 Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
643 void *ret = NULL;
644
645 if (!svr)
646 return NULL;
647
648 ret = svr->data;
649 svr->data = data;
650 return ret;
651}
652
653EAPI Eina_Bool
654ecore_con_server_connected_get(const Ecore_Con *obj)
655{
656 return efl_network_connected_get((Ecore_Con *)obj);
657}
658
659EOLIAN static Eina_Bool
660_efl_network_server_efl_network_connected_get(Eo *obj EINA_UNUSED, Efl_Network_Server_Data *svr)
661{
662 return !svr->connecting;
663}
664
665EOLIAN static const Eina_List *
666_efl_network_server_clients_get(Eo *obj EINA_UNUSED, Efl_Network_Server_Data *svr)
667{
668 return svr->clients;
669}
670
671EOLIAN static void
672_efl_network_server_connection_type_set(Eo *obj, Efl_Network_Server_Data *svr, Ecore_Con_Type type)
673{
674 EO_CONSTRUCTOR_CHECK_RETURN(obj);
675
676 svr->type = type;
677}
678
679EOLIAN static Ecore_Con_Type
680_efl_network_server_connection_type_get(Eo *obj EINA_UNUSED, Efl_Network_Server_Data *svr)
681{
682 return svr->type;
683}
684
685EOLIAN static void
686_efl_network_server_name_set(Eo *obj EINA_UNUSED, Efl_Network_Server_Data *svr, const char *name)
687{
688 EO_CONSTRUCTOR_CHECK_RETURN(obj);
689
690 if (svr->name)
691 free(svr->name);
692
693 svr->name = strdup(name);
694}
695
696EOLIAN static const char *
697_efl_network_server_name_get(Eo *obj EINA_UNUSED, Efl_Network_Server_Data *svr)
698{
699 return svr->name;
700}
701
702EAPI int
703ecore_con_server_port_get(const Ecore_Con *obj)
704{
705 return efl_network_port_get((Ecore_Con *)obj);
706}
707
708EOLIAN static void
709_efl_network_server_efl_network_port_set(Eo *obj EINA_UNUSED, Efl_Network_Server_Data *svr, int port)
710{
711 EO_CONSTRUCTOR_CHECK_RETURN(obj);
712
713 svr->port = port;
714}
715
716EOLIAN static int
717_efl_network_server_efl_network_port_get(Eo *obj EINA_UNUSED, Efl_Network_Server_Data *svr)
718{
719 return svr->port;
720}
721
722EAPI int
723ecore_con_server_send(Ecore_Con *obj, const void *data, int size)
724{
725 return efl_network_send((Ecore_Con *)obj, data, size);
726}
727
728EOLIAN static int
729_efl_network_server_efl_network_send(Eo *obj EINA_UNUSED, Efl_Network_Server_Data *svr, const void *data, int size)
730{
731 EINA_SAFETY_ON_TRUE_RETURN_VAL(svr->delete_me, 0);
732
733 EINA_SAFETY_ON_NULL_RETURN_VAL(data, 0);
734
735 EINA_SAFETY_ON_TRUE_RETURN_VAL(size < 1, 0);
736
737 if (svr->fd_handler)
738 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE);
739
740 if (!svr->buf)
741 {
742 svr->buf = eina_binbuf_new();
743 EINA_SAFETY_ON_NULL_RETURN_VAL(svr->buf, 0);
744#ifdef TCP_CORK
745 if ((svr->fd != INVALID_SOCKET) && ((svr->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_CORK))
746 {
747 int state = 1;
748 if (setsockopt(svr->fd, IPPROTO_TCP, TCP_CORK, (char *)&state, sizeof(int)) < 0)
749 /* realistically this isn't anything serious so we can just log and continue */
750 ERR("corking failed! %s", strerror(errno));
751 }
752#endif
753 }
754 if (!eina_binbuf_append_length(svr->buf, data, size))
755 ERR("eina_binbuf_append_length() failed");
756
757 return size;
758}
759
760EOLIAN static void
761_efl_network_server_client_limit_set(Eo *obj EINA_UNUSED, Efl_Network_Server_Data *svr,
762 int client_limit,
763 char reject_excess_clients)
764{
765 svr->client_limit = client_limit;
766 svr->reject_excess_clients = reject_excess_clients;
767}
768
769EOLIAN static void
770_efl_network_server_client_limit_get(Eo *obj EINA_UNUSED, Efl_Network_Server_Data *svr,
771 int *client_limit,
772 char *reject_excess_clients)
773{
774 if (client_limit) *client_limit = svr->client_limit;
775 if (reject_excess_clients) *reject_excess_clients = svr->reject_excess_clients;
776}
777
778EAPI const char *
779ecore_con_server_ip_get(const Ecore_Con *obj)
780{
781 return efl_network_ip_get(obj);
782}
783
784EOLIAN static const char *
785_efl_network_server_efl_network_ip_get(Eo *obj EINA_UNUSED, Efl_Network_Server_Data *svr)
786{
787 return svr->ip;
788}
789
790EAPI double
791ecore_con_server_uptime_get(const Ecore_Con *obj)
792{
793 return efl_network_uptime_get(obj);
794}
795
796EOLIAN static double
797_efl_network_server_efl_network_uptime_get(Eo *obj EINA_UNUSED, Efl_Network_Server_Data *svr)
798{
799 return ecore_time_get() - svr->start_time;
800}
801
802EAPI void
803ecore_con_server_flush(Ecore_Con *obj)
804{
805 efl_network_flush((Ecore_Con *)obj);
806}
807
808EOLIAN static void
809_efl_network_server_efl_network_flush(Eo *obj, Efl_Network_Server_Data *svr EINA_UNUSED)
810{
811 _ecore_con_server_flush(obj);
812}
813
814/**
815 * @}
816 */
817
818/**
819 * @addtogroup Ecore_Con_Client_Group Ecore Connection Client Functions
820 *
821 * Functions that operate on Ecore connection client objects.
822 *
823 * @{
824 */
825
826/**
827 * @example ecore_con_client_example.c
828 * Shows how to write a simple client that connects to the example server.
829 */
830
831EAPI int
832ecore_con_client_send(Ecore_Con *obj, const void *data, int size)
833{
834 return efl_network_send((Ecore_Con *)obj, data, size);
835}
836
837EOLIAN static int
838_efl_network_client_efl_network_send(Eo *obj EINA_UNUSED, Efl_Network_Client_Data *cl, const void *data, int size)
839{
840 Efl_Network_Server_Data *host_server = NULL;
841 EINA_SAFETY_ON_TRUE_RETURN_VAL(cl->delete_me, 0);
842
843 EINA_SAFETY_ON_NULL_RETURN_VAL(data, 0);
844
845 EINA_SAFETY_ON_TRUE_RETURN_VAL(size < 1, 0);
846
847 if (cl->fd_handler)
848 ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE);
849
850 if (cl->host_server)
851 host_server = efl_data_scope_get(cl->host_server, EFL_NETWORK_CLIENT_CLASS);
852
853
854 if (cl->host_server && ((host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_UDP))
855 {
856 int ret;
857
858 ret = (int)sendto(host_server->fd, data, size, 0,
859 (struct sockaddr *)cl->client_addr,
860 cl->client_addr_len);
861 return ret;
862 }
863 else
864 {
865 if (!cl->buf)
866 {
867 cl->buf = eina_binbuf_new();
868 EINA_SAFETY_ON_NULL_RETURN_VAL(cl->buf, 0);
869#ifdef TCP_CORK
870 if ((cl->fd != INVALID_SOCKET) && (host_server) &&
871 ((host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_CORK))
872 {
873 int state = 1;
874 if (setsockopt(cl->fd, IPPROTO_TCP, TCP_CORK, (char *)&state, sizeof(int)) < 0)
875 /* realistically this isn't anything serious so we can just log and continue */
876 ERR("corking failed! %s", strerror(errno));
877 }
878#endif
879 }
880 if (!eina_binbuf_append_length(cl->buf, data, size))
881 ERR("eina_binbuf_append_length() failed");
882 }
883 return size;
884}
885
886EOLIAN static Ecore_Con_Server *
887_efl_network_client_server_get(Eo *obj EINA_UNUSED, Efl_Network_Client_Data *cl)
888{
889 return cl->host_server;
890}
891
892EOLIAN static Eina_Bool
893_efl_network_client_efl_network_connected_get(Eo *obj EINA_UNUSED, Efl_Network_Client_Data *cl)
894{
895 return !cl->delete_me;
896}
897
898EAPI Eina_Bool
899ecore_con_client_connected_get(const Ecore_Con *obj)
900{
901 return efl_network_connected_get((Ecore_Con *)obj);
902}
903
904EOLIAN static void
905_efl_network_client_efl_network_timeout_set(Eo *obj, Efl_Network_Client_Data *cl, double timeout)
906{
907 cl->disconnect_time = timeout;
908
909 _ecore_con_cl_timer_update(obj);
910}
911
912EAPI void
913ecore_con_client_timeout_set(Ecore_Con *obj, double timeout)
914{
915 efl_network_timeout_set((Ecore_Con *)obj, timeout);
916}
917
918EOLIAN static double
919_efl_network_client_efl_network_timeout_get(Eo *obj EINA_UNUSED, Efl_Network_Client_Data *cl)
920{
921 return cl->disconnect_time;
922}
923
924EAPI double
925ecore_con_client_timeout_get(const Ecore_Con *obj)
926{
927 return efl_network_timeout_get((Ecore_Con *)obj);
928}
929
930EAPI void *
931ecore_con_client_del(Ecore_Con_Client *obj)
932{
933 if (!obj) return NULL;
934 Efl_Network_Client_Data *cl = efl_data_scope_get(obj, EFL_NETWORK_CLIENT_CLASS);
935 if (!cl) return NULL;
936
937#ifdef _WIN32
938 WSASendDisconnect(cl->fd, NULL);
939#endif
940
941 _ecore_con_client_kill(obj);
942 return cl->data;
943}
944
945EAPI void
946ecore_con_client_data_set(Ecore_Con_Client *obj,
947 const void *data)
948{
949 Efl_Network_Client_Data *cl = efl_data_scope_get(obj, EFL_NETWORK_CLIENT_CLASS);
950 if (!cl)
951 return;
952
953 cl->data = (void *)data;
954}
955
956EAPI void *
957ecore_con_client_data_get(Ecore_Con_Client *obj)
958{
959 Efl_Network_Client_Data *cl = efl_data_scope_get(obj, EFL_NETWORK_CLIENT_CLASS);
960 if (!cl)
961 return NULL;
962
963 return cl->data;
964}
965
966EOLIAN static const char *
967_efl_network_client_efl_network_ip_get(Eo *obj EINA_UNUSED, Efl_Network_Client_Data *cl)
968{
969 if (!cl->ip)
970 cl->ip = _ecore_con_pretty_ip(cl->client_addr);
971
972 return cl->ip;
973}
974
975EAPI const char *
976ecore_con_client_ip_get(const Ecore_Con *obj)
977{
978 return efl_network_ip_get(obj);
979}
980
981EOLIAN static int
982_efl_network_client_efl_network_port_get(Eo *obj EINA_UNUSED, Efl_Network_Client_Data *cl)
983{
984 Efl_Network_Server_Data *sd = efl_data_scope_get(cl->host_server, EFL_NETWORK_SERVER_CLASS);
985
986 if (sd->type != ECORE_CON_REMOTE_TCP &&
987 sd->type != ECORE_CON_REMOTE_MCAST &&
988 sd->type != ECORE_CON_REMOTE_UDP &&
989 sd->type != ECORE_CON_REMOTE_BROADCAST &&
990 sd->type != ECORE_CON_REMOTE_NODELAY)
991 return -1;
992
993 if (cl->client_addr->sa_family == AF_INET)
994 return ((struct sockaddr_in *)cl->client_addr)->sin_port;
995#ifdef HAVE_IPV6
996 return ((struct sockaddr_in6 *)cl->client_addr)->sin6_port;
997#else
998 return -1;
999#endif
1000}
1001
1002EAPI int
1003ecore_con_client_port_get(const Ecore_Con *obj)
1004{
1005 return efl_network_port_get((Ecore_Con *)obj);
1006}
1007
1008EOLIAN static double
1009_efl_network_client_efl_network_uptime_get(Eo *obj EINA_UNUSED, Efl_Network_Client_Data *cl)
1010{
1011 return ecore_time_get() - cl->start_time;
1012}
1013
1014EAPI double
1015ecore_con_client_uptime_get(const Ecore_Con *obj)
1016{
1017 return efl_network_uptime_get(obj);
1018}
1019
1020EOLIAN static void
1021_efl_network_client_efl_network_flush(Eo *obj, Efl_Network_Client_Data *cl EINA_UNUSED)
1022{
1023 _ecore_con_client_flush(obj);
1024}
1025
1026EAPI void
1027ecore_con_client_flush(Ecore_Con *obj)
1028{
1029 efl_network_flush((Ecore_Con *)obj);
1030}
1031
1032EAPI int 174EAPI int
1033ecore_con_server_fd_get(const Ecore_Con *obj) 175ecore_con_ssl_available_get(void)
1034{
1035 return efl_network_fd_get((Ecore_Con *)obj);
1036}
1037
1038EOLIAN static int
1039_efl_network_server_efl_network_fd_get(Eo *obj EINA_UNUSED, Efl_Network_Server_Data *svr)
1040{
1041 if (svr->created) return -1;
1042 if (svr->delete_me) return -1;
1043 return ecore_main_fd_handler_fd_get(svr->fd_handler);
1044}
1045
1046EOLIAN static int
1047_efl_network_client_efl_network_fd_get(Eo *obj EINA_UNUSED, Efl_Network_Client_Data *cl)
1048{
1049 return ecore_main_fd_handler_fd_get(cl->fd_handler);
1050}
1051
1052EAPI int
1053ecore_con_client_fd_get(const Ecore_Con *obj)
1054{
1055 return efl_network_fd_get((Ecore_Con *)obj);
1056}
1057
1058/**
1059 * @}
1060 */
1061
1062void
1063ecore_con_event_proxy_bind(Ecore_Con_Server *obj)
1064{
1065 Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
1066 Ecore_Con_Event_Proxy_Bind *e;
1067 int ev = ECORE_CON_EVENT_PROXY_BIND;
1068
1069 e = ecore_con_event_proxy_bind_alloc();
1070 EINA_SAFETY_ON_NULL_RETURN(e);
1071
1072 svr->event_count = eina_list_append(svr->event_count, e);
1073 _ecore_con_server_timer_update(obj);
1074 e->server = obj;
1075 e->ip = svr->proxyip;
1076 e->port = svr->proxyport;
1077 ecore_event_add(ev, e,
1078 _ecore_con_event_server_add_free, NULL);
1079 _ecore_con_event_count++;
1080}
1081
1082void
1083ecore_con_event_server_add(Ecore_Con_Server *obj)
1084{
1085 Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
1086 /* we got our server! */
1087 Ecore_Con_Event_Server_Add *e;
1088 int ev = ECORE_CON_EVENT_SERVER_ADD;
1089
1090 e = ecore_con_event_server_add_alloc();
1091 EINA_SAFETY_ON_NULL_RETURN(e);
1092
1093 svr->connecting = EINA_FALSE;
1094 svr->start_time = ecore_time_get();
1095 svr->event_count = eina_list_append(svr->event_count, e);
1096 _ecore_con_server_timer_update(obj);
1097 e->server = obj;
1098 if (svr->upgrade) ev = ECORE_CON_EVENT_SERVER_UPGRADE;
1099 ecore_event_add(ev, e,
1100 _ecore_con_event_server_add_free, NULL);
1101 efl_event_callback_call(obj, EFL_NETWORK_EVENT_CONNECTION_UPGRADED, NULL);
1102 _ecore_con_event_count++;
1103}
1104
1105void
1106ecore_con_event_server_del(Ecore_Con_Server *obj)
1107{ 176{
1108 Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS); 177#if HAVE_GNUTLS
1109 Ecore_Con_Event_Server_Del *e; 178 return 1;
1110 179#elif HAVE_OPENSSL
1111 svr->delete_me = EINA_TRUE; 180 return 2;
1112 INF("svr %p is dead", svr);
1113 e = ecore_con_event_server_del_alloc();
1114 EINA_SAFETY_ON_NULL_RETURN(e);
1115
1116 svr->event_count = eina_list_append(svr->event_count, e);
1117 _ecore_con_server_timer_update(obj);
1118 e->server = obj;
1119 if (svr->ecs)
1120 {
1121 svr->ecs_state = svr->ecs->lookup ? ECORE_CON_PROXY_STATE_RESOLVED : ECORE_CON_PROXY_STATE_DONE;
1122 eina_stringshare_replace(&svr->proxyip, NULL);
1123 svr->proxyport = 0;
1124 }
1125 ecore_event_add(ECORE_CON_EVENT_SERVER_DEL, e,
1126 _ecore_con_event_server_del_free, NULL);
1127 _ecore_con_event_count++;
1128}
1129
1130void
1131ecore_con_event_server_write(Ecore_Con_Server *obj, int num)
1132{
1133 Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
1134 Ecore_Con_Event_Server_Write *e;
1135
1136 e = ecore_con_event_server_write_alloc();
1137 EINA_SAFETY_ON_NULL_RETURN(e);
1138
1139 INF("Wrote %d bytes", num);
1140 svr->event_count = eina_list_append(svr->event_count, e);
1141 e->server = obj;
1142 e->size = num;
1143 ecore_event_add(ECORE_CON_EVENT_SERVER_WRITE, e,
1144 (Ecore_End_Cb)_ecore_con_event_server_write_free, NULL);
1145 _ecore_con_event_count++;
1146}
1147
1148void
1149ecore_con_event_server_data(Ecore_Con_Server *obj, unsigned char *buf, int num, Eina_Bool duplicate)
1150{
1151 Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
1152 Ecore_Con_Event_Server_Data *e;
1153
1154 e = ecore_con_event_server_data_alloc();
1155 EINA_SAFETY_ON_NULL_RETURN(e);
1156
1157 svr->event_count = eina_list_append(svr->event_count, e);
1158 _ecore_con_server_timer_update(obj);
1159 e->server = obj;
1160 if (duplicate)
1161 {
1162 e->data = malloc(num);
1163 if (!e->data)
1164 {
1165 ERR("server data allocation failure !");
1166 _ecore_con_event_server_data_free(NULL, e);
1167 return;
1168 }
1169 memcpy(e->data, buf, num);
1170 }
1171 else
1172 e->data = buf;
1173 e->size = num;
1174 ecore_event_add(ECORE_CON_EVENT_SERVER_DATA, e,
1175 _ecore_con_event_server_data_free, NULL);
1176 {
1177 Ecore_Con_Event_Data_Received event_info = { NULL, 0 };
1178 event_info.data = e->data;
1179 event_info.size = e->size;
1180 efl_event_callback_call(obj, EFL_NETWORK_EVENT_DATA_RECEIVED, &event_info);
1181 }
1182 _ecore_con_event_count++;
1183}
1184
1185void
1186ecore_con_event_client_add(Ecore_Con_Client *obj)
1187{
1188 Efl_Network_Client_Data *cl = efl_data_scope_get(obj, EFL_NETWORK_CLIENT_CLASS);
1189 Ecore_Con_Event_Client_Add *e;
1190 int ev = ECORE_CON_EVENT_CLIENT_ADD;
1191
1192 e = ecore_con_event_client_add_alloc();
1193 EINA_SAFETY_ON_NULL_RETURN(e);
1194
1195 Efl_Network_Server_Data *host_server = efl_data_scope_get(cl->host_server, EFL_NETWORK_SERVER_CLASS);
1196
1197 cl->event_count = eina_list_append(cl->event_count, e);
1198 host_server->event_count = eina_list_append(host_server->event_count, e);
1199 _ecore_con_cl_timer_update(obj);
1200 cl->start_time = ecore_time_get();
1201 e->client = obj;
1202 if (cl->upgrade) ev = ECORE_CON_EVENT_CLIENT_UPGRADE;
1203 ecore_event_add(ev, e,
1204 (Ecore_End_Cb)_ecore_con_event_client_add_free, cl->host_server);
1205 efl_event_callback_call(obj, EFL_NETWORK_EVENT_CONNECTION_UPGRADED, NULL);
1206 _ecore_con_event_count++;
1207}
1208
1209void
1210ecore_con_event_client_del(Ecore_Con_Client *obj)
1211{
1212 Efl_Network_Client_Data *cl = efl_data_scope_get(obj, EFL_NETWORK_CLIENT_CLASS);
1213 Ecore_Con_Event_Client_Del *e;
1214
1215 if (!cl) return;
1216 cl->delete_me = EINA_TRUE;
1217 INF("cl %p is dead", cl);
1218 e = ecore_con_event_client_del_alloc();
1219 EINA_SAFETY_ON_NULL_RETURN(e);
1220 cl->event_count = eina_list_append(cl->event_count, e);
1221
1222 Efl_Network_Server_Data *host_server = efl_data_scope_get(cl->host_server, EFL_NETWORK_SERVER_CLASS);
1223
1224 host_server->event_count = eina_list_append(host_server->event_count, e);
1225 _ecore_con_cl_timer_update(obj);
1226 e->client = obj;
1227 ecore_event_add(ECORE_CON_EVENT_CLIENT_DEL, e,
1228 (Ecore_End_Cb)_ecore_con_event_client_del_free, cl->host_server);
1229 _ecore_con_event_count++;
1230}
1231
1232void
1233ecore_con_event_client_write(Ecore_Con_Client *obj, int num)
1234{
1235 Efl_Network_Client_Data *cl = efl_data_scope_get(obj, EFL_NETWORK_CLIENT_CLASS);
1236 Ecore_Con_Event_Client_Write *e;
1237
1238 e = ecore_con_event_client_write_alloc();
1239 EINA_SAFETY_ON_NULL_RETURN(e);
1240
1241 Efl_Network_Server_Data *host_server = efl_data_scope_get(cl->host_server, EFL_NETWORK_SERVER_CLASS);
1242
1243 cl->event_count = eina_list_append(cl->event_count, e);
1244 host_server->event_count = eina_list_append(host_server->event_count, e);
1245 e->client = obj;
1246 e->size = num;
1247 ecore_event_add(ECORE_CON_EVENT_CLIENT_WRITE, e,
1248 (Ecore_End_Cb)_ecore_con_event_client_write_free, cl->host_server);
1249 _ecore_con_event_count++;
1250}
1251
1252void
1253ecore_con_event_client_data(Ecore_Con_Client *obj, unsigned char *buf, int num, Eina_Bool duplicate)
1254{
1255 Efl_Network_Client_Data *cl = efl_data_scope_get(obj, EFL_NETWORK_CLIENT_CLASS);
1256 Ecore_Con_Event_Client_Data *e;
1257
1258 e = ecore_con_event_client_data_alloc();
1259 EINA_SAFETY_ON_NULL_RETURN(e);
1260
1261 Efl_Network_Server_Data *host_server = efl_data_scope_get(cl->host_server, EFL_NETWORK_SERVER_CLASS);
1262
1263 cl->event_count = eina_list_append(cl->event_count, e);
1264 host_server->event_count = eina_list_append(host_server->event_count, e);
1265 _ecore_con_cl_timer_update(obj);
1266 e->client = obj;
1267 if ((duplicate) && (num > 0))
1268 {
1269 e->data = malloc(num);
1270 if (!e->data)
1271 {
1272 ERR("client data allocation failure !");
1273 _ecore_con_event_client_data_free(cl->host_server, e);
1274 return;
1275 }
1276 memcpy(e->data, buf, num);
1277 }
1278 else
1279 e->data = buf;
1280 e->size = num;
1281 ecore_event_add(ECORE_CON_EVENT_CLIENT_DATA, e,
1282 (Ecore_End_Cb)_ecore_con_event_client_data_free, cl->host_server);
1283 {
1284 Ecore_Con_Event_Data_Received event_info = { NULL, 0 };
1285 event_info.data = e->data;
1286 event_info.size = e->size;
1287 efl_event_callback_call(obj, EFL_NETWORK_EVENT_DATA_RECEIVED, &event_info);
1288 }
1289 _ecore_con_event_count++;
1290}
1291
1292void
1293ecore_con_server_infos_del(Ecore_Con_Server *obj, void *info)
1294{
1295 Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
1296 svr->infos = eina_list_remove(svr->infos, info);
1297}
1298
1299void
1300_ecore_con_event_server_error(Ecore_Con_Server *obj, char *error, Eina_Bool duplicate)
1301{
1302 Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
1303 Ecore_Con_Event_Server_Error *e;
1304
1305 e = ecore_con_event_server_error_alloc();
1306 EINA_SAFETY_ON_NULL_RETURN(e);
1307
1308 e->server = obj;
1309 e->error = duplicate ? strdup(error) : error;
1310 DBG("%s", error);
1311 svr->event_count = eina_list_append(svr->event_count, e);
1312 ecore_event_add(ECORE_CON_EVENT_SERVER_ERROR, e, (Ecore_End_Cb)_ecore_con_event_server_error_free, NULL);
1313 efl_event_callback_call(obj, EFL_NETWORK_EVENT_CONNECTION_ERROR, e->error);
1314 _ecore_con_event_count++;
1315}
1316
1317void
1318ecore_con_event_client_error(Ecore_Con_Client *obj, const char *error)
1319{
1320 Efl_Network_Client_Data *cl = efl_data_scope_get(obj, EFL_NETWORK_CLIENT_CLASS);
1321 Ecore_Con_Event_Client_Error *e;
1322
1323 e = ecore_con_event_client_error_alloc();
1324 EINA_SAFETY_ON_NULL_RETURN(e);
1325
1326 Efl_Network_Server_Data *host_server = efl_data_scope_get(cl->host_server, EFL_NETWORK_SERVER_CLASS);
1327
1328 e->client = obj;
1329 e->error = strdup(error);
1330 DBG("%s", error);
1331 cl->event_count = eina_list_append(cl->event_count, e);
1332 host_server->event_count = eina_list_append(host_server->event_count, e);
1333 ecore_event_add(ECORE_CON_EVENT_CLIENT_ERROR, e, (Ecore_End_Cb)_ecore_con_event_client_error_free, cl->host_server);
1334 efl_event_callback_call(obj, EFL_NETWORK_EVENT_CONNECTION_ERROR, e->error);
1335 _ecore_con_event_count++;
1336}
1337
1338static void
1339_ecore_con_server_free(Ecore_Con_Server *obj)
1340{
1341 efl_del(obj);
1342}
1343
1344EOLIAN static void
1345_efl_network_server_efl_object_destructor(Eo *obj, Efl_Network_Server_Data *svr)
1346{
1347 Ecore_Con_Client *cl_obj;
1348 double t_start, t;
1349
1350 if (svr->event_count) goto end;
1351
1352 while (svr->infos)
1353 {
1354 ecore_con_info_data_clear(svr->infos->data);
1355 svr->infos = eina_list_remove_list(svr->infos, svr->infos);
1356 }
1357
1358 t_start = ecore_time_get();
1359 while (svr->buf && (!svr->delete_me))
1360 {
1361 _ecore_con_server_flush(obj);
1362 t = ecore_time_get();
1363 if ((t - t_start) > 0.5)
1364 {
1365 WRN("ECORE_CON: EEK - stuck in _ecore_con_server_free() trying\n"
1366 " to flush data out from the server, and have been for\n"
1367 " %1.1f seconds. This is taking too long. Aborting flush.",
1368 (t - t_start));
1369 break;
1370 }
1371 }
1372
1373#ifdef _WIN32
1374 ecore_con_local_win32_server_del(obj);
1375#endif
1376 if (svr->event_count) goto end;
1377
1378 if (svr->buf)
1379 eina_binbuf_free(svr->buf);
1380
1381 EINA_LIST_FREE(svr->clients, cl_obj)
1382 {
1383 Efl_Network_Client_Data *cl = efl_data_scope_get(cl_obj, EFL_NETWORK_CLIENT_CLASS);
1384 Ecore_Con_Event_Server_Add *ev;
1385
1386 /* some pointer hacks here to prevent double frees if people are being stupid */
1387 EINA_LIST_FREE(cl->event_count, ev)
1388 ev->server = NULL;
1389 cl->delete_me = EINA_TRUE;
1390 INF("cl %p is dead", cl);
1391 _ecore_con_client_free(cl_obj);
1392 }
1393 if ((svr->created) && (svr->path) && (svr->ppid == getpid()))
1394 unlink(svr->path);
1395
1396 ecore_con_ssl_server_shutdown(obj);
1397 free(svr->name);
1398 svr->name = NULL;
1399
1400 free(svr->path);
1401 svr->path = NULL;
1402
1403 eina_stringshare_del(svr->ip);
1404 eina_stringshare_del(svr->verify_name);
1405
1406 if (svr->ecs_buf) eina_binbuf_free(svr->ecs_buf);
1407 if (svr->ecs_recvbuf) eina_binbuf_free(svr->ecs_recvbuf);
1408
1409 if (svr->fd_handler)
1410 ecore_main_fd_handler_del(svr->fd_handler);
1411
1412 if (svr->fd != INVALID_SOCKET)
1413 closesocket(svr->fd);
1414
1415 if (svr->until_deletion)
1416 ecore_timer_del(svr->until_deletion);
1417
1418 servers = eina_list_remove(servers, obj);
1419 svr->data = NULL;
1420
1421 efl_destructor(efl_super(obj, EFL_NETWORK_SERVER_CLASS));
1422end:
1423 return;
1424}
1425
1426static void
1427_ecore_con_client_free(Ecore_Con_Client *obj)
1428{
1429 efl_del(obj);
1430}
1431
1432EOLIAN static void
1433_efl_network_client_efl_object_destructor(Eo *obj, Efl_Network_Client_Data *cl)
1434{
1435 double t_start, t;
1436
1437 if (cl->event_count) return;
1438
1439 t_start = ecore_time_get();
1440 while ((cl->buf) && (!cl->delete_me))
1441 {
1442 _ecore_con_client_flush(obj);
1443 t = ecore_time_get();
1444 if ((t - t_start) > 0.5)
1445 {
1446 WRN("EEK - stuck in _ecore_con_client_free() trying\n"
1447 " to flush data out from the client, and have been for\n"
1448 " %1.1f seconds. This is taking too long. Aborting flush.",
1449 (t - t_start));
1450 break;
1451 }
1452 }
1453 Efl_Network_Server_Data *host_server = efl_data_scope_get(cl->host_server, EFL_NETWORK_SERVER_CLASS);
1454
1455 if (host_server)
1456 {
1457 host_server->clients = eina_list_remove(host_server->clients, obj);
1458 --host_server->client_count;
1459 }
1460
1461#ifdef _WIN32
1462 ecore_con_local_win32_client_del(obj);
1463#endif
1464
1465 if (cl->event_count) return;
1466
1467 if (cl->buf) eina_binbuf_free(cl->buf);
1468
1469 if (host_server && (host_server->type & ECORE_CON_SSL))
1470 ecore_con_ssl_client_shutdown(obj);
1471
1472 if (cl->fd_handler)
1473 ecore_main_fd_handler_del(cl->fd_handler);
1474
1475 if (cl->fd != INVALID_SOCKET)
1476 closesocket(cl->fd);
1477
1478 free(cl->client_addr);
1479 cl->client_addr = NULL;
1480
1481 if (cl->until_deletion)
1482 ecore_timer_del(cl->until_deletion);
1483
1484 eina_stringshare_del(cl->ip);
1485 cl->data = NULL;
1486
1487 efl_destructor(efl_super(obj, EFL_NETWORK_CLIENT_CLASS));
1488}
1489
1490static Eina_Bool
1491_ecore_con_server_timer(Ecore_Con_Server *obj)
1492{
1493 Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
1494 ecore_con_server_del(obj);
1495
1496 svr->until_deletion = NULL;
1497 return ECORE_CALLBACK_CANCEL;
1498}
1499
1500static void
1501_ecore_con_server_timer_update(Ecore_Con_Server *obj)
1502{
1503 Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
1504 if (svr->disconnect_time)
1505 {
1506 if (svr->disconnect_time > 0)
1507 {
1508 if (svr->until_deletion)
1509 {
1510 ecore_timer_interval_set(svr->until_deletion, svr->disconnect_time);
1511 ecore_timer_reset(svr->until_deletion);
1512 }
1513 else
1514 svr->until_deletion = ecore_timer_add(svr->disconnect_time, (Ecore_Task_Cb)_ecore_con_server_timer, obj);
1515 }
1516 else if (svr->until_deletion)
1517 {
1518 ecore_timer_del(svr->until_deletion);
1519 svr->until_deletion = NULL;
1520 }
1521 }
1522 else
1523 {
1524 if (svr->until_deletion)
1525 {
1526 ecore_timer_del(svr->until_deletion);
1527 svr->until_deletion = NULL;
1528 }
1529 }
1530}
1531
1532static Eina_Bool
1533_ecore_con_client_timer(Ecore_Con_Client *obj)
1534{
1535 Efl_Network_Client_Data *cl = efl_data_scope_get(obj, EFL_NETWORK_CLIENT_CLASS);
1536 ecore_con_client_del(obj);
1537
1538 cl->until_deletion = NULL;
1539 return ECORE_CALLBACK_CANCEL;
1540}
1541
1542static void
1543_ecore_con_cl_timer_update(Ecore_Con_Client *obj)
1544{
1545 Efl_Network_Client_Data *cl = efl_data_scope_get(obj, EFL_NETWORK_CLIENT_CLASS);
1546 if (cl->disconnect_time)
1547 {
1548 if (cl->disconnect_time > 0)
1549 {
1550 if (cl->until_deletion)
1551 {
1552 ecore_timer_interval_set(cl->until_deletion, cl->disconnect_time);
1553 ecore_timer_reset(cl->until_deletion);
1554 }
1555 else
1556 cl->until_deletion = ecore_timer_add(cl->disconnect_time, (Ecore_Task_Cb)_ecore_con_client_timer, obj);
1557 }
1558 else if (cl->until_deletion)
1559 {
1560 ecore_timer_del(cl->until_deletion);
1561 cl->until_deletion = NULL;
1562 }
1563 }
1564 else
1565 {
1566 Efl_Network_Server_Data *host_server = efl_data_scope_get(cl->host_server, EFL_NETWORK_SERVER_CLASS);
1567
1568 if (host_server && host_server->client_disconnect_time > 0)
1569 {
1570 if (cl->until_deletion)
1571 {
1572 ecore_timer_interval_set(cl->until_deletion, host_server->client_disconnect_time);
1573 ecore_timer_reset(cl->until_deletion);
1574 }
1575 else
1576 cl->until_deletion = ecore_timer_add(host_server->client_disconnect_time, (Ecore_Task_Cb)_ecore_con_client_timer, obj);
1577 }
1578 else if (cl->until_deletion)
1579 {
1580 ecore_timer_del(cl->until_deletion);
1581 cl->until_deletion = NULL;
1582 }
1583 }
1584}
1585
1586static void
1587_ecore_con_cb_tcp_listen(void *data,
1588 Ecore_Con_Info *net_info)
1589{
1590 Ecore_Con_Server *obj = data;
1591 Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
1592 struct linger lin;
1593 const char *memerr = NULL;
1594#ifdef _WIN32
1595 u_long mode = 1;
1596#endif
1597
1598 errno = 0;
1599 if (!net_info) /* error message has already been handled */
1600 {
1601 svr->delete_me = EINA_TRUE;
1602 goto error;
1603 }
1604
1605#ifdef HAVE_SYSTEMD
1606 if (svr->type & ECORE_CON_SOCKET_ACTIVATE && sd_fd_index < sd_fd_max)
1607 {
1608 if (sd_is_socket_inet(SD_LISTEN_FDS_START + sd_fd_index,
1609 net_info->info.ai_family,
1610 net_info->info.ai_socktype,
1611 1,
1612 svr->port) <= 0)
1613 {
1614 ERR("Your systemd unit seems to provide fd in the wrong order for Socket activation.");
1615 goto error;
1616 }
1617
1618 svr->fd = SD_LISTEN_FDS_START + sd_fd_index++;
1619
1620 /* I am wondering if that's really going to work as the bind is already done */
1621 if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
1622
1623 lin.l_onoff = 1;
1624 lin.l_linger = 0;
1625 if (setsockopt(svr->fd, SOL_SOCKET, SO_LINGER, (const void *)&lin,
1626 sizeof(struct linger)) < 0)
1627 goto error;
1628
1629 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_NODELAY)
1630 {
1631 int flag = 1;
1632
1633 if (setsockopt(svr->fd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag,
1634 sizeof(int)) < 0)
1635 {
1636 goto error;
1637 }
1638 }
1639
1640 goto fd_ready;
1641 }
1642#endif
1643
1644 svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype,
1645 net_info->info.ai_protocol);
1646#ifdef _WIN32
1647 if (svr->fd == INVALID_SOCKET) goto error;
1648
1649 if (ioctlsocket(svr->fd, FIONBIO, &mode)) goto error;
1650#else 181#else
1651 if (svr->fd < 0) goto error; 182 return 0;
1652
1653 if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
1654 if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
1655#endif 183#endif
1656
1657 lin.l_onoff = 1;
1658 lin.l_linger = 0;
1659 if (setsockopt(svr->fd, SOL_SOCKET, SO_LINGER, (const void *)&lin,
1660 sizeof(struct linger)) < 0)
1661 goto error;
1662
1663 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_NODELAY)
1664 {
1665 int flag = 1;
1666
1667 if (setsockopt(svr->fd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag,
1668 sizeof(int)) < 0)
1669 {
1670 goto error;
1671 }
1672 }
1673
1674 if (bind(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen) != 0)
1675 goto error;
1676
1677 if (listen(svr->fd, 4096) != 0) goto error;
1678
1679#ifdef HAVE_SYSTEMD
1680fd_ready:
1681#endif
1682 svr->fd_handler = ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
1683 _ecore_con_svr_tcp_handler, obj, NULL, NULL);
1684 if (!svr->fd_handler)
1685 {
1686 memerr = "Memory allocation failure";
1687 goto error;
1688 }
1689
1690 return;
1691
1692error:
1693 if (errno || memerr) ecore_con_event_server_error(obj, memerr ? : strerror(errno));
1694 ecore_con_ssl_server_shutdown(obj);
1695 _ecore_con_server_kill(obj);
1696}
1697
1698static void
1699_ecore_con_cb_udp_listen(void *data,
1700 Ecore_Con_Info *net_info)
1701{
1702 Ecore_Con_Server *obj = data;
1703 Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
1704 Ecore_Con_Type type;
1705 struct ip_mreq mreq;
1706#ifdef HAVE_IPV6
1707 struct ipv6_mreq mreq6;
1708#endif
1709 const int on = 1;
1710 const char *memerr = NULL;
1711#ifdef _WIN32
1712 u_long mode = 1;
1713#endif
1714
1715 type = svr->type;
1716 type &= ECORE_CON_TYPE;
1717
1718 errno = 0;
1719 if (!net_info) /* error message has already been handled */
1720 {
1721 svr->delete_me = EINA_TRUE;
1722 goto error;
1723 }
1724#ifdef HAVE_SYSTEMD
1725 if (svr->type & ECORE_CON_SOCKET_ACTIVATE && sd_fd_index < sd_fd_max)
1726 {
1727 if (sd_is_socket_inet(SD_LISTEN_FDS_START + sd_fd_index,
1728 net_info->info.ai_family,
1729 net_info->info.ai_socktype,
1730 -1,
1731 svr->port) <= 0)
1732 {
1733 ERR("Your systemd unit seems to provide fd in the wrong order for Socket activation.");
1734 goto error;
1735 }
1736 svr->fd = SD_LISTEN_FDS_START + sd_fd_index++;
1737
1738 if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof(on)) != 0)
1739 goto error;
1740 if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
1741
1742 goto fd_ready;
1743 }
1744#endif
1745 svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype,
1746 net_info->info.ai_protocol);
1747#ifdef _WIN32
1748 if (svr->fd == INVALID_SOCKET) goto error;
1749
1750 if (ioctlsocket(svr->fd, FIONBIO, &mode)) goto error;
1751#else
1752 if (svr->fd < 0) goto error;
1753
1754 if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
1755 if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
1756#endif
1757
1758 if (type == ECORE_CON_REMOTE_MCAST)
1759 {
1760 if (net_info->info.ai_family == AF_INET)
1761 {
1762 if (!inet_pton(net_info->info.ai_family, net_info->ip,
1763 &mreq.imr_multiaddr))
1764 goto error;
1765
1766 mreq.imr_interface.s_addr = htonl(INADDR_ANY);
1767 if (setsockopt(svr->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
1768 (const void *)&mreq, sizeof(mreq)) != 0)
1769 goto error;
1770 }
1771#ifdef HAVE_IPV6
1772 else if (net_info->info.ai_family == AF_INET6)
1773 {
1774 if (!inet_pton(net_info->info.ai_family, net_info->ip,
1775 &mreq6.ipv6mr_multiaddr))
1776 goto error;
1777 mreq6.ipv6mr_interface = htonl(INADDR_ANY);
1778 if (setsockopt(svr->fd, IPPROTO_IPV6, IPV6_JOIN_GROUP,
1779 (const void *)&mreq6, sizeof(mreq6)) != 0)
1780 goto error;
1781 }
1782#endif
1783 }
1784
1785 if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof(on)) != 0)
1786 goto error;
1787
1788 if (bind(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen) < 0)
1789 goto error;
1790
1791#ifdef HAVE_SYSTEMD
1792fd_ready:
1793#endif
1794 svr->fd_handler =
1795 ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
1796 _ecore_con_svr_udp_handler, obj, NULL, NULL);
1797 if (!svr->fd_handler)
1798 {
1799 memerr = "Memory allocation failure";
1800 goto error;
1801 }
1802
1803 svr->ip = eina_stringshare_add(net_info->ip);
1804
1805 return;
1806
1807error:
1808 if (errno || memerr) ecore_con_event_server_error(obj, memerr ? : strerror(errno));
1809 ecore_con_ssl_server_shutdown(obj);
1810 _ecore_con_server_kill(obj);
1811}
1812
1813static void
1814_ecore_con_cb_tcp_connect(void *data,
1815 Ecore_Con_Info *net_info)
1816{
1817 Ecore_Con_Server *obj = data;
1818 Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
1819 int res;
1820 int curstate = 0;
1821 const char *memerr = NULL;
1822#ifdef _WIN32
1823 u_long mode = 1;
1824#endif
1825
1826 errno = 0;
1827 if (!net_info) /* error message has already been handled */
1828 {
1829 svr->delete_me = EINA_TRUE;
1830 goto error;
1831 }
1832
1833 svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype,
1834 net_info->info.ai_protocol);
1835#ifdef _WIN32
1836 if (svr->fd == INVALID_SOCKET) goto error;
1837
1838 if (ioctlsocket(svr->fd, FIONBIO, &mode)) goto error;
1839#else
1840 if (svr->fd < 0) goto error;
1841
1842 if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
1843 if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
1844#endif
1845
1846 if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&curstate, sizeof(curstate)) < 0)
1847 goto error;
1848
1849 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_NODELAY)
1850 {
1851 int flag = 1;
1852
1853 if (setsockopt(svr->fd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int)) < 0)
1854 {
1855 goto error;
1856 }
1857 }
1858
1859 res = connect(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen);
1860#ifdef _WIN32
1861 if (res == SOCKET_ERROR)
1862 {
1863 if (WSAGetLastError() != WSAEWOULDBLOCK)
1864 {
1865 char *err;
1866 err = evil_format_message(WSAGetLastError());
1867 _ecore_con_event_server_error(obj, err, EINA_FALSE);
1868 ecore_con_ssl_server_shutdown(obj);
1869 _ecore_con_server_kill(obj);
1870 return;
1871 }
1872
1873#else
1874 if (res < 0)
1875 {
1876 if (errno != EINPROGRESS) goto error;
1877#endif
1878 svr->connecting = EINA_TRUE;
1879 svr->fd_handler =
1880 ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ | ECORE_FD_WRITE,
1881 _ecore_con_cl_handler, obj, NULL, NULL);
1882 }
1883 else
1884 {
1885 ecore_con_event_server_add(obj);
1886 svr->fd_handler = ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
1887 _ecore_con_cl_handler, obj, NULL, NULL);
1888 }
1889
1890 if (svr->type & ECORE_CON_SSL)
1891 {
1892 svr->handshaking = EINA_TRUE;
1893 svr->ssl_state = ECORE_CON_SSL_STATE_INIT;
1894 DBG("%s ssl handshake", svr->ecs_state ? "Queuing" : "Beginning");
1895 if ((!svr->ecs_state) && ecore_con_ssl_server_init(obj))
1896 goto error;
1897 }
1898
1899 if (!svr->fd_handler)
1900 {
1901 memerr = "Memory allocation failure";
1902 goto error;
1903 }
1904
1905 if ((!svr->ecs) || (svr->ecs->lookup))
1906 svr->ip = eina_stringshare_add(net_info->ip);
1907
1908 return;
1909
1910error:
1911 ecore_con_event_server_error(obj,
1912 memerr ? : errno ? strerror(errno) : "DNS error");
1913 ecore_con_ssl_server_shutdown(obj);
1914 _ecore_con_server_kill(obj);
1915}
1916
1917static void
1918_ecore_con_cb_udp_connect(void *data,
1919 Ecore_Con_Info *net_info)
1920{
1921 Ecore_Con_Server *obj = data;
1922 int curstate = 0;
1923 int broadcast = 1;
1924 const char *memerr = NULL;
1925 Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
1926#ifdef _WIN32
1927 u_long mode = 1;
1928#endif
1929
1930 errno = 0;
1931 if (!net_info) /* error message has already been handled */
1932 {
1933 svr->delete_me = EINA_TRUE;
1934 goto error;
1935 }
1936
1937 svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype,
1938 net_info->info.ai_protocol);
1939#ifdef _WIN32
1940 if (svr->fd == INVALID_SOCKET) goto error;
1941
1942 if (ioctlsocket(svr->fd, FIONBIO, &mode)) goto error;
1943#else
1944 if (svr->fd < 0) goto error;
1945
1946 if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
1947 if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
1948#endif
1949 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_BROADCAST)
1950 {
1951 if (setsockopt(svr->fd, SOL_SOCKET, SO_BROADCAST,
1952 (const void *)&broadcast,
1953 sizeof(broadcast)) < 0)
1954 {
1955 goto error;
1956 }
1957 }
1958 if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR,
1959 (const void *)&curstate, sizeof(curstate)) < 0)
1960 goto error;
1961
1962 if (connect(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen) < 0)
1963 goto error;
1964
1965 svr->fd_handler = ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ | ECORE_FD_WRITE,
1966 _ecore_con_cl_udp_handler, obj, NULL, NULL);
1967
1968 if (!svr->fd_handler)
1969 {
1970 memerr = "Memory allocation failure";
1971 goto error;
1972 }
1973
1974 if ((!svr->ecs) || (svr->ecs->lookup))
1975 svr->ip = eina_stringshare_add(net_info->ip);
1976
1977 return;
1978
1979error:
1980 if (errno || memerr) ecore_con_event_server_error(obj, memerr ? : strerror(errno));
1981 ecore_con_ssl_server_shutdown(obj);
1982 _ecore_con_server_kill(obj);
1983}
1984
1985static Ecore_Con_State
1986svr_try_connect_plain(Ecore_Con_Server *obj)
1987{
1988 Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
1989 int res;
1990 int so_err = 0;
1991 socklen_t size = sizeof(int);
1992
1993 res = getsockopt(svr->fd, SOL_SOCKET, SO_ERROR, (void *)&so_err, &size);
1994#ifdef _WIN32
1995 if (res == SOCKET_ERROR)
1996 so_err = WSAGetLastError();
1997
1998 if ((so_err == WSAEINPROGRESS) && !svr->delete_me)
1999 return ECORE_CON_INPROGRESS;
2000
2001#else
2002 if (res < 0)
2003 so_err = errno;
2004
2005 if ((so_err == EINPROGRESS) && !svr->delete_me)
2006 return ECORE_CON_INPROGRESS;
2007
2008#endif
2009
2010 if (so_err)
2011 {
2012 /* we lost our server! */
2013 ecore_con_event_server_error(obj, strerror(so_err));
2014 DBG("Connection lost: %s", strerror(so_err));
2015 _ecore_con_server_kill(obj);
2016 return ECORE_CON_DISCONNECTED;
2017 }
2018
2019 if ((!svr->delete_me) && (!svr->handshaking) && svr->connecting)
2020 {
2021 if (svr->ecs)
2022 {
2023 if (ecore_con_socks_svr_init(obj))
2024 return ECORE_CON_INPROGRESS;
2025 }
2026 else
2027 ecore_con_event_server_add(obj);
2028 }
2029
2030 if (svr->fd_handler)
2031 {
2032 if (svr->buf)
2033 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE);
2034 else
2035 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
2036 }
2037
2038 if (!svr->delete_me)
2039 return ECORE_CON_CONNECTED;
2040 else
2041 return ECORE_CON_DISCONNECTED;
2042}
2043
2044static const char *
2045_ecore_con_pretty_ip(struct sockaddr *client_addr)
2046{
2047#ifndef HAVE_IPV6
2048 char ipbuf[INET_ADDRSTRLEN + 1];
2049#else
2050 char ipbuf[INET6_ADDRSTRLEN + 1];
2051#endif
2052 int family = client_addr->sa_family;
2053 void *src;
2054
2055 switch (family)
2056 {
2057 case AF_INET:
2058 src = &(((struct sockaddr_in *)client_addr)->sin_addr);
2059 break;
2060
2061#ifdef HAVE_IPV6
2062 case AF_INET6:
2063 src = &(((struct sockaddr_in6 *)client_addr)->sin6_addr);
2064
2065 if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)src))
2066 {
2067 family = AF_INET;
2068 src = (char *)src + 12;
2069 }
2070 break;
2071
2072#endif
2073 default:
2074 return eina_stringshare_add("0.0.0.0");
2075 }
2076
2077 if (!inet_ntop(family, src, ipbuf, sizeof(ipbuf)))
2078 return eina_stringshare_add("0.0.0.0");
2079
2080 ipbuf[sizeof(ipbuf) - 1] = 0;
2081 return eina_stringshare_add(ipbuf);
2082}
2083
2084static Eina_Bool
2085_ecore_con_svr_tcp_handler(void *data,
2086 Ecore_Fd_Handler *fd_handler EINA_UNUSED)
2087{
2088 Ecore_Con_Server *svr_obj = data;
2089 Ecore_Con_Client *obj = NULL;
2090 unsigned char client_addr[256];
2091 unsigned int client_addr_len;
2092 const char *clerr = NULL;
2093 Efl_Network_Server_Data *svr = efl_data_scope_get(svr_obj, EFL_NETWORK_SERVER_CLASS);
2094#ifdef _WIN32
2095 u_long mode = 1;
2096#endif
2097
2098 if (svr->delete_me)
2099 return ECORE_CALLBACK_RENEW;
2100
2101 if ((svr->client_limit >= 0) && (!svr->reject_excess_clients) &&
2102 (svr->client_count >= (unsigned int)svr->client_limit))
2103 return ECORE_CALLBACK_RENEW;
2104
2105 /* a new client */
2106
2107 obj = efl_add(EFL_NETWORK_CLIENT_CLASS, NULL);
2108 Efl_Network_Client_Data *cl = efl_data_scope_get(obj, EFL_NETWORK_CLIENT_CLASS);
2109 if (!cl)
2110 {
2111 ecore_con_event_server_error(svr_obj, "Memory allocation failure when attempting to add a new client");
2112 return ECORE_CALLBACK_RENEW;
2113 }
2114 cl->host_server = svr_obj;
2115
2116 client_addr_len = sizeof(client_addr);
2117 memset(&client_addr, 0, client_addr_len);
2118 cl->fd = accept(svr->fd, (struct sockaddr *)&client_addr, (socklen_t *)&client_addr_len);
2119#ifdef _WIN32
2120 if (cl->fd == INVALID_SOCKET) goto error;
2121#else
2122 if (cl->fd < 0) goto error;
2123#endif
2124 if ((svr->client_limit >= 0) && (svr->reject_excess_clients) &&
2125 (svr->client_count >= (unsigned int)svr->client_limit))
2126 {
2127 clerr = "Maximum client limit reached";
2128 goto error;
2129 }
2130
2131#ifdef _WIN32
2132 if (ioctlsocket(cl->fd, FIONBIO, &mode)) goto error;
2133#else
2134 if (fcntl(cl->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
2135 if (fcntl(cl->fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
2136#endif
2137 cl->fd_handler = ecore_main_fd_handler_add(cl->fd, ECORE_FD_READ,
2138 _ecore_con_svr_cl_handler, obj, NULL, NULL);
2139 if (!cl->fd_handler) goto error;
2140
2141 if ((!svr->upgrade) && (svr->type & ECORE_CON_SSL))
2142 {
2143 cl->handshaking = EINA_TRUE;
2144 cl->ssl_state = ECORE_CON_SSL_STATE_INIT;
2145 if (ecore_con_ssl_client_init(obj))
2146 goto error;
2147 }
2148
2149 cl->client_addr = malloc(client_addr_len);
2150 if (!cl->client_addr)
2151 {
2152 clerr = "Memory allocation failure when attempting to add a new client";
2153 goto error;
2154 }
2155 cl->client_addr_len = client_addr_len;
2156 memcpy(cl->client_addr, &client_addr, client_addr_len);
2157
2158 svr->clients = eina_list_append(svr->clients, obj);
2159 svr->client_count++;
2160
2161 if ((!cl->delete_me) && (!cl->handshaking))
2162 ecore_con_event_client_add(obj);
2163
2164 return ECORE_CALLBACK_RENEW;
2165
2166error:
2167 if (cl->fd_handler) ecore_main_fd_handler_del(cl->fd_handler);
2168 if (cl->fd != INVALID_SOCKET) closesocket(cl->fd);
2169 {
2170 Ecore_Event *ev;
2171
2172 EINA_LIST_FREE(cl->event_count, ev)
2173 {
2174 svr->event_count = eina_list_remove(svr->event_count, ev);
2175 ecore_event_del(ev);
2176 }
2177 }
2178 efl_del(obj);
2179 if (clerr || errno) ecore_con_event_server_error(svr_obj, clerr ? : strerror(errno));
2180 return ECORE_CALLBACK_RENEW;
2181}
2182
2183static void
2184_ecore_con_cl_read(Ecore_Con_Server *obj)
2185{
2186 Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
2187 int num = 0;
2188 Eina_Bool lost_server = EINA_TRUE;
2189 unsigned char buf[READBUFSIZ];
2190
2191 DBG("svr=%p", svr);
2192
2193 /* only possible with non-ssl connections */
2194 if (svr->connecting && (svr_try_connect_plain(obj) != ECORE_CON_CONNECTED))
2195 return;
2196
2197 if (svr->handshaking && (!svr->ecs_state))
2198 {
2199 DBG("Continuing ssl handshake");
2200 if (!ecore_con_ssl_server_init(obj))
2201 lost_server = EINA_FALSE;
2202 _ecore_con_server_timer_update(obj);
2203 }
2204
2205 if (svr->ecs_state || !(svr->type & ECORE_CON_SSL))
2206 {
2207 errno = 0;
2208 num = recv(svr->fd, (char *)buf, sizeof(buf), 0);
2209
2210 /* 0 is not a valid return value for a tcp socket */
2211#ifdef _WIN32
2212 if ((num > 0) || ((num < 0) && (WSAGetLastError() == WSAEWOULDBLOCK)))
2213#else
2214 if ((num > 0) || ((num < 0) && (errno == EAGAIN)))
2215#endif
2216 lost_server = EINA_FALSE;
2217 else if (num < 0)
2218 ecore_con_event_server_error(obj, strerror(errno));
2219 }
2220 else
2221 {
2222 num = ecore_con_ssl_server_read(obj, buf, sizeof(buf));
2223 /* this is not an actual 0 return, 0 here just means non-fatal error such as EAGAIN */
2224 if (num >= 0)
2225 lost_server = EINA_FALSE;
2226 }
2227
2228 if ((!svr->delete_me) && (num > 0))
2229 {
2230 if (svr->ecs_state)
2231 ecore_con_socks_read(obj, buf, num);
2232 else
2233 ecore_con_event_server_data(obj, buf, num, EINA_TRUE);
2234 }
2235
2236 if (lost_server)
2237 _ecore_con_server_kill(obj);
2238}
2239
2240static Eina_Bool
2241_ecore_con_cl_handler(void *data,
2242 Ecore_Fd_Handler *fd_handler)
2243{
2244 Ecore_Con_Server *obj = data;
2245 Eina_Bool want_read, want_write;
2246 Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
2247
2248 if (svr->delete_me)
2249 return ECORE_CALLBACK_RENEW;
2250
2251 if (svr->delete_me)
2252 return ECORE_CALLBACK_RENEW;
2253
2254 want_read = ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ);
2255 want_write = ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE);
2256
2257 if ((!svr->ecs_state) && svr->handshaking && (want_read || want_write))
2258 {
2259 DBG("Continuing ssl handshake: preparing to %s...", want_read ? "read" : "write");
2260#ifdef ISCOMFITOR
2261 if (want_read)
2262 {
2263 char buf[READBUFSIZ];
2264 ssize_t len;
2265 len = recv(svr->fd, (char *)buf, sizeof(buf), MSG_DONTWAIT | MSG_PEEK);
2266 DBG("%zu bytes in buffer", len);
2267 }
2268#endif
2269 if (ecore_con_ssl_server_init(obj))
2270 {
2271 DBG("ssl handshaking failed!");
2272 svr->handshaking = EINA_FALSE;
2273 }
2274 else if (!svr->ssl_state)
2275 ecore_con_event_server_add(obj);
2276 return ECORE_CALLBACK_RENEW;
2277 }
2278 if (svr->ecs && svr->ecs_state && (svr->ecs_state < ECORE_CON_PROXY_STATE_READ) && (!svr->ecs_buf))
2279 {
2280 if (svr->ecs_state < ECORE_CON_PROXY_STATE_INIT)
2281 {
2282 INF("PROXY STATE++");
2283 svr->ecs_state++;
2284 }
2285 if (ecore_con_socks_svr_init(obj)) return ECORE_CALLBACK_RENEW;
2286 }
2287 if (want_read)
2288 _ecore_con_cl_read(obj);
2289 else if (want_write) /* only possible with non-ssl connections */
2290 {
2291 if (svr->connecting && (!svr_try_connect_plain(obj)) && (!svr->ecs_state))
2292 return ECORE_CALLBACK_RENEW;
2293
2294 _ecore_con_server_flush(obj);
2295 }
2296
2297 return ECORE_CALLBACK_RENEW;
2298}
2299
2300static Eina_Bool
2301_ecore_con_cl_udp_handler(void *data,
2302 Ecore_Fd_Handler *fd_handler)
2303{
2304 unsigned char buf[READBUFSIZ];
2305 int num;
2306 Ecore_Con_Server *obj = data;
2307 Eina_Bool want_read, want_write;
2308 Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
2309
2310 want_read = ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ);
2311 want_write = ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE);
2312
2313 if (svr->delete_me || ((!want_read) && (!want_write)))
2314 return ECORE_CALLBACK_RENEW;
2315
2316 if (want_write)
2317 {
2318 _ecore_con_server_flush(obj);
2319 return ECORE_CALLBACK_RENEW;
2320 }
2321
2322 num = recv(svr->fd, (char *)buf, READBUFSIZ, 0);
2323
2324 if ((!svr->delete_me) && (num > 0))
2325 ecore_con_event_server_data(obj, buf, num, EINA_TRUE);
2326
2327 if (num < 0 && (errno != EAGAIN) && (errno != EINTR))
2328 {
2329 ecore_con_event_server_error(obj, strerror(errno));
2330 _ecore_con_server_kill(obj);
2331 }
2332
2333 return ECORE_CALLBACK_RENEW;
2334}
2335
2336static Eina_Bool
2337_ecore_con_svr_udp_handler(void *data,
2338 Ecore_Fd_Handler *fd_handler)
2339{
2340 unsigned char buf[READBUFSIZ];
2341 unsigned char client_addr[256];
2342 socklen_t client_addr_len = sizeof(client_addr);
2343 int num;
2344 Ecore_Con_Server *svr_obj = data;
2345 Ecore_Con_Client *obj = NULL;
2346#ifdef _WIN32
2347 u_long mode = 1;
2348#endif
2349
2350 Efl_Network_Server_Data *svr = efl_data_scope_get(svr_obj, EFL_NETWORK_SERVER_CLASS);
2351 if (svr->delete_me)
2352 return ECORE_CALLBACK_RENEW;
2353
2354 if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE))
2355 return ECORE_CALLBACK_RENEW;
2356
2357 if (!ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
2358 return ECORE_CALLBACK_RENEW;
2359
2360#ifdef _WIN32
2361 if (!ioctlsocket(svr->fd, FIONBIO, &mode))
2362 num = recvfrom(svr->fd, (char *)buf, sizeof(buf), 0,
2363 (struct sockaddr *)&client_addr,
2364 &client_addr_len);
2365
2366#else
2367 num = recvfrom(svr->fd, buf, sizeof(buf), MSG_DONTWAIT,
2368 (struct sockaddr *)&client_addr,
2369 &client_addr_len);
2370#endif
2371
2372 if (num < 0 && (errno != EAGAIN) && (errno != EINTR))
2373 {
2374 ecore_con_event_server_error(svr_obj, strerror(errno));
2375 if (!svr->delete_me)
2376 ecore_con_event_client_del(NULL);
2377 _ecore_con_server_kill(svr_obj);
2378 return ECORE_CALLBACK_CANCEL;
2379 }
2380
2381/* Create a new client for use in the client data event */
2382 obj = efl_add(EFL_NETWORK_CLIENT_CLASS, NULL);
2383 Efl_Network_Client_Data *cl = efl_data_scope_get(obj, EFL_NETWORK_CLIENT_CLASS);
2384 EINA_SAFETY_ON_NULL_RETURN_VAL(cl, ECORE_CALLBACK_RENEW);
2385
2386 cl->host_server = svr_obj;
2387 cl->fd = INVALID_SOCKET;
2388 cl->client_addr = malloc(client_addr_len);
2389 if (!cl->client_addr)
2390 {
2391 free(cl);
2392 return ECORE_CALLBACK_RENEW;
2393 }
2394 cl->client_addr_len = client_addr_len;
2395
2396 memcpy(cl->client_addr, &client_addr, client_addr_len);
2397 svr->clients = eina_list_append(svr->clients, obj);
2398 svr->client_count++;
2399
2400 ecore_con_event_client_add(obj);
2401 ecore_con_event_client_data(obj, buf, num, EINA_TRUE);
2402
2403 return ECORE_CALLBACK_RENEW;
2404}
2405
2406static void
2407_ecore_con_svr_cl_read(Ecore_Con_Client *obj)
2408{
2409 Efl_Network_Client_Data *cl = efl_data_scope_get(obj, EFL_NETWORK_CLIENT_CLASS);
2410 int num = 0;
2411 Eina_Bool lost_client = EINA_TRUE;
2412 unsigned char buf[READBUFSIZ];
2413
2414 DBG("cl=%p", cl);
2415
2416 if (cl->handshaking)
2417 {
2418 /* add an extra handshake attempt just before read, even though
2419 * read also attempts to handshake, to try to finish sooner
2420 */
2421 if (ecore_con_ssl_client_init(obj))
2422 lost_client = EINA_FALSE;
2423
2424 _ecore_con_cl_timer_update(obj);
2425 }
2426
2427 Efl_Network_Server_Data *host_server = efl_data_scope_get(cl->host_server, EFL_NETWORK_SERVER_CLASS);
2428 if (!(host_server->type & ECORE_CON_SSL) && (!cl->upgrade))
2429 {
2430 num = recv(cl->fd, (char *)buf, sizeof(buf), 0);
2431
2432 /* 0 is not a valid return value for a tcp socket */
2433 if ((num > 0) || ((num < 0) && ((errno == EAGAIN) || (errno == EINTR))))
2434 lost_client = EINA_FALSE;
2435 else if (num < 0)
2436 ecore_con_event_client_error(obj, strerror(errno));
2437 }
2438 else
2439 {
2440 num = ecore_con_ssl_client_read(obj, buf, sizeof(buf));
2441 /* this is not an actual 0 return, 0 here just means non-fatal error such as EAGAIN */
2442 if (num >= 0)
2443 lost_client = EINA_FALSE;
2444 }
2445
2446 if ((!cl->delete_me) && (num > 0))
2447 ecore_con_event_client_data(obj, buf, num, EINA_TRUE);
2448
2449 if (lost_client) _ecore_con_client_kill(obj);
2450}
2451
2452static Eina_Bool
2453_ecore_con_svr_cl_handler(void *data,
2454 Ecore_Fd_Handler *fd_handler)
2455{
2456 Ecore_Con_Client *obj = data;
2457 Efl_Network_Client_Data *cl = efl_data_scope_get(obj, EFL_NETWORK_CLIENT_CLASS);
2458
2459 if (cl->delete_me)
2460 return ECORE_CALLBACK_RENEW;
2461
2462 if (cl->handshaking && ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ | ECORE_FD_WRITE))
2463 {
2464 if (ecore_con_ssl_client_init(obj))
2465 {
2466 DBG("ssl handshaking failed!");
2467 _ecore_con_client_kill(obj);
2468 return ECORE_CALLBACK_RENEW;
2469 }
2470 else if (!cl->ssl_state)
2471 ecore_con_event_client_add(obj);
2472 }
2473 else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
2474 _ecore_con_svr_cl_read(obj);
2475
2476 else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE))
2477 _ecore_con_client_flush(obj);
2478
2479 return ECORE_CALLBACK_RENEW;
2480}
2481
2482static void
2483_ecore_con_server_flush(Ecore_Con_Server *obj)
2484{
2485 Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
2486 int count;
2487 size_t num;
2488 size_t buf_len;
2489 size_t *buf_offset;
2490 const unsigned char *buf;
2491 Eina_Binbuf *buf_p;
2492
2493 DBG("(svr=%p,buf=%p)", svr, svr->buf);
2494 if (!svr->fd_handler) return;
2495#ifdef _WIN32
2496 if (ecore_con_local_win32_server_flush(obj))
2497 return;
2498#endif
2499
2500 if ((!svr->buf) && (!svr->ecs_buf))
2501 {
2502 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
2503 return;
2504 }
2505
2506 if (svr->buf)
2507 {
2508 buf_p = svr->buf;
2509 buf_offset = &(svr->write_buf_offset);
2510 }
2511 else
2512 {
2513 buf_p = svr->ecs_buf;
2514 buf_offset = &(svr->ecs_buf_offset);
2515 }
2516 buf = eina_binbuf_string_get(buf_p);
2517 buf_len = eina_binbuf_length_get(buf_p);
2518 num = buf_len - *buf_offset;
2519
2520 /* check whether we need to write anything at all.
2521 * we must not write zero bytes with SSL_write() since it
2522 * causes undefined behaviour
2523 */
2524 /* we thank Tommy[D] for needing to check negative buffer sizes
2525 * here because his system is amazing.
2526 */
2527 if (num <= 0) return;
2528
2529 if ((!svr->ecs_state) && svr->handshaking)
2530 {
2531 DBG("Continuing ssl handshake");
2532 if (ecore_con_ssl_server_init(obj))
2533 _ecore_con_server_kill(obj);
2534 _ecore_con_server_timer_update(obj);
2535 return;
2536 }
2537
2538 if (svr->ecs_state || (!(svr->type & ECORE_CON_SSL)))
2539 count = send(svr->fd, (const char *)buf + *buf_offset, num, 0);
2540 else
2541 count = ecore_con_ssl_server_write(obj, buf + *buf_offset, num);
2542
2543#ifdef _WIN32
2544 if (count == SOCKET_ERROR)
2545 {
2546 switch (WSAGetLastError())
2547 {
2548 case WSAEINTR:
2549 case WSAEINPROGRESS:
2550 case WSAEWOULDBLOCK:
2551 break;
2552 default:
2553 {
2554 LPTSTR s;
2555
2556 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
2557 FORMAT_MESSAGE_FROM_SYSTEM,
2558 NULL, WSAGetLastError(),
2559 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
2560 (LPTSTR)&s, 0, NULL);
2561 ecore_con_event_server_error(obj, (char *)s);
2562 free(s);
2563 _ecore_con_server_kill(obj);
2564 }
2565 }
2566 }
2567#else
2568 if (count < 0)
2569 {
2570 if ((errno != EAGAIN) && (errno != EINTR))
2571 {
2572 ecore_con_event_server_error(obj, strerror(errno));
2573 _ecore_con_server_kill(obj);
2574 }
2575 return;
2576 }
2577#endif
2578
2579
2580 if (count && (!svr->ecs_state)) ecore_con_event_server_write(obj, count);
2581
2582 if (!eina_binbuf_remove(buf_p, 0, count))
2583 *buf_offset += count;
2584 else
2585 {
2586 *buf_offset = 0;
2587 buf_len -= count;
2588 }
2589 if (*buf_offset >= buf_len)
2590 {
2591 *buf_offset = 0;
2592 eina_binbuf_free(buf_p);
2593
2594 if (svr->ecs_buf)
2595 {
2596 svr->ecs_buf = NULL;
2597 INF("PROXY STATE++");
2598 svr->ecs_state++;
2599 }
2600 else
2601 {
2602 svr->buf = NULL;
2603#ifdef TCP_CORK
2604 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_CORK)
2605 {
2606 int state = 0;
2607 if (setsockopt(svr->fd, IPPROTO_TCP, TCP_CORK, (char *)&state, sizeof(int)) < 0)
2608 /* realistically this isn't anything serious so we can just log and continue */
2609 ERR("uncorking failed! %s", strerror(errno));
2610 }
2611#endif
2612 }
2613 if (svr->fd_handler)
2614 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
2615 }
2616 else if (((unsigned int)count < num) && svr->fd_handler)
2617 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE);
2618}
2619
2620static void
2621_ecore_con_client_flush(Ecore_Con_Client *obj)
2622{
2623 Efl_Network_Client_Data *cl = efl_data_scope_get(obj, EFL_NETWORK_CLIENT_CLASS);
2624 int count = 0;
2625 size_t num = 0;
2626
2627 if (!cl->fd_handler) return;
2628#ifdef _WIN32
2629 if (ecore_con_local_win32_client_flush(obj))
2630 return;
2631#endif
2632
2633 if (!cl->buf)
2634 {
2635 ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ);
2636 return;
2637 }
2638
2639 if (cl->handshaking)
2640 {
2641 if (ecore_con_ssl_client_init(obj))
2642 count = -1;
2643
2644 _ecore_con_cl_timer_update(obj);
2645 }
2646
2647 if (!count)
2648 {
2649 if (!cl->buf) return;
2650 num = eina_binbuf_length_get(cl->buf) - cl->buf_offset;
2651 if (num <= 0) return;
2652 Efl_Network_Server_Data *host_server = efl_data_scope_get(cl->host_server, EFL_NETWORK_SERVER_CLASS);
2653 if (!(host_server->type & ECORE_CON_SSL) && (!cl->upgrade))
2654 count = send(cl->fd, (char *)eina_binbuf_string_get(cl->buf) + cl->buf_offset, num, 0);
2655 else
2656 count = ecore_con_ssl_client_write(obj, eina_binbuf_string_get(cl->buf) + cl->buf_offset, num);
2657 }
2658
2659 if (count < 0)
2660 {
2661 if ((errno != EAGAIN) && (errno != EINTR) && (!cl->delete_me))
2662 {
2663 ecore_con_event_client_error(obj, strerror(errno));
2664 _ecore_con_client_kill(obj);
2665 }
2666
2667 return;
2668 }
2669
2670 if (count) ecore_con_event_client_write(obj, count);
2671 cl->buf_offset += count, num -= count;
2672 if (cl->buf_offset >= eina_binbuf_length_get(cl->buf))
2673 {
2674 cl->buf_offset = 0;
2675 eina_binbuf_free(cl->buf);
2676 cl->buf = NULL;
2677#ifdef TCP_CORK
2678 Efl_Network_Server_Data *host_server = efl_data_scope_get(cl->host_server, EFL_NETWORK_SERVER_CLASS);
2679 if ((host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_CORK)
2680 {
2681 int state = 0;
2682 if (setsockopt(cl->fd, IPPROTO_TCP, TCP_CORK, (char *)&state, sizeof(int)) < 0)
2683 /* realistically this isn't anything serious so we can just log and continue */
2684 ERR("uncorking failed! %s", strerror(errno));
2685 }
2686#endif
2687 if (cl->fd_handler)
2688 ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ);
2689 }
2690 else if (cl->fd_handler)
2691 ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_WRITE);
2692}
2693
2694static void
2695_ecore_con_event_client_add_free(Ecore_Con_Server *obj,
2696 void *ev)
2697{
2698 Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
2699 Ecore_Con_Event_Client_Add *e;
2700
2701 e = ev;
2702 if (e->client)
2703 {
2704 Efl_Network_Client_Data *cl = efl_data_scope_get(e->client, EFL_NETWORK_CLIENT_CLASS);
2705 Eina_Bool svrfreed = EINA_FALSE;
2706
2707 if ((svr) && (cl))
2708 {
2709 cl->event_count = eina_list_remove(cl->event_count, e);
2710 if (cl->host_server)
2711 {
2712 Efl_Network_Server_Data *host_server = efl_data_scope_get(cl->host_server, EFL_NETWORK_SERVER_CLASS);
2713 if (host_server)
2714 host_server->event_count = eina_list_remove(host_server->event_count, ev);
2715 if ((!svr->event_count) && (svr->delete_me))
2716 {
2717 _ecore_con_server_free(obj);
2718 svrfreed = EINA_TRUE;
2719 }
2720 }
2721 if (!svrfreed)
2722 {
2723 if ((!cl->event_count) && (cl->delete_me))
2724 ecore_con_client_del(e->client);
2725 }
2726 }
2727 }
2728
2729 ecore_con_event_client_add_free(e);
2730 _ecore_con_event_count--;
2731 if ((!_ecore_con_event_count) && (!_ecore_con_init_count))
2732 ecore_con_mempool_shutdown();
2733}
2734
2735static void
2736_ecore_con_event_client_del_free(Ecore_Con_Server *obj,
2737 void *ev)
2738{
2739 Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
2740 Ecore_Con_Event_Client_Del *e;
2741
2742 e = ev;
2743 if (e->client)
2744 {
2745 Efl_Network_Client_Data *cl = efl_data_scope_get(e->client, EFL_NETWORK_CLIENT_CLASS);
2746 Eina_Bool svrfreed = EINA_FALSE;
2747
2748 if ((svr) && (cl))
2749 {
2750 cl->event_count = eina_list_remove(cl->event_count, e);
2751 if (cl->host_server)
2752 {
2753 Efl_Network_Server_Data *host_server = efl_data_scope_get(cl->host_server, EFL_NETWORK_SERVER_CLASS);
2754 if (host_server)
2755 host_server->event_count = eina_list_remove(host_server->event_count, ev);
2756 if ((!svr->event_count) && (svr->delete_me))
2757 {
2758 _ecore_con_server_free(obj);
2759 svrfreed = EINA_TRUE;
2760 }
2761 }
2762 if (!svrfreed)
2763 {
2764 if (!cl->event_count)
2765 _ecore_con_client_free(e->client);
2766 }
2767 }
2768 }
2769 ecore_con_event_client_del_free(e);
2770 _ecore_con_event_count--;
2771 if ((!_ecore_con_event_count) && (!_ecore_con_init_count))
2772 ecore_con_mempool_shutdown();
2773}
2774
2775static void
2776_ecore_con_event_client_write_free(Ecore_Con_Server *obj,
2777 Ecore_Con_Event_Client_Write *e)
2778{
2779 Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
2780 if (e->client)
2781 {
2782 Efl_Network_Client_Data *cl = efl_data_scope_get(e->client, EFL_NETWORK_CLIENT_CLASS);
2783 Eina_Bool svrfreed = EINA_FALSE;
2784
2785 if ((svr) && (cl))
2786 {
2787 cl->event_count = eina_list_remove(cl->event_count, e);
2788 if (cl->host_server)
2789 {
2790 Efl_Network_Server_Data *host_server = efl_data_scope_get(cl->host_server, EFL_NETWORK_SERVER_CLASS);
2791 if (host_server)
2792 host_server->event_count = eina_list_remove(host_server->event_count, e);
2793 if ((!svr->event_count) && (svr->delete_me))
2794 {
2795 _ecore_con_server_free(obj);
2796 svrfreed = EINA_TRUE;
2797 }
2798 }
2799 if (!svrfreed)
2800 {
2801 Efl_Network_Server_Data *host_server = efl_data_scope_get(cl->host_server, EFL_NETWORK_SERVER_CLASS);
2802 if (((!cl->event_count) && (cl->delete_me)) ||
2803 ((cl->host_server &&
2804 ((host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_UDP ||
2805 (host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_MCAST))))
2806 ecore_con_client_del(e->client);
2807 }
2808 }
2809 }
2810 ecore_con_event_client_write_free(e);
2811 _ecore_con_event_count--;
2812 if ((!_ecore_con_event_count) && (!_ecore_con_init_count))
2813 ecore_con_mempool_shutdown();
2814}
2815
2816static void
2817_ecore_con_event_client_data_free(Ecore_Con_Server *obj,
2818 void *ev)
2819{
2820 Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
2821 Ecore_Con_Event_Client_Data *e;
2822
2823 e = ev;
2824 if (e->client)
2825 {
2826 Efl_Network_Client_Data *cl = efl_data_scope_get(e->client, EFL_NETWORK_CLIENT_CLASS);
2827 Eina_Bool svrfreed = EINA_FALSE;
2828
2829 if ((svr) && (cl))
2830 {
2831 cl->event_count = eina_list_remove(cl->event_count, e);
2832 if (cl->host_server)
2833 {
2834 Efl_Network_Server_Data *host_server = efl_data_scope_get(cl->host_server, EFL_NETWORK_SERVER_CLASS);
2835 if (host_server)
2836 host_server->event_count = eina_list_remove(host_server->event_count, ev);
2837 }
2838 if ((!svr->event_count) && (svr->delete_me))
2839 {
2840 _ecore_con_server_free(obj);
2841 svrfreed = EINA_TRUE;
2842 }
2843 if (!svrfreed)
2844 {
2845 Efl_Network_Server_Data *host_server = efl_data_scope_get(cl->host_server, EFL_NETWORK_SERVER_CLASS);
2846 if (((!cl->event_count) && (cl->delete_me)) ||
2847 ((cl->host_server &&
2848 ((host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_UDP ||
2849 (host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_MCAST))))
2850 ecore_con_client_del(e->client);
2851 }
2852 }
2853 }
2854 free(e->data);
2855 ecore_con_event_client_data_free(e);
2856 _ecore_con_event_count--;
2857 if ((!_ecore_con_event_count) && (!_ecore_con_init_count))
2858 ecore_con_mempool_shutdown();
2859}
2860
2861static void
2862_ecore_con_event_server_add_free(void *data EINA_UNUSED,
2863 void *ev)
2864{
2865 Ecore_Con_Event_Server_Add *e;
2866
2867 e = ev;
2868 if (e->server)
2869 {
2870 Efl_Network_Server_Data *svr = efl_data_scope_get(e->server, EFL_NETWORK_SERVER_CLASS);
2871 if (svr)
2872 {
2873 svr->event_count = eina_list_remove(svr->event_count, ev);
2874 if ((!svr->event_count) && (svr->delete_me))
2875 _ecore_con_server_free(e->server);
2876 }
2877 }
2878 ecore_con_event_server_add_free(e);
2879 _ecore_con_event_count--;
2880 if ((!_ecore_con_event_count) && (!_ecore_con_init_count))
2881 ecore_con_mempool_shutdown();
2882}
2883
2884static void
2885_ecore_con_event_server_del_free(void *data EINA_UNUSED,
2886 void *ev)
2887{
2888 Ecore_Con_Event_Server_Del *e;
2889
2890 e = ev;
2891 if (e->server)
2892 {
2893 Efl_Network_Server_Data *svr = efl_data_scope_get(e->server, EFL_NETWORK_SERVER_CLASS);
2894 if (svr)
2895 {
2896 svr->event_count = eina_list_remove(svr->event_count, ev);
2897 if (!svr->event_count)
2898 _ecore_con_server_free(e->server);
2899 }
2900 }
2901 ecore_con_event_server_del_free(e);
2902 _ecore_con_event_count--;
2903 if ((!_ecore_con_event_count) && (!_ecore_con_init_count))
2904 ecore_con_mempool_shutdown();
2905}
2906
2907static void
2908_ecore_con_event_server_write_free(void *data EINA_UNUSED,
2909 Ecore_Con_Event_Server_Write *e)
2910{
2911 if (e->server)
2912 {
2913 Efl_Network_Server_Data *svr = efl_data_scope_get(e->server, EFL_NETWORK_SERVER_CLASS);
2914 if (svr)
2915 {
2916 svr->event_count = eina_list_remove(svr->event_count, e);
2917 if ((!svr->event_count) && (svr->delete_me))
2918 _ecore_con_server_free(e->server);
2919 }
2920 }
2921 ecore_con_event_server_write_free(e);
2922 _ecore_con_event_count--;
2923 if ((!_ecore_con_event_count) && (!_ecore_con_init_count))
2924 ecore_con_mempool_shutdown();
2925}
2926
2927static void
2928_ecore_con_event_server_data_free(void *data EINA_UNUSED,
2929 void *ev)
2930{
2931 Ecore_Con_Event_Server_Data *e;
2932
2933 e = ev;
2934 if (e->server)
2935 {
2936 Efl_Network_Server_Data *svr = efl_data_scope_get(e->server, EFL_NETWORK_SERVER_CLASS);
2937 if (svr)
2938 {
2939 svr->event_count = eina_list_remove(svr->event_count, ev);
2940 if ((!svr->event_count) && (svr->delete_me))
2941 _ecore_con_server_free(e->server);
2942 }
2943 }
2944
2945 free(e->data);
2946 ecore_con_event_server_data_free(e);
2947 _ecore_con_event_count--;
2948 if ((!_ecore_con_event_count) && (!_ecore_con_init_count))
2949 ecore_con_mempool_shutdown();
2950}
2951
2952static void
2953_ecore_con_event_server_error_free(void *data EINA_UNUSED, Ecore_Con_Event_Server_Error *e)
2954{
2955 if (e->server)
2956 {
2957 Efl_Network_Server_Data *svr = efl_data_scope_get(e->server, EFL_NETWORK_SERVER_CLASS);
2958 if (svr)
2959 {
2960 svr->event_count = eina_list_remove(svr->event_count, e);
2961 if ((!svr->event_count) && (svr->delete_me))
2962 _ecore_con_server_free(e->server);
2963 }
2964 }
2965 free(e->error);
2966 ecore_con_event_server_error_free(e);
2967 _ecore_con_event_count--;
2968 if ((!_ecore_con_event_count) && (!_ecore_con_init_count))
2969 ecore_con_mempool_shutdown();
2970}
2971
2972static void
2973_ecore_con_event_client_error_free(Ecore_Con_Server *obj, Ecore_Con_Event_Client_Error *e)
2974{
2975 Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
2976 if (e->client)
2977 {
2978 Efl_Network_Client_Data *cl = efl_data_scope_get(e->client, EFL_NETWORK_CLIENT_CLASS);
2979 Eina_Bool svrfreed = EINA_FALSE;
2980
2981 if ((svr) && (cl))
2982 {
2983 if (eina_list_data_find(svr->clients, e->client))
2984 {
2985 cl->event_count = eina_list_remove(cl->event_count, e);
2986 if ((!cl->event_count) && (cl->delete_me))
2987 {
2988 _ecore_con_client_free(e->client);
2989 svrfreed = EINA_TRUE;
2990 }
2991 }
2992 svr->event_count = eina_list_remove(svr->event_count, e);
2993 if (!svrfreed)
2994 {
2995 if ((!svr->event_count) && (svr->delete_me))
2996 _ecore_con_server_free(obj);
2997 }
2998 }
2999 }
3000 free(e->error);
3001 ecore_con_event_client_error_free(e);
3002 _ecore_con_event_count--;
3003 if ((!_ecore_con_event_count) && (!_ecore_con_init_count))
3004 ecore_con_mempool_shutdown();
3005}
3006
3007static void
3008_ecore_con_lookup_done(void *data,
3009 Ecore_Con_Info *infos)
3010{
3011 Ecore_Con_Server *obj = data;
3012 Ecore_Con_Lookup *lk;
3013
3014 Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
3015 if (!svr) return;
3016 lk = svr->data;
3017
3018 if (infos)
3019 lk->done_cb(infos->info.ai_canonname, infos->ip,
3020 infos->info.ai_addr, infos->info.ai_addrlen,
3021 (void *)lk->data);
3022 else
3023 lk->done_cb(NULL, NULL, NULL, 0, (void *)lk->data);
3024
3025 free(lk);
3026} 184}
3027 185
3028#include "efl_network.eo.c"
3029#include "efl_network_client.eo.c"
3030#include "efl_network_server.eo.c"
3031#include "efl_network_connector.eo.c"
3032 186
3033#ifndef _WIN32 187#ifndef _WIN32
3034Eina_Bool 188Eina_Bool
diff --git a/src/lib/ecore_con/ecore_con_alloc.c b/src/lib/ecore_con/ecore_con_alloc.c
index 1c04a557bc..b5d49b9486 100644
--- a/src/lib/ecore_con/ecore_con_alloc.c
+++ b/src/lib/ecore_con/ecore_con_alloc.c
@@ -35,7 +35,9 @@ GENERIC_ALLOC_FREE(Ecore_Con_Event_Client_Del, ecore_con_event_client_del);
35GENERIC_ALLOC_FREE(Ecore_Con_Event_Client_Write, ecore_con_event_client_write); 35GENERIC_ALLOC_FREE(Ecore_Con_Event_Client_Write, ecore_con_event_client_write);
36GENERIC_ALLOC_FREE(Ecore_Con_Event_Client_Data, ecore_con_event_client_data); 36GENERIC_ALLOC_FREE(Ecore_Con_Event_Client_Data, ecore_con_event_client_data);
37GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Error, ecore_con_event_server_error); 37GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Error, ecore_con_event_server_error);
38GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Upgrade, ecore_con_event_server_upgrade);
38GENERIC_ALLOC_FREE(Ecore_Con_Event_Client_Error, ecore_con_event_client_error); 39GENERIC_ALLOC_FREE(Ecore_Con_Event_Client_Error, ecore_con_event_client_error);
40GENERIC_ALLOC_FREE(Ecore_Con_Event_Client_Upgrade, ecore_con_event_client_upgrade);
39GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Add, ecore_con_event_server_add); 41GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Add, ecore_con_event_server_add);
40GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Del, ecore_con_event_server_del); 42GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Del, ecore_con_event_server_del);
41GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Write, ecore_con_event_server_write); 43GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Write, ecore_con_event_server_write);
@@ -48,7 +50,9 @@ static Ecore_Con_Mempool *mempool_array[] = {
48 &ecore_con_event_client_write_mp, 50 &ecore_con_event_client_write_mp,
49 &ecore_con_event_client_data_mp, 51 &ecore_con_event_client_data_mp,
50 &ecore_con_event_server_error_mp, 52 &ecore_con_event_server_error_mp,
53 &ecore_con_event_server_upgrade_mp,
51 &ecore_con_event_client_error_mp, 54 &ecore_con_event_client_error_mp,
55 &ecore_con_event_client_upgrade_mp,
52 &ecore_con_event_server_add_mp, 56 &ecore_con_event_server_add_mp,
53 &ecore_con_event_server_del_mp, 57 &ecore_con_event_server_del_mp,
54 &ecore_con_event_server_write_mp, 58 &ecore_con_event_server_write_mp,
diff --git a/src/lib/ecore_con/ecore_con_eet.c b/src/lib/ecore_con/ecore_con_eet.c
index 1cf9954ebc..aed9b9fc11 100644
--- a/src/lib/ecore_con/ecore_con_eet.c
+++ b/src/lib/ecore_con/ecore_con_eet.c
@@ -17,6 +17,9 @@
17 17
18#include <Eina.h> 18#include <Eina.h>
19 19
20#include "Ecore.h"
21#include "Ecore_Con.h"
22#include "ecore_con_private.h"
20#include "Ecore_Con_Eet.h" 23#include "Ecore_Con_Eet.h"
21 24
22#define ECORE_CON_EET_RAW_MAGIC 0xDEAD007 25#define ECORE_CON_EET_RAW_MAGIC 0xDEAD007
@@ -699,7 +702,7 @@ _ecore_con_eet_base_efl_object_finalize(Eo *obj, Ecore_Con_Eet_Base_Data *pd)
699EOLIAN static void 702EOLIAN static void
700_ecore_con_eet_base_server_set(Eo *obj EINA_UNUSED, Ecore_Con_Eet_Base_Data *pd, Ecore_Con_Server *data) 703_ecore_con_eet_base_server_set(Eo *obj EINA_UNUSED, Ecore_Con_Eet_Base_Data *pd, Ecore_Con_Server *data)
701{ 704{
702 if (!efl_isa(data, EFL_NETWORK_SERVER_CLASS)) 705 if (!ecore_con_server_check(data))
703 return; 706 return;
704 707
705 pd->server = data; 708 pd->server = data;
diff --git a/src/lib/ecore_con/ecore_con_eet_base.eo b/src/lib/ecore_con/ecore_con_eet_base.eo
index fcbc83574f..9f57ea6e18 100644
--- a/src/lib/ecore_con/ecore_con_eet_base.eo
+++ b/src/lib/ecore_con/ecore_con_eet_base.eo
@@ -1,5 +1,4 @@
1import efl_network_server; 1struct @extern Ecore_Con_Server;
2
3type @extern Ecore_Con_Eet_Data_Cb: __undefined_type; [[Ecore connection eet data callback type]] /* FIXME: function pointers not supported. */ 2type @extern Ecore_Con_Eet_Data_Cb: __undefined_type; [[Ecore connection eet data callback type]] /* FIXME: function pointers not supported. */
4type @extern Ecore_Con_Eet_Raw_Data_Cb: __undefined_type; [[Ecore connection eet raw data callback type]]/* FIXME: function pointers not supported. */ 3type @extern Ecore_Con_Eet_Raw_Data_Cb: __undefined_type; [[Ecore connection eet raw data callback type]]/* FIXME: function pointers not supported. */
5 4
@@ -19,7 +18,7 @@ class Ecore.Con.Eet.Base (Efl.Object) {
19 get { 18 get {
20 } 19 }
21 values { 20 values {
22 data: Efl.Network.Server; [[Server object]] 21 data: ptr(Ecore_Con_Server); [[Server object]]
23 } 22 }
24 } 23 }
25 @property data_callback { 24 @property data_callback {
diff --git a/src/lib/ecore_con/ecore_con_info.c b/src/lib/ecore_con/ecore_con_info.c
deleted file mode 100644
index 5038817c61..0000000000
--- a/src/lib/ecore_con/ecore_con_info.c
+++ /dev/null
@@ -1,297 +0,0 @@
1/*
2 * getaddrinfo with callback
3 *
4 * man getaddrinfo
5 *
6 */
7
8#ifdef HAVE_CONFIG_H
9# include <config.h>
10#endif
11
12#ifdef STDC_HEADERS
13# include <stdlib.h>
14# include <stddef.h>
15#else
16# ifdef HAVE_STDLIB_H
17# include <stdlib.h>
18# endif
19#endif
20
21#include <string.h>
22#include <sys/types.h>
23#include <unistd.h>
24#include <fcntl.h>
25#include <ctype.h>
26#ifdef HAVE_SYS_SOCKET_H
27# include <sys/socket.h>
28#endif
29#ifdef __OpenBSD__
30# include <sys/types.h>
31#endif
32#ifdef HAVE_NETINET_IN_H
33# include <netinet/in.h>
34#endif
35#ifdef HAVE_ARPA_INET_H
36# include <arpa/inet.h>
37#endif
38#ifdef HAVE_ARPA_NAMESER_H
39# include <arpa/nameser.h>
40#endif
41#ifdef HAVE_NETDB_H
42# include <netdb.h>
43#endif
44
45#include <errno.h>
46
47#include "Ecore.h"
48#include "ecore_private.h"
49#include "ecore_con_private.h"
50
51typedef struct _CB_Data CB_Data;
52
53struct _CB_Data
54{
55 EINA_INLIST;
56 Ecore_Con_Info_Cb cb_done;
57 void *data;
58 Ecore_Thread *thread;
59 struct addrinfo hints;
60 Ecore_Con_Info *result;
61 int error;
62 char service[NI_MAXSERV];
63 char name[NI_MAXHOST];
64};
65
66static void _ecore_con_info_slave_free (CB_Data *cbdata);
67static void _ecore_con_info_slave_result(void *data, Ecore_Thread *th);
68static void _ecore_con_info_slave_cancel(void *data, Ecore_Thread *th);
69static void _ecore_con_info_slave_lookup(void *data, Ecore_Thread *th);
70
71static int info_init = 0;
72static CB_Data *info_slaves = NULL;
73
74int
75ecore_con_info_init(void)
76{
77 info_init++;
78 return info_init;
79}
80
81int
82ecore_con_info_shutdown(void)
83{
84 info_init--;
85 if (info_init == 0)
86 {
87 while (info_slaves)
88 {
89 CB_Data *cbdata;
90
91 cbdata = info_slaves;
92 info_slaves = (CB_Data *)eina_inlist_remove
93 (EINA_INLIST_GET(info_slaves), EINA_INLIST_GET(info_slaves));
94 ecore_thread_cancel(cbdata->thread);
95 }
96 }
97 return info_init;
98}
99
100static void
101_hints_fill(struct addrinfo *hints, int flags, int proto)
102{
103 memset(hints, 0, sizeof(struct addrinfo));
104 hints->ai_family = AF_UNSPEC;
105 hints->ai_flags = flags;
106 if (proto == IPPROTO_TCP) hints->ai_socktype = SOCK_STREAM;
107 else hints->ai_socktype = SOCK_DGRAM;
108 hints->ai_protocol = proto;
109}
110
111int
112ecore_con_info_tcp_connect(Ecore_Con_Server *svr,
113 Ecore_Con_Info_Cb done_cb,
114 void *data)
115{
116 struct addrinfo hints;
117 _hints_fill(&hints, AI_CANONNAME, IPPROTO_TCP);
118 return ecore_con_info_get(svr, done_cb, data, &hints);
119}
120
121int
122ecore_con_info_tcp_listen(Ecore_Con_Server *svr,
123 Ecore_Con_Info_Cb done_cb,
124 void *data)
125{
126 struct addrinfo hints;
127 _hints_fill(&hints, AI_PASSIVE, IPPROTO_TCP);
128 return ecore_con_info_get(svr, done_cb, data, &hints);
129}
130
131int
132ecore_con_info_udp_connect(Ecore_Con_Server *svr,
133 Ecore_Con_Info_Cb done_cb,
134 void *data)
135{
136 struct addrinfo hints;
137 _hints_fill(&hints, AI_CANONNAME, IPPROTO_UDP);
138 return ecore_con_info_get(svr, done_cb, data, &hints);
139}
140
141int
142ecore_con_info_udp_listen(Ecore_Con_Server *svr,
143 Ecore_Con_Info_Cb done_cb,
144 void *data)
145{
146 struct addrinfo hints;
147 _hints_fill(&hints, AI_PASSIVE, IPPROTO_UDP);
148 return ecore_con_info_get(svr, done_cb, data, &hints);
149}
150
151int
152ecore_con_info_mcast_listen(Ecore_Con_Server *svr,
153 Ecore_Con_Info_Cb done_cb,
154 void *data)
155{
156 struct addrinfo hints;
157 _hints_fill(&hints, 0, IPPROTO_UDP);
158 return ecore_con_info_get(svr, done_cb, data, &hints);
159}
160
161EAPI int
162ecore_con_info_get(Ecore_Con_Server *obj,
163 Ecore_Con_Info_Cb done_cb,
164 void *data,
165 struct addrinfo *hints)
166{
167 Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
168 CB_Data *cbdata;
169
170 if (!svr) return 0;
171 cbdata = calloc(1, sizeof(CB_Data));
172 if (!cbdata)
173 {
174 ecore_con_event_server_error(obj, "Memory allocation failure");
175 return 0;
176 }
177
178 cbdata->cb_done = done_cb;
179 cbdata->data = data;
180 cbdata->hints = *hints;
181 cbdata->thread = ecore_thread_run(_ecore_con_info_slave_lookup,
182 _ecore_con_info_slave_result,
183 _ecore_con_info_slave_cancel,
184 cbdata);
185 if (!cbdata->thread)
186 {
187 free(cbdata);
188 ecore_con_event_server_error(obj, "Memory allocation failure");
189 return 0;
190 }
191 eina_convert_itoa(svr->ecs ? svr->ecs->port : svr->port, cbdata->service);
192 strncpy(cbdata->name, svr->ecs ? svr->ecs->ip : svr->name, NI_MAXHOST - 1);
193 cbdata->name[NI_MAXHOST - 1] = 0;
194 info_slaves = (CB_Data *)eina_inlist_append(EINA_INLIST_GET(info_slaves),
195 EINA_INLIST_GET(cbdata));
196 svr->infos = eina_list_append(svr->infos, cbdata);
197 return 1;
198}
199
200void
201ecore_con_info_data_clear(void *info)
202{
203 CB_Data *cbdata = info;
204 cbdata->data = NULL;
205}
206
207static void
208_ecore_con_info_slave_free(CB_Data *cbdata)
209{
210 if (info_slaves)
211 info_slaves = (CB_Data *)eina_inlist_remove(EINA_INLIST_GET(info_slaves),
212 EINA_INLIST_GET(cbdata));
213 if (cbdata->result) free(cbdata->result);
214 cbdata->result = NULL;
215 if (cbdata->data) ecore_con_server_infos_del(cbdata->data, cbdata);
216 cbdata->data = NULL;
217 free(cbdata);
218}
219
220static void
221_ecore_con_info_slave_result(void *data, Ecore_Thread *th EINA_UNUSED)
222{
223 CB_Data *cbdata = data;
224
225 if (cbdata->result) // lookup ok
226 {
227 if (cbdata->data) cbdata->cb_done(cbdata->data, cbdata->result);
228 }
229 else // an error occured
230 {
231 if (cbdata->data)
232 {
233 char *str = strerror(cbdata->error);
234 ecore_con_event_server_error(cbdata->data, str);
235 cbdata->cb_done(cbdata->data, NULL);
236 }
237 }
238 if (cbdata->data) ecore_con_server_infos_del(cbdata->data, cbdata);
239 cbdata->data = NULL;
240 _ecore_con_info_slave_free(cbdata);
241}
242
243static void
244_ecore_con_info_slave_cancel(void *data, Ecore_Thread *th EINA_UNUSED)
245{
246 CB_Data *cbdata = data;
247 _ecore_con_info_slave_free(cbdata);
248}
249
250static void
251_ecore_con_info_slave_lookup(void *data, Ecore_Thread *th EINA_UNUSED)
252{
253 CB_Data *cbdata = data;
254 struct addrinfo *result = NULL;
255
256 // do lookup, fill cbdata
257 if ((!getaddrinfo(cbdata->name, cbdata->service, &(cbdata->hints), &result))
258 && (result))
259 {
260 Ecore_Con_Info *info;
261 unsigned int canonname_size = 0, size;
262
263 if (result->ai_canonname)
264 canonname_size = strlen(result->ai_canonname) + 1;
265 size = sizeof(Ecore_Con_Info) + result->ai_addrlen + canonname_size;
266 info = calloc(1, size);
267 if (info)
268 {
269 char hbuf[NI_MAXHOST] = { 0 }, sbuf[NI_MAXSERV] = { 0 }, *p;
270
271 info->size = size;
272 memcpy(&(info->info), result, sizeof(struct addrinfo));
273 p = ((char *)info) + sizeof(Ecore_Con_Info);
274 memcpy(p, result->ai_addr, result->ai_addrlen);
275 info->info.ai_addr = (struct sockaddr *)p;
276 if (result->ai_canonname)
277 {
278 p = ((char *)info) + sizeof(Ecore_Con_Info) + result->ai_addrlen;
279 memcpy(p, result->ai_canonname, canonname_size);
280 info->info.ai_canonname = p;
281 }
282 // we don't care about multiple entries - take first one then
283 info->info.ai_next = NULL;
284 if (!getnameinfo(result->ai_addr, result->ai_addrlen,
285 hbuf, sizeof(hbuf), sbuf, sizeof(sbuf),
286 NI_NUMERICHOST | NI_NUMERICSERV))
287 {
288 memcpy(info->ip, hbuf, sizeof(info->ip));
289 memcpy(info->service, sbuf, sizeof(info->service));
290 }
291 cbdata->result = info;
292 }
293 if (!cbdata->result) free(info);
294 }
295 if (!cbdata->result) cbdata->error = errno;
296 if (result) freeaddrinfo(result);
297}
diff --git a/src/lib/ecore_con/ecore_con_legacy.c b/src/lib/ecore_con/ecore_con_legacy.c
index 107ccfd41f..0aa1760987 100644
--- a/src/lib/ecore_con/ecore_con_legacy.c
+++ b/src/lib/ecore_con/ecore_con_legacy.c
@@ -1,15 +1,2508 @@
1/******************************************************************** 1#ifdef HAVE_CONFIG_H
2 * ecore_con_url.eo.c 2# include <config.h>
3 *******************************************************************/ 3#endif
4
5#ifdef HAVE_ARPA_INET_H
6# include <arpa/inet.h>
7#endif
8
9#ifdef HAVE_EVIL
10# include <Evil.h>
11#endif
12
13#include "Ecore.h"
14#include "ecore_private.h"
15#include "Ecore_Con.h"
16#include "ecore_con_private.h"
17
18/* This file exists solely to provide ABI compatibility */
19
20struct _Ecore_Con_Server
21{
22 ECORE_MAGIC;
23 Eo *dialer;
24 Eo *server;
25 struct {
26 Efl_Future *job;
27 Eo *clients_ctx;
28 Eina_List *certs;
29 Eina_List *privkeys;
30 Eina_List *crls;
31 Eina_List *cafiles;
32 Eina_Stringshare *verify_name;
33 Eina_Bool verify;
34 Eina_Bool verify_basic;
35 Eina_Bool upgrading;
36 Ecore_Con_Type upgrade_type;
37 } ssl;
38 Eina_List *clients;
39 Eina_List *event_count;
40 const void *data;
41 Eina_Stringshare *name;
42 Eina_Stringshare *ip;
43 size_t pending_write;
44 double start_time;
45 double timeout;
46 Ecore_Con_Type type;
47 int port;
48 Eina_Bool want_mcast;
49 Eina_Bool is_dialer;
50 Eina_Bool connecting;
51 Eina_Bool delete_me;
52};
53
54struct _Ecore_Con_Client
55{
56 ECORE_MAGIC;
57 Eo *socket;
58 Ecore_Con_Server *svr;
59 Eina_List *event_count;
60 const void *data;
61 Eina_Stringshare *ip;
62 struct {
63 Efl_Future *job;
64 Eo *ctx;
65 Eina_Bool upgrading;
66 } ssl;
67 size_t pending_write;
68 double start_time;
69 int port;
70 Eina_Bool delete_me;
71};
72
73typedef struct _Ecore_Con_Lookup_Ctx {
74 Ecore_Thread *thread;
75 Ecore_Con_Dns_Cb cb;
76 const void *data;
77} Ecore_Con_Lookup_Ctx;
78
79/* allows delete_me to be true */
80#define ECORE_CON_SERVER_CHECK_RELAXED_RETURN(svr, ...) \
81 do \
82 { \
83 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) \
84 { \
85 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, __FUNCTION__); \
86 return __VA_ARGS__; \
87 } \
88 } \
89 while (0)
90
91#define ECORE_CON_SERVER_CHECK_RETURN(svr, ...) \
92 do \
93 { \
94 ECORE_CON_SERVER_CHECK_RELAXED_RETURN(svr, __VA_ARGS__) ; \
95 EINA_SAFETY_ON_TRUE_RETURN_VAL(svr->delete_me, __VA_ARGS__); \
96 } \
97 while (0)
98
99#define ECORE_CON_CLIENT_CHECK_RELAXED_RETURN(cl, ...) \
100 do \
101 { \
102 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) \
103 { \
104 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, __FUNCTION__); \
105 return __VA_ARGS__; \
106 } \
107 } \
108 while (0)
109
110#define ECORE_CON_CLIENT_CHECK_RETURN(cl, ...) \
111 do \
112 { \
113 ECORE_CON_CLIENT_CHECK_RELAXED_RETURN(cl, __VA_ARGS__) ; \
114 EINA_SAFETY_ON_TRUE_RETURN_VAL(cl->delete_me, __VA_ARGS__); \
115 } \
116 while (0)
117
118
119/* from ecore_con_alloc.c */
120#define GENERIC_ALLOC_FREE_HEADER(TYPE, Type) \
121 TYPE *Type##_alloc(void); \
122 void Type##_free(TYPE *e);
123