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