X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fcnid_dbd%2Fusockfd.c;h=ceb6ff211ad6628693b18e48bb2c1fbec2925c03;hb=e83a5199e4f35ceea335dc3075b23e8d983e7642;hp=8fba6054c0e00278f753f8f0513266247b60b12e;hpb=ecfc96169ab669b578e53fa8e13592934fe37788;p=netatalk.git diff --git a/etc/cnid_dbd/usockfd.c b/etc/cnid_dbd/usockfd.c index 8fba6054..ceb6ff21 100644 --- a/etc/cnid_dbd/usockfd.c +++ b/etc/cnid_dbd/usockfd.c @@ -1,6 +1,4 @@ /* - * $Id: usockfd.c,v 1.2 2005-04-28 20:49:49 bfernhomberg Exp $ - * * Copyright (C) Joerg Lenneis 2003 * All Rights Reserved. See COPYING. */ @@ -33,6 +31,7 @@ #include #include "usockfd.h" +#include int usockfd_create(char *usock_fn, mode_t mode, int backlog) { @@ -66,6 +65,9 @@ int usockfd_create(char *usock_fn, mode_t mode, int backlog) return -1; } +#ifdef chmod +#undef chmod +#endif if (chmod(usock_fn, mode) < 0) { LOG(log_error, logtype_cnid, "error changing permissions for %s: %s", usock_fn, strerror(errno)); @@ -77,81 +79,87 @@ int usockfd_create(char *usock_fn, mode_t mode, int backlog) } /* --------------- - create a tcp socket (should share dsi stuff) -*/ -int tsockfd_create(char *host, u_int16_t ipport, int backlog) + * create a tcp socket + */ +int tsockfd_create(char *host, char *port, int backlog) { - int sockfd; - struct sockaddr_in server; - struct hostent *hp; - int port; - - hp=gethostbyname(host); - if (!hp) { - unsigned long int addr=inet_addr(host); - if (addr!= (unsigned)-1) - hp=gethostbyaddr((char*)addr,sizeof(addr),AF_INET); - - if (!hp) { - LOG(log_error, logtype_cnid, "gethostbyaddr %s: %s", host, strerror(errno)); - return -1; - } - } - memcpy((char*)&server.sin_addr,(char*)hp->h_addr,sizeof(server.sin_addr)); + int sockfd, flag, ret; + struct addrinfo hints, *servinfo, *p; - if ((sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { - LOG(log_error, logtype_cnid, "error in socket call: %s", strerror(errno)); - return -1; + /* Prepare hint for getaddrinfo */ + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + if ((ret = getaddrinfo(host, port, &hints, &servinfo)) != 0) { + LOG(log_error, logtype_default, "tsockfd_create: getaddrinfo: %s\n", gai_strerror(ret)); + return 0; } - - port = htons(ipport); - - server.sin_family = AF_INET; - server.sin_port = port; + /* create a socket */ + /* loop through all the results and bind to the first we can */ + for (p = servinfo; p != NULL; p = p->ai_next) { + if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { + LOG(log_info, logtype_default, "tsockfd_create: socket: %s", strerror(errno)); + continue; + } + + /* + * Set some socket options: + * SO_REUSEADDR deals w/ quick close/opens + * TCP_NODELAY diables Nagle + */ #ifdef SO_REUSEADDR - port = 1; - setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &port, sizeof(port)); -#endif /* SO_REUSEADDR */ + flag = 1; + setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag)); +#endif -#ifdef USE_TCP_NODELAY +#ifdef USE_TCP_NODELAY #ifndef SOL_TCP #define SOL_TCP IPPROTO_TCP -#endif /* ! SOL_TCP */ - port = 1; - setsockopt(sockfd, SOL_TCP, TCP_NODELAY, &port, sizeof(port)); +#endif + flag = 1; + setsockopt(sockfd, SOL_TCP, TCP_NODELAY, &flag, sizeof(flag)); #endif /* USE_TCP_NODELAY */ + + if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) { + close(sockfd); + LOG(log_info, logtype_default, "tsockfd_create: bind: %s\n", strerror(errno)); + continue; + } - if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0) { - LOG(log_error, logtype_cnid, "error binding to socket for %s: %s", - host, strerror(errno)); - return -1; + if (listen(sockfd, backlog) < 0) { + close(sockfd); + LOG(log_info, logtype_default, "tsockfd_create: listen: %s\n", strerror(errno)); + continue; + } + + /* We got a socket */ + break; } - if (listen(sockfd, backlog) < 0) { - LOG(log_error, logtype_cnid, "error in listen for %s: %s", - host, strerror(errno)); + if (p == NULL) { + LOG(log_error, logtype_default, "tsockfd_create: no suitable network config %s:%s", host, port); + freeaddrinfo(servinfo); return -1; } + freeaddrinfo(servinfo); return sockfd; } /* --------------------- */ -int usockfd_check(int sockfd, unsigned long ndelay) +int usockfd_check(int sockfd, const sigset_t *sigset) { int fd; - int size; + socklen_t size; fd_set readfds; - struct timeval tv; int ret; FD_ZERO(&readfds); FD_SET(sockfd, &readfds); - tv.tv_usec = ndelay % 1000000; - tv.tv_sec = ndelay / 1000000; - if ((ret = select(sockfd + 1, &readfds, NULL, NULL, &tv)) < 0) { + if ((ret = pselect(sockfd + 1, &readfds, NULL, NULL, NULL, sigset)) < 0) { if (errno == EINTR) return 0; LOG(log_error, logtype_cnid, "error in select: %s",