CSL 5.2

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

server.c
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2004 Steve Harris
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as
6 * published by the Free Software Foundation; either version 2.1 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
13 *
14 * $Id$
15 */
16
17 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif
20
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <float.h>
26 #include <sys/types.h>
27
28 #ifdef _MSC_VER
29 #define _WINSOCKAPI_
30 #define snprintf _snprintf
31 #else
32 #include <unistd.h>
33 #endif
34
35 #ifdef WIN32
36 #include <winsock2.h>
37 #include <ws2tcpip.h>
38 #define EADDRINUSE WSAEADDRINUSE
39 #else
40 #include <netdb.h>
41 #include <sys/socket.h>
42 #ifdef HAVE_POLL
43 #include <sys/poll.h>
44 #endif
45 #include <sys/un.h>
46 #include <arpa/inet.h>
47 #endif
48
49 #ifdef WIN32
50 #define geterror() WSAGetLastError()
51 #else
52 #define geterror() errno
53 #endif
54
55 #include "lo_types_internal.h"
56 #include "lo_internal.h"
57 #include "lo/lo.h"
58 #include "lo/lo_throw.h"
59
60 #define LO_HOST_SIZE 1024
61
62 typedef struct {
63 lo_timetag ts;
64 char *path;
65 lo_message msg;
66 void *next;
67 } queued_msg_list;
68
69 struct lo_cs lo_client_sockets = {-1, -1};
70
71 static int lo_can_coerce_spec(const char *a, const char *b);
72 static int lo_can_coerce(char a, char b);
73 static void dispatch_method(lo_server s, const char *path,
74 lo_message msg);
75 static int dispatch_queued(lo_server s);
76 static void queue_data(lo_server s, lo_timetag ts, const char *path,
77 lo_message msg);
78 static lo_server lo_server_new_with_proto_internal(const char *group,
79 const char *port, int proto,
80 lo_err_handler err_h);
81 static int lo_server_add_socket(lo_server s, int socket);
82 static void lo_server_del_socket(lo_server s, int index, int socket);
83 static int lo_server_join_multicast_group(lo_server s, const char *group);
84
85 #ifdef WIN32
86 #ifndef gai_strerror
87 // Copied from the Win32 SDK
88
89 // WARNING: The gai_strerror inline functions below use static buffers,
90 // and hence are not thread-safe. We'll use buffers long enough to hold
91 // 1k characters. Any system error messages longer than this will be
92 // returned as empty strings. However 1k should work for the error codes
93 // used by getaddrinfo().
94 #define GAI_STRERROR_BUFFER_SIZE 1024
95
96 char *WSAAPI gai_strerrorA(int ecode)
97 {
98 DWORD dwMsgLen;
99 static char buff[GAI_STRERROR_BUFFER_SIZE + 1];
100
101 dwMsgLen = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
102 |FORMAT_MESSAGE_IGNORE_INSERTS
103 |FORMAT_MESSAGE_MAX_WIDTH_MASK,
104 NULL,
105 ecode,
106 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
107 (LPSTR)buff,
108 GAI_STRERROR_BUFFER_SIZE,
109 NULL);
110 return buff;
111 }
112 #endif
113
114 static int stateWSock = -1;
115
116 int initWSock()
117 {
118 WORD reqversion;
119 WSADATA wsaData;
120 if(stateWSock >= 0) return stateWSock;
121 /* TODO - which version of Winsock do we actually need? */
122
123 reqversion = MAKEWORD( 2, 2 );
124 if(WSAStartup(reqversion,&wsaData) != 0) {
125 /* Couldn't initialize Winsock */
126 stateWSock = 0;
127 }
128 else if ( LOBYTE( wsaData.wVersion ) != LOBYTE(reqversion) ||
129 HIBYTE( wsaData.wVersion ) != HIBYTE(reqversion) ) {
130 /* wrong version */
131 WSACleanup();
132 stateWSock = 0;
133 }
134 else
135 stateWSock = 1;
136
137 return stateWSock;
138 }
139 #endif
140
141 lo_server lo_server_new(const char *port, lo_err_handler err_h)
142 {
143 return lo_server_new_with_proto(port, LO_DEFAULT, err_h);
144 }
145
146 lo_server lo_server_new_multicast(const char *group, const char *port,
147 lo_err_handler err_h)
148 {
149 return lo_server_new_with_proto_internal(group, port, LO_UDP, err_h);
150 }
151
152 lo_server lo_server_new_with_proto(const char *port, int proto,
153 lo_err_handler err_h)
154 {
155 return lo_server_new_with_proto_internal(NULL, port, proto, err_h);
156 }
157
158 lo_server lo_server_new_with_proto_internal(const char *group,
159 const char *port, int proto,
160 lo_err_handler err_h)
161 {
162 lo_server s;
163 struct addrinfo *ai = NULL, *it, *used;
164 struct addrinfo hints;
165 int ret = -1;
166 int tries = 0;
167 char pnum[16];
168 const char *service;
169 char hostname[LO_HOST_SIZE];
170
171 // Set real protocol, if Default is requested
172 if (proto==LO_DEFAULT) {
173 #ifndef WIN32
174 if (port && *port == '/') proto = LO_UNIX;
175 else
176 #endif
177 proto = LO_UDP;
178 }
179
180
181 #ifdef WIN32
182 if(!initWSock()) return NULL;
183 #endif
184
185 s = calloc(1, sizeof(struct _lo_server));
186 if (!s) return 0;
187
188 s->err_h = err_h;
189 s->first = NULL;
190 s->ai = NULL;
191 s->hostname = NULL;
192 s->protocol = proto;
193 s->port = 0;
194 s->path = NULL;
195 s->queued = NULL;
196 s->sockets_len = 1;
197 s->sockets_alloc = 2;
198 s->sockets = calloc(2, sizeof(*(s->sockets)));
199
200 if (!s->sockets) {
201 free(s);
202 return 0;
203 }
204
205 s->sockets[0].fd = -1;
206
207 memset(&hints, 0, sizeof(hints));
208
209 if (proto == LO_UDP) {
210 hints.ai_socktype = SOCK_DGRAM;
211 } else if (proto == LO_TCP) {
212 hints.ai_socktype = SOCK_STREAM;
213 }
214 #ifndef WIN32
215 else if (proto == LO_UNIX) {
216
217 struct sockaddr_un sa;
218
219 s->sockets[0].fd = socket(PF_UNIX, SOCK_DGRAM, 0);
220 if (s->sockets[0].fd == -1) {
221 int err = geterror();
222 used = NULL;
223 lo_throw(s, err, strerror(err), "socket()");
224 lo_server_free(s);
225
226 return NULL;
227 }
228
229 sa.sun_family = AF_UNIX;
230 strncpy(sa.sun_path, port, sizeof(sa.sun_path)-1);
231
232 if ((ret = bind(s->sockets[0].fd,
233 (struct sockaddr *)&sa, sizeof(sa))) < 0) {
234 int err = geterror();
235 lo_throw(s, err, strerror(err), "bind()");
236
237 lo_server_free(s);
238 return NULL;
239 }
240
241 s->path = strdup(port);
242
243 return s;
244 }
245 #endif
246 else {
247 lo_throw(s, LO_UNKNOWNPROTO, "Unknown protocol", NULL);
248 lo_server_free(s);
249
250 return NULL;
251 }
252
253 #ifdef ENABLE_IPV6
254 hints.ai_family = PF_UNSPEC;
255 #else
256 hints.ai_family = PF_INET;
257 #endif
258 hints.ai_flags = AI_PASSIVE;
259
260 if (!port) {
261 service = pnum;
262 } else {
263 service = port;
264 }
265 do {
266 if (!port) {
267 /* not a good way to get random numbers, but its not critical */
268 snprintf(pnum, 15, "%ld", 10000 + ((unsigned int)rand() +
269 time(NULL)) % 10000);
270 }
271
272 if ((ret = getaddrinfo(NULL, service, &hints, &ai))) {
273 lo_throw(s, ret, gai_strerror(ret), NULL);
274 freeaddrinfo(ai);
275
276 return NULL;
277 }
278
279 used = NULL;
280 s->ai = ai;
281 s->sockets[0].fd = -1;
282 s->port = 0;
283
284 for (it = ai; it && s->sockets[0].fd == -1; it = it->ai_next) {
285 used = it;
286 s->sockets[0].fd = socket(it->ai_family, hints.ai_socktype, 0);
287 }
288 if (s->sockets[0].fd == -1) {
289 int err = geterror();
290 used = NULL;
291 lo_throw(s, err, strerror(err), "socket()");
292
293 lo_server_free(s);
294 return NULL;
295 }
296
297 /* Join multicast group if specified. */
298 /* This must be done before bind() on POSIX, but after bind() Windows. */
299 #ifndef WIN32
300 if (group != NULL)
301 if (lo_server_join_multicast_group(s, group))
302 return NULL;
303 #endif
304
305 if ((ret = bind(s->sockets[0].fd, used->ai_addr, used->ai_addrlen)) < 0) {
306 int err = geterror();
307 if (err == EINVAL || err == EADDRINUSE) {
308 used = NULL;
309
310 continue;
311 }
312 lo_throw(s, err, strerror(err), "bind()");
313
314 lo_server_free(s);
315
316 return NULL;
317 }
318 } while (!used && tries++ < 16);
319
320 /* Join multicast group if specified (see above). */
321 #ifdef WIN32
322 if (group != NULL)
323 if (lo_server_join_multicast_group(s, group))
324 return NULL;
325 #endif
326
327 if (proto == LO_TCP) {
328 listen(s->sockets[0].fd, 8);
329 }
330
331 if (!used) {
332 lo_throw(s, LO_NOPORT, "cannot find free port", NULL);
333
334 lo_server_free(s);
335 return NULL;
336 }
337
338 if (proto == LO_UDP) {
339 lo_client_sockets.udp = s->sockets[0].fd;
340 } else if (proto == LO_TCP) {
341 lo_client_sockets.tcp = s->sockets[0].fd;
342 }
343
344 /* Set hostname to empty string */
345 hostname[0] = '\0';
346
347 #ifdef ENABLE_IPV6
348 /* Try it the IPV6 friendly way first */
349 for (it = ai; it; it = it->ai_next) {
350 if (getnameinfo(it->ai_addr, it->ai_addrlen, hostname,
351 sizeof(hostname), NULL, 0, NI_NAMEREQD) == 0) {
352 break;
353 }
354 }
355
356 /* check to make sure getnameinfo() didn't just set the hostname to "::".
357 Needed on Darwin. */
358 if (hostname[0] == ':') {
359 hostname[0] = '\0';
360 }
361 #endif
362
363
364 /* Fallback to the oldschool (i.e. more reliable) way */
365 if (!hostname[0]) {
366 struct hostent *he;
367
368 gethostname(hostname, sizeof(hostname));
369 he = gethostbyname(hostname);
370 if (he) {
371 strncpy(hostname, he->h_name, sizeof(hostname));
372 }
373 }
374
375 /* soethings gone really wrong, just hope its local only */
376 if (!hostname[0]) {
377 strcpy(hostname, "localhost");
378 }
379 s->hostname = strdup(hostname);
380
381 if (used->ai_family == PF_INET6) {
382 struct sockaddr_in6 *addr = (struct sockaddr_in6 *)used->ai_addr;
383
384 s->port = htons(addr->sin6_port);
385 } else if (used->ai_family == PF_INET) {
386 struct sockaddr_in *addr = (struct sockaddr_in *)used->ai_addr;
387
388 s->port = htons(addr->sin_port);
389 } else {
390 lo_throw(s, LO_UNKNOWNPROTO, "unknown protocol family", NULL);
391 s->port = atoi(port);
392 }
393
394 return s;
395 }
396
397 int lo_server_join_multicast_group(lo_server s, const char *group)
398 {
399 struct ip_mreq mreq;
400 unsigned int yes = 1;
401 memset(&mreq, 0, sizeof(mreq));
402 #ifdef HAVE_INET_ATON
403 if (inet_aton(group, &mreq.imr_multiaddr)==0) {
404 int err = geterror();
405 lo_throw(s, err, strerror(err), "inet_aton()");
406 lo_server_free(s);
407 return err;
408 }
409 #else
410 mreq.imr_multiaddr.s_addr = inet_addr(group);
411 if (mreq.imr_multiaddr.s_addr == INADDR_ANY
412 || mreq.imr_multiaddr.s_addr == INADDR_NONE)
413 {
414 int err = geterror();
415 lo_throw(s, err, strerror(err), "inet_addr()");
416 lo_server_free(s);
417 return err;
418 }
419 #endif
420 mreq.imr_interface.s_addr=htonl(INADDR_ANY);
421
422 if (setsockopt(s->sockets[0].fd,IPPROTO_IP,IP_ADD_MEMBERSHIP,
423 &mreq,sizeof(mreq)) < 0)
424 {
425 int err = geterror();
426 lo_throw(s, err, strerror(err), "setsockopt(IP_ADD_MEMBERSHIP)");
427 lo_server_free(s);
428 return err;
429 }
430
431 if (setsockopt(s->sockets[0].fd,SOL_SOCKET,SO_REUSEADDR,
432 &yes,sizeof(yes)) < 0)
433 {
434 int err = geterror();
435 lo_throw(s, err, strerror(err), "setsockopt(SO_REUSEADDR)");
436 lo_server_free(s);
437 return err;
438 }
439
440 #ifdef SO_REUSEPORT
441 if (setsockopt(s->sockets[0].fd,SOL_SOCKET,SO_REUSEPORT,
442 &yes,sizeof(yes)) < 0)
443 {
444 int err = geterror();
445 lo_throw(s, err, strerror(err), "setsockopt(SO_REUSEPORT)");
446 lo_server_free(s);
447 return err;
448 }
449 #endif
450
451 return 0;
452 }
453
454 void lo_server_free(lo_server s)
455 {
456 if (s) {
457 lo_method it;
458 lo_method next;
459 int i;
460
461 for (i=s->sockets_len-1; i >= 0; i--)
462 {
463 if (s->sockets[i].fd != -1) {
464 if (s->protocol == LO_UDP
465 && s->sockets[i].fd == lo_client_sockets.udp)
466 {
467 lo_client_sockets.udp = -1;
468 }
469 else if (s->protocol == LO_TCP
470 && s->sockets[0].fd == lo_client_sockets.tcp)
471 {
472 lo_client_sockets.tcp = -1;
473 }
474
475 close(s->sockets[i].fd);
476 s->sockets[i].fd = -1;
477 }
478 }
479 if (s->ai) {
480 freeaddrinfo(s->ai);
481 s->ai=NULL;
482 }
483 if (s->hostname) {
484 free(s->hostname);
485 s->hostname = NULL;
486 }
487 if (s->path) {
488 if (s->protocol == LO_UNIX) unlink( s->path );
489 free(s->path);
490 s->path = NULL;
491 }
492 for (it = s->first; it; it = next) {
493 next = it->next;
494 free((char *)it->path);
495 free((char *)it->typespec);
496 free(it);
497 }
498 free(s->sockets);
499 free(s);
500 }
501 }
502
503 void *lo_server_recv_raw(lo_server s, size_t *size)
504 {
505 char buffer[LO_MAX_MSG_SIZE];
506 int ret;
507 void *data = NULL;
508
509 #ifdef WIN32
510 if(!initWSock()) return NULL;
511 #endif
512
513 s->addr_len = sizeof(s->addr);
514
515 ret = recvfrom(s->sockets[0].fd, buffer, LO_MAX_MSG_SIZE, 0,
516 (struct sockaddr *)&s->addr, &s->addr_len);
517 if (ret <= 0) {
518 return NULL;
519 }
520 data = malloc(ret);
521 memcpy(data, buffer, ret);
522
523 if (size) *size = ret;
524
525 return data;
526 }
527
528 void *lo_server_recv_raw_stream(lo_server s, size_t *size)
529 {
530 struct sockaddr_storage addr;
531 socklen_t addr_len = sizeof(addr);
532 char buffer[LO_MAX_MSG_SIZE];
533 int32_t read_size;
534 int ret=0, i;
535 void *data = NULL;
536 int sock = -1;
537 int repeat = 1;
538 #ifdef HAVE_SELECT
539 #ifndef HAVE_POLL
540 fd_set ps;
541 int nfds=0;
542 #endif
543 #endif
544
545 /* check sockets in reverse order so that already-open sockets
546 * have priority. this allows checking for closed sockets even
547 * when new connections are being requested. it also allows to
548 * continue looping through the list of sockets after closing and
549 * deleting a socket, since deleting sockets doesn't affect the
550 * order of the array to the left of the index. */
551
552 #ifdef HAVE_POLL
553 for (i=0; i < s->sockets_len; i++) {
554 s->sockets[i].events = POLLIN | POLLPRI;
555 s->sockets[i].revents = 0;
556 }
557
558 poll(s->sockets, s->sockets_len, -1);
559
560 for (i=(s->sockets_len-1); i >= 0; --i) {
561 if (s->sockets[i].revents == POLLERR
562 || s->sockets[i].revents == POLLHUP)
563 {
564 if (i>0) {
565 close(s->sockets[i].fd);
566 lo_server_del_socket(s, i, s->sockets[i].fd);
567 continue;
568 }
569 else
570 return NULL;
571 }
572 if (s->sockets[i].revents) {
573 sock = s->sockets[i].fd;
574
575 #else
576 #ifdef HAVE_SELECT
577 if(!initWSock()) return NULL;
578
579 FD_ZERO(&ps);
580 for (i=(s->sockets_len-1); i >= 0; --i) {
581 FD_SET(s->sockets[i].fd, &ps);
582 if (s->sockets[i].fd > nfds)
583 nfds = s->sockets[i].fd;
584 }
585
586 if (select(nfds+1,&ps,NULL,NULL,NULL) == SOCKET_ERROR)
587 return NULL;
588
589 for (i=0; i < s->sockets_len; i++) {
590 if (FD_ISSET(s->sockets[i].fd, &ps)) {
591 sock = s->sockets[i].fd;
592
593 #endif
594 #endif
595
596 if (sock == -1 || !repeat)
597 return NULL;
598
599 /* zeroeth socket is listening for new connections */
600 if (sock == s->sockets[0].fd) {
601 sock = accept(sock, (struct sockaddr *)&addr, &addr_len);
602 i = lo_server_add_socket(s, sock);
603
604 /* only repeat this loop for sockets other than the listening
605 * socket, (otherwise i will be wrong next time around) */
606 repeat = 0;
607 }
608
609 if (i<0) {
610 close(sock);
611 return NULL;
612 }
613
614 ret = recv(sock, &read_size, sizeof(read_size), 0);
615 read_size = ntohl(read_size);
616 if (read_size > LO_MAX_MSG_SIZE || ret <= 0) {
617 close(sock);
618 lo_server_del_socket(s, i, sock);
619 if (ret > 0)
620 lo_throw(s, LO_TOOBIG, "Message too large", "recv()");
621 continue;
622 }
623 ret = recv(sock, buffer, read_size, 0);
624 if (ret <= 0) {
625 close(sock);
626 lo_server_del_socket(s, i, sock);
627 continue;
628 }
629
630 /* end of loop over sockets: successfully read data */
631 break;
632 }
633 }
634
635 data = malloc(ret);
636 memcpy(data, buffer, ret);
637
638 if (size) *size = ret;
639
640 return data;
641 }
642
643 int lo_server_wait(lo_server s, int timeout)
644 {
645 int sched_timeout = lo_server_next_event_delay(s) * 1000;
646 int i;
647 #ifdef HAVE_SELECT
648 #ifndef HAVE_POLL
649 fd_set ps;
650 struct timeval stimeout;
651 #endif
652 #endif
653
654 #ifdef HAVE_POLL
655 for (i=0; i < s->sockets_len; i++) {
656 s->sockets[i].events = POLLIN | POLLPRI | POLLERR | POLLHUP;
657 s->sockets[i].revents = 0;
658 }
659
660 poll(s->sockets, s->sockets_len,
661 timeout > sched_timeout ? sched_timeout : timeout);
662
663 if (lo_server_next_event_delay(s) < 0.01)
664 return 1;
665
666 for (i=0; i < s->sockets_len; i++) {
667 if (s->sockets[i].revents == POLLERR
668 || s->sockets[i].revents == POLLHUP)
669 return 0;
670 if (s->sockets[i].revents)
671 return 1;
672 }
673 #else
674 #ifdef HAVE_SELECT
675 int res,to,nfds=0;
676
677 if(!initWSock()) return 0;
678
679 to = timeout > sched_timeout ? sched_timeout : timeout;
680 stimeout.tv_sec = to/1000;
681 stimeout.tv_usec = (to%1000)*1000;
682
683 FD_ZERO(&ps);
684 for (i=0; i < s->sockets_len; i++) {
685 FD_SET(s->sockets[i].fd,&ps);
686 if (s->sockets[i].fd > nfds)
687 nfds = s->sockets[i].fd;
688 }
689
690 res = select(nfds+1,&ps,NULL,NULL,&stimeout);
691
692 if(res == SOCKET_ERROR)
693 return 0;
694
695 if (res || lo_server_next_event_delay(s) < 0.01)
696 return 1;
697 #endif
698 #endif
699
700 return 0;
701 }
702
703 int lo_server_recv_noblock(lo_server s, int timeout)
704 {
705 int result = lo_server_wait(s,timeout);
706 if (result>0) {
707 return lo_server_recv(s);
708 } else {
709 return 0;
710 }
711 }
712
713 int lo_server_recv(lo_server s)
714 {
715 void *data;
716 size_t size;
717 double sched_time = lo_server_next_event_delay(s);
718 int i;
719 #ifdef HAVE_SELECT
720 #ifndef HAVE_POLL
721 fd_set ps;
722 struct timeval stimeout;
723 int res,nfds=0;
724 #endif
725 #endif
726
727 again:
728 if (sched_time > 0.01) {
729 if (sched_time > 10.0) {
730 sched_time = 10.0;
731 }
732
733 #ifdef HAVE_POLL
734 for (i=0; i < s->sockets_len; i++) {
735 s->sockets[i].events = POLLIN | POLLPRI | POLLERR | POLLHUP;
736 s->sockets[i].revents = 0;
737 }
738
739 poll(s->sockets, s->sockets_len, (int)(sched_time * 1000.0));
740
741 for (i=0; i < s->sockets_len; i++)
742 {
743 if ( s->sockets[i].revents == POLLERR
744 || s->sockets[i].revents == POLLHUP)
745 return 0;
746
747 if (s->sockets[i].revents)
748 break;
749 }
750
751 if (i >= s->sockets_len)
752 {
753 sched_time = lo_server_next_event_delay(s);
754
755 if (sched_time > 0.01)
756 goto again;
757
758 return dispatch_queued(s);
759 }
760 #else
761 #ifdef HAVE_SELECT
762 if(!initWSock()) return 0;
763
764 FD_ZERO(&ps);
765 for (i=0; i < s->sockets_len; i++) {
766 FD_SET(s->sockets[i].fd,&ps);
767 if (s->sockets[i].fd > nfds)
768 nfds = s->sockets[i].fd;
769 }
770
771 stimeout.tv_sec = sched_time;
772 stimeout.tv_usec = (sched_time-stimeout.tv_sec)*1.e6;
773 res = select(nfds+1,&ps,NULL,NULL,&stimeout);
774 if(res == SOCKET_ERROR) {
775 return 0;
776 }
777
778 if(!res) {
779 sched_time = lo_server_next_event_delay(s);
780
781 if (sched_time > 0.01)
782 goto again;
783
784 return dispatch_queued(s);
785 }
786 #endif
787 #endif
788 } else {
789 return dispatch_queued(s);
790 }
791 if (s->protocol == LO_TCP) {
792 data = lo_server_recv_raw_stream(s, &size);
793 } else {
794 data = lo_server_recv_raw(s, &size);
795 }
796
797 if (!data) {
798 return 0;
799 }
800 if (lo_server_dispatch_data(s, data, size) < 0) {
801 free(data);
802 return -1;
803 }
804 free(data);
805 return size;
806 }
807
808 /** \internal \brief Add a socket to this server's list of sockets.
809 * \param s The lo_server
810 * \param socket The socket number to add.
811 * \return The index number of the added socket, or -1 on failure.
812 */
813 int lo_server_add_socket(lo_server s, int socket)
814 {
815 if ((s->sockets_len+1) > s->sockets_alloc) {
816 void *sp = realloc(s->sockets,
817 sizeof(*(s->sockets))*(s->sockets_alloc*2));
818 if (!sp)
819 return -1;
820 s->sockets = sp;
821 s->sockets_alloc *= 2;
822 }
823
824 s->sockets[s->sockets_len].fd = socket;
825 s->sockets_len ++;
826
827 return s->sockets_len-1;
828 }
829
830 /** \internal \brief Delete a socket from this server's list of sockets.
831 * \param s The lo_server
832 * \param index The index of the socket to delete, -1 if socket is provided.
833 * \param socket The socket number to delete, -1 if index is provided.
834 * \return The index number of the added socket.
835 */
836 void lo_server_del_socket(lo_server s, int index, int socket)
837 {
838 int i;
839
840 if (index < 0 && socket != -1) {
841 for (index=0; index < s->sockets_len; index++)
842 if (s->sockets[index].fd == socket)
843 break;
844 }
845
846 if (index < 0 || index >= s->sockets_len)
847 return;
848
849 for (i=index+1; i < s->sockets_len; i++)
850 s->sockets[i-1] = s->sockets[i];
851 s->sockets_len --;
852 }
853
854 int lo_server_dispatch_data(lo_server s, void *data, size_t size)
855 {
856 int result = 0;
857 char *path = data;
858 ssize_t len = lo_validate_string(data, size);
859 if (len < 0) {
860 lo_throw(s, -len, "Invalid message path", NULL);
861 return len;
862 }
863
864 if (!strcmp(data, "#bundle")) {
865 char *pos;
866 int remain;
867 uint32_t elem_len;
868 lo_timetag ts, now;
869
870 ssize_t bundle_result = lo_validate_bundle(data, size);
871 if (bundle_result < 0) {
872 lo_throw(s, -bundle_result, "Invalid bundle", NULL);
873 return bundle_result;
874 }
875 pos = (char *)data + len;
876 remain = size - len;
877
878 lo_timetag_now(&now);
879 ts.sec = lo_otoh32(*((uint32_t *)pos));
880 pos += 4;
881 ts.frac = lo_otoh32(*((uint32_t *)pos));
882 pos += 4;
883 remain -= 8;
884
885 while (remain >= 4) {
886 lo_message msg;
887 elem_len = lo_otoh32(*((uint32_t *)pos));
888 pos += 4;
889 remain -= 4;
890 msg = lo_message_deserialise(pos, elem_len, &result);
891 if (!msg) {
892 lo_throw(s, result, "Invalid bundle element received", path);
893 return -result;
894 }
895
896 // set timetag from bundle
897 msg->ts = ts;
898
899 // test for immediate dispatch
900 if ((ts.sec == LO_TT_IMMEDIATE.sec
901 && ts.frac == LO_TT_IMMEDIATE.frac) ||
902 lo_timetag_diff(ts, now) <= 0.0) {
903 dispatch_method(s, pos, msg);
904 lo_message_free(msg);
905 } else {
906 queue_data(s, ts, pos, msg);
907 }
908 pos += elem_len;
909 remain -= elem_len;
910 }
911 } else {
912 lo_message msg = lo_message_deserialise(data, size, &result);
913 if (NULL == msg) {
914 lo_throw(s, result, "Invalid message received", path);
915 return -result;
916 }
917 dispatch_method(s, data, msg);
918 lo_message_free(msg);
919 }
920 return size;
921 }
922
923 /* returns the time in seconds until the next scheduled event */
924 double lo_server_next_event_delay(lo_server s)
925 {
926 if (s->queued) {
927 lo_timetag now;
928 double delay;
929
930 lo_timetag_now(&now);
931 delay = lo_timetag_diff(((queued_msg_list *)s->queued)->ts, now);
932
933 delay = delay > 100.0 ? 100.0 : delay;
934 delay = delay < 0.0 ? 0.0 : delay;
935
936 return delay;
937 }
938
939 return 100.0;
940 }
941
942 static void dispatch_method(lo_server s, const char *path,
943 lo_message msg)
944 {
945 char *types = msg->types + 1;
946 int argc = strlen(types);
947 lo_arg **argv = msg->argv;
948 lo_method it;
949 int ret = 1;
950 int err;
951 int pattern = strpbrk(path, " #*,?[]{}") != NULL;
952 lo_address src = lo_address_new(NULL, NULL);
953 char hostname[LO_HOST_SIZE];
954 char portname[32];
955 const char *pptr;
956
957 msg->source = src;
958
959 //inet_ntop(s->addr.ss_family, &s->addr.padding, hostname, sizeof(hostname));
960 if (s->protocol == LO_UDP && s->addr_len>0) {
961 err = getnameinfo((struct sockaddr *)&s->addr, sizeof(s->addr),
962 hostname, sizeof(hostname), portname, sizeof(portname),
963 NI_NUMERICHOST | NI_NUMERICSERV);
964 if (err) {
965 switch (err) {
966 case EAI_AGAIN:
967 lo_throw(s, err, "Try again", path);
968 break;
969 case EAI_BADFLAGS:
970 lo_throw(s, err, "Bad flags", path);
971 break;
972 case EAI_FAIL:
973 lo_throw(s, err, "Failed", path);
974 break;
975 case EAI_FAMILY:
976 lo_throw(s, err, "Cannot resolve address family", path);
977 break;
978 case EAI_MEMORY:
979 lo_throw(s, err, "Out of memory", path);
980 break;
981 case EAI_NONAME:
982 lo_throw(s, err, "Cannot resolve", path);
983 break;
984 #ifndef WIN32
985 case EAI_SYSTEM:
986 lo_throw(s, err, strerror(err), path);
987 break;
988 #endif
989 default:
990 lo_throw(s, err, "Unknown error", path);
991 break;
992 }
993
994 return;
995 }
996 } else {
997 hostname[0] = '\0';
998 portname[0] = '\0';
999 }
1000
1001
1002 // Store the source information in the lo_address
1003 if (src->host) free(src->host);
1004 if (src->host) free(src->port);
1005 src->host = strdup(hostname);
1006 src->port = strdup(portname);
1007 src->protocol = s->protocol;
1008
1009 for (it = s->first; it; it = it->next) {
1010 /* If paths match or handler is wildcard */
1011 if (!it->path || !strcmp(path, it->path) ||
1012 (pattern && lo_pattern_match(it->path, path))) {
1013 /* If types match or handler is wildcard */
1014 if (!it->typespec || !strcmp(types, it->typespec)) {
1015 /* Send wildcard path to generic handler, expanded path
1016 to others.
1017 */
1018 pptr = path;
1019 if (it->path) pptr = it->path;
1020 ret = it->handler(pptr, types, argv, argc, msg,
1021 it->user_data);
1022
1023 } else if (lo_can_coerce_spec(types, it->typespec)) {
1024 int i;
1025 int opsize = 0;
1026 char *ptr = msg->data;
1027 char *data_co, *data_co_ptr;
1028
1029 argv = calloc(argc, sizeof(lo_arg *));
1030 for (i=0; i<argc; i++) {
1031 opsize += lo_arg_size(it->typespec[i], ptr);
1032 ptr += lo_arg_size(types[i], ptr);
1033 }
1034
1035 data_co = malloc(opsize);
1036 data_co_ptr = data_co;
1037 ptr = msg->data;
1038 for (i=0; i<argc; i++) {
1039 argv[i] = (lo_arg *)data_co_ptr;
1040 lo_coerce(it->typespec[i], (lo_arg *)data_co_ptr,
1041 types[i], (lo_arg *)ptr);
1042 data_co_ptr += lo_arg_size(it->typespec[i], data_co_ptr);
1043 ptr += lo_arg_size(types[i], ptr);
1044 }
1045
1046 /* Send wildcard path to generic handler, expanded path
1047 to others.
1048 */
1049 pptr = path;
1050 if (it->path) pptr = it->path;
1051 ret = it->handler(pptr, it->typespec, argv, argc, msg,
1052 it->user_data);
1053 free(argv);
1054 free(data_co);
1055 argv = NULL;
1056 }
1057
1058 if (ret == 0 && !pattern) {
1059 break;
1060 }
1061 }
1062 }
1063
1064 /* If we find no matching methods, check for protocol level stuff */
1065 if (ret == 1 && s->protocol == LO_UDP) {
1066 char *pos = strrchr(path, '/');
1067
1068 /* if its a method enumeration call */
1069 if (pos && *(pos+1) == '\0') {
1070 lo_message reply = lo_message_new();
1071 int len = strlen(path);
1072 lo_strlist *sl = NULL, *slit, *slnew, *slend;
1073
1074 if (!strcmp(types, "i")) {
1075 lo_message_add_int32(reply, argv[0]->i);
1076 }
1077 lo_message_add_string(reply, path);
1078
1079 for (it = s->first; it; it = it->next) {
1080 /* If paths match */
1081 if (it->path && !strncmp(path, it->path, len)) {
1082 char *tmp;
1083 char *sec;
1084
1085 tmp = malloc(strlen(it->path + len) + 1);
1086 strcpy(tmp, it->path + len);
1087 #ifdef WIN32
1088 sec = strchr(tmp,'/');
1089 #else
1090 sec = index(tmp, '/');
1091 #endif
1092 if (sec) *sec = '\0';
1093 slend = sl;
1094 for (slit = sl; slit; slend = slit, slit = slit->next) {
1095 if (!strcmp(slit->str, tmp)) {
1096 free(tmp);
1097 tmp = NULL;
1098 break;
1099 }
1100 }
1101 if (tmp) {
1102 slnew = calloc(1, sizeof(lo_strlist));
1103 slnew->str = tmp;
1104 slnew->next = NULL;
1105 if (!slend) {
1106 sl = slnew;
1107 } else {
1108 slend->next = slnew;
1109 }
1110 }
1111 }
1112 }
1113
1114 slit = sl;
1115 while(slit) {
1116 lo_message_add_string(reply, slit->str);
1117 slnew = slit;
1118 slit = slit->next;
1119 free(slnew->str);
1120 free(slnew);
1121 }
1122 lo_send_message(src, "#reply", reply);
1123 lo_message_free(reply);
1124 }
1125 }
1126
1127 lo_address_free(src);
1128 msg->source = NULL;
1129 }
1130
1131 int lo_server_events_pending(lo_server s)
1132 {
1133 return s->queued != 0;
1134 }
1135
1136 static void queue_data(lo_server s, lo_timetag ts, const char *path,
1137 lo_message msg)
1138 {
1139 /* insert blob into future dispatch queue */
1140 queued_msg_list *it = s->queued;
1141 queued_msg_list *prev = NULL;
1142 queued_msg_list *ins = calloc(1, sizeof(queued_msg_list));
1143
1144 ins->ts = ts;
1145 ins->path = strdup(path);
1146 ins->msg = msg;
1147
1148 while (it) {
1149 if (lo_timetag_diff(it->ts, ts) > 0.0) {
1150 if (prev) {
1151 prev->next = ins;
1152 } else {
1153 s->queued = ins;
1154 ins->next = NULL;
1155 }
1156 ins->next = it;
1157
1158 return;
1159 }
1160 prev = it;
1161 it = it->next;
1162 }
1163
1164 /* fell through, so this event is last */
1165 if (prev) {
1166 prev->next = ins;
1167 } else {
1168 s->queued = ins;
1169 }
1170 ins->next = NULL;
1171 }
1172
1173 static int dispatch_queued(lo_server s)
1174 {
1175 queued_msg_list *head = s->queued;
1176 queued_msg_list *tailhead;
1177 lo_timetag disp_time;
1178
1179 if (!head) {
1180 lo_throw(s, LO_INT_ERR, "attempted to dispatch with empty queue",
1181 "timeout");
1182 return 1;
1183 }
1184
1185 disp_time = head->ts;
1186
1187 do {
1188 char *path;
1189 lo_message msg;
1190 tailhead = head->next;
1191 path = ((queued_msg_list *)s->queued)->path;
1192 msg = ((queued_msg_list *)s->queued)->msg;
1193 dispatch_method(s, path, msg);
1194 free(path);
1195 lo_message_free(msg);
1196 free((queued_msg_list *)s->queued);
1197
1198 s->queued = tailhead;
1199 head = tailhead;
1200 } while (head && lo_timetag_diff(head->ts, disp_time) < FLT_EPSILON);
1201
1202 return 0;
1203 }
1204
1205 lo_method lo_server_add_method(lo_server s, const char *path,
1206 const char *typespec, lo_method_handler h,
1207 void *user_data)
1208 {
1209 lo_method m = calloc(1, sizeof(struct _lo_method));
1210 lo_method it;
1211
1212 if (path && strpbrk(path, " #*,?[]{}")) {
1213 return NULL;
1214 }
1215
1216 if (path) {
1217 m->path = strdup(path);
1218 } else {
1219 m->path = NULL;
1220 }
1221
1222 if (typespec) {
1223 m->typespec = strdup(typespec);
1224 } else {
1225 m->typespec = NULL;
1226 }
1227
1228 m->handler = h;
1229 m->user_data = user_data;
1230 m->next = NULL;
1231
1232 /* append the new method to the list */
1233 if (!s->first) {
1234 s->first = m;
1235 } else {
1236 /* get to the last member of the list */
1237 for (it=s->first; it->next; it=it->next);
1238 it->next = m;
1239 }
1240
1241 return m;
1242 }
1243
1244 void lo_server_del_method(lo_server s, const char *path,
1245 const char *typespec)
1246 {
1247 lo_method it, prev, next;
1248 int pattern = 0;
1249
1250 if (!s->first) return;
1251 if (path) pattern = strpbrk(path, " #*,?[]{}") != NULL;
1252
1253 it = s->first;
1254 prev = it;
1255 while (it) {
1256 /* incase we free it */
1257 next = it->next;
1258
1259 /* If paths match or handler is wildcard */
1260 if ((it->path == path) ||
1261 (path && it->path && !strcmp(path, it->path)) ||
1262 (pattern && it->path && lo_pattern_match(it->path, path))) {
1263 /* If types match or handler is wildcard */
1264 if ((it->typespec == typespec) ||
1265 (typespec && it->typespec && !strcmp(typespec, it->typespec))
1266 ) {
1267 /* Take care when removing the head. */
1268 if (it == s->first) {
1269 s->first = it->next;
1270 } else {
1271 prev->next = it->next;
1272 }
1273 next = it->next;
1274 free((void *)it->path);
1275 free((void *)it->typespec);
1276 free(it);
1277 it = prev;
1278 }
1279 }
1280 prev = it;
1281 if (it) it = next;
1282 }
1283 }
1284
1285 int lo_server_get_socket_fd(lo_server s)
1286 {
1287 if (s->protocol != LO_UDP &&
1288 s->protocol != LO_TCP
1289 #ifndef WIN32
1290 && s->protocol != LO_UNIX
1291 #endif
1292 ) {
1293 return -1; /* assume it is not supported */
1294 }
1295 return s->sockets[0].fd;
1296 }
1297
1298 int lo_server_get_port(lo_server s)
1299 {
1300 if (!s) {
1301 return 0;
1302 }
1303
1304 return s->port;
1305 }
1306
1307 int lo_server_get_protocol(lo_server s)
1308 {
1309 if (!s) {
1310 return -1;
1311 }
1312
1313 return s->protocol;
1314 }
1315
1316
1317 char *lo_server_get_url(lo_server s)
1318 {
1319 int ret=0;
1320 char *buf;
1321
1322 if (!s) {
1323 return NULL;
1324 }
1325
1326 if (s->protocol == LO_UDP || s->protocol == LO_TCP) {
1327 char *proto = s->protocol == LO_UDP ? "udp" : "tcp";
1328
1329 #ifndef _MSC_VER
1330 ret = snprintf(NULL, 0, "osc.%s://%s:%d/", proto, s->hostname, s->port);
1331 #endif
1332 if (ret <= 0) {
1333 /* this libc is not C99 compliant, guess a size */
1334 ret = 1023;
1335 }
1336 buf = malloc((ret + 2) * sizeof(char));
1337 snprintf(buf, ret+1, "osc.%s://%s:%d/", proto, s->hostname, s->port);
1338
1339 return buf;
1340 }
1341 #ifndef WIN32
1342 else if (s->protocol == LO_UNIX) {
1343 ret = snprintf(NULL, 0, "osc.unix:///%s", s->path);
1344 if (ret <= 0) {
1345 /* this libc is not C99 compliant, guess a size */
1346 ret = 1023;
1347 }
1348 buf = malloc((ret + 2) * sizeof(char));
1349 snprintf(buf, ret+1, "osc.unix:///%s", s->path);
1350
1351 return buf;
1352 }
1353 #endif
1354 return NULL;
1355 }
1356
1357 void lo_server_pp(lo_server s)
1358 {
1359 lo_method it;
1360
1361 printf("socket: %d\n\n", s->sockets[0].fd);
1362 printf("Methods\n");
1363 for (it = s->first; it; it = it->next) {
1364 printf("\n");
1365 lo_method_pp_prefix(it, " ");
1366 }
1367 }
1368
1369 static int lo_can_coerce_spec(const char *a, const char *b)
1370 {
1371 unsigned int i;
1372
1373 if (strlen(a) != strlen(b)) {
1374 return 0;
1375 }
1376
1377 for (i=0; a[i]; i++) {
1378 if (!lo_can_coerce(a[i], b[i])) {
1379 return 0;
1380 }
1381 }
1382
1383 return 1;
1384 }
1385
1386 static int lo_can_coerce(char a, char b)
1387 {
1388 return ((a == b) ||
1389 (lo_is_numerical_type(a) && lo_is_numerical_type(b)) ||
1390 (lo_is_string_type(a) && lo_is_string_type (b)));
1391 }
1392
1393 void lo_throw(lo_server s, int errnum, const char *message, const char *path)
1394 {
1395 if (s->err_h) {
1396 (*s->err_h)(errnum, message, path);
1397 }
1398 }
1399
1400 /* vi:set ts=8 sts=4 sw=4: */