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