X-Git-Url: https://git.saurik.com/apple/syslog.git/blobdiff_plain/02b408bf291fdcb65e851a9c1a558913dcc66184..HEAD:/syslogd.tproj/udp_in.c diff --git a/syslogd.tproj/udp_in.c b/syslogd.tproj/udp_in.c index 666ab3d..4874748 100644 --- a/syslogd.tproj/udp_in.c +++ b/syslogd.tproj/udp_in.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2004-2011 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -21,6 +21,12 @@ * @APPLE_LICENSE_HEADER_END@ */ +#include + +#if TARGET_OS_SIMULATOR +struct _not_empty; +#else + #include #include #include @@ -39,53 +45,39 @@ #define forever for(;;) +#define UDP_SOCKET_NAME "NetworkListener" #define MY_ID "udp_in" #define MAXLINE 4096 #define MAXSOCK 16 static int nsock = 0; static int ufd[MAXSOCK]; +static dispatch_source_t ufd_src[MAXSOCK]; static char uline[MAXLINE + 1]; +static dispatch_source_t in_src[MAXSOCK]; +static dispatch_queue_t in_queue; + #define FMT_LEGACY 0 #define FMT_ASL 1 -asl_msg_t * -udp_convert(int fmt, char *s, int len, char *from) -{ - char *out; - asl_msg_t *m; - - out = NULL; - m = NULL; - - if (fmt == FMT_ASL) - { - m = asl_msg_from_string(s); - if (from != NULL) asl_set(m, ASL_KEY_HOST, from); - return m; - } - - return asl_syslog_input_convert(uline, len, from, 0); -} - -asl_msg_t * +void udp_in_acceptmsg(int fd) { - int format, status, x, fromlen; - size_t off; + socklen_t fromlen; ssize_t len; struct sockaddr_storage from; char fromstr[64], *r, *p; struct sockaddr_in *s4; struct sockaddr_in6 *s6; + asl_msg_t *m; fromlen = sizeof(struct sockaddr_storage); memset(&from, 0, fromlen); len = recvfrom(fd, uline, MAXLINE, 0, (struct sockaddr *)&from, &fromlen); - if (len <= 0) return NULL; + if (len <= 0) return; fromstr[0] = '\0'; r = NULL; @@ -95,14 +87,14 @@ udp_in_acceptmsg(int fd) s4 = (struct sockaddr_in *)&from; inet_ntop(from.ss_family, &(s4->sin_addr), fromstr, 64); r = fromstr; - asldebug("%s: recvfrom %s len %d\n", MY_ID, fromstr, len); + asldebug("%s: fd %d recvfrom %s len %d\n", MY_ID, fd, fromstr, len); } else if (from.ss_family == AF_INET6) { s6 = (struct sockaddr_in6 *)&from; inet_ntop(from.ss_family, &(s6->sin6_addr), fromstr, 64); r = fromstr; - asldebug("%s: recvfrom %s len %d\n", MY_ID, fromstr, len); + asldebug("%s: fd %d recvfrom %s len %d\n", MY_ID, fd, fromstr, len); } uline[len] = '\0'; @@ -110,83 +102,85 @@ udp_in_acceptmsg(int fd) p = strrchr(uline, '\n'); if (p != NULL) *p = '\0'; - - /* - * Determine if the input is "old" syslog format or new ASL format. - * Old format lines should start with "<", but they can just be - * straight text. ASL input starts with a length (10 bytes) - * followed by a space and a '['. - */ - format = FMT_LEGACY; - off = 0; - - if ((uline[0] != '<') && (len > 11)) - { - status = sscanf(uline, "%d ", &x); - if (status == 1) - { - if ((uline[10] == ' ') && (uline[11] == '[')) - { - format = FMT_ASL; - off = 11; - } - } - } - - return udp_convert(format, uline+off, len-off, r); + m = asl_input_parse(uline, len, r, SOURCE_UDP_SOCKET); + process_message(m, SOURCE_UDP_SOCKET); } int -udp_in_init(void) +udp_in_init() { - struct addrinfo hints, *gai, *ai; - int status, i; + int i, rbufsize, len, fd; + launch_data_t sockets_dict, fd_array, fd_dict; + static dispatch_once_t once; + + dispatch_once(&once, ^{ + in_queue = dispatch_queue_create(MY_ID, NULL); + }); asldebug("%s: init\n", MY_ID); if (nsock > 0) return 0; - memset(&hints, 0, sizeof(hints)); - hints.ai_flags = AI_PASSIVE; - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_DGRAM; + if (global.launch_dict == NULL) + { + asldebug("%s: launchd dict is NULL\n", MY_ID); + return -1; + } + + sockets_dict = launch_data_dict_lookup(global.launch_dict, LAUNCH_JOBKEY_SOCKETS); + if (sockets_dict == NULL) + { + asldebug("%s: launchd lookup of LAUNCH_JOBKEY_SOCKETS failed\n", MY_ID); + return -1; + } + + fd_array = launch_data_dict_lookup(sockets_dict, UDP_SOCKET_NAME); + if (fd_array == NULL) + { + asldebug("%s: launchd lookup of UDP_SOCKET_NAME failed\n", MY_ID); + return -1; + } - status = getaddrinfo(NULL, "syslog", &hints, &gai); - if (status != 0) return -1; + nsock = launch_data_array_get_count(fd_array); + if (nsock <= 0) + { + asldebug("%s: launchd fd array is empty\n", MY_ID); + return -1; + } - for (ai = gai; (ai != NULL) && (nsock < MAXSOCK); ai = ai->ai_next) + for (i = 0; i < nsock; i++) { - ufd[nsock] = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); - if (ufd[nsock] < 0) + ufd[i] = -1; + + fd_dict = launch_data_array_get_index(fd_array, i); + if (fd_dict == NULL) { - asldebug("%s: socket: %s\n", MY_ID, strerror(errno)); - continue; + asldebug("%s: launchd file discriptor array element 0 is NULL\n", MY_ID); + return -1; } - if (bind(ufd[nsock], ai->ai_addr, ai->ai_addrlen) < 0) + fd = launch_data_get_fd(fd_dict); + + rbufsize = 128 * 1024; + len = sizeof(rbufsize); + + if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rbufsize, len) < 0) { - asldebug("%s: bind: %s\n", MY_ID, strerror(errno)); - close(ufd[nsock]); - continue; + asldebug("%s: couldn't set receive buffer size for file descriptor %d: %s\n", MY_ID, fd, strerror(errno)); } - nsock++; - } + if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) + { + asldebug("%s: couldn't set O_NONBLOCK for file descriptor %d: %s\n", MY_ID, fd, strerror(errno)); + } - freeaddrinfo(gai); + ufd[i] = fd; - if (nsock == 0) - { - asldebug("%s: no input sockets\n", MY_ID); - return -1; - } + in_src[i] = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, (uintptr_t)fd, 0, in_queue); + dispatch_source_set_event_handler(in_src[i], ^{ udp_in_acceptmsg(fd); }); - for (i = 0; i < nsock; i++) aslevent_addfd(ufd[i], udp_in_acceptmsg, NULL, NULL); - return 0; -} + dispatch_resume(in_src[i]); + } -int -udp_in_reset(void) -{ return 0; } @@ -195,15 +189,34 @@ udp_in_close(void) { int i; - if (nsock == 0) return 1; + if (nsock == 0) return -1; for (i = 0; i < nsock; i++) { - close(ufd[i]); - ufd[i] = -1; + if (ufd_src[i] != NULL) + { + dispatch_source_cancel(in_src[i]); + dispatch_release(in_src[i]); + in_src[i] = NULL; + } + + if (ufd[i] != -1) + { + close(ufd[i]); + ufd[i] = -1; + } } nsock = 0; return 0; } + +int +udp_in_reset(void) +{ + if (udp_in_close() != 0) return -1; + return udp_in_init(); +} + +#endif /* !TARGET_OS_SIMULATOR */