#include "arglist.h"
#include "dgram.h"
#include "util.h"
+#include "conffile.h"
void
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;
+ struct sockaddr_storage name;
int save_errno;
-#if defined(USE_REUSEADDR)
- const int on = 1;
- int r;
-#endif
+ int *portrange;
+ portrange = getconf_intrange(CNF_RESERVED_UDP_PORT);
*portp = (in_port_t)0;
- if((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
+ if((s = socket(family, SOCK_DGRAM, 0)) == -1) {
save_errno = errno;
dbprintf(("%s: dgram_bind: socket() failed: %s\n",
- debug_prefix(NULL),
+ debug_prefix_time(NULL),
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),
+ debug_prefix_time(NULL),
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;
-
-#ifdef USE_REUSEADDR
- r = setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
- (void *)&on, (socklen_t)sizeof(on));
- if (r < 0) {
- dbprintf(("%s: dgram_bind: setsockopt(SO_REUSEADDR) failed: %s\n",
- debug_prefix(NULL),
- strerror(errno)));
- }
-#endif
+ SS_INIT(&name, family);
+ SS_SET_INADDR_ANY(&name);
/*
* If a port range was specified, we try to get a port in that
* is within the range it requires.
*/
for (retries = 0; ; retries++) {
-#ifdef UDPPORTRANGE
- if (bind_portrange(s, &name, UDPPORTRANGE, "udp") == 0)
+ if (bind_portrange(s, &name, portrange[0], portrange[1], "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)
- goto out;
- dbprintf(("%s: dgram_bind: Could to bind to any port: %s\n",
- debug_prefix(NULL), strerror(errno)));
-
+ dbprintf(("%s: dgram_bind: Could not bind to port in range: %d - %d.\n",
+ debug_prefix_time(NULL), portrange[0], portrange[1]));
if (retries >= BIND_CYCLE_RETRIES) {
- dbprintf(("%s: dgram_bind: Giving up...\n", debug_prefix(NULL)));
+ dbprintf(("%s: dgram_bind: Giving up...\n",
+ debug_prefix_time(NULL)));
break;
}
dbprintf(("%s: dgram_bind: Retrying entire range after 10 second delay.\n",
- debug_prefix(NULL)));
+ debug_prefix_time(NULL)));
sleep(15);
}
save_errno = errno;
- dbprintf(("%s: dgram_bind: bind(INADDR_ANY) failed: %s\n",
- debug_prefix(NULL),
+ dbprintf(("%s: dgram_bind: bind(in6addr_any) failed: %s\n",
+ debug_prefix_time(NULL),
strerror(save_errno)));
aclose(s);
errno = save_errno;
if(getsockname(s, (struct sockaddr *)&name, &len) == -1) {
save_errno = errno;
dbprintf(("%s: dgram_bind: getsockname() failed: %s\n",
- debug_prefix(NULL),
+ debug_prefix_time(NULL),
strerror(save_errno)));
errno = save_errno;
aclose(s);
return -1;
}
- *portp = (in_port_t)ntohs(name.sin_port);
+ *portp = SS_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(("%s: dgram_bind: socket %d bound to %s\n",
+ debug_prefix_time(NULL), dgram->socket, str_sockaddr(&name)));
return 0;
}
int
dgram_send_addr(
- struct sockaddr_in addr,
+ struct sockaddr_storage *addr,
dgram_t * dgram)
{
int s, rc;
int socket_opened;
- struct sockaddr_in addr_save;
int save_errno;
int max_wait;
int wait_count;
#endif
dbprintf(("%s: dgram_send_addr(addr=%p, dgram=%p)\n",
- debug_prefix(NULL), &addr, dgram));
- dump_sockaddr(&addr);
+ debug_prefix_time(NULL), addr, dgram));
+ dump_sockaddr(addr);
dbprintf(("%s: dgram_send_addr: %p->socket = %d\n",
- debug_prefix(NULL), dgram, dgram->socket));
+ debug_prefix_time(NULL), dgram, dgram->socket));
if(dgram->socket != -1) {
s = dgram->socket;
socket_opened = 0;
} else {
- if((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
+ if((s = socket(addr->ss_family, SOCK_DGRAM, 0)) == -1) {
save_errno = errno;
dbprintf(("%s: dgram_send_addr: socket() failed: %s\n",
- debug_prefix(NULL),
+ debug_prefix_time(NULL),
strerror(save_errno)));
errno = save_errno;
return -1;
(void *)&on, (socklen_t)sizeof(on));
if (r < 0) {
dbprintf(("%s: dgram_send_addr: setsockopt(SO_REUSEADDR) failed: %s\n",
- debug_prefix(NULL),
- strerror(errno)));
+ debug_prefix_time(NULL),
+ strerror(errno)));
}
#endif
}
- 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),
+ debug_prefix_time(NULL),
s));
errno = EMFILE; /* out of range */
rc = -1;
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",
+ dbprintf(("%s: dgram_send_addr: sendto(%s): retry %d after ECONNREFUSED\n",
debug_prefix_time(NULL),
- inet_ntoa(addr_save.sin_addr),
- (in_port_t)ntohs(addr.sin_port),
+ str_sockaddr(addr),
wait_count));
continue;
}
#ifdef EAGAIN
if(errno == EAGAIN && wait_count++ < max_wait) {
sleep(5);
- dbprintf(("%s: dgram_send_addr: sendto(%s.%hu): retry %d after EAGAIN\n",
+ dbprintf(("%s: dgram_send_addr: sendto(%s): retry %d after EAGAIN\n",
debug_prefix_time(NULL),
- inet_ntoa(addr_save.sin_addr),
- (in_port_t)ntohs(addr.sin_port),
+ str_sockaddr(addr),
wait_count));
continue;
}
#endif
save_errno = errno;
- dbprintf(("%s: dgram_send_addr: sendto(%s.%d) failed: %s \n",
+ dbprintf(("%s: dgram_send_addr: sendto(%s) failed: %s \n",
debug_prefix_time(NULL),
- inet_ntoa(addr_save.sin_addr),
- (int) ntohs(addr.sin_port),
+ str_sockaddr(addr),
strerror(save_errno)));
errno = save_errno;
rc = -1;
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),
+ dbprintf(("%s: dgram_send_addr: close(%s): failed: %s\n",
+ debug_prefix_time(NULL),
+ str_sockaddr(addr),
strerror(errno)));
/*
* Calling function should not care that the close failed.
}
-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)
+ struct sockaddr_storage *fromaddr)
{
SELECT_ARG_TYPE ready;
struct timeval to;
to.tv_usec = 0;
dbprintf(("%s: dgram_recv(dgram=%p, timeout=%u, fromaddr=%p)\n",
- debug_prefix_time(NULL), timeout, fromaddr));
- dump_sockaddr(fromaddr);
+ debug_prefix_time(NULL), dgram, timeout, fromaddr));
nfound = (ssize_t)select(sock+1, &ready, NULL, NULL, &to);
if(nfound <= 0 || !FD_ISSET(sock, &ready)) {
return nfound;
}
- addrlen = (socklen_t)sizeof(struct sockaddr_in);
+ addrlen = (socklen_t)sizeof(struct sockaddr_storage);
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),
+ debug_prefix_time(NULL),
strerror(save_errno)));
errno = save_errno;
return -1;
}
+ dump_sockaddr(fromaddr);
dgram->len = (size_t)size;
dgram->data[size] = '\0';
dgram->cur = dgram->data;
arglist_start(argp, fmt);
len = vsnprintf(dgram->cur, (size_t)bufsize, fmt, argp);
arglist_end(argp);
- if((ssize_t)len > bufsize) {
+ if(len < 0) {
+ return -1;
+ } else if((ssize_t)len > bufsize) {
dgram->len = sizeof(dgram->data);
dgram->cur = dgram->data + dgram->len;
return -1;
}
else {
- arglist_start(argp, fmt);
- dgram->len += vsnprintf(dgram->cur, (size_t)bufsize, fmt, argp);
- arglist_end(argp);
+ dgram->len += len;
dgram->cur = dgram->data + dgram->len;
}
return 0;