CSL  5.2
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 {
64  char *path;
66  void *next;
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 
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 
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 
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 
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 */
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 
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 
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 
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 
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 
1299 {
1300  if (!s) {
1301  return 0;
1302  }
1303 
1304  return s->port;
1305 }
1306 
1308 {
1309  if (!s) {
1310  return -1;
1311  }
1312 
1313  return s->protocol;
1314 }
1315 
1316 
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 
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) ||
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: */