xref: /freebsd/contrib/unbound/util/net_help.h (revision be771a7b7f4580a30d99e41a5bb1b93a385a119d)
1 /*
2  * util/net_help.h - network help functions
3  *
4  * Copyright (c) 2007, NLnet Labs. All rights reserved.
5  *
6  * This software is open source.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  *
15  * Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  *
19  * Neither the name of the NLNET LABS nor the names of its contributors may
20  * be used to endorse or promote products derived from this software without
21  * specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 /**
37  * \file
38  *
39  * This file contains functions to perform network related tasks.
40  */
41 
42 #ifndef NET_HELP_H
43 #define NET_HELP_H
44 #include "util/log.h"
45 #include "util/random.h"
46 struct sock_list;
47 struct regional;
48 struct config_strlist;
49 
50 /** DNS constants for uint16_t style flag manipulation. host byteorder.
51  *                                1  1  1  1  1  1
52  *  0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
53  * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
54  * |QR|   Opcode  |AA|TC|RD|RA| Z|AD|CD|   RCODE   |
55  * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
56  */
57 /** CD flag */
58 #define BIT_CD 0x0010
59 /** AD flag */
60 #define BIT_AD 0x0020
61 /** Z flag */
62 #define BIT_Z  0x0040
63 /** RA flag */
64 #define BIT_RA 0x0080
65 /** RD flag */
66 #define BIT_RD 0x0100
67 /** TC flag */
68 #define BIT_TC 0x0200
69 /** AA flag */
70 #define BIT_AA 0x0400
71 /** QR flag */
72 #define BIT_QR 0x8000
73 /** get RCODE bits from uint16 flags */
74 #define FLAGS_GET_RCODE(f) ((f) & 0xf)
75 /** set RCODE bits in uint16 flags */
76 #define FLAGS_SET_RCODE(f, r) (f = (((f) & 0xfff0) | (r)))
77 
78 /** timeout in milliseconds for UDP queries to auth servers. */
79 #define UDP_AUTH_QUERY_TIMEOUT 3000
80 /** Advertised version of EDNS capabilities */
81 #define EDNS_ADVERTISED_VERSION         0
82 /** Advertised size of EDNS capabilities */
83 extern uint16_t EDNS_ADVERTISED_SIZE;
84 /** bits for EDNS bitfield */
85 #define EDNS_DO 0x8000 /* Dnssec Ok */
86 /** byte size of ip4 address */
87 #define INET_SIZE 4
88 /** byte size of ip6 address */
89 #define INET6_SIZE 16
90 
91 /** DNSKEY zone sign key flag */
92 #define DNSKEY_BIT_ZSK 0x0100
93 /** DNSKEY secure entry point, KSK flag */
94 #define DNSKEY_BIT_SEP 0x0001
95 
96 /** return a random 16-bit number given a random source */
97 #define GET_RANDOM_ID(rnd) (((unsigned)ub_random(rnd)>>8) & 0xffff)
98 
99 /** define MSG_DONTWAIT for unsupported platforms */
100 #ifndef MSG_DONTWAIT
101 #define MSG_DONTWAIT 0
102 #endif
103 
104 /** minimal responses when positive answer */
105 extern int MINIMAL_RESPONSES;
106 
107 /** rrset order roundrobin */
108 extern int RRSET_ROUNDROBIN;
109 
110 /** log tag queries with name instead of 'info' for filtering */
111 extern int LOG_TAG_QUERYREPLY;
112 
113 /**
114  * See if string is ip4 or ip6.
115  * @param str: IP specification.
116  * @return: true if string addr is an ip6 specced address.
117  */
118 int str_is_ip6(const char* str);
119 
120 /**
121  * Set fd nonblocking.
122  * @param s: file descriptor.
123  * @return: 0 on error (error is printed to log).
124  */
125 int fd_set_nonblock(int s);
126 
127 /**
128  * Set fd (back to) blocking.
129  * @param s: file descriptor.
130  * @return: 0 on error (error is printed to log).
131  */
132 int fd_set_block(int s);
133 
134 /**
135  * See if number is a power of 2.
136  * @param num: the value.
137  * @return: true if the number is a power of 2.
138  */
139 int is_pow2(size_t num);
140 
141 /**
142  * Allocate memory and copy over contents.
143  * @param data: what to copy over.
144  * @param len: length of data.
145  * @return: NULL on malloc failure, or newly malloced data.
146  */
147 void* memdup(void* data, size_t len);
148 
149 /**
150  * Prints the sockaddr in readable format with log_info. Debug helper.
151  * @param v: at what verbosity level to print this.
152  * @param str: descriptive string printed with it.
153  * @param addr: the sockaddr to print. Can be ip4 or ip6.
154  * @param addrlen: length of addr.
155  */
156 void log_addr(enum verbosity_value v, const char* str,
157 	struct sockaddr_storage* addr, socklen_t addrlen);
158 
159 /**
160  * Prints zone name and sockaddr in readable format with log_info. Debug.
161  * @param v: at what verbosity level to print this.
162  * @param str: descriptive string printed with it.
163  * @param zone: DNS domain name, uncompressed wireformat.
164  * @param addr: the sockaddr to print. Can be ip4 or ip6.
165  * @param addrlen: length of addr.
166  */
167 void log_name_addr(enum verbosity_value v, const char* str, uint8_t* zone,
168 	struct sockaddr_storage* addr, socklen_t addrlen);
169 
170 /**
171  * Log errno and addr.
172  * @param str: descriptive string printed with it.
173  * @param err: errno string to print, i.e. strerror(errno).
174  * @param addr: the sockaddr to print. Can be ip4 or ip6.
175  * @param addrlen: length of addr.
176  */
177 void log_err_addr(const char* str, const char* err,
178 	struct sockaddr_storage* addr, socklen_t addrlen);
179 
180 /**
181  * Convert address string, with "@port" appendix, to sockaddr.
182  * Uses DNS port by default.
183  * @param str: the string
184  * @param addr: where to store sockaddr.
185  * @param addrlen: length of stored sockaddr is returned.
186  * @param port: default port.
187  * @return 0 on error.
188  */
189 int extstrtoaddr(const char* str, struct sockaddr_storage* addr,
190 	socklen_t* addrlen, int port);
191 
192 /**
193  * Convert ip address string and port to sockaddr.
194  * @param ip: ip4 or ip6 address string.
195  * @param port: port number, host format.
196  * @param addr: where to store sockaddr.
197  * @param addrlen: length of stored sockaddr is returned.
198  * @return 0 on error.
199  */
200 int ipstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr,
201 	socklen_t* addrlen);
202 
203 /**
204  * Convert ip netblock (ip/netsize) string and port to sockaddr.
205  * performs a copy internally to avoid writing over 'ip' string.
206  * @param ip: ip4 or ip6 address string.
207  * @param port: port number, host format.
208  * @param addr: where to store sockaddr.
209  * @param addrlen: length of stored sockaddr is returned.
210  * @param net: netblock size is returned.
211  * @return 0 on error.
212  */
213 int netblockstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr,
214 	socklen_t* addrlen, int* net);
215 
216 /**
217  * Convert address string, with "@port" appendix, to sockaddr.
218  * It can also have an "#tls-auth-name" appendix (after the port).
219  * The returned auth_name string is a pointer into the input string.
220  * Uses DNS port by default; TLS port when a "#tls-auth-name" is configured.
221  * @param str: the string
222  * @param addr: where to store sockaddr.
223  * @param addrlen: length of stored sockaddr is returned.
224  * @param auth_name: returned pointer to tls_auth_name, or NULL if none.
225  * @return 0 on error.
226  */
227 int authextstrtoaddr(char* str, struct sockaddr_storage* addr,
228 	socklen_t* addrlen, char** auth_name);
229 
230 /**
231  * Convert domain string, with "@port" appendix, to dname.
232  * It can also have an "#tls-auth-name" appendix (after the port).
233  * The return port is the parsed port.
234  * Uses DNS port by default; TLS port when a "#tls-auth-name" is configured.
235  * The returned auth_name string is a pointer into the input string.
236  * @param str: the string
237  * @param port: pointer to be assigned the parsed port value.
238  * @param auth_name: returned pointer to tls_auth_name, or NULL if none.
239  * @return pointer to the dname.
240  */
241 uint8_t* authextstrtodname(char* str, int* port, char** auth_name);
242 
243 /**
244  * Store port number into sockaddr structure
245  * @param addr: sockaddr structure, ip4 or ip6.
246  * @param addrlen: length of addr.
247  * @param port: port number to put into the addr.
248  */
249 void sockaddr_store_port(struct sockaddr_storage* addr, socklen_t addrlen,
250 	int port);
251 
252 /**
253  * Print string with neat domain name, type and class.
254  * @param v: at what verbosity level to print this.
255  * @param str: string of message.
256  * @param name: domain name uncompressed wireformat.
257  * @param type: host format RR type.
258  * @param dclass: host format RR class.
259  */
260 void log_nametypeclass(enum verbosity_value v, const char* str,
261 	uint8_t* name, uint16_t type, uint16_t dclass);
262 
263 /**
264  * Like log_nametypeclass, but logs with log_query for query logging
265  */
266 void log_query_in(const char* str, uint8_t* name, uint16_t type,
267 	uint16_t dclass);
268 
269 /**
270  * Compare two sockaddrs. Imposes an ordering on the addresses.
271  * Compares address and port.
272  * @param addr1: address 1.
273  * @param len1: lengths of addr1.
274  * @param addr2: address 2.
275  * @param len2: lengths of addr2.
276  * @return: 0 if addr1 == addr2. -1 if addr1 is smaller, +1 if larger.
277  */
278 int sockaddr_cmp(struct sockaddr_storage* addr1, socklen_t len1,
279 	struct sockaddr_storage* addr2, socklen_t len2);
280 
281 /**
282  * Compare two sockaddrs. Compares address, not the port.
283  * @param addr1: address 1.
284  * @param len1: lengths of addr1.
285  * @param addr2: address 2.
286  * @param len2: lengths of addr2.
287  * @return: 0 if addr1 == addr2. -1 if addr1 is smaller, +1 if larger.
288  */
289 int sockaddr_cmp_addr(struct sockaddr_storage* addr1, socklen_t len1,
290 	struct sockaddr_storage* addr2, socklen_t len2);
291 
292 /**
293  * Compare two sockaddrs. Imposes an ordering on the addresses.
294  * Compares address and port. It also compares scope_id for ip6.
295  * @param addr1: address 1.
296  * @param len1: lengths of addr1.
297  * @param addr2: address 2.
298  * @param len2: lengths of addr2.
299  * @return: 0 if addr1 == addr2. -1 if addr1 is smaller, +1 if larger.
300  */
301 int sockaddr_cmp_scopeid(struct sockaddr_storage* addr1, socklen_t len1,
302 	struct sockaddr_storage* addr2, socklen_t len2);
303 
304 /**
305  * Checkout address family.
306  * @param addr: the sockaddr to examine.
307  * @param len: the length of addr.
308  * @return: true if sockaddr is ip6.
309  */
310 int addr_is_ip6(struct sockaddr_storage* addr, socklen_t len);
311 
312 /**
313  * Make sure the sockaddr ends in zeroes. For tree insertion and subsequent
314  * comparison.
315  * @param addr: the ip4 or ip6 addr.
316  * @param len: length of addr.
317  * @param net: number of bits to leave untouched, the rest of the netblock
318  * 	address is zeroed.
319  */
320 void addr_mask(struct sockaddr_storage* addr, socklen_t len, int net);
321 
322 /**
323  * See how many bits are shared, equal, between two addrs.
324  * @param addr1: first addr.
325  * @param net1: netblock size of first addr.
326  * @param addr2: second addr.
327  * @param net2: netblock size of second addr.
328  * @param addrlen: length of first addr and of second addr.
329  * 	They must be of the same length (i.e. same type IP4, IP6).
330  * @return: number of bits the same.
331  */
332 int addr_in_common(struct sockaddr_storage* addr1, int net1,
333 	struct sockaddr_storage* addr2, int net2, socklen_t addrlen);
334 
335 /**
336  * Put address into string, works for IPv4 and IPv6.
337  * @param addr: address
338  * @param addrlen: length of address
339  * @param buf: result string stored here
340  * @param len: length of buf.
341  * On failure a string with "error" is stored inside.
342  */
343 void addr_to_str(struct sockaddr_storage* addr, socklen_t addrlen,
344 	char* buf, size_t len);
345 
346 /**
347  * Check if the prefix network length is one of the allowed 32, 40, 48, 56, 64,
348  * or 96.
349  * @param prefixnet: prefix network length to check.
350  * @return 1 on success, 0 on failure.
351  */
352 int prefixnet_is_nat64(int prefixnet);
353 
354 /**
355  * Create a NAT64 address from a given address (needs to be IPv4) and a given
356  * NAT64 prefix. The NAT64 prefix net needs to be one of 32, 40, 48, 56, 64, 96.
357  * @param addr: IPv4 address.
358  * @param nat64_prefix: NAT64 prefix.
359  * @param nat64_prefixlen: NAT64 prefix len.
360  * @param nat64_prefixnet: NAT64 prefix mask.
361  * @param nat64_addr: the resulting NAT64 address.
362  * @param nat64_addrlen: the resulting NAT64 address length.
363  */
364 void addr_to_nat64(const struct sockaddr_storage* addr,
365 	const struct sockaddr_storage* nat64_prefix,
366 	socklen_t nat64_prefixlen, int nat64_prefixnet,
367 	struct sockaddr_storage* nat64_addr, socklen_t* nat64_addrlen);
368 
369 /**
370  * See if sockaddr is an ipv6 mapped ipv4 address, "::ffff:0.0.0.0"
371  * @param addr: address
372  * @param addrlen: length of address
373  * @return true if so
374  */
375 int addr_is_ip4mapped(struct sockaddr_storage* addr, socklen_t addrlen);
376 
377 /**
378  * See if sockaddr is an ipv6 fe80::/10 link local address.
379  * @param addr: address
380  * @param addrlen: length of address
381  * @return true if so
382  */
383 int addr_is_ip6linklocal(struct sockaddr_storage* addr, socklen_t addrlen);
384 
385 /**
386  * See if sockaddr is 255.255.255.255.
387  * @param addr: address
388  * @param addrlen: length of address
389  * @return true if so
390  */
391 int addr_is_broadcast(struct sockaddr_storage* addr, socklen_t addrlen);
392 
393 /**
394  * See if sockaddr is 0.0.0.0 or ::0.
395  * @param addr: address
396  * @param addrlen: length of address
397  * @return true if so
398  */
399 int addr_is_any(struct sockaddr_storage* addr, socklen_t addrlen);
400 
401 /**
402  * Insert new socket list item. If fails logs error.
403  * @param list: pointer to pointer to first item.
404  * @param addr: address or NULL if 'cache'.
405  * @param len: length of addr, or 0 if 'cache'.
406  * @param region: where to allocate
407  */
408 void sock_list_insert(struct sock_list** list, struct sockaddr_storage* addr,
409 	socklen_t len, struct regional* region);
410 
411 /**
412  * Append one list to another.  Must both be from same qstate(regional).
413  * @param list: pointer to result list that is modified.
414  * @param add: item(s) to add.  They are prepended to list.
415  */
416 void sock_list_prepend(struct sock_list** list, struct sock_list* add);
417 
418 /**
419  * Find addr in list.
420  * @param list: to search in
421  * @param addr: address to look for.
422  * @param len: length. Can be 0, look for 'cache entry'.
423  * @return true if found.
424  */
425 int sock_list_find(struct sock_list* list, struct sockaddr_storage* addr,
426         socklen_t len);
427 
428 /**
429  * Merge socklist into another socket list.  Allocates the new entries
430  * freshly and copies them over, so also performs a region switchover.
431  * Allocation failures are logged.
432  * @param list: the destination list (checked for duplicates)
433  * @param region: where to allocate
434  * @param add: the list of entries to add.
435  */
436 void sock_list_merge(struct sock_list** list, struct regional* region,
437 	struct sock_list* add);
438 
439 /**
440  * Log libcrypto error with descriptive string. Calls log_err().
441  * @param str: what failed.
442  */
443 void log_crypto_err(const char* str);
444 
445 /**
446  * Log libcrypto error from errcode with descriptive string, calls log_err.
447  * @param str: what failed.
448  * @param err: error code from ERR_get_error.
449  */
450 void log_crypto_err_code(const char* str, unsigned long err);
451 
452 /**
453  * Log an error from libcrypto that came from SSL_write and so on, with
454  * a value from SSL_get_error, calls log_err. If that fails it logs with
455  * log_crypto_err.
456  * @param str: what failed
457  * @param r: output of SSL_get_error on the I/O operation result.
458  */
459 void log_crypto_err_io(const char* str, int r);
460 
461 /**
462  * Log an error from libcrypt that came from an I/O routine with the
463  * errcode from ERR_get_error. Calls log_err() and log_crypto_err_code.
464  * @param str: what failed
465  * @param r: output of SSL_get_error on the I/O operation result.
466  * @param err: error code from ERR_get_error
467  */
468 void log_crypto_err_io_code(const char* str, int r, unsigned long err);
469 
470 /**
471  * Log certificate details verbosity, string, of X509 cert
472  * @param level: verbosity level
473  * @param str: string to prefix on output
474  * @param cert: X509* structure.
475  */
476 void log_cert(unsigned level, const char* str, void* cert);
477 
478 /**
479  * Set SSL_OP_NOxxx options on SSL context to disable bad crypto
480  * @param ctxt: SSL_CTX*
481  * @return false on failure.
482  */
483 int listen_sslctx_setup(void* ctxt);
484 
485 /**
486  * Further setup of listening SSL context, after keys loaded.
487  * @param ctxt: SSL_CTX*
488  */
489 void listen_sslctx_setup_2(void* ctxt);
490 
491 /**
492  * create SSL listen context
493  * @param key: private key file.
494  * @param pem: public key cert.
495  * @param verifypem: if nonNULL, verifylocation file.
496  * @param tls_ciphers: if non empty string, tls ciphers to use.
497  * @param tls_ciphersuites: if non empty string, tls ciphersuites to use.
498  * @param set_ticket_keys_cb: if the callback for configured ticket keys needs
499  *	to be set.
500  * @param is_dot: if the TLS connection is for DoT to set the appropriate ALPN.
501  * @param is_doh: if the TLS connection is for DoH to set the appropriate ALPN.
502  * return SSL_CTX* or NULL on failure (logged).
503  */
504 void* listen_sslctx_create(const char* key, const char* pem,
505 	const char* verifypem, const char* tls_ciphers,
506 	const char* tls_ciphersuites, int set_ticket_keys_cb,
507 	int is_dot, int is_doh);
508 
509 /**
510  * create SSL connect context
511  * @param key: if nonNULL (also pem nonNULL), the client private key.
512  * @param pem: client public key (or NULL if key is NULL).
513  * @param verifypem: if nonNULL used for verifylocation file.
514  * @param wincert: add system certificate store to ctx (add to verifypem ca
515  * 	certs).
516  * @return SSL_CTX* or NULL on failure (logged).
517  */
518 void* connect_sslctx_create(char* key, char* pem, char* verifypem, int wincert);
519 
520 /**
521  * accept a new fd and wrap it in a BIO in SSL
522  * @param sslctx: the SSL_CTX to use (from listen_sslctx_create()).
523  * @param fd: from accept, nonblocking.
524  * @return SSL or NULL on alloc failure.
525  */
526 void* incoming_ssl_fd(void* sslctx, int fd);
527 
528 /**
529  * connect a new fd and wrap it in a BIO in SSL
530  * @param sslctx: the SSL_CTX to use (from connect_sslctx_create())
531  * @param fd: from connect.
532  * @return SSL or NULL on alloc failure
533  */
534 void* outgoing_ssl_fd(void* sslctx, int fd);
535 
536 /**
537  * check if authname SSL functionality is available, false if not
538  * @param auth_name: the name for the remote server, used for error print.
539  * @return false if SSL functionality to check the SSL name is not available.
540  */
541 int check_auth_name_for_ssl(char* auth_name);
542 
543 /**
544  * set auth name on SSL for verification
545  * @param ssl: SSL* to set
546  * @param auth_name: if NULL nothing happens, otherwise the name to check.
547  * @param use_sni: if SNI will be used.
548  * @return 1 on success or NULL auth_name, 0 on failure.
549  */
550 int set_auth_name_on_ssl(void* ssl, char* auth_name, int use_sni);
551 
552 /**
553  * Initialize openssl locking for thread safety
554  * @return false on failure (alloc failure).
555  */
556 int ub_openssl_lock_init(void);
557 
558 /**
559  * De-init the allocated openssl locks
560  */
561 void ub_openssl_lock_delete(void);
562 
563 /**
564  * setup TLS session ticket
565  * @param tls_session_ticket_keys: TLS ticket secret filenames
566  * @return false on failure (alloc failure).
567  */
568 int listen_sslctx_setup_ticket_keys(struct config_strlist* tls_session_ticket_keys);
569 
570 /** Free memory used for TLS session ticket keys */
571 void listen_sslctx_delete_ticket_keys(void);
572 
573 /**
574  * RPZ format netblock to network byte order address and netblock
575  * example RPZ netblock format dnames:
576  *  - 24.10.100.51.198.rpz-ip -> 198.51.100.10/24
577  *  - 32.10.zz.db8.2001.rpz-ip -> 2001:db8:0:0:0:0:0:10/32
578  * @param dname: the dname containing RPZ format netblock
579  * @param dnamelen: length of dname
580  * @param addr: where to store sockaddr.
581  * @param addrlen: length of stored sockaddr is returned.
582  * @param net: where to store netmask
583  * @param af: where to store address family.
584  * @return 0 on error.
585  */
586 int netblockdnametoaddr(uint8_t* dname, size_t dnamelen,
587 	struct sockaddr_storage* addr, socklen_t* addrlen, int* net, int* af);
588 
589 /** Return strerror or wsastrerror for socket error printout */
590 char* sock_strerror(int errn);
591 /** close the socket with close, or wsa closesocket */
592 void sock_close(int socket);
593 
594 /**
595  * Convert binary data to a string of hexadecimal characters.
596  */
597 ssize_t hex_ntop(uint8_t const *src, size_t srclength, char *target,
598 		 size_t targsize);
599 
600 /** Convert hexadecimal data to binary. */
601 ssize_t hex_pton(const char* src, uint8_t* target, size_t targsize);
602 
603 #endif /* NET_HELP_H */
604