Home | History | Annotate | Line # | Download | only in dist
xfrd-tcp.c revision 1.1.1.5.2.1
      1          1.1  christos /*
      2          1.1  christos  * xfrd-tcp.c - XFR (transfer) Daemon TCP system source file. Manages tcp conn.
      3          1.1  christos  *
      4          1.1  christos  * Copyright (c) 2001-2006, NLnet Labs. All rights reserved.
      5          1.1  christos  *
      6          1.1  christos  * See LICENSE for the license.
      7          1.1  christos  *
      8          1.1  christos  */
      9          1.1  christos 
     10          1.1  christos #include "config.h"
     11          1.1  christos #include <assert.h>
     12          1.1  christos #include <errno.h>
     13          1.1  christos #include <fcntl.h>
     14          1.1  christos #include <unistd.h>
     15          1.1  christos #include <stdlib.h>
     16      1.1.1.2  christos #include <sys/uio.h>
     17          1.1  christos #include "nsd.h"
     18          1.1  christos #include "xfrd-tcp.h"
     19          1.1  christos #include "buffer.h"
     20          1.1  christos #include "packet.h"
     21          1.1  christos #include "dname.h"
     22          1.1  christos #include "options.h"
     23          1.1  christos #include "namedb.h"
     24          1.1  christos #include "xfrd.h"
     25          1.1  christos #include "xfrd-disk.h"
     26          1.1  christos #include "util.h"
     27      1.1.1.5  christos #ifdef HAVE_TLS_1_3
     28      1.1.1.5  christos #include <openssl/ssl.h>
     29      1.1.1.5  christos #include <openssl/err.h>
     30      1.1.1.5  christos #endif
     31      1.1.1.5  christos 
     32      1.1.1.5  christos #ifdef HAVE_TLS_1_3
     33      1.1.1.5  christos void log_crypto_err(const char* str); /* in server.c */
     34      1.1.1.5  christos 
     35      1.1.1.5  christos static SSL_CTX*
     36      1.1.1.5  christos create_ssl_context()
     37      1.1.1.5  christos {
     38      1.1.1.5  christos 	SSL_CTX *ctx;
     39  1.1.1.5.2.1    martin 	unsigned char protos[] = { 3, 'd', 'o', 't' };
     40      1.1.1.5  christos 	ctx = SSL_CTX_new(TLS_client_method());
     41      1.1.1.5  christos 	if (!ctx) {
     42      1.1.1.5  christos 		log_msg(LOG_ERR, "xfrd tls: Unable to create SSL ctxt");
     43      1.1.1.5  christos 	}
     44      1.1.1.5  christos 	else if (SSL_CTX_set_default_verify_paths(ctx) != 1) {
     45      1.1.1.5  christos 		SSL_CTX_free(ctx);
     46      1.1.1.5  christos 		log_msg(LOG_ERR, "xfrd tls: Unable to set default SSL verify paths");
     47      1.1.1.5  christos 		return NULL;
     48      1.1.1.5  christos 	}
     49      1.1.1.5  christos 	/* Only trust 1.3 as per the specification */
     50      1.1.1.5  christos 	else if (!SSL_CTX_set_min_proto_version(ctx, TLS1_3_VERSION)) {
     51      1.1.1.5  christos 		SSL_CTX_free(ctx);
     52      1.1.1.5  christos 		log_msg(LOG_ERR, "xfrd tls: Unable to set minimum TLS version 1.3");
     53      1.1.1.5  christos 		return NULL;
     54      1.1.1.5  christos 	}
     55  1.1.1.5.2.1    martin 
     56  1.1.1.5.2.1    martin 	if (SSL_CTX_set_alpn_protos(ctx, protos, sizeof(protos)) != 0) {
     57  1.1.1.5.2.1    martin 		SSL_CTX_free(ctx);
     58  1.1.1.5.2.1    martin 		log_msg(LOG_ERR, "xfrd tls: Unable to set ALPN protocols");
     59  1.1.1.5.2.1    martin 		return NULL;
     60  1.1.1.5.2.1    martin 	}
     61      1.1.1.5  christos 	return ctx;
     62      1.1.1.5  christos }
     63      1.1.1.5  christos 
     64      1.1.1.5  christos static int
     65      1.1.1.5  christos tls_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
     66      1.1.1.5  christos {
     67      1.1.1.5  christos 	int err = X509_STORE_CTX_get_error(ctx);
     68      1.1.1.5  christos 	int depth = X509_STORE_CTX_get_error_depth(ctx);
     69      1.1.1.5  christos 
     70      1.1.1.5  christos 	// report the specific cert error here - will need custom verify code if
     71      1.1.1.5  christos 	// SPKI pins are supported
     72      1.1.1.5  christos 	if (!preverify_ok)
     73      1.1.1.5  christos 		log_msg(LOG_ERR, "xfrd tls: TLS verify failed - (%d) depth: %d error: %s",
     74      1.1.1.5  christos 				err,
     75      1.1.1.5  christos 				depth,
     76      1.1.1.5  christos 				X509_verify_cert_error_string(err));
     77      1.1.1.5  christos 	return preverify_ok;
     78      1.1.1.5  christos }
     79      1.1.1.5  christos 
     80      1.1.1.5  christos static int
     81      1.1.1.5  christos setup_ssl(struct xfrd_tcp_pipeline* tp, struct xfrd_tcp_set* tcp_set,
     82      1.1.1.5  christos 		  const char* auth_domain_name)
     83      1.1.1.5  christos {
     84      1.1.1.5  christos 	if (!tcp_set->ssl_ctx) {
     85      1.1.1.5  christos 		log_msg(LOG_ERR, "xfrd tls: No TLS CTX, cannot set up XFR-over-TLS");
     86      1.1.1.5  christos 		return 0;
     87      1.1.1.5  christos 	}
     88      1.1.1.5  christos 	DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd: setting up TLS for tls_auth domain name %s",
     89      1.1.1.5  christos 						 auth_domain_name));
     90      1.1.1.5  christos 	tp->ssl = SSL_new((SSL_CTX*)tcp_set->ssl_ctx);
     91      1.1.1.5  christos 	if(!tp->ssl) {
     92      1.1.1.5  christos 		log_msg(LOG_ERR, "xfrd tls: Unable to create TLS object");
     93      1.1.1.5  christos 		return 0;
     94      1.1.1.5  christos 	}
     95      1.1.1.5  christos 	SSL_set_connect_state(tp->ssl);
     96      1.1.1.5  christos 	(void)SSL_set_mode(tp->ssl, SSL_MODE_AUTO_RETRY);
     97      1.1.1.5  christos 	if(!SSL_set_fd(tp->ssl, tp->tcp_w->fd)) {
     98      1.1.1.5  christos 		log_msg(LOG_ERR, "xfrd tls: Unable to set TLS fd");
     99      1.1.1.5  christos 		SSL_free(tp->ssl);
    100      1.1.1.5  christos 		tp->ssl = NULL;
    101      1.1.1.5  christos 		return 0;
    102      1.1.1.5  christos 	}
    103      1.1.1.5  christos 
    104      1.1.1.5  christos 	SSL_set_verify(tp->ssl, SSL_VERIFY_PEER, tls_verify_callback);
    105      1.1.1.5  christos 	if(!SSL_set1_host(tp->ssl, auth_domain_name)) {
    106      1.1.1.5  christos 		log_msg(LOG_ERR, "xfrd tls: TLS setting of hostname %s failed",
    107      1.1.1.5  christos 		auth_domain_name);
    108      1.1.1.5  christos 		SSL_free(tp->ssl);
    109      1.1.1.5  christos 		tp->ssl = NULL;
    110      1.1.1.5  christos 		return 0;
    111      1.1.1.5  christos 	}
    112      1.1.1.5  christos 	return 1;
    113      1.1.1.5  christos }
    114      1.1.1.5  christos 
    115      1.1.1.5  christos static int
    116      1.1.1.5  christos ssl_handshake(struct xfrd_tcp_pipeline* tp)
    117      1.1.1.5  christos {
    118      1.1.1.5  christos 	int ret;
    119      1.1.1.5  christos 
    120      1.1.1.5  christos 	ERR_clear_error();
    121      1.1.1.5  christos 	ret = SSL_do_handshake(tp->ssl);
    122      1.1.1.5  christos 	if(ret == 1) {
    123      1.1.1.5  christos 		DEBUG(DEBUG_XFRD, 1, (LOG_INFO, "xfrd: TLS handshake successful"));
    124      1.1.1.5  christos 		tp->handshake_done = 1;
    125      1.1.1.5  christos 		return 1;
    126      1.1.1.5  christos 	}
    127      1.1.1.5  christos 	tp->handshake_want = SSL_get_error(tp->ssl, ret);
    128      1.1.1.5  christos 	if(tp->handshake_want == SSL_ERROR_WANT_READ
    129      1.1.1.5  christos 	|| tp->handshake_want == SSL_ERROR_WANT_WRITE)
    130      1.1.1.5  christos 		return 1;
    131      1.1.1.5  christos 
    132      1.1.1.5  christos 	return 0;
    133      1.1.1.5  christos }
    134      1.1.1.5  christos 
    135      1.1.1.5  christos int password_cb(char *buf, int size, int ATTR_UNUSED(rwflag), void *u)
    136      1.1.1.5  christos {
    137      1.1.1.5  christos 	strlcpy(buf, (char*)u, size);
    138      1.1.1.5  christos 	return strlen(buf);
    139      1.1.1.5  christos }
    140      1.1.1.5  christos 
    141      1.1.1.5  christos #endif
    142          1.1  christos 
    143          1.1  christos /* sort tcppipe, first on IP address, for an IPaddresss, sort on num_unused */
    144          1.1  christos static int
    145          1.1  christos xfrd_pipe_cmp(const void* a, const void* b)
    146          1.1  christos {
    147          1.1  christos 	const struct xfrd_tcp_pipeline* x = (struct xfrd_tcp_pipeline*)a;
    148          1.1  christos 	const struct xfrd_tcp_pipeline* y = (struct xfrd_tcp_pipeline*)b;
    149          1.1  christos 	int r;
    150          1.1  christos 	if(x == y)
    151          1.1  christos 		return 0;
    152      1.1.1.5  christos 	if(y->key.ip_len != x->key.ip_len)
    153          1.1  christos 		/* subtraction works because nonnegative and small numbers */
    154      1.1.1.5  christos 		return (int)y->key.ip_len - (int)x->key.ip_len;
    155      1.1.1.5  christos 	r = memcmp(&x->key.ip, &y->key.ip, x->key.ip_len);
    156          1.1  christos 	if(r != 0)
    157          1.1  christos 		return r;
    158          1.1  christos 	/* sort that num_unused is sorted ascending, */
    159      1.1.1.5  christos 	if(x->key.num_unused != y->key.num_unused) {
    160      1.1.1.5  christos 		return (x->key.num_unused < y->key.num_unused) ? -1 : 1;
    161          1.1  christos 	}
    162          1.1  christos 	/* different pipelines are different still, even with same numunused*/
    163          1.1  christos 	return (uintptr_t)x < (uintptr_t)y ? -1 : 1;
    164          1.1  christos }
    165          1.1  christos 
    166      1.1.1.5  christos struct xfrd_tcp_set* xfrd_tcp_set_create(struct region* region, const char *tls_cert_bundle, int tcp_max, int tcp_pipeline)
    167          1.1  christos {
    168          1.1  christos 	int i;
    169      1.1.1.2  christos 	struct xfrd_tcp_set* tcp_set = region_alloc(region,
    170      1.1.1.2  christos 		sizeof(struct xfrd_tcp_set));
    171      1.1.1.2  christos 	memset(tcp_set, 0, sizeof(struct xfrd_tcp_set));
    172      1.1.1.5  christos 	tcp_set->tcp_state = NULL;
    173      1.1.1.5  christos 	tcp_set->tcp_max = tcp_max;
    174      1.1.1.5  christos 	tcp_set->tcp_pipeline = tcp_pipeline;
    175          1.1  christos 	tcp_set->tcp_count = 0;
    176          1.1  christos 	tcp_set->tcp_waiting_first = 0;
    177          1.1  christos 	tcp_set->tcp_waiting_last = 0;
    178      1.1.1.5  christos #ifdef HAVE_TLS_1_3
    179      1.1.1.5  christos 	/* Set up SSL context */
    180      1.1.1.5  christos 	tcp_set->ssl_ctx = create_ssl_context();
    181      1.1.1.5  christos 	if (tcp_set->ssl_ctx == NULL)
    182      1.1.1.5  christos 		log_msg(LOG_ERR, "xfrd: XFR-over-TLS not available");
    183      1.1.1.5  christos 
    184      1.1.1.5  christos 	else if (tls_cert_bundle && tls_cert_bundle[0] && SSL_CTX_load_verify_locations(
    185      1.1.1.5  christos 				tcp_set->ssl_ctx, tls_cert_bundle, NULL) != 1) {
    186      1.1.1.5  christos 		log_msg(LOG_ERR, "xfrd tls: Unable to set the certificate bundle file %s",
    187      1.1.1.5  christos 				tls_cert_bundle);
    188      1.1.1.5  christos 	}
    189      1.1.1.5  christos #else
    190      1.1.1.5  christos 	(void)tls_cert_bundle;
    191      1.1.1.5  christos 	log_msg(LOG_INFO, "xfrd: No TLS 1.3 support - XFR-over-TLS not available");
    192      1.1.1.5  christos #endif
    193      1.1.1.5  christos 	tcp_set->tcp_state = region_alloc(region,
    194      1.1.1.5  christos 		sizeof(*tcp_set->tcp_state)*tcp_set->tcp_max);
    195      1.1.1.5  christos 	for(i=0; i<tcp_set->tcp_max; i++)
    196      1.1.1.5  christos 		tcp_set->tcp_state[i] = xfrd_tcp_pipeline_create(region,
    197      1.1.1.5  christos 			tcp_pipeline);
    198          1.1  christos 	tcp_set->pipetree = rbtree_create(region, &xfrd_pipe_cmp);
    199          1.1  christos 	return tcp_set;
    200          1.1  christos }
    201          1.1  christos 
    202      1.1.1.5  christos static int pipeline_id_compare(const void* x, const void* y)
    203      1.1.1.5  christos {
    204      1.1.1.5  christos 	struct xfrd_tcp_pipeline_id* a = (struct xfrd_tcp_pipeline_id*)x;
    205      1.1.1.5  christos 	struct xfrd_tcp_pipeline_id* b = (struct xfrd_tcp_pipeline_id*)y;
    206      1.1.1.5  christos 	if(a->id < b->id)
    207      1.1.1.5  christos 		return -1;
    208      1.1.1.5  christos 	if(a->id > b->id)
    209      1.1.1.5  christos 		return 1;
    210      1.1.1.5  christos 	return 0;
    211      1.1.1.5  christos }
    212      1.1.1.5  christos 
    213      1.1.1.5  christos void pick_id_values(uint16_t* array, int num, int max)
    214      1.1.1.5  christos {
    215      1.1.1.5  christos 	uint8_t inserted[65536];
    216      1.1.1.5  christos 	int j, done;
    217      1.1.1.5  christos 	if(num == 65536) {
    218      1.1.1.5  christos 		/* all of them, loop and insert */
    219      1.1.1.5  christos 		int i;
    220      1.1.1.5  christos 		for(i=0; i<num; i++)
    221      1.1.1.5  christos 			array[i] = (uint16_t)i;
    222      1.1.1.5  christos 		return;
    223      1.1.1.5  christos 	}
    224      1.1.1.5  christos 	assert(max <= 65536);
    225      1.1.1.5  christos 	/* This uses the Robert Floyd sampling algorithm */
    226      1.1.1.5  christos 	/* keep track if values are already inserted, using the bitmap
    227      1.1.1.5  christos 	 * in insert array */
    228      1.1.1.5  christos 	memset(inserted, 0, sizeof(inserted[0])*max);
    229      1.1.1.5  christos 	done=0;
    230      1.1.1.5  christos 	for(j = max-num; j<max; j++) {
    231      1.1.1.5  christos 		/* random generate creates from 0..arg-1 */
    232      1.1.1.5  christos 		int t;
    233      1.1.1.5  christos 		if(j+1 <= 1)
    234      1.1.1.5  christos 			t = 0;
    235      1.1.1.5  christos 		else	t = random_generate(j+1);
    236      1.1.1.5  christos 		if(!inserted[t]) {
    237      1.1.1.5  christos 			array[done++]=t;
    238      1.1.1.5  christos 			inserted[t] = 1;
    239      1.1.1.5  christos 		} else {
    240      1.1.1.5  christos 			array[done++]=j;
    241      1.1.1.5  christos 			inserted[j] = 1;
    242      1.1.1.5  christos 		}
    243      1.1.1.5  christos 	}
    244      1.1.1.5  christos }
    245      1.1.1.5  christos 
    246      1.1.1.5  christos static void
    247      1.1.1.5  christos clear_pipeline_entry(struct xfrd_tcp_pipeline* tp, rbnode_type* node)
    248      1.1.1.5  christos {
    249      1.1.1.5  christos 	struct xfrd_tcp_pipeline_id *n;
    250      1.1.1.5  christos 	if(node == NULL || node == RBTREE_NULL)
    251      1.1.1.5  christos 		return;
    252      1.1.1.5  christos 	clear_pipeline_entry(tp, node->left);
    253      1.1.1.5  christos 	node->left = NULL;
    254      1.1.1.5  christos 	clear_pipeline_entry(tp, node->right);
    255      1.1.1.5  christos 	node->right = NULL;
    256      1.1.1.5  christos 	/* move the node into the free list */
    257      1.1.1.5  christos 	n = (struct xfrd_tcp_pipeline_id*)node;
    258      1.1.1.5  christos 	n->next_free = tp->pipe_id_free_list;
    259      1.1.1.5  christos 	tp->pipe_id_free_list = n;
    260      1.1.1.5  christos }
    261      1.1.1.5  christos 
    262      1.1.1.5  christos static void
    263      1.1.1.5  christos xfrd_tcp_pipeline_cleanup(struct xfrd_tcp_pipeline* tp)
    264      1.1.1.5  christos {
    265      1.1.1.5  christos 	/* move entries into free list */
    266      1.1.1.5  christos 	clear_pipeline_entry(tp, tp->zone_per_id->root);
    267      1.1.1.5  christos 	/* clear the tree */
    268      1.1.1.5  christos 	tp->zone_per_id->count = 0;
    269      1.1.1.5  christos 	tp->zone_per_id->root = RBTREE_NULL;
    270      1.1.1.5  christos }
    271      1.1.1.5  christos 
    272      1.1.1.5  christos static void
    273      1.1.1.5  christos xfrd_tcp_pipeline_init(struct xfrd_tcp_pipeline* tp)
    274      1.1.1.5  christos {
    275      1.1.1.5  christos 	tp->key.node.key = tp;
    276      1.1.1.5  christos 	tp->key.num_unused = tp->pipe_num;
    277      1.1.1.5  christos 	tp->key.num_skip = 0;
    278      1.1.1.5  christos 	tp->tcp_send_first = NULL;
    279      1.1.1.5  christos 	tp->tcp_send_last = NULL;
    280      1.1.1.5  christos 	xfrd_tcp_pipeline_cleanup(tp);
    281      1.1.1.5  christos 	pick_id_values(tp->unused, tp->pipe_num, 65536);
    282      1.1.1.5  christos }
    283      1.1.1.5  christos 
    284          1.1  christos struct xfrd_tcp_pipeline*
    285      1.1.1.5  christos xfrd_tcp_pipeline_create(region_type* region, int tcp_pipeline)
    286          1.1  christos {
    287          1.1  christos 	int i;
    288          1.1  christos 	struct xfrd_tcp_pipeline* tp = (struct xfrd_tcp_pipeline*)
    289          1.1  christos 		region_alloc_zero(region, sizeof(*tp));
    290      1.1.1.5  christos 	if(tcp_pipeline < 0)
    291      1.1.1.5  christos 		tcp_pipeline = 0;
    292      1.1.1.5  christos 	if(tcp_pipeline > 65536)
    293      1.1.1.5  christos 		tcp_pipeline = 65536; /* max 16 bit ID numbers */
    294      1.1.1.5  christos 	tp->pipe_num = tcp_pipeline;
    295      1.1.1.5  christos 	tp->key.num_unused = tp->pipe_num;
    296      1.1.1.5  christos 	tp->zone_per_id = rbtree_create(region, &pipeline_id_compare);
    297      1.1.1.5  christos 	tp->pipe_id_free_list = NULL;
    298      1.1.1.5  christos 	for(i=0; i<tp->pipe_num; i++) {
    299      1.1.1.5  christos 		struct xfrd_tcp_pipeline_id* n = (struct xfrd_tcp_pipeline_id*)
    300      1.1.1.5  christos 			region_alloc_zero(region, sizeof(*n));
    301      1.1.1.5  christos 		n->next_free = tp->pipe_id_free_list;
    302      1.1.1.5  christos 		tp->pipe_id_free_list = n;
    303      1.1.1.5  christos 	}
    304      1.1.1.5  christos 	tp->unused = (uint16_t*)region_alloc_zero(region,
    305      1.1.1.5  christos 		sizeof(tp->unused[0])*tp->pipe_num);
    306          1.1  christos 	tp->tcp_r = xfrd_tcp_create(region, QIOBUFSZ);
    307          1.1  christos 	tp->tcp_w = xfrd_tcp_create(region, 512);
    308      1.1.1.5  christos 	xfrd_tcp_pipeline_init(tp);
    309          1.1  christos 	return tp;
    310          1.1  christos }
    311          1.1  christos 
    312      1.1.1.5  christos static struct xfrd_zone*
    313      1.1.1.5  christos xfrd_tcp_pipeline_lookup_id(struct xfrd_tcp_pipeline* tp, uint16_t id)
    314      1.1.1.5  christos {
    315      1.1.1.5  christos 	struct xfrd_tcp_pipeline_id key;
    316      1.1.1.5  christos 	rbnode_type* n;
    317      1.1.1.5  christos 	memset(&key, 0, sizeof(key));
    318      1.1.1.5  christos 	key.node.key = &key;
    319      1.1.1.5  christos 	key.id = id;
    320      1.1.1.5  christos 	n = rbtree_search(tp->zone_per_id, &key);
    321      1.1.1.5  christos 	if(n && n != RBTREE_NULL) {
    322      1.1.1.5  christos 		return ((struct xfrd_tcp_pipeline_id*)n)->zone;
    323      1.1.1.5  christos 	}
    324      1.1.1.5  christos 	return NULL;
    325      1.1.1.5  christos }
    326      1.1.1.5  christos 
    327      1.1.1.5  christos static void
    328      1.1.1.5  christos xfrd_tcp_pipeline_insert_id(struct xfrd_tcp_pipeline* tp, uint16_t id,
    329      1.1.1.5  christos 	struct xfrd_zone* zone)
    330      1.1.1.5  christos {
    331      1.1.1.5  christos 	struct xfrd_tcp_pipeline_id* n;
    332      1.1.1.5  christos 	/* because there are tp->pipe_num preallocated entries, and we have
    333      1.1.1.5  christos 	 * only tp->pipe_num id values, the list cannot be empty now. */
    334      1.1.1.5  christos 	assert(tp->pipe_id_free_list != NULL);
    335      1.1.1.5  christos 	/* pick up next free xfrd_tcp_pipeline_id node */
    336      1.1.1.5  christos 	n = tp->pipe_id_free_list;
    337      1.1.1.5  christos 	tp->pipe_id_free_list = n->next_free;
    338      1.1.1.5  christos 	n->next_free = NULL;
    339      1.1.1.5  christos 	memset(&n->node, 0, sizeof(n->node));
    340      1.1.1.5  christos 	n->node.key = n;
    341      1.1.1.5  christos 	n->id = id;
    342      1.1.1.5  christos 	n->zone = zone;
    343      1.1.1.5  christos 	rbtree_insert(tp->zone_per_id, &n->node);
    344      1.1.1.5  christos }
    345      1.1.1.5  christos 
    346      1.1.1.5  christos static void
    347      1.1.1.5  christos xfrd_tcp_pipeline_remove_id(struct xfrd_tcp_pipeline* tp, uint16_t id)
    348      1.1.1.5  christos {
    349      1.1.1.5  christos 	struct xfrd_tcp_pipeline_id key;
    350      1.1.1.5  christos 	rbnode_type* node;
    351      1.1.1.5  christos 	memset(&key, 0, sizeof(key));
    352      1.1.1.5  christos 	key.node.key = &key;
    353      1.1.1.5  christos 	key.id = id;
    354      1.1.1.5  christos 	node = rbtree_delete(tp->zone_per_id, &key);
    355      1.1.1.5  christos 	if(node && node != RBTREE_NULL) {
    356      1.1.1.5  christos 		struct xfrd_tcp_pipeline_id* n =
    357      1.1.1.5  christos 			(struct xfrd_tcp_pipeline_id*)node;
    358      1.1.1.5  christos 		n->next_free = tp->pipe_id_free_list;
    359      1.1.1.5  christos 		tp->pipe_id_free_list = n;
    360      1.1.1.5  christos 	}
    361      1.1.1.5  christos }
    362      1.1.1.5  christos 
    363      1.1.1.5  christos static void
    364      1.1.1.5  christos xfrd_tcp_pipeline_skip_id(struct xfrd_tcp_pipeline* tp, uint16_t id)
    365      1.1.1.5  christos {
    366      1.1.1.5  christos 	struct xfrd_tcp_pipeline_id key;
    367      1.1.1.5  christos 	rbnode_type* n;
    368      1.1.1.5  christos 	memset(&key, 0, sizeof(key));
    369      1.1.1.5  christos 	key.node.key = &key;
    370      1.1.1.5  christos 	key.id = id;
    371      1.1.1.5  christos 	n = rbtree_search(tp->zone_per_id, &key);
    372      1.1.1.5  christos 	if(n && n != RBTREE_NULL) {
    373      1.1.1.5  christos 		struct xfrd_tcp_pipeline_id* zid = (struct xfrd_tcp_pipeline_id*)n;
    374      1.1.1.5  christos 		zid->zone = TCP_NULL_SKIP;
    375      1.1.1.5  christos 	}
    376      1.1.1.5  christos }
    377      1.1.1.5  christos 
    378          1.1  christos void
    379          1.1  christos xfrd_setup_packet(buffer_type* packet,
    380          1.1  christos 	uint16_t type, uint16_t klass, const dname_type* dname, uint16_t qid)
    381          1.1  christos {
    382          1.1  christos 	/* Set up the header */
    383          1.1  christos 	buffer_clear(packet);
    384          1.1  christos 	ID_SET(packet, qid);
    385          1.1  christos 	FLAGS_SET(packet, 0);
    386          1.1  christos 	OPCODE_SET(packet, OPCODE_QUERY);
    387          1.1  christos 	QDCOUNT_SET(packet, 1);
    388          1.1  christos 	ANCOUNT_SET(packet, 0);
    389          1.1  christos 	NSCOUNT_SET(packet, 0);
    390          1.1  christos 	ARCOUNT_SET(packet, 0);
    391          1.1  christos 	buffer_skip(packet, QHEADERSZ);
    392          1.1  christos 
    393          1.1  christos 	/* The question record. */
    394          1.1  christos 	buffer_write(packet, dname_name(dname), dname->name_size);
    395          1.1  christos 	buffer_write_u16(packet, type);
    396          1.1  christos 	buffer_write_u16(packet, klass);
    397          1.1  christos }
    398          1.1  christos 
    399          1.1  christos static socklen_t
    400          1.1  christos #ifdef INET6
    401      1.1.1.2  christos xfrd_acl_sockaddr(acl_options_type* acl, unsigned int port,
    402          1.1  christos 	struct sockaddr_storage *sck)
    403          1.1  christos #else
    404      1.1.1.2  christos xfrd_acl_sockaddr(acl_options_type* acl, unsigned int port,
    405          1.1  christos 	struct sockaddr_in *sck, const char* fromto)
    406          1.1  christos #endif /* INET6 */
    407          1.1  christos {
    408          1.1  christos 	/* setup address structure */
    409          1.1  christos #ifdef INET6
    410          1.1  christos 	memset(sck, 0, sizeof(struct sockaddr_storage));
    411          1.1  christos #else
    412          1.1  christos 	memset(sck, 0, sizeof(struct sockaddr_in));
    413          1.1  christos #endif
    414          1.1  christos 	if(acl->is_ipv6) {
    415          1.1  christos #ifdef INET6
    416          1.1  christos 		struct sockaddr_in6* sa = (struct sockaddr_in6*)sck;
    417          1.1  christos 		sa->sin6_family = AF_INET6;
    418          1.1  christos 		sa->sin6_port = htons(port);
    419          1.1  christos 		sa->sin6_addr = acl->addr.addr6;
    420          1.1  christos 		return sizeof(struct sockaddr_in6);
    421          1.1  christos #else
    422          1.1  christos 		log_msg(LOG_ERR, "xfrd: IPv6 connection %s %s attempted but no \
    423          1.1  christos INET6.", fromto, acl->ip_address_spec);
    424          1.1  christos 		return 0;
    425          1.1  christos #endif
    426          1.1  christos 	} else {
    427          1.1  christos 		struct sockaddr_in* sa = (struct sockaddr_in*)sck;
    428          1.1  christos 		sa->sin_family = AF_INET;
    429          1.1  christos 		sa->sin_port = htons(port);
    430          1.1  christos 		sa->sin_addr = acl->addr.addr;
    431          1.1  christos 		return sizeof(struct sockaddr_in);
    432          1.1  christos 	}
    433          1.1  christos }
    434          1.1  christos 
    435          1.1  christos socklen_t
    436          1.1  christos #ifdef INET6
    437      1.1.1.2  christos xfrd_acl_sockaddr_to(acl_options_type* acl, struct sockaddr_storage *to)
    438          1.1  christos #else
    439      1.1.1.2  christos xfrd_acl_sockaddr_to(acl_options_type* acl, struct sockaddr_in *to)
    440          1.1  christos #endif /* INET6 */
    441          1.1  christos {
    442      1.1.1.5  christos #ifdef HAVE_TLS_1_3
    443      1.1.1.5  christos 	unsigned int port = acl->port?acl->port:(acl->tls_auth_options?
    444      1.1.1.5  christos 						(unsigned)atoi(TLS_PORT):(unsigned)atoi(TCP_PORT));
    445      1.1.1.5  christos #else
    446          1.1  christos 	unsigned int port = acl->port?acl->port:(unsigned)atoi(TCP_PORT);
    447      1.1.1.5  christos #endif
    448          1.1  christos #ifdef INET6
    449          1.1  christos 	return xfrd_acl_sockaddr(acl, port, to);
    450          1.1  christos #else
    451          1.1  christos 	return xfrd_acl_sockaddr(acl, port, to, "to");
    452          1.1  christos #endif /* INET6 */
    453          1.1  christos }
    454          1.1  christos 
    455          1.1  christos socklen_t
    456          1.1  christos #ifdef INET6
    457      1.1.1.2  christos xfrd_acl_sockaddr_frm(acl_options_type* acl, struct sockaddr_storage *frm)
    458          1.1  christos #else
    459      1.1.1.2  christos xfrd_acl_sockaddr_frm(acl_options_type* acl, struct sockaddr_in *frm)
    460          1.1  christos #endif /* INET6 */
    461          1.1  christos {
    462          1.1  christos 	unsigned int port = acl->port?acl->port:0;
    463          1.1  christos #ifdef INET6
    464          1.1  christos 	return xfrd_acl_sockaddr(acl, port, frm);
    465          1.1  christos #else
    466          1.1  christos 	return xfrd_acl_sockaddr(acl, port, frm, "from");
    467          1.1  christos #endif /* INET6 */
    468          1.1  christos }
    469          1.1  christos 
    470          1.1  christos void
    471          1.1  christos xfrd_write_soa_buffer(struct buffer* packet,
    472          1.1  christos 	const dname_type* apex, struct xfrd_soa* soa)
    473          1.1  christos {
    474          1.1  christos 	size_t rdlength_pos;
    475          1.1  christos 	uint16_t rdlength;
    476          1.1  christos 	buffer_write(packet, dname_name(apex), apex->name_size);
    477          1.1  christos 
    478          1.1  christos 	/* already in network order */
    479          1.1  christos 	buffer_write(packet, &soa->type, sizeof(soa->type));
    480          1.1  christos 	buffer_write(packet, &soa->klass, sizeof(soa->klass));
    481          1.1  christos 	buffer_write(packet, &soa->ttl, sizeof(soa->ttl));
    482          1.1  christos 	rdlength_pos = buffer_position(packet);
    483          1.1  christos 	buffer_skip(packet, sizeof(rdlength));
    484          1.1  christos 
    485          1.1  christos 	/* uncompressed dnames */
    486          1.1  christos 	buffer_write(packet, soa->prim_ns+1, soa->prim_ns[0]);
    487          1.1  christos 	buffer_write(packet, soa->email+1, soa->email[0]);
    488          1.1  christos 
    489          1.1  christos 	buffer_write(packet, &soa->serial, sizeof(uint32_t));
    490          1.1  christos 	buffer_write(packet, &soa->refresh, sizeof(uint32_t));
    491          1.1  christos 	buffer_write(packet, &soa->retry, sizeof(uint32_t));
    492          1.1  christos 	buffer_write(packet, &soa->expire, sizeof(uint32_t));
    493          1.1  christos 	buffer_write(packet, &soa->minimum, sizeof(uint32_t));
    494          1.1  christos 
    495          1.1  christos 	/* write length of RR */
    496          1.1  christos 	rdlength = buffer_position(packet) - rdlength_pos - sizeof(rdlength);
    497          1.1  christos 	buffer_write_u16_at(packet, rdlength_pos, rdlength);
    498          1.1  christos }
    499          1.1  christos 
    500      1.1.1.2  christos struct xfrd_tcp*
    501          1.1  christos xfrd_tcp_create(region_type* region, size_t bufsize)
    502          1.1  christos {
    503      1.1.1.2  christos 	struct xfrd_tcp* tcp_state = (struct xfrd_tcp*)region_alloc(
    504      1.1.1.2  christos 		region, sizeof(struct xfrd_tcp));
    505      1.1.1.2  christos 	memset(tcp_state, 0, sizeof(struct xfrd_tcp));
    506          1.1  christos 	tcp_state->packet = buffer_create(region, bufsize);
    507          1.1  christos 	tcp_state->fd = -1;
    508          1.1  christos 
    509          1.1  christos 	return tcp_state;
    510          1.1  christos }
    511          1.1  christos 
    512          1.1  christos static struct xfrd_tcp_pipeline*
    513      1.1.1.2  christos pipeline_find(struct xfrd_tcp_set* set, xfrd_zone_type* zone)
    514          1.1  christos {
    515      1.1.1.2  christos 	rbnode_type* sme = NULL;
    516          1.1  christos 	struct xfrd_tcp_pipeline* r;
    517          1.1  christos 	/* smaller buf than a full pipeline with 64kb ID array, only need
    518          1.1  christos 	 * the front part with the key info, this front part contains the
    519          1.1  christos 	 * members that the compare function uses. */
    520      1.1.1.5  christos 	struct xfrd_tcp_pipeline_key k, *key=&k;
    521          1.1  christos 	key->node.key = key;
    522          1.1  christos 	key->ip_len = xfrd_acl_sockaddr_to(zone->master, &key->ip);
    523      1.1.1.5  christos 	key->num_unused = set->tcp_pipeline;
    524          1.1  christos 	/* lookup existing tcp transfer to the master with highest unused */
    525          1.1  christos 	if(rbtree_find_less_equal(set->pipetree, key, &sme)) {
    526          1.1  christos 		/* exact match, strange, fully unused tcp cannot be open */
    527          1.1  christos 		assert(0);
    528          1.1  christos 	}
    529          1.1  christos 	if(!sme)
    530          1.1  christos 		return NULL;
    531          1.1  christos 	r = (struct xfrd_tcp_pipeline*)sme->key;
    532          1.1  christos 	/* <= key pointed at, is the master correct ? */
    533      1.1.1.5  christos 	if(r->key.ip_len != key->ip_len)
    534          1.1  christos 		return NULL;
    535      1.1.1.5  christos 	if(memcmp(&r->key.ip, &key->ip, key->ip_len) != 0)
    536          1.1  christos 		return NULL;
    537          1.1  christos 	/* correct master, is there a slot free for this transfer? */
    538      1.1.1.5  christos 	if(r->key.num_unused == 0)
    539          1.1  christos 		return NULL;
    540          1.1  christos 	return r;
    541          1.1  christos }
    542          1.1  christos 
    543          1.1  christos /* remove zone from tcp waiting list */
    544          1.1  christos static void
    545      1.1.1.2  christos tcp_zone_waiting_list_popfirst(struct xfrd_tcp_set* set, xfrd_zone_type* zone)
    546          1.1  christos {
    547          1.1  christos 	assert(zone->tcp_waiting);
    548          1.1  christos 	set->tcp_waiting_first = zone->tcp_waiting_next;
    549          1.1  christos 	if(zone->tcp_waiting_next)
    550          1.1  christos 		zone->tcp_waiting_next->tcp_waiting_prev = NULL;
    551          1.1  christos 	else	set->tcp_waiting_last = 0;
    552          1.1  christos 	zone->tcp_waiting_next = 0;
    553          1.1  christos 	zone->tcp_waiting = 0;
    554          1.1  christos }
    555          1.1  christos 
    556          1.1  christos /* remove zone from tcp pipe write-wait list */
    557          1.1  christos static void
    558      1.1.1.2  christos tcp_pipe_sendlist_remove(struct xfrd_tcp_pipeline* tp, xfrd_zone_type* zone)
    559          1.1  christos {
    560          1.1  christos 	if(zone->in_tcp_send) {
    561          1.1  christos 		if(zone->tcp_send_prev)
    562          1.1  christos 			zone->tcp_send_prev->tcp_send_next=zone->tcp_send_next;
    563          1.1  christos 		else	tp->tcp_send_first=zone->tcp_send_next;
    564          1.1  christos 		if(zone->tcp_send_next)
    565          1.1  christos 			zone->tcp_send_next->tcp_send_prev=zone->tcp_send_prev;
    566          1.1  christos 		else	tp->tcp_send_last=zone->tcp_send_prev;
    567          1.1  christos 		zone->in_tcp_send = 0;
    568          1.1  christos 	}
    569          1.1  christos }
    570          1.1  christos 
    571          1.1  christos /* remove first from write-wait list */
    572          1.1  christos static void
    573      1.1.1.2  christos tcp_pipe_sendlist_popfirst(struct xfrd_tcp_pipeline* tp, xfrd_zone_type* zone)
    574          1.1  christos {
    575          1.1  christos 	tp->tcp_send_first = zone->tcp_send_next;
    576          1.1  christos 	if(tp->tcp_send_first)
    577          1.1  christos 		tp->tcp_send_first->tcp_send_prev = NULL;
    578          1.1  christos 	else	tp->tcp_send_last = NULL;
    579          1.1  christos 	zone->in_tcp_send = 0;
    580          1.1  christos }
    581          1.1  christos 
    582          1.1  christos /* remove zone from tcp pipe ID map */
    583          1.1  christos static void
    584      1.1.1.5  christos tcp_pipe_id_remove(struct xfrd_tcp_pipeline* tp, xfrd_zone_type* zone,
    585      1.1.1.5  christos 	int alsotree)
    586          1.1  christos {
    587      1.1.1.5  christos 	assert(tp->key.num_unused < tp->pipe_num && tp->key.num_unused >= 0);
    588      1.1.1.5  christos 	if(alsotree)
    589      1.1.1.5  christos 		xfrd_tcp_pipeline_remove_id(tp, zone->query_id);
    590      1.1.1.5  christos 	tp->unused[tp->key.num_unused] = zone->query_id;
    591          1.1  christos 	/* must remove and re-add for sort order in tree */
    592      1.1.1.5  christos 	(void)rbtree_delete(xfrd->tcp_set->pipetree, &tp->key.node);
    593      1.1.1.5  christos 	tp->key.num_unused++;
    594      1.1.1.5  christos 	(void)rbtree_insert(xfrd->tcp_set->pipetree, &tp->key.node);
    595          1.1  christos }
    596          1.1  christos 
    597          1.1  christos /* stop the tcp pipe (and all its zones need to retry) */
    598          1.1  christos static void
    599          1.1  christos xfrd_tcp_pipe_stop(struct xfrd_tcp_pipeline* tp)
    600          1.1  christos {
    601      1.1.1.5  christos 	struct xfrd_tcp_pipeline_id* zid;
    602      1.1.1.5  christos 	int conn = -1;
    603      1.1.1.5  christos 	assert(tp->key.num_unused < tp->pipe_num); /* at least one 'in-use' */
    604      1.1.1.5  christos 	assert(tp->pipe_num - tp->key.num_unused > tp->key.num_skip); /* at least one 'nonskip' */
    605          1.1  christos 	/* need to retry for all the zones connected to it */
    606          1.1  christos 	/* these could use different lists and go to a different nextmaster*/
    607      1.1.1.5  christos 	RBTREE_FOR(zid, struct xfrd_tcp_pipeline_id*, tp->zone_per_id) {
    608      1.1.1.5  christos 		xfrd_zone_type* zone = zid->zone;
    609      1.1.1.5  christos 		if(zone && zone != TCP_NULL_SKIP) {
    610      1.1.1.5  christos 			assert(zone->query_id == zid->id);
    611          1.1  christos 			conn = zone->tcp_conn;
    612          1.1  christos 			zone->tcp_conn = -1;
    613          1.1  christos 			zone->tcp_waiting = 0;
    614          1.1  christos 			tcp_pipe_sendlist_remove(tp, zone);
    615      1.1.1.5  christos 			tcp_pipe_id_remove(tp, zone, 0);
    616          1.1  christos 			xfrd_set_refresh_now(zone);
    617          1.1  christos 		}
    618          1.1  christos 	}
    619      1.1.1.5  christos 	xfrd_tcp_pipeline_cleanup(tp);
    620          1.1  christos 	assert(conn != -1);
    621          1.1  christos 	/* now release the entire tcp pipe */
    622          1.1  christos 	xfrd_tcp_pipe_release(xfrd->tcp_set, tp, conn);
    623          1.1  christos }
    624          1.1  christos 
    625          1.1  christos static void
    626          1.1  christos tcp_pipe_reset_timeout(struct xfrd_tcp_pipeline* tp)
    627          1.1  christos {
    628          1.1  christos 	int fd = tp->handler.ev_fd;
    629          1.1  christos 	struct timeval tv;
    630          1.1  christos 	tv.tv_sec = xfrd->tcp_set->tcp_timeout;
    631          1.1  christos 	tv.tv_usec = 0;
    632          1.1  christos 	if(tp->handler_added)
    633          1.1  christos 		event_del(&tp->handler);
    634      1.1.1.3  christos 	memset(&tp->handler, 0, sizeof(tp->handler));
    635          1.1  christos 	event_set(&tp->handler, fd, EV_PERSIST|EV_TIMEOUT|EV_READ|
    636      1.1.1.5  christos #ifdef HAVE_TLS_1_3
    637      1.1.1.5  christos 		( tp->ssl
    638      1.1.1.5  christos 		? ( tp->handshake_done ?  ( tp->tcp_send_first ? EV_WRITE : 0 )
    639      1.1.1.5  christos 		  : tp->handshake_want == SSL_ERROR_WANT_WRITE ? EV_WRITE : 0 )
    640      1.1.1.5  christos 		: tp->tcp_send_first ? EV_WRITE : 0 ),
    641      1.1.1.5  christos #else
    642      1.1.1.5  christos 		( tp->tcp_send_first ? EV_WRITE : 0 ),
    643      1.1.1.5  christos #endif
    644      1.1.1.5  christos 		xfrd_handle_tcp_pipe, tp);
    645          1.1  christos 	if(event_base_set(xfrd->event_base, &tp->handler) != 0)
    646          1.1  christos 		log_msg(LOG_ERR, "xfrd tcp: event_base_set failed");
    647          1.1  christos 	if(event_add(&tp->handler, &tv) != 0)
    648          1.1  christos 		log_msg(LOG_ERR, "xfrd tcp: event_add failed");
    649          1.1  christos 	tp->handler_added = 1;
    650          1.1  christos }
    651          1.1  christos 
    652          1.1  christos /* handle event from fd of tcp pipe */
    653          1.1  christos void
    654          1.1  christos xfrd_handle_tcp_pipe(int ATTR_UNUSED(fd), short event, void* arg)
    655          1.1  christos {
    656          1.1  christos 	struct xfrd_tcp_pipeline* tp = (struct xfrd_tcp_pipeline*)arg;
    657          1.1  christos 	if((event & EV_WRITE)) {
    658          1.1  christos 		tcp_pipe_reset_timeout(tp);
    659          1.1  christos 		if(tp->tcp_send_first) {
    660          1.1  christos 			DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd: event tcp write, zone %s",
    661          1.1  christos 				tp->tcp_send_first->apex_str));
    662          1.1  christos 			xfrd_tcp_write(tp, tp->tcp_send_first);
    663          1.1  christos 		}
    664          1.1  christos 	}
    665          1.1  christos 	if((event & EV_READ) && tp->handler_added) {
    666          1.1  christos 		DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd: event tcp read"));
    667          1.1  christos 		tcp_pipe_reset_timeout(tp);
    668          1.1  christos 		xfrd_tcp_read(tp);
    669          1.1  christos 	}
    670          1.1  christos 	if((event & EV_TIMEOUT) && tp->handler_added) {
    671          1.1  christos 		/* tcp connection timed out */
    672          1.1  christos 		DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd: event tcp timeout"));
    673          1.1  christos 		xfrd_tcp_pipe_stop(tp);
    674          1.1  christos 	}
    675          1.1  christos }
    676          1.1  christos 
    677          1.1  christos /* add a zone to the pipeline, it starts to want to write its query */
    678          1.1  christos static void
    679      1.1.1.2  christos pipeline_setup_new_zone(struct xfrd_tcp_set* set, struct xfrd_tcp_pipeline* tp,
    680      1.1.1.2  christos 	xfrd_zone_type* zone)
    681          1.1  christos {
    682          1.1  christos 	/* assign the ID */
    683          1.1  christos 	int idx;
    684      1.1.1.5  christos 	assert(tp->key.num_unused > 0);
    685          1.1  christos 	/* we pick a random ID, even though it is TCP anyway */
    686      1.1.1.5  christos 	idx = random_generate(tp->key.num_unused);
    687          1.1  christos 	zone->query_id = tp->unused[idx];
    688      1.1.1.5  christos 	tp->unused[idx] = tp->unused[tp->key.num_unused-1];
    689      1.1.1.5  christos 	xfrd_tcp_pipeline_insert_id(tp, zone->query_id, zone);
    690          1.1  christos 	/* decrement unused counter, and fixup tree */
    691      1.1.1.5  christos 	(void)rbtree_delete(set->pipetree, &tp->key.node);
    692      1.1.1.5  christos 	tp->key.num_unused--;
    693      1.1.1.5  christos 	(void)rbtree_insert(set->pipetree, &tp->key.node);
    694          1.1  christos 
    695          1.1  christos 	/* add to sendlist, at end */
    696          1.1  christos 	zone->tcp_send_next = NULL;
    697          1.1  christos 	zone->tcp_send_prev = tp->tcp_send_last;
    698          1.1  christos 	zone->in_tcp_send = 1;
    699          1.1  christos 	if(tp->tcp_send_last)
    700          1.1  christos 		tp->tcp_send_last->tcp_send_next = zone;
    701          1.1  christos 	else	tp->tcp_send_first = zone;
    702          1.1  christos 	tp->tcp_send_last = zone;
    703          1.1  christos 
    704          1.1  christos 	/* is it first in line? */
    705          1.1  christos 	if(tp->tcp_send_first == zone) {
    706          1.1  christos 		xfrd_tcp_setup_write_packet(tp, zone);
    707          1.1  christos 		/* add write to event handler */
    708          1.1  christos 		tcp_pipe_reset_timeout(tp);
    709          1.1  christos 	}
    710          1.1  christos }
    711          1.1  christos 
    712          1.1  christos void
    713      1.1.1.2  christos xfrd_tcp_obtain(struct xfrd_tcp_set* set, xfrd_zone_type* zone)
    714          1.1  christos {
    715          1.1  christos 	struct xfrd_tcp_pipeline* tp;
    716          1.1  christos 	assert(zone->tcp_conn == -1);
    717          1.1  christos 	assert(zone->tcp_waiting == 0);
    718          1.1  christos 
    719      1.1.1.5  christos 	if(set->tcp_count < set->tcp_max) {
    720          1.1  christos 		int i;
    721          1.1  christos 		assert(!set->tcp_waiting_first);
    722          1.1  christos 		set->tcp_count ++;
    723          1.1  christos 		/* find a free tcp_buffer */
    724      1.1.1.5  christos 		for(i=0; i<set->tcp_max; i++) {
    725          1.1  christos 			if(set->tcp_state[i]->tcp_r->fd == -1) {
    726          1.1  christos 				zone->tcp_conn = i;
    727          1.1  christos 				break;
    728          1.1  christos 			}
    729          1.1  christos 		}
    730          1.1  christos 		/** What if there is no free tcp_buffer? return; */
    731          1.1  christos 		if (zone->tcp_conn < 0) {
    732          1.1  christos 			return;
    733          1.1  christos 		}
    734          1.1  christos 
    735          1.1  christos 		tp = set->tcp_state[zone->tcp_conn];
    736          1.1  christos 		zone->tcp_waiting = 0;
    737          1.1  christos 
    738          1.1  christos 		/* stop udp use (if any) */
    739          1.1  christos 		if(zone->zone_handler.ev_fd != -1)
    740          1.1  christos 			xfrd_udp_release(zone);
    741          1.1  christos 
    742          1.1  christos 		if(!xfrd_tcp_open(set, tp, zone)) {
    743          1.1  christos 			zone->tcp_conn = -1;
    744          1.1  christos 			set->tcp_count --;
    745          1.1  christos 			xfrd_set_refresh_now(zone);
    746          1.1  christos 			return;
    747          1.1  christos 		}
    748          1.1  christos 		/* ip and ip_len set by tcp_open */
    749      1.1.1.5  christos 		xfrd_tcp_pipeline_init(tp);
    750          1.1  christos 
    751          1.1  christos 		/* insert into tree */
    752      1.1.1.5  christos 		(void)rbtree_insert(set->pipetree, &tp->key.node);
    753          1.1  christos 		xfrd_deactivate_zone(zone);
    754          1.1  christos 		xfrd_unset_timer(zone);
    755          1.1  christos 		pipeline_setup_new_zone(set, tp, zone);
    756          1.1  christos 		return;
    757          1.1  christos 	}
    758          1.1  christos 	/* check for a pipeline to the same master with unused ID */
    759          1.1  christos 	if((tp = pipeline_find(set, zone))!= NULL) {
    760          1.1  christos 		int i;
    761          1.1  christos 		if(zone->zone_handler.ev_fd != -1)
    762          1.1  christos 			xfrd_udp_release(zone);
    763      1.1.1.5  christos 		for(i=0; i<set->tcp_max; i++) {
    764          1.1  christos 			if(set->tcp_state[i] == tp)
    765          1.1  christos 				zone->tcp_conn = i;
    766          1.1  christos 		}
    767          1.1  christos 		xfrd_deactivate_zone(zone);
    768          1.1  christos 		xfrd_unset_timer(zone);
    769          1.1  christos 		pipeline_setup_new_zone(set, tp, zone);
    770          1.1  christos 		return;
    771          1.1  christos 	}
    772          1.1  christos 
    773          1.1  christos 	/* wait, at end of line */
    774          1.1  christos 	DEBUG(DEBUG_XFRD,2, (LOG_INFO, "xfrd: max number of tcp "
    775      1.1.1.5  christos 		"connections (%d) reached.", set->tcp_max));
    776          1.1  christos 	zone->tcp_waiting_next = 0;
    777          1.1  christos 	zone->tcp_waiting_prev = set->tcp_waiting_last;
    778          1.1  christos 	zone->tcp_waiting = 1;
    779          1.1  christos 	if(!set->tcp_waiting_last) {
    780          1.1  christos 		set->tcp_waiting_first = zone;
    781          1.1  christos 		set->tcp_waiting_last = zone;
    782          1.1  christos 	} else {
    783          1.1  christos 		set->tcp_waiting_last->tcp_waiting_next = zone;
    784          1.1  christos 		set->tcp_waiting_last = zone;
    785          1.1  christos 	}
    786          1.1  christos 	xfrd_deactivate_zone(zone);
    787          1.1  christos 	xfrd_unset_timer(zone);
    788          1.1  christos }
    789          1.1  christos 
    790          1.1  christos int
    791      1.1.1.2  christos xfrd_tcp_open(struct xfrd_tcp_set* set, struct xfrd_tcp_pipeline* tp,
    792      1.1.1.2  christos 	xfrd_zone_type* zone)
    793          1.1  christos {
    794          1.1  christos 	int fd, family, conn;
    795          1.1  christos 	struct timeval tv;
    796          1.1  christos 	assert(zone->tcp_conn != -1);
    797          1.1  christos 
    798          1.1  christos 	/* if there is no next master, fallback to use the first one */
    799          1.1  christos 	/* but there really should be a master set */
    800          1.1  christos 	if(!zone->master) {
    801          1.1  christos 		zone->master = zone->zone_options->pattern->request_xfr;
    802          1.1  christos 		zone->master_num = 0;
    803          1.1  christos 	}
    804          1.1  christos 
    805          1.1  christos 	DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd: zone %s open tcp conn to %s",
    806          1.1  christos 		zone->apex_str, zone->master->ip_address_spec));
    807          1.1  christos 	tp->tcp_r->is_reading = 1;
    808          1.1  christos 	tp->tcp_r->total_bytes = 0;
    809          1.1  christos 	tp->tcp_r->msglen = 0;
    810          1.1  christos 	buffer_clear(tp->tcp_r->packet);
    811          1.1  christos 	tp->tcp_w->is_reading = 0;
    812          1.1  christos 	tp->tcp_w->total_bytes = 0;
    813          1.1  christos 	tp->tcp_w->msglen = 0;
    814          1.1  christos 	tp->connection_established = 0;
    815          1.1  christos 
    816          1.1  christos 	if(zone->master->is_ipv6) {
    817          1.1  christos #ifdef INET6
    818          1.1  christos 		family = PF_INET6;
    819          1.1  christos #else
    820          1.1  christos 		xfrd_set_refresh_now(zone);
    821          1.1  christos 		return 0;
    822          1.1  christos #endif
    823          1.1  christos 	} else {
    824          1.1  christos 		family = PF_INET;
    825          1.1  christos 	}
    826          1.1  christos 	fd = socket(family, SOCK_STREAM, IPPROTO_TCP);
    827          1.1  christos 	if(fd == -1) {
    828      1.1.1.2  christos 		/* squelch 'Address family not supported by protocol' at low
    829      1.1.1.2  christos 		 * verbosity levels */
    830      1.1.1.2  christos 		if(errno != EAFNOSUPPORT || verbosity > 2)
    831      1.1.1.2  christos 		    log_msg(LOG_ERR, "xfrd: %s cannot create tcp socket: %s",
    832          1.1  christos 			zone->master->ip_address_spec, strerror(errno));
    833          1.1  christos 		xfrd_set_refresh_now(zone);
    834          1.1  christos 		return 0;
    835          1.1  christos 	}
    836          1.1  christos 	if(fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
    837          1.1  christos 		log_msg(LOG_ERR, "xfrd: fcntl failed: %s", strerror(errno));
    838          1.1  christos 		close(fd);
    839          1.1  christos 		xfrd_set_refresh_now(zone);
    840          1.1  christos 		return 0;
    841          1.1  christos 	}
    842          1.1  christos 
    843          1.1  christos 	if(xfrd->nsd->outgoing_tcp_mss > 0) {
    844          1.1  christos #if defined(IPPROTO_TCP) && defined(TCP_MAXSEG)
    845          1.1  christos 		if(setsockopt(fd, IPPROTO_TCP, TCP_MAXSEG,
    846          1.1  christos 			(void*)&xfrd->nsd->outgoing_tcp_mss,
    847          1.1  christos 			sizeof(xfrd->nsd->outgoing_tcp_mss)) < 0) {
    848          1.1  christos 			log_msg(LOG_ERR, "xfrd: setsockopt(TCP_MAXSEG)"
    849          1.1  christos 					"failed: %s", strerror(errno));
    850          1.1  christos 		}
    851          1.1  christos #else
    852          1.1  christos 		log_msg(LOG_ERR, "setsockopt(TCP_MAXSEG) unsupported");
    853          1.1  christos #endif
    854          1.1  christos 	}
    855          1.1  christos 
    856      1.1.1.5  christos 	tp->key.ip_len = xfrd_acl_sockaddr_to(zone->master, &tp->key.ip);
    857          1.1  christos 
    858          1.1  christos 	/* bind it */
    859          1.1  christos 	if (!xfrd_bind_local_interface(fd, zone->zone_options->pattern->
    860          1.1  christos 		outgoing_interface, zone->master, 1)) {
    861          1.1  christos 		close(fd);
    862          1.1  christos 		xfrd_set_refresh_now(zone);
    863          1.1  christos 		return 0;
    864          1.1  christos         }
    865          1.1  christos 
    866      1.1.1.5  christos 	conn = connect(fd, (struct sockaddr*)&tp->key.ip, tp->key.ip_len);
    867          1.1  christos 	if (conn == -1 && errno != EINPROGRESS) {
    868          1.1  christos 		log_msg(LOG_ERR, "xfrd: connect %s failed: %s",
    869          1.1  christos 			zone->master->ip_address_spec, strerror(errno));
    870          1.1  christos 		close(fd);
    871          1.1  christos 		xfrd_set_refresh_now(zone);
    872          1.1  christos 		return 0;
    873          1.1  christos 	}
    874          1.1  christos 	tp->tcp_r->fd = fd;
    875          1.1  christos 	tp->tcp_w->fd = fd;
    876          1.1  christos 
    877      1.1.1.5  christos 	/* Check if an tls_auth name is configured which means we should try to
    878      1.1.1.5  christos 	   establish an SSL connection */
    879      1.1.1.5  christos 	if (zone->master->tls_auth_options &&
    880      1.1.1.5  christos 		zone->master->tls_auth_options->auth_domain_name) {
    881      1.1.1.5  christos #ifdef HAVE_TLS_1_3
    882      1.1.1.5  christos 		if (!setup_ssl(tp, set, zone->master->tls_auth_options->auth_domain_name)) {
    883      1.1.1.5  christos 			log_msg(LOG_ERR, "xfrd: Cannot setup TLS on pipeline for %s to %s",
    884      1.1.1.5  christos 					zone->apex_str, zone->master->ip_address_spec);
    885      1.1.1.5  christos 			close(fd);
    886      1.1.1.5  christos 			xfrd_set_refresh_now(zone);
    887      1.1.1.5  christos 			return 0;
    888      1.1.1.5  christos 		}
    889      1.1.1.5  christos 
    890      1.1.1.5  christos 		/* Load client certificate (if provided) */
    891      1.1.1.5  christos 		if (zone->master->tls_auth_options->client_cert &&
    892      1.1.1.5  christos 		    zone->master->tls_auth_options->client_key) {
    893      1.1.1.5  christos 			if (SSL_CTX_use_certificate_chain_file(set->ssl_ctx,
    894      1.1.1.5  christos 			                                       zone->master->tls_auth_options->client_cert) != 1) {
    895      1.1.1.5  christos 				log_msg(LOG_ERR, "xfrd tls: Unable to load client certificate from file %s", zone->master->tls_auth_options->client_cert);
    896      1.1.1.5  christos 			}
    897      1.1.1.5  christos 
    898      1.1.1.5  christos 			if (zone->master->tls_auth_options->client_key_pw) {
    899      1.1.1.5  christos 				SSL_CTX_set_default_passwd_cb(set->ssl_ctx, password_cb);
    900      1.1.1.5  christos 				SSL_CTX_set_default_passwd_cb_userdata(set->ssl_ctx, zone->master->tls_auth_options->client_key_pw);
    901      1.1.1.5  christos 			}
    902      1.1.1.5  christos 
    903      1.1.1.5  christos 			if (SSL_CTX_use_PrivateKey_file(set->ssl_ctx, zone->master->tls_auth_options->client_key, SSL_FILETYPE_PEM) != 1) {
    904      1.1.1.5  christos 				log_msg(LOG_ERR, "xfrd tls: Unable to load private key from file %s", zone->master->tls_auth_options->client_key);
    905      1.1.1.5  christos 			}
    906      1.1.1.5  christos 		}
    907      1.1.1.5  christos 
    908      1.1.1.5  christos 		tp->handshake_done = 0;
    909      1.1.1.5  christos 		if(!ssl_handshake(tp)) {
    910      1.1.1.5  christos 			if(tp->handshake_want == SSL_ERROR_SYSCALL) {
    911      1.1.1.5  christos 				log_msg(LOG_ERR, "xfrd: TLS handshake failed "
    912      1.1.1.5  christos 					"for %s to %s: %s", zone->apex_str,
    913      1.1.1.5  christos 					zone->master->ip_address_spec,
    914      1.1.1.5  christos 					strerror(errno));
    915      1.1.1.5  christos 
    916      1.1.1.5  christos 			} else if(tp->handshake_want == SSL_ERROR_SSL) {
    917      1.1.1.5  christos 				char errmsg[1024];
    918      1.1.1.5  christos 				snprintf(errmsg, sizeof(errmsg), "xfrd: "
    919      1.1.1.5  christos 					"TLS handshake failed for %s to %s",
    920      1.1.1.5  christos 					zone->apex_str,
    921      1.1.1.5  christos 					zone->master->ip_address_spec);
    922      1.1.1.5  christos 				log_crypto_err(errmsg);
    923      1.1.1.5  christos 			} else {
    924      1.1.1.5  christos 				log_msg(LOG_ERR, "xfrd: TLS handshake failed "
    925      1.1.1.5  christos 					"for %s to %s with %d", zone->apex_str,
    926      1.1.1.5  christos 					zone->master->ip_address_spec,
    927      1.1.1.5  christos 					tp->handshake_want);
    928      1.1.1.5  christos 			}
    929      1.1.1.5  christos 			close(fd);
    930      1.1.1.5  christos 			xfrd_set_refresh_now(zone);
    931      1.1.1.5  christos 			return 0;
    932      1.1.1.5  christos 		}
    933      1.1.1.5  christos #else
    934      1.1.1.5  christos 		log_msg(LOG_ERR, "xfrd: TLS 1.3 is not available, XFR-over-TLS is "
    935      1.1.1.5  christos 						 "not supported for %s to %s",
    936      1.1.1.5  christos 						  zone->apex_str, zone->master->ip_address_spec);
    937      1.1.1.5  christos 		close(fd);
    938      1.1.1.5  christos 		xfrd_set_refresh_now(zone);
    939      1.1.1.5  christos 		return 0;
    940      1.1.1.5  christos #endif
    941      1.1.1.5  christos 	}
    942      1.1.1.5  christos 
    943          1.1  christos 	/* set the tcp pipe event */
    944          1.1  christos 	if(tp->handler_added)
    945          1.1  christos 		event_del(&tp->handler);
    946      1.1.1.3  christos 	memset(&tp->handler, 0, sizeof(tp->handler));
    947      1.1.1.5  christos 	event_set(&tp->handler, fd, EV_PERSIST|EV_TIMEOUT|EV_READ|
    948      1.1.1.5  christos #ifdef HAVE_TLS_1_3
    949      1.1.1.5  christos 		( !tp->ssl
    950      1.1.1.5  christos 		|| tp->handshake_done
    951      1.1.1.5  christos 		|| tp->handshake_want == SSL_ERROR_WANT_WRITE ? EV_WRITE : 0),
    952      1.1.1.5  christos #else
    953      1.1.1.5  christos 		EV_WRITE,
    954      1.1.1.5  christos #endif
    955      1.1.1.5  christos 	        xfrd_handle_tcp_pipe, tp);
    956          1.1  christos 	if(event_base_set(xfrd->event_base, &tp->handler) != 0)
    957          1.1  christos 		log_msg(LOG_ERR, "xfrd tcp: event_base_set failed");
    958          1.1  christos 	tv.tv_sec = set->tcp_timeout;
    959          1.1  christos 	tv.tv_usec = 0;
    960          1.1  christos 	if(event_add(&tp->handler, &tv) != 0)
    961          1.1  christos 		log_msg(LOG_ERR, "xfrd tcp: event_add failed");
    962          1.1  christos 	tp->handler_added = 1;
    963          1.1  christos 	return 1;
    964          1.1  christos }
    965          1.1  christos 
    966          1.1  christos void
    967      1.1.1.2  christos xfrd_tcp_setup_write_packet(struct xfrd_tcp_pipeline* tp, xfrd_zone_type* zone)
    968          1.1  christos {
    969      1.1.1.2  christos 	struct xfrd_tcp* tcp = tp->tcp_w;
    970          1.1  christos 	assert(zone->tcp_conn != -1);
    971          1.1  christos 	assert(zone->tcp_waiting == 0);
    972          1.1  christos 	/* start AXFR or IXFR for the zone */
    973          1.1  christos 	if(zone->soa_disk_acquired == 0 || zone->master->use_axfr_only ||
    974          1.1  christos 		zone->master->ixfr_disabled ||
    975          1.1  christos 		/* if zone expired, after the first round, do not ask for
    976          1.1  christos 		 * IXFR any more, but full AXFR (of any serial number) */
    977          1.1  christos 		(zone->state == xfrd_zone_expired && zone->round_num != 0)) {
    978          1.1  christos 		DEBUG(DEBUG_XFRD,1, (LOG_INFO, "request full zone transfer "
    979          1.1  christos 						"(AXFR) for %s to %s",
    980          1.1  christos 			zone->apex_str, zone->master->ip_address_spec));
    981          1.1  christos 
    982          1.1  christos 		xfrd_setup_packet(tcp->packet, TYPE_AXFR, CLASS_IN, zone->apex,
    983          1.1  christos 			zone->query_id);
    984      1.1.1.5  christos 		xfrd_prepare_zone_xfr(zone, TYPE_AXFR);
    985          1.1  christos 	} else {
    986          1.1  christos 		DEBUG(DEBUG_XFRD,1, (LOG_INFO, "request incremental zone "
    987          1.1  christos 						"transfer (IXFR) for %s to %s",
    988          1.1  christos 			zone->apex_str, zone->master->ip_address_spec));
    989          1.1  christos 
    990          1.1  christos 		xfrd_setup_packet(tcp->packet, TYPE_IXFR, CLASS_IN, zone->apex,
    991          1.1  christos 			zone->query_id);
    992      1.1.1.5  christos 		xfrd_prepare_zone_xfr(zone, TYPE_IXFR);
    993      1.1.1.5  christos 		NSCOUNT_SET(tcp->packet, 1);
    994          1.1  christos 		xfrd_write_soa_buffer(tcp->packet, zone->apex, &zone->soa_disk);
    995          1.1  christos 	}
    996          1.1  christos 	if(zone->master->key_options && zone->master->key_options->tsig_key) {
    997      1.1.1.5  christos 		xfrd_tsig_sign_request(
    998      1.1.1.5  christos 			tcp->packet, &zone->latest_xfr->tsig, zone->master);
    999          1.1  christos 	}
   1000          1.1  christos 	buffer_flip(tcp->packet);
   1001          1.1  christos 	DEBUG(DEBUG_XFRD,1, (LOG_INFO, "sent tcp query with ID %d", zone->query_id));
   1002          1.1  christos 	tcp->msglen = buffer_limit(tcp->packet);
   1003          1.1  christos 	tcp->total_bytes = 0;
   1004          1.1  christos }
   1005          1.1  christos 
   1006          1.1  christos static void
   1007      1.1.1.2  christos tcp_conn_ready_for_reading(struct xfrd_tcp* tcp)
   1008          1.1  christos {
   1009          1.1  christos 	tcp->total_bytes = 0;
   1010          1.1  christos 	tcp->msglen = 0;
   1011          1.1  christos 	buffer_clear(tcp->packet);
   1012          1.1  christos }
   1013          1.1  christos 
   1014      1.1.1.5  christos #ifdef HAVE_TLS_1_3
   1015      1.1.1.5  christos static int
   1016      1.1.1.5  christos conn_write_ssl(struct xfrd_tcp* tcp, SSL* ssl)
   1017      1.1.1.5  christos {
   1018      1.1.1.5  christos 	int request_length;
   1019      1.1.1.5  christos 	ssize_t sent;
   1020      1.1.1.5  christos 
   1021      1.1.1.5  christos 	if(tcp->total_bytes < sizeof(tcp->msglen)) {
   1022      1.1.1.5  christos 		uint16_t sendlen = htons(tcp->msglen);
   1023      1.1.1.5  christos 		// send
   1024      1.1.1.5  christos 		request_length = sizeof(tcp->msglen) - tcp->total_bytes;
   1025      1.1.1.5  christos 		ERR_clear_error();
   1026      1.1.1.5  christos 		sent = SSL_write(ssl, (const char*)&sendlen + tcp->total_bytes,
   1027      1.1.1.5  christos 						 request_length);
   1028      1.1.1.5  christos 		switch(SSL_get_error(ssl,sent)) {
   1029      1.1.1.5  christos 			case SSL_ERROR_NONE:
   1030      1.1.1.5  christos 				break;
   1031      1.1.1.5  christos 			default:
   1032      1.1.1.5  christos 				log_msg(LOG_ERR, "xfrd: generic write problem with tls");
   1033      1.1.1.5  christos 		}
   1034      1.1.1.5  christos 
   1035      1.1.1.5  christos 		if(sent == -1) {
   1036      1.1.1.5  christos 			if(errno == EAGAIN || errno == EINTR) {
   1037      1.1.1.5  christos 				/* write would block, try later */
   1038      1.1.1.5  christos 				return 0;
   1039      1.1.1.5  christos 			} else {
   1040      1.1.1.5  christos 				return -1;
   1041      1.1.1.5  christos 			}
   1042      1.1.1.5  christos 		}
   1043      1.1.1.5  christos 
   1044      1.1.1.5  christos 		tcp->total_bytes += sent;
   1045      1.1.1.5  christos 		if(sent > (ssize_t)sizeof(tcp->msglen))
   1046      1.1.1.5  christos 			buffer_skip(tcp->packet, sent-sizeof(tcp->msglen));
   1047      1.1.1.5  christos 		if(tcp->total_bytes < sizeof(tcp->msglen)) {
   1048      1.1.1.5  christos 			/* incomplete write, resume later */
   1049      1.1.1.5  christos 			return 0;
   1050      1.1.1.5  christos 		}
   1051      1.1.1.5  christos 		assert(tcp->total_bytes >= sizeof(tcp->msglen));
   1052      1.1.1.5  christos 	}
   1053      1.1.1.5  christos 
   1054      1.1.1.5  christos 	assert(tcp->total_bytes < tcp->msglen + sizeof(tcp->msglen));
   1055      1.1.1.5  christos 
   1056      1.1.1.5  christos 	request_length = buffer_remaining(tcp->packet);
   1057      1.1.1.5  christos 	ERR_clear_error();
   1058      1.1.1.5  christos 	sent = SSL_write(ssl, buffer_current(tcp->packet), request_length);
   1059      1.1.1.5  christos 	switch(SSL_get_error(ssl,sent)) {
   1060      1.1.1.5  christos 		case SSL_ERROR_NONE:
   1061      1.1.1.5  christos 			break;
   1062      1.1.1.5  christos 		default:
   1063      1.1.1.5  christos 			log_msg(LOG_ERR, "xfrd: generic write problem with tls");
   1064      1.1.1.5  christos 	}
   1065      1.1.1.5  christos 	if(sent == -1) {
   1066      1.1.1.5  christos 		if(errno == EAGAIN || errno == EINTR) {
   1067      1.1.1.5  christos 			/* write would block, try later */
   1068      1.1.1.5  christos 			return 0;
   1069      1.1.1.5  christos 		} else {
   1070      1.1.1.5  christos 			return -1;
   1071      1.1.1.5  christos 		}
   1072      1.1.1.5  christos 	}
   1073      1.1.1.5  christos 
   1074      1.1.1.5  christos 	buffer_skip(tcp->packet, sent);
   1075      1.1.1.5  christos 	tcp->total_bytes += sent;
   1076      1.1.1.5  christos 
   1077      1.1.1.5  christos 	if(tcp->total_bytes < tcp->msglen + sizeof(tcp->msglen)) {
   1078      1.1.1.5  christos 		/* more to write when socket becomes writable again */
   1079      1.1.1.5  christos 		return 0;
   1080      1.1.1.5  christos 	}
   1081      1.1.1.5  christos 
   1082      1.1.1.5  christos 	assert(tcp->total_bytes == tcp->msglen + sizeof(tcp->msglen));
   1083      1.1.1.5  christos 	return 1;
   1084      1.1.1.5  christos }
   1085      1.1.1.5  christos #endif
   1086      1.1.1.5  christos 
   1087      1.1.1.2  christos int conn_write(struct xfrd_tcp* tcp)
   1088          1.1  christos {
   1089          1.1  christos 	ssize_t sent;
   1090          1.1  christos 
   1091          1.1  christos 	if(tcp->total_bytes < sizeof(tcp->msglen)) {
   1092          1.1  christos 		uint16_t sendlen = htons(tcp->msglen);
   1093      1.1.1.2  christos #ifdef HAVE_WRITEV
   1094      1.1.1.2  christos 		struct iovec iov[2];
   1095      1.1.1.2  christos 		iov[0].iov_base = (uint8_t*)&sendlen + tcp->total_bytes;
   1096      1.1.1.2  christos 		iov[0].iov_len = sizeof(sendlen) - tcp->total_bytes;
   1097      1.1.1.2  christos 		iov[1].iov_base = buffer_begin(tcp->packet);
   1098      1.1.1.2  christos 		iov[1].iov_len = buffer_limit(tcp->packet);
   1099      1.1.1.2  christos 		sent = writev(tcp->fd, iov, 2);
   1100      1.1.1.2  christos #else /* HAVE_WRITEV */
   1101          1.1  christos 		sent = write(tcp->fd,
   1102          1.1  christos 			(const char*)&sendlen + tcp->total_bytes,
   1103          1.1  christos 			sizeof(tcp->msglen) - tcp->total_bytes);
   1104      1.1.1.2  christos #endif /* HAVE_WRITEV */
   1105          1.1  christos 
   1106          1.1  christos 		if(sent == -1) {
   1107          1.1  christos 			if(errno == EAGAIN || errno == EINTR) {
   1108          1.1  christos 				/* write would block, try later */
   1109          1.1  christos 				return 0;
   1110          1.1  christos 			} else {
   1111          1.1  christos 				return -1;
   1112          1.1  christos 			}
   1113          1.1  christos 		}
   1114          1.1  christos 
   1115          1.1  christos 		tcp->total_bytes += sent;
   1116      1.1.1.2  christos 		if(sent > (ssize_t)sizeof(tcp->msglen))
   1117      1.1.1.2  christos 			buffer_skip(tcp->packet, sent-sizeof(tcp->msglen));
   1118          1.1  christos 		if(tcp->total_bytes < sizeof(tcp->msglen)) {
   1119          1.1  christos 			/* incomplete write, resume later */
   1120          1.1  christos 			return 0;
   1121          1.1  christos 		}
   1122      1.1.1.2  christos #ifdef HAVE_WRITEV
   1123      1.1.1.2  christos 		if(tcp->total_bytes == tcp->msglen + sizeof(tcp->msglen)) {
   1124      1.1.1.2  christos 			/* packet done */
   1125      1.1.1.2  christos 			return 1;
   1126      1.1.1.2  christos 		}
   1127      1.1.1.2  christos #endif
   1128      1.1.1.2  christos 		assert(tcp->total_bytes >= sizeof(tcp->msglen));
   1129          1.1  christos 	}
   1130          1.1  christos 
   1131          1.1  christos 	assert(tcp->total_bytes < tcp->msglen + sizeof(tcp->msglen));
   1132          1.1  christos 
   1133          1.1  christos 	sent = write(tcp->fd,
   1134          1.1  christos 		buffer_current(tcp->packet),
   1135          1.1  christos 		buffer_remaining(tcp->packet));
   1136          1.1  christos 	if(sent == -1) {
   1137          1.1  christos 		if(errno == EAGAIN || errno == EINTR) {
   1138          1.1  christos 			/* write would block, try later */
   1139          1.1  christos 			return 0;
   1140          1.1  christos 		} else {
   1141          1.1  christos 			return -1;
   1142          1.1  christos 		}
   1143          1.1  christos 	}
   1144          1.1  christos 
   1145          1.1  christos 	buffer_skip(tcp->packet, sent);
   1146          1.1  christos 	tcp->total_bytes += sent;
   1147          1.1  christos 
   1148          1.1  christos 	if(tcp->total_bytes < tcp->msglen + sizeof(tcp->msglen)) {
   1149          1.1  christos 		/* more to write when socket becomes writable again */
   1150          1.1  christos 		return 0;
   1151          1.1  christos 	}
   1152          1.1  christos 
   1153          1.1  christos 	assert(tcp->total_bytes == tcp->msglen + sizeof(tcp->msglen));
   1154          1.1  christos 	return 1;
   1155          1.1  christos }
   1156          1.1  christos 
   1157          1.1  christos void
   1158      1.1.1.2  christos xfrd_tcp_write(struct xfrd_tcp_pipeline* tp, xfrd_zone_type* zone)
   1159          1.1  christos {
   1160          1.1  christos 	int ret;
   1161      1.1.1.2  christos 	struct xfrd_tcp* tcp = tp->tcp_w;
   1162          1.1  christos 	assert(zone->tcp_conn != -1);
   1163          1.1  christos 	assert(zone == tp->tcp_send_first);
   1164          1.1  christos 	/* see if for non-established connection, there is a connect error */
   1165          1.1  christos 	if(!tp->connection_established) {
   1166          1.1  christos 		/* check for pending error from nonblocking connect */
   1167          1.1  christos 		/* from Stevens, unix network programming, vol1, 3rd ed, p450 */
   1168          1.1  christos 		int error = 0;
   1169          1.1  christos 		socklen_t len = sizeof(error);
   1170          1.1  christos 		if(getsockopt(tcp->fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0){
   1171          1.1  christos 			error = errno; /* on solaris errno is error */
   1172          1.1  christos 		}
   1173          1.1  christos 		if(error == EINPROGRESS || error == EWOULDBLOCK)
   1174          1.1  christos 			return; /* try again later */
   1175          1.1  christos 		if(error != 0) {
   1176          1.1  christos 			log_msg(LOG_ERR, "%s: Could not tcp connect to %s: %s",
   1177          1.1  christos 				zone->apex_str, zone->master->ip_address_spec,
   1178          1.1  christos 				strerror(error));
   1179          1.1  christos 			xfrd_tcp_pipe_stop(tp);
   1180          1.1  christos 			return;
   1181          1.1  christos 		}
   1182          1.1  christos 	}
   1183      1.1.1.5  christos #ifdef HAVE_TLS_1_3
   1184      1.1.1.5  christos 	if (tp->ssl) {
   1185      1.1.1.5  christos 		if(tp->handshake_done) {
   1186      1.1.1.5  christos 			ret = conn_write_ssl(tcp, tp->ssl);
   1187      1.1.1.5  christos 
   1188      1.1.1.5  christos 		} else if(ssl_handshake(tp)) {
   1189      1.1.1.5  christos 			tcp_pipe_reset_timeout(tp); /* reschedule */
   1190      1.1.1.5  christos 			return;
   1191      1.1.1.5  christos 
   1192      1.1.1.5  christos 		} else {
   1193      1.1.1.5  christos 			if(tp->handshake_want == SSL_ERROR_SYSCALL) {
   1194      1.1.1.5  christos 				log_msg(LOG_ERR, "xfrd: TLS handshake failed: %s",
   1195      1.1.1.5  christos 					strerror(errno));
   1196      1.1.1.5  christos 
   1197      1.1.1.5  christos 			} else if(tp->handshake_want == SSL_ERROR_SSL) {
   1198      1.1.1.5  christos 				log_crypto_err("xfrd: TLS handshake failed");
   1199      1.1.1.5  christos 			} else {
   1200      1.1.1.5  christos 				log_msg(LOG_ERR, "xfrd: TLS handshake failed "
   1201      1.1.1.5  christos 					"with value: %d", tp->handshake_want);
   1202      1.1.1.5  christos 			}
   1203      1.1.1.5  christos 			xfrd_tcp_pipe_stop(tp);
   1204      1.1.1.5  christos 			return;
   1205      1.1.1.5  christos 		}
   1206      1.1.1.5  christos 	} else
   1207      1.1.1.5  christos #endif
   1208      1.1.1.5  christos 		ret = conn_write(tcp);
   1209          1.1  christos 	if(ret == -1) {
   1210          1.1  christos 		log_msg(LOG_ERR, "xfrd: failed writing tcp %s", strerror(errno));
   1211          1.1  christos 		xfrd_tcp_pipe_stop(tp);
   1212          1.1  christos 		return;
   1213          1.1  christos 	}
   1214          1.1  christos 	if(tcp->total_bytes != 0 && !tp->connection_established)
   1215          1.1  christos 		tp->connection_established = 1;
   1216          1.1  christos 	if(ret == 0) {
   1217          1.1  christos 		return; /* write again later */
   1218          1.1  christos 	}
   1219          1.1  christos 	/* done writing this message */
   1220          1.1  christos 
   1221          1.1  christos 	/* remove first zone from sendlist */
   1222          1.1  christos 	tcp_pipe_sendlist_popfirst(tp, zone);
   1223          1.1  christos 
   1224          1.1  christos 	/* see if other zone wants to write; init; let it write (now) */
   1225          1.1  christos 	/* and use a loop, because 64k stack calls is a too much */
   1226          1.1  christos 	while(tp->tcp_send_first) {
   1227          1.1  christos 		/* setup to write for this zone */
   1228          1.1  christos 		xfrd_tcp_setup_write_packet(tp, tp->tcp_send_first);
   1229          1.1  christos 		/* attempt to write for this zone (if success, continue loop)*/
   1230      1.1.1.5  christos #ifdef HAVE_TLS_1_3
   1231      1.1.1.5  christos 		if (tp->ssl)
   1232      1.1.1.5  christos 			ret = conn_write_ssl(tcp, tp->ssl);
   1233      1.1.1.5  christos 		else
   1234      1.1.1.5  christos #endif
   1235      1.1.1.5  christos 			ret = conn_write(tcp);
   1236          1.1  christos 		if(ret == -1) {
   1237          1.1  christos 			log_msg(LOG_ERR, "xfrd: failed writing tcp %s", strerror(errno));
   1238          1.1  christos 			xfrd_tcp_pipe_stop(tp);
   1239          1.1  christos 			return;
   1240          1.1  christos 		}
   1241          1.1  christos 		if(ret == 0)
   1242          1.1  christos 			return; /* write again later */
   1243          1.1  christos 		tcp_pipe_sendlist_popfirst(tp, tp->tcp_send_first);
   1244          1.1  christos 	}
   1245          1.1  christos 
   1246          1.1  christos 	/* if sendlist empty, remove WRITE from event */
   1247          1.1  christos 
   1248          1.1  christos 	/* listen to READ, and not WRITE events */
   1249          1.1  christos 	assert(tp->tcp_send_first == NULL);
   1250          1.1  christos 	tcp_pipe_reset_timeout(tp);
   1251          1.1  christos }
   1252          1.1  christos 
   1253      1.1.1.5  christos #ifdef HAVE_TLS_1_3
   1254      1.1.1.5  christos static int
   1255      1.1.1.5  christos conn_read_ssl(struct xfrd_tcp* tcp, SSL* ssl)
   1256      1.1.1.5  christos {
   1257      1.1.1.5  christos 	ssize_t received;
   1258      1.1.1.5  christos 	/* receive leading packet length bytes */
   1259      1.1.1.5  christos 	if(tcp->total_bytes < sizeof(tcp->msglen)) {
   1260      1.1.1.5  christos 		ERR_clear_error();
   1261      1.1.1.5  christos 		received = SSL_read(ssl,
   1262      1.1.1.5  christos 						(char*) &tcp->msglen + tcp->total_bytes,
   1263      1.1.1.5  christos 						sizeof(tcp->msglen) - tcp->total_bytes);
   1264      1.1.1.5  christos 		if (received <= 0) {
   1265      1.1.1.5  christos 			int err = SSL_get_error(ssl, received);
   1266      1.1.1.5  christos 			if(err == SSL_ERROR_WANT_READ && errno == EAGAIN) {
   1267      1.1.1.5  christos 				return 0;
   1268      1.1.1.5  christos 			}
   1269      1.1.1.5  christos 			if(err == SSL_ERROR_ZERO_RETURN) {
   1270      1.1.1.5  christos 				/* EOF */
   1271  1.1.1.5.2.1    martin 				return -1;
   1272      1.1.1.5  christos 			}
   1273  1.1.1.5.2.1    martin 			if(err == SSL_ERROR_SYSCALL)
   1274  1.1.1.5.2.1    martin 				log_msg(LOG_ERR, "ssl_read returned error SSL_ERROR_SYSCALL with received %zd: %s", received, strerror(errno));
   1275  1.1.1.5.2.1    martin 			else
   1276  1.1.1.5.2.1    martin 				log_msg(LOG_ERR, "ssl_read returned error %d with received %zd", err, received);
   1277      1.1.1.5  christos 		}
   1278      1.1.1.5  christos 		if(received == -1) {
   1279      1.1.1.5  christos 			if(errno == EAGAIN || errno == EINTR) {
   1280      1.1.1.5  christos 				/* read would block, try later */
   1281      1.1.1.5  christos 				return 0;
   1282      1.1.1.5  christos 			} else {
   1283      1.1.1.5  christos #ifdef ECONNRESET
   1284      1.1.1.5  christos 				if (verbosity >= 2 || errno != ECONNRESET)
   1285      1.1.1.5  christos #endif /* ECONNRESET */
   1286      1.1.1.5  christos 					log_msg(LOG_ERR, "tls read sz: %s", strerror(errno));
   1287      1.1.1.5  christos 				return -1;
   1288      1.1.1.5  christos 			}
   1289      1.1.1.5  christos 		} else if(received == 0) {
   1290      1.1.1.5  christos 			/* EOF */
   1291      1.1.1.5  christos 			return -1;
   1292      1.1.1.5  christos 		}
   1293      1.1.1.5  christos 		tcp->total_bytes += received;
   1294      1.1.1.5  christos 		if(tcp->total_bytes < sizeof(tcp->msglen)) {
   1295      1.1.1.5  christos 			/* not complete yet, try later */
   1296      1.1.1.5  christos 			return 0;
   1297      1.1.1.5  christos 		}
   1298      1.1.1.5  christos 
   1299      1.1.1.5  christos 		assert(tcp->total_bytes == sizeof(tcp->msglen));
   1300      1.1.1.5  christos 		tcp->msglen = ntohs(tcp->msglen);
   1301      1.1.1.5  christos 
   1302      1.1.1.5  christos 		if(tcp->msglen == 0) {
   1303      1.1.1.5  christos 			buffer_set_limit(tcp->packet, tcp->msglen);
   1304      1.1.1.5  christos 			return 1;
   1305      1.1.1.5  christos 		}
   1306      1.1.1.5  christos 		if(tcp->msglen > buffer_capacity(tcp->packet)) {
   1307      1.1.1.5  christos 			log_msg(LOG_ERR, "buffer too small, dropping connection");
   1308      1.1.1.5  christos 			return 0;
   1309      1.1.1.5  christos 		}
   1310      1.1.1.5  christos 		buffer_set_limit(tcp->packet, tcp->msglen);
   1311      1.1.1.5  christos 	}
   1312      1.1.1.5  christos 
   1313      1.1.1.5  christos 	assert(buffer_remaining(tcp->packet) > 0);
   1314      1.1.1.5  christos 	ERR_clear_error();
   1315      1.1.1.5  christos 
   1316      1.1.1.5  christos 	received = SSL_read(ssl, buffer_current(tcp->packet),
   1317      1.1.1.5  christos 					buffer_remaining(tcp->packet));
   1318      1.1.1.5  christos 
   1319      1.1.1.5  christos 	if (received <= 0) {
   1320      1.1.1.5  christos 		int err = SSL_get_error(ssl, received);
   1321      1.1.1.5  christos 		if(err == SSL_ERROR_ZERO_RETURN) {
   1322      1.1.1.5  christos 			/* EOF */
   1323  1.1.1.5.2.1    martin 			return -1;
   1324      1.1.1.5  christos 		}
   1325  1.1.1.5.2.1    martin 		if(err == SSL_ERROR_SYSCALL)
   1326  1.1.1.5.2.1    martin 			log_msg(LOG_ERR, "ssl_read returned error SSL_ERROR_SYSCALL with received %zd: %s", received, strerror(errno));
   1327  1.1.1.5.2.1    martin 		else
   1328  1.1.1.5.2.1    martin 			log_msg(LOG_ERR, "ssl_read returned error %d with received %zd", err, received);
   1329      1.1.1.5  christos 	}
   1330      1.1.1.5  christos 	if(received == -1) {
   1331      1.1.1.5  christos 		if(errno == EAGAIN || errno == EINTR) {
   1332      1.1.1.5  christos 			/* read would block, try later */
   1333      1.1.1.5  christos 			return 0;
   1334      1.1.1.5  christos 		} else {
   1335      1.1.1.5  christos #ifdef ECONNRESET
   1336      1.1.1.5  christos 			if (verbosity >= 2 || errno != ECONNRESET)
   1337      1.1.1.5  christos #endif /* ECONNRESET */
   1338      1.1.1.5  christos 				log_msg(LOG_ERR, "tcp read %s", strerror(errno));
   1339      1.1.1.5  christos 			return -1;
   1340      1.1.1.5  christos 		}
   1341      1.1.1.5  christos 	} else if(received == 0) {
   1342      1.1.1.5  christos 		/* EOF */
   1343      1.1.1.5  christos 		return -1;
   1344      1.1.1.5  christos 	}
   1345      1.1.1.5  christos 
   1346      1.1.1.5  christos 	tcp->total_bytes += received;
   1347      1.1.1.5  christos 	buffer_skip(tcp->packet, received);
   1348      1.1.1.5  christos 
   1349      1.1.1.5  christos 	if(buffer_remaining(tcp->packet) > 0) {
   1350      1.1.1.5  christos 		/* not complete yet, wait for more */
   1351      1.1.1.5  christos 		return 0;
   1352      1.1.1.5  christos 	}
   1353      1.1.1.5  christos 
   1354      1.1.1.5  christos 	/* completed */
   1355      1.1.1.5  christos 	assert(buffer_position(tcp->packet) == tcp->msglen);
   1356      1.1.1.5  christos 	return 1;
   1357      1.1.1.5  christos }
   1358      1.1.1.5  christos #endif
   1359      1.1.1.5  christos 
   1360          1.1  christos int
   1361      1.1.1.2  christos conn_read(struct xfrd_tcp* tcp)
   1362          1.1  christos {
   1363          1.1  christos 	ssize_t received;
   1364          1.1  christos 	/* receive leading packet length bytes */
   1365          1.1  christos 	if(tcp->total_bytes < sizeof(tcp->msglen)) {
   1366          1.1  christos 		received = read(tcp->fd,
   1367          1.1  christos 			(char*) &tcp->msglen + tcp->total_bytes,
   1368          1.1  christos 			sizeof(tcp->msglen) - tcp->total_bytes);
   1369          1.1  christos 		if(received == -1) {
   1370          1.1  christos 			if(errno == EAGAIN || errno == EINTR) {
   1371          1.1  christos 				/* read would block, try later */
   1372          1.1  christos 				return 0;
   1373          1.1  christos 			} else {
   1374          1.1  christos #ifdef ECONNRESET
   1375          1.1  christos 				if (verbosity >= 2 || errno != ECONNRESET)
   1376          1.1  christos #endif /* ECONNRESET */
   1377          1.1  christos 				log_msg(LOG_ERR, "tcp read sz: %s", strerror(errno));
   1378          1.1  christos 				return -1;
   1379          1.1  christos 			}
   1380          1.1  christos 		} else if(received == 0) {
   1381          1.1  christos 			/* EOF */
   1382          1.1  christos 			return -1;
   1383          1.1  christos 		}
   1384          1.1  christos 		tcp->total_bytes += received;
   1385          1.1  christos 		if(tcp->total_bytes < sizeof(tcp->msglen)) {
   1386          1.1  christos 			/* not complete yet, try later */
   1387          1.1  christos 			return 0;
   1388          1.1  christos 		}
   1389          1.1  christos 
   1390          1.1  christos 		assert(tcp->total_bytes == sizeof(tcp->msglen));
   1391          1.1  christos 		tcp->msglen = ntohs(tcp->msglen);
   1392          1.1  christos 
   1393          1.1  christos 		if(tcp->msglen == 0) {
   1394          1.1  christos 			buffer_set_limit(tcp->packet, tcp->msglen);
   1395          1.1  christos 			return 1;
   1396          1.1  christos 		}
   1397          1.1  christos 		if(tcp->msglen > buffer_capacity(tcp->packet)) {
   1398          1.1  christos 			log_msg(LOG_ERR, "buffer too small, dropping connection");
   1399          1.1  christos 			return 0;
   1400          1.1  christos 		}
   1401          1.1  christos 		buffer_set_limit(tcp->packet, tcp->msglen);
   1402          1.1  christos 	}
   1403          1.1  christos 
   1404          1.1  christos 	assert(buffer_remaining(tcp->packet) > 0);
   1405          1.1  christos 
   1406          1.1  christos 	received = read(tcp->fd, buffer_current(tcp->packet),
   1407          1.1  christos 		buffer_remaining(tcp->packet));
   1408          1.1  christos 	if(received == -1) {
   1409          1.1  christos 		if(errno == EAGAIN || errno == EINTR) {
   1410          1.1  christos 			/* read would block, try later */
   1411          1.1  christos 			return 0;
   1412          1.1  christos 		} else {
   1413          1.1  christos #ifdef ECONNRESET
   1414          1.1  christos 			if (verbosity >= 2 || errno != ECONNRESET)
   1415          1.1  christos #endif /* ECONNRESET */
   1416          1.1  christos 			log_msg(LOG_ERR, "tcp read %s", strerror(errno));
   1417          1.1  christos 			return -1;
   1418          1.1  christos 		}
   1419          1.1  christos 	} else if(received == 0) {
   1420          1.1  christos 		/* EOF */
   1421          1.1  christos 		return -1;
   1422          1.1  christos 	}
   1423          1.1  christos 
   1424          1.1  christos 	tcp->total_bytes += received;
   1425          1.1  christos 	buffer_skip(tcp->packet, received);
   1426          1.1  christos 
   1427          1.1  christos 	if(buffer_remaining(tcp->packet) > 0) {
   1428          1.1  christos 		/* not complete yet, wait for more */
   1429          1.1  christos 		return 0;
   1430          1.1  christos 	}
   1431          1.1  christos 
   1432          1.1  christos 	/* completed */
   1433          1.1  christos 	assert(buffer_position(tcp->packet) == tcp->msglen);
   1434          1.1  christos 	return 1;
   1435          1.1  christos }
   1436          1.1  christos 
   1437          1.1  christos void
   1438          1.1  christos xfrd_tcp_read(struct xfrd_tcp_pipeline* tp)
   1439          1.1  christos {
   1440      1.1.1.2  christos 	xfrd_zone_type* zone;
   1441      1.1.1.2  christos 	struct xfrd_tcp* tcp = tp->tcp_r;
   1442          1.1  christos 	int ret;
   1443          1.1  christos 	enum xfrd_packet_result pkt_result;
   1444      1.1.1.5  christos #ifdef HAVE_TLS_1_3
   1445      1.1.1.5  christos 	if(tp->ssl) {
   1446      1.1.1.5  christos 		if(tp->handshake_done) {
   1447      1.1.1.5  christos 			ret = conn_read_ssl(tcp, tp->ssl);
   1448      1.1.1.5  christos 
   1449      1.1.1.5  christos 		} else if(ssl_handshake(tp)) {
   1450      1.1.1.5  christos 			tcp_pipe_reset_timeout(tp); /* reschedule */
   1451      1.1.1.5  christos 			return;
   1452      1.1.1.5  christos 
   1453      1.1.1.5  christos 		} else {
   1454      1.1.1.5  christos 			if(tp->handshake_want == SSL_ERROR_SYSCALL) {
   1455      1.1.1.5  christos 				log_msg(LOG_ERR, "xfrd: TLS handshake failed: %s",
   1456      1.1.1.5  christos 					strerror(errno));
   1457          1.1  christos 
   1458      1.1.1.5  christos 			} else if(tp->handshake_want == SSL_ERROR_SSL) {
   1459      1.1.1.5  christos 				log_crypto_err("xfrd: TLS handshake failed");
   1460      1.1.1.5  christos 			} else {
   1461      1.1.1.5  christos 				log_msg(LOG_ERR, "xfrd: TLS handshake failed "
   1462      1.1.1.5  christos 					"with value: %d", tp->handshake_want);
   1463      1.1.1.5  christos 			}
   1464      1.1.1.5  christos 			xfrd_tcp_pipe_stop(tp);
   1465      1.1.1.5  christos 			return;
   1466      1.1.1.5  christos 		}
   1467      1.1.1.5  christos 	} else
   1468      1.1.1.5  christos #endif
   1469      1.1.1.5  christos 		ret = conn_read(tcp);
   1470          1.1  christos 	if(ret == -1) {
   1471  1.1.1.5.2.1    martin 		if(errno != 0)
   1472  1.1.1.5.2.1    martin 			log_msg(LOG_ERR, "xfrd: failed reading tcp %s", strerror(errno));
   1473  1.1.1.5.2.1    martin 		else
   1474  1.1.1.5.2.1    martin 			log_msg(LOG_ERR, "xfrd: failed reading tcp: closed");
   1475          1.1  christos 		xfrd_tcp_pipe_stop(tp);
   1476          1.1  christos 		return;
   1477          1.1  christos 	}
   1478          1.1  christos 	if(ret == 0)
   1479          1.1  christos 		return;
   1480          1.1  christos 	/* completed msg */
   1481          1.1  christos 	buffer_flip(tcp->packet);
   1482          1.1  christos 	/* see which ID number it is, if skip, handle skip, NULL: warn */
   1483          1.1  christos 	if(tcp->msglen < QHEADERSZ) {
   1484          1.1  christos 		/* too short for DNS header, skip it */
   1485          1.1  christos 		DEBUG(DEBUG_XFRD,1, (LOG_INFO,
   1486          1.1  christos 			"xfrd: tcp skip response that is too short"));
   1487          1.1  christos 		tcp_conn_ready_for_reading(tcp);
   1488          1.1  christos 		return;
   1489          1.1  christos 	}
   1490      1.1.1.5  christos 	zone = xfrd_tcp_pipeline_lookup_id(tp, ID(tcp->packet));
   1491          1.1  christos 	if(!zone || zone == TCP_NULL_SKIP) {
   1492          1.1  christos 		/* no zone for this id? skip it */
   1493          1.1  christos 		DEBUG(DEBUG_XFRD,1, (LOG_INFO,
   1494          1.1  christos 			"xfrd: tcp skip response with %s ID",
   1495          1.1  christos 			zone?"set-to-skip":"unknown"));
   1496          1.1  christos 		tcp_conn_ready_for_reading(tcp);
   1497          1.1  christos 		return;
   1498          1.1  christos 	}
   1499          1.1  christos 	assert(zone->tcp_conn != -1);
   1500          1.1  christos 
   1501          1.1  christos 	/* handle message for zone */
   1502          1.1  christos 	pkt_result = xfrd_handle_received_xfr_packet(zone, tcp->packet);
   1503          1.1  christos 	/* setup for reading the next packet on this connection */
   1504          1.1  christos 	tcp_conn_ready_for_reading(tcp);
   1505          1.1  christos 	switch(pkt_result) {
   1506          1.1  christos 		case xfrd_packet_more:
   1507          1.1  christos 			/* wait for next packet */
   1508          1.1  christos 			break;
   1509          1.1  christos 		case xfrd_packet_newlease:
   1510          1.1  christos 			/* set to skip if more packets with this ID */
   1511      1.1.1.5  christos 			xfrd_tcp_pipeline_skip_id(tp, zone->query_id);
   1512      1.1.1.5  christos 			tp->key.num_skip++;
   1513          1.1  christos 			/* fall through to remove zone from tp */
   1514      1.1.1.2  christos 			/* fallthrough */
   1515          1.1  christos 		case xfrd_packet_transfer:
   1516          1.1  christos 			if(zone->zone_options->pattern->multi_master_check) {
   1517          1.1  christos 				xfrd_tcp_release(xfrd->tcp_set, zone);
   1518          1.1  christos 				xfrd_make_request(zone);
   1519          1.1  christos 				break;
   1520          1.1  christos 			}
   1521          1.1  christos 			xfrd_tcp_release(xfrd->tcp_set, zone);
   1522          1.1  christos 			assert(zone->round_num == -1);
   1523          1.1  christos 			break;
   1524          1.1  christos 		case xfrd_packet_notimpl:
   1525          1.1  christos 			xfrd_disable_ixfr(zone);
   1526          1.1  christos 			xfrd_tcp_release(xfrd->tcp_set, zone);
   1527          1.1  christos 			/* query next server */
   1528          1.1  christos 			xfrd_make_request(zone);
   1529          1.1  christos 			break;
   1530          1.1  christos 		case xfrd_packet_bad:
   1531          1.1  christos 		case xfrd_packet_tcp:
   1532          1.1  christos 		default:
   1533          1.1  christos 			/* set to skip if more packets with this ID */
   1534      1.1.1.5  christos 			xfrd_tcp_pipeline_skip_id(tp, zone->query_id);
   1535      1.1.1.5  christos 			tp->key.num_skip++;
   1536          1.1  christos 			xfrd_tcp_release(xfrd->tcp_set, zone);
   1537          1.1  christos 			/* query next server */
   1538          1.1  christos 			xfrd_make_request(zone);
   1539          1.1  christos 			break;
   1540          1.1  christos 	}
   1541          1.1  christos }
   1542          1.1  christos 
   1543          1.1  christos void
   1544      1.1.1.2  christos xfrd_tcp_release(struct xfrd_tcp_set* set, xfrd_zone_type* zone)
   1545          1.1  christos {
   1546          1.1  christos 	int conn = zone->tcp_conn;
   1547          1.1  christos 	struct xfrd_tcp_pipeline* tp = set->tcp_state[conn];
   1548          1.1  christos 	DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd: zone %s released tcp conn to %s",
   1549          1.1  christos 		zone->apex_str, zone->master->ip_address_spec));
   1550          1.1  christos 	assert(zone->tcp_conn != -1);
   1551          1.1  christos 	assert(zone->tcp_waiting == 0);
   1552          1.1  christos 	zone->tcp_conn = -1;
   1553          1.1  christos 	zone->tcp_waiting = 0;
   1554          1.1  christos 
   1555          1.1  christos 	/* remove from tcp_send list */
   1556          1.1  christos 	tcp_pipe_sendlist_remove(tp, zone);
   1557          1.1  christos 	/* remove it from the ID list */
   1558      1.1.1.5  christos 	if(xfrd_tcp_pipeline_lookup_id(tp, zone->query_id) != TCP_NULL_SKIP)
   1559      1.1.1.5  christos 		tcp_pipe_id_remove(tp, zone, 1);
   1560          1.1  christos 	DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd: released tcp pipe now %d unused",
   1561      1.1.1.5  christos 		tp->key.num_unused));
   1562          1.1  christos 	/* if pipe was full, but no more, then see if waiting element is
   1563          1.1  christos 	 * for the same master, and can fill the unused ID */
   1564      1.1.1.5  christos 	if(tp->key.num_unused == 1 && set->tcp_waiting_first) {
   1565          1.1  christos #ifdef INET6
   1566          1.1  christos 		struct sockaddr_storage to;
   1567          1.1  christos #else
   1568          1.1  christos 		struct sockaddr_in to;
   1569          1.1  christos #endif
   1570          1.1  christos 		socklen_t to_len = xfrd_acl_sockaddr_to(
   1571          1.1  christos 			set->tcp_waiting_first->master, &to);
   1572      1.1.1.5  christos 		if(to_len == tp->key.ip_len && memcmp(&to, &tp->key.ip, to_len) == 0) {
   1573          1.1  christos 			/* use this connection for the waiting zone */
   1574          1.1  christos 			zone = set->tcp_waiting_first;
   1575          1.1  christos 			assert(zone->tcp_conn == -1);
   1576          1.1  christos 			zone->tcp_conn = conn;
   1577          1.1  christos 			tcp_zone_waiting_list_popfirst(set, zone);
   1578          1.1  christos 			if(zone->zone_handler.ev_fd != -1)
   1579          1.1  christos 				xfrd_udp_release(zone);
   1580          1.1  christos 			xfrd_unset_timer(zone);
   1581          1.1  christos 			pipeline_setup_new_zone(set, tp, zone);
   1582          1.1  christos 			return;
   1583          1.1  christos 		}
   1584          1.1  christos 		/* waiting zone did not go to same server */
   1585          1.1  christos 	}
   1586          1.1  christos 
   1587          1.1  christos 	/* if all unused, or only skipped leftover, close the pipeline */
   1588      1.1.1.5  christos 	if(tp->key.num_unused >= tp->pipe_num || tp->key.num_skip >= tp->pipe_num - tp->key.num_unused)
   1589          1.1  christos 		xfrd_tcp_pipe_release(set, tp, conn);
   1590          1.1  christos }
   1591          1.1  christos 
   1592          1.1  christos void
   1593      1.1.1.2  christos xfrd_tcp_pipe_release(struct xfrd_tcp_set* set, struct xfrd_tcp_pipeline* tp,
   1594          1.1  christos 	int conn)
   1595          1.1  christos {
   1596          1.1  christos 	DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd: tcp pipe released"));
   1597          1.1  christos 	/* one handler per tcp pipe */
   1598          1.1  christos 	if(tp->handler_added)
   1599          1.1  christos 		event_del(&tp->handler);
   1600          1.1  christos 	tp->handler_added = 0;
   1601          1.1  christos 
   1602      1.1.1.5  christos #ifdef HAVE_TLS_1_3
   1603      1.1.1.5  christos 	/* close SSL */
   1604      1.1.1.5  christos 	if (tp->ssl) {
   1605      1.1.1.5  christos 		DEBUG(DEBUG_XFRD, 1, (LOG_INFO, "xfrd: Shutting down TLS"));
   1606      1.1.1.5  christos 		SSL_shutdown(tp->ssl);
   1607      1.1.1.5  christos 		SSL_free(tp->ssl);
   1608      1.1.1.5  christos 		tp->ssl = NULL;
   1609      1.1.1.5  christos 	}
   1610      1.1.1.5  christos #endif
   1611      1.1.1.5  christos 
   1612          1.1  christos 	/* fd in tcp_r and tcp_w is the same, close once */
   1613          1.1  christos 	if(tp->tcp_r->fd != -1)
   1614          1.1  christos 		close(tp->tcp_r->fd);
   1615          1.1  christos 	tp->tcp_r->fd = -1;
   1616          1.1  christos 	tp->tcp_w->fd = -1;
   1617          1.1  christos 
   1618          1.1  christos 	/* remove from pipetree */
   1619      1.1.1.5  christos 	(void)rbtree_delete(xfrd->tcp_set->pipetree, &tp->key.node);
   1620          1.1  christos 
   1621          1.1  christos 	/* a waiting zone can use the free tcp slot (to another server) */
   1622          1.1  christos 	/* if that zone fails to set-up or connect, we try to start the next
   1623          1.1  christos 	 * waiting zone in the list */
   1624      1.1.1.5  christos 	while(set->tcp_count == set->tcp_max && set->tcp_waiting_first) {
   1625          1.1  christos 		/* pop first waiting process */
   1626      1.1.1.2  christos 		xfrd_zone_type* zone = set->tcp_waiting_first;
   1627          1.1  christos 		/* start it */
   1628          1.1  christos 		assert(zone->tcp_conn == -1);
   1629          1.1  christos 		zone->tcp_conn = conn;
   1630          1.1  christos 		tcp_zone_waiting_list_popfirst(set, zone);
   1631          1.1  christos 
   1632          1.1  christos 		/* stop udp (if any) */
   1633          1.1  christos 		if(zone->zone_handler.ev_fd != -1)
   1634          1.1  christos 			xfrd_udp_release(zone);
   1635          1.1  christos 		if(!xfrd_tcp_open(set, tp, zone)) {
   1636          1.1  christos 			zone->tcp_conn = -1;
   1637          1.1  christos 			xfrd_set_refresh_now(zone);
   1638          1.1  christos 			/* try to start the next zone (if any) */
   1639          1.1  christos 			continue;
   1640          1.1  christos 		}
   1641          1.1  christos 		/* re-init this tcppipe */
   1642          1.1  christos 		/* ip and ip_len set by tcp_open */
   1643      1.1.1.5  christos 		xfrd_tcp_pipeline_init(tp);
   1644          1.1  christos 
   1645          1.1  christos 		/* insert into tree */
   1646      1.1.1.5  christos 		(void)rbtree_insert(set->pipetree, &tp->key.node);
   1647          1.1  christos 		/* setup write */
   1648          1.1  christos 		xfrd_unset_timer(zone);
   1649          1.1  christos 		pipeline_setup_new_zone(set, tp, zone);
   1650          1.1  christos 		/* started a task, no need for cleanups, so return */
   1651          1.1  christos 		return;
   1652          1.1  christos 	}
   1653          1.1  christos 	/* no task to start, cleanup */
   1654          1.1  christos 	assert(!set->tcp_waiting_first);
   1655          1.1  christos 	set->tcp_count --;
   1656          1.1  christos 	assert(set->tcp_count >= 0);
   1657          1.1  christos }
   1658          1.1  christos 
   1659