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