diff options
author | David Walter Seikel | 2013-01-13 17:29:19 +1000 |
---|---|---|
committer | David Walter Seikel | 2013-01-13 17:29:19 +1000 |
commit | 07274513e984f0b5544586c74508ccd16e7dcafa (patch) | |
tree | b32ff2a9136fbc1a4a6a0ed1e4d79cde0f5f16d9 /libraries/ecore/src/lib/ecore_con/ecore_con.c | |
parent | Added Irrlicht 1.8, but without all the Windows binaries. (diff) | |
download | SledjHamr-07274513e984f0b5544586c74508ccd16e7dcafa.zip SledjHamr-07274513e984f0b5544586c74508ccd16e7dcafa.tar.gz SledjHamr-07274513e984f0b5544586c74508ccd16e7dcafa.tar.bz2 SledjHamr-07274513e984f0b5544586c74508ccd16e7dcafa.tar.xz |
Remove EFL, since it's been released now.
Diffstat (limited to 'libraries/ecore/src/lib/ecore_con/ecore_con.c')
-rw-r--r-- | libraries/ecore/src/lib/ecore_con/ecore_con.c | 2583 |
1 files changed, 0 insertions, 2583 deletions
diff --git a/libraries/ecore/src/lib/ecore_con/ecore_con.c b/libraries/ecore/src/lib/ecore_con/ecore_con.c deleted file mode 100644 index fe83478..0000000 --- a/libraries/ecore/src/lib/ecore_con/ecore_con.c +++ /dev/null | |||
@@ -1,2583 +0,0 @@ | |||
1 | #ifdef HAVE_CONFIG_H | ||
2 | # include <config.h> | ||
3 | #endif | ||
4 | |||
5 | #include <stdio.h> | ||
6 | #include <string.h> | ||
7 | #include <sys/types.h> | ||
8 | #include <sys/stat.h> | ||
9 | #include <errno.h> | ||
10 | #include <unistd.h> | ||
11 | #include <fcntl.h> | ||
12 | |||
13 | #ifdef HAVE_NETINET_TCP_H | ||
14 | # include <netinet/tcp.h> | ||
15 | #endif | ||
16 | |||
17 | #ifdef HAVE_NETINET_IN_H | ||
18 | # include <netinet/in.h> | ||
19 | #endif | ||
20 | |||
21 | #ifdef HAVE_ARPA_INET_H | ||
22 | # include <arpa/inet.h> | ||
23 | #endif | ||
24 | |||
25 | #ifdef HAVE_SYS_SOCKET_H | ||
26 | # include <sys/socket.h> | ||
27 | #endif | ||
28 | |||
29 | #ifdef HAVE_SYS_UN_H | ||
30 | # include <sys/un.h> | ||
31 | #endif | ||
32 | |||
33 | #ifdef HAVE_WS2TCPIP_H | ||
34 | # include <ws2tcpip.h> | ||
35 | #endif | ||
36 | |||
37 | #ifdef HAVE_EVIL | ||
38 | # include <Evil.h> | ||
39 | #endif | ||
40 | |||
41 | #include "Ecore.h" | ||
42 | #include "ecore_private.h" | ||
43 | #include "Ecore_Con.h" | ||
44 | #include "ecore_con_private.h" | ||
45 | |||
46 | static Eina_Bool _ecore_con_client_timer(Ecore_Con_Client *cl); | ||
47 | static void _ecore_con_cl_timer_update(Ecore_Con_Client *cl); | ||
48 | static Eina_Bool _ecore_con_server_timer(Ecore_Con_Server *svr); | ||
49 | static void _ecore_con_server_timer_update(Ecore_Con_Server *svr); | ||
50 | |||
51 | static void _ecore_con_cb_tcp_connect(void *data, | ||
52 | Ecore_Con_Info *info); | ||
53 | static void _ecore_con_cb_udp_connect(void *data, | ||
54 | Ecore_Con_Info *info); | ||
55 | static void _ecore_con_cb_tcp_listen(void *data, | ||
56 | Ecore_Con_Info *info); | ||
57 | static void _ecore_con_cb_udp_listen(void *data, | ||
58 | Ecore_Con_Info *info); | ||
59 | |||
60 | static void _ecore_con_server_free(Ecore_Con_Server *svr); | ||
61 | static void _ecore_con_client_free(Ecore_Con_Client *cl); | ||
62 | |||
63 | static void _ecore_con_cl_read(Ecore_Con_Server *svr); | ||
64 | static Eina_Bool _ecore_con_svr_tcp_handler(void *data, | ||
65 | Ecore_Fd_Handler *fd_handler); | ||
66 | static Eina_Bool _ecore_con_cl_handler(void *data, | ||
67 | Ecore_Fd_Handler *fd_handler); | ||
68 | static Eina_Bool _ecore_con_cl_udp_handler(void *data, | ||
69 | Ecore_Fd_Handler *fd_handler); | ||
70 | static Eina_Bool _ecore_con_svr_udp_handler(void *data, | ||
71 | Ecore_Fd_Handler *fd_handler); | ||
72 | |||
73 | static void _ecore_con_svr_cl_read(Ecore_Con_Client *cl); | ||
74 | static Eina_Bool _ecore_con_svr_cl_handler(void *data, | ||
75 | Ecore_Fd_Handler *fd_handler); | ||
76 | |||
77 | static void _ecore_con_server_flush(Ecore_Con_Server *svr); | ||
78 | static void _ecore_con_client_flush(Ecore_Con_Client *cl); | ||
79 | |||
80 | static void _ecore_con_event_client_add_free(Ecore_Con_Server *svr, | ||
81 | void *ev); | ||
82 | static void _ecore_con_event_client_del_free(Ecore_Con_Server *svr, | ||
83 | void *ev); | ||
84 | static void _ecore_con_event_client_data_free(Ecore_Con_Server *svr, | ||
85 | void *ev); | ||
86 | static void _ecore_con_event_server_add_free(void *data, | ||
87 | void *ev); | ||
88 | static void _ecore_con_event_server_del_free(void *data, | ||
89 | void *ev); | ||
90 | static void _ecore_con_event_server_data_free(void *data, | ||
91 | void *ev); | ||
92 | static void _ecore_con_event_server_error_free(void *data, | ||
93 | Ecore_Con_Event_Server_Error *e); | ||
94 | static void _ecore_con_event_client_error_free(Ecore_Con_Server *svr, | ||
95 | Ecore_Con_Event_Client_Error *e); | ||
96 | static void _ecore_con_event_server_write_free(void *data, | ||
97 | Ecore_Con_Event_Server_Write *e); | ||
98 | static void _ecore_con_event_client_write_free(Ecore_Con_Server *svr, | ||
99 | Ecore_Con_Event_Client_Write *e); | ||
100 | |||
101 | static void _ecore_con_lookup_done(void *data, | ||
102 | Ecore_Con_Info *infos); | ||
103 | |||
104 | static const char * _ecore_con_pretty_ip(struct sockaddr *client_addr); | ||
105 | |||
106 | |||
107 | void | ||
108 | _ecore_con_client_kill(Ecore_Con_Client *cl) | ||
109 | { | ||
110 | if (cl->delete_me) | ||
111 | DBG("Multi kill request for client %p", cl); | ||
112 | else | ||
113 | { | ||
114 | ecore_con_event_client_del(cl); | ||
115 | if (cl->buf) return; | ||
116 | } | ||
117 | INF("Lost client %s", (cl->ip) ? cl->ip : ""); | ||
118 | if (cl->fd_handler) | ||
119 | ecore_main_fd_handler_del(cl->fd_handler); | ||
120 | |||
121 | cl->fd_handler = NULL; | ||
122 | } | ||
123 | |||
124 | void | ||
125 | _ecore_con_server_kill(Ecore_Con_Server *svr) | ||
126 | { | ||
127 | if (svr->delete_me) | ||
128 | DBG("Multi kill request for svr %p", svr); | ||
129 | else | ||
130 | ecore_con_event_server_del(svr); | ||
131 | |||
132 | if (svr->fd_handler) | ||
133 | ecore_main_fd_handler_del(svr->fd_handler); | ||
134 | |||
135 | svr->fd_handler = NULL; | ||
136 | } | ||
137 | |||
138 | #define _ecore_con_server_kill(svr) do { \ | ||
139 | DBG("KILL %p", (svr)); \ | ||
140 | _ecore_con_server_kill((svr)); \ | ||
141 | } while (0) | ||
142 | |||
143 | #define _ecore_con_client_kill(cl) do { \ | ||
144 | DBG("KILL %p", (cl)); \ | ||
145 | _ecore_con_client_kill((cl)); \ | ||
146 | } while (0) | ||
147 | |||
148 | EAPI int ECORE_CON_EVENT_CLIENT_ADD = 0; | ||
149 | EAPI int ECORE_CON_EVENT_CLIENT_DEL = 0; | ||
150 | EAPI int ECORE_CON_EVENT_SERVER_ADD = 0; | ||
151 | EAPI int ECORE_CON_EVENT_SERVER_DEL = 0; | ||
152 | EAPI int ECORE_CON_EVENT_CLIENT_DATA = 0; | ||
153 | EAPI int ECORE_CON_EVENT_SERVER_DATA = 0; | ||
154 | EAPI int ECORE_CON_EVENT_CLIENT_WRITE = 0; | ||
155 | EAPI int ECORE_CON_EVENT_SERVER_WRITE = 0; | ||
156 | EAPI int ECORE_CON_EVENT_CLIENT_ERROR = 0; | ||
157 | EAPI int ECORE_CON_EVENT_SERVER_ERROR = 0; | ||
158 | EAPI int ECORE_CON_EVENT_PROXY_BIND = 0; | ||
159 | |||
160 | static Eina_List *servers = NULL; | ||
161 | static int _ecore_con_init_count = 0; | ||
162 | static int _ecore_con_event_count = 0; | ||
163 | int _ecore_con_log_dom = -1; | ||
164 | Ecore_Con_Socks *_ecore_con_proxy_once = NULL; | ||
165 | Ecore_Con_Socks *_ecore_con_proxy_global = NULL; | ||
166 | |||
167 | EAPI int | ||
168 | ecore_con_init(void) | ||
169 | { | ||
170 | if (++_ecore_con_init_count != 1) | ||
171 | return _ecore_con_init_count; | ||
172 | |||
173 | #ifdef HAVE_EVIL | ||
174 | if (!evil_init()) | ||
175 | return --_ecore_con_init_count; | ||
176 | |||
177 | #endif | ||
178 | |||
179 | if (!ecore_init()) | ||
180 | return --_ecore_con_init_count; | ||
181 | |||
182 | _ecore_con_log_dom = eina_log_domain_register | ||
183 | ("ecore_con", ECORE_CON_DEFAULT_LOG_COLOR); | ||
184 | if (_ecore_con_log_dom < 0) | ||
185 | { | ||
186 | EINA_LOG_ERR("Impossible to create a log domain for Ecore Con."); | ||
187 | ecore_shutdown(); | ||
188 | return --_ecore_con_init_count; | ||
189 | } | ||
190 | |||
191 | ecore_con_mempool_init(); | ||
192 | |||
193 | ECORE_CON_EVENT_CLIENT_ADD = ecore_event_type_new(); | ||
194 | ECORE_CON_EVENT_CLIENT_DEL = ecore_event_type_new(); | ||
195 | ECORE_CON_EVENT_SERVER_ADD = ecore_event_type_new(); | ||
196 | ECORE_CON_EVENT_SERVER_DEL = ecore_event_type_new(); | ||
197 | ECORE_CON_EVENT_CLIENT_DATA = ecore_event_type_new(); | ||
198 | ECORE_CON_EVENT_SERVER_DATA = ecore_event_type_new(); | ||
199 | ECORE_CON_EVENT_CLIENT_WRITE = ecore_event_type_new(); | ||
200 | ECORE_CON_EVENT_SERVER_WRITE = ecore_event_type_new(); | ||
201 | ECORE_CON_EVENT_CLIENT_ERROR = ecore_event_type_new(); | ||
202 | ECORE_CON_EVENT_SERVER_ERROR = ecore_event_type_new(); | ||
203 | ECORE_CON_EVENT_PROXY_BIND = ecore_event_type_new(); | ||
204 | |||
205 | |||
206 | eina_magic_string_set(ECORE_MAGIC_CON_SERVER, "Ecore_Con_Server"); | ||
207 | eina_magic_string_set(ECORE_MAGIC_CON_CLIENT, "Ecore_Con_Server"); | ||
208 | eina_magic_string_set(ECORE_MAGIC_CON_URL, "Ecore_Con_Url"); | ||
209 | |||
210 | /* TODO Remember return value, if it fails, use gethostbyname() */ | ||
211 | ecore_con_socks_init(); | ||
212 | ecore_con_ssl_init(); | ||
213 | ecore_con_info_init(); | ||
214 | |||
215 | return _ecore_con_init_count; | ||
216 | } | ||
217 | |||
218 | EAPI int | ||
219 | ecore_con_shutdown(void) | ||
220 | { | ||
221 | Eina_List *l, *l2; | ||
222 | Ecore_Con_Server *svr; | ||
223 | |||
224 | if (--_ecore_con_init_count != 0) | ||
225 | return _ecore_con_init_count; | ||
226 | |||
227 | EINA_LIST_FOREACH_SAFE(servers, l, l2, svr) | ||
228 | { | ||
229 | Ecore_Con_Event_Server_Add *ev; | ||
230 | |||
231 | svr->delete_me = EINA_TRUE; | ||
232 | INF("svr %p is dead", svr); | ||
233 | /* some pointer hacks here to prevent double frees if people are being stupid */ | ||
234 | EINA_LIST_FREE(svr->event_count, ev) | ||
235 | ev->server = NULL; | ||
236 | _ecore_con_server_free(svr); | ||
237 | } | ||
238 | |||
239 | ecore_con_socks_shutdown(); | ||
240 | if (!_ecore_con_event_count) ecore_con_mempool_shutdown(); | ||
241 | |||
242 | ecore_con_info_shutdown(); | ||
243 | ecore_con_ssl_shutdown(); | ||
244 | eina_log_domain_unregister(_ecore_con_log_dom); | ||
245 | _ecore_con_log_dom = -1; | ||
246 | ecore_shutdown(); | ||
247 | #ifdef HAVE_EVIL | ||
248 | evil_shutdown(); | ||
249 | #endif | ||
250 | |||
251 | return _ecore_con_init_count; | ||
252 | } | ||
253 | |||
254 | EAPI Eina_Bool | ||
255 | ecore_con_lookup(const char *name, | ||
256 | Ecore_Con_Dns_Cb done_cb, | ||
257 | const void *data) | ||
258 | { | ||
259 | Ecore_Con_Server *svr; | ||
260 | Ecore_Con_Lookup *lk; | ||
261 | struct addrinfo hints; | ||
262 | |||
263 | if (!name || !done_cb) | ||
264 | return EINA_FALSE; | ||
265 | |||
266 | svr = calloc(1, sizeof(Ecore_Con_Server)); | ||
267 | if (!svr) | ||
268 | return EINA_FALSE; | ||
269 | |||
270 | lk = malloc(sizeof (Ecore_Con_Lookup)); | ||
271 | if (!lk) | ||
272 | { | ||
273 | free(svr); | ||
274 | return EINA_FALSE; | ||
275 | } | ||
276 | |||
277 | lk->done_cb = done_cb; | ||
278 | lk->data = data; | ||
279 | |||
280 | svr->name = strdup(name); | ||
281 | if (!svr->name) | ||
282 | goto on_error; | ||
283 | |||
284 | svr->type = ECORE_CON_REMOTE_TCP; | ||
285 | svr->port = 1025; | ||
286 | svr->data = lk; | ||
287 | svr->created = EINA_TRUE; | ||
288 | svr->reject_excess_clients = EINA_FALSE; | ||
289 | svr->client_limit = -1; | ||
290 | svr->clients = NULL; | ||
291 | svr->ppid = getpid(); | ||
292 | |||
293 | memset(&hints, 0, sizeof(struct addrinfo)); | ||
294 | hints.ai_family = AF_UNSPEC; | ||
295 | hints.ai_socktype = SOCK_STREAM; | ||
296 | hints.ai_flags = AI_CANONNAME; | ||
297 | hints.ai_protocol = IPPROTO_TCP; | ||
298 | hints.ai_canonname = NULL; | ||
299 | hints.ai_next = NULL; | ||
300 | hints.ai_addr = NULL; | ||
301 | |||
302 | if (ecore_con_info_get(svr, _ecore_con_lookup_done, svr, | ||
303 | &hints)) | ||
304 | return EINA_TRUE; | ||
305 | |||
306 | free(svr->name); | ||
307 | on_error: | ||
308 | free(lk); | ||
309 | free(svr); | ||
310 | return EINA_FALSE; | ||
311 | } | ||
312 | |||
313 | /** | ||
314 | * @addtogroup Ecore_Con_Server_Group Ecore Connection Server Functions | ||
315 | * | ||
316 | * Functions that operate on Ecore server objects. | ||
317 | * | ||
318 | * @{ | ||
319 | */ | ||
320 | |||
321 | /** | ||
322 | * @example ecore_con_server_example.c | ||
323 | * Shows how to write a simple server using the Ecore_Con library. | ||
324 | */ | ||
325 | |||
326 | EAPI Ecore_Con_Server * | ||
327 | ecore_con_server_add(Ecore_Con_Type compl_type, | ||
328 | const char *name, | ||
329 | int port, | ||
330 | const void *data) | ||
331 | { | ||
332 | Ecore_Con_Server *svr; | ||
333 | Ecore_Con_Type type; | ||
334 | |||
335 | if (port < 0 || !name) | ||
336 | return NULL; /* local user socket: FILE: ~/.ecore/[name]/[port] */ | ||
337 | |||
338 | /* local system socket: FILE: /tmp/.ecore_service|[name]|[port] */ | ||
339 | /* remote system socket: TCP/IP: [name]:[port] */ | ||
340 | svr = calloc(1, sizeof(Ecore_Con_Server)); | ||
341 | if (!svr) | ||
342 | return NULL; | ||
343 | |||
344 | svr->name = strdup(name); | ||
345 | if (!svr->name) | ||
346 | goto error; | ||
347 | |||
348 | svr->type = compl_type; | ||
349 | svr->port = port; | ||
350 | svr->data = (void *)data; | ||
351 | svr->created = EINA_TRUE; | ||
352 | svr->use_cert = (compl_type & ECORE_CON_SSL & ECORE_CON_LOAD_CERT) == ECORE_CON_LOAD_CERT; | ||
353 | svr->reject_excess_clients = EINA_FALSE; | ||
354 | svr->client_limit = -1; | ||
355 | svr->clients = NULL; | ||
356 | svr->ppid = getpid(); | ||
357 | if (ecore_con_ssl_server_prepare(svr, compl_type & ECORE_CON_SSL)) | ||
358 | goto error; | ||
359 | |||
360 | type = compl_type & ECORE_CON_TYPE; | ||
361 | |||
362 | if ((type == ECORE_CON_LOCAL_USER) || | ||
363 | (type == ECORE_CON_LOCAL_SYSTEM) || | ||
364 | (type == ECORE_CON_LOCAL_ABSTRACT)) | ||
365 | /* Local */ | ||
366 | #ifdef _WIN32 | ||
367 | if (!ecore_con_local_listen(svr)) | ||
368 | goto error; | ||
369 | #else | ||
370 | if (!ecore_con_local_listen(svr, _ecore_con_svr_tcp_handler, svr)) | ||
371 | goto error; | ||
372 | #endif | ||
373 | |||
374 | if ((type == ECORE_CON_REMOTE_TCP) || | ||
375 | (type == ECORE_CON_REMOTE_NODELAY) || | ||
376 | (type == ECORE_CON_REMOTE_CORK)) | ||
377 | { | ||
378 | /* TCP */ | ||
379 | if (!ecore_con_info_tcp_listen(svr, _ecore_con_cb_tcp_listen, | ||
380 | svr)) | ||
381 | goto error; | ||
382 | } | ||
383 | else if ((type == ECORE_CON_REMOTE_MCAST) || | ||
384 | (type == ECORE_CON_REMOTE_UDP)) | ||
385 | /* UDP and MCAST */ | ||
386 | if (!ecore_con_info_udp_listen(svr, _ecore_con_cb_udp_listen, | ||
387 | svr)) | ||
388 | goto error; | ||
389 | |||
390 | servers = eina_list_append(servers, svr); | ||
391 | ECORE_MAGIC_SET(svr, ECORE_MAGIC_CON_SERVER); | ||
392 | |||
393 | return svr; | ||
394 | |||
395 | error: | ||
396 | if (svr->name) | ||
397 | free(svr->name); | ||
398 | |||
399 | if (svr->path) | ||
400 | free(svr->path); | ||
401 | |||
402 | |||
403 | if (svr->fd_handler) | ||
404 | ecore_main_fd_handler_del(svr->fd_handler); | ||
405 | |||
406 | if (svr->fd > 0) | ||
407 | close(svr->fd); | ||
408 | |||
409 | if (svr->buf) | ||
410 | eina_binbuf_free(svr->buf); | ||
411 | |||
412 | if (svr->ip) | ||
413 | eina_stringshare_del(svr->ip); | ||
414 | |||
415 | ecore_con_ssl_server_shutdown(svr); | ||
416 | free(svr); | ||
417 | return NULL; | ||
418 | } | ||
419 | |||
420 | EAPI Ecore_Con_Server * | ||
421 | ecore_con_server_connect(Ecore_Con_Type compl_type, | ||
422 | const char *name, | ||
423 | int port, | ||
424 | const void *data) | ||
425 | { | ||
426 | Ecore_Con_Server *svr; | ||
427 | Ecore_Con_Type type; | ||
428 | |||
429 | if ((!name) || (!name[0])) | ||
430 | return NULL; | ||
431 | /* local user socket: FILE: ~/.ecore/[name]/[port] */ | ||
432 | /* local system socket: FILE: /tmp/.ecore_service|[name]|[port] */ | ||
433 | /* remote system socket: TCP/IP: [name]:[port] */ | ||
434 | svr = calloc(1, sizeof(Ecore_Con_Server)); | ||
435 | if (!svr) | ||
436 | return NULL; | ||
437 | |||
438 | svr->name = strdup(name); | ||
439 | if (!svr->name) | ||
440 | goto error; | ||
441 | |||
442 | svr->type = compl_type; | ||
443 | svr->port = port; | ||
444 | svr->data = (void *)data; | ||
445 | svr->created = EINA_FALSE; | ||
446 | svr->use_cert = (compl_type & ECORE_CON_SSL & ECORE_CON_LOAD_CERT) == ECORE_CON_LOAD_CERT; | ||
447 | svr->reject_excess_clients = EINA_FALSE; | ||
448 | svr->clients = NULL; | ||
449 | svr->client_limit = -1; | ||
450 | |||
451 | type = compl_type & ECORE_CON_TYPE; | ||
452 | |||
453 | if (type > ECORE_CON_LOCAL_ABSTRACT) | ||
454 | { | ||
455 | /* never use proxies on local connections */ | ||
456 | if (_ecore_con_proxy_once) | ||
457 | svr->ecs = _ecore_con_proxy_once; | ||
458 | else if (_ecore_con_proxy_global) | ||
459 | svr->ecs = _ecore_con_proxy_global; | ||
460 | _ecore_con_proxy_once = NULL; | ||
461 | if (svr->ecs) | ||
462 | { | ||
463 | if ((!svr->ecs->lookup) && | ||
464 | (!ecore_con_lookup(svr->name, (Ecore_Con_Dns_Cb)ecore_con_socks_dns_cb, svr))) | ||
465 | goto error; | ||
466 | if (svr->ecs->lookup) | ||
467 | svr->ecs_state = ECORE_CON_PROXY_STATE_RESOLVED; | ||
468 | } | ||
469 | } | ||
470 | if (ecore_con_ssl_server_prepare(svr, compl_type & ECORE_CON_SSL)) | ||
471 | goto error; | ||
472 | |||
473 | if (((type == ECORE_CON_REMOTE_TCP) || | ||
474 | (type == ECORE_CON_REMOTE_NODELAY) || | ||
475 | (type == ECORE_CON_REMOTE_CORK) || | ||
476 | (type == ECORE_CON_REMOTE_UDP) || | ||
477 | (type == ECORE_CON_REMOTE_BROADCAST)) && | ||
478 | (port < 0)) | ||
479 | goto error; | ||
480 | |||
481 | if ((type == ECORE_CON_LOCAL_USER) || | ||
482 | (type == ECORE_CON_LOCAL_SYSTEM) || | ||
483 | (type == ECORE_CON_LOCAL_ABSTRACT)) | ||
484 | /* Local */ | ||
485 | #ifdef _WIN32 | ||
486 | if (!ecore_con_local_connect(svr, _ecore_con_cl_handler)) | ||
487 | goto error; | ||
488 | #else | ||
489 | if (!ecore_con_local_connect(svr, _ecore_con_cl_handler, svr)) | ||
490 | goto error; | ||
491 | #endif | ||
492 | |||
493 | if ((type == ECORE_CON_REMOTE_TCP) || | ||
494 | (type == ECORE_CON_REMOTE_NODELAY) || | ||
495 | (type == ECORE_CON_REMOTE_CORK)) | ||
496 | { | ||
497 | /* TCP */ | ||
498 | if (!ecore_con_info_tcp_connect(svr, _ecore_con_cb_tcp_connect, | ||
499 | svr)) | ||
500 | goto error; | ||
501 | } | ||
502 | else if ((type == ECORE_CON_REMOTE_UDP) || | ||
503 | (type == ECORE_CON_REMOTE_BROADCAST)) | ||
504 | /* UDP and MCAST */ | ||
505 | if (!ecore_con_info_udp_connect(svr, _ecore_con_cb_udp_connect, | ||
506 | svr)) | ||
507 | goto error; | ||
508 | |||
509 | servers = eina_list_append(servers, svr); | ||
510 | ECORE_MAGIC_SET(svr, ECORE_MAGIC_CON_SERVER); | ||
511 | |||
512 | return svr; | ||
513 | |||
514 | error: | ||
515 | if (svr->name) | ||
516 | free(svr->name); | ||
517 | |||
518 | if (svr->path) | ||
519 | free(svr->path); | ||
520 | |||
521 | if (svr->fd_handler) | ||
522 | ecore_main_fd_handler_del(svr->fd_handler); | ||
523 | |||
524 | if (svr->fd > 0) | ||
525 | close(svr->fd); | ||
526 | |||
527 | ecore_con_ssl_server_shutdown(svr); | ||
528 | free(svr); | ||
529 | return NULL; | ||
530 | } | ||
531 | |||
532 | EAPI void | ||
533 | ecore_con_server_timeout_set(Ecore_Con_Server *svr, | ||
534 | double timeout) | ||
535 | { | ||
536 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
537 | { | ||
538 | ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_timeout_set"); | ||
539 | return; | ||
540 | } | ||
541 | |||
542 | if (svr->created) | ||
543 | svr->client_disconnect_time = timeout; | ||
544 | else | ||
545 | svr->disconnect_time = timeout; | ||
546 | } | ||
547 | |||
548 | EAPI double | ||
549 | ecore_con_server_timeout_get(Ecore_Con_Server *svr) | ||
550 | { | ||
551 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
552 | { | ||
553 | ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_timeout_get"); | ||
554 | return 0; | ||
555 | } | ||
556 | |||
557 | return svr->created ? svr->client_disconnect_time : svr->disconnect_time; | ||
558 | } | ||
559 | |||
560 | EAPI void * | ||
561 | ecore_con_server_del(Ecore_Con_Server *svr) | ||
562 | { | ||
563 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
564 | { | ||
565 | ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_del"); | ||
566 | return NULL; | ||
567 | } | ||
568 | |||
569 | if (svr->delete_me) | ||
570 | return NULL; | ||
571 | |||
572 | _ecore_con_server_kill(svr); | ||
573 | return svr->data; | ||
574 | } | ||
575 | |||
576 | EAPI void * | ||
577 | ecore_con_server_data_get(Ecore_Con_Server *svr) | ||
578 | { | ||
579 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
580 | { | ||
581 | ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_data_get"); | ||
582 | return NULL; | ||
583 | } | ||
584 | |||
585 | return svr->data; | ||
586 | } | ||
587 | |||
588 | EAPI void * | ||
589 | ecore_con_server_data_set(Ecore_Con_Server *svr, | ||
590 | void *data) | ||
591 | { | ||
592 | void *ret = NULL; | ||
593 | |||
594 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
595 | { | ||
596 | ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_data_get"); | ||
597 | return NULL; | ||
598 | } | ||
599 | |||
600 | ret = svr->data; | ||
601 | svr->data = data; | ||
602 | return ret; | ||
603 | } | ||
604 | |||
605 | EAPI Eina_Bool | ||
606 | ecore_con_server_connected_get(Ecore_Con_Server *svr) | ||
607 | { | ||
608 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
609 | { | ||
610 | ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_connected_get"); | ||
611 | return EINA_FALSE; | ||
612 | } | ||
613 | |||
614 | if (svr->connecting) | ||
615 | return EINA_FALSE; | ||
616 | |||
617 | return EINA_TRUE; | ||
618 | } | ||
619 | |||
620 | EAPI const Eina_List * | ||
621 | ecore_con_server_clients_get(Ecore_Con_Server *svr) | ||
622 | { | ||
623 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
624 | { | ||
625 | ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, | ||
626 | "ecore_con_server_clients_get"); | ||
627 | return NULL; | ||
628 | } | ||
629 | |||
630 | return svr->clients; | ||
631 | } | ||
632 | |||
633 | EAPI const char * | ||
634 | ecore_con_server_name_get(Ecore_Con_Server *svr) | ||
635 | { | ||
636 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
637 | { | ||
638 | ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, | ||
639 | "ecore_con_server_name_get"); | ||
640 | return NULL; | ||
641 | } | ||
642 | |||
643 | return svr->name; | ||
644 | } | ||
645 | |||
646 | EAPI int | ||
647 | ecore_con_server_port_get(Ecore_Con_Server *svr) | ||
648 | { | ||
649 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
650 | { | ||
651 | ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, | ||
652 | "ecore_con_server_port_get"); | ||
653 | return -1; | ||
654 | } | ||
655 | return svr->port; | ||
656 | } | ||
657 | |||
658 | EAPI int | ||
659 | ecore_con_server_send(Ecore_Con_Server *svr, | ||
660 | const void *data, | ||
661 | int size) | ||
662 | { | ||
663 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
664 | { | ||
665 | ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_send"); | ||
666 | return 0; | ||
667 | } | ||
668 | |||
669 | EINA_SAFETY_ON_TRUE_RETURN_VAL(svr->delete_me, 0); | ||
670 | |||
671 | EINA_SAFETY_ON_NULL_RETURN_VAL(data, 0); | ||
672 | |||
673 | EINA_SAFETY_ON_TRUE_RETURN_VAL(size < 1, 0); | ||
674 | |||
675 | if (svr->fd_handler) | ||
676 | ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE); | ||
677 | |||
678 | if (!svr->buf) | ||
679 | { | ||
680 | svr->buf = eina_binbuf_new(); | ||
681 | EINA_SAFETY_ON_NULL_RETURN_VAL(svr->buf, 0); | ||
682 | #ifdef TCP_CORK | ||
683 | if ((svr->fd >= 0) && ((svr->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_CORK)) | ||
684 | { | ||
685 | int state = 1; | ||
686 | if (setsockopt(svr->fd, IPPROTO_TCP, TCP_CORK, (char *)&state, sizeof(int)) < 0) | ||
687 | /* realistically this isn't anything serious so we can just log and continue */ | ||
688 | ERR("corking failed! %s", strerror(errno)); | ||
689 | } | ||
690 | #endif | ||
691 | } | ||
692 | eina_binbuf_append_length(svr->buf, data, size); | ||
693 | |||
694 | return size; | ||
695 | } | ||
696 | |||
697 | EAPI void | ||
698 | ecore_con_server_client_limit_set(Ecore_Con_Server *svr, | ||
699 | int client_limit, | ||
700 | char reject_excess_clients) | ||
701 | { | ||
702 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
703 | { | ||
704 | ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, | ||
705 | "ecore_con_server_client_limit_set"); | ||
706 | return; | ||
707 | } | ||
708 | |||
709 | svr->client_limit = client_limit; | ||
710 | svr->reject_excess_clients = reject_excess_clients; | ||
711 | } | ||
712 | |||
713 | EAPI const char * | ||
714 | ecore_con_server_ip_get(Ecore_Con_Server *svr) | ||
715 | { | ||
716 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
717 | { | ||
718 | ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_ip_get"); | ||
719 | return NULL; | ||
720 | } | ||
721 | |||
722 | return svr->ip; | ||
723 | } | ||
724 | |||
725 | EAPI double | ||
726 | ecore_con_server_uptime_get(Ecore_Con_Server *svr) | ||
727 | { | ||
728 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
729 | { | ||
730 | ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_uptime_get"); | ||
731 | return -1; | ||
732 | } | ||
733 | |||
734 | return ecore_time_get() - svr->start_time; | ||
735 | } | ||
736 | |||
737 | EAPI void | ||
738 | ecore_con_server_flush(Ecore_Con_Server *svr) | ||
739 | { | ||
740 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
741 | { | ||
742 | ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_flush"); | ||
743 | return; | ||
744 | } | ||
745 | |||
746 | _ecore_con_server_flush(svr); | ||
747 | } | ||
748 | |||
749 | /** | ||
750 | * @} | ||
751 | */ | ||
752 | |||
753 | /** | ||
754 | * @addtogroup Ecore_Con_Client_Group Ecore Connection Client Functions | ||
755 | * | ||
756 | * Functions that operate on Ecore connection client objects. | ||
757 | * | ||
758 | * @{ | ||
759 | */ | ||
760 | |||
761 | /** | ||
762 | * @example ecore_con_client_example.c | ||
763 | * Shows how to write a simple client that connects to the example server. | ||
764 | */ | ||
765 | |||
766 | EAPI int | ||
767 | ecore_con_client_send(Ecore_Con_Client *cl, | ||
768 | const void *data, | ||
769 | int size) | ||
770 | { | ||
771 | if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) | ||
772 | { | ||
773 | ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_send"); | ||
774 | return 0; | ||
775 | } | ||
776 | |||
777 | EINA_SAFETY_ON_TRUE_RETURN_VAL(cl->delete_me, 0); | ||
778 | |||
779 | EINA_SAFETY_ON_NULL_RETURN_VAL(data, 0); | ||
780 | |||
781 | EINA_SAFETY_ON_TRUE_RETURN_VAL(size < 1, 0); | ||
782 | |||
783 | if (cl->fd_handler) | ||
784 | ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE); | ||
785 | |||
786 | if (cl->host_server && ((cl->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_UDP)) | ||
787 | sendto(cl->host_server->fd, data, size, 0, (struct sockaddr *)cl->client_addr, | ||
788 | cl->client_addr_len); | ||
789 | else if (!cl->buf) | ||
790 | { | ||
791 | cl->buf = eina_binbuf_new(); | ||
792 | EINA_SAFETY_ON_NULL_RETURN_VAL(cl->buf, 0); | ||
793 | #ifdef TCP_CORK | ||
794 | if ((cl->fd >= 0) && ((cl->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_CORK)) | ||
795 | { | ||
796 | int state = 1; | ||
797 | if (setsockopt(cl->fd, IPPROTO_TCP, TCP_CORK, (char *)&state, sizeof(int)) < 0) | ||
798 | /* realistically this isn't anything serious so we can just log and continue */ | ||
799 | ERR("corking failed! %s", strerror(errno)); | ||
800 | } | ||
801 | #endif | ||
802 | } | ||
803 | eina_binbuf_append_length(cl->buf, data, size); | ||
804 | |||
805 | return size; | ||
806 | } | ||
807 | |||
808 | EAPI Ecore_Con_Server * | ||
809 | ecore_con_client_server_get(Ecore_Con_Client *cl) | ||
810 | { | ||
811 | if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) | ||
812 | { | ||
813 | ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, | ||
814 | "ecore_con_client_server_get"); | ||
815 | return NULL; | ||
816 | } | ||
817 | |||
818 | return cl->host_server; | ||
819 | } | ||
820 | |||
821 | EAPI Eina_Bool | ||
822 | ecore_con_client_connected_get(Ecore_Con_Client *cl) | ||
823 | { | ||
824 | if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) | ||
825 | { | ||
826 | ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, | ||
827 | "ecore_con_client_connected_get"); | ||
828 | return EINA_FALSE; | ||
829 | } | ||
830 | |||
831 | return !cl->delete_me; | ||
832 | } | ||
833 | |||
834 | EAPI void | ||
835 | ecore_con_client_timeout_set(Ecore_Con_Client *cl, | ||
836 | double timeout) | ||
837 | { | ||
838 | if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) | ||
839 | { | ||
840 | ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, | ||
841 | "ecore_con_client_timeout_set"); | ||
842 | return; | ||
843 | } | ||
844 | |||
845 | cl->disconnect_time = timeout; | ||
846 | |||
847 | _ecore_con_cl_timer_update(cl); | ||
848 | } | ||
849 | |||
850 | EAPI double | ||
851 | ecore_con_client_timeout_get(Ecore_Con_Client *cl) | ||
852 | { | ||
853 | if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) | ||
854 | { | ||
855 | ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_timeout_get"); | ||
856 | return 0; | ||
857 | } | ||
858 | |||
859 | return cl->disconnect_time; | ||
860 | } | ||
861 | |||
862 | EAPI void * | ||
863 | ecore_con_client_del(Ecore_Con_Client *cl) | ||
864 | { | ||
865 | if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) | ||
866 | { | ||
867 | ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_del"); | ||
868 | return NULL; | ||
869 | } | ||
870 | |||
871 | _ecore_con_client_kill(cl); | ||
872 | return cl->data; | ||
873 | } | ||
874 | |||
875 | EAPI void | ||
876 | ecore_con_client_data_set(Ecore_Con_Client *cl, | ||
877 | const void *data) | ||
878 | { | ||
879 | if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) | ||
880 | { | ||
881 | ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_data_set"); | ||
882 | return; | ||
883 | } | ||
884 | |||
885 | cl->data = (void *)data; | ||
886 | } | ||
887 | |||
888 | EAPI void * | ||
889 | ecore_con_client_data_get(Ecore_Con_Client *cl) | ||
890 | { | ||
891 | if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) | ||
892 | { | ||
893 | ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_data_get"); | ||
894 | return NULL; | ||
895 | } | ||
896 | |||
897 | return cl->data; | ||
898 | } | ||
899 | |||
900 | EAPI const char * | ||
901 | ecore_con_client_ip_get(Ecore_Con_Client *cl) | ||
902 | { | ||
903 | if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) | ||
904 | { | ||
905 | ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_ip_get"); | ||
906 | return NULL; | ||
907 | } | ||
908 | if (!cl->ip) | ||
909 | cl->ip = _ecore_con_pretty_ip(cl->client_addr); | ||
910 | |||
911 | return cl->ip; | ||
912 | } | ||
913 | |||
914 | EAPI int | ||
915 | ecore_con_client_port_get(Ecore_Con_Client *cl) | ||
916 | { | ||
917 | if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) | ||
918 | { | ||
919 | ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_port_get"); | ||
920 | return -1; | ||
921 | } | ||
922 | if (cl->client_addr->sa_family == AF_INET) | ||
923 | return ((struct sockaddr_in*)cl->client_addr)->sin_port; | ||
924 | #ifdef HAVE_IPV6 | ||
925 | return ((struct sockaddr_in6*)cl->client_addr)->sin6_port; | ||
926 | #else | ||
927 | return -1; | ||
928 | #endif | ||
929 | } | ||
930 | |||
931 | EAPI double | ||
932 | ecore_con_client_uptime_get(Ecore_Con_Client *cl) | ||
933 | { | ||
934 | if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) | ||
935 | { | ||
936 | ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_uptime_get"); | ||
937 | return -1; | ||
938 | } | ||
939 | |||
940 | return ecore_time_get() - cl->start_time; | ||
941 | } | ||
942 | |||
943 | EAPI void | ||
944 | ecore_con_client_flush(Ecore_Con_Client *cl) | ||
945 | { | ||
946 | if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) | ||
947 | { | ||
948 | ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_flush"); | ||
949 | return; | ||
950 | } | ||
951 | |||
952 | _ecore_con_client_flush(cl); | ||
953 | } | ||
954 | |||
955 | EAPI int | ||
956 | ecore_con_server_fd_get(Ecore_Con_Server *svr) | ||
957 | { | ||
958 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
959 | { | ||
960 | ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, __func__); | ||
961 | return -1; | ||
962 | } | ||
963 | if (svr->created) return -1; | ||
964 | return ecore_main_fd_handler_fd_get(svr->fd_handler); | ||
965 | } | ||
966 | |||
967 | EAPI int | ||
968 | ecore_con_client_fd_get(Ecore_Con_Client *cl) | ||
969 | { | ||
970 | if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) | ||
971 | { | ||
972 | ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, __func__); | ||
973 | return -1; | ||
974 | } | ||
975 | return ecore_main_fd_handler_fd_get(cl->fd_handler); | ||
976 | } | ||
977 | |||
978 | /** | ||
979 | * @} | ||
980 | */ | ||
981 | |||
982 | void | ||
983 | ecore_con_event_proxy_bind(Ecore_Con_Server *svr) | ||
984 | { | ||
985 | Ecore_Con_Event_Proxy_Bind *e; | ||
986 | int ev = ECORE_CON_EVENT_PROXY_BIND; | ||
987 | |||
988 | e = ecore_con_event_proxy_bind_alloc(); | ||
989 | EINA_SAFETY_ON_NULL_RETURN(e); | ||
990 | |||
991 | svr->event_count = eina_list_append(svr->event_count, e); | ||
992 | _ecore_con_server_timer_update(svr); | ||
993 | e->server = svr; | ||
994 | e->ip = svr->proxyip; | ||
995 | e->port = svr->proxyport; | ||
996 | ecore_event_add(ev, e, | ||
997 | _ecore_con_event_server_add_free, NULL); | ||
998 | _ecore_con_event_count++; | ||
999 | } | ||
1000 | |||
1001 | void | ||
1002 | ecore_con_event_server_add(Ecore_Con_Server *svr) | ||
1003 | { | ||
1004 | /* we got our server! */ | ||
1005 | Ecore_Con_Event_Server_Add *e; | ||
1006 | int ev = ECORE_CON_EVENT_SERVER_ADD; | ||
1007 | |||
1008 | e = ecore_con_event_server_add_alloc(); | ||
1009 | EINA_SAFETY_ON_NULL_RETURN(e); | ||
1010 | |||
1011 | svr->connecting = EINA_FALSE; | ||
1012 | svr->start_time = ecore_time_get(); | ||
1013 | svr->event_count = eina_list_append(svr->event_count, e); | ||
1014 | _ecore_con_server_timer_update(svr); | ||
1015 | e->server = svr; | ||
1016 | if (svr->upgrade) ev = ECORE_CON_EVENT_SERVER_UPGRADE; | ||
1017 | ecore_event_add(ev, e, | ||
1018 | _ecore_con_event_server_add_free, NULL); | ||
1019 | _ecore_con_event_count++; | ||
1020 | } | ||
1021 | |||
1022 | void | ||
1023 | ecore_con_event_server_del(Ecore_Con_Server *svr) | ||
1024 | { | ||
1025 | Ecore_Con_Event_Server_Del *e; | ||
1026 | |||
1027 | svr->delete_me = EINA_TRUE; | ||
1028 | INF("svr %p is dead", svr); | ||
1029 | e = ecore_con_event_server_del_alloc(); | ||
1030 | EINA_SAFETY_ON_NULL_RETURN(e); | ||
1031 | |||
1032 | svr->event_count = eina_list_append(svr->event_count, e); | ||
1033 | _ecore_con_server_timer_update(svr); | ||
1034 | e->server = svr; | ||
1035 | if (svr->ecs) | ||
1036 | { | ||
1037 | svr->ecs_state = svr->ecs->lookup ? ECORE_CON_PROXY_STATE_RESOLVED : ECORE_CON_PROXY_STATE_DONE; | ||
1038 | eina_stringshare_replace(&svr->proxyip, NULL); | ||
1039 | svr->proxyport = 0; | ||
1040 | } | ||
1041 | ecore_event_add(ECORE_CON_EVENT_SERVER_DEL, e, | ||
1042 | _ecore_con_event_server_del_free, NULL); | ||
1043 | _ecore_con_event_count++; | ||
1044 | } | ||
1045 | |||
1046 | void | ||
1047 | ecore_con_event_server_write(Ecore_Con_Server *svr, int num) | ||
1048 | { | ||
1049 | Ecore_Con_Event_Server_Write *e; | ||
1050 | |||
1051 | e = ecore_con_event_server_write_alloc(); | ||
1052 | EINA_SAFETY_ON_NULL_RETURN(e); | ||
1053 | |||
1054 | INF("Wrote %d bytes", num); | ||
1055 | svr->event_count = eina_list_append(svr->event_count, e); | ||
1056 | e->server = svr; | ||
1057 | e->size = num; | ||
1058 | ecore_event_add(ECORE_CON_EVENT_SERVER_WRITE, e, | ||
1059 | (Ecore_End_Cb)_ecore_con_event_server_write_free, NULL); | ||
1060 | _ecore_con_event_count++; | ||
1061 | } | ||
1062 | |||
1063 | void | ||
1064 | ecore_con_event_server_data(Ecore_Con_Server *svr, unsigned char *buf, int num, Eina_Bool duplicate) | ||
1065 | { | ||
1066 | Ecore_Con_Event_Server_Data *e; | ||
1067 | |||
1068 | e = ecore_con_event_server_data_alloc(); | ||
1069 | EINA_SAFETY_ON_NULL_RETURN(e); | ||
1070 | |||
1071 | svr->event_count = eina_list_append(svr->event_count, e); | ||
1072 | _ecore_con_server_timer_update(svr); | ||
1073 | e->server = svr; | ||
1074 | if (duplicate) | ||
1075 | { | ||
1076 | e->data = malloc(num); | ||
1077 | if (!e->data) | ||
1078 | { | ||
1079 | ERR("server data allocation failure !"); | ||
1080 | _ecore_con_event_server_data_free(NULL, e); | ||
1081 | return; | ||
1082 | } | ||
1083 | memcpy(e->data, buf, num); | ||
1084 | } | ||
1085 | else | ||
1086 | e->data = buf; | ||
1087 | e->size = num; | ||
1088 | ecore_event_add(ECORE_CON_EVENT_SERVER_DATA, e, | ||
1089 | _ecore_con_event_server_data_free, NULL); | ||
1090 | _ecore_con_event_count++; | ||
1091 | } | ||
1092 | |||
1093 | void | ||
1094 | ecore_con_event_client_add(Ecore_Con_Client *cl) | ||
1095 | { | ||
1096 | Ecore_Con_Event_Client_Add *e; | ||
1097 | int ev = ECORE_CON_EVENT_CLIENT_ADD; | ||
1098 | |||
1099 | e = ecore_con_event_client_add_alloc(); | ||
1100 | EINA_SAFETY_ON_NULL_RETURN(e); | ||
1101 | |||
1102 | cl->event_count = eina_list_append(cl->event_count, e); | ||
1103 | cl->host_server->event_count = eina_list_append(cl->host_server->event_count, e); | ||
1104 | _ecore_con_cl_timer_update(cl); | ||
1105 | e->client = cl; | ||
1106 | if (cl->upgrade) ev = ECORE_CON_EVENT_CLIENT_UPGRADE; | ||
1107 | ecore_event_add(ev, e, | ||
1108 | (Ecore_End_Cb)_ecore_con_event_client_add_free, cl->host_server); | ||
1109 | _ecore_con_event_count++; | ||
1110 | } | ||
1111 | |||
1112 | void | ||
1113 | ecore_con_event_client_del(Ecore_Con_Client *cl) | ||
1114 | { | ||
1115 | Ecore_Con_Event_Client_Del *e; | ||
1116 | |||
1117 | if (!cl) return; | ||
1118 | cl->delete_me = EINA_TRUE; | ||
1119 | INF("cl %p is dead", cl); | ||
1120 | e = ecore_con_event_client_del_alloc(); | ||
1121 | EINA_SAFETY_ON_NULL_RETURN(e); | ||
1122 | cl->event_count = eina_list_append(cl->event_count, e); | ||
1123 | |||
1124 | cl->host_server->event_count = eina_list_append(cl->host_server->event_count, e); | ||
1125 | _ecore_con_cl_timer_update(cl); | ||
1126 | e->client = cl; | ||
1127 | ecore_event_add(ECORE_CON_EVENT_CLIENT_DEL, e, | ||
1128 | (Ecore_End_Cb)_ecore_con_event_client_del_free, cl->host_server); | ||
1129 | _ecore_con_event_count++; | ||
1130 | } | ||
1131 | |||
1132 | void | ||
1133 | ecore_con_event_client_write(Ecore_Con_Client *cl, int num) | ||
1134 | { | ||
1135 | Ecore_Con_Event_Client_Write *e; | ||
1136 | |||
1137 | e = ecore_con_event_client_write_alloc(); | ||
1138 | EINA_SAFETY_ON_NULL_RETURN(e); | ||
1139 | |||
1140 | cl->event_count = eina_list_append(cl->event_count, e); | ||
1141 | cl->host_server->event_count = eina_list_append(cl->host_server->event_count, e); | ||
1142 | e->client = cl; | ||
1143 | e->size = num; | ||
1144 | ecore_event_add(ECORE_CON_EVENT_CLIENT_WRITE, e, | ||
1145 | (Ecore_End_Cb)_ecore_con_event_client_write_free, cl->host_server); | ||
1146 | _ecore_con_event_count++; | ||
1147 | } | ||
1148 | |||
1149 | void | ||
1150 | ecore_con_event_client_data(Ecore_Con_Client *cl, unsigned char *buf, int num, Eina_Bool duplicate) | ||
1151 | { | ||
1152 | Ecore_Con_Event_Client_Data *e; | ||
1153 | |||
1154 | e = ecore_con_event_client_data_alloc(); | ||
1155 | EINA_SAFETY_ON_NULL_RETURN(e); | ||
1156 | |||
1157 | cl->event_count = eina_list_append(cl->event_count, e); | ||
1158 | cl->host_server->event_count = eina_list_append(cl->host_server->event_count, e); | ||
1159 | _ecore_con_cl_timer_update(cl); | ||
1160 | e->client = cl; | ||
1161 | if (duplicate) | ||
1162 | { | ||
1163 | e->data = malloc(num); | ||
1164 | if (!e->data) | ||
1165 | { | ||
1166 | ERR("client data allocation failure !"); | ||
1167 | _ecore_con_event_client_data_free(cl->host_server, e); | ||
1168 | return; | ||
1169 | } | ||
1170 | memcpy(e->data, buf, num); | ||
1171 | } | ||
1172 | else | ||
1173 | e->data = buf; | ||
1174 | e->size = num; | ||
1175 | ecore_event_add(ECORE_CON_EVENT_CLIENT_DATA, e, | ||
1176 | (Ecore_End_Cb)_ecore_con_event_client_data_free, cl->host_server); | ||
1177 | _ecore_con_event_count++; | ||
1178 | } | ||
1179 | |||
1180 | |||
1181 | void | ||
1182 | ecore_con_server_infos_del(Ecore_Con_Server *svr, void *info) | ||
1183 | { | ||
1184 | svr->infos = eina_list_remove(svr->infos, info); | ||
1185 | } | ||
1186 | |||
1187 | void | ||
1188 | _ecore_con_event_server_error(Ecore_Con_Server *svr, char *error, Eina_Bool duplicate) | ||
1189 | { | ||
1190 | Ecore_Con_Event_Server_Error *e; | ||
1191 | |||
1192 | e = ecore_con_event_server_error_alloc(); | ||
1193 | EINA_SAFETY_ON_NULL_RETURN(e); | ||
1194 | |||
1195 | e->server = svr; | ||
1196 | e->error = duplicate ? strdup(error) : error; | ||
1197 | ERR("%s", error); | ||
1198 | svr->event_count = eina_list_append(svr->event_count, e); | ||
1199 | ecore_event_add(ECORE_CON_EVENT_SERVER_ERROR, e, (Ecore_End_Cb)_ecore_con_event_server_error_free, NULL); | ||
1200 | _ecore_con_event_count++; | ||
1201 | } | ||
1202 | |||
1203 | void | ||
1204 | ecore_con_event_client_error(Ecore_Con_Client *cl, const char *error) | ||
1205 | { | ||
1206 | Ecore_Con_Event_Client_Error *e; | ||
1207 | |||
1208 | e = ecore_con_event_client_error_alloc(); | ||
1209 | EINA_SAFETY_ON_NULL_RETURN(e); | ||
1210 | |||
1211 | e->client = cl; | ||
1212 | e->error = strdup(error); | ||
1213 | ERR("%s", error); | ||
1214 | cl->event_count = eina_list_append(cl->event_count, e); | ||
1215 | cl->host_server->event_count = eina_list_append(cl->host_server->event_count, e); | ||
1216 | ecore_event_add(ECORE_CON_EVENT_CLIENT_ERROR, e, (Ecore_End_Cb)_ecore_con_event_client_error_free, cl->host_server); | ||
1217 | _ecore_con_event_count++; | ||
1218 | } | ||
1219 | |||
1220 | static void | ||
1221 | _ecore_con_server_free(Ecore_Con_Server *svr) | ||
1222 | { | ||
1223 | Ecore_Con_Client *cl; | ||
1224 | double t_start, t; | ||
1225 | |||
1226 | if (svr->event_count) return; | ||
1227 | |||
1228 | while (svr->infos) | ||
1229 | { | ||
1230 | ecore_con_info_data_clear(svr->infos->data); | ||
1231 | svr->infos = eina_list_remove_list(svr->infos, svr->infos); | ||
1232 | } | ||
1233 | |||
1234 | t_start = ecore_time_get(); | ||
1235 | while (svr->buf && (!svr->delete_me)) | ||
1236 | { | ||
1237 | _ecore_con_server_flush(svr); | ||
1238 | t = ecore_time_get(); | ||
1239 | if ((t - t_start) > 0.5) | ||
1240 | { | ||
1241 | WRN("ECORE_CON: EEK - stuck in _ecore_con_server_free() trying\n" | ||
1242 | " to flush data out from the server, and have been for\n" | ||
1243 | " %1.1f seconds. This is taking too long. Aborting flush.", | ||
1244 | (t - t_start)); | ||
1245 | break; | ||
1246 | } | ||
1247 | } | ||
1248 | |||
1249 | #ifdef _WIN32 | ||
1250 | ecore_con_local_win32_server_del(svr); | ||
1251 | #endif | ||
1252 | if (svr->event_count) return; | ||
1253 | ECORE_MAGIC_SET(svr, ECORE_MAGIC_NONE); | ||
1254 | |||
1255 | if (svr->buf) | ||
1256 | eina_binbuf_free(svr->buf); | ||
1257 | |||
1258 | EINA_LIST_FREE(svr->clients, cl) | ||
1259 | { | ||
1260 | Ecore_Con_Event_Server_Add *ev; | ||
1261 | |||
1262 | /* some pointer hacks here to prevent double frees if people are being stupid */ | ||
1263 | EINA_LIST_FREE(cl->event_count, ev) | ||
1264 | ev->server = NULL; | ||
1265 | cl->delete_me = EINA_TRUE; | ||
1266 | INF("cl %p is dead", cl); | ||
1267 | _ecore_con_client_free(cl); | ||
1268 | } | ||
1269 | if ((svr->created) && (svr->path) && (svr->ppid == getpid())) | ||
1270 | unlink(svr->path); | ||
1271 | |||
1272 | ecore_con_ssl_server_shutdown(svr); | ||
1273 | free(svr->name); | ||
1274 | |||
1275 | free(svr->path); | ||
1276 | |||
1277 | eina_stringshare_del(svr->ip); | ||
1278 | eina_stringshare_del(svr->verify_name); | ||
1279 | |||
1280 | if (svr->ecs_buf) eina_binbuf_free(svr->ecs_buf); | ||
1281 | if (svr->ecs_recvbuf) eina_binbuf_free(svr->ecs_recvbuf); | ||
1282 | |||
1283 | if (svr->fd_handler) | ||
1284 | ecore_main_fd_handler_del(svr->fd_handler); | ||
1285 | |||
1286 | if (svr->fd > 0) | ||
1287 | close(svr->fd); | ||
1288 | |||
1289 | if (svr->until_deletion) | ||
1290 | ecore_timer_del(svr->until_deletion); | ||
1291 | |||
1292 | servers = eina_list_remove(servers, svr); | ||
1293 | svr->data = NULL; | ||
1294 | free(svr); | ||
1295 | } | ||
1296 | |||
1297 | static void | ||
1298 | _ecore_con_client_free(Ecore_Con_Client *cl) | ||
1299 | { | ||
1300 | double t_start, t; | ||
1301 | |||
1302 | if (cl->event_count) return; | ||
1303 | |||
1304 | t_start = ecore_time_get(); | ||
1305 | while ((cl->buf) && (!cl->delete_me)) | ||
1306 | { | ||
1307 | _ecore_con_client_flush(cl); | ||
1308 | t = ecore_time_get(); | ||
1309 | if ((t - t_start) > 0.5) | ||
1310 | { | ||
1311 | WRN("EEK - stuck in _ecore_con_client_free() trying\n" | ||
1312 | " to flush data out from the client, and have been for\n" | ||
1313 | " %1.1f seconds. This is taking too long. Aborting flush.", | ||
1314 | (t - t_start)); | ||
1315 | break; | ||
1316 | } | ||
1317 | } | ||
1318 | |||
1319 | #ifdef _WIN32 | ||
1320 | ecore_con_local_win32_client_del(cl); | ||
1321 | #endif | ||
1322 | |||
1323 | if (cl->event_count) return; | ||
1324 | ECORE_MAGIC_SET(cl, ECORE_MAGIC_NONE); | ||
1325 | |||
1326 | if (cl->buf) eina_binbuf_free(cl->buf); | ||
1327 | |||
1328 | if (cl->host_server->type & ECORE_CON_SSL) | ||
1329 | ecore_con_ssl_client_shutdown(cl); | ||
1330 | |||
1331 | if (cl->fd_handler) | ||
1332 | ecore_main_fd_handler_del(cl->fd_handler); | ||
1333 | |||
1334 | if (cl->fd > 0) | ||
1335 | close(cl->fd); | ||
1336 | |||
1337 | free(cl->client_addr); | ||
1338 | cl->client_addr = NULL; | ||
1339 | |||
1340 | if (cl->until_deletion) | ||
1341 | ecore_timer_del(cl->until_deletion); | ||
1342 | |||
1343 | eina_stringshare_del(cl->ip); | ||
1344 | cl->data = NULL; | ||
1345 | free(cl); | ||
1346 | return; | ||
1347 | } | ||
1348 | |||
1349 | static Eina_Bool | ||
1350 | _ecore_con_server_timer(Ecore_Con_Server *svr) | ||
1351 | { | ||
1352 | ecore_con_server_del(svr); | ||
1353 | |||
1354 | svr->until_deletion = NULL; | ||
1355 | return ECORE_CALLBACK_CANCEL; | ||
1356 | } | ||
1357 | |||
1358 | static void | ||
1359 | _ecore_con_server_timer_update(Ecore_Con_Server *svr) | ||
1360 | { | ||
1361 | if (svr->disconnect_time) | ||
1362 | { | ||
1363 | if (svr->disconnect_time > 0) | ||
1364 | { | ||
1365 | if (svr->until_deletion) | ||
1366 | ecore_timer_interval_set(svr->until_deletion, svr->disconnect_time); | ||
1367 | else | ||
1368 | svr->until_deletion = ecore_timer_add(svr->disconnect_time, (Ecore_Task_Cb)_ecore_con_server_timer, svr); | ||
1369 | } | ||
1370 | else if (svr->until_deletion) | ||
1371 | { | ||
1372 | ecore_timer_del(svr->until_deletion); | ||
1373 | svr->until_deletion = NULL; | ||
1374 | } | ||
1375 | } | ||
1376 | else | ||
1377 | { | ||
1378 | if (svr->until_deletion) | ||
1379 | { | ||
1380 | ecore_timer_del(svr->until_deletion); | ||
1381 | svr->until_deletion = NULL; | ||
1382 | } | ||
1383 | } | ||
1384 | } | ||
1385 | |||
1386 | static Eina_Bool | ||
1387 | _ecore_con_client_timer(Ecore_Con_Client *cl) | ||
1388 | { | ||
1389 | ecore_con_client_del(cl); | ||
1390 | |||
1391 | cl->until_deletion = NULL; | ||
1392 | return ECORE_CALLBACK_CANCEL; | ||
1393 | } | ||
1394 | |||
1395 | static void | ||
1396 | _ecore_con_cl_timer_update(Ecore_Con_Client *cl) | ||
1397 | { | ||
1398 | if (cl->disconnect_time) | ||
1399 | { | ||
1400 | if (cl->disconnect_time > 0) | ||
1401 | { | ||
1402 | if (cl->until_deletion) | ||
1403 | ecore_timer_interval_set(cl->until_deletion, cl->disconnect_time); | ||
1404 | else | ||
1405 | cl->until_deletion = ecore_timer_add(cl->disconnect_time, (Ecore_Task_Cb)_ecore_con_client_timer, cl); | ||
1406 | } | ||
1407 | else if (cl->until_deletion) | ||
1408 | { | ||
1409 | ecore_timer_del(cl->until_deletion); | ||
1410 | cl->until_deletion = NULL; | ||
1411 | } | ||
1412 | } | ||
1413 | else | ||
1414 | { | ||
1415 | if (cl->host_server->client_disconnect_time > 0) | ||
1416 | { | ||
1417 | if (cl->until_deletion) | ||
1418 | ecore_timer_interval_set(cl->until_deletion, cl->host_server->client_disconnect_time); | ||
1419 | else | ||
1420 | cl->until_deletion = ecore_timer_add(cl->host_server->client_disconnect_time, (Ecore_Task_Cb)_ecore_con_client_timer, cl); | ||
1421 | } | ||
1422 | else if (cl->until_deletion) | ||
1423 | { | ||
1424 | ecore_timer_del(cl->until_deletion); | ||
1425 | cl->until_deletion = NULL; | ||
1426 | } | ||
1427 | } | ||
1428 | } | ||
1429 | |||
1430 | static void | ||
1431 | _ecore_con_cb_tcp_listen(void *data, | ||
1432 | Ecore_Con_Info *net_info) | ||
1433 | { | ||
1434 | Ecore_Con_Server *svr; | ||
1435 | struct linger lin; | ||
1436 | const char *memerr = NULL; | ||
1437 | |||
1438 | svr = data; | ||
1439 | |||
1440 | errno = 0; | ||
1441 | if (!net_info) /* error message has already been handled */ | ||
1442 | goto error; | ||
1443 | |||
1444 | svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype, | ||
1445 | net_info->info.ai_protocol); | ||
1446 | if (svr->fd < 0) goto error; | ||
1447 | if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error; | ||
1448 | if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error; | ||
1449 | |||
1450 | lin.l_onoff = 1; | ||
1451 | lin.l_linger = 0; | ||
1452 | if (setsockopt(svr->fd, SOL_SOCKET, SO_LINGER, (const void *)&lin, | ||
1453 | sizeof(struct linger)) < 0) | ||
1454 | goto error; | ||
1455 | |||
1456 | if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_NODELAY) | ||
1457 | { | ||
1458 | #ifdef HAVE_NETINET_TCP_H | ||
1459 | int flag = 1; | ||
1460 | |||
1461 | if (setsockopt(svr->fd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, | ||
1462 | sizeof(int)) < 0) | ||
1463 | #endif | ||
1464 | { | ||
1465 | goto error; | ||
1466 | } | ||
1467 | } | ||
1468 | |||
1469 | if (bind(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen) < 0) | ||
1470 | goto error; | ||
1471 | |||
1472 | if (listen(svr->fd, 4096) < 0) goto error; | ||
1473 | |||
1474 | svr->fd_handler = ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ, | ||
1475 | _ecore_con_svr_tcp_handler, svr, NULL, NULL); | ||
1476 | if (!svr->fd_handler) | ||
1477 | { | ||
1478 | memerr = "Memory allocation failure"; | ||
1479 | goto error; | ||
1480 | } | ||
1481 | |||
1482 | return; | ||
1483 | |||
1484 | error: | ||
1485 | if (errno || memerr) ecore_con_event_server_error(svr, memerr ?: strerror(errno)); | ||
1486 | ecore_con_ssl_server_shutdown(svr); | ||
1487 | _ecore_con_server_kill(svr); | ||
1488 | } | ||
1489 | |||
1490 | static void | ||
1491 | _ecore_con_cb_udp_listen(void *data, | ||
1492 | Ecore_Con_Info *net_info) | ||
1493 | { | ||
1494 | Ecore_Con_Server *svr; | ||
1495 | Ecore_Con_Type type; | ||
1496 | struct ip_mreq mreq; | ||
1497 | #ifdef HAVE_IPV6 | ||
1498 | struct ipv6_mreq mreq6; | ||
1499 | #endif | ||
1500 | const int on = 1; | ||
1501 | const char *memerr = NULL; | ||
1502 | |||
1503 | svr = data; | ||
1504 | type = svr->type; | ||
1505 | type &= ECORE_CON_TYPE; | ||
1506 | |||
1507 | errno = 0; | ||
1508 | if (!net_info) /* error message has already been handled */ | ||
1509 | goto error; | ||
1510 | |||
1511 | svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype, | ||
1512 | net_info->info.ai_protocol); | ||
1513 | if (svr->fd < 0) goto error; | ||
1514 | |||
1515 | if (type == ECORE_CON_REMOTE_MCAST) | ||
1516 | { | ||
1517 | if (net_info->info.ai_family == AF_INET) | ||
1518 | { | ||
1519 | if (!inet_pton(net_info->info.ai_family, net_info->ip, | ||
1520 | &mreq.imr_multiaddr)) | ||
1521 | goto error; | ||
1522 | |||
1523 | mreq.imr_interface.s_addr = htonl(INADDR_ANY); | ||
1524 | if (setsockopt(svr->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, | ||
1525 | (const void *)&mreq, sizeof(mreq)) != 0) | ||
1526 | goto error; | ||
1527 | } | ||
1528 | #ifdef HAVE_IPV6 | ||
1529 | else if (net_info->info.ai_family == AF_INET6) | ||
1530 | { | ||
1531 | if (!inet_pton(net_info->info.ai_family, net_info->ip, | ||
1532 | &mreq6.ipv6mr_multiaddr)) | ||
1533 | goto error; | ||
1534 | mreq6.ipv6mr_interface = htonl(INADDR_ANY); | ||
1535 | if (setsockopt(svr->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, | ||
1536 | (const void *)&mreq6, sizeof(mreq6)) != 0) | ||
1537 | goto error; | ||
1538 | } | ||
1539 | #endif | ||
1540 | } | ||
1541 | |||
1542 | if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof(on)) != 0) | ||
1543 | goto error; | ||
1544 | if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error; | ||
1545 | if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error; | ||
1546 | |||
1547 | if (bind(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen) < 0) | ||
1548 | goto error; | ||
1549 | |||
1550 | svr->fd_handler = | ||
1551 | ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ, | ||
1552 | _ecore_con_svr_udp_handler, svr, NULL, NULL); | ||
1553 | if (!svr->fd_handler) | ||
1554 | { | ||
1555 | memerr = "Memory allocation failure"; | ||
1556 | goto error; | ||
1557 | } | ||
1558 | |||
1559 | svr->ip = eina_stringshare_add(net_info->ip); | ||
1560 | |||
1561 | return; | ||
1562 | |||
1563 | error: | ||
1564 | if (errno || memerr) ecore_con_event_server_error(svr, memerr ?: strerror(errno)); | ||
1565 | ecore_con_ssl_server_shutdown(svr); | ||
1566 | _ecore_con_server_kill(svr); | ||
1567 | } | ||
1568 | |||
1569 | static void | ||
1570 | _ecore_con_cb_tcp_connect(void *data, | ||
1571 | Ecore_Con_Info *net_info) | ||
1572 | { | ||
1573 | Ecore_Con_Server *svr; | ||
1574 | int res; | ||
1575 | int curstate = 0; | ||
1576 | const char *memerr = NULL; | ||
1577 | |||
1578 | svr = data; | ||
1579 | |||
1580 | errno = 0; | ||
1581 | if (!net_info) /* error message has already been handled */ | ||
1582 | goto error; | ||
1583 | |||
1584 | svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype, | ||
1585 | net_info->info.ai_protocol); | ||
1586 | if (svr->fd < 0) goto error; | ||
1587 | |||
1588 | if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error; | ||
1589 | if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error; | ||
1590 | |||
1591 | if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&curstate, sizeof(curstate)) < 0) | ||
1592 | goto error; | ||
1593 | |||
1594 | if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_NODELAY) | ||
1595 | { | ||
1596 | #ifdef HAVE_NETINET_TCP_H | ||
1597 | int flag = 1; | ||
1598 | |||
1599 | if (setsockopt(svr->fd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int)) < 0) | ||
1600 | #endif | ||
1601 | { | ||
1602 | goto error; | ||
1603 | } | ||
1604 | } | ||
1605 | |||
1606 | res = connect(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen); | ||
1607 | #ifdef _WIN32 | ||
1608 | if (res == SOCKET_ERROR) | ||
1609 | { | ||
1610 | if (WSAGetLastError() != WSAEINPROGRESS) | ||
1611 | { | ||
1612 | char *err; | ||
1613 | err = evil_format_message(WSAGetLastError()); | ||
1614 | _ecore_con_event_server_error(svr, err, EINA_FALSE); | ||
1615 | ecore_con_ssl_server_shutdown(svr); | ||
1616 | _ecore_con_server_kill(svr); | ||
1617 | return; | ||
1618 | } | ||
1619 | |||
1620 | #else | ||
1621 | if (res < 0) | ||
1622 | { | ||
1623 | if (errno != EINPROGRESS) goto error; | ||
1624 | #endif | ||
1625 | svr->connecting = EINA_TRUE; | ||
1626 | svr->fd_handler = | ||
1627 | ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ | ECORE_FD_WRITE, | ||
1628 | _ecore_con_cl_handler, svr, NULL, NULL); | ||
1629 | } | ||
1630 | else | ||
1631 | svr->fd_handler = ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ, | ||
1632 | _ecore_con_cl_handler, svr, NULL, NULL); | ||
1633 | |||
1634 | if (svr->type & ECORE_CON_SSL) | ||
1635 | { | ||
1636 | svr->handshaking = EINA_TRUE; | ||
1637 | svr->ssl_state = ECORE_CON_SSL_STATE_INIT; | ||
1638 | DBG("%s ssl handshake", svr->ecs_state ? "Queuing" : "Beginning"); | ||
1639 | if ((!svr->ecs_state) && ecore_con_ssl_server_init(svr)) | ||
1640 | goto error; | ||
1641 | } | ||
1642 | |||
1643 | if (!svr->fd_handler) | ||
1644 | { | ||
1645 | memerr = "Memory allocation failure"; | ||
1646 | goto error; | ||
1647 | } | ||
1648 | |||
1649 | if ((!svr->ecs) || (svr->ecs->lookup)) | ||
1650 | svr->ip = eina_stringshare_add(net_info->ip); | ||
1651 | |||
1652 | return; | ||
1653 | |||
1654 | error: | ||
1655 | if (errno || memerr) ecore_con_event_server_error(svr, memerr ?: strerror(errno)); | ||
1656 | ecore_con_ssl_server_shutdown(svr); | ||
1657 | _ecore_con_server_kill(svr); | ||
1658 | } | ||
1659 | |||
1660 | static void | ||
1661 | _ecore_con_cb_udp_connect(void *data, | ||
1662 | Ecore_Con_Info *net_info) | ||
1663 | { | ||
1664 | Ecore_Con_Server *svr; | ||
1665 | int curstate = 0; | ||
1666 | int broadcast = 1; | ||
1667 | const char *memerr = NULL; | ||
1668 | svr = data; | ||
1669 | |||
1670 | errno = 0; | ||
1671 | if (!net_info) /* error message has already been handled */ | ||
1672 | goto error; | ||
1673 | |||
1674 | svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype, | ||
1675 | net_info->info.ai_protocol); | ||
1676 | if (svr->fd < 0) goto error; | ||
1677 | if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error; | ||
1678 | if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error; | ||
1679 | if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_BROADCAST) | ||
1680 | { | ||
1681 | if (setsockopt(svr->fd, SOL_SOCKET, SO_BROADCAST, | ||
1682 | (const void *)&broadcast, | ||
1683 | sizeof(broadcast)) < 0) | ||
1684 | { | ||
1685 | goto error; | ||
1686 | } | ||
1687 | } | ||
1688 | if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, | ||
1689 | (const void *)&curstate, sizeof(curstate)) < 0) | ||
1690 | goto error; | ||
1691 | |||
1692 | if (connect(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen) < 0) | ||
1693 | goto error; | ||
1694 | |||
1695 | svr->fd_handler = ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ | ECORE_FD_WRITE, | ||
1696 | _ecore_con_cl_udp_handler, svr, NULL, NULL); | ||
1697 | |||
1698 | if (!svr->fd_handler) | ||
1699 | { | ||
1700 | memerr = "Memory allocation failure"; | ||
1701 | goto error; | ||
1702 | } | ||
1703 | |||
1704 | if ((!svr->ecs) || (svr->ecs->lookup)) | ||
1705 | svr->ip = eina_stringshare_add(net_info->ip); | ||
1706 | |||
1707 | return; | ||
1708 | |||
1709 | error: | ||
1710 | if (errno || memerr) ecore_con_event_server_error(svr, memerr ?: strerror(errno)); | ||
1711 | ecore_con_ssl_server_shutdown(svr); | ||
1712 | _ecore_con_server_kill(svr); | ||
1713 | } | ||
1714 | |||
1715 | static Ecore_Con_State | ||
1716 | svr_try_connect_plain(Ecore_Con_Server *svr) | ||
1717 | { | ||
1718 | int res; | ||
1719 | int so_err = 0; | ||
1720 | socklen_t size = sizeof(int); | ||
1721 | |||
1722 | res = getsockopt(svr->fd, SOL_SOCKET, SO_ERROR, (void *)&so_err, &size); | ||
1723 | #ifdef _WIN32 | ||
1724 | if (res == SOCKET_ERROR) | ||
1725 | so_err = WSAGetLastError(); | ||
1726 | |||
1727 | if ((so_err == WSAEINPROGRESS) && !svr->delete_me) | ||
1728 | return ECORE_CON_INPROGRESS; | ||
1729 | |||
1730 | #else | ||
1731 | if (res < 0) | ||
1732 | so_err = errno; | ||
1733 | |||
1734 | if ((so_err == EINPROGRESS) && !svr->delete_me) | ||
1735 | return ECORE_CON_INPROGRESS; | ||
1736 | |||
1737 | #endif | ||
1738 | |||
1739 | if (so_err) | ||
1740 | { | ||
1741 | /* we lost our server! */ | ||
1742 | ecore_con_event_server_error(svr, strerror(so_err)); | ||
1743 | ERR("Connection lost: %s", strerror(so_err)); | ||
1744 | _ecore_con_server_kill(svr); | ||
1745 | return ECORE_CON_DISCONNECTED; | ||
1746 | } | ||
1747 | |||
1748 | if ((!svr->delete_me) && (!svr->handshaking) && svr->connecting) | ||
1749 | { | ||
1750 | if (svr->ecs) | ||
1751 | { | ||
1752 | if (ecore_con_socks_svr_init(svr)) | ||
1753 | return ECORE_CON_INPROGRESS; | ||
1754 | } | ||
1755 | else | ||
1756 | ecore_con_event_server_add(svr); | ||
1757 | } | ||
1758 | |||
1759 | if (svr->fd_handler && (!svr->buf)) | ||
1760 | ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ); | ||
1761 | |||
1762 | if (!svr->delete_me) | ||
1763 | return ECORE_CON_CONNECTED; | ||
1764 | else | ||
1765 | return ECORE_CON_DISCONNECTED; | ||
1766 | } | ||
1767 | |||
1768 | static const char * | ||
1769 | _ecore_con_pretty_ip(struct sockaddr *client_addr) | ||
1770 | { | ||
1771 | #ifndef HAVE_IPV6 | ||
1772 | char ipbuf[INET_ADDRSTRLEN + 1]; | ||
1773 | #else | ||
1774 | char ipbuf[INET6_ADDRSTRLEN + 1]; | ||
1775 | #endif | ||
1776 | int family = client_addr->sa_family; | ||
1777 | void *src; | ||
1778 | |||
1779 | switch(family) | ||
1780 | { | ||
1781 | case AF_INET: | ||
1782 | src = &(((struct sockaddr_in *)client_addr)->sin_addr); | ||
1783 | break; | ||
1784 | #ifdef HAVE_IPV6 | ||
1785 | case AF_INET6: | ||
1786 | src = &(((struct sockaddr_in6 *)client_addr)->sin6_addr); | ||
1787 | |||
1788 | if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)src)) | ||
1789 | { | ||
1790 | family = AF_INET; | ||
1791 | src = (char*)src + 12; | ||
1792 | } | ||
1793 | break; | ||
1794 | #endif | ||
1795 | default: | ||
1796 | return eina_stringshare_add("0.0.0.0"); | ||
1797 | } | ||
1798 | |||
1799 | if (!inet_ntop(family, src, ipbuf, sizeof(ipbuf))) | ||
1800 | return eina_stringshare_add("0.0.0.0"); | ||
1801 | |||
1802 | ipbuf[sizeof(ipbuf) - 1] = 0; | ||
1803 | return eina_stringshare_add(ipbuf); | ||
1804 | } | ||
1805 | |||
1806 | static Eina_Bool | ||
1807 | _ecore_con_svr_tcp_handler(void *data, | ||
1808 | Ecore_Fd_Handler *fd_handler __UNUSED__) | ||
1809 | { | ||
1810 | Ecore_Con_Server *svr; | ||
1811 | Ecore_Con_Client *cl = NULL; | ||
1812 | unsigned char client_addr[256]; | ||
1813 | unsigned int client_addr_len; | ||
1814 | const char *clerr = NULL; | ||
1815 | |||
1816 | svr = data; | ||
1817 | if (svr->delete_me) | ||
1818 | return ECORE_CALLBACK_RENEW; | ||
1819 | |||
1820 | if (svr->delete_me) | ||
1821 | return ECORE_CALLBACK_RENEW; | ||
1822 | |||
1823 | if ((svr->client_limit >= 0) && (!svr->reject_excess_clients) && | ||
1824 | (svr->client_count >= (unsigned int)svr->client_limit)) | ||
1825 | return ECORE_CALLBACK_RENEW; | ||
1826 | |||
1827 | /* a new client */ | ||
1828 | |||
1829 | cl = calloc(1, sizeof(Ecore_Con_Client)); | ||
1830 | if (!cl) | ||
1831 | { | ||
1832 | ecore_con_event_server_error(svr, "Memory allocation failure when attempting to add a new client"); | ||
1833 | return ECORE_CALLBACK_RENEW; | ||
1834 | } | ||
1835 | cl->host_server = svr; | ||
1836 | |||
1837 | client_addr_len = sizeof(client_addr); | ||
1838 | memset(&client_addr, 0, client_addr_len); | ||
1839 | cl->fd = accept(svr->fd, (struct sockaddr *)&client_addr, (socklen_t *)&client_addr_len); | ||
1840 | if (cl->fd < 0) goto error; | ||
1841 | if ((svr->client_limit >= 0) && (svr->reject_excess_clients) && | ||
1842 | (svr->client_count >= (unsigned int)svr->client_limit)) | ||
1843 | { | ||
1844 | clerr = "Maximum client limit reached"; | ||
1845 | goto error; | ||
1846 | } | ||
1847 | |||
1848 | if (fcntl(cl->fd, F_SETFL, O_NONBLOCK) < 0) goto error; | ||
1849 | if (fcntl(cl->fd, F_SETFD, FD_CLOEXEC) < 0) goto error; | ||
1850 | cl->fd_handler = ecore_main_fd_handler_add(cl->fd, ECORE_FD_READ, | ||
1851 | _ecore_con_svr_cl_handler, cl, NULL, NULL); | ||
1852 | if (!cl->fd_handler) goto error; | ||
1853 | ECORE_MAGIC_SET(cl, ECORE_MAGIC_CON_CLIENT); | ||
1854 | |||
1855 | if ((!svr->upgrade) && (svr->type & ECORE_CON_SSL)) | ||
1856 | { | ||
1857 | cl->handshaking = EINA_TRUE; | ||
1858 | cl->ssl_state = ECORE_CON_SSL_STATE_INIT; | ||
1859 | if (ecore_con_ssl_client_init(cl)) | ||
1860 | goto error; | ||
1861 | } | ||
1862 | |||
1863 | cl->client_addr = malloc(client_addr_len); | ||
1864 | if (!cl->client_addr) | ||
1865 | { | ||
1866 | clerr = "Memory allocation failure when attempting to add a new client"; | ||
1867 | goto error; | ||
1868 | } | ||
1869 | cl->client_addr_len = client_addr_len; | ||
1870 | memcpy(cl->client_addr, &client_addr, client_addr_len); | ||
1871 | |||
1872 | svr->clients = eina_list_append(svr->clients, cl); | ||
1873 | svr->client_count++; | ||
1874 | |||
1875 | if ((!cl->delete_me) && (!cl->handshaking)) | ||
1876 | ecore_con_event_client_add(cl); | ||
1877 | |||
1878 | return ECORE_CALLBACK_RENEW; | ||
1879 | |||
1880 | error: | ||
1881 | if (cl->fd_handler) ecore_main_fd_handler_del(cl->fd_handler); | ||
1882 | if (cl->fd >= 0) close(cl->fd); | ||
1883 | free(cl); | ||
1884 | if (clerr || errno) ecore_con_event_server_error(svr, clerr ?: strerror(errno)); | ||
1885 | return ECORE_CALLBACK_RENEW; | ||
1886 | } | ||
1887 | |||
1888 | static void | ||
1889 | _ecore_con_cl_read(Ecore_Con_Server *svr) | ||
1890 | { | ||
1891 | int num = 0; | ||
1892 | Eina_Bool lost_server = EINA_TRUE; | ||
1893 | unsigned char buf[READBUFSIZ]; | ||
1894 | |||
1895 | DBG("svr=%p", svr); | ||
1896 | |||
1897 | /* only possible with non-ssl connections */ | ||
1898 | if (svr->connecting && (svr_try_connect_plain(svr) != ECORE_CON_CONNECTED)) | ||
1899 | return; | ||
1900 | |||
1901 | if (svr->handshaking && (!svr->ecs_state)) | ||
1902 | { | ||
1903 | DBG("Continuing ssl handshake"); | ||
1904 | if (!ecore_con_ssl_server_init(svr)) | ||
1905 | lost_server = EINA_FALSE; | ||
1906 | _ecore_con_server_timer_update(svr); | ||
1907 | } | ||
1908 | |||
1909 | if (svr->ecs_state || !(svr->type & ECORE_CON_SSL)) | ||
1910 | { | ||
1911 | errno = 0; | ||
1912 | num = read(svr->fd, buf, sizeof(buf)); | ||
1913 | /* 0 is not a valid return value for a tcp socket */ | ||
1914 | if ((num > 0) || ((num < 0) && (errno == EAGAIN))) | ||
1915 | lost_server = EINA_FALSE; | ||
1916 | else if (num < 0) | ||
1917 | ecore_con_event_server_error(svr, strerror(errno)); | ||
1918 | } | ||
1919 | else | ||
1920 | { | ||
1921 | num = ecore_con_ssl_server_read(svr, buf, sizeof(buf)); | ||
1922 | /* this is not an actual 0 return, 0 here just means non-fatal error such as EAGAIN */ | ||
1923 | if (num >= 0) | ||
1924 | lost_server = EINA_FALSE; | ||
1925 | } | ||
1926 | |||
1927 | if ((!svr->delete_me) && (num > 0)) | ||
1928 | { | ||
1929 | if (svr->ecs_state) | ||
1930 | ecore_con_socks_read(svr, buf, num); | ||
1931 | else | ||
1932 | ecore_con_event_server_data(svr, buf, num, EINA_TRUE); | ||
1933 | } | ||
1934 | |||
1935 | if (lost_server) | ||
1936 | _ecore_con_server_kill(svr); | ||
1937 | } | ||
1938 | |||
1939 | static Eina_Bool | ||
1940 | _ecore_con_cl_handler(void *data, | ||
1941 | Ecore_Fd_Handler *fd_handler) | ||
1942 | { | ||
1943 | Ecore_Con_Server *svr; | ||
1944 | Eina_Bool want_read, want_write; | ||
1945 | |||
1946 | svr = data; | ||
1947 | if (svr->delete_me) | ||
1948 | return ECORE_CALLBACK_RENEW; | ||
1949 | |||
1950 | if (svr->delete_me) | ||
1951 | return ECORE_CALLBACK_RENEW; | ||
1952 | |||
1953 | want_read = ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ); | ||
1954 | want_write = ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE); | ||
1955 | |||
1956 | if ((!svr->ecs_state) && svr->handshaking && (want_read || want_write)) | ||
1957 | { | ||
1958 | DBG("Continuing ssl handshake: preparing to %s...", want_read ? "read" : "write"); | ||
1959 | #ifdef ISCOMFITOR | ||
1960 | if (want_read) | ||
1961 | { | ||
1962 | char buf[READBUFSIZ]; | ||
1963 | ssize_t len; | ||
1964 | len = recv(svr->fd, buf, sizeof(buf), MSG_DONTWAIT | MSG_PEEK); | ||
1965 | DBG("%zu bytes in buffer", len); | ||
1966 | } | ||
1967 | #endif | ||
1968 | if (ecore_con_ssl_server_init(svr)) | ||
1969 | { | ||
1970 | ERR("ssl handshaking failed!"); | ||
1971 | svr->handshaking = EINA_FALSE; | ||
1972 | } | ||
1973 | else if (!svr->ssl_state) | ||
1974 | ecore_con_event_server_add(svr); | ||
1975 | return ECORE_CALLBACK_RENEW; | ||
1976 | } | ||
1977 | if (svr->ecs && svr->ecs_state && (svr->ecs_state < ECORE_CON_PROXY_STATE_READ) && (!svr->ecs_buf)) | ||
1978 | { | ||
1979 | if (svr->ecs_state < ECORE_CON_PROXY_STATE_INIT) | ||
1980 | { | ||
1981 | INF("PROXY STATE++"); | ||
1982 | svr->ecs_state++; | ||
1983 | } | ||
1984 | if (ecore_con_socks_svr_init(svr)) return ECORE_CALLBACK_RENEW; | ||
1985 | } | ||
1986 | if (want_read) | ||
1987 | _ecore_con_cl_read(svr); | ||
1988 | else if (want_write) /* only possible with non-ssl connections */ | ||
1989 | { | ||
1990 | if (svr->connecting && (!svr_try_connect_plain(svr)) && (!svr->ecs_state)) | ||
1991 | return ECORE_CALLBACK_RENEW; | ||
1992 | |||
1993 | _ecore_con_server_flush(svr); | ||
1994 | } | ||
1995 | |||
1996 | return ECORE_CALLBACK_RENEW; | ||
1997 | } | ||
1998 | |||
1999 | static Eina_Bool | ||
2000 | _ecore_con_cl_udp_handler(void *data, | ||
2001 | Ecore_Fd_Handler *fd_handler) | ||
2002 | { | ||
2003 | unsigned char buf[READBUFSIZ]; | ||
2004 | int num; | ||
2005 | Ecore_Con_Server *svr; | ||
2006 | Eina_Bool want_read, want_write; | ||
2007 | |||
2008 | want_read = ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ); | ||
2009 | want_write = ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE); | ||
2010 | |||
2011 | svr = data; | ||
2012 | if (svr->delete_me || svr->delete_me || ((!want_read) && (!want_write))) | ||
2013 | return ECORE_CALLBACK_RENEW; | ||
2014 | |||
2015 | if (want_write) | ||
2016 | { | ||
2017 | _ecore_con_server_flush(svr); | ||
2018 | return ECORE_CALLBACK_RENEW; | ||
2019 | } | ||
2020 | |||
2021 | num = read(svr->fd, buf, READBUFSIZ); | ||
2022 | |||
2023 | if ((!svr->delete_me) && (num > 0)) | ||
2024 | ecore_con_event_server_data(svr, buf, num, EINA_TRUE); | ||
2025 | |||
2026 | if (num < 0 && (errno != EAGAIN) && (errno != EINTR)) | ||
2027 | { | ||
2028 | ecore_con_event_server_error(svr, strerror(errno)); | ||
2029 | _ecore_con_server_kill(svr); | ||
2030 | } | ||
2031 | |||
2032 | return ECORE_CALLBACK_RENEW; | ||
2033 | } | ||
2034 | |||
2035 | static Eina_Bool | ||
2036 | _ecore_con_svr_udp_handler(void *data, | ||
2037 | Ecore_Fd_Handler *fd_handler) | ||
2038 | { | ||
2039 | unsigned char buf[READBUFSIZ]; | ||
2040 | unsigned char client_addr[256]; | ||
2041 | socklen_t client_addr_len = sizeof(client_addr); | ||
2042 | int num; | ||
2043 | Ecore_Con_Server *svr; | ||
2044 | Ecore_Con_Client *cl = NULL; | ||
2045 | |||
2046 | svr = data; | ||
2047 | |||
2048 | if (svr->delete_me) | ||
2049 | return ECORE_CALLBACK_RENEW; | ||
2050 | |||
2051 | if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE)) | ||
2052 | { | ||
2053 | _ecore_con_client_flush(cl); | ||
2054 | return ECORE_CALLBACK_RENEW; | ||
2055 | } | ||
2056 | |||
2057 | if (!ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) | ||
2058 | return ECORE_CALLBACK_RENEW; | ||
2059 | |||
2060 | #ifdef _WIN32 | ||
2061 | num = fcntl(svr->fd, F_SETFL, O_NONBLOCK); | ||
2062 | if (num >= 0) | ||
2063 | num = recvfrom(svr->fd, (char *)buf, sizeof(buf), 0, | ||
2064 | (struct sockaddr *)&client_addr, | ||
2065 | &client_addr_len); | ||
2066 | |||
2067 | #else | ||
2068 | num = recvfrom(svr->fd, buf, sizeof(buf), MSG_DONTWAIT, | ||
2069 | (struct sockaddr *)&client_addr, | ||
2070 | &client_addr_len); | ||
2071 | #endif | ||
2072 | |||
2073 | if (num < 0 && (errno != EAGAIN) && (errno != EINTR)) | ||
2074 | { | ||
2075 | ecore_con_event_server_error(svr, strerror(errno)); | ||
2076 | if (!svr->delete_me) | ||
2077 | ecore_con_event_client_del(NULL); | ||
2078 | _ecore_con_server_kill(svr); | ||
2079 | return ECORE_CALLBACK_CANCEL; | ||
2080 | } | ||
2081 | |||
2082 | |||
2083 | /* Create a new client for use in the client data event */ | ||
2084 | cl = calloc(1, sizeof(Ecore_Con_Client)); | ||
2085 | EINA_SAFETY_ON_NULL_RETURN_VAL(cl, ECORE_CALLBACK_RENEW); | ||
2086 | |||
2087 | cl->host_server = svr; | ||
2088 | cl->client_addr = malloc(client_addr_len); | ||
2089 | if (!cl->client_addr) | ||
2090 | { | ||
2091 | free(cl); | ||
2092 | return ECORE_CALLBACK_RENEW; | ||
2093 | } | ||
2094 | cl->client_addr_len = client_addr_len; | ||
2095 | |||
2096 | memcpy(cl->client_addr, &client_addr, client_addr_len); | ||
2097 | ECORE_MAGIC_SET(cl, ECORE_MAGIC_CON_CLIENT); | ||
2098 | svr->clients = eina_list_append(svr->clients, cl); | ||
2099 | svr->client_count++; | ||
2100 | |||
2101 | ecore_con_event_client_add(cl); | ||
2102 | ecore_con_event_client_data(cl, buf, num, EINA_TRUE); | ||
2103 | |||
2104 | return ECORE_CALLBACK_RENEW; | ||
2105 | } | ||
2106 | |||
2107 | static void | ||
2108 | _ecore_con_svr_cl_read(Ecore_Con_Client *cl) | ||
2109 | { | ||
2110 | int num = 0; | ||
2111 | Eina_Bool lost_client = EINA_TRUE; | ||
2112 | unsigned char buf[READBUFSIZ]; | ||
2113 | |||
2114 | DBG("cl=%p", cl); | ||
2115 | |||
2116 | if (cl->handshaking) | ||
2117 | { | ||
2118 | /* add an extra handshake attempt just before read, even though | ||
2119 | * read also attempts to handshake, to try to finish sooner | ||
2120 | */ | ||
2121 | if (ecore_con_ssl_client_init(cl)) | ||
2122 | lost_client = EINA_FALSE; | ||
2123 | |||
2124 | _ecore_con_cl_timer_update(cl); | ||
2125 | } | ||
2126 | |||
2127 | if (!(cl->host_server->type & ECORE_CON_SSL) || (!cl->upgrade)) | ||
2128 | { | ||
2129 | num = read(cl->fd, buf, sizeof(buf)); | ||
2130 | /* 0 is not a valid return value for a tcp socket */ | ||
2131 | if ((num > 0) || ((num < 0) && ((errno == EAGAIN) || (errno == EINTR)))) | ||
2132 | lost_client = EINA_FALSE; | ||
2133 | else if (num < 0) | ||
2134 | ecore_con_event_client_error(cl, strerror(errno)); | ||
2135 | } | ||
2136 | else | ||
2137 | { | ||
2138 | num = ecore_con_ssl_client_read(cl, buf, sizeof(buf)); | ||
2139 | /* this is not an actual 0 return, 0 here just means non-fatal error such as EAGAIN */ | ||
2140 | if (num >= 0) | ||
2141 | lost_client = EINA_FALSE; | ||
2142 | } | ||
2143 | |||
2144 | if ((!cl->delete_me) && (num > 0)) | ||
2145 | ecore_con_event_client_data(cl, buf, num, EINA_TRUE); | ||
2146 | |||
2147 | if (lost_client) _ecore_con_client_kill(cl); | ||
2148 | } | ||
2149 | |||
2150 | static Eina_Bool | ||
2151 | _ecore_con_svr_cl_handler(void *data, | ||
2152 | Ecore_Fd_Handler *fd_handler) | ||
2153 | { | ||
2154 | Ecore_Con_Client *cl; | ||
2155 | |||
2156 | cl = data; | ||
2157 | if (cl->delete_me) | ||
2158 | return ECORE_CALLBACK_RENEW; | ||
2159 | |||
2160 | if (cl->handshaking && ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ | ECORE_FD_WRITE)) | ||
2161 | { | ||
2162 | if (ecore_con_ssl_client_init(cl)) | ||
2163 | { | ||
2164 | ERR("ssl handshaking failed!"); | ||
2165 | _ecore_con_client_kill(cl); | ||
2166 | return ECORE_CALLBACK_RENEW; | ||
2167 | } | ||
2168 | else if (!cl->ssl_state) | ||
2169 | ecore_con_event_client_add(cl); | ||
2170 | } | ||
2171 | else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) | ||
2172 | _ecore_con_svr_cl_read(cl); | ||
2173 | |||
2174 | else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE)) | ||
2175 | _ecore_con_client_flush(cl); | ||
2176 | |||
2177 | return ECORE_CALLBACK_RENEW; | ||
2178 | } | ||
2179 | |||
2180 | static void | ||
2181 | _ecore_con_server_flush(Ecore_Con_Server *svr) | ||
2182 | { | ||
2183 | int count, num; | ||
2184 | size_t buf_len, buf_offset; | ||
2185 | const void *buf; | ||
2186 | |||
2187 | DBG("(svr=%p,buf=%p)", svr, svr->buf); | ||
2188 | #ifdef _WIN32 | ||
2189 | if (ecore_con_local_win32_server_flush(svr)) | ||
2190 | return; | ||
2191 | #endif | ||
2192 | |||
2193 | if ((!svr->buf) && (!svr->ecs_buf) && svr->fd_handler) | ||
2194 | { | ||
2195 | ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ); | ||
2196 | return; | ||
2197 | } | ||
2198 | |||
2199 | buf = svr->buf ? eina_binbuf_string_get(svr->buf) : eina_binbuf_string_get(svr->ecs_buf); | ||
2200 | buf_len = svr->buf ? eina_binbuf_length_get(svr->buf) : eina_binbuf_length_get(svr->ecs_buf); | ||
2201 | buf_offset = svr->buf ? svr->write_buf_offset : svr->ecs_buf_offset; | ||
2202 | num = buf_len - buf_offset; | ||
2203 | |||
2204 | /* check whether we need to write anything at all. | ||
2205 | * we must not write zero bytes with SSL_write() since it | ||
2206 | * causes undefined behaviour | ||
2207 | */ | ||
2208 | /* we thank Tommy[D] for needing to check negative buffer sizes | ||
2209 | * here because his system is amazing. | ||
2210 | */ | ||
2211 | if (num <= 0) return; | ||
2212 | |||
2213 | if ((!svr->ecs_state) && svr->handshaking) | ||
2214 | { | ||
2215 | DBG("Continuing ssl handshake"); | ||
2216 | if (ecore_con_ssl_server_init(svr)) | ||
2217 | _ecore_con_server_kill(svr); | ||
2218 | _ecore_con_server_timer_update(svr); | ||
2219 | return; | ||
2220 | } | ||
2221 | |||
2222 | if (svr->ecs_state || (!(svr->type & ECORE_CON_SSL))) | ||
2223 | count = write(svr->fd, buf + buf_offset, num); | ||
2224 | else | ||
2225 | count = ecore_con_ssl_server_write(svr, buf + buf_offset, num); | ||
2226 | |||
2227 | if (count < 0) | ||
2228 | { | ||
2229 | if ((errno != EAGAIN) && (errno != EINTR)) | ||
2230 | { | ||
2231 | ecore_con_event_server_error(svr, strerror(errno)); | ||
2232 | _ecore_con_server_kill(svr); | ||
2233 | } | ||
2234 | return; | ||
2235 | } | ||
2236 | |||
2237 | if (count && (!svr->ecs_state)) ecore_con_event_server_write(svr, count); | ||
2238 | if (svr->ecs_buf) | ||
2239 | buf_offset = svr->ecs_buf_offset += count; | ||
2240 | else | ||
2241 | buf_offset = svr->write_buf_offset += count; | ||
2242 | if (buf_offset >= buf_len) | ||
2243 | { | ||
2244 | if (svr->ecs_buf) | ||
2245 | { | ||
2246 | svr->ecs_buf_offset = 0; | ||
2247 | eina_binbuf_free(svr->ecs_buf); | ||
2248 | svr->ecs_buf = NULL; | ||
2249 | INF("PROXY STATE++"); | ||
2250 | svr->ecs_state++; | ||
2251 | } | ||
2252 | else | ||
2253 | { | ||
2254 | svr->write_buf_offset = 0; | ||
2255 | eina_binbuf_free(svr->buf); | ||
2256 | svr->buf = NULL; | ||
2257 | #ifdef TCP_CORK | ||
2258 | if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_CORK) | ||
2259 | { | ||
2260 | int state = 0; | ||
2261 | if (setsockopt(svr->fd, IPPROTO_TCP, TCP_CORK, (char *)&state, sizeof(int)) < 0) | ||
2262 | /* realistically this isn't anything serious so we can just log and continue */ | ||
2263 | ERR("uncorking failed! %s", strerror(errno)); | ||
2264 | } | ||
2265 | #endif | ||
2266 | } | ||
2267 | if (svr->fd_handler) | ||
2268 | ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ); | ||
2269 | } | ||
2270 | else if ((count < num) && svr->fd_handler) | ||
2271 | ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE); | ||
2272 | } | ||
2273 | |||
2274 | static void | ||
2275 | _ecore_con_client_flush(Ecore_Con_Client *cl) | ||
2276 | { | ||
2277 | int num = 0, count = 0; | ||
2278 | |||
2279 | #ifdef _WIN32 | ||
2280 | if (ecore_con_local_win32_client_flush(cl)) | ||
2281 | return; | ||
2282 | #endif | ||
2283 | |||
2284 | if (!cl->buf && cl->fd_handler) | ||
2285 | { | ||
2286 | ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ); | ||
2287 | return; | ||
2288 | } | ||
2289 | |||
2290 | if (cl->handshaking) | ||
2291 | { | ||
2292 | if (ecore_con_ssl_client_init(cl)) | ||
2293 | count = -1; | ||
2294 | |||
2295 | _ecore_con_cl_timer_update(cl); | ||
2296 | } | ||
2297 | |||
2298 | if (!count) | ||
2299 | { | ||
2300 | num = eina_binbuf_length_get(cl->buf) - cl->buf_offset; | ||
2301 | if (num <= 0) return; | ||
2302 | if (!(cl->host_server->type & ECORE_CON_SSL) || (!cl->upgrade)) | ||
2303 | count = write(cl->fd, eina_binbuf_string_get(cl->buf) + cl->buf_offset, num); | ||
2304 | else | ||
2305 | count = ecore_con_ssl_client_write(cl, eina_binbuf_string_get(cl->buf) + cl->buf_offset, num); | ||
2306 | } | ||
2307 | |||
2308 | if (count < 0) | ||
2309 | { | ||
2310 | if ((errno != EAGAIN) && (errno != EINTR) && (!cl->delete_me)) | ||
2311 | { | ||
2312 | ecore_con_event_client_error(cl, strerror(errno)); | ||
2313 | _ecore_con_client_kill(cl); | ||
2314 | } | ||
2315 | |||
2316 | return; | ||
2317 | } | ||
2318 | |||
2319 | if (count) ecore_con_event_client_write(cl, count); | ||
2320 | cl->buf_offset += count, num -= count; | ||
2321 | if (cl->buf_offset >= eina_binbuf_length_get(cl->buf)) | ||
2322 | { | ||
2323 | cl->buf_offset = 0; | ||
2324 | eina_binbuf_free(cl->buf); | ||
2325 | cl->buf = NULL; | ||
2326 | #ifdef TCP_CORK | ||
2327 | if ((cl->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_CORK) | ||
2328 | { | ||
2329 | int state = 0; | ||
2330 | if (setsockopt(cl->fd, IPPROTO_TCP, TCP_CORK, (char *)&state, sizeof(int)) < 0) | ||
2331 | /* realistically this isn't anything serious so we can just log and continue */ | ||
2332 | ERR("uncorking failed! %s", strerror(errno)); | ||
2333 | } | ||
2334 | #endif | ||
2335 | if (cl->fd_handler) | ||
2336 | ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ); | ||
2337 | } | ||
2338 | else if (cl->fd_handler && (num >= 0)) | ||
2339 | ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_WRITE); | ||
2340 | } | ||
2341 | |||
2342 | static void | ||
2343 | _ecore_con_event_client_add_free(Ecore_Con_Server *svr, | ||
2344 | void *ev) | ||
2345 | { | ||
2346 | Ecore_Con_Event_Client_Add *e; | ||
2347 | |||
2348 | e = ev; | ||
2349 | if (e->client) | ||
2350 | { | ||
2351 | e->client->event_count = eina_list_remove(e->client->event_count, e); | ||
2352 | if (e->client->host_server) | ||
2353 | { | ||
2354 | e->client->host_server->event_count = eina_list_remove(e->client->host_server->event_count, ev); | ||
2355 | if ((!svr->event_count) && (svr->delete_me)) | ||
2356 | _ecore_con_server_free(svr); | ||
2357 | } | ||
2358 | if ((!e->client->event_count) && (e->client->delete_me)) | ||
2359 | ecore_con_client_del(e->client); | ||
2360 | } | ||
2361 | |||
2362 | ecore_con_event_client_add_free(e); | ||
2363 | _ecore_con_event_count--; | ||
2364 | if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) | ||
2365 | ecore_con_mempool_shutdown(); | ||
2366 | } | ||
2367 | |||
2368 | static void | ||
2369 | _ecore_con_event_client_del_free(Ecore_Con_Server *svr, | ||
2370 | void *ev) | ||
2371 | { | ||
2372 | Ecore_Con_Event_Client_Del *e; | ||
2373 | |||
2374 | e = ev; | ||
2375 | if (e->client) | ||
2376 | { | ||
2377 | e->client->event_count = eina_list_remove(e->client->event_count, e); | ||
2378 | if (e->client->host_server) | ||
2379 | { | ||
2380 | e->client->host_server->event_count = eina_list_remove(e->client->host_server->event_count, ev); | ||
2381 | if ((!svr->event_count) && (svr->delete_me)) | ||
2382 | _ecore_con_server_free(svr); | ||
2383 | } | ||
2384 | if (!e->client->event_count) | ||
2385 | ecore_con_client_del(e->client); | ||
2386 | } | ||
2387 | ecore_con_event_client_del_free(e); | ||
2388 | _ecore_con_event_count--; | ||
2389 | if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) | ||
2390 | ecore_con_mempool_shutdown(); | ||
2391 | } | ||
2392 | |||
2393 | static void | ||
2394 | _ecore_con_event_client_write_free(Ecore_Con_Server *svr, | ||
2395 | Ecore_Con_Event_Client_Write *e) | ||
2396 | { | ||
2397 | if (e->client) | ||
2398 | { | ||
2399 | e->client->event_count = eina_list_remove(e->client->event_count, e); | ||
2400 | if (e->client->host_server) | ||
2401 | { | ||
2402 | e->client->host_server->event_count = eina_list_remove(e->client->host_server->event_count, e); | ||
2403 | if ((!svr->event_count) && (svr->delete_me)) | ||
2404 | _ecore_con_server_free(svr); | ||
2405 | } | ||
2406 | if (((!e->client->event_count) && (e->client->delete_me)) || | ||
2407 | ((e->client->host_server && | ||
2408 | ((e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_UDP || | ||
2409 | (e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_MCAST)))) | ||
2410 | ecore_con_client_del(e->client); | ||
2411 | } | ||
2412 | ecore_con_event_client_write_free(e); | ||
2413 | _ecore_con_event_count--; | ||
2414 | if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) | ||
2415 | ecore_con_mempool_shutdown(); | ||
2416 | } | ||
2417 | |||
2418 | static void | ||
2419 | _ecore_con_event_client_data_free(Ecore_Con_Server *svr, | ||
2420 | void *ev) | ||
2421 | { | ||
2422 | Ecore_Con_Event_Client_Data *e; | ||
2423 | |||
2424 | e = ev; | ||
2425 | if (e->client) | ||
2426 | { | ||
2427 | e->client->event_count = eina_list_remove(e->client->event_count, e); | ||
2428 | if (e->client->host_server) | ||
2429 | { | ||
2430 | e->client->host_server->event_count = eina_list_remove(e->client->host_server->event_count, ev); | ||
2431 | } | ||
2432 | if ((!svr->event_count) && (svr->delete_me)) | ||
2433 | _ecore_con_server_free(svr); | ||
2434 | if (((!e->client->event_count) && (e->client->delete_me)) || | ||
2435 | ((e->client->host_server && | ||
2436 | ((e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_UDP || | ||
2437 | (e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_MCAST)))) | ||
2438 | ecore_con_client_del(e->client); | ||
2439 | } | ||
2440 | free(e->data); | ||
2441 | ecore_con_event_client_data_free(e); | ||
2442 | _ecore_con_event_count--; | ||
2443 | if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) | ||
2444 | ecore_con_mempool_shutdown(); | ||
2445 | } | ||
2446 | |||
2447 | static void | ||
2448 | _ecore_con_event_server_add_free(void *data __UNUSED__, | ||
2449 | void *ev) | ||
2450 | { | ||
2451 | Ecore_Con_Event_Server_Add *e; | ||
2452 | |||
2453 | e = ev; | ||
2454 | if (e->server) | ||
2455 | { | ||
2456 | e->server->event_count = eina_list_remove(e->server->event_count, ev); | ||
2457 | if ((!e->server->event_count) && (e->server->delete_me)) | ||
2458 | _ecore_con_server_free(e->server); | ||
2459 | } | ||
2460 | ecore_con_event_server_add_free(e); | ||
2461 | _ecore_con_event_count--; | ||
2462 | if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) | ||
2463 | ecore_con_mempool_shutdown(); | ||
2464 | } | ||
2465 | |||
2466 | static void | ||
2467 | _ecore_con_event_server_del_free(void *data __UNUSED__, | ||
2468 | void *ev) | ||
2469 | { | ||
2470 | Ecore_Con_Event_Server_Del *e; | ||
2471 | |||
2472 | e = ev; | ||
2473 | if (e->server) | ||
2474 | { | ||
2475 | e->server->event_count = eina_list_remove(e->server->event_count, ev); | ||
2476 | if (!e->server->event_count) | ||
2477 | _ecore_con_server_free(e->server); | ||
2478 | } | ||
2479 | ecore_con_event_server_del_free(e); | ||
2480 | _ecore_con_event_count--; | ||
2481 | if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) | ||
2482 | ecore_con_mempool_shutdown(); | ||
2483 | } | ||
2484 | |||
2485 | static void | ||
2486 | _ecore_con_event_server_write_free(void *data __UNUSED__, | ||
2487 | Ecore_Con_Event_Server_Write *e) | ||
2488 | { | ||
2489 | if (e->server) | ||
2490 | { | ||
2491 | e->server->event_count = eina_list_remove(e->server->event_count, e); | ||
2492 | if ((!e->server->event_count) && (e->server->delete_me)) | ||
2493 | _ecore_con_server_free(e->server); | ||
2494 | } | ||
2495 | |||
2496 | ecore_con_event_server_write_free(e); | ||
2497 | _ecore_con_event_count--; | ||
2498 | if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) | ||
2499 | ecore_con_mempool_shutdown(); | ||
2500 | } | ||
2501 | |||
2502 | static void | ||
2503 | _ecore_con_event_server_data_free(void *data __UNUSED__, | ||
2504 | void *ev) | ||
2505 | { | ||
2506 | Ecore_Con_Event_Server_Data *e; | ||
2507 | |||
2508 | e = ev; | ||
2509 | if (e->server) | ||
2510 | { | ||
2511 | e->server->event_count = eina_list_remove(e->server->event_count, ev); | ||
2512 | if ((!e->server->event_count) && (e->server->delete_me)) | ||
2513 | _ecore_con_server_free(e->server); | ||
2514 | } | ||
2515 | |||
2516 | free(e->data); | ||
2517 | ecore_con_event_server_data_free(e); | ||
2518 | _ecore_con_event_count--; | ||
2519 | if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) | ||
2520 | ecore_con_mempool_shutdown(); | ||
2521 | } | ||
2522 | |||
2523 | |||
2524 | static void | ||
2525 | _ecore_con_event_server_error_free(void *data __UNUSED__, Ecore_Con_Event_Server_Error *e) | ||
2526 | { | ||
2527 | if (e->server) | ||
2528 | { | ||
2529 | e->server->event_count = eina_list_remove(e->server->event_count, e); | ||
2530 | if ((!e->server->event_count) && (e->server->delete_me)) | ||
2531 | _ecore_con_server_free(e->server); | ||
2532 | } | ||
2533 | free(e->error); | ||
2534 | ecore_con_event_server_error_free(e); | ||
2535 | _ecore_con_event_count--; | ||
2536 | if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) | ||
2537 | ecore_con_mempool_shutdown(); | ||
2538 | } | ||
2539 | |||
2540 | static void | ||
2541 | _ecore_con_event_client_error_free(Ecore_Con_Server *svr, Ecore_Con_Event_Client_Error *e) | ||
2542 | { | ||
2543 | if (e->client) | ||
2544 | { | ||
2545 | e->client->host_server->event_count = eina_list_remove(e->client->host_server->event_count, e); | ||
2546 | if ((!e->client->event_count) && (e->client->delete_me)) | ||
2547 | _ecore_con_client_free(e->client); | ||
2548 | if (e->client->host_server) | ||
2549 | { | ||
2550 | e->client->host_server->event_count = eina_list_remove(e->client->host_server->event_count, e); | ||
2551 | if ((!svr->event_count) && (svr->delete_me)) | ||
2552 | _ecore_con_server_free(svr); | ||
2553 | } | ||
2554 | } | ||
2555 | free(e->error); | ||
2556 | ecore_con_event_client_error_free(e); | ||
2557 | _ecore_con_event_count--; | ||
2558 | if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) | ||
2559 | ecore_con_mempool_shutdown(); | ||
2560 | } | ||
2561 | |||
2562 | static void | ||
2563 | _ecore_con_lookup_done(void *data, | ||
2564 | Ecore_Con_Info *infos) | ||
2565 | { | ||
2566 | Ecore_Con_Server *svr; | ||
2567 | Ecore_Con_Lookup *lk; | ||
2568 | |||
2569 | svr = data; | ||
2570 | lk = svr->data; | ||
2571 | |||
2572 | if (infos) | ||
2573 | lk->done_cb(infos->info.ai_canonname, infos->ip, | ||
2574 | infos->info.ai_addr, infos->info.ai_addrlen, | ||
2575 | (void *)lk->data); | ||
2576 | else | ||
2577 | lk->done_cb(NULL, NULL, NULL, 0, (void *)lk->data); | ||
2578 | |||
2579 | free(svr->name); | ||
2580 | free(lk); | ||
2581 | free(svr); | ||
2582 | } | ||
2583 | |||