Home | History | Annotate | Line # | Download | only in dist
xfrd-tcp.c revision 1.1.1.6
      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.6  christos 	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.6  christos 
     56  1.1.1.6  christos 	if (SSL_CTX_set_alpn_protos(ctx, protos, sizeof(protos)) != 0) {
     57  1.1.1.6  christos 		SSL_CTX_free(ctx);
     58  1.1.1.6  christos 		log_msg(LOG_ERR, "xfrd tls: Unable to set ALPN protocols");
     59  1.1.1.6  christos 		return NULL;
     60  1.1.1.6  christos 	}
     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.6  christos 				return -1;
   1272  1.1.1.5  christos 			}
   1273  1.1.1.6  christos 			if(err == SSL_ERROR_SYSCALL)
   1274  1.1.1.6  christos 				log_msg(LOG_ERR, "ssl_read returned error SSL_ERROR_SYSCALL with received %zd: %s", received, strerror(errno));
   1275  1.1.1.6  christos 			else
   1276  1.1.1.6  christos 				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.6  christos 			return -1;
   1324  1.1.1.5  christos 		}
   1325  1.1.1.6  christos 		if(err == SSL_ERROR_SYSCALL)
   1326  1.1.1.6  christos 			log_msg(LOG_ERR, "ssl_read returned error SSL_ERROR_SYSCALL with received %zd: %s", received, strerror(errno));
   1327  1.1.1.6  christos 		else
   1328  1.1.1.6  christos 			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.6  christos 		if(errno != 0)
   1472  1.1.1.6  christos 			log_msg(LOG_ERR, "xfrd: failed reading tcp %s", strerror(errno));
   1473  1.1.1.6  christos 		else
   1474  1.1.1.6  christos 			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