--- embedaddon/dnsmasq/src/dnsmasq.h 2021/03/17 00:56:46 1.1.1.4 +++ embedaddon/dnsmasq/src/dnsmasq.h 2023/09/27 11:02:07 1.1.1.5 @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2022 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -14,7 +14,7 @@ along with this program. If not, see . */ -#define COPYRIGHT "Copyright (c) 2000-2021 Simon Kelley" +#define COPYRIGHT "Copyright (c) 2000-2022 Simon Kelley" /* We do defines that influence behavior of stdio.h, so complain if included too early. */ @@ -95,11 +95,7 @@ typedef unsigned long long u64; #if defined(HAVE_SOLARIS_NETWORK) # include #endif -#if defined(HAVE_POLL_H) -# include -#else -# include -#endif +#include #include #include #include @@ -111,6 +107,7 @@ typedef unsigned long long u64; #endif #include #include +#include #include #include #include @@ -136,6 +133,7 @@ typedef unsigned long long u64; #include #include #include +#include #ifndef HAVE_LINUX_NETWORK # include #endif @@ -273,7 +271,18 @@ struct event_desc { #define OPT_IGNORE_CLID 59 #define OPT_SINGLE_PORT 60 #define OPT_LEASE_RENEW 61 -#define OPT_LAST 62 +#define OPT_LOG_DEBUG 62 +#define OPT_UMBRELLA 63 +#define OPT_UMBRELLA_DEVID 64 +#define OPT_CMARK_ALST_EN 65 +#define OPT_QUIET_TFTP 66 +#define OPT_FILTER_A 67 +#define OPT_FILTER_AAAA 68 +#define OPT_STRIP_ECS 69 +#define OPT_STRIP_MAC 70 +#define OPT_NORR 71 +#define OPT_NO_IDENT 72 +#define OPT_LAST 73 #define OPTION_BITS (sizeof(unsigned int)*8) #define OPTION_SIZE ( (OPT_LAST/OPTION_BITS)+((OPT_LAST%OPTION_BITS)!=0) ) @@ -281,11 +290,13 @@ struct event_desc { #define option_val(x) ((1u) << ((x) % OPTION_BITS)) #define option_bool(x) (option_var(x) & option_val(x)) -/* extra flags for my_syslog, we use a couple of facilities since they are known - not to occupy the same bits as priorities, no matter how syslog.h is set up. */ +/* extra flags for my_syslog, we use facilities since they are known + not to occupy the same bits as priorities, no matter how syslog.h is set up. + MS_DEBUG messages are suppressed unless --log-debug is set. */ #define MS_TFTP LOG_USER #define MS_DHCP LOG_DAEMON #define MS_SCRIPT LOG_MAIL +#define MS_DEBUG LOG_NEWS /* Note that this is used widely as a container for IPv4/IPv6 addresses, so for that reason, was well as to avoid wasting memory in almost every @@ -321,12 +332,14 @@ union all_addr { /* for log_query */ struct { unsigned short keytag, algo, digest, rcode; + int ede; } log; }; struct bogus_addr { - struct in_addr addr; + int is6, prefix; + union all_addr addr; struct bogus_addr *next; }; @@ -427,10 +440,17 @@ struct host_record { struct host_record *next; }; +#define IN4 1 +#define IN6 2 +#define INP4 4 +#define INP6 8 + struct interface_name { char *name; /* domain name */ char *intr; /* interface name */ - int family; /* AF_INET, AF_INET6 or zero for both */ + int flags; + struct in_addr proto4; + struct in6_addr proto6; struct addrlist *addr; struct interface_name *next; }; @@ -490,9 +510,10 @@ struct crec { #define F_NO_RR (1u<<25) #define F_IPSET (1u<<26) #define F_NOEXTRA (1u<<27) -#define F_SERVFAIL (1u<<28) /* currently unused. */ +#define F_DOMAINSRV (1u<<28) #define F_RCODE (1u<<29) #define F_SRV (1u<<30) +#define F_STALE (1u<<31) #define UID_NONE 0 /* Values of uid in crecs with F_CONFIG bit set. */ @@ -516,23 +537,24 @@ union mysockaddr { #define IFACE_PERMANENT 4 -#define SERV_FROM_RESOLV 1 /* 1 for servers from resolv, 0 for command line. */ -#define SERV_NO_ADDR 2 /* no server, this domain is local only */ -#define SERV_LITERAL_ADDRESS 4 /* addr is the answer, not the server */ -#define SERV_HAS_DOMAIN 8 /* server for one domain only */ -#define SERV_HAS_SOURCE 16 /* source address defined */ -#define SERV_FOR_NODOTS 32 /* server for names with no domain part only */ -#define SERV_WARNED_RECURSIVE 64 /* avoid warning spam */ -#define SERV_FROM_DBUS 128 /* 1 if source is DBus */ -#define SERV_MARK 256 /* for mark-and-delete */ -#define SERV_TYPE (SERV_HAS_DOMAIN | SERV_FOR_NODOTS) -#define SERV_COUNTED 512 /* workspace for log code */ -#define SERV_USE_RESOLV 1024 /* forward this domain in the normal way */ -#define SERV_NO_REBIND 2048 /* inhibit dns-rebind protection */ -#define SERV_FROM_FILE 4096 /* read from --servers-file */ -#define SERV_LOOP 8192 /* server causes forwarding loop */ -#define SERV_DO_DNSSEC 16384 /* Validate DNSSEC when using this server */ -#define SERV_GOT_TCP 32768 /* Got some data from the TCP connection */ +/* The actual values here matter, since we sort on them to get records in the order + IPv6 addr, IPv4 addr, all zero return, resolvconf servers, upstream server, no-data return */ +#define SERV_LITERAL_ADDRESS 1 /* addr is the answer, or NoDATA is the answer, depending on the next four flags */ +#define SERV_USE_RESOLV 2 /* forward this domain in the normal way */ +#define SERV_ALL_ZEROS 4 /* return all zeros for A and AAAA */ +#define SERV_4ADDR 8 /* addr is IPv4 */ +#define SERV_6ADDR 16 /* addr is IPv6 */ +#define SERV_HAS_SOURCE 32 /* source address defined */ +#define SERV_FOR_NODOTS 64 /* server for names with no domain part only */ +#define SERV_WARNED_RECURSIVE 128 /* avoid warning spam */ +#define SERV_FROM_DBUS 256 /* 1 if source is DBus */ +#define SERV_MARK 512 /* for mark-and-delete and log code */ +#define SERV_WILDCARD 1024 /* domain has leading '*' */ +#define SERV_FROM_RESOLV 2048 /* 1 for servers from resolv, 0 for command line. */ +#define SERV_FROM_FILE 4096 /* read from --servers-file */ +#define SERV_LOOP 8192 /* server causes forwarding loop */ +#define SERV_DO_DNSSEC 16384 /* Validate DNSSEC when using this server */ +#define SERV_GOT_TCP 32768 /* Got some data from the TCP connection */ struct serverfd { int fd; @@ -543,30 +565,76 @@ struct serverfd { }; struct randfd { + struct server *serv; int fd; - unsigned short refcount, family; + unsigned short refcount; /* refcount == 0xffff means overflow record. */ }; - + +struct randfd_list { + struct randfd *rfd; + struct randfd_list *next; +}; + + struct server { + u16 flags, domain_len; + char *domain; + struct server *next; + int serial, arrayposn; + int last_server; union mysockaddr addr, source_addr; char interface[IF_NAMESIZE+1]; + unsigned int ifindex; /* corresponding to interface, above */ struct serverfd *sfd; - char *domain; /* set if this server only handles a domain. */ - int flags, tcpfd, edns_pktsz; + int tcpfd, edns_pktsz; time_t pktsz_reduced; - unsigned int queries, failed_queries; + unsigned int queries, failed_queries, nxdomain_replies, retrys; + unsigned int query_latency, mma_latency; + time_t forwardtime; + int forwardcount; #ifdef HAVE_LOOP u32 uid; #endif - struct server *next; }; +/* First four fields must match struct server in next three definitions.. */ +struct serv_addr4 { + u16 flags, domain_len; + char *domain; + struct server *next; + struct in_addr addr; +}; + +struct serv_addr6 { + u16 flags, domain_len; + char *domain; + struct server *next; + struct in6_addr addr; +}; + +struct serv_local { + u16 flags, domain_len; + char *domain; + struct server *next; +}; + +struct rebind_domain { + char *domain; + struct rebind_domain *next; +}; + struct ipsets { char **sets; char *domain; struct ipsets *next; }; +struct allowlist { + u32 mark, mask; + char **patterns; + struct allowlist *next; +}; + struct irec { union mysockaddr addr; struct in_addr netmask; /* only valid for IPv4 */ @@ -602,6 +670,7 @@ struct resolvc { struct resolvc *next; int is_default, logged; time_t mtime; + ino_t ino; char *name; #ifdef HAVE_INOTIFY int wd; /* inotify watch descriptor */ @@ -620,37 +689,59 @@ struct hostsfile { struct hostsfile *next; int flags; char *fname; + unsigned int index; /* matches to cache entries for logging */ +}; + +struct dyndir { + struct dyndir *next; + struct hostsfile *files; + int flags; + char *dname; #ifdef HAVE_INOTIFY int wd; /* inotify watch descriptor */ #endif - unsigned int index; /* matches to cache entries for logging */ }; /* packet-dump flags */ -#define DUMP_QUERY 0x0001 -#define DUMP_REPLY 0x0002 -#define DUMP_UP_QUERY 0x0004 -#define DUMP_UP_REPLY 0x0008 -#define DUMP_SEC_QUERY 0x0010 -#define DUMP_SEC_REPLY 0x0020 -#define DUMP_BOGUS 0x0040 -#define DUMP_SEC_BOGUS 0x0080 +#define DUMP_QUERY 0x0001 +#define DUMP_REPLY 0x0002 +#define DUMP_UP_QUERY 0x0004 +#define DUMP_UP_REPLY 0x0008 +#define DUMP_SEC_QUERY 0x0010 +#define DUMP_SEC_REPLY 0x0020 +#define DUMP_BOGUS 0x0040 +#define DUMP_SEC_BOGUS 0x0080 +#define DUMP_DHCP 0x1000 +#define DUMP_DHCPV6 0x2000 +#define DUMP_RA 0x4000 +#define DUMP_TFTP 0x8000 - /* DNSSEC status values. */ -#define STAT_SECURE 1 -#define STAT_INSECURE 2 -#define STAT_BOGUS 3 -#define STAT_NEED_DS 4 -#define STAT_NEED_KEY 5 -#define STAT_TRUNCATED 6 -#define STAT_SECURE_WILDCARD 7 -#define STAT_OK 8 -#define STAT_ABANDONED 9 +#define STAT_SECURE 0x10000 +#define STAT_INSECURE 0x20000 +#define STAT_BOGUS 0x30000 +#define STAT_NEED_DS 0x40000 +#define STAT_NEED_KEY 0x50000 +#define STAT_TRUNCATED 0x60000 +#define STAT_SECURE_WILDCARD 0x70000 +#define STAT_OK 0x80000 +#define STAT_ABANDONED 0x90000 +#define DNSSEC_FAIL_NYV 0x0001 /* key not yet valid */ +#define DNSSEC_FAIL_EXP 0x0002 /* key expired */ +#define DNSSEC_FAIL_INDET 0x0004 /* indetermined */ +#define DNSSEC_FAIL_NOKEYSUP 0x0008 /* no supported key algo. */ +#define DNSSEC_FAIL_NOSIG 0x0010 /* No RRsigs */ +#define DNSSEC_FAIL_NOZONE 0x0020 /* No Zone bit set */ +#define DNSSEC_FAIL_NONSEC 0x0040 /* No NSEC */ +#define DNSSEC_FAIL_NODSSUP 0x0080 /* no supported DS algo. */ +#define DNSSEC_FAIL_NOKEY 0x0100 /* no DNSKEY */ + +#define STAT_ISEQUAL(a, b) (((a) & 0xffff0000) == (b)) + #define FREC_NOREBIND 1 #define FREC_CHECKING_DISABLED 2 -#define FREC_HAS_SUBNET 4 +#define FREC_NO_CACHE 4 #define FREC_DNSKEY_QUERY 8 #define FREC_DS_QUERY 16 #define FREC_AD_QUESTION 32 @@ -659,7 +750,6 @@ struct hostsfile { #define FREC_TEST_PKTSZ 256 #define FREC_HAS_EXTRADATA 512 #define FREC_HAS_PHEADER 1024 -#define FREC_NO_CACHE 2048 #define HASH_SIZE 32 /* SHA-256 digest size */ @@ -673,17 +763,19 @@ struct frec { struct frec_src *next; } frec_src; struct server *sentto; /* NULL means free */ - struct randfd *rfd4; - struct randfd *rfd6; + struct randfd_list *rfds; unsigned short new_id; int forwardall, flags; time_t time; + u32 forward_timestamp; + int forward_delay; unsigned char *hash[HASH_SIZE]; -#ifdef HAVE_DNSSEC - int class, work_counter; struct blockdata *stash; /* Saved reply, whilst we validate */ size_t stash_len; +#ifdef HAVE_DNSSEC + int class, work_counter; struct frec *dependent; /* Query awaiting internally-generated DNSKEY or DS query */ + struct frec *next_dependent; /* list of above. */ struct frec *blocking_query; /* Query which is blocking us. */ #endif struct frec *next; @@ -706,6 +798,7 @@ struct frec { #define ACTION_TFTP 5 #define ACTION_ARP 6 #define ACTION_ARP_DEL 7 +#define ACTION_RELAY_SNOOP 8 #define LEASE_NEW 1 /* newly created */ #define LEASE_CHANGED 2 /* modified */ @@ -896,10 +989,12 @@ struct dhcp_bridge { }; struct cond_domain { - char *domain, *prefix; + char *domain, *prefix; /* prefix is text-prefix on domain name */ + char *interface; /* These two set when domain comes from interface. */ + struct addrlist *al; struct in_addr start, end; struct in6_addr start6, end6; - int is6, indexed; + int is6, indexed, prefixlen; struct cond_domain *next; }; @@ -1004,7 +1099,15 @@ struct dhcp_relay { union all_addr local, server; char *interface; /* Allowable interface for replies from server, and dest for IPv6 multicast */ int iface_index; /* working - interface in which requests arrived, for return */ - struct dhcp_relay *current, *next; + int port; /* Port of relay we forward to. */ +#ifdef HAVE_SCRIPT + struct snoop_record { + struct in6_addr client, prefix; + int prefix_len; + struct snoop_record *next; + } *snoop_records; +#endif + struct dhcp_relay *next; }; extern struct daemon { @@ -1040,15 +1143,25 @@ extern struct daemon { char *lease_change_command; struct iname *if_names, *if_addrs, *if_except, *dhcp_except, *auth_peers, *tftp_interfaces; struct bogus_addr *bogus_addr, *ignore_addr; - struct server *servers; - struct ipsets *ipsets; + struct server *servers, *servers_tail, *local_domains, **serverarray; + struct rebind_domain *no_rebind; + int server_has_wildcard; + int serverarraysz, serverarrayhwm; + struct ipsets *ipsets, *nftsets; + u32 allowlist_mask; + struct allowlist *allowlists; int log_fac; /* log facility */ char *log_file; /* optional log file */ int max_logs; /* queue limit */ + int randport_limit; /* Maximum number of source ports for query. */ int cachesize, ftabsize; int port, query_port, min_port, max_port; unsigned long local_ttl, neg_ttl, max_ttl, min_cache_ttl, max_cache_ttl, auth_ttl, dhcp_ttl, use_dhcp_ttl; char *dns_client_id; + u32 umbrella_org; + u32 umbrella_asset; + u8 umbrella_device[8]; + int host_index; struct hostsfile *addn_hosts; struct dhcp_context *dhcp, *dhcp6; struct ra_interface *ra_interfaces; @@ -1069,7 +1182,8 @@ extern struct daemon { int doing_ra, doing_dhcp6; struct dhcp_netid_list *dhcp_ignore, *dhcp_ignore_names, *dhcp_gen_names; struct dhcp_netid_list *force_broadcast, *bootp_dynamic; - struct hostsfile *dhcp_hosts_file, *dhcp_opts_file, *dynamic_dirs; + struct hostsfile *dhcp_hosts_file, *dhcp_opts_file; + struct dyndir *dynamic_dirs; int dhcp_max, tftp_max, tftp_mtu; int dhcp_server_port, dhcp_client_port; int start_tftp_port, end_tftp_port; @@ -1086,6 +1200,8 @@ extern struct daemon { int dump_mask; unsigned long soa_sn, soa_refresh, soa_retry, soa_expiry; u32 metrics[__METRIC_MAX]; + int fast_retry_time, fast_retry_timeout; + int cache_max_expiry; #ifdef HAVE_DNSSEC struct ds_config *ds; char *timestamp_file; @@ -1095,9 +1211,12 @@ extern struct daemon { char *packet; /* packet buffer */ int packet_buff_sz; /* size of above */ char *namebuff; /* MAXDNAME size buffer */ +#if (defined(HAVE_CONNTRACK) && defined(HAVE_UBUS)) || defined(HAVE_DNSSEC) + /* CONNTRACK UBUS code uses this buffer, as well as DNSSEC code. */ + char *workspacename; +#endif #ifdef HAVE_DNSSEC char *keyname; /* MAXDNAME size buffer */ - char *workspacename; /* ditto */ unsigned long *rr_status; /* ceiling in TTL from DNSSEC or zero for insecure */ int rr_status_sz; int dnssec_no_time_check; @@ -1109,16 +1228,15 @@ extern struct daemon { struct serverfd *sfds; struct irec *interfaces; struct listener *listeners; - struct server *last_server; - time_t forwardtime; - int forwardcount; struct server *srv_save; /* Used for resend on DoD */ size_t packet_len; /* " " */ - struct randfd *rfd_save; /* " " */ + int fd_save; /* " " */ pid_t tcp_pids[MAX_PROCS]; int tcp_pipes[MAX_PROCS]; int pipe_to_parent; - struct randfd randomsocks[RANDOM_SOCKS]; + int numrrand; + struct randfd *randomsocks; + struct randfd_list *rfl_spare, *rfl_poll; int v6pktinfo; struct addrlist *interface_addrs; /* list of all addresses/prefix lengths associated with all local interfaces */ int log_id, log_display_id; /* ids of transactions for logging */ @@ -1145,13 +1263,18 @@ extern struct daemon { unsigned char *duid; struct iovec outpacket; int dhcp6fd, icmp6fd; +# ifdef HAVE_SCRIPT + struct snoop_record *free_snoops; +# endif #endif + /* DBus stuff */ /* void * here to avoid depending on dbus headers outside dbus.c */ void *dbus; #ifdef HAVE_DBUS struct watch *watches; #endif + /* UBus stuff */ #ifdef HAVE_UBUS /* void * here to avoid depending on ubus headers outside ubus.c */ @@ -1171,12 +1294,19 @@ extern struct daemon { #endif } *daemon; +struct server_details { + union mysockaddr *addr, *source_addr; + struct addrinfo *hostinfo, *orig_hostinfo; + char *interface, *source, *scope_id, *interface_opt; + int serv_port, source_port, addr_type, scope_index, valid; + u16 *flags; +}; + /* cache.c */ void cache_init(void); void next_uid(struct crec *crecp); -void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg); +void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg, unsigned short type); char *record_source(unsigned int index); -char *querystr(char *desc, unsigned short type); int cache_find_non_terminal(char *name, time_t now); struct crec *cache_find_by_addr(struct crec *crecp, union all_addr *addr, time_t now, @@ -1185,6 +1315,7 @@ struct crec *cache_find_by_name(struct crec *crecp, char *name, time_t now, unsigned int prot); void cache_end_insert(void); void cache_start_insert(void); +unsigned int cache_remove_uid(const unsigned int uid); int cache_recv_insert(time_t now, int fd); struct crec *cache_insert(char *name, union all_addr *addr, unsigned short class, time_t now, unsigned long ttl, unsigned int flags); @@ -1225,18 +1356,20 @@ unsigned char *skip_questions(struct dns_header *heade unsigned char *skip_section(unsigned char *ansp, int count, struct dns_header *header, size_t plen); unsigned int extract_request(struct dns_header *header, size_t qlen, char *name, unsigned short *typep); -size_t setup_reply(struct dns_header *header, size_t qlen, - union all_addr *addrp, unsigned int flags, - unsigned long ttl); +void setup_reply(struct dns_header *header, unsigned int flags, int ede); int extract_addresses(struct dns_header *header, size_t qlen, char *name, - time_t now, char **ipsets, int is_sign, int check_rebind, - int no_cache_dnssec, int secure, int *doctored); + time_t now, struct ipsets *ipsets, struct ipsets *nftsets, int is_sign, + int check_rebind, int no_cache_dnssec, int secure, int *doctored); +#if defined(HAVE_CONNTRACK) && defined(HAVE_UBUS) +void report_addresses(struct dns_header *header, size_t len, u32 mark); +#endif size_t answer_request(struct dns_header *header, char *limit, size_t qlen, struct in_addr local_addr, struct in_addr local_netmask, - time_t now, int ad_reqd, int do_bit, int have_pseudoheader); + time_t now, int ad_reqd, int do_bit, int have_pseudoheader, + int *stale); int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name, - struct bogus_addr *baddr, time_t now); -int check_for_ignored_address(struct dns_header *header, size_t qlen, struct bogus_addr *baddr); + time_t now); +int check_for_ignored_address(struct dns_header *header, size_t qlen); int check_for_local_domain(char *name, time_t now); size_t resize_packet(struct dns_header *header, size_t plen, unsigned char *pheader, size_t hlen); @@ -1255,6 +1388,7 @@ int in_zone(struct auth_zone *zone, char *name, char * #endif /* dnssec.c */ +#ifdef HAVE_DNSSEC size_t dnssec_generate_query(struct dns_header *header, unsigned char *end, char *name, int class, int type, int edns_pktsz); int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class); int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class); @@ -1263,6 +1397,8 @@ int dnssec_validate_reply(time_t now, struct dns_heade int dnskey_keytag(int alg, int flags, unsigned char *key, int keylen); size_t filter_rrsigs(struct dns_header *header, size_t plen); int setup_timestamp(void); +int errflags_to_ede(int status); +#endif /* hash_questions.c */ void hash_questions_init(void); @@ -1289,13 +1425,18 @@ void *safe_malloc(size_t size); void safe_strncpy(char *dest, const char *src, size_t size); void safe_pipe(int *fd, int read_noblock); void *whine_malloc(size_t size); +void *whine_realloc(void *ptr, size_t size); int sa_len(union mysockaddr *addr); -int sockaddr_isequal(union mysockaddr *s1, union mysockaddr *s2); +int sockaddr_isequal(const union mysockaddr *s1, const union mysockaddr *s2); +int sockaddr_isnull(const union mysockaddr *s); +int hostname_order(const char *a, const char *b); int hostname_isequal(const char *a, const char *b); int hostname_issubdomain(char *a, char *b); time_t dnsmasq_time(void); +u32 dnsmasq_milliseconds(void); int netmask_length(struct in_addr mask); int is_same_net(struct in_addr a, struct in_addr b, struct in_addr mask); +int is_same_net_prefix(struct in_addr a, struct in_addr b, int prefix); int is_same_net6(struct in6_addr *a, struct in6_addr *b, int prefixlen); u64 addr6part(struct in6_addr *addr); void setaddr6part(struct in6_addr *addr, u64 host); @@ -1336,38 +1477,31 @@ void read_servers_file(void); void set_option_bool(unsigned int opt); void reset_option_bool(unsigned int opt); struct hostsfile *expand_filelist(struct hostsfile *list); -char *parse_server(char *arg, union mysockaddr *addr, - union mysockaddr *source_addr, char *interface, int *flags); +char *parse_server(char *arg, struct server_details *sdetails); +char *parse_server_addr(struct server_details *sdetails); +int parse_server_next(struct server_details *sdetails); int option_read_dynfile(char *file, int flags); /* forward.c */ -void reply_query(int fd, int family, time_t now); +void reply_query(int fd, time_t now); void receive_query(struct listener *listen, time_t now); unsigned char *tcp_request(int confd, time_t now, union mysockaddr *local_addr, struct in_addr netmask, int auth_dns); void server_gone(struct server *server); -struct frec *get_new_frec(time_t now, int *wait, struct frec *force); int send_from(int fd, int nowild, char *packet, size_t len, union mysockaddr *to, union all_addr *source, unsigned int iface); void resend_query(void); -struct randfd *allocate_rfd(int family); -void free_rfd(struct randfd *rfd); +int allocate_rfd(struct randfd_list **fdlp, struct server *serv); +void free_rfds(struct randfd_list **fdlp); +int fast_retry(time_t now); /* network.c */ int indextoname(int fd, int index, char *name); int local_bind(int fd, union mysockaddr *addr, char *intname, unsigned int ifindex, int is_tcp); -int random_sock(int family); void pre_allocate_sfds(void); int reload_servers(char *fname); -void mark_servers(int flag); -void cleanup_servers(void); -void add_update_server(int flags, - union mysockaddr *addr, - union mysockaddr *source_addr, - const char *interface, - const char *domain); -void check_servers(void); +void check_servers(int no_loop_call); int enumerate_interfaces(int reset); void create_wildcard_listeners(void); void create_bound_listeners(int dienow); @@ -1500,10 +1634,14 @@ void emit_dbus_signal(int action, struct dhcp_lease *l /* ubus.c */ #ifdef HAVE_UBUS -void ubus_init(void); +char *ubus_init(void); void set_ubus_listeners(void); void check_ubus_listeners(void); void ubus_event_bcast(const char *type, const char *mac, const char *ip, const char *name, const char *interface); +# ifdef HAVE_CONNTRACK +void ubus_event_bcast_connmark_allowlist_refused(u32 mark, const char *name); +void ubus_event_bcast_connmark_allowlist_resolved(u32 mark, const char *pattern, const char *ip, u32 ttl); +# endif #endif /* ipset.c */ @@ -1512,6 +1650,19 @@ void ipset_init(void); int add_to_ipset(const char *setname, const union all_addr *ipaddr, int flags, int remove); #endif +/* nftset.c */ +#ifdef HAVE_NFTSET +void nftset_init(void); +int add_to_nftset(const char *setpath, const union all_addr *ipaddr, int flags, int remove); +#endif + +/* pattern.c */ +#ifdef HAVE_CONNTRACK +int is_valid_dns_name(const char *value); +int is_valid_dns_name_pattern(const char *value); +int is_dns_name_matching_pattern(const char *name, const char *pattern); +#endif + /* helper.c */ #if defined(HAVE_SCRIPT) int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd); @@ -1524,7 +1675,10 @@ void queue_tftp(off_t file_len, char *filename, union void queue_arp(int action, unsigned char *mac, int maclen, int family, union all_addr *addr); int helper_buf_empty(void); +#ifdef HAVE_DHCP6 +void queue_relay_snoop(struct in6_addr *client, int if_index, struct in6_addr *prefix, int prefix_len); #endif +#endif /* tftp.c */ #ifdef HAVE_TFTP @@ -1566,10 +1720,13 @@ void get_client_mac(struct in6_addr *client, int iface unsigned short dhcp6_reply(struct dhcp_context *context, int interface, char *iface_name, struct in6_addr *fallback, struct in6_addr *ll_addr, struct in6_addr *ula_addr, size_t sz, struct in6_addr *client_addr, time_t now); -void relay_upstream6(struct dhcp_relay *relay, ssize_t sz, struct in6_addr *peer_address, +int relay_upstream6(int iface_index, ssize_t sz, struct in6_addr *peer_address, u32 scope_id, time_t now); -unsigned short relay_reply6( struct sockaddr_in6 *peer, ssize_t sz, char *arrival_interface); +int relay_reply6( struct sockaddr_in6 *peer, ssize_t sz, char *arrival_interface); +# ifdef HAVE_SCRIPT +int do_snoop_script_run(void); +# endif #endif /* dhcp-common.c */ @@ -1596,7 +1753,7 @@ struct dhcp_config *find_config(struct dhcp_config *co int config_has_mac(struct dhcp_config *config, unsigned char *hwaddr, int len, int type); #ifdef HAVE_LINUX_NETWORK char *whichdevice(void); -void bindtodevice(char *device, int fd); +int bind_dhcp_devices(char *bound_device); #endif # ifdef HAVE_DHCP6 void display_opts6(void); @@ -1657,7 +1814,11 @@ int do_poll(int timeout); size_t rrfilter(struct dns_header *header, size_t plen, int mode); u16 *rrfilter_desc(int type); int expand_workspace(unsigned char ***wkspc, int *szp, int new); - +/* modes. */ +#define RRFILTER_EDNS0 0 +#define RRFILTER_DNSSEC 1 +#define RRFILTER_A 2 +#define RRFILTER_AAAA 3 /* edns0.c */ unsigned char *find_pseudoheader(struct dns_header *header, size_t plen, size_t *len, unsigned char **p, int *is_sign, int *is_last); @@ -1665,7 +1826,7 @@ size_t add_pseudoheader(struct dns_header *header, siz unsigned short udp_sz, int optno, unsigned char *opt, size_t optlen, int set_do, int replace); size_t add_do_bit(struct dns_header *header, size_t plen, unsigned char *limit); size_t add_edns0_config(struct dns_header *header, size_t plen, unsigned char *limit, - union mysockaddr *source, time_t now, int *check_subnet, int *cacheable); + union mysockaddr *source, time_t now, int *cacheable); int check_source(struct dns_header *header, size_t plen, unsigned char *pseudoheader, union mysockaddr *peer); /* arp.c */ @@ -1675,5 +1836,28 @@ int do_arp_script_run(void); /* dump.c */ #ifdef HAVE_DUMPFILE void dump_init(void); -void dump_packet(int mask, void *packet, size_t len, union mysockaddr *src, union mysockaddr *dst); +void dump_packet_udp(int mask, void *packet, size_t len, union mysockaddr *src, + union mysockaddr *dst, int fd); +void dump_packet_icmp(int mask, void *packet, size_t len, union mysockaddr *src, + union mysockaddr *dst); #endif + +/* domain-match.c */ +void build_server_array(void); +int lookup_domain(char *qdomain, int flags, int *lowout, int *highout); +int filter_servers(int seed, int flags, int *lowout, int *highout); +int is_local_answer(time_t now, int first, char *name); +size_t make_local_answer(int flags, int gotname, size_t size, struct dns_header *header, + char *name, char *limit, int first, int last, int ede); +int server_samegroup(struct server *a, struct server *b); +#ifdef HAVE_DNSSEC +int dnssec_server(struct server *server, char *keyname, int *firstp, int *lastp); +#endif +void mark_servers(int flag); +void cleanup_servers(void); +int add_update_server(int flags, + union mysockaddr *addr, + union mysockaddr *source_addr, + const char *interface, + const char *domain, + union all_addr *local_addr);