X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=common-src%2Fdgram.c;h=7f04bec39be7ea269ab50e9a22d02429749d8e74;hb=HEAD;hp=a4c4ba378f773ae129e6a40525091e8fd8980aeb;hpb=34197d9f46a5f4e944378cbb65fca32ee0eec7b9;p=debian%2Famanda diff --git a/common-src/dgram.c b/common-src/dgram.c index a4c4ba3..7f04bec 100644 --- a/common-src/dgram.c +++ b/common-src/dgram.c @@ -1,6 +1,7 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver * Copyright (c) 1991-1999 University of Maryland at College Park + * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. * All Rights Reserved. * * Permission to use, copy, modify, distribute, and sell this software and its @@ -25,7 +26,7 @@ * University of Maryland at College Park */ /* - * $Id: dgram.c,v 1.32.2.4 2006/10/16 18:23:53 martinea Exp $ + * $Id: dgram.c,v 1.32 2006/07/05 19:54:20 martinea Exp $ * * library routines to marshall/send, recv/unmarshall UDP packets */ @@ -33,15 +34,17 @@ #include "arglist.h" #include "dgram.h" #include "util.h" +#include "conffile.h" +#include "sockaddr-util.h" void dgram_socket( dgram_t * dgram, int socket) { - if(socket < 0 || socket >= FD_SETSIZE) { - error("dgram_socket: socket %d out of range (0 .. %d)\n", - socket, FD_SETSIZE-1); + if(socket < 0 || socket >= (int)FD_SETSIZE) { + error(_("dgram_socket: socket %d out of range (0 .. %d)\n"), + socket, (int)FD_SETSIZE-1); /*NOTREACHED*/ } dgram->socket = socket; @@ -51,34 +54,43 @@ dgram_socket( int dgram_bind( dgram_t * dgram, + sa_family_t family, in_port_t * portp) { int s, retries; - socklen_t len; - struct sockaddr_in name; + socklen_t_equiv len; + sockaddr_union name; int save_errno; + int *portrange; + int sndbufsize = MAX_DGRAM; + portrange = getconf_intrange(CNF_RESERVED_UDP_PORT); *portp = (in_port_t)0; - if((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { + g_debug("dgram_bind: setting up a socket with family %d", family); + if((s = socket(family, SOCK_DGRAM, 0)) == -1) { save_errno = errno; - dbprintf(("%s: dgram_bind: socket() failed: %s\n", - debug_prefix(NULL), - strerror(save_errno))); + dbprintf(_("dgram_bind: socket() failed: %s\n"), + strerror(save_errno)); errno = save_errno; return -1; } if(s < 0 || s >= (int)FD_SETSIZE) { - dbprintf(("%s: dgram_bind: socket out of range: %d\n", - debug_prefix(NULL), - s)); + dbprintf(_("dgram_bind: socket out of range: %d\n"), + s); aclose(s); errno = EMFILE; /* out of range */ return -1; } - memset(&name, 0, SIZEOF(name)); - name.sin_family = (sa_family_t)AF_INET; - name.sin_addr.s_addr = INADDR_ANY; + /* try setting the buffer size (= maximum allowable UDP packet size) */ + if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, + (void *) &sndbufsize, sizeof(sndbufsize)) < 0) { + dbprintf("dgram_bind: could not set udp send buffer to %d: %s (ignored)\n", + sndbufsize, strerror(errno)); + } + + SU_INIT(&name, family); + SU_SET_INADDR_ANY(&name); /* * If a port range was specified, we try to get a port in that @@ -92,39 +104,22 @@ dgram_bind( * is within the range it requires. */ for (retries = 0; ; retries++) { -#ifdef UDPPORTRANGE - if (bind_portrange(s, &name, UDPPORTRANGE, "udp") == 0) - goto out; - dbprintf(("%s: dgram_bind: Could to bind to port in range: %d - %d.\n", - debug_prefix(NULL), UDPPORTRANGE)); -#endif - - if (bind_portrange(s, &name, (in_port_t)512, - (in_port_t)(IPPORT_RESERVED - 1), "udp") == 0) - goto out; - dbprintf(("%s: dgram_bind: Could to bind to port in range: 512 - %d.\n", - debug_prefix(NULL), IPPORT_RESERVED - 1)); - - name.sin_port = INADDR_ANY; - if (bind(s, (struct sockaddr *)&name, (socklen_t)sizeof(name)) == 0) + if (bind_portrange(s, &name, portrange[0], portrange[1], "udp") == 0) goto out; - dbprintf(("%s: dgram_bind: Could to bind to any port: %s\n", - debug_prefix(NULL), strerror(errno))); - + dbprintf(_("dgram_bind: Could not bind to port in range: %d - %d.\n"), + portrange[0], portrange[1]); if (retries >= BIND_CYCLE_RETRIES) { - dbprintf(("%s: dgram_bind: Giving up...\n", debug_prefix(NULL))); + dbprintf(_("dgram_bind: Giving up...\n")); break; } - dbprintf(("%s: dgram_bind: Retrying entire range after 10 second delay.\n", - debug_prefix(NULL))); + dbprintf(_("dgram_bind: Retrying entire range after 10 second delay.\n")); sleep(15); } save_errno = errno; - dbprintf(("%s: dgram_bind: bind(INADDR_ANY) failed: %s\n", - debug_prefix(NULL), - strerror(save_errno))); + dbprintf(_("dgram_bind: bind(in6addr_any) failed: %s\n"), + strerror(save_errno)); aclose(s); errno = save_errno; return -1; @@ -132,35 +127,30 @@ dgram_bind( out: /* find out what name was actually used */ - len = (socklen_t)sizeof(name); + len = (socklen_t_equiv)sizeof(name); if(getsockname(s, (struct sockaddr *)&name, &len) == -1) { save_errno = errno; - dbprintf(("%s: dgram_bind: getsockname() failed: %s\n", - debug_prefix(NULL), - strerror(save_errno))); + dbprintf(_("dgram_bind: getsockname() failed: %s\n"), strerror(save_errno)); errno = save_errno; aclose(s); return -1; } - *portp = (in_port_t)ntohs(name.sin_port); + *portp = SU_GET_PORT(&name); dgram->socket = s; - dbprintf(("%s: dgram_bind: socket bound to %s.%d\n", - debug_prefix_time(NULL), - inet_ntoa(name.sin_addr), - *portp)); + dbprintf(_("dgram_bind: socket %d bound to %s\n"), + dgram->socket, str_sockaddr(&name)); return 0; } int dgram_send_addr( - struct sockaddr_in addr, + sockaddr_union *addr, dgram_t * dgram) { int s, rc; int socket_opened; - struct sockaddr_in addr_save; int save_errno; int max_wait; int wait_count; @@ -169,40 +159,45 @@ dgram_send_addr( int r; #endif - dbprintf(("%s: dgram_send_addr(addr=%p, dgram=%p)\n", - debug_prefix(NULL), &addr, dgram)); - dump_sockaddr(&addr); - dbprintf(("%s: dgram_send_addr: %p->socket = %d\n", - debug_prefix(NULL), dgram, dgram->socket)); + dbprintf(_("dgram_send_addr(addr=%p, dgram=%p)\n"), + addr, dgram); + dump_sockaddr(addr); + dbprintf(_("dgram_send_addr: %p->socket = %d\n"), + dgram, dgram->socket); if(dgram->socket != -1) { s = dgram->socket; socket_opened = 0; } else { - if((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { + int sndbufsize = MAX_DGRAM; + + g_debug("dgram_send_addr: setting up a socket with family %d", SU_GET_FAMILY(addr)); + if((s = socket(SU_GET_FAMILY(addr), SOCK_DGRAM, 0)) == -1) { save_errno = errno; - dbprintf(("%s: dgram_send_addr: socket() failed: %s\n", - debug_prefix(NULL), - strerror(save_errno))); + dbprintf(_("dgram_send_addr: socket() failed: %s\n"), + strerror(save_errno)); errno = save_errno; return -1; } socket_opened = 1; #ifdef USE_REUSEADDR r = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, - (void *)&on, (socklen_t)sizeof(on)); + (void *)&on, (socklen_t_equiv)sizeof(on)); if (r < 0) { - dbprintf(("%s: dgram_send_addr: setsockopt(SO_REUSEADDR) failed: %s\n", - debug_prefix(NULL), - strerror(errno))); + dbprintf(_("dgram_send_addr: setsockopt(SO_REUSEADDR) failed: %s\n"), + strerror(errno)); } #endif + + /* try setting the buffer size (= maximum allowable UDP packet size) */ + if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, + (void *) &sndbufsize, sizeof(sndbufsize)) < 0) { + dbprintf("dgram_send_addr: could not set udp send buffer to %d: %s (ignored)\n", + sndbufsize, strerror(errno)); + } } - memcpy(&addr_save, &addr, SIZEOF(addr)); - if(s < 0 || s >= FD_SETSIZE) { - dbprintf(("%s: dgram_send_addr: socket out of range: %d\n", - debug_prefix(NULL), - s)); + if(s < 0 || s >= (int)FD_SETSIZE) { + dbprintf(_("dgram_send_addr: socket out of range: %d\n"), s); errno = EMFILE; /* out of range */ rc = -1; } else { @@ -213,36 +208,30 @@ dgram_send_addr( dgram->data, dgram->len, 0, - (struct sockaddr *)&addr, - (int)sizeof(struct sockaddr_in)) == -1) { + (struct sockaddr *)addr, + SS_LEN(addr)) == -1) { #ifdef ECONNREFUSED if(errno == ECONNREFUSED && wait_count++ < max_wait) { sleep(5); - dbprintf(("%s: dgram_send_addr: sendto(%s.%hu): retry %d after ECONNREFUSED\n", - debug_prefix_time(NULL), - inet_ntoa(addr_save.sin_addr), - (in_port_t)ntohs(addr.sin_port), - wait_count)); + dbprintf(_("dgram_send_addr: sendto(%s): retry %d after ECONNREFUSED\n"), + str_sockaddr(addr), + wait_count); continue; } #endif #ifdef EAGAIN if(errno == EAGAIN && wait_count++ < max_wait) { sleep(5); - dbprintf(("%s: dgram_send_addr: sendto(%s.%hu): retry %d after EAGAIN\n", - debug_prefix_time(NULL), - inet_ntoa(addr_save.sin_addr), - (in_port_t)ntohs(addr.sin_port), - wait_count)); + dbprintf(_("dgram_send_addr: sendto(%s): retry %d after EAGAIN\n"), + str_sockaddr(addr), + wait_count); continue; } #endif save_errno = errno; - dbprintf(("%s: dgram_send_addr: sendto(%s.%d) failed: %s \n", - debug_prefix_time(NULL), - inet_ntoa(addr_save.sin_addr), - (int) ntohs(addr.sin_port), - strerror(save_errno))); + dbprintf(_("dgram_send_addr: sendto(%s) failed: %s \n"), + str_sockaddr(addr), + strerror(save_errno)); errno = save_errno; rc = -1; break; @@ -252,11 +241,9 @@ dgram_send_addr( if(socket_opened) { save_errno = errno; if(close(s) == -1) { - dbprintf(("%s: dgram_send_addr: close(%s.%d): failed: %s\n", - debug_prefix(NULL), - inet_ntoa(addr_save.sin_addr), - (int) ntohs(addr.sin_port), - strerror(errno))); + dbprintf(_("dgram_send_addr: close(%s): failed: %s\n"), + str_sockaddr(addr), + strerror(errno)); /* * Calling function should not care that the close failed. * It does care about the send results though. @@ -269,43 +256,18 @@ dgram_send_addr( } -int -dgram_send( - char * hostname, - in_port_t port, - dgram_t * dgram) -{ - struct sockaddr_in name; - struct hostent *hp; - int save_errno; - - if((hp = gethostbyname(hostname)) == 0) { - save_errno = errno; - dbprintf(("%s: dgram_send: gethostbyname(%s) failed\n", - debug_prefix_time(NULL), - hostname)); - errno = save_errno; - return -1; - } - memcpy(&name.sin_addr, hp->h_addr, (size_t)hp->h_length); - name.sin_family = (sa_family_t)AF_INET; - name.sin_port = (in_port_t)htons(port); - - return dgram_send_addr(name, dgram); -} - ssize_t dgram_recv( dgram_t * dgram, int timeout, - struct sockaddr_in *fromaddr) + sockaddr_union *fromaddr) { SELECT_ARG_TYPE ready; struct timeval to; ssize_t size; int sock; - socklen_t addrlen; + socklen_t_equiv addrlen; ssize_t nfound; int save_errno; @@ -316,31 +278,26 @@ dgram_recv( to.tv_sec = timeout; to.tv_usec = 0; - dbprintf(("%s: dgram_recv(dgram=%p, timeout=%u, fromaddr=%p)\n", - debug_prefix_time(NULL), dgram, timeout, fromaddr)); + dbprintf(_("dgram_recv(dgram=%p, timeout=%u, fromaddr=%p)\n"), + dgram, timeout, fromaddr); nfound = (ssize_t)select(sock+1, &ready, NULL, NULL, &to); if(nfound <= 0 || !FD_ISSET(sock, &ready)) { save_errno = errno; if(nfound < 0) { - dbprintf(("%s: dgram_recv: select() failed: %s\n", - debug_prefix_time(NULL), - strerror(save_errno))); + dbprintf(_("dgram_recv: select() failed: %s\n"), strerror(save_errno)); } else if(nfound == 0) { - dbprintf(("%s: dgram_recv: timeout after %d second%s\n", - debug_prefix_time(NULL), - timeout, - (timeout == 1) ? "" : "s")); + dbprintf(plural(_("dgram_recv: timeout after %d second\n"), + _("dgram_recv: timeout after %d seconds\n"), + timeout), + timeout); nfound = 0; } else if (!FD_ISSET(sock, &ready)) { int i; for(i = 0; i < sock + 1; i++) { if(FD_ISSET(i, &ready)) { - dbprintf(("%s: dgram_recv: got fd %d instead of %d\n", - debug_prefix_time(NULL), - i, - sock)); + dbprintf(_("dgram_recv: got fd %d instead of %d\n"), i, sock); } } save_errno = EBADF; @@ -350,14 +307,12 @@ dgram_recv( return nfound; } - addrlen = (socklen_t)sizeof(struct sockaddr_in); + addrlen = (socklen_t_equiv)sizeof(sockaddr_union); size = recvfrom(sock, dgram->data, (size_t)MAX_DGRAM, 0, (struct sockaddr *)fromaddr, &addrlen); if(size == -1) { save_errno = errno; - dbprintf(("%s: dgram_recv: recvfrom() failed: %s\n", - debug_prefix(NULL), - strerror(save_errno))); + dbprintf(_("dgram_recv: recvfrom() failed: %s\n"), strerror(save_errno)); errno = save_errno; return -1; } @@ -395,7 +350,7 @@ printf_arglist_function1(int dgram_cat, dgram_t *, dgram, const char *, fmt) return -1; arglist_start(argp, fmt); - len = vsnprintf(dgram->cur, (size_t)bufsize, fmt, argp); + len = g_vsnprintf(dgram->cur, (size_t)bufsize, fmt, argp); arglist_end(argp); if(len < 0) { return -1;