configure.in: Update AC_PREREQ to autoconf 2.64. Use LT_INIT instead
of AC_PROG_LIBTOOL. Remove the deprecated AC_TYPE_SIGNAL (which we
didn't use anyway). Fix the indentation of the explanatory text for
--without-kevent and --with-win32.
src/sar.c: Convert "struct sockaddr_storage" to "void *" to comply
with C99's strict(er) aliasing rules. Allocate off the stack or
heap, as appropriate. Add new function sar_free_nameserver() to
clean up the heap-allocated data.
dnl Process this file with autoconf to create a configure script.
dnl General initialization.
dnl Process this file with autoconf to create a configure script.
dnl General initialization.
AC_INIT([srvx],[1.4.0-rc3],[srvx-bugs@lists.sourceforge.net])
CODENAME=surge
AC_CONFIG_HEADERS(src/config.h)
AC_INIT([srvx],[1.4.0-rc3],[srvx-bugs@lists.sourceforge.net])
CODENAME=surge
AC_CONFIG_HEADERS(src/config.h)
AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE([gnu 1.6])
AM_MAINTAINER_MODE
AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE([gnu 1.6])
AM_MAINTAINER_MODE
dnl Compiler/runtime feature checks.
dnl Compiler/runtime feature checks.
AC_C_CONST
dnl "const" *should* be in the -Werror section, but that breaks Linux. gg gcc.
AC_C_CONST
dnl "const" *should* be in the -Werror section, but that breaks Linux. gg gcc.
AC_PROG_AWK
AC_PROG_CC
AC_PROG_INSTALL
AC_PROG_AWK
AC_PROG_CC
AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_MAKE_SET
AC_PROG_GCC_TRADITIONAL
AC_PROG_LN_S
AC_PROG_MAKE_SET
AC_PROG_GCC_TRADITIONAL
-[ --without-kevent Disables the kevent() I/O backend],
+[ --without-kevent Disables the kevent() I/O backend],
[],
[withval="$ac_cv_func_kevent"])
if test "x$withval" = xyes ; then
[],
[withval="$ac_cv_func_kevent"])
if test "x$withval" = xyes ; then
-[ --with-win32 Enables the Win32 I/O backend],
+[ --with-win32 Enables the Win32 I/O backend],
[],
[withval="no"])
if test "x$withval" = xyes ; then
[],
[withval="no"])
if test "x$withval" = xyes ; then
char sar_localdomain[MAXLEN];
struct string_list *sar_search;
struct string_list *sar_nslist;
char sar_localdomain[MAXLEN];
struct string_list *sar_search;
struct string_list *sar_nslist;
- struct sockaddr_storage sar_bind_address;
+ void *sar_bind_address;
} conf;
static struct log_type *sar_log;
} conf;
static struct log_type *sar_log;
unsigned int resp_failures;
unsigned int resp_scrambled;
unsigned int ss_len;
unsigned int resp_failures;
unsigned int resp_scrambled;
unsigned int ss_len;
- struct sockaddr_storage ss;
};
/* EDNS0 uses 12 bit RCODEs, TSIG/TKEY use 16 bit RCODEs.
};
/* EDNS0 uses 12 bit RCODEs, TSIG/TKEY use 16 bit RCODEs.
free_string_list(ns_sv);
ns_sv = string_list_copy(slist);
}
free_string_list(ns_sv);
ns_sv = string_list_copy(slist);
}
- sa = (struct sockaddr*)&conf.sar_bind_address;
- memset(sa, 0, sizeof(conf.sar_bind_address));
+ sa = (struct sockaddr*)conf.sar_bind_address;
+ memset(sa, 0, sizeof(struct sockaddr_storage));
str = database_get_data(node, "bind_address", RECDB_QSTRING);
str = database_get_data(node, "bind_address", RECDB_QSTRING);
- if (str) sar_pton(sa, sizeof(conf.sar_bind_address), NULL, str);
+ if (str) sar_pton(sa, sizeof(struct sockaddr_storage), NULL, str);
str = database_get_data(node, "bind_port", RECDB_QSTRING);
if (str != NULL) {
if (sa->sa_family == AF_INET) {
str = database_get_data(node, "bind_port", RECDB_QSTRING);
if (str != NULL) {
if (sa->sa_family == AF_INET) {
struct sar_nameserver *ns;
ns = iter_data(it);
struct sar_nameserver *ns;
ns = iter_data(it);
- if (ns->ss_len == ss_len && !memcmp(ss, &ns->ss, ss_len))
+ if (ns->ss_len == ss_len && !memcmp(ss, ns->ss, ss_len))
return ns;
}
return NULL;
return ns;
}
return NULL;
static void
sar_fd_readable(struct io_fd *fd)
{
static void
sar_fd_readable(struct io_fd *fd)
{
- struct sockaddr_storage ss;
struct dns_header hdr;
struct sar_nameserver *ns;
struct sar_request *req;
struct dns_header hdr;
struct sar_nameserver *ns;
struct sar_request *req;
unsigned char *buf;
socklen_t ss_len;
int res, rcode, buf_len;
unsigned char *buf;
socklen_t ss_len;
int res, rcode, buf_len;
if (!buf_len)
buf_len = 512;
buf = alloca(buf_len);
if (!buf_len)
buf_len = 512;
buf = alloca(buf_len);
- ss_len = sizeof(ss);
- res = recvfrom(sar_fd_fd, buf, buf_len, 0, (struct sockaddr*)&ss, &ss_len);
- if (res < 12 || !(ns = sar_our_server(&ss, ss_len)))
+ ss_len = sizeof(struct sockaddr_storage);
+ ss = alloca(ss_len);
+ res = recvfrom(sar_fd_fd, buf, buf_len, 0, (struct sockaddr*)ss, &ss_len);
+ if (res < 12 || !(ns = sar_our_server((struct sockaddr_storage*)ss, ss_len)))
return;
hdr.id = buf[0] << 8 | buf[1];
hdr.flags = buf[2] << 8 | buf[3];
return;
hdr.id = buf[0] << 8 | buf[1];
hdr.flags = buf[2] << 8 | buf[3];
name = nslist->list[ii];
ns = dict_find(sar_nameservers, name, NULL);
if (!ns) {
name = nslist->list[ii];
ns = dict_find(sar_nameservers, name, NULL);
if (!ns) {
ns = calloc(1, sizeof(*ns) + strlen(name) + 1);
ns->name = (char*)(ns + 1);
strcpy(ns->name, name);
ns = calloc(1, sizeof(*ns) + strlen(name) + 1);
ns->name = (char*)(ns + 1);
strcpy(ns->name, name);
- ns->ss_len = sizeof(ns->ss);
- if (!sar_pton((struct sockaddr*)&ns->ss, sizeof(ns->ss), NULL, name)) {
+ ns->ss_len = sizeof(struct sockaddr_storage);
+ ns->ss = calloc(1, ns->ss_len);
+ sa = (struct sockaddr*)ns->ss;
+ if (!sar_pton(sa, ns->ss_len, NULL, name)) {
- sar_set_port((struct sockaddr*)&ns->ss, sizeof(ns->ss), 53);
- ns->ss_len = sar_helpers[ns->ss.ss_family]->socklen;
+ sar_set_port(sa, ns->ss_len, 53);
+ ns->ss_len = sar_helpers[sa->sa_family]->socklen;
dict_insert(sar_nameservers, ns->name, ns);
}
ns->valid = 1;
dict_insert(sar_nameservers, ns->name, ns);
}
ns->valid = 1;
+static void
+sar_free_nameserver(void *obj)
+{
+ struct sar_nameserver *ns = obj;
+ free(ns->ss);
+ free(ns);
+}
+
+static unsigned int
+sar_addrlen(const struct sockaddr *sa, UNUSED_ARG(unsigned int size))
+{
+ return sa->sa_family <= MAX_FAMILY && sar_helpers[sa->sa_family]
+ ? sar_helpers[sa->sa_family]->socklen : 0;
+}
+
static int
sar_open_fd(void)
{
static int
sar_open_fd(void)
{
int res;
/* Build list of nameservers. */
sar_build_nslist(conf.sar_nslist);
int res;
/* Build list of nameservers. */
sar_build_nslist(conf.sar_nslist);
- if (conf.sar_bind_address.ss_family != 0) {
- struct addrinfo *ai;
-
- ai = (struct addrinfo*)&conf.sar_bind_address;
- sar_fd_fd = socket(ai->ai_family, SOCK_DGRAM, 0);
+ sa = (struct sockaddr*)conf.sar_bind_address;
+ if (sa->sa_family != 0) {
+ sar_fd_fd = socket(sa->sa_family, SOCK_DGRAM, 0);
if (sar_fd_fd < 0) {
log_module(sar_log, LOG_FATAL, "Unable to create resolver socket: %s", strerror(errno));
return 1;
}
if (sar_fd_fd < 0) {
log_module(sar_log, LOG_FATAL, "Unable to create resolver socket: %s", strerror(errno));
return 1;
}
- res = bind(sar_fd_fd, ai->ai_addr, ai->ai_addrlen);
+ res = bind(sar_fd_fd, sa, sar_addrlen(sa, sizeof(struct sockaddr_storage)));
if (res < 0)
log_module(sar_log, LOG_ERROR, "Unable to bind resolver socket to address [%s]:%s: %s", (char*)conf_get_data("modules/sar/bind_address", RECDB_QSTRING), (char*)conf_get_data("modules/sar/bind_port", RECDB_QSTRING), strerror(errno));
} else {
if (res < 0)
log_module(sar_log, LOG_ERROR, "Unable to bind resolver socket to address [%s]:%s: %s", (char*)conf_get_data("modules/sar/bind_address", RECDB_QSTRING), (char*)conf_get_data("modules/sar/bind_port", RECDB_QSTRING), strerror(errno));
} else {
it = dict_first(sar_nameservers);
ns = iter_data(it);
it = dict_first(sar_nameservers);
ns = iter_data(it);
- sar_fd_fd = socket(ns->ss.ss_family, SOCK_DGRAM, 0);
+ sar_fd_fd = socket(((struct sockaddr*)ns->ss)->sa_family, SOCK_DGRAM, 0);
if (sar_fd_fd < 0) {
log_module(sar_log, LOG_FATAL, "Unable to create resolver socket: %s", strerror(errno));
return 1;
if (sar_fd_fd < 0) {
log_module(sar_log, LOG_FATAL, "Unable to create resolver socket: %s", strerror(errno));
return 1;
int res;
ns = iter_data(it);
int res;
ns = iter_data(it);
- res = sendto(sar_fd_fd, req->body, req->body_len, 0, (struct sockaddr*)&ns->ss, ns->ss_len);
+ res = sendto(sar_fd_fd, req->body, req->body_len, 0, (struct sockaddr*)ns->ss, ns->ss_len);
if (res > 0) {
ns->req_sent++;
log_module(sar_log, LOG_DEBUG, "Sent %u bytes to %s.", res, ns->name);
if (res > 0) {
ns->req_sent++;
log_module(sar_log, LOG_DEBUG, "Sent %u bytes to %s.", res, ns->name);
sar_first_helper = helper;
}
sar_first_helper = helper;
}
-static unsigned int
-sar_addrlen(const struct sockaddr *sa, UNUSED_ARG(unsigned int size))
-{
- return sa->sa_family <= MAX_FAMILY && sar_helpers[sa->sa_family]
- ? sar_helpers[sa->sa_family]->socklen : 0;
-}
-
struct sar_getaddr_state {
struct sar_family_helper *helper;
struct addrinfo *ai_head;
struct sar_getaddr_state {
struct sar_family_helper *helper;
struct addrinfo *ai_head;
struct sar_request *
sar_getaddr(const char *node, const char *service, const struct addrinfo *hints_, sar_addr_cb cb, void *cb_ctx)
{
struct sar_request *
sar_getaddr(const char *node, const char *service, const struct addrinfo *hints_, sar_addr_cb cb, void *cb_ctx)
{
- struct sockaddr_storage ss;
struct addrinfo hints;
struct sar_family_helper *helper;
struct service_byname *svc;
char *end;
struct addrinfo hints;
struct sar_family_helper *helper;
struct service_byname *svc;
char *end;
+ void *ss;
+ size_t ss_len;
unsigned int portnum;
unsigned int pos;
enum service_proto proto;
unsigned int portnum;
unsigned int pos;
enum service_proto proto;
}
/* Try to parse \a node as a numeric hostname.*/
}
/* Try to parse \a node as a numeric hostname.*/
- pos = sar_pton((struct sockaddr*)&ss, sizeof(ss), NULL, node);
+ ss_len = sizeof(struct sockaddr_storage);
+ ss = alloca(ss_len);
+ pos = sar_pton((struct sockaddr*)ss, ss_len, NULL, node);
if (pos && node[pos] == '\0') {
struct addrinfo *ai;
char canonname[SAR_NTOP_MAX];
/* we have a valid address; use it */
if (pos && node[pos] == '\0') {
struct addrinfo *ai;
char canonname[SAR_NTOP_MAX];
/* we have a valid address; use it */
- sar_set_port((struct sockaddr*)&ss, sizeof(ss), portnum);
- hints.ai_addrlen = sar_addrlen((struct sockaddr*)&ss, sizeof(ss));
+ sar_set_port((struct sockaddr*)ss, ss_len, portnum);
+ hints.ai_addrlen = sar_addrlen((struct sockaddr*)ss, ss_len);
if (!hints.ai_addrlen) {
cb(cb_ctx, NULL, SAI_FAMILY);
return NULL;
}
if (!hints.ai_addrlen) {
cb(cb_ctx, NULL, SAI_FAMILY);
return NULL;
}
- pos = sar_ntop(canonname, sizeof(canonname), (struct sockaddr*)&ss, hints.ai_addrlen);
+ pos = sar_ntop(canonname, sizeof(canonname), (struct sockaddr*)ss, hints.ai_addrlen);
/* allocate and fill in the addrinfo response */
ai = calloc(1, sizeof(*ai) + hints.ai_addrlen + pos + 1);
/* allocate and fill in the addrinfo response */
ai = calloc(1, sizeof(*ai) + hints.ai_addrlen + pos + 1);
- ai->ai_family = ss.ss_family;
+ ai->ai_family = ((struct sockaddr*)ss)->sa_family;
ai->ai_socktype = hints.ai_socktype;
ai->ai_protocol = hints.ai_protocol;
ai->ai_addrlen = hints.ai_addrlen;
ai->ai_socktype = hints.ai_socktype;
ai->ai_protocol = hints.ai_protocol;
ai->ai_addrlen = hints.ai_addrlen;
- ai->ai_addr = memcpy(ai + 1, &ss, ai->ai_addrlen);
+ ai->ai_addr = memcpy(ai + 1, ss, ai->ai_addrlen);
ai->ai_canonname = strcpy((char*)ai->ai_addr + ai->ai_addrlen, canonname);
cb(cb_ctx, ai, SAI_SUCCESS);
return NULL;
ai->ai_canonname = strcpy((char*)ai->ai_addr + ai->ai_addrlen, canonname);
cb(cb_ctx, ai, SAI_SUCCESS);
return NULL;
+ conf.sar_bind_address = calloc(1, sizeof(struct sockaddr_storage));
reg_exit_func(sar_cleanup);
sar_log = log_register_type("sar", NULL);
reg_exit_func(sar_cleanup);
sar_log = log_register_type("sar", NULL);
dict_set_free_data(sar_requests, sar_request_cleanup);
sar_nameservers = dict_new();
dict_set_free_data(sar_requests, sar_request_cleanup);
sar_nameservers = dict_new();
- dict_set_free_data(sar_nameservers, free);
+ dict_set_free_data(sar_nameservers, sar_free_nameserver);
sar_register_helper(&sar_ipv4_helper);
#if defined(AF_INET6)
sar_register_helper(&sar_ipv4_helper);
#if defined(AF_INET6)