From: <al...@us...> - 2002-09-25 22:50:19
|
Update of /cvsroot/msyslog/syslog/src/modules In directory usw-pr-cvs1:/tmp/cvs-serv9410/src/modules Modified Files: im_udp.c ip_misc.c Log Message: move im_udp networking stuff to ip_misc update ip_misc to handle it properly (i.e. using a socket for reading) have an option on im_udp to avoid doing dns resolution (-n) have the port on the ret structure some style *UNTESTED* Index: im_udp.c =================================================================== RCS file: /cvsroot/msyslog/syslog/src/modules/im_udp.c,v retrieving revision 1.78 retrieving revision 1.79 diff -u -d -r1.78 -r1.79 --- im_udp.c 25 Sep 2002 07:25:52 -0000 1.78 +++ im_udp.c 25 Sep 2002 22:50:16 -0000 1.79 @@ -38,17 +38,11 @@ #include "config.h" -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/uio.h> -#include <sys/un.h> #include <sys/param.h> -#include <netinet/in.h> #include <ctype.h> #include <errno.h> #include <syslog.h> -#include <netdb.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -76,9 +70,13 @@ #define M_NOTFQDN 0x02 #define M_CACHENAMES 0x04 #define M_REPLACENONPRINT 0x08 +#define M_DONTRESOLV 0x10 /* prototypes */ struct sockaddr *resolv_name(char *, char *, char *, socklen_t *); +int sock_udp(char *, char *, void **, int *); +int udp_recv(int, char *, int, char *, int, char *, int, int); +#define M_NODNS 0x01 /* same as ip_misc.c */ /* * initialize udp input @@ -91,8 +89,8 @@ im_udp_init(struct i_module *I, char **argv, int argc) { struct im_udp_ctx *c; - char *host, *port; - int ch, argcnt; + char *host, *port; + int ch, argcnt; m_dprintf(MSYSLOG_INFORMATIVE, "im_udp_init: entering\n"); @@ -108,8 +106,8 @@ /* parse args (skip module name) */ for (argcnt = 1; (ch = getxopt(argc, argv, "h!host: p!port: " - "a!addhost q!nofqdn c!cachenames r!replacechar: n!noresolv", - &argcnt)) != -1; argcnt++) { + "a!addhost q!nofqdn c!cachenames r!replacechar: " + "n!noresolv", &argcnt)) != -1; argcnt++) { switch (ch) { case 'h': @@ -136,37 +134,30 @@ c->flags |= M_REPLACENONPRINT; c->subst = *argv[argcnt]; break; + case 'n': + /* don't resolv hostnames */ + c->flags |= M_DONTRESOLV; + break; default: - m_dprintf(MSYSLOG_SERIOUS, "im_udp_init: parsing error [%c]\n", ch); + m_dprintf(MSYSLOG_SERIOUS, "im_udp_init: parsing error" + " [%c]\n", ch); free(c); -return (-1); + return (-1); } } - { /* get the udp socket */ - struct sockaddr *sa; - socklen_t salen; - - I->im_fd = socket(AF_INET, SOCK_DGRAM, 0); - - if ((sa = resolv_name(host, port, "udp", &salen)) == NULL) { - m_dprintf(MSYSLOG_SERIOUS, "im_udp_init: error resolving host" - "[%s] and port [%s]", host, port); - free(c); -return (-1); - } + if ((I->im_fd = sock_udp(host, port, NULL, NULL)) == -1) { - if (bind(I->im_fd, sa, salen) < 0) { - m_dprintf(MSYSLOG_SERIOUS, "im_udp_init: error binding to host" - "[%s] and port [%s]", host, port); + m_dprintf(MSYSLOG_SERIOUS, "im_udp_init: error creating " + "input socket for host [%s] and port [%s]", host, port); free(c); -return (-1); + return (-1); } - } watch_fd_input('p', I->im_fd , I); m_dprintf(MSYSLOG_INFORMATIVE, "im_udp: running\n"); -return (1); + + return (1); } @@ -181,9 +172,7 @@ im_udp_read(struct i_module *im, int infd, struct im_msg *ret) { struct im_udp_ctx *c; - struct sockaddr_in frominet; - char *p; - int slen; + char *p; m_dprintf(MSYSLOG_INFORMATIVE, "im_udp_read: entering...\n"); @@ -196,18 +185,16 @@ ret->im_pri = -1; ret->im_flags = 0; - slen = sizeof(frominet); - if ((ret->im_len = recvfrom(im->im_fd, ret->im_msg, - sizeof(ret->im_msg) - 1, 0, (struct sockaddr *)&frominet, - (socklen_t *)&slen)) < 1) { - if (ret->im_len < 0 && errno != EINTR) - logerror("recvfrom inet"); - return (1); - } + c = (struct im_udp_ctx *) im->im_ctx; - ret->im_msg[ret->im_len] = '\0'; + if ((ret->im_len = udp_recv(im->im_fd, ret->im_msg, + sizeof (ret->im_msg), ret->im_host, sizeof (ret->im_host), + ret->im_port, sizeof (ret->im_port), + c->flags & M_DONTRESOLV? M_NODNS : 0)) == -1) { - c = (struct im_udp_ctx *) im->im_ctx; + logerror("im_udp_read: reading from net"); + return (1); + } /* change non printable chars to c->subst, just in case */ if (c->flags & M_REPLACENONPRINT) @@ -215,27 +202,28 @@ if (!isprint((unsigned int) *p) && *p != '\n') *p = c->subst; + /* extract hostname from message */ + /* XXX: THIS SHOULD BE DONE OUTSIDE THE MODULES */ if (c->flags & M_USEMSGHOST) { - /* extract hostname from message */ char host[90]; int n1 = 0; int n2 = 0; - if ((sscanf(ret->im_msg, "<%*d>%*3s %*i %*i:%*i:%*i %n%89s %n%*s", - &n1, host, &n2) != 1 && - sscanf(ret->im_msg, "%*3s %*i %*i:%*i:%*i %n%89s %n%*s", - &n1, host, &n2) != 1 && - sscanf(ret->im_msg, "%n%89s %n%*s", &n1, host, &n2) != 1) - || - ret->im_msg[n2] == '\0') - { + if ((sscanf(ret->im_msg, "<%*d>%*3s %*i %*i:%*i:%*i %n%89s " + "%n%*s", &n1, host, &n2) != 1 + && sscanf(ret->im_msg, "%*3s %*i %*i:%*i:%*i %n%89s %n%*s", + &n1, host, &n2) != 1 + && sscanf(ret->im_msg, "%n%89s %n%*s", &n1, host, &n2) != 1) + || ret->im_msg[n2] == '\0') { + m_dprintf(MSYSLOG_INFORMATIVE, "im_udp_read: skipped" " invalid message [%s]\n", ret->im_msg); -return (0); + + return (0); } if (ret->im_msg[n2] == '\0') -return (0); + return (0); /* remove host from message */ while (ret->im_msg[n2] != '\0') @@ -243,42 +231,9 @@ ret->im_msg[n1] = '\0'; strncat(ret->im_host, host, sizeof(ret->im_host)); - - /* strip domain from hostname */ - /* XXX: what is this? - * There is no assurance that the hostname is not an ip address - * in which case stripping off the domain would be inappropriate. - * - */ - } else { - struct hostent *hent; - - /* - * extract host ip address from ip header - * and attempt to look up the name - */ - - hent = gethostbyaddr((char *) &frominet.sin_addr, - sizeof(frominet.sin_addr), frominet.sin_family); - - if (hent) { - - strncpy(ret->im_host, hent->h_name, sizeof(ret->im_host)); - - /* strip domain from hostname */ - if (c->flags & M_NOTFQDN) { - char *dot; - - if ((dot = strchr(ret->im_host, '.')) != NULL) - *dot = '\0'; - } - } else - strncpy(ret->im_host, inet_ntoa(frominet.sin_addr), - sizeof(ret->im_host) - 1); + ret->im_host[sizeof (ret->im_host) - 1] = '\0'; } - ret->im_host[sizeof(ret->im_host) - 1] = '\0'; - return (1); } @@ -288,5 +243,5 @@ close(im->im_fd); -return (0); + return (0); } Index: ip_misc.c =================================================================== RCS file: /cvsroot/msyslog/syslog/src/modules/ip_misc.c,v retrieving revision 1.25 retrieving revision 1.26 diff -u -d -r1.25 -r1.26 --- ip_misc.c 17 Sep 2002 05:20:28 -0000 1.25 +++ ip_misc.c 25 Sep 2002 22:50:16 -0000 1.26 @@ -80,6 +80,7 @@ #define TCP_KEEPALIVE 30 /* seconds to probe TCP connection */ #define MSYSLOG_MAX_TCP_CLIENTS 100 #define LISTENQ 35 +#define M_NODNS 0x01 /* * resolv_addr: get a host name from a generic sockaddr structure @@ -158,6 +159,45 @@ return (-1); } +/* + * resolv_addr_nodns: get a host name from a generic sockaddr struct + * without resolving + */ + +int +resolv_addr_nodns(struct sockaddr *addr, socklen_t addrlen, + char *host, int hlen, char *port, int plen) +{ + struct sockaddr_in *sin4; +#ifdef AF_INET6 + struct sockaddr_in6 *sin6; +#endif + + switch (addr->sa_family) { + case AF_INET: + inet_ntop(AF_INET, addr, host, hlen); + sin4 = (struct sockaddr_in *) addr; + snprintf(port, (unsigned) plen, "%u", + ntohs(sin4->sin_port)); + break; +#ifdef AF_INET6 + case AF_INET6: + inet_ntop(AF_INET6, addr, host, hlen); + sin6 = (struct sockaddr_in6 *) addr; + snprintf(port, (unsigned) plen, "%u", + ntohs(sin6->sin6_port)); + break; +#endif + default: + return (-1); + } + + host[hlen - 1] = '\0'; + port[plen - 1] = '\0'; + + return (1); +} + /* * resolv_name: get a sockaddr address from host and port string @@ -400,15 +440,18 @@ sock_udp(char *host, char *port, void **addr, int *addrlen) { struct sockaddr *sa; + socklen_t salen; - if (addr == NULL || addrlen == NULL) - return (-1); - - if ( (sa = resolv_name(host, port, "udp", (socklen_t *) addrlen)) - == NULL) + if ((sa = resolv_name(host, port, "udp", &salen)) == NULL) return (-1); - *addr = sa; + /* pass struct sockaddr if requested */ + if (addrlen != NULL) + *addrlen = salen; + if (addr != NULL) + *addr = sa; + else + free(sa); return (socket(sa->sa_family, SOCK_DGRAM, 0)); } @@ -423,6 +466,47 @@ return (sendto(fd, msg, mlen, 0, (struct sockaddr *) addr, addrlen)); } + +/* + * udp_recv: receive an UDP packet + */ + +int +udp_recv(int fd, char *msg, int mlen, char *host, int hlen, + char *port, int plen, int flags) +{ + struct sockaddr *sa; + socklen_t salen; + int rlen; + + salen = sizeof (struct +#ifdef AF_INET6 + sockaddr_in6 +#else + sockaddr_in +#endif + ); + + if ((sa = (struct sockaddr *) malloc(salen)) == NULL) + return (-1); + + if ((rlen = recvfrom(fd, msg, mlen - 1, 0, sa, &salen)) < 1) { + + free(sa); + return (-1); + } + + msg[rlen] = '\0'; + + if (flags & M_NODNS) + resolv_addr_nodns(sa, salen, host, hlen, port, plen); + else + resolv_addr(sa, salen, host, hlen, port, plen); + + free(sa); + return (rlen); +} + /* * resolv_domain: get a domain for a name, used to get local domain * @@ -442,3 +526,18 @@ return (1); } + +#if 0 +int +resolv_addr_cached(struct name_cache *cache, char *host, char *port, + char *proto, socklen_t *salen) +{ + /* walk through the cache */ + /* if found, return pointer to cache */ + /* else, resolv */ + /* if cache full, remove first entry(ies) (as many as needed) + * move forwards others (since this name could be longer than one) + * and add this name at the end */ + return (-1); +} +#endif |