Misc cleanup.
[profile/ivi/ecore.git] / src / lib / ecore_con / ecore_con.c
1 /*
2  * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
3  */
4
5 #include <sys/stat.h>
6 #include <arpa/inet.h>
7 #include <sys/socket.h>
8 #include <sys/un.h>
9 #include <errno.h>
10
11 #include <config.h>
12
13 #include "Ecore.h"
14 #include "ecore_private.h"
15 #include "Ecore_Con.h"
16 #include "ecore_con_private.h"
17
18 #ifdef HAVE_NETINET_IN_H
19 # include <netinet/in.h>
20 #endif
21 #ifdef HAVE_WINSOCK2_H
22 # include <winsock2.h>
23 #endif
24
25 static void _ecore_con_cb_tcp_connect(void *data, Ecore_Con_Info *info);
26 static void _ecore_con_cb_udp_connect(void *data, Ecore_Con_Info *info);
27 static void _ecore_con_cb_tcp_listen(void *data, Ecore_Con_Info *info);
28 static void _ecore_con_cb_udp_listen(void *data, Ecore_Con_Info *info);
29
30 static void _ecore_con_server_free(Ecore_Con_Server *svr);
31 static void _ecore_con_client_free(Ecore_Con_Client *cl);
32
33 static int _ecore_con_svr_handler(void *data, Ecore_Fd_Handler *fd_handler);
34 static int _ecore_con_cl_handler(void *data, Ecore_Fd_Handler *fd_handler);
35 static int _ecore_con_cl_udp_handler(void *data, Ecore_Fd_Handler *fd_handler);
36 static int _ecore_con_svr_udp_handler(void *data, Ecore_Fd_Handler *fd_handler);
37 static int _ecore_con_svr_cl_handler(void *data, Ecore_Fd_Handler *fd_handler);
38
39 static void _ecore_con_server_flush(Ecore_Con_Server *svr);
40 static void _ecore_con_client_flush(Ecore_Con_Client *cl);
41
42 static void _ecore_con_event_client_add_free(void *data, void *ev);
43 static void _ecore_con_event_client_del_free(void *data, void *ev);
44 static void _ecore_con_event_client_data_free(void *data, void *ev);
45 static void _ecore_con_event_server_add_free(void *data, void *ev);
46 static void _ecore_con_event_server_del_free(void *data, void *ev);
47 static void _ecore_con_event_server_data_free(void *data, void *ev);
48
49 EAPI int ECORE_CON_EVENT_CLIENT_ADD = 0;
50 EAPI int ECORE_CON_EVENT_CLIENT_DEL = 0;
51 EAPI int ECORE_CON_EVENT_SERVER_ADD = 0;
52 EAPI int ECORE_CON_EVENT_SERVER_DEL = 0;
53 EAPI int ECORE_CON_EVENT_CLIENT_DATA = 0;
54 EAPI int ECORE_CON_EVENT_SERVER_DATA = 0;
55
56 static Ecore_List *servers = NULL;
57 static int init_count = 0;
58
59 #define LENGTH_OF_SOCKADDR_UN(s) (strlen((s)->sun_path) + (size_t)(((struct sockaddr_un *)NULL)->sun_path))
60 #define LENGTH_OF_ABSTRACT_SOCKADDR_UN(s, path) (strlen(path) + 1 + (size_t)(((struct sockaddr_un *)NULL)->sun_path))
61
62 /**
63  * @defgroup Ecore_Con_Lib_Group Ecore Connection Library Functions
64  *
65  * Utility functions that set up and shut down the Ecore Connection
66  * library.
67  */
68
69 /**
70  * Initialises the Ecore_Con library.
71  * @return  Number of times the library has been initialised without being
72  *          shut down.
73  * @ingroup Ecore_Con_Lib_Group
74  */
75 EAPI int
76 ecore_con_init(void)
77 {
78    if (++init_count != 1) return init_count;
79
80    ecore_init();
81    ECORE_CON_EVENT_CLIENT_ADD = ecore_event_type_new();
82    ECORE_CON_EVENT_CLIENT_DEL = ecore_event_type_new();
83    ECORE_CON_EVENT_SERVER_ADD = ecore_event_type_new();
84    ECORE_CON_EVENT_SERVER_DEL = ecore_event_type_new();
85    ECORE_CON_EVENT_CLIENT_DATA = ecore_event_type_new();
86    ECORE_CON_EVENT_SERVER_DATA = ecore_event_type_new();
87
88    /* TODO Remember return value, if it fails, use gethostbyname() */
89    ecore_con_ssl_init();
90    ecore_con_dns_init();
91    ecore_con_info_init();
92
93    servers = ecore_list_new();
94
95    return init_count;
96 }
97
98 /**
99  * Shuts down the Ecore_Con library.
100  * @return  Number of times the library has been initialised without being
101  *          shut down.
102  * @ingroup Ecore_Con_Lib_Group
103  */
104 EAPI int
105 ecore_con_shutdown(void)
106 {
107    if (--init_count != 0) return init_count;
108
109    while (!ecore_list_empty_is(servers))
110      _ecore_con_server_free(ecore_list_first_remove(servers));
111    ecore_list_destroy(servers);
112    servers = NULL;
113
114    ecore_con_info_shutdown();
115    ecore_con_dns_shutdown();
116    ecore_con_ssl_shutdown();
117
118    ecore_shutdown();
119
120    return init_count;
121 }
122
123 /**
124  * @defgroup Ecore_Con_Server_Group Ecore Connection Server Functions
125  *
126  * Functions that operate on Ecore server objects.
127  */
128
129 /**
130  * Creates a server to listen for connections.
131  *
132  * The socket on which the server listens depends on the connection
133  * type:
134  * @li If @a compl_type is @c ECORE_CON_LOCAL_USER, the server will listen on
135  *     the Unix socket "~/.ecore/[name]/[port]".
136  * @li If @a compl_type is @c ECORE_CON_LOCAL_SYSTEM, the server will listen
137  *     on Unix socket "/tmp/.ecore_service|[name]|[port]".
138  * @li If @a compl_type is @c ECORE_CON_REMOTE_TCP, the server will listen
139  *     on TCP port @c port.
140  *
141  * @param  compl_type The connection type.
142  * @param  name       Name to associate with the socket.  It is used when
143  *                    generating the socket name of a Unix socket.  Though
144  *                    it is not used for the TCP socket, it still needs to
145  *                    be a valid character array.  @c NULL will not be
146  *                    accepted.
147  * @param  port       Number to identify socket.  When a Unix socket is used,
148  *                    it becomes part of the socket name.  When a TCP socket
149  *                    is used, it is used as the TCP port.
150  * @param  data       Data to associate with the created Ecore_Con_Server
151  *                    object.
152  * @return A new Ecore_Con_Server.
153  * @ingroup Ecore_Con_Server_Group
154  */
155 EAPI Ecore_Con_Server *
156 ecore_con_server_add(Ecore_Con_Type compl_type, const char *name, int port,
157                      const void *data)
158 {
159    Ecore_Con_Server   *svr;
160    Ecore_Con_Type      type;
161    struct sockaddr_un  socket_unix;
162    struct linger       lin;
163    char                buf[4096];
164    mode_t              pmode;
165
166    if (port < 0) return NULL;
167    /* local  user   socket: FILE:   ~/.ecore/[name]/[port] */
168    /* local  system socket: FILE:   /tmp/.ecore_service|[name]|[port] */
169    /* remote system socket: TCP/IP: [name]:[port] */
170    svr = calloc(1, sizeof(Ecore_Con_Server));
171    if (!svr) return NULL;
172
173    svr->name = strdup(name);
174    if (!svr->name) goto error;
175    svr->type = compl_type;
176    svr->port = port;
177    svr->data = (void *)data;
178    svr->created = 1;
179    svr->reject_excess_clients = 0;
180    svr->client_limit = -1;
181    svr->clients = NULL;
182    svr->ppid = getpid();
183    ecore_con_ssl_server_prepare(svr);
184
185    type = compl_type & ECORE_CON_TYPE;
186
187    if ((type == ECORE_CON_LOCAL_USER) || (type == ECORE_CON_LOCAL_SYSTEM) ||
188        (type == ECORE_CON_LOCAL_ABSTRACT))
189      {
190         const char *homedir;
191         struct stat st;
192         mode_t mask;
193         int socket_unix_len;
194
195         if (!name) goto error;
196         mask = S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH;
197
198         if (type == ECORE_CON_LOCAL_USER)
199           {
200              homedir = getenv("HOME");
201              if (!homedir) homedir = getenv("TMP");
202              if (!homedir) homedir = "/tmp";
203              mask = S_IRUSR | S_IWUSR | S_IXUSR;
204              snprintf(buf, sizeof(buf), "%s/.ecore", homedir);
205              if (stat(buf, &st) < 0) mkdir(buf, mask);
206              snprintf(buf, sizeof(buf), "%s/.ecore/%s", homedir, name);
207              if (stat(buf, &st) < 0) mkdir(buf, mask);
208              snprintf(buf, sizeof(buf), "%s/.ecore/%s/%i", homedir, name, port);
209              mask = S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH;
210           }
211         else if (type == ECORE_CON_LOCAL_SYSTEM)
212           {
213              mask = 0;
214              if (name[0] == '/')
215                {
216                   if (port >= 0)
217                     snprintf(buf, sizeof(buf), "%s|%i", name, port);
218                   else
219                     snprintf(buf, sizeof(buf), "%s", name);
220                }
221              else
222                snprintf(buf, sizeof(buf), "/tmp/.ecore_service|%s|%i", name, port);
223           }
224         else if (type == ECORE_CON_LOCAL_ABSTRACT)
225           strncpy(buf, name, sizeof(buf));
226         pmode = umask(mask);
227         start:
228         svr->fd = socket(AF_UNIX, SOCK_STREAM, 0);
229         if (svr->fd < 0) goto error_umask;
230         if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error_umask;
231         if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error_umask;
232         lin.l_onoff = 1;
233         lin.l_linger = 0;
234         if (setsockopt(svr->fd, SOL_SOCKET, SO_LINGER, &lin, sizeof(struct linger)) < 0) goto error_umask;
235         socket_unix.sun_family = AF_UNIX;
236         if (type == ECORE_CON_LOCAL_ABSTRACT)
237           {
238 #ifdef HAVE_ABSTRACT_SOCKETS
239              /* . is a placeholder */
240              snprintf(socket_unix.sun_path, sizeof(socket_unix.sun_path), ".%s", name);
241              /* first char null indicates abstract namespace */
242              socket_unix.sun_path[0] = '\0';
243              socket_unix_len = LENGTH_OF_ABSTRACT_SOCKADDR_UN(&socket_unix, name);
244 #else
245              fprintf(stderr, "Your system does not support abstract sockets!\n");
246              goto error_umask;
247 #endif
248           }
249         else
250           {
251              strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path));
252              socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix);
253           }
254         if (bind(svr->fd, (struct sockaddr *)&socket_unix, socket_unix_len) < 0)
255           {
256             if (((type == ECORE_CON_LOCAL_USER) || (type == ECORE_CON_LOCAL_SYSTEM)) &&
257                 (connect(svr->fd, (struct sockaddr *)&socket_unix, socket_unix_len) < 0) &&
258                 (unlink(buf) >= 0))
259               goto start;
260             else
261               goto error_umask;
262           }
263         if (listen(svr->fd, 4096) < 0) goto error_umask;
264         svr->path = strdup(buf);
265         if (!svr->path) goto error_umask;
266         svr->fd_handler =
267           ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
268                                     _ecore_con_svr_handler, svr, NULL, NULL);
269         umask(pmode);
270         if (!svr->fd_handler) goto error;
271      }
272
273    if (type == ECORE_CON_REMOTE_TCP)
274      {
275         /* TCP */
276         if (!ecore_con_info_tcp_listen(svr, _ecore_con_cb_tcp_listen, svr)) goto error;
277      }
278    else if (type == ECORE_CON_REMOTE_MCAST || type == ECORE_CON_REMOTE_UDP)
279      {
280         /* UDP and MCAST */
281         if (!ecore_con_info_udp_listen(svr, _ecore_con_cb_udp_listen, svr)) goto error;
282      }
283
284    ecore_list_append(servers, svr);
285    ECORE_MAGIC_SET(svr, ECORE_MAGIC_CON_SERVER);
286
287    return svr;
288
289    error_umask:
290    umask(pmode);
291    error:
292    if (svr->name) free(svr->name);
293    if (svr->path) free(svr->path);
294    if (svr->fd >= 0) close(svr->fd);
295    if (svr->fd_handler) ecore_main_fd_handler_del(svr->fd_handler);
296    if (svr->write_buf) free(svr->write_buf);
297    if (svr->ip) free(svr->ip);
298    ecore_con_ssl_server_shutdown(svr);
299    free(svr);
300    return NULL;
301 }
302
303 /**
304  * Creates a server object to represent the server listening at the
305  * given port.
306  *
307  * The socket to which the server connects depends on the connection type:
308  * @li If @a compl_type is @c ECORE_CON_LOCAL_USER, the function will
309  *     connect to the server listening on the Unix socket
310  *     "~/.ecore/[name]/[port]".
311  * @li If @a compl_type is @c ECORE_CON_LOCAL_SYSTEM, the function will
312  *     connect to the server listening on the Unix socket
313  *     "/tmp/.ecore_service|[name]|[port]".
314  * @li If @a compl_type is @c ECORE_CON_REMOTE_TCP, the function will
315  *     connect to the server listening on the TCP port "[name]:[port]".
316  *
317  * @param  compl_type The connection type.
318  * @param  name       Name used when determining what socket to connect to.
319  *                    It is used to generate the socket name when the socket
320  *                    is a Unix socket.  It is used as the hostname when
321  *                    connecting with a TCP socket.
322  * @param  port       Number to identify the socket to connect to.  Used when
323  *                    generating the socket name for a Unix socket, or as the
324  *                    TCP port when connecting to a TCP socket.
325  * @param  data       Data to associate with the created Ecore_Con_Server
326  *                    object.
327  * @return A new Ecore_Con_Server.
328  * @ingroup Ecore_Con_Server_Group
329  */
330 EAPI Ecore_Con_Server *
331 ecore_con_server_connect(Ecore_Con_Type compl_type, const char *name, int port,
332                          const void *data)
333 {
334    Ecore_Con_Server   *svr;
335    Ecore_Con_Type      type;
336    struct sockaddr_un  socket_unix;
337    int                 curstate = 0;
338    char                buf[4096];
339
340    if (!name) return NULL;
341    /* local  user   socket: FILE:   ~/.ecore/[name]/[port] */
342    /* local  system socket: FILE:   /tmp/.ecore_service|[name]|[port] */
343    /* remote system socket: TCP/IP: [name]:[port] */
344    svr = calloc(1, sizeof(Ecore_Con_Server));
345    if (!svr) return NULL;
346
347    svr->name = strdup(name);
348    if (!svr->name) goto error;
349    svr->type = compl_type;
350    svr->port = port;
351    svr->data = (void *)data;
352    svr->created = 0;
353    svr->reject_excess_clients = 0;
354    svr->clients = NULL;
355    svr->client_limit = -1;
356    ecore_con_ssl_server_prepare(svr);
357
358    type = compl_type & ECORE_CON_TYPE;
359
360    if ((type == ECORE_CON_REMOTE_TCP || type == ECORE_CON_REMOTE_UDP) && (port < 0)) return NULL;
361
362    if ((type == ECORE_CON_LOCAL_USER) || (type == ECORE_CON_LOCAL_SYSTEM) ||
363        (type == ECORE_CON_LOCAL_ABSTRACT))
364      {
365         const char *homedir;
366         int socket_unix_len;
367
368         if (type == ECORE_CON_LOCAL_USER)
369           {
370              homedir = getenv("HOME");
371              if (!homedir) homedir = getenv("TMP");
372              if (!homedir) homedir = "/tmp";
373              snprintf(buf, sizeof(buf), "%s/.ecore/%s/%i", homedir, name, port);
374           }
375         else if (type == ECORE_CON_LOCAL_SYSTEM)
376           {
377              if (port < 0)
378                {
379                   if (name[0] == '/')
380                     strncpy(buf, name, sizeof(buf));
381                   else
382                     snprintf(buf, sizeof(buf), "/tmp/.ecore_service|%s", name);
383                }
384              else
385                {
386                   if (name[0] == '/')
387                     snprintf(buf, sizeof(buf), "%s|%i", name, port);
388                   else
389                     snprintf(buf, sizeof(buf), "/tmp/.ecore_service|%s|%i", name, port);
390                }
391           }
392         else if (type == ECORE_CON_LOCAL_ABSTRACT)
393           strncpy(buf, name, sizeof(buf));
394
395         svr->fd = socket(AF_UNIX, SOCK_STREAM, 0);
396         if (svr->fd < 0) goto error;
397         if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
398         if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
399         if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, &curstate, sizeof(curstate)) < 0) goto error;
400         socket_unix.sun_family = AF_UNIX;
401
402         if (type == ECORE_CON_LOCAL_ABSTRACT)
403           {
404 #ifdef HAVE_ABSTRACT_SOCKETS
405              /* copy name insto sun_path, prefixed by null to indicate abstract namespace */
406              snprintf(socket_unix.sun_path, sizeof(socket_unix.sun_path), ".%s", name);
407              socket_unix.sun_path[0] = '\0';
408              socket_unix_len = LENGTH_OF_ABSTRACT_SOCKADDR_UN(&socket_unix, name);
409 #else
410              fprintf(stderr, "Your system does not support abstract sockets!\n");
411              goto error;
412 #endif
413           }
414         else
415           {
416              strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path));
417              socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix);
418           }
419
420         if (connect(svr->fd, (struct sockaddr *)&socket_unix, socket_unix_len) < 0)
421           {
422             goto error;
423           }
424         svr->path = strdup(buf);
425         if (!svr->path) goto error;
426
427         if (svr->type & ECORE_CON_SSL)
428           ecore_con_ssl_server_init(svr);
429
430         svr->fd_handler =
431           ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
432                                     _ecore_con_cl_handler, svr, NULL, NULL);
433         if (!svr->fd_handler) goto error;
434
435         if (!svr->delete_me)
436           {
437              /* we got our server! */
438              Ecore_Con_Event_Server_Add *e;
439
440              e = calloc(1, sizeof(Ecore_Con_Event_Server_Add));
441              if (e)
442                {
443                   svr->event_count++;
444                   e->server = svr;
445                   ecore_event_add(ECORE_CON_EVENT_SERVER_ADD, e,
446                                   _ecore_con_event_server_add_free, NULL);
447                }
448           }
449      }
450
451    if (type == ECORE_CON_REMOTE_TCP)
452      {
453         /* TCP */
454         if (!ecore_con_info_tcp_connect(svr, _ecore_con_cb_tcp_connect, svr)) goto error;
455      }
456    else if (type == ECORE_CON_REMOTE_UDP)
457      {
458         /* UDP and MCAST */
459         if (!ecore_con_info_udp_connect(svr, _ecore_con_cb_udp_connect, svr)) goto error;
460      }
461
462    ecore_list_append(servers, svr);
463    ECORE_MAGIC_SET(svr, ECORE_MAGIC_CON_SERVER);
464
465    return svr;
466
467    error:
468    if (svr->name) free(svr->name);
469    if (svr->path) free(svr->path);
470    if (svr->fd >= 0) close(svr->fd);
471    if (svr->fd_handler) ecore_main_fd_handler_del(svr->fd_handler);
472    ecore_con_ssl_server_shutdown(svr);
473    free(svr);
474    return NULL;
475 }
476
477 /**
478  * Closes the connection and frees the given server.
479  * @param   svr The given server.
480  * @return  Data associated with the server when it was created.
481  * @ingroup Ecore_Con_Server_Group
482  */
483 EAPI void *
484 ecore_con_server_del(Ecore_Con_Server *svr)
485 {
486    void *data;
487
488    if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
489      {
490         ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_del");
491         return NULL;
492      }
493    data = svr->data;
494    svr->data = NULL;
495    svr->delete_me = 1;
496    if (svr->event_count > 0)
497      {
498         if (svr->fd_handler)
499           {
500              ecore_main_fd_handler_del(svr->fd_handler);
501              svr->fd_handler = NULL;
502           }
503      }
504    else
505      {
506         _ecore_con_server_free(svr);
507         if (ecore_list_goto(servers, svr)) ecore_list_remove(servers);
508      }
509    return data;
510 }
511
512 /**
513  * Retrieves the data associated with the given server.
514  * @param   svr The given server.
515  * @return  The associated data.
516  * @ingroup Ecore_Con_Server_Group
517  */
518 EAPI void *
519 ecore_con_server_data_get(Ecore_Con_Server *svr)
520 {
521    if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
522      {
523         ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_data_get");
524         return NULL;
525      }
526    return svr->data;
527 }
528
529 /**
530  * Retrieves whether the given server is currently connected.
531  * @todo Check that this function does what the documenter believes it does.
532  * @param   svr The given server.
533  * @return  @c 1 if the server is connected.  @c 0 otherwise.
534  * @ingroup Ecore_Con_Server_Group
535  */
536 EAPI int
537 ecore_con_server_connected_get(Ecore_Con_Server *svr)
538 {
539    if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
540      {
541         ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_connected_get");
542         return 0;
543      }
544    if (svr->connecting) return 0;
545    return 1;
546 }
547
548 /**
549  * Retrieves the current list of clients.
550  * @param   svr The given server.
551  * @return  The list of clients on this server.
552  * @ingroup Ecore_Con_Server_Group
553  */
554 EAPI Eina_List *
555 ecore_con_server_clients_get(Ecore_Con_Server *svr)
556 {
557    if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
558      {
559         ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_clients_get");
560         return NULL;
561      }
562    return svr->clients;
563 }
564
565 /**
566  * Sends the given data to the given server.
567  * @param   svr  The given server.
568  * @param   data The given data.
569  * @param   size Length of the data, in bytes, to send.
570  * @return  The number of bytes sent.  @c 0 will be returned if there is an
571  *          error.
572  * @ingroup Ecore_Con_Server_Group
573  */
574 EAPI int
575 ecore_con_server_send(Ecore_Con_Server *svr, const void *data, int size)
576 {
577    if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
578      {
579         ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_send");
580         return 0;
581      }
582    if (svr->dead) return 0;
583    if (!data) return 0;
584    if (size < 1) return 0;
585    if (svr->fd_handler)
586      ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE);
587    if (svr->write_buf)
588      {
589         unsigned char *newbuf;
590
591         newbuf = realloc(svr->write_buf, svr->write_buf_size + size);
592         if (newbuf) svr->write_buf = newbuf;
593         else return 0;
594         memcpy(svr->write_buf + svr->write_buf_size, data, size);
595         svr->write_buf_size += size;
596      }
597    else
598      {
599         svr->write_buf = malloc(size);
600         if (!svr->write_buf) return 0;
601         svr->write_buf_size = size;
602         memcpy(svr->write_buf, data, size);
603      }
604    return size;
605 }
606
607 /**
608  * Sets a limit on the number of clients that can be handled concurrently
609  * by the given server, and a policy on what to do if excess clients try to
610  * connect.
611  * Beware that if you set this once ecore is already running, you may
612  * already have pending CLIENT_ADD events in your event queue.  Those
613  * clients have already connected and will not be affected by this call.
614  * Only clients subsequently trying to connect will be affected.
615  * @param   svr           The given server.
616  * @param   client_limit  The maximum number of clients to handle
617  *                        concurrently.  -1 means unlimited (default).  0
618  *                        effectively disables the server.
619  * @param   reject_excess_clients  Set to 1 to automatically disconnect
620  *                        excess clients as soon as they connect if you are
621  *                        already handling client_limit clients.  Set to 0
622  *                        (default) to just hold off on the "accept()"
623  *                        system call until the number of active clients
624  *                        drops. This causes the kernel to queue up to 4096
625  *                        connections (or your kernel's limit, whichever is
626  *                        lower).
627  * @ingroup Ecore_Con_Server_Group
628  */
629 EAPI void
630 ecore_con_server_client_limit_set(Ecore_Con_Server *svr, int client_limit, char reject_excess_clients)
631 {
632    if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
633      {
634         ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_client_limit_set");
635         return;
636      }
637    svr->client_limit = client_limit;
638    svr->reject_excess_clients = reject_excess_clients;
639 }
640
641 /**
642  * Gets the IP address of a server that has been connected to.
643  *
644  * @param   svr           The given server.
645  * @return  A pointer to an internal string that contains the IP address of
646  *          the connected server in the form "XXX.YYY.ZZZ.AAA" IP notation.
647  *          This string should not be modified or trusted to stay valid after
648  *          deletion for the @p svr object. If no IP is known NULL is returned.
649  * @ingroup Ecore_Con_Server_Group
650  */
651 EAPI char *
652 ecore_con_server_ip_get(Ecore_Con_Server *svr)
653 {
654    if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
655      {
656         ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_ip_get");
657         return NULL;
658      }
659    return svr->ip;
660 }
661
662 /**
663  * Flushes all pending data to the given server. Will return when done.
664  *
665  * @param   svr           The given server.
666  * @ingroup Ecore_Con_Server_Group
667  */
668 EAPI void
669 ecore_con_server_flush(Ecore_Con_Server *svr)
670 {
671    if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
672      {
673         ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_flush");
674         return;
675      }
676    _ecore_con_server_flush(svr);
677 }
678
679 /**
680  * @defgroup Ecore_Con_Client_Group Ecore Connection Client Functions
681  *
682  * Functions that operate on Ecore connection client objects.
683  */
684
685 /**
686  * Sends the given data to the given client.
687  * @param   cl   The given client.
688  * @param   data The given data.
689  * @param   size Length of the data, in bytes, to send.
690  * @return  The number of bytes sent.  @c 0 will be returned if there is an
691  *          error.
692  * @ingroup Ecore_Con_Client_Group
693  */
694 EAPI int
695 ecore_con_client_send(Ecore_Con_Client *cl, const void *data, int size)
696 {
697    if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
698      {
699         ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_send");
700         return 0;
701      }
702    if (cl->dead) return 0;
703    if (!data) return 0;
704    if (size < 1) return 0;
705    if (cl->fd_handler)
706      ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE);
707
708    if(cl->server && cl->server->type == ECORE_CON_REMOTE_UDP)
709      {
710        sendto(cl->server->fd, data, size, 0, (struct sockaddr *) cl->data, sizeof(struct sockaddr_in));
711      }
712    else if (cl->buf)
713      {
714        unsigned char *newbuf;
715
716        newbuf = realloc(cl->buf, cl->buf_size + size);
717        if (newbuf) cl->buf = newbuf;
718        else return 0;
719        memcpy(cl->buf + cl->buf_size, data, size);
720        cl->buf_size += size;
721      }
722    else
723      {
724         cl->buf = malloc(size);
725         if (!cl->buf) return 0;
726         cl->buf_size = size;
727         memcpy(cl->buf, data, size);
728      }
729    return size;
730 }
731
732 /**
733  * Retrieves the server representing the socket the client has
734  * connected to.
735  * @param   cl The given client.
736  * @return  The server that the client connected to.
737  * @ingroup Ecore_Con_Client_Group
738  */
739 EAPI Ecore_Con_Server *
740 ecore_con_client_server_get(Ecore_Con_Client *cl)
741 {
742    if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
743      {
744         ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_server_get");
745         return NULL;
746      }
747    return cl->server;
748 }
749
750 /**
751  * Closes the connection and frees memory allocated to the given client.
752  * @param   cl The given client.
753  * @return  Data associated with the client.
754  * @ingroup Ecore_Con_Client_Group
755  */
756 EAPI void *
757 ecore_con_client_del(Ecore_Con_Client *cl)
758 {
759    void *data = NULL;
760
761    if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
762      {
763         ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_del");
764         return NULL;
765      }
766
767    if(cl->data && cl->server && (cl->server->type == ECORE_CON_REMOTE_UDP ||
768                                  cl->server->type == ECORE_CON_REMOTE_MCAST))
769      free(cl->data);
770    else
771      data = cl->data;
772
773    cl->data = NULL;
774    cl->delete_me = 1;
775    if (cl->event_count > 0)
776      {
777         if (cl->fd_handler)
778           {
779              ecore_main_fd_handler_del(cl->fd_handler);
780              cl->fd_handler = NULL;
781           }
782      }
783    else
784      {
785         cl->server->clients = eina_list_remove(cl->server->clients, cl);
786         _ecore_con_client_free(cl);
787      }
788    return data;
789 }
790
791 /**
792  * Sets the data associated with the given client to @p data.
793  * @param   cl   The given client.
794  * @param   data What to set the data to.
795  * @ingroup Ecore_Con_Client_Group
796  */
797 EAPI void
798 ecore_con_client_data_set(Ecore_Con_Client *cl, const void *data)
799 {
800    if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
801      {
802         ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_data_set");
803         return;
804      }
805    cl->data = (void *)data;
806 }
807
808 /**
809  * Retrieves the data associated with the given client.
810  * @param   cl The given client.
811  * @return  The data associated with @p cl.
812  * @ingroup Ecore_Con_Client_Group
813  */
814 EAPI void *
815 ecore_con_client_data_get(Ecore_Con_Client *cl)
816 {
817    if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
818      {
819         ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_data_get");
820         return NULL;
821      }
822    return cl->data;
823 }
824
825 /**
826  * Gets the IP address of a cleint that has connected.
827  *
828  * @param   cl            The given client.
829  * @return  A pointer to an internal string that contains the IP address of
830  *          the connected client in the form "XXX.YYY.ZZZ.AAA" IP notation.
831  *          This string should not be modified or trusted to stay valid after
832  *          deletion for the @p cl object. If no IP is known NULL is returned.
833  * @ingroup Ecore_Con_Client_Group
834  */
835 EAPI char *
836 ecore_con_client_ip_get(Ecore_Con_Client *cl)
837 {
838    if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
839      {
840         ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_ip_get");
841         return NULL;
842      }
843    return cl->ip;
844 }
845
846 /**
847  * Flushes all pending data to the given client. Will return when done.
848  *
849  * @param   cl            The given client.
850  * @ingroup Ecore_Con_Client_Group
851  */
852 EAPI void
853 ecore_con_client_flush(Ecore_Con_Client *cl)
854 {
855    if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
856      {
857         ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_flush");
858         return;
859      }
860    _ecore_con_client_flush(cl);
861 }
862
863 static void
864 _ecore_con_server_free(Ecore_Con_Server *svr)
865 {
866    Ecore_Con_Client *cl;
867    double t_start, t;
868
869    ECORE_MAGIC_SET(svr, ECORE_MAGIC_NONE);
870    t_start = ecore_time_get();
871    while ((svr->write_buf) && (!svr->dead))
872      {
873         _ecore_con_server_flush(svr);
874         t = ecore_time_get();
875         if ((t - t_start) > 0.5)
876           {
877              printf("ECORE_CON: EEK - stuck in _ecore_con_server_free() trying\n"
878                     "  to flush data out from the server, and have been for\n"
879                     "  %1.1f seconds. This is taking too long. Aborting flush.\n",
880                     (t - t_start));
881              break;
882           }
883      }
884    if (svr->write_buf) free(svr->write_buf);
885    while (svr->clients)
886      {
887        cl = eina_list_data_get(svr->clients);
888        svr->clients = eina_list_remove(svr->clients, cl);
889        _ecore_con_client_free(cl);
890      }
891    if ((svr->created) && (svr->path) && (svr->ppid == getpid()))
892      unlink(svr->path);
893    if (svr->fd >= 0) close(svr->fd);
894    ecore_con_ssl_server_shutdown(svr);
895    if (svr->name) free(svr->name);
896    if (svr->path) free(svr->path);
897    if (svr->ip) free(svr->ip);
898    if (svr->fd_handler) ecore_main_fd_handler_del(svr->fd_handler);
899    free(svr);
900 }
901
902 static void
903 _ecore_con_client_free(Ecore_Con_Client *cl)
904 {
905    double t_start, t;
906
907    ECORE_MAGIC_SET(cl, ECORE_MAGIC_NONE);
908    t_start = ecore_time_get();
909    while ((cl->buf) && (!cl->dead))
910      {
911         _ecore_con_client_flush(cl);
912         t = ecore_time_get();
913         if ((t - t_start) > 0.5)
914           {
915              printf("ECORE_CON: EEK - stuck in _ecore_con_client_free() trying\n"
916                     "  to flush data out from the client, and have been for\n"
917                     "  %1.1f seconds. This is taking too long. Aborting flush.\n",
918                     (t - t_start));
919              break;
920           }
921      }
922    if (cl->buf) free(cl->buf);
923    if (cl->fd >= 0) close(cl->fd);
924    if (cl->fd_handler) ecore_main_fd_handler_del(cl->fd_handler);
925    if (cl->ip) free(cl->ip);
926    free(cl);
927 }
928
929 static void
930 kill_server(Ecore_Con_Server *svr)
931 {
932    if (!svr->delete_me)
933      {
934         Ecore_Con_Event_Server_Del *e;
935
936         e = calloc(1, sizeof(Ecore_Con_Event_Server_Del));
937         if (e)
938           {
939              svr->event_count++;
940              e->server = svr;
941              ecore_event_add(ECORE_CON_EVENT_SERVER_DEL, e,
942                              _ecore_con_event_server_del_free, NULL);
943           }
944      }
945
946    svr->dead = 1;
947    if (svr->fd_handler) ecore_main_fd_handler_del(svr->fd_handler);
948    svr->fd_handler = NULL;
949 }
950
951 static void
952 _ecore_con_cb_tcp_listen(void *data, Ecore_Con_Info *net_info)
953 {
954    Ecore_Con_Server *svr;
955    struct linger lin;
956
957    svr = data;
958
959    if(!net_info) goto error;
960
961    svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype, net_info->info.ai_protocol);
962    if (svr->fd < 0) goto error;
963    if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
964    if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
965    lin.l_onoff = 1;
966    lin.l_linger = 0;
967    if (setsockopt(svr->fd, SOL_SOCKET, SO_LINGER, &lin, sizeof(struct linger)) < 0) goto error;
968    if (bind(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen) < 0) goto error;
969    if (listen(svr->fd, 4096) < 0) goto error;
970    svr->fd_handler =
971      ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
972                                _ecore_con_svr_handler, svr, NULL, NULL);
973    if (!svr->fd_handler) goto error;
974
975    return;
976
977    error:
978    ecore_con_ssl_server_shutdown(svr);
979    kill_server(svr);
980 }
981
982 static void
983 _ecore_con_cb_udp_listen(void *data, Ecore_Con_Info *net_info)
984 {
985    Ecore_Con_Server *svr;
986    Ecore_Con_Type type;
987    struct ip_mreq mreq;
988    struct ipv6_mreq mreq6;
989    const int on = 1;
990
991    svr = data;
992    type = svr->type;
993    type &= ECORE_CON_TYPE;
994
995    if (!net_info) goto error;
996
997    svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype, net_info->info.ai_protocol);
998    if(svr->fd < 0) goto error;
999
1000    if (type == ECORE_CON_REMOTE_MCAST)
1001      {
1002        if (net_info->info.ai_family == AF_INET)
1003          {
1004            if (!inet_pton(net_info->info.ai_family, net_info->ip, &mreq.imr_multiaddr)) goto error;
1005            mreq.imr_interface.s_addr = htonl(INADDR_ANY);
1006            if (setsockopt(svr->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,sizeof(mreq)) != 0) goto error;
1007          }
1008        else if (net_info->info.ai_family == AF_INET6)
1009          {
1010            if (!inet_pton(net_info->info.ai_family, net_info->ip, &mreq6.ipv6mr_multiaddr)) goto error;
1011            mreq6.ipv6mr_interface = htonl(INADDR_ANY);
1012            if (setsockopt(svr->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq6,sizeof(mreq6)) != 0) goto error;
1013          }
1014        if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, &on,sizeof(on)) != 0) goto error;
1015      }
1016
1017    if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
1018    if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
1019    if (bind(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen) < 0) goto error;
1020    svr->fd_handler =
1021      ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
1022                                _ecore_con_svr_udp_handler, svr, NULL, NULL);
1023    if (!svr->fd_handler) goto error;
1024    svr->ip = strdup(net_info->ip);
1025
1026    return;
1027
1028    error:
1029    ecore_con_ssl_server_shutdown(svr);
1030    kill_server(svr);
1031 }
1032
1033 static void
1034 _ecore_con_cb_tcp_connect(void *data, Ecore_Con_Info *net_info)
1035 {
1036    Ecore_Con_Server   *svr;
1037    int                 curstate = 0;
1038
1039    svr = data;
1040
1041    if (!net_info) goto error;
1042    svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype, net_info->info.ai_protocol);
1043    if (svr->fd < 0) goto error;
1044    if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
1045    if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
1046    if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, &curstate, sizeof(curstate)) < 0)
1047      goto error;
1048    if (connect(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen) < 0)
1049      {
1050        if (errno != EINPROGRESS)
1051          goto error;
1052        svr->connecting = 1;
1053        svr->fd_handler =
1054          ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ | ECORE_FD_WRITE,
1055                                    _ecore_con_cl_handler, svr, NULL, NULL);
1056      }
1057    else
1058      svr->fd_handler =
1059        ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
1060                                  _ecore_con_cl_handler, svr, NULL, NULL);
1061
1062    if (svr->type & ECORE_CON_SSL)
1063      if (ecore_con_ssl_server_init(svr))
1064        goto error;
1065
1066    if (!svr->fd_handler) goto error;
1067    svr->ip = strdup(net_info->ip);
1068
1069    return;
1070
1071    error:
1072    ecore_con_ssl_server_shutdown(svr);
1073    kill_server(svr);
1074 }
1075
1076 static void
1077 _ecore_con_cb_udp_connect(void *data, Ecore_Con_Info *net_info)
1078 {
1079    Ecore_Con_Server   *svr;
1080    int                 curstate = 0;
1081
1082    svr = data;
1083
1084    if (!net_info) goto error;
1085    svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype, net_info->info.ai_protocol);
1086    if (svr->fd < 0) goto error;
1087    if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
1088    if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
1089    if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, &curstate, sizeof(curstate)) < 0)
1090      goto error;
1091    if (connect(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen) < 0)
1092      goto error;
1093    else
1094      svr->fd_handler =
1095        ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ | ECORE_FD_WRITE,
1096                                  _ecore_con_cl_udp_handler, svr, NULL, NULL);
1097    if (!svr->fd_handler) goto error;
1098    svr->ip = strdup(net_info->ip);
1099
1100    return;
1101
1102    error:
1103    ecore_con_ssl_server_shutdown(svr);
1104    kill_server(svr);
1105 }
1106
1107 static Ecore_Con_State
1108 svr_try_connect_plain(Ecore_Con_Server *svr)
1109 {
1110    int so_err = 0;
1111    unsigned int size = sizeof(int);
1112
1113    if (getsockopt(svr->fd, SOL_SOCKET, SO_ERROR, &so_err, &size) < 0)
1114      so_err = -1;
1115
1116    if (so_err == EINPROGRESS && !svr->dead)
1117      return ECORE_CON_INPROGRESS;
1118
1119    if (so_err != 0)
1120      {
1121         /* we lost our server! */
1122         kill_server(svr);
1123         return ECORE_CON_DISCONNECTED;
1124      }
1125    else
1126      {
1127         if (!svr->delete_me)
1128           {
1129              /* we got our server! */
1130              Ecore_Con_Event_Server_Add *e;
1131
1132              svr->connecting = 0;
1133              e = calloc(1, sizeof(Ecore_Con_Event_Server_Add));
1134              if (e)
1135                {
1136                   svr->event_count++;
1137                   e->server = svr;
1138                   ecore_event_add(ECORE_CON_EVENT_SERVER_ADD, e,
1139                                   _ecore_con_event_server_add_free, NULL);
1140                }
1141           }
1142         if (svr->fd_handler)
1143           {
1144              if (!svr->write_buf)
1145                ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
1146           }
1147      }
1148
1149    if (!svr->dead)
1150      return ECORE_CON_CONNECTED;
1151    else
1152      return ECORE_CON_DISCONNECTED;
1153 }
1154
1155 /* returns 1 on success, 0 on failure */
1156 static Ecore_Con_State svr_try_connect(Ecore_Con_Server *svr)
1157 {
1158   if (!(svr->type & ECORE_CON_SSL))
1159     return svr_try_connect_plain(svr);
1160   else
1161     {
1162       switch (ecore_con_ssl_server_try(svr)) {
1163       case ECORE_CON_CONNECTED:
1164         return svr_try_connect_plain(svr);
1165       case ECORE_CON_DISCONNECTED:
1166         kill_server(svr);
1167         return ECORE_CON_DISCONNECTED;
1168       default:
1169         return ECORE_CON_INPROGRESS;
1170       }
1171     }
1172 }
1173
1174 static int
1175 _ecore_con_svr_handler(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__)
1176 {
1177    Ecore_Con_Server   *svr;
1178    int                 new_fd;
1179    struct sockaddr_in  incoming;
1180    size_t              size_in;
1181
1182    svr = data;
1183    if (svr->dead) return 1;
1184    if (svr->delete_me) return 1;
1185    if ((svr->client_limit >= 0) && (!svr->reject_excess_clients))
1186      {
1187         if (eina_list_count(svr->clients) >= svr->client_limit) return 1;
1188      }
1189    /* a new client */
1190    size_in = sizeof(struct sockaddr_in);
1191
1192    new_fd = accept(svr->fd, (struct sockaddr *)&incoming, (socklen_t *)&size_in);
1193    if (new_fd >= 0)
1194      {
1195         Ecore_Con_Client *cl;
1196         char buf[64];
1197         uint32_t ip;
1198
1199         if ((svr->client_limit >= 0) && (svr->reject_excess_clients))
1200           {
1201              close(new_fd);
1202              return 1;
1203           }
1204
1205         cl = calloc(1, sizeof(Ecore_Con_Client));
1206         if (!cl)
1207           {
1208              close(new_fd);
1209              return 1;
1210           }
1211
1212         fcntl(new_fd, F_SETFL, O_NONBLOCK);
1213         fcntl(new_fd, F_SETFD, FD_CLOEXEC);
1214         cl->fd = new_fd;
1215         cl->server = svr;
1216
1217         if ((svr->type & ECORE_CON_SSL) &&
1218             (ecore_con_ssl_client_init(cl)))
1219           {
1220             close(new_fd);
1221             ecore_con_ssl_client_shutdown(cl);
1222             return 1;
1223           }
1224
1225         cl->fd_handler =
1226           ecore_main_fd_handler_add(cl->fd, ECORE_FD_READ,
1227                                     _ecore_con_svr_cl_handler, cl, NULL, NULL);
1228         ECORE_MAGIC_SET(cl, ECORE_MAGIC_CON_CLIENT);
1229         eina_list_append(svr->clients, cl);
1230         if (!svr->path)
1231           {
1232              ip = incoming.sin_addr.s_addr;
1233              snprintf(buf, sizeof(buf),
1234                       "%i.%i.%i.%i",
1235                       (ip      ) & 0xff,
1236                       (ip >> 8 ) & 0xff,
1237                       (ip >> 16) & 0xff,
1238                       (ip >> 24) & 0xff);
1239              cl->ip = strdup(buf);
1240           }
1241         if (!cl->delete_me)
1242           {
1243              Ecore_Con_Event_Client_Add *e;
1244
1245              e = calloc(1, sizeof(Ecore_Con_Event_Client_Add));
1246              if (e)
1247                {
1248                   cl->event_count++;
1249                   e->client = cl;
1250                   ecore_event_add(ECORE_CON_EVENT_CLIENT_ADD, e,
1251                                   _ecore_con_event_client_add_free, NULL);
1252                }
1253           }
1254      }
1255    return 1;
1256 }
1257
1258 static int
1259 _ecore_con_cl_handler(void *data, Ecore_Fd_Handler *fd_handler)
1260 {
1261    Ecore_Con_Server   *svr;
1262
1263    svr = data;
1264    if (svr->dead) return 1;
1265    if (svr->delete_me) return 1;
1266    if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
1267      {
1268         unsigned char *inbuf = NULL;
1269         int            inbuf_num = 0;
1270
1271         if (svr->connecting && (svr_try_connect(svr) != ECORE_CON_CONNECTED))
1272            return 1;
1273
1274         for (;;)
1275           {
1276             int num;
1277             int lost_server = 1;
1278             unsigned char buf[READBUFSIZ];
1279
1280             if (!(svr->type & ECORE_CON_SSL))
1281               {
1282                 if (((num = read(svr->fd, buf, READBUFSIZ)) < 0) &&
1283                     (errno == EAGAIN))
1284                   lost_server = 0;
1285               }
1286             else
1287               if (!(num = ecore_con_ssl_server_read(svr, buf, READBUFSIZ)))
1288                   lost_server = 0;
1289
1290             if (num < 1)
1291               {
1292                 if (inbuf && !svr->delete_me)
1293                   {
1294                     Ecore_Con_Event_Server_Data *e;
1295
1296                     e = calloc(1, sizeof(Ecore_Con_Event_Server_Data));
1297                     if (e)
1298                       {
1299                         svr->event_count++;
1300                         e->server = svr;
1301                         e->data = inbuf;
1302                         e->size = inbuf_num;
1303                         ecore_event_add(ECORE_CON_EVENT_SERVER_DATA, e,
1304                                         _ecore_con_event_server_data_free,
1305                                         NULL);
1306                       }
1307                   }
1308                 if (lost_server) kill_server(svr);
1309                 break;
1310               }
1311
1312             inbuf = realloc(inbuf, inbuf_num + num);
1313             memcpy(inbuf + inbuf_num, buf, num);
1314             inbuf_num += num;
1315           }
1316
1317 /* #if USE_OPENSSL */
1318 /*      if (svr->fd_handler) */
1319 /*        { */
1320 /*           if (svr->ssl && ssl_err == SSL_ERROR_WANT_READ) */
1321 /*             ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ); */
1322 /*           else if (svr->ssl && ssl_err == SSL_ERROR_WANT_WRITE) */
1323 /*             ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE); */
1324 /*        } */
1325 /* #endif */
1326      }
1327    else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE))
1328      {
1329         if (svr->connecting && !svr_try_connect (svr))
1330            return 1;
1331         _ecore_con_server_flush(svr);
1332      }
1333
1334    return 1;
1335 }
1336
1337 static int
1338 _ecore_con_cl_udp_handler(void *data, Ecore_Fd_Handler *fd_handler)
1339 {
1340    Ecore_Con_Server   *svr;
1341
1342    svr = data;
1343    if (svr->dead) return 1;
1344    if (svr->delete_me) return 1;
1345    if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
1346      {
1347        unsigned char buf[65536];
1348        int           num = 0;
1349
1350        errno = 0;
1351        num = read(svr->fd, buf, 65536);
1352        if (num > 0)
1353          {
1354            if (!svr->delete_me)
1355              {
1356                Ecore_Con_Event_Server_Data *e;
1357                unsigned char *inbuf;
1358
1359                inbuf = malloc(num);
1360                if(inbuf == NULL)
1361                  return 1;
1362                memcpy(inbuf, buf, num);
1363
1364                e = calloc(1, sizeof(Ecore_Con_Event_Server_Data));
1365                if (e)
1366                  {
1367                    svr->event_count++;
1368                    e->server = svr;
1369                    e->data = inbuf;
1370                    e->size = num;
1371                    ecore_event_add(ECORE_CON_EVENT_SERVER_DATA, e,
1372                                    _ecore_con_event_server_data_free,
1373                                    NULL);
1374                  }
1375              }
1376          }
1377      }
1378    else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE))
1379        _ecore_con_server_flush(svr);
1380
1381    return 1;
1382 }
1383
1384 static int
1385 _ecore_con_svr_udp_handler(void *data, Ecore_Fd_Handler *fd_handler)
1386 {
1387    Ecore_Con_Server   *svr;
1388    Ecore_Con_Client *cl;
1389
1390    svr = data;
1391    if (svr->dead) return 1;
1392    if (svr->delete_me) return 1;
1393    if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
1394      {
1395        unsigned char buf[READBUFSIZ];
1396        struct sockaddr_in client_addr;
1397        unsigned int client_addr_len = sizeof(client_addr);
1398        int num;
1399
1400        errno = 0;
1401        num = recvfrom(svr->fd, buf, sizeof(buf), MSG_DONTWAIT, (struct sockaddr*) &client_addr, &client_addr_len);
1402
1403        if (num > 0)
1404          {
1405            if (!svr->delete_me)
1406              {
1407                Ecore_Con_Event_Client_Data *e;
1408                unsigned char *inbuf;
1409                uint32_t ip;
1410                char ipbuf[64];
1411
1412                /* Create a new client for use in the client data event */
1413                cl = calloc(1, sizeof(Ecore_Con_Client));
1414                if(cl == NULL)
1415                  return 1;
1416                cl->buf = NULL;
1417                cl->fd = 0;
1418                cl->fd_handler = NULL;
1419                cl->server = svr;
1420                cl->data = calloc(1, sizeof(client_addr));
1421                if(cl->data == NULL)
1422                  {
1423                    free(cl);
1424                    return 1;
1425                  }
1426                memcpy(cl->data,  &client_addr, sizeof(client_addr));
1427                ECORE_MAGIC_SET(cl, ECORE_MAGIC_CON_CLIENT);
1428                eina_list_append(svr->clients, cl);
1429
1430                ip = client_addr.sin_addr.s_addr;
1431                snprintf(ipbuf, sizeof(ipbuf),
1432                         "%i.%i.%i.%i",
1433                         (ip      ) & 0xff,
1434                         (ip >> 8 ) & 0xff,
1435                         (ip >> 16) & 0xff,
1436                         (ip >> 24) & 0xff);
1437                cl->ip = strdup(ipbuf);
1438
1439                inbuf = malloc(num);
1440                if(inbuf == NULL)
1441                  {
1442                    free(cl->data);
1443                    free(cl);
1444                    return 1;
1445                  }
1446
1447                memcpy(inbuf, buf, num);
1448
1449                e = calloc(1, sizeof(Ecore_Con_Event_Client_Data));
1450                if (e)
1451                  {
1452                    svr->event_count++;
1453                    e->client = cl;
1454                    e->data = inbuf;
1455                    e->size = num;
1456                    ecore_event_add(ECORE_CON_EVENT_CLIENT_DATA, e,
1457                                    _ecore_con_event_client_data_free,
1458                                    NULL);
1459                  }
1460
1461                if(!cl->delete_me)
1462                  {
1463                    Ecore_Con_Event_Client_Add *add;
1464
1465                    add = calloc(1, sizeof(Ecore_Con_Event_Client_Add));
1466                    if(add)
1467                      {
1468                        /*cl->event_count++;*/
1469                        add->client = cl;
1470                        ecore_event_add(ECORE_CON_EVENT_CLIENT_ADD, add,
1471                                        _ecore_con_event_client_add_free, NULL);
1472                      }
1473                  }
1474              }
1475            if ((errno == EIO) ||  (errno == EBADF) ||
1476                (errno == EPIPE) || (errno == EINVAL) ||
1477                (errno == ENOSPC) || (num == 0)/* is num == 0 right? */)
1478              {
1479                if (!svr->delete_me)
1480                  {
1481                    /* we lost our client! */
1482                    Ecore_Con_Event_Client_Del *e;
1483
1484                    e = calloc(1, sizeof(Ecore_Con_Event_Client_Del));
1485                    if (e)
1486                      {
1487                        svr->event_count++;
1488                        e->client = cl;
1489                        ecore_event_add(ECORE_CON_EVENT_CLIENT_DEL, e,
1490                                        _ecore_con_event_client_del_free,
1491                                        NULL);
1492                      }
1493                  }
1494                svr->dead = 1;
1495                if (svr->fd_handler)
1496                  ecore_main_fd_handler_del(svr->fd_handler);
1497                svr->fd_handler = NULL;
1498              }
1499          }
1500      }
1501    else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE))
1502      _ecore_con_client_flush(cl);
1503    return 1;
1504 }
1505
1506 static int
1507 _ecore_con_svr_cl_handler(void *data, Ecore_Fd_Handler *fd_handler)
1508 {
1509    Ecore_Con_Client   *cl;
1510
1511    cl = data;
1512    if (cl->dead) return 1;
1513    if (cl->delete_me) return 1;
1514    if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
1515      {
1516         unsigned char *inbuf = NULL;
1517         int            inbuf_num = 0;
1518         int            lost_client = 1;
1519
1520         for (;;)
1521           {
1522              unsigned char buf[65536];
1523              int num;
1524
1525              errno = 0;
1526
1527              if (!(cl->server->type & ECORE_CON_SSL))
1528                {
1529                  if (((num = read(cl->fd, buf, 65536)) < 0) &&
1530                      (errno == EAGAIN))
1531                    lost_client = 0;
1532                }
1533              else
1534                if (!(num = ecore_con_ssl_client_read(cl, buf, 65536)))
1535                  lost_client = 0;
1536
1537              if (num < 1)
1538                {
1539                   if (inbuf && !cl->delete_me)
1540                     {
1541                       Ecore_Con_Event_Client_Data *e;
1542                       
1543                       e = calloc(1, sizeof(Ecore_Con_Event_Client_Data));
1544                       if (e)
1545                         {
1546                           cl->event_count++;
1547                           e->client = cl;
1548                           e->data = inbuf;
1549                           e->size = inbuf_num;
1550                           ecore_event_add(ECORE_CON_EVENT_CLIENT_DATA, e,
1551                                           _ecore_con_event_client_data_free,
1552                                           NULL);
1553                         }
1554                     }
1555
1556                   if (lost_client)
1557                     {
1558                        if (!cl->delete_me)
1559                          {
1560                             /* we lost our client! */
1561                             Ecore_Con_Event_Client_Del *e;
1562
1563                             e = calloc(1, sizeof(Ecore_Con_Event_Client_Del));
1564                             if (e)
1565                               {
1566                                  cl->event_count++;
1567                                  e->client = cl;
1568                                  ecore_event_add(ECORE_CON_EVENT_CLIENT_DEL, e,
1569                                                  _ecore_con_event_client_del_free,
1570                                                  NULL);
1571                               }
1572                          }
1573                        cl->dead = 1;
1574                        if (cl->fd_handler)
1575                          ecore_main_fd_handler_del(cl->fd_handler);
1576                        cl->fd_handler = NULL;
1577                     }
1578                   break;
1579                }
1580              else
1581                {
1582                   inbuf = realloc(inbuf, inbuf_num + num);
1583                   memcpy(inbuf + inbuf_num, buf, num);
1584                   inbuf_num += num;
1585                }
1586           }
1587      }
1588    else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE))
1589      _ecore_con_client_flush(cl);
1590    return 1;
1591 }
1592
1593 static void
1594 _ecore_con_server_flush(Ecore_Con_Server *svr)
1595 {
1596    int count, num;
1597
1598    if (!svr->write_buf) return;
1599
1600    /* check whether we need to write anything at all.
1601     * we must not write zero bytes with SSL_write() since it
1602     * causes undefined behaviour
1603     */
1604    if (svr->write_buf_size == svr->write_buf_offset)
1605       return;
1606
1607    num = svr->write_buf_size - svr->write_buf_offset;
1608
1609    if (!(svr->type & ECORE_CON_SSL))
1610      count = write(svr->fd, svr->write_buf + svr->write_buf_offset, num);
1611    else
1612      count = ecore_con_ssl_server_write(svr, svr->write_buf + svr->write_buf_offset, num);
1613
1614    if (count < 0)
1615      {
1616         /* we lost our server! */
1617         kill_server(svr);
1618         return;
1619      }
1620
1621    svr->write_buf_offset += count;
1622    if (svr->write_buf_offset >= svr->write_buf_size)
1623      {
1624         svr->write_buf_size = 0;
1625         svr->write_buf_offset = 0;
1626         free(svr->write_buf);
1627         svr->write_buf = NULL;
1628         if (svr->fd_handler)
1629           ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
1630      }
1631 }
1632
1633 static void
1634 _ecore_con_client_flush(Ecore_Con_Client *cl)
1635 {
1636    int count, num;
1637
1638    if (!cl->buf) return;
1639    num = cl->buf_size - cl->buf_offset;
1640    if (!(cl->server->type & ECORE_CON_SSL))
1641      count = write(cl->fd, cl->buf + cl->buf_offset, num);
1642    else
1643      count = ecore_con_ssl_client_write(cl, cl->buf + cl->buf_offset, num);
1644    if (count < 1)
1645      {
1646         if ((errno == EIO) || (errno == EBADF) || (errno == EPIPE) ||
1647             (errno == EINVAL) || (errno == ENOSPC))
1648           {
1649              if (!cl->delete_me)
1650                {
1651                   /* we lost our client! */
1652                   Ecore_Con_Event_Client_Del *e;
1653
1654                   e = calloc(1, sizeof(Ecore_Con_Event_Client_Del));
1655                   if (e)
1656                     {
1657                        cl->event_count++;
1658                        e->client = cl;
1659                        ecore_event_add(ECORE_CON_EVENT_CLIENT_DEL, e,
1660                                        _ecore_con_event_client_del_free, NULL);
1661                     }
1662                   cl->dead = 1;
1663                   if (cl->fd_handler)
1664                     ecore_main_fd_handler_del(cl->fd_handler);
1665                   cl->fd_handler = NULL;
1666                }
1667           }
1668         return;
1669      }
1670    cl->buf_offset += count;
1671    if (cl->buf_offset >= cl->buf_size)
1672      {
1673         cl->buf_size = 0;
1674         cl->buf_offset = 0;
1675         free(cl->buf);
1676         cl->buf = NULL;
1677         if (cl->fd_handler)
1678           ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ);
1679      }
1680 }
1681
1682 static void
1683 _ecore_con_event_client_add_free(void *data __UNUSED__, void *ev)
1684 {
1685    Ecore_Con_Event_Client_Add *e;
1686
1687    e = ev;
1688    e->client->event_count--;
1689    if ((e->client->event_count == 0) && (e->client->delete_me))
1690      ecore_con_client_del(e->client);
1691    free(e);
1692 }
1693
1694 static void
1695 _ecore_con_event_client_del_free(void *data __UNUSED__, void *ev)
1696 {
1697    Ecore_Con_Event_Client_Del *e;
1698
1699    e = ev;
1700    e->client->event_count--;
1701    if ((e->client->event_count == 0) && (e->client->delete_me))
1702      ecore_con_client_del(e->client);
1703    free(e);
1704 }
1705
1706 static void
1707 _ecore_con_event_client_data_free(void *data __UNUSED__, void *ev)
1708 {
1709    Ecore_Con_Event_Client_Data *e;
1710
1711    e = ev;
1712    e->client->event_count--;
1713    if (e->data) free(e->data);
1714    if (((e->client->event_count == 0) && (e->client->delete_me)) ||
1715        ((e->client->server && (e->client->server->type == ECORE_CON_REMOTE_UDP ||
1716                                e->client->server->type == ECORE_CON_REMOTE_MCAST))))
1717      ecore_con_client_del(e->client);
1718    free(e);
1719 }
1720
1721 static void
1722 _ecore_con_event_server_add_free(void *data __UNUSED__, void *ev)
1723 {
1724    Ecore_Con_Event_Server_Add *e;
1725
1726    e = ev;
1727    e->server->event_count--;
1728    if ((e->server->event_count == 0) && (e->server->delete_me))
1729      ecore_con_server_del(e->server);
1730    free(e);
1731 }
1732
1733 static void
1734 _ecore_con_event_server_del_free(void *data __UNUSED__, void *ev)
1735 {
1736    Ecore_Con_Event_Server_Del *e;
1737
1738    e = ev;
1739    e->server->event_count--;
1740    if ((e->server->event_count == 0) && (e->server->delete_me))
1741      ecore_con_server_del(e->server);
1742    free(e);
1743 }
1744
1745 static void
1746 _ecore_con_event_server_data_free(void *data __UNUSED__, void *ev)
1747 {
1748    Ecore_Con_Event_Server_Data *e;
1749
1750    e = ev;
1751    e->server->event_count--;
1752    if (e->data) free(e->data);
1753    if ((e->server->event_count == 0) && (e->server->delete_me))
1754      ecore_con_server_del(e->server);
1755    free(e);
1756 }