1
#define EFL_BETA_API_SUPPORT
3
#include <Ecore_Getopt.h>
6
static Eina_Bool echo = EINA_FALSE;
7
static double timeout = 10.0;
9
/* NOTE: client i/o events are only used as debug, you can omit these */
12
_client_can_read_changed(void *data EINA_UNUSED, const Efl_Event *event)
14
fprintf(stderr, "INFO: client %s can_read=%d\n",
15
efl_net_socket_address_remote_get(event->object),
16
efl_io_reader_can_read_get(event->object));
20
_client_can_write_changed(void *data EINA_UNUSED, const Efl_Event *event)
22
fprintf(stderr, "INFO: client %s can_write=%d\n",
23
efl_net_socket_address_remote_get(event->object),
24
efl_io_writer_can_write_get(event->object));
28
_client_eos(void *data EINA_UNUSED, const Efl_Event *event)
30
fprintf(stderr, "INFO: client %s eos.\n",
31
efl_net_socket_address_remote_get(event->object));
35
_client_closed(void *data EINA_UNUSED, const Efl_Event *event)
37
fprintf(stderr, "INFO: client %s closed.\n",
38
efl_net_socket_address_remote_get(event->object));
41
EFL_CALLBACKS_ARRAY_DEFINE(client_cbs,
42
{ EFL_IO_READER_EVENT_CAN_READ_CHANGED, _client_can_read_changed },
43
{ EFL_IO_READER_EVENT_EOS, _client_eos },
44
{ EFL_IO_WRITER_EVENT_CAN_WRITE_CHANGED, _client_can_write_changed },
45
{ EFL_IO_CLOSER_EVENT_CLOSED, _client_closed });
48
/* copier events are of interest, you should hook to at least "done"
52
/* echo copier is about the same socket, you can close it right away */
55
_echo_copier_done(void *data EINA_UNUSED, const Efl_Event *event)
57
Eo *copier = event->object;
58
fprintf(stderr, "INFO: echo copier done, close and del %p\n", copier);
59
efl_del(copier); /* set to close_on_destructor, will auto close copier and client */
63
_echo_copier_error(void *data EINA_UNUSED, const Efl_Event *event)
65
Eo *copier = event->object;
66
const Eina_Error *perr = event->info;
68
if (*perr == ETIMEDOUT)
70
Eo *client = efl_io_copier_source_get(copier);
71
fprintf(stderr, "INFO: client '%s' timed out, delete it.\n",
72
efl_net_socket_address_remote_get(client));
77
efl_loop_quit(efl_loop_get(event->object), eina_value_int_init(EXIT_FAILURE));
79
fprintf(stderr, "ERROR: echo copier %p failed %d '%s', close and del.\n",
80
copier, *perr, eina_error_msg_get(*perr));
85
EFL_CALLBACKS_ARRAY_DEFINE(echo_copier_cbs,
86
{ EFL_IO_COPIER_EVENT_DONE, _echo_copier_done },
87
{ EFL_IO_COPIER_EVENT_ERROR, _echo_copier_error});
89
/* When sender and receiver peers are about different entities, you
90
* can only close when both are done, otherwise the socket will be
93
* Here we use a struct with both copiers and NULL them once they are
94
* done, when both are done we close the socket and free the struct.
102
static Send_Recv_Data *
103
_send_recv_new(Eo *client)
105
Send_Recv_Data *d = calloc(1, sizeof(Send_Recv_Data));
108
/* take a reference since copiers will only hold their reference
109
* while they are alive. As we're deleting them before calling
110
* efl_io_closer_close(), then we need it for bit longer.
112
d->client = efl_ref(client);
117
_send_recv_free(Send_Recv_Data *d)
119
efl_unref(d->client);
124
_send_recv_done(Send_Recv_Data *d, Eo *copier)
126
if (d->send_copier == copier) d->send_copier = NULL;
127
else d->recv_copier = NULL;
130
if (d->send_copier || d->recv_copier) return;
131
efl_io_closer_close(d->client); /* manually close once both copiers are done */
136
_send_copier_done(void *data, const Efl_Event *event)
138
Eo *copier = event->object;
139
Eo *buffer = efl_io_copier_source_get(copier);
140
Eo *client = efl_io_copier_destination_get(copier);
141
Send_Recv_Data *d = data;
142
Eina_Slice slice = efl_io_buffer_slice_get(buffer);
144
/* show what we sent, just for debug */
146
"INFO: sent to %s %zd bytes:"
147
"\n--BEGIN SENT DATA--\n"
149
"\n--END SENT DATA--\n",
150
efl_net_socket_address_remote_get(client),
151
slice.len, EINA_SLICE_STR_PRINT(slice));
155
/* only start the reader inactivity timeout once the sender is done */
156
efl_io_copier_timeout_inactivity_set(d->recv_copier, efl_io_copier_timeout_inactivity_get(copier));
159
fprintf(stderr, "INFO: send copier done, check if should close %p\n", copier);
160
_send_recv_done(d, copier);
164
_send_copier_error(void *data, const Efl_Event *event)
166
Eo *copier = event->object;
167
Eo *buffer = efl_io_copier_source_get(copier);
168
Eo *client = efl_io_copier_destination_get(copier);
169
const Eina_Error *perr = event->info;
170
Send_Recv_Data *d = data;
172
Eina_Slice slice, remaining;
174
if (*perr == ETIMEDOUT)
176
fprintf(stderr, "INFO: client '%s' timed out send, delete it.\n",
177
efl_net_socket_address_remote_get(client));
178
efl_io_closer_close(copier); /* forces client to be closed, thus closes the recv copier as an effect */
182
efl_loop_quit(efl_loop_get(event->object), eina_value_int_init(EXIT_FAILURE));
184
offset = efl_io_buffer_position_read_get(buffer);
185
slice = efl_io_buffer_slice_get(buffer);
188
remaining.bytes += offset;
189
remaining.len -= offset;
194
"ERROR: sent to %s only %zd bytes:"
195
"\n--BEGIN SENT DATA--\n"
197
"\n--END SENT DATA--\n"
198
"Remaining %zd bytes:"
199
"\n--BEGIN REMAINING DATA--\n"
201
"\n--END REMAINING DATA--\n",
202
efl_net_socket_address_remote_get(client),
203
slice.len, EINA_SLICE_STR_PRINT(slice),
204
remaining.len, EINA_SLICE_STR_PRINT(remaining));
206
fprintf(stderr, "ERROR: send copier %p failed %d '%s', check if should close..\n",
207
copier, *perr, eina_error_msg_get(*perr));
208
_send_recv_done(d, copier);
211
EFL_CALLBACKS_ARRAY_DEFINE(send_copier_cbs,
212
{ EFL_IO_COPIER_EVENT_DONE, _send_copier_done },
213
{ EFL_IO_COPIER_EVENT_ERROR, _send_copier_error});
216
_recv_copier_done(void *data, const Efl_Event *event)
218
Eo *copier = event->object;
219
Eo *client = efl_io_copier_source_get(copier);
220
Eo *buffer = efl_io_copier_destination_get(copier);
221
Send_Recv_Data *d = data;
222
Eina_Slice slice = efl_io_buffer_slice_get(buffer);
224
/* show case, you could use a copier to Efl_Io_Stdout, a
225
* file... and get progressive processing.
227
* Here we're using a memory buffer and printing everything at
230
* You could also steal the binbuf with
231
* efl_io_buffer_binbuf_steal()
234
"INFO: recv from %s %zd bytes:"
235
"\n--BEGIN RECV DATA--\n"
236
EINA_SLICE_STR_FMT "\n"
237
"\n--END RECV DATA--\n",
238
efl_net_socket_address_remote_get(client),
239
slice.len, EINA_SLICE_STR_PRINT(slice));
241
fprintf(stderr, "INFO: receive copier done, check if should close %p\n", copier);
242
_send_recv_done(d, copier);
246
_recv_copier_error(void *data, const Efl_Event *event)
248
Eo *copier = event->object;
249
Eo *buffer = efl_io_copier_destination_get(copier);
250
Eo *client = efl_io_copier_source_get(copier);
251
const Eina_Error *perr = event->info;
252
Send_Recv_Data *d = data;
255
if (*perr == ETIMEDOUT)
257
fprintf(stderr, "INFO: client '%s' timed out recv, delete it.\n",
258
efl_net_socket_address_remote_get(client));
259
efl_io_closer_close(copier); /* forces client to be closed, thus closes the send copier as an effect */
263
efl_loop_quit(efl_loop_get(event->object), eina_value_int_init(EXIT_FAILURE));
265
slice = efl_io_buffer_slice_get(buffer);
267
"ERROR: recv to %s only %zd bytes:"
268
"\n--BEGIN RECV DATA--\n"
269
EINA_SLICE_STR_FMT "\n"
270
"\n--END RECV DATA--\n",
271
efl_net_socket_address_remote_get(client),
272
slice.len, EINA_SLICE_STR_PRINT(slice));
274
fprintf(stderr, "ERROR: receive copier %p failed %d '%s', check if should close..\n",
275
copier, *perr, eina_error_msg_get(*perr));
276
_send_recv_done(d, copier);
279
EFL_CALLBACKS_ARRAY_DEFINE(recv_copier_cbs,
280
{ EFL_IO_COPIER_EVENT_DONE, _recv_copier_done },
281
{ EFL_IO_COPIER_EVENT_ERROR, _recv_copier_error});
284
/* server events are mandatory, afterall you need to define what's
285
* going to happen after a client socket is connected. This is the
286
* "client,add" event.
288
* if clients_limit and clients_reject_excess are set, then
289
* "client,rejected" is dispatched for rejected sockets, they contain
290
* the string with socket identification.
293
_server_client_add(void *data EINA_UNUSED, const Efl_Event *event)
295
Efl_Net_Socket *client = event->info;
297
fprintf(stderr, "INFO: accepted client %s\n",
298
efl_net_socket_address_remote_get(client));
300
/* to use a client, you must efl_ref() it. Here we're not doing it
301
* explicitly because copiers do take a reference.
305
* monitor the client socket for debug purposes (optional)
307
efl_event_callback_array_add(client, client_cbs(), NULL);
310
* Since sockets are reader/writer/closer objects, we can use the
311
* Efl_Io_Copier utility.
317
* An echo copier is pretty simple, use the socket as both
318
* source and destination.
320
Eo *echo_copier = efl_add(EFL_IO_COPIER_CLASS, efl_parent_get(client),
321
efl_io_copier_source_set(efl_added, client),
322
efl_io_copier_destination_set(efl_added, client),
323
efl_io_copier_timeout_inactivity_set(efl_added, timeout),
324
efl_event_callback_array_add(efl_added, echo_copier_cbs(), client),
325
efl_io_closer_close_on_invalidate_set(efl_added, EINA_TRUE) /* we want to auto-close as we have a single copier */
328
fprintf(stderr, "INFO: using an echo copier=%p for client %s\n",
329
echo_copier, efl_net_socket_address_remote_get(client));
335
* Here we create a fixed buffer with a string to send:
337
* and another one to store the received buffer so we can print as
338
* a single blob at the end.
340
* One can change these to Efl_Io_File or event pipe to something
341
* else like Efl_Io_Stdin, Efl_Io_Stdout and it would just work.
343
static const Eina_Slice hello_world_slice = EINA_SLICE_STR_LITERAL("Hello World!");
345
Eo *send_buffer, *recv_buffer;
347
d = _send_recv_new(client);
350
fprintf(stderr, "ERROR: could not allocate memory\n");
354
send_buffer = efl_add_ref(EFL_IO_BUFFER_CLASS, NULL,
355
efl_io_buffer_adopt_readonly(efl_added, hello_world_slice));
357
/* Unlimited buffer to store the received data. */
358
recv_buffer = efl_add_ref(EFL_IO_BUFFER_CLASS, NULL);
360
/* an input copier that takes data from send_buffer and pushes to client */
361
d->send_copier = efl_add(EFL_IO_COPIER_CLASS, efl_parent_get(client),
362
efl_io_copier_source_set(efl_added, send_buffer),
363
efl_io_copier_destination_set(efl_added, client),
364
efl_io_copier_timeout_inactivity_set(efl_added, timeout),
365
efl_event_callback_array_add(efl_added, send_copier_cbs(), d),
366
efl_io_closer_close_on_invalidate_set(efl_added, EINA_FALSE) /* we must wait both copiers to finish before we close! */
369
fprintf(stderr, "INFO: using sender buffer %p with copier %p for client %s\n",
370
send_buffer, d->send_copier, efl_net_socket_address_remote_get(client));
372
efl_unref(send_buffer); /* d->send_copier adds a reference */
374
fprintf(stderr, "ERROR: failed to create sender copier\n");
377
/* an output copier that takes data from socket and pushes to recv_buffer. */
378
d->recv_copier = efl_add(EFL_IO_COPIER_CLASS, efl_parent_get(client),
379
efl_io_copier_source_set(efl_added, client),
380
efl_io_copier_destination_set(efl_added, recv_buffer),
381
efl_io_copier_timeout_inactivity_set(efl_added, 0.0), /* we'll only set an inactivity timeout once the sender is done */
382
efl_event_callback_array_add(efl_added, recv_copier_cbs(), d),
383
efl_io_closer_close_on_invalidate_set(efl_added, EINA_FALSE) /* we must wait both copiers to finish before we close! */
386
fprintf(stderr, "INFO: using receiver buffer %p with copier %p for client %s\n",
387
recv_buffer, d->recv_copier, efl_net_socket_address_remote_get(client));
389
efl_unref(recv_buffer); /* d->recv_copier adds a reference */
391
fprintf(stderr, "ERROR: failed to create receiver copier\n");
393
if (!d->recv_copier && !d->send_copier)
399
_server_client_rejected(void *data EINA_UNUSED, const Efl_Event *event)
401
const char *client_address = event->info;
402
fprintf(stderr, "INFO: rejected client %s\n", client_address);
406
_server_error(void *data EINA_UNUSED, const Efl_Event *event)
408
const Eina_Error *perr = event->info;
409
fprintf(stderr, "ERROR: %d '%s'\n", *perr, eina_error_msg_get(*perr));
410
efl_loop_quit(efl_loop_get(event->object), eina_value_int_init(EXIT_FAILURE));
414
_server_serving(void *data EINA_UNUSED, const Efl_Event *event)
416
fprintf(stderr, "INFO: serving at %s\n",
417
efl_net_server_address_get(event->object));
419
if (efl_class_get(event->object) == EFL_NET_SERVER_TCP_CLASS)
423
" - IPv6 only: %u\n",
424
efl_net_server_ip_ipv6_only_get(event->object));
426
else if (efl_class_get(event->object) == EFL_NET_SERVER_UDP_CLASS)
434
" - don't route: %u\n"
435
" - multicast TTL: %u\n"
436
" - multicast loopback: %u\n"
437
" - multicast groups:\n",
438
efl_net_server_ip_ipv6_only_get(event->object),
439
efl_net_server_udp_dont_route_get(event->object),
440
efl_net_server_udp_multicast_time_to_live_get(event->object),
441
efl_net_server_udp_multicast_loopback_get(event->object));
443
it = efl_net_server_udp_multicast_groups_get(event->object);
444
EINA_ITERATOR_FOREACH(it, str)
445
fprintf(stderr, " * %s\n", str);
446
eina_iterator_free(it);
450
EFL_CALLBACKS_ARRAY_DEFINE(server_cbs,
451
{ EFL_NET_SERVER_EVENT_CLIENT_ADD, _server_client_add },
452
{ EFL_NET_SERVER_EVENT_CLIENT_REJECTED, _server_client_rejected },
453
{ EFL_NET_SERVER_EVENT_SERVER_ERROR, _server_error },
454
{ EFL_NET_SERVER_EVENT_SERVING, _server_serving });
456
static const char * protocols[] = {
460
#ifdef EFL_NET_SERVER_WINDOWS_CLASS
463
#ifdef EFL_NET_SERVER_UNIX_CLASS
469
static const char *ciphers_strs[] = {
477
static const Ecore_Getopt options = {
478
"efl_net_server_example", /* program name */
479
NULL, /* usage line */
481
"(C) 2016 Enlightenment Project", /* copyright */
482
"BSD 2-Clause", /* license */
483
/* long description, may be multiline and contain \n */
484
"Example of Efl_Net_Server objects usage.\n"
486
"This example spawns a server of the given protocol at the given address.",
489
ECORE_GETOPT_STORE_TRUE('e', "echo",
490
"Behave as 'echo' server, send back to client all the data receive"),
491
ECORE_GETOPT_STORE_TRUE(0, "socket-activated",
492
"Try to use $LISTEN_FDS from systemd, if not do a regular serve()"),
493
ECORE_GETOPT_STORE_UINT('l', "clients-limit",
494
"If set will limit number of clients to accept"),
495
ECORE_GETOPT_STORE_TRUE('r', "clients-reject-excess",
496
"Immediately reject excess clients (over limit)"),
497
ECORE_GETOPT_STORE_FALSE(0, "ipv4-on-ipv6",
498
"IPv4 clients will be automatically converted into IPv6 and handled transparently."),
499
ECORE_GETOPT_STORE_DOUBLE('t', "inactivity-timeout",
500
"The timeout in seconds to disconnect a client. The timeout is restarted for each client when there is some activity. It's particularly useful for UDP where there is no disconnection event."),
502
ECORE_GETOPT_VERSION('V', "version"),
503
ECORE_GETOPT_COPYRIGHT('C', "copyright"),
504
ECORE_GETOPT_LICENSE('L', "license"),
505
ECORE_GETOPT_HELP('h', "help"),
507
ECORE_GETOPT_CATEGORY("udp", "UDP options"),
508
ECORE_GETOPT_STORE_TRUE(0, "udp-dont-route",
509
"If true, datagrams won't be routed using a gateway, being restricted to the local network."),
510
ECORE_GETOPT_STORE_UINT(0, "udp-multicast-ttl",
511
"Multicast time to live in number of hops from 0-255. Defaults to 1 (only local network)."),
512
ECORE_GETOPT_STORE_FALSE(0, "udp-multicast-noloopback",
513
"Disable multicast loopback."),
514
ECORE_GETOPT_APPEND('M', "udp-multicast-group", "Join a multicast group in the form 'IP@INTERFACE', with optional '@INTERFACE', where INTERFACE is the IP address of the interface to join the multicast.", ECORE_GETOPT_TYPE_STR),
516
ECORE_GETOPT_CATEGORY("ssl", "SSL options"),
517
ECORE_GETOPT_CHOICE('c', "ssl-cipher", "Cipher to use, defaults to 'auto'", ciphers_strs),
518
ECORE_GETOPT_APPEND(0, "ssl-certificate", "certificate path to use.", ECORE_GETOPT_TYPE_STR),
519
ECORE_GETOPT_APPEND(0, "ssl-private-key", "private key path to use.", ECORE_GETOPT_TYPE_STR),
520
ECORE_GETOPT_APPEND(0, "ssl-crl", "certificate revocation list to use.", ECORE_GETOPT_TYPE_STR),
521
ECORE_GETOPT_APPEND(0, "ssl-ca", "certificate authorities path to use.", ECORE_GETOPT_TYPE_STR),
523
ECORE_GETOPT_CHOICE_METAVAR(0, NULL, "The server protocol.", "protocol",
525
ECORE_GETOPT_STORE_METAVAR_STR(0, NULL,
526
"The server address to listen, such as "
527
"IPv4:PORT, [IPv6]:PORT, Unix socket path...",
530
ECORE_GETOPT_SENTINEL
534
static Eo *server = NULL;
537
efl_pause(void *data EINA_UNUSED,
538
const Efl_Event *ev EINA_UNUSED)
543
efl_resume(void *data EINA_UNUSED,
544
const Efl_Event *ev EINA_UNUSED)
549
efl_terminate(void *data EINA_UNUSED,
550
const Efl_Event *ev EINA_UNUSED)
552
/* FIXME: For the moment the main loop doesn't get
553
properly destroyed on shutdown which disallow
554
relying on parent destroying their children */
561
fprintf(stderr, "INFO: main loop finished.\n");
565
efl_main(void *data EINA_UNUSED,
568
const Efl_Class *cls;
569
char *protocol = NULL;
570
char *address = NULL;
571
Eina_List *udp_mcast_groups = NULL;
573
unsigned int clients_limit = 0;
574
unsigned udp_mcast_ttl = 1;
575
Eina_Bool clients_reject_excess = EINA_FALSE;
576
Eina_Bool ipv6_only = EINA_TRUE;
577
Eina_Bool udp_dont_route = EINA_FALSE;
578
Eina_Bool udp_mcast_loopback = EINA_TRUE;
579
Eina_List *certificates = NULL;
580
Eina_List *private_keys = NULL;
581
Eina_List *crls = NULL;
582
Eina_List *cas = NULL;
583
char *cipher_choice = NULL;
584
Eina_Bool socket_activated = EINA_FALSE;
585
Eina_Bool quit_option = EINA_FALSE;
586
Ecore_Getopt_Value values[] = {
587
ECORE_GETOPT_VALUE_BOOL(echo),
588
ECORE_GETOPT_VALUE_BOOL(socket_activated),
589
ECORE_GETOPT_VALUE_UINT(clients_limit),
590
ECORE_GETOPT_VALUE_BOOL(clients_reject_excess),
591
ECORE_GETOPT_VALUE_BOOL(ipv6_only),
592
ECORE_GETOPT_VALUE_DOUBLE(timeout),
594
/* standard block to provide version, copyright, license and help */
595
ECORE_GETOPT_VALUE_BOOL(quit_option), /* -V/--version quits */
596
ECORE_GETOPT_VALUE_BOOL(quit_option), /* -C/--copyright quits */
597
ECORE_GETOPT_VALUE_BOOL(quit_option), /* -L/--license quits */
598
ECORE_GETOPT_VALUE_BOOL(quit_option), /* -h/--help quits */
600
ECORE_GETOPT_VALUE_BOOL(quit_option), /* category: udp */
601
ECORE_GETOPT_VALUE_BOOL(udp_dont_route),
602
ECORE_GETOPT_VALUE_UINT(udp_mcast_ttl),
603
ECORE_GETOPT_VALUE_BOOL(udp_mcast_loopback),
604
ECORE_GETOPT_VALUE_LIST(udp_mcast_groups),
606
ECORE_GETOPT_VALUE_BOOL(quit_option), /* category: ssl */
607
ECORE_GETOPT_VALUE_STR(cipher_choice),
608
ECORE_GETOPT_VALUE_LIST(certificates),
609
ECORE_GETOPT_VALUE_LIST(private_keys),
610
ECORE_GETOPT_VALUE_LIST(crls),
611
ECORE_GETOPT_VALUE_LIST(cas),
613
/* positional argument */
614
ECORE_GETOPT_VALUE_STR(protocol),
615
ECORE_GETOPT_VALUE_STR(address),
617
ECORE_GETOPT_VALUE_NONE /* sentinel */
622
args = ecore_getopt_parse(&options, values, 0, NULL);
625
fputs("ERROR: Could not parse command line options.\n", stderr);
629
if (quit_option) goto end;
631
args = ecore_getopt_parse_positional(&options, values, 0, NULL, args);
634
fputs("ERROR: Could not parse positional arguments.\n", stderr);
640
fputs("ERROR: missing protocol.\n", stderr);
644
if (strcmp(protocol, "tcp") == 0) cls = EFL_NET_SERVER_TCP_CLASS;
645
else if (strcmp(protocol, "udp") == 0) cls = EFL_NET_SERVER_UDP_CLASS;
646
else if (strcmp(protocol, "ssl") == 0) cls = EFL_NET_SERVER_SSL_CLASS;
647
#ifdef EFL_NET_SERVER_WINDOWS_CLASS
648
else if (strcmp(protocol, "windows") == 0) cls = EFL_NET_SERVER_WINDOWS_CLASS;
650
#ifdef EFL_NET_SERVER_UNIX_CLASS
651
else if (strcmp(protocol, "unix") == 0) cls = EFL_NET_SERVER_UNIX_CLASS;
655
fprintf(stderr, "ERROR: unsupported protocol: %s\n", protocol);
659
server = efl_add(cls, ev->object, /* it's mandatory to use a main loop provider as the server parent */
660
efl_net_server_clients_limit_set(efl_added,
662
clients_reject_excess), /* optional */
663
efl_event_callback_array_add(efl_added, server_cbs(), NULL)); /* mandatory to have "client,add" in order to be useful */
666
fprintf(stderr, "ERROR: could not create class %p (%s)\n",
667
cls, efl_class_name_get(cls));
671
if (cls == EFL_NET_SERVER_TCP_CLASS)
673
efl_net_server_ip_ipv6_only_set(server, ipv6_only);
674
efl_net_server_fd_reuse_address_set(server, EINA_TRUE); /* optional, but nice for testing */
675
efl_net_server_fd_reuse_port_set(server, EINA_TRUE); /* optional, but nice for testing... not secure unless you know what you're doing */
677
if (socket_activated) efl_net_server_fd_socket_activate(server, address);
679
else if (cls == EFL_NET_SERVER_UDP_CLASS)
681
const Eina_List *lst;
683
efl_net_server_ip_ipv6_only_set(server, ipv6_only);
684
efl_net_server_udp_dont_route_set(server, udp_dont_route);
686
efl_net_server_udp_multicast_time_to_live_set(server, udp_mcast_ttl);
687
efl_net_server_udp_multicast_loopback_set(server, udp_mcast_loopback);
689
EINA_LIST_FOREACH(udp_mcast_groups, lst, str)
690
efl_net_server_udp_multicast_join(server, str);
693
efl_net_server_fd_reuse_address_set(server, EINA_TRUE); /* optional, but nice for testing */
694
efl_net_server_fd_reuse_port_set(server, EINA_TRUE); /* optional, but nice for testing... not secure unless you know what you're doing */
695
if (socket_activated) efl_net_server_fd_socket_activate(server, address);
697
else if (cls == EFL_NET_SERVER_SSL_CLASS)
700
Efl_Net_Ssl_Cipher cipher = EFL_NET_SSL_CIPHER_AUTO;
703
if (strcmp(cipher_choice, "auto") == 0)
704
cipher = EFL_NET_SSL_CIPHER_AUTO;
705
else if (strcmp(cipher_choice, "tlsv1") == 0)
706
cipher = EFL_NET_SSL_CIPHER_TLSV1;
707
else if (strcmp(cipher_choice, "tlsv1.1") == 0)
708
cipher = EFL_NET_SSL_CIPHER_TLSV1_1;
709
else if (strcmp(cipher_choice, "tlsv1.2") == 0)
710
cipher = EFL_NET_SSL_CIPHER_TLSV1_2;
713
ssl_ctx = efl_add_ref(EFL_NET_SSL_CONTEXT_CLASS, NULL,
714
efl_net_ssl_context_certificates_set(efl_added, eina_list_iterator_new(certificates)),
715
efl_net_ssl_context_private_keys_set(efl_added, eina_list_iterator_new(private_keys)),
716
efl_net_ssl_context_certificate_revocation_lists_set(efl_added, eina_list_iterator_new(crls)),
717
efl_net_ssl_context_certificate_authorities_set(efl_added, eina_list_iterator_new(cas)),
718
efl_net_ssl_context_setup(efl_added, cipher, EINA_FALSE /* a server! */));
720
efl_net_server_ssl_context_set(server, ssl_ctx);
722
efl_net_server_fd_reuse_address_set(server, EINA_TRUE); /* optional, but nice for testing */
723
efl_net_server_fd_reuse_port_set(server, EINA_TRUE); /* optional, but nice for testing... not secure unless you know what you're doing */
724
if (socket_activated) efl_net_server_fd_socket_activate(server, address);
726
#ifdef EFL_NET_SERVER_UNIX_CLASS
727
else if (cls == EFL_NET_SERVER_UNIX_CLASS)
729
efl_net_server_unix_unlink_before_bind_set(server, EINA_TRUE); /* makes testing easier */
730
if (socket_activated) efl_net_server_fd_socket_activate(server, address);
734
/* an explicit call to efl_net_server_serve() after the object is
735
* constructed allows for more complex setup, such as interacting
736
* with the object to add more properties that couldn't be done
739
if (!efl_net_server_serving_get(server))
741
if (socket_activated)
742
fprintf(stderr, "WARNING: --socket-activated, but not able to use $LISTEN_FDS descriptors. Try to start the server...\n");
744
err = efl_net_server_serve(server, address);
747
fprintf(stderr, "ERROR: could not serve(%s): %s\n",
748
address, eina_error_msg_get(err));
760
EINA_LIST_FREE(udp_mcast_groups, str)
763
efl_loop_quit(efl_loop_get(ev->object), eina_value_int_init(EXIT_FAILURE));