summaryrefslogtreecommitdiff
path: root/usr.sbin/nsd/xfrd.h
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/nsd/xfrd.h')
-rw-r--r--usr.sbin/nsd/xfrd.h295
1 files changed, 295 insertions, 0 deletions
diff --git a/usr.sbin/nsd/xfrd.h b/usr.sbin/nsd/xfrd.h
new file mode 100644
index 00000000000..9b34322b67b
--- /dev/null
+++ b/usr.sbin/nsd/xfrd.h
@@ -0,0 +1,295 @@
+/*
+ * xfrd.h - XFR (transfer) Daemon header file. Coordinates SOA updates.
+ *
+ * Copyright (c) 2001-2006, NLnet Labs. All rights reserved.
+ *
+ * See LICENSE for the license.
+ *
+ */
+
+#ifndef XFRD_H
+#define XFRD_H
+
+#include <config.h>
+#include "netio.h"
+#include "rbtree.h"
+#include "namedb.h"
+#include "options.h"
+#include "dns.h"
+#include "tsig.h"
+
+struct nsd;
+struct region;
+struct buffer;
+struct xfrd_tcp;
+struct xfrd_tcp_set;
+struct notify_zone_t;
+typedef struct xfrd_state xfrd_state_t;
+typedef struct xfrd_zone xfrd_zone_t;
+typedef struct xfrd_soa xfrd_soa_t;
+/*
+ * The global state for the xfrd daemon process.
+ * The time_t times are epochs in secs since 1970, absolute times.
+ */
+struct xfrd_state {
+ /* time when daemon was last started */
+ time_t xfrd_start_time;
+ struct region* region;
+ netio_type* netio;
+ struct nsd* nsd;
+
+ struct xfrd_tcp_set* tcp_set;
+ /* packet buffer for udp packets */
+ struct buffer* packet;
+ /* udp waiting list */
+ struct xfrd_zone *udp_waiting_first, *udp_waiting_last;
+ /* number of udp sockets (for sending queries) in use */
+ size_t udp_use_num;
+
+ /* current time is cached */
+ uint8_t got_time;
+ time_t current_time;
+
+ /* timer for NSD reload */
+ struct timespec reload_timeout;
+ netio_handler_type reload_handler;
+ /* last reload must have caught all zone updates before this time */
+ time_t reload_cmd_last_sent;
+ uint8_t can_send_reload;
+
+ /* communication channel with server_main */
+ netio_handler_type ipc_handler;
+ uint8_t ipc_is_soa;
+ uint8_t parent_soa_info_pass;
+ struct xfrd_tcp *ipc_conn;
+ struct buffer* ipc_pass;
+ /* sending ipc to server_main */
+ struct xfrd_tcp *ipc_conn_write;
+ uint8_t need_to_send_reload;
+ uint8_t need_to_send_quit;
+ uint8_t sending_zone_state;
+ uint8_t ipc_send_blocked;
+ stack_type* dirty_zones; /* stack of xfrd_zone* */
+
+ /* xfrd shutdown flag */
+ uint8_t shutdown;
+
+ /* tree of zones, by apex name, contains xfrd_zone_t*. Only secondary zones. */
+ rbtree_t *zones;
+
+ /* tree of zones, by apex name, contains notify_zone_t*. All zones. */
+ rbtree_t *notify_zones;
+ /* number of notify_zone_t active using UDP socket */
+ int notify_udp_num;
+ /* first and last notify_zone_t* entries waiting for a UDP socket */
+ struct notify_zone_t *notify_waiting_first, *notify_waiting_last;
+};
+
+/*
+ * XFR daemon SOA information kept in network format.
+ * This is in packet order.
+ */
+struct xfrd_soa {
+ /* name of RR is zone apex dname */
+ uint16_t type; /* = TYPE_SOA */
+ uint16_t klass; /* = CLASS_IN */
+ uint32_t ttl;
+ uint16_t rdata_count; /* = 7 */
+ /* format is 1 octet length, + wireformat dname.
+ one more octet since parse_dname_wire_from_packet needs it.
+ maximum size is allocated to avoid memory alloc/free. */
+ uint8_t prim_ns[MAXDOMAINLEN + 2];
+ uint8_t email[MAXDOMAINLEN + 2];
+ uint32_t serial;
+ uint32_t refresh;
+ uint32_t retry;
+ uint32_t expire;
+ uint32_t minimum;
+};
+
+
+/*
+ * XFRD state for a single zone
+ */
+struct xfrd_zone {
+ rbnode_t node;
+
+ /* name of the zone */
+ const dname_type* apex;
+ const char* apex_str;
+
+ /* Three types of soas:
+ * NSD: in use by running server
+ * disk: stored on disk in db/diff file
+ * notified: from notification, could be available on a master.
+ * And the time the soa was acquired (start time for timeouts).
+ * If the time==0, no SOA is available.
+ */
+ xfrd_soa_t soa_nsd;
+ time_t soa_nsd_acquired;
+ xfrd_soa_t soa_disk;
+ time_t soa_disk_acquired;
+ xfrd_soa_t soa_notified;
+ time_t soa_notified_acquired;
+
+ enum xfrd_zone_state {
+ xfrd_zone_ok,
+ xfrd_zone_refreshing,
+ xfrd_zone_expired
+ } state;
+
+ /* if state is dirty it needs to be sent to server_main.
+ * it is also on the dirty_stack. Not saved on disk. */
+ uint8_t dirty;
+
+ /* master to try to transfer from, number for persistence */
+ acl_options_t* master;
+ int master_num;
+ int next_master; /* -1 or set by notify where to try next */
+ /* round of xfrattempts, -1 is waiting for timeout */
+ int round_num;
+ zone_options_t* zone_options;
+ int fresh_xfr_timeout;
+
+ /* handler for timeouts */
+ struct timespec timeout;
+ netio_handler_type zone_handler;
+
+ /* tcp connection zone is using, or -1 */
+ int tcp_conn;
+ /* zone is waiting for a tcp connection */
+ uint8_t tcp_waiting;
+ /* next zone in waiting list */
+ xfrd_zone_t* tcp_waiting_next;
+ /* zone is waiting for a udp connection (tcp is preferred) */
+ uint8_t udp_waiting;
+ /* next zone in waiting list for UDP */
+ xfrd_zone_t* udp_waiting_next;
+
+ /* xfr message handling data */
+ /* query id */
+ uint16_t query_id;
+ uint32_t msg_seq_nr; /* number of messages already handled */
+ uint32_t msg_old_serial, msg_new_serial; /* host byte order */
+ size_t msg_rr_count;
+ uint8_t msg_is_ixfr; /* 1:IXFR detected. 2:middle IXFR SOA seen. */
+#ifdef TSIG
+ tsig_record_type tsig; /* tsig state for IXFR/AXFR */
+#endif
+};
+
+enum xfrd_packet_result {
+ xfrd_packet_bad, /* drop the packet/connection */
+ xfrd_packet_more, /* more packets to follow on tcp */
+ xfrd_packet_notimpl, /* server responded with NOTIMPL or FORMATERR */
+ xfrd_packet_tcp, /* try tcp connection */
+ xfrd_packet_transfer, /* server responded with transfer*/
+ xfrd_packet_newlease /* no changes, soa OK */
+};
+
+/*
+ Division of the (portably: 1024) max number of sockets that can be open.
+ The sum of the below numbers should be below the user limit for sockets
+ open, or you see errors in your logfile.
+ And it should be below FD_SETSIZE, to be able to select() on replies.
+ Note that also some sockets are used for writing the ixfr.db, xfrd.state
+ files and for the pipes to the main parent process.
+*/
+#define XFRD_MAX_TCP 50 /* max number of TCP AXFR/IXFR concurrent connections.*/
+ /* Each entry has 64Kb buffer preallocated.*/
+#define XFRD_MAX_UDP 100 /* max number of UDP sockets at a time for IXFR */
+#define XFRD_MAX_UDP_NOTIFY 50 /* max concurrent UDP sockets for NOTIFY */
+
+extern xfrd_state_t* xfrd;
+
+/* start xfrd, new start. Pass socket to server_main. */
+void xfrd_init(int socket, struct nsd* nsd);
+
+/* get the current time epoch. Cached for speed. */
+time_t xfrd_time();
+
+/*
+ * Handle final received packet from network.
+ * returns enum of packet discovery results
+ */
+enum xfrd_packet_result xfrd_handle_received_xfr_packet(
+ xfrd_zone_t* zone, buffer_type* packet);
+
+/* set timer to specific value */
+void xfrd_set_timer(xfrd_zone_t* zone, time_t t);
+/* set refresh timer of zone to refresh at time now */
+void xfrd_set_refresh_now(xfrd_zone_t* zone);
+/* unset the timer - no more timeouts, for when zone is queued */
+void xfrd_unset_timer(xfrd_zone_t* zone);
+
+/*
+ * Make a new request to next master server.
+ * uses next_master if set (and a fresh set of rounds).
+ * otherwised, starts new round of requests if none started already.
+ * starts next round of requests if at last master.
+ * if too many rounds of requests, sets timer for next retry.
+ */
+void xfrd_make_request(xfrd_zone_t* zone);
+
+/*
+ * send packet via udp (returns UDP fd source socket) to acl addr.
+ * returns -1 on failure.
+ */
+int xfrd_send_udp(acl_options_t* acl, buffer_type* packet, acl_options_t* ifc);
+
+/*
+ * read from udp port packet into buffer, returns 0 on failure
+ */
+int xfrd_udp_read_packet(buffer_type* packet, int fd);
+
+/*
+ * Release udp socket that a zone is using
+ */
+void xfrd_udp_release(xfrd_zone_t* zone);
+
+/*
+ * Get a static buffer for temporary use (to build a packet).
+ */
+struct buffer* xfrd_get_temp_buffer();
+
+/*
+ * TSIG sign outgoing request. Call if acl has a key.
+ */
+#ifdef TSIG
+void xfrd_tsig_sign_request(buffer_type* packet, struct tsig_record* tsig,
+ acl_options_t* acl);
+#endif
+
+/* handle incoming soa information (NSD is running it, time acquired=guess).
+ Pass soa=NULL,acquired=now if NSD has nothing loaded for the zone
+ (i.e. zonefile was deleted). */
+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);
+
+/* send expiry notify for all zones to nsd (sets all dirty). */
+void xfrd_send_expy_all_zones();
+
+/* try to reopen the logfile. */
+void xfrd_reopen_logfile();
+
+/* copy SOA info from rr to soa struct. */
+void xfrd_copy_soa(xfrd_soa_t* soa, rr_type* rr);
+
+/* check for failed updates - it is assumed that now the reload has
+ finished, and all zone SOAs have been sent. */
+void xfrd_check_failed_updates();
+
+/*
+ * Prepare zones for a reload, this sets the times on the zones to be
+ * before the current time, so the reload happens after.
+ */
+void xfrd_prepare_zones_for_reload();
+
+/* Bind a local interface to a socket descriptor, return 1 on success */
+int xfrd_bind_local_interface(int sockd, acl_options_t* ifc,
+ acl_options_t* acl, int tcp);
+
+#endif /* XFRD_H */