summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsthen <sthen@openbsd.org>2012-11-23 20:29:13 +0000
committersthen <sthen@openbsd.org>2012-11-23 20:29:13 +0000
commit7b21d3dd3d331725464646c35fee6d771b4d8b55 (patch)
tree05dbcc01911231df6538b2eb4ef0d829fc4fd217
parentDocument SIOCGIFXFLAGS, SIOCGIFMTU, SIOCGIFHARDMTU, SIOCGIFRDOMAIN ioctls. (diff)
downloadwireguard-openbsd-7b21d3dd3d331725464646c35fee6d771b4d8b55.tar.xz
wireguard-openbsd-7b21d3dd3d331725464646c35fee6d771b4d8b55.zip
update to NSD 3.2.14, requested by/ok brad@
-rw-r--r--usr.sbin/nsd/difffile.c6
-rw-r--r--usr.sbin/nsd/ipc.c18
-rw-r--r--usr.sbin/nsd/ipc.h1
-rw-r--r--usr.sbin/nsd/options.c130
-rw-r--r--usr.sbin/nsd/options.h1
-rw-r--r--usr.sbin/nsd/tsig.c1
-rw-r--r--usr.sbin/nsd/xfrd-notify.c2
-rw-r--r--usr.sbin/nsd/xfrd.c15
-rw-r--r--usr.sbin/nsd/xfrd.h6
9 files changed, 116 insertions, 64 deletions
diff --git a/usr.sbin/nsd/difffile.c b/usr.sbin/nsd/difffile.c
index fd0f8684fea..aed2ad10aa0 100644
--- a/usr.sbin/nsd/difffile.c
+++ b/usr.sbin/nsd/difffile.c
@@ -1512,6 +1512,7 @@ diff_read_file(namedb_type* db, nsd_options_t* opt, struct diff_log** log,
log_msg(LOG_ERR, "difffile %s bad first part: no timestamp",
filename);
region_destroy(data->region);
+ fclose(df);
return 0;
}
else if (curr_timestamp[0] != timestamp[0] ||
@@ -1536,6 +1537,7 @@ diff_read_file(namedb_type* db, nsd_options_t* opt, struct diff_log** log,
log_msg(LOG_INFO, "could not fseeko file %s: %s.", filename,
strerror(errno));
region_destroy(data->region);
+ fclose(df);
return 0;
}
if(db->diff_skip) {
@@ -1551,6 +1553,7 @@ diff_read_file(namedb_type* db, nsd_options_t* opt, struct diff_log** log,
if(startpos == -1) {
log_msg(LOG_INFO, "could not ftello: %s.", strerror(errno));
region_destroy(data->region);
+ fclose(df);
return 0;
}
@@ -1566,6 +1569,7 @@ diff_read_file(namedb_type* db, nsd_options_t* opt, struct diff_log** log,
log_msg(LOG_INFO, "could not read timestamp: %s.",
strerror(errno));
region_destroy(data->region);
+ fclose(df);
return 0;
}
@@ -1574,12 +1578,14 @@ diff_read_file(namedb_type* db, nsd_options_t* opt, struct diff_log** log,
{
log_msg(LOG_INFO, "error processing diff file");
region_destroy(data->region);
+ fclose(df);
return 0;
}
startpos = ftello(df);
if(startpos == -1) {
log_msg(LOG_INFO, "could not ftello: %s.", strerror(errno));
region_destroy(data->region);
+ fclose(df);
return 0;
}
}
diff --git a/usr.sbin/nsd/ipc.c b/usr.sbin/nsd/ipc.c
index 157e4185c2e..b2911e39f6b 100644
--- a/usr.sbin/nsd/ipc.c
+++ b/usr.sbin/nsd/ipc.c
@@ -396,10 +396,10 @@ parent_handle_child_command(netio_type *ATTR_UNUSED(netio),
/* read rest later */
return;
}
- /* read the acl number */
+ /* read the acl numbers */
got_acl = data->got_bytes - sizeof(data->total_bytes) - data->total_bytes;
if((len = read(handler->fd, (char*)&data->acl_num+got_acl,
- sizeof(data->acl_num)-got_acl)) == -1 ) {
+ sizeof(data->acl_num)+sizeof(data->acl_xfr)-got_acl)) == -1 ) {
log_msg(LOG_ERR, "handle_child_command: read: %s",
strerror(errno));
return;
@@ -411,7 +411,7 @@ parent_handle_child_command(netio_type *ATTR_UNUSED(netio),
}
got_acl += len;
data->got_bytes += len;
- if(got_acl >= (int)sizeof(data->acl_num)) {
+ if(got_acl >= (int)(sizeof(data->acl_num)+sizeof(data->acl_xfr))) {
uint16_t len = htons(data->total_bytes);
DEBUG(DEBUG_IPC,2, (LOG_INFO,
"main fwd passed packet write %d", (int)data->got_bytes));
@@ -426,7 +426,9 @@ parent_handle_child_command(netio_type *ATTR_UNUSED(netio),
!write_socket(*data->xfrd_sock, buffer_begin(data->packet),
data->total_bytes) ||
!write_socket(*data->xfrd_sock, &data->acl_num,
- sizeof(data->acl_num))) {
+ sizeof(data->acl_num)) ||
+ !write_socket(*data->xfrd_sock, &data->acl_xfr,
+ sizeof(data->acl_xfr))) {
log_msg(LOG_ERR, "error in ipc fwd main2xfrd: %s",
strerror(errno));
}
@@ -595,7 +597,7 @@ xfrd_send_quit_req(xfrd_state_t* xfrd)
xfrd->ipc_handler.event_types &= (~NETIO_EVENT_WRITE);
xfrd->sending_zone_state = 0;
DEBUG(DEBUG_IPC,1, (LOG_INFO, "xfrd: ipc send ackreload(quit)"));
- if(write_socket(xfrd->ipc_handler.fd, &cmd, sizeof(cmd)) == -1) {
+ if(!write_socket(xfrd->ipc_handler.fd, &cmd, sizeof(cmd))) {
log_msg(LOG_ERR, "xfrd: error writing ack to main: %s",
strerror(errno));
}
@@ -723,6 +725,7 @@ xfrd_handle_ipc_read(netio_handler_type *handler, xfrd_state_t* xfrd)
if(xfrd->ipc_conn->is_reading==2) {
buffer_type* tmp = xfrd->ipc_pass;
uint32_t acl_num;
+ int32_t acl_xfr;
/* read acl_num */
int ret = conn_read(xfrd->ipc_conn);
if(ret == -1) {
@@ -737,7 +740,8 @@ xfrd_handle_ipc_read(netio_handler_type *handler, xfrd_state_t* xfrd)
xfrd->ipc_conn->packet = tmp;
xfrd->ipc_conn->is_reading = 0;
acl_num = buffer_read_u32(xfrd->ipc_pass);
- xfrd_handle_passed_packet(xfrd->ipc_conn->packet, acl_num);
+ acl_xfr = (int32_t)buffer_read_u32(xfrd->ipc_pass);
+ xfrd_handle_passed_packet(xfrd->ipc_conn->packet, acl_num, acl_xfr);
return;
}
if(xfrd->ipc_conn->is_reading) {
@@ -761,7 +765,7 @@ xfrd_handle_ipc_read(netio_handler_type *handler, xfrd_state_t* xfrd)
xfrd->ipc_pass = xfrd->ipc_conn->packet;
xfrd->ipc_conn->packet = tmp;
xfrd->ipc_conn->total_bytes = sizeof(xfrd->ipc_conn->msglen);
- xfrd->ipc_conn->msglen = sizeof(uint32_t);
+ xfrd->ipc_conn->msglen = 2*sizeof(uint32_t);
buffer_clear(xfrd->ipc_conn->packet);
buffer_set_limit(xfrd->ipc_conn->packet, xfrd->ipc_conn->msglen);
}
diff --git a/usr.sbin/nsd/ipc.h b/usr.sbin/nsd/ipc.h
index bcdd09eb758..0bd02e32b72 100644
--- a/usr.sbin/nsd/ipc.h
+++ b/usr.sbin/nsd/ipc.h
@@ -34,6 +34,7 @@ struct main_ipc_handler_data
size_t got_bytes;
uint16_t total_bytes;
uint32_t acl_num;
+ int32_t acl_xfr;
/* writing data, connection and state */
uint8_t busy_writing_zone_state;
diff --git a/usr.sbin/nsd/options.c b/usr.sbin/nsd/options.c
index 5fd82666873..60dbef010d7 100644
--- a/usr.sbin/nsd/options.c
+++ b/usr.sbin/nsd/options.c
@@ -13,10 +13,8 @@
#include "options.h"
#include "query.h"
#include "tsig.h"
-#include "difffile.h"
#include "configyyrename.h"
-#include "configparser.h"
nsd_options_t* nsd_options = 0;
config_parser_state_t* cfg_parser = 0;
extern FILE* c_in, *c_out;
@@ -299,37 +297,92 @@ int acl_check_incoming(acl_options_t* acl, struct query* q,
return found_match;
}
+#ifdef INET6
+int acl_addr_matches_ipv6host(acl_options_t* acl, struct sockaddr_storage* addr_storage, unsigned int port)
+{
+ struct sockaddr_in6* addr = (struct sockaddr_in6*)addr_storage;
+ if(acl->port != 0 && acl->port != port)
+ return 0;
+ switch(acl->rangetype) {
+ case acl_range_mask:
+ case acl_range_subnet:
+ if(!acl_addr_match_mask((uint32_t*)&acl->addr.addr6, (uint32_t*)&addr->sin6_addr,
+ (uint32_t*)&acl->range_mask.addr6, sizeof(struct in6_addr)))
+ return 0;
+ break;
+ case acl_range_minmax:
+ if(!acl_addr_match_range((uint32_t*)&acl->addr.addr6, (uint32_t*)&addr->sin6_addr,
+ (uint32_t*)&acl->range_mask.addr6, sizeof(struct in6_addr)))
+ return 0;
+ break;
+ case acl_range_single:
+ default:
+ if(memcmp(&addr->sin6_addr, &acl->addr.addr6,
+ sizeof(struct in6_addr)) != 0)
+ return 0;
+ break;
+ }
+ return 1;
+}
+#endif
+
+int acl_addr_matches_ipv4host(acl_options_t* acl, struct sockaddr_in* addr, unsigned int port)
+{
+ if(acl->port != 0 && acl->port != port)
+ return 0;
+ switch(acl->rangetype) {
+ case acl_range_mask:
+ case acl_range_subnet:
+ if(!acl_addr_match_mask((uint32_t*)&acl->addr.addr, (uint32_t*)&addr->sin_addr,
+ (uint32_t*)&acl->range_mask.addr, sizeof(struct in_addr)))
+ return 0;
+ break;
+ case acl_range_minmax:
+ if(!acl_addr_match_range((uint32_t*)&acl->addr.addr, (uint32_t*)&addr->sin_addr,
+ (uint32_t*)&acl->range_mask.addr, sizeof(struct in_addr)))
+ return 0;
+ break;
+ case acl_range_single:
+ default:
+ if(memcmp(&addr->sin_addr, &acl->addr.addr,
+ sizeof(struct in_addr)) != 0)
+ return 0;
+ break;
+ }
+ return 1;
+}
+
+int acl_addr_matches_host(acl_options_t* acl, acl_options_t* host)
+{
+ if(acl->is_ipv6)
+ {
+#ifdef INET6
+ struct sockaddr_storage* addr = (struct sockaddr_storage*)&host->addr;
+ if(!host->is_ipv6) return 0;
+ return acl_addr_matches_ipv6host(acl, addr, host->port);
+#else
+ return 0; /* no inet6, no match */
+#endif
+ }
+ else
+ {
+ struct sockaddr_in* addr = (struct sockaddr_in*)&host->addr;
+ if(host->is_ipv6) return 0;
+ return acl_addr_matches_ipv4host(acl, addr, host->port);
+ }
+ /* ENOTREACH */
+ return 0;
+}
+
int acl_addr_matches(acl_options_t* acl, struct query* q)
{
if(acl->is_ipv6)
{
#ifdef INET6
- struct sockaddr_storage* addr_storage = (struct sockaddr_storage*)&q->addr;
- struct sockaddr_in6* addr = (struct sockaddr_in6*)&q->addr;
- if(addr_storage->ss_family != AF_INET6)
- return 0;
- if(acl->port != 0 && acl->port != ntohs(addr->sin6_port))
+ struct sockaddr_storage* addr = (struct sockaddr_storage*)&q->addr;
+ if(addr->ss_family != AF_INET6)
return 0;
- switch(acl->rangetype) {
- case acl_range_mask:
- case acl_range_subnet:
- if(!acl_addr_match_mask((uint32_t*)&acl->addr.addr6, (uint32_t*)&addr->sin6_addr,
- (uint32_t*)&acl->range_mask.addr6, sizeof(struct in6_addr)))
- return 0;
- break;
- case acl_range_minmax:
- if(!acl_addr_match_range((uint32_t*)&acl->addr.addr6, (uint32_t*)&addr->sin6_addr,
- (uint32_t*)&acl->range_mask.addr6, sizeof(struct in6_addr)))
- return 0;
- break;
- case acl_range_single:
- default:
- if(memcmp(&addr->sin6_addr, &acl->addr.addr6,
- sizeof(struct in6_addr)) != 0)
- return 0;
- break;
- }
- return 1;
+ return acl_addr_matches_ipv6host(acl, addr, ntohs(((struct sockaddr_in6*)addr)->sin6_port));
#else
return 0; /* no inet6, no match */
#endif
@@ -339,28 +392,7 @@ int acl_addr_matches(acl_options_t* acl, struct query* q)
struct sockaddr_in* addr = (struct sockaddr_in*)&q->addr;
if(addr->sin_family != AF_INET)
return 0;
- if(acl->port != 0 && acl->port != ntohs(addr->sin_port))
- return 0;
- switch(acl->rangetype) {
- case acl_range_mask:
- case acl_range_subnet:
- if(!acl_addr_match_mask((uint32_t*)&acl->addr.addr, (uint32_t*)&addr->sin_addr,
- (uint32_t*)&acl->range_mask.addr, sizeof(struct in_addr)))
- return 0;
- break;
- case acl_range_minmax:
- if(!acl_addr_match_range((uint32_t*)&acl->addr.addr, (uint32_t*)&addr->sin_addr,
- (uint32_t*)&acl->range_mask.addr, sizeof(struct in_addr)))
- return 0;
- break;
- case acl_range_single:
- default:
- if(memcmp(&addr->sin_addr, &acl->addr.addr,
- sizeof(struct in_addr)) != 0)
- return 0;
- break;
- }
- return 1;
+ return acl_addr_matches_ipv4host(acl, addr, ntohs(addr->sin_port));
}
/* ENOTREACH */
return 0;
diff --git a/usr.sbin/nsd/options.h b/usr.sbin/nsd/options.h
index 282027aad90..6da56fe9e4f 100644
--- a/usr.sbin/nsd/options.h
+++ b/usr.sbin/nsd/options.h
@@ -188,6 +188,7 @@ void key_options_tsig_add(nsd_options_t* opt);
/* the reason why (the acl) is returned too (or NULL) */
int acl_check_incoming(acl_options_t* acl, struct query* q,
acl_options_t** reason);
+int acl_addr_matches_host(acl_options_t* acl, acl_options_t* host);
int acl_addr_matches(acl_options_t* acl, struct query* q);
int acl_key_matches(acl_options_t* acl, struct query* q);
int acl_addr_match_mask(uint32_t* a, uint32_t* b, uint32_t* mask, size_t sz);
diff --git a/usr.sbin/nsd/tsig.c b/usr.sbin/nsd/tsig.c
index 7fa7b957f2c..be1ca85ce44 100644
--- a/usr.sbin/nsd/tsig.c
+++ b/usr.sbin/nsd/tsig.c
@@ -16,7 +16,6 @@
#include "tsig-openssl.h"
#include "dns.h"
#include "packet.h"
-#include "query.h"
static region_type *tsig_region;
diff --git a/usr.sbin/nsd/xfrd-notify.c b/usr.sbin/nsd/xfrd-notify.c
index 21cc22694a6..0aa5c2c6cd7 100644
--- a/usr.sbin/nsd/xfrd-notify.c
+++ b/usr.sbin/nsd/xfrd-notify.c
@@ -11,7 +11,7 @@
#include <assert.h>
#include <string.h>
#include <unistd.h>
-#include <errno.h>
+
#include "xfrd-notify.h"
#include "xfrd.h"
#include "xfrd-tcp.h"
diff --git a/usr.sbin/nsd/xfrd.c b/usr.sbin/nsd/xfrd.c
index 8bd12502fd9..7cb0ebbdcc0 100644
--- a/usr.sbin/nsd/xfrd.c
+++ b/usr.sbin/nsd/xfrd.c
@@ -200,8 +200,8 @@ xfrd_shutdown()
close(zone->zone_handler.fd);
zone->zone_handler.fd = -1;
}
- close_notify_fds(xfrd->notify_zones);
}
+ close_notify_fds(xfrd->notify_zones);
/* shouldn't we clean up memory used by xfrd process */
DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd shutdown complete"));
@@ -869,6 +869,7 @@ xfrd_send_udp(acl_options_t* acl, buffer_type* packet, acl_options_t* ifc)
log_msg(LOG_ERR, "xfrd: cannot bind outgoing interface '%s' to "
"udp socket: No matching ip addresses found",
ifc->ip_address_spec);
+ close(fd);
return -1;
}
@@ -880,6 +881,7 @@ xfrd_send_udp(acl_options_t* acl, buffer_type* packet, acl_options_t* ifc)
{
log_msg(LOG_ERR, "xfrd: sendto %s failed %s",
acl->ip_address_spec, strerror(errno));
+ close(fd);
return -1;
}
return fd;
@@ -1500,7 +1502,8 @@ xfrd_handle_reload(netio_type *ATTR_UNUSED(netio),
}
void
-xfrd_handle_passed_packet(buffer_type* packet, int acl_num)
+xfrd_handle_passed_packet(buffer_type* packet,
+ int acl_num, int acl_num_xfr)
{
uint8_t qnamebuf[MAXDOMAINLEN];
uint16_t qtype, qclass;
@@ -1545,7 +1548,11 @@ xfrd_handle_passed_packet(buffer_type* packet, int acl_num)
xfrd_set_refresh_now(zone);
}
}
- next = find_same_master_notify(zone, acl_num);
+ /* First, see if our notifier has a match in provide-xfr */
+ if (acl_find_num(zone->zone_options->request_xfr, acl_num_xfr))
+ next = acl_num_xfr;
+ else /* If not, find master that matches notifiers ACL entry */
+ next = find_same_master_notify(zone, acl_num);
if(next != -1) {
zone->next_master = next;
DEBUG(DEBUG_XFRD,1, (LOG_INFO,
@@ -1602,7 +1609,7 @@ find_same_master_notify(xfrd_zone_t* zone, int acl_num_nfy)
return -1;
while(master)
{
- if(acl_same_host(nfy_acl, master))
+ if(acl_addr_matches_host(nfy_acl, master))
return num;
master = master->next;
num++;
diff --git a/usr.sbin/nsd/xfrd.h b/usr.sbin/nsd/xfrd.h
index d332ec0af8b..49337035277 100644
--- a/usr.sbin/nsd/xfrd.h
+++ b/usr.sbin/nsd/xfrd.h
@@ -262,8 +262,10 @@ void xfrd_tsig_sign_request(buffer_type* packet, struct tsig_record* tsig,
void xfrd_handle_incoming_soa(xfrd_zone_t* zone, xfrd_soa_t* soa,
time_t acquired);
/* handle a packet passed along ipc route. acl is the one that accepted
- the packet. The packet is the network blob received. */
-void xfrd_handle_passed_packet(buffer_type* packet, int acl_num);
+ the packet. The packet is the network blob received. acl_xfr is
+ provide-xfr acl matching notify sender or -1 */
+void xfrd_handle_passed_packet(buffer_type* packet,
+ int acl_num, int acl_xfr);
/* send expiry notify for all zones to nsd (sets all dirty). */
void xfrd_send_expy_all_zones();