xref: /openbsd/usr.sbin/smtpd/mta.c (revision 73471bf0)
1 /*	$OpenBSD: mta.c,v 1.240 2021/06/14 17:58:15 eric Exp $	*/
2 
3 /*
4  * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
5  * Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
6  * Copyright (c) 2009 Jacek Masiulaniec <jacekm@dobremiasto.net>
7  * Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
8  *
9  * Permission to use, copy, modify, and distribute this software for any
10  * purpose with or without fee is hereby granted, provided that the above
11  * copyright notice and this permission notice appear in all copies.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20  */
21 
22 #include <inttypes.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <tls.h>
26 
27 #include "smtpd.h"
28 #include "log.h"
29 #include "ssl.h"
30 
31 #define MAXERROR_PER_ROUTE	4
32 
33 #define DELAY_CHECK_SOURCE	1
34 #define DELAY_CHECK_SOURCE_SLOW	10
35 #define DELAY_CHECK_SOURCE_FAST 0
36 #define DELAY_CHECK_LIMIT	5
37 
38 #define	DELAY_QUADRATIC		1
39 #define DELAY_ROUTE_BASE	15
40 #define DELAY_ROUTE_MAX		3600
41 
42 #define RELAY_ONHOLD		0x01
43 #define RELAY_HOLDQ		0x02
44 
45 static void mta_setup_dispatcher(struct dispatcher *);
46 static void mta_handle_envelope(struct envelope *, const char *);
47 static void mta_query_smarthost(struct envelope *);
48 static void mta_on_smarthost(struct envelope *, const char *);
49 static void mta_query_mx(struct mta_relay *);
50 static void mta_query_secret(struct mta_relay *);
51 static void mta_query_preference(struct mta_relay *);
52 static void mta_query_source(struct mta_relay *);
53 static void mta_on_mx(void *, void *, void *);
54 static void mta_on_secret(struct mta_relay *, const char *);
55 static void mta_on_preference(struct mta_relay *, int);
56 static void mta_on_source(struct mta_relay *, struct mta_source *);
57 static void mta_on_timeout(struct runq *, void *);
58 static void mta_connect(struct mta_connector *);
59 static void mta_route_enable(struct mta_route *);
60 static void mta_route_disable(struct mta_route *, int, int);
61 static void mta_drain(struct mta_relay *);
62 static void mta_delivery_flush_event(int, short, void *);
63 static void mta_flush(struct mta_relay *, int, const char *);
64 static struct mta_route *mta_find_route(struct mta_connector *, time_t, int*,
65     time_t*, struct mta_mx **);
66 static void mta_log(const struct mta_envelope *, const char *, const char *,
67     const char *, const char *);
68 
69 SPLAY_HEAD(mta_relay_tree, mta_relay);
70 static struct mta_relay *mta_relay(struct envelope *, struct relayhost *);
71 static void mta_relay_ref(struct mta_relay *);
72 static void mta_relay_unref(struct mta_relay *);
73 static void mta_relay_show(struct mta_relay *, struct mproc *, uint32_t, time_t);
74 static int mta_relay_cmp(const struct mta_relay *, const struct mta_relay *);
75 SPLAY_PROTOTYPE(mta_relay_tree, mta_relay, entry, mta_relay_cmp);
76 
77 SPLAY_HEAD(mta_host_tree, mta_host);
78 static struct mta_host *mta_host(const struct sockaddr *);
79 static void mta_host_ref(struct mta_host *);
80 static void mta_host_unref(struct mta_host *);
81 static int mta_host_cmp(const struct mta_host *, const struct mta_host *);
82 SPLAY_PROTOTYPE(mta_host_tree, mta_host, entry, mta_host_cmp);
83 
84 SPLAY_HEAD(mta_domain_tree, mta_domain);
85 static struct mta_domain *mta_domain(char *, int);
86 #if 0
87 static void mta_domain_ref(struct mta_domain *);
88 #endif
89 static void mta_domain_unref(struct mta_domain *);
90 static int mta_domain_cmp(const struct mta_domain *, const struct mta_domain *);
91 SPLAY_PROTOTYPE(mta_domain_tree, mta_domain, entry, mta_domain_cmp);
92 
93 SPLAY_HEAD(mta_source_tree, mta_source);
94 static struct mta_source *mta_source(const struct sockaddr *);
95 static void mta_source_ref(struct mta_source *);
96 static void mta_source_unref(struct mta_source *);
97 static const char *mta_source_to_text(struct mta_source *);
98 static int mta_source_cmp(const struct mta_source *, const struct mta_source *);
99 SPLAY_PROTOTYPE(mta_source_tree, mta_source, entry, mta_source_cmp);
100 
101 static struct mta_connector *mta_connector(struct mta_relay *,
102     struct mta_source *);
103 static void mta_connector_free(struct mta_connector *);
104 static const char *mta_connector_to_text(struct mta_connector *);
105 
106 SPLAY_HEAD(mta_route_tree, mta_route);
107 static struct mta_route *mta_route(struct mta_source *, struct mta_host *);
108 static void mta_route_ref(struct mta_route *);
109 static void mta_route_unref(struct mta_route *);
110 static const char *mta_route_to_text(struct mta_route *);
111 static int mta_route_cmp(const struct mta_route *, const struct mta_route *);
112 SPLAY_PROTOTYPE(mta_route_tree, mta_route, entry, mta_route_cmp);
113 
114 struct mta_block {
115 	SPLAY_ENTRY(mta_block)	 entry;
116 	struct mta_source	*source;
117 	char			*domain;
118 };
119 
120 SPLAY_HEAD(mta_block_tree, mta_block);
121 void mta_block(struct mta_source *, char *);
122 void mta_unblock(struct mta_source *, char *);
123 int mta_is_blocked(struct mta_source *, char *);
124 static int mta_block_cmp(const struct mta_block *, const struct mta_block *);
125 SPLAY_PROTOTYPE(mta_block_tree, mta_block, entry, mta_block_cmp);
126 
127 /*
128  * This function is not publicy exported because it is a hack until libtls
129  * has a proper privsep setup
130  */
131 void tls_config_use_fake_private_key(struct tls_config *config);
132 
133 static struct mta_relay_tree		relays;
134 static struct mta_domain_tree		domains;
135 static struct mta_host_tree		hosts;
136 static struct mta_source_tree		sources;
137 static struct mta_route_tree		routes;
138 static struct mta_block_tree		blocks;
139 
140 static struct tree wait_mx;
141 static struct tree wait_preference;
142 static struct tree wait_secret;
143 static struct tree wait_smarthost;
144 static struct tree wait_source;
145 static struct tree flush_evp;
146 static struct event ev_flush_evp;
147 
148 static struct runq *runq_relay;
149 static struct runq *runq_connector;
150 static struct runq *runq_route;
151 static struct runq *runq_hoststat;
152 
153 static time_t	max_seen_conndelay_route;
154 static time_t	max_seen_discdelay_route;
155 
156 #define	HOSTSTAT_EXPIRE_DELAY	(4 * 3600)
157 struct hoststat {
158 	char			 name[HOST_NAME_MAX+1];
159 	time_t			 tm;
160 	char			 error[LINE_MAX];
161 	struct tree		 deferred;
162 };
163 static struct dict hoststat;
164 
165 void mta_hoststat_update(const char *, const char *);
166 void mta_hoststat_cache(const char *, uint64_t);
167 void mta_hoststat_uncache(const char *, uint64_t);
168 void mta_hoststat_reschedule(const char *);
169 static void mta_hoststat_remove_entry(struct hoststat *);
170 
171 void
172 mta_imsg(struct mproc *p, struct imsg *imsg)
173 {
174 	struct mta_relay	*relay;
175 	struct mta_domain	*domain;
176 	struct mta_host		*host;
177 	struct mta_route	*route;
178 	struct mta_block	*block;
179 	struct mta_mx		*mx, *imx;
180 	struct mta_source	*source;
181 	struct hoststat		*hs;
182 	struct sockaddr_storage	 ss;
183 	struct envelope		 evp, *e;
184 	struct msg		 m;
185 	const char		*secret;
186 	const char		*hostname;
187 	const char		*dom;
188 	const char		*smarthost;
189 	uint64_t		 reqid;
190 	time_t			 t;
191 	char			 buf[LINE_MAX];
192 	int			 dnserror, preference, v, status;
193 	void			*iter;
194 	uint64_t		 u64;
195 
196 	switch (imsg->hdr.type) {
197 	case IMSG_QUEUE_TRANSFER:
198 		m_msg(&m, imsg);
199 		m_get_envelope(&m, &evp);
200 		m_end(&m);
201 		mta_handle_envelope(&evp, NULL);
202 		return;
203 
204 	case IMSG_MTA_OPEN_MESSAGE:
205 		mta_session_imsg(p, imsg);
206 		return;
207 
208 	case IMSG_MTA_LOOKUP_CREDENTIALS:
209 		m_msg(&m, imsg);
210 		m_get_id(&m, &reqid);
211 		m_get_string(&m, &secret);
212 		m_end(&m);
213 		relay = tree_xpop(&wait_secret, reqid);
214 		mta_on_secret(relay, secret[0] ? secret : NULL);
215 		return;
216 
217 	case IMSG_MTA_LOOKUP_SOURCE:
218 		m_msg(&m, imsg);
219 		m_get_id(&m, &reqid);
220 		m_get_int(&m, &status);
221 		if (status == LKA_OK)
222 			m_get_sockaddr(&m, (struct sockaddr*)&ss);
223 		m_end(&m);
224 
225 		relay = tree_xpop(&wait_source, reqid);
226 		mta_on_source(relay, (status == LKA_OK) ?
227 		    mta_source((struct sockaddr *)&ss) : NULL);
228 		return;
229 
230 	case IMSG_MTA_LOOKUP_SMARTHOST:
231 		m_msg(&m, imsg);
232 		m_get_id(&m, &reqid);
233 		m_get_int(&m, &status);
234 		smarthost = NULL;
235 		if (status == LKA_OK)
236 			m_get_string(&m, &smarthost);
237 		m_end(&m);
238 
239 		e = tree_xpop(&wait_smarthost, reqid);
240 		mta_on_smarthost(e, smarthost);
241 		return;
242 
243 	case IMSG_MTA_LOOKUP_HELO:
244 		mta_session_imsg(p, imsg);
245 		return;
246 
247 	case IMSG_MTA_DNS_HOST:
248 		m_msg(&m, imsg);
249 		m_get_id(&m, &reqid);
250 		m_get_string(&m, &hostname);
251 		m_get_sockaddr(&m, (struct sockaddr*)&ss);
252 		m_get_int(&m, &preference);
253 		m_end(&m);
254 		domain = tree_xget(&wait_mx, reqid);
255 		mx = xcalloc(1, sizeof *mx);
256 		mx->mxname = xstrdup(hostname);
257 		mx->host = mta_host((struct sockaddr*)&ss);
258 		mx->preference = preference;
259 		TAILQ_FOREACH(imx, &domain->mxs, entry) {
260 			if (imx->preference > mx->preference) {
261 				TAILQ_INSERT_BEFORE(imx, mx, entry);
262 				return;
263 			}
264 		}
265 		TAILQ_INSERT_TAIL(&domain->mxs, mx, entry);
266 		return;
267 
268 	case IMSG_MTA_DNS_HOST_END:
269 		m_msg(&m, imsg);
270 		m_get_id(&m, &reqid);
271 		m_get_int(&m, &dnserror);
272 		m_end(&m);
273 		domain = tree_xpop(&wait_mx, reqid);
274 		domain->mxstatus = dnserror;
275 		if (domain->mxstatus == DNS_OK) {
276 			log_debug("debug: MXs for domain %s:",
277 			    domain->name);
278 			TAILQ_FOREACH(mx, &domain->mxs, entry)
279 				log_debug("	%s preference %d",
280 				    sa_to_text(mx->host->sa),
281 				    mx->preference);
282 		}
283 		else {
284 			log_debug("debug: Failed MX query for %s:",
285 			    domain->name);
286 		}
287 		domain->lastmxquery = time(NULL);
288 		waitq_run(&domain->mxs, domain);
289 		return;
290 
291 	case IMSG_MTA_DNS_MX_PREFERENCE:
292 		m_msg(&m, imsg);
293 		m_get_id(&m, &reqid);
294 		m_get_int(&m, &dnserror);
295 		if (dnserror == 0)
296 			m_get_int(&m, &preference);
297 		m_end(&m);
298 
299 		relay = tree_xpop(&wait_preference, reqid);
300 		if (dnserror) {
301 			log_warnx("warn: Couldn't find backup "
302 			    "preference for %s: error %d",
303 			    mta_relay_to_text(relay), dnserror);
304 			preference = INT_MAX;
305 		}
306 		mta_on_preference(relay, preference);
307 		return;
308 
309 	case IMSG_CTL_RESUME_ROUTE:
310 		u64 = *((uint64_t *)imsg->data);
311 		if (u64)
312 			log_debug("resuming route: %llu",
313 			    (unsigned long long)u64);
314 		else
315 			log_debug("resuming all routes");
316 		SPLAY_FOREACH(route, mta_route_tree, &routes) {
317 			if (u64 && route->id != u64)
318 				continue;
319 
320 			if (route->flags & ROUTE_DISABLED) {
321 				log_info("smtp-out: Enabling route %s per admin request",
322 				    mta_route_to_text(route));
323 				if (!runq_cancel(runq_route, route)) {
324 					log_warnx("warn: route not on runq");
325 					fatalx("exiting");
326 				}
327 				route->flags &= ~ROUTE_DISABLED;
328 				route->flags |= ROUTE_NEW;
329 				route->nerror = 0;
330 				route->penalty = 0;
331 				mta_route_unref(route); /* from mta_route_disable */
332 			}
333 
334 			if (u64)
335 				break;
336 		}
337 		return;
338 
339 	case IMSG_CTL_MTA_SHOW_HOSTS:
340 		t = time(NULL);
341 		SPLAY_FOREACH(host, mta_host_tree, &hosts) {
342 			(void)snprintf(buf, sizeof(buf),
343 			    "%s %s refcount=%d nconn=%zu lastconn=%s",
344 			    sockaddr_to_text(host->sa),
345 			    host->ptrname,
346 			    host->refcount,
347 			    host->nconn,
348 			    host->lastconn ? duration_to_text(t - host->lastconn) : "-");
349 			m_compose(p, IMSG_CTL_MTA_SHOW_HOSTS,
350 			    imsg->hdr.peerid, 0, -1,
351 			    buf, strlen(buf) + 1);
352 		}
353 		m_compose(p, IMSG_CTL_MTA_SHOW_HOSTS, imsg->hdr.peerid,
354 		    0, -1, NULL, 0);
355 		return;
356 
357 	case IMSG_CTL_MTA_SHOW_RELAYS:
358 		t = time(NULL);
359 		SPLAY_FOREACH(relay, mta_relay_tree, &relays)
360 			mta_relay_show(relay, p, imsg->hdr.peerid, t);
361 		m_compose(p, IMSG_CTL_MTA_SHOW_RELAYS, imsg->hdr.peerid,
362 		    0, -1, NULL, 0);
363 		return;
364 
365 	case IMSG_CTL_MTA_SHOW_ROUTES:
366 		SPLAY_FOREACH(route, mta_route_tree, &routes) {
367 			v = runq_pending(runq_route, route, &t);
368 			(void)snprintf(buf, sizeof(buf),
369 			    "%llu. %s %c%c%c%c nconn=%zu nerror=%d penalty=%d timeout=%s",
370 			    (unsigned long long)route->id,
371 			    mta_route_to_text(route),
372 			    route->flags & ROUTE_NEW ? 'N' : '-',
373 			    route->flags & ROUTE_DISABLED ? 'D' : '-',
374 			    route->flags & ROUTE_RUNQ ? 'Q' : '-',
375 			    route->flags & ROUTE_KEEPALIVE ? 'K' : '-',
376 			    route->nconn,
377 			    route->nerror,
378 			    route->penalty,
379 			    v ? duration_to_text(t - time(NULL)) : "-");
380 			m_compose(p, IMSG_CTL_MTA_SHOW_ROUTES,
381 			    imsg->hdr.peerid, 0, -1,
382 			    buf, strlen(buf) + 1);
383 		}
384 		m_compose(p, IMSG_CTL_MTA_SHOW_ROUTES, imsg->hdr.peerid,
385 		    0, -1, NULL, 0);
386 		return;
387 
388 	case IMSG_CTL_MTA_SHOW_HOSTSTATS:
389 		iter = NULL;
390 		while (dict_iter(&hoststat, &iter, &hostname,
391 			(void **)&hs)) {
392 			(void)snprintf(buf, sizeof(buf),
393 			    "%s|%llu|%s",
394 			    hostname, (unsigned long long) hs->tm,
395 			    hs->error);
396 			m_compose(p, IMSG_CTL_MTA_SHOW_HOSTSTATS,
397 			    imsg->hdr.peerid, 0, -1,
398 			    buf, strlen(buf) + 1);
399 		}
400 		m_compose(p, IMSG_CTL_MTA_SHOW_HOSTSTATS,
401 		    imsg->hdr.peerid,
402 		    0, -1, NULL, 0);
403 		return;
404 
405 	case IMSG_CTL_MTA_BLOCK:
406 		m_msg(&m, imsg);
407 		m_get_sockaddr(&m, (struct sockaddr*)&ss);
408 		m_get_string(&m, &dom);
409 		m_end(&m);
410 		source = mta_source((struct sockaddr*)&ss);
411 		if (*dom != '\0') {
412 			if (!(strlcpy(buf, dom, sizeof(buf))
413 				>= sizeof(buf)))
414 				mta_block(source, buf);
415 		}
416 		else
417 			mta_block(source, NULL);
418 		mta_source_unref(source);
419 		m_compose(p, IMSG_CTL_OK, imsg->hdr.peerid, 0, -1, NULL, 0);
420 		return;
421 
422 	case IMSG_CTL_MTA_UNBLOCK:
423 		m_msg(&m, imsg);
424 		m_get_sockaddr(&m, (struct sockaddr*)&ss);
425 		m_get_string(&m, &dom);
426 		m_end(&m);
427 		source = mta_source((struct sockaddr*)&ss);
428 		if (*dom != '\0') {
429 			if (!(strlcpy(buf, dom, sizeof(buf))
430 				>= sizeof(buf)))
431 				mta_unblock(source, buf);
432 		}
433 		else
434 			mta_unblock(source, NULL);
435 		mta_source_unref(source);
436 		m_compose(p, IMSG_CTL_OK, imsg->hdr.peerid, 0, -1, NULL, 0);
437 		return;
438 
439 	case IMSG_CTL_MTA_SHOW_BLOCK:
440 		SPLAY_FOREACH(block, mta_block_tree, &blocks) {
441 			(void)snprintf(buf, sizeof(buf), "%s -> %s",
442 			    mta_source_to_text(block->source),
443 			    block->domain ? block->domain : "*");
444 			m_compose(p, IMSG_CTL_MTA_SHOW_BLOCK,
445 			    imsg->hdr.peerid, 0, -1, buf, strlen(buf) + 1);
446 		}
447 		m_compose(p, IMSG_CTL_MTA_SHOW_BLOCK, imsg->hdr.peerid,
448 		    0, -1, NULL, 0);
449 		return;
450 	}
451 
452 	fatalx("mta_imsg: unexpected %s imsg", imsg_to_str(imsg->hdr.type));
453 }
454 
455 void
456 mta_postfork(void)
457 {
458 	struct dispatcher *dispatcher;
459 	const char *key;
460 	void *iter;
461 
462 	iter = NULL;
463 	while (dict_iter(env->sc_dispatchers, &iter, &key, (void **)&dispatcher)) {
464 		log_debug("%s: %s", __func__, key);
465 		mta_setup_dispatcher(dispatcher);
466 	}
467 }
468 
469 static void
470 mta_setup_dispatcher(struct dispatcher *dispatcher)
471 {
472 	struct dispatcher_remote *remote;
473 	static const char *dheparams[] = { "none", "auto", "legacy" };
474 	struct tls_config *config;
475 	struct pki *pki;
476 	struct ca *ca;
477 	const char *ciphers;
478 	uint32_t protos;
479 
480 	if (dispatcher->type != DISPATCHER_REMOTE)
481 		return;
482 
483 	remote = &dispatcher->u.remote;
484 
485 	if ((config = tls_config_new()) == NULL)
486 		fatal("smtpd: tls_config_new");
487 
488 	ciphers = env->sc_tls_ciphers;
489 	if (remote->tls_ciphers)
490 		ciphers = remote->tls_ciphers;
491 	if (ciphers && tls_config_set_ciphers(config, ciphers) == -1)
492 		fatal("%s", tls_config_error(config));
493 
494 	if (remote->tls_protocols) {
495 		if (tls_config_parse_protocols(&protos,
496 		    remote->tls_protocols) == -1)
497 			fatal("failed to parse protocols \"%s\"",
498 			    remote->tls_protocols);
499 		if (tls_config_set_protocols(config, protos) == -1)
500 			fatal("%s", tls_config_error(config));
501 	}
502 
503 	if (remote->pki) {
504 		pki = dict_get(env->sc_pki_dict, remote->pki);
505 		if (pki == NULL)
506 			fatal("client pki \"%s\" not found ", remote->pki);
507 
508 		tls_config_set_dheparams(config, dheparams[pki->pki_dhe]);
509 		tls_config_use_fake_private_key(config);
510 		if (tls_config_set_keypair_mem(config, pki->pki_cert,
511 		    pki->pki_cert_len, NULL, 0) == -1)
512 		fatal("tls_config_set_keypair_mem");
513 	}
514 
515 	if (remote->ca) {
516 		ca = dict_get(env->sc_ca_dict, remote->ca);
517 		if (tls_config_set_ca_mem(config, ca->ca_cert, ca->ca_cert_len)
518 		    == -1)
519 			fatal("tls_config_set_ca_mem");
520 	}
521 	else if (tls_config_set_ca_file(config, tls_default_ca_cert_file())
522 	    == -1)
523 		fatal("tls_config_set_ca_file");
524 
525 	if (remote->tls_noverify) {
526 		tls_config_insecure_noverifycert(config);
527 		tls_config_insecure_noverifyname(config);
528 		tls_config_insecure_noverifytime(config);
529 	}
530 	else
531 		tls_config_verify(config);
532 
533 	remote->tls_config = config;
534 }
535 
536 void
537 mta_postprivdrop(void)
538 {
539 	SPLAY_INIT(&relays);
540 	SPLAY_INIT(&domains);
541 	SPLAY_INIT(&hosts);
542 	SPLAY_INIT(&sources);
543 	SPLAY_INIT(&routes);
544 	SPLAY_INIT(&blocks);
545 
546 	tree_init(&wait_secret);
547 	tree_init(&wait_smarthost);
548 	tree_init(&wait_mx);
549 	tree_init(&wait_preference);
550 	tree_init(&wait_source);
551 	tree_init(&flush_evp);
552 	dict_init(&hoststat);
553 
554 	evtimer_set(&ev_flush_evp, mta_delivery_flush_event, NULL);
555 
556 	runq_init(&runq_relay, mta_on_timeout);
557 	runq_init(&runq_connector, mta_on_timeout);
558 	runq_init(&runq_route, mta_on_timeout);
559 	runq_init(&runq_hoststat, mta_on_timeout);
560 }
561 
562 
563 /*
564  * Local error on the given source.
565  */
566 void
567 mta_source_error(struct mta_relay *relay, struct mta_route *route, const char *e)
568 {
569 	struct mta_connector	*c;
570 
571 	/*
572 	 * Remember the source as broken for this connector.
573 	 */
574 	c = mta_connector(relay, route->src);
575 	if (!(c->flags & CONNECTOR_ERROR_SOURCE))
576 		log_info("smtp-out: Error on %s: %s",
577 		    mta_route_to_text(route), e);
578 	c->flags |= CONNECTOR_ERROR_SOURCE;
579 }
580 
581 void
582 mta_route_error(struct mta_relay *relay, struct mta_route *route)
583 {
584 #if 0
585 	route->nerror += 1;
586 
587 	if (route->nerror > MAXERROR_PER_ROUTE) {
588 		log_info("smtp-out: Too many errors on %s: "
589 		    "disabling for a while", mta_route_to_text(route));
590 		mta_route_disable(route, 2, ROUTE_DISABLED_SMTP);
591 	}
592 #endif
593 }
594 
595 void
596 mta_route_ok(struct mta_relay *relay, struct mta_route *route)
597 {
598 	struct mta_connector	*c;
599 
600 	if (!(route->flags & ROUTE_NEW))
601 		return;
602 
603 	log_debug("debug: mta-routing: route %s is now valid.",
604 	    mta_route_to_text(route));
605 
606 	route->nerror = 0;
607 	route->flags &= ~ROUTE_NEW;
608 
609 	c = mta_connector(relay, route->src);
610 	mta_connect(c);
611 }
612 
613 void
614 mta_route_down(struct mta_relay *relay, struct mta_route *route)
615 {
616 #if 0
617 	mta_route_disable(route, 2, ROUTE_DISABLED_SMTP);
618 #endif
619 }
620 
621 void
622 mta_route_collect(struct mta_relay *relay, struct mta_route *route)
623 {
624 	struct mta_connector	*c;
625 
626 	log_debug("debug: mta_route_collect(%s)",
627 	    mta_route_to_text(route));
628 
629 	relay->nconn -= 1;
630 	relay->domain->nconn -= 1;
631 	route->nconn -= 1;
632 	route->src->nconn -= 1;
633 	route->dst->nconn -= 1;
634 	route->lastdisc = time(NULL);
635 
636 	/* First connection failed */
637 	if (route->flags & ROUTE_NEW)
638 		mta_route_disable(route, 1, ROUTE_DISABLED_NET);
639 
640 	c = mta_connector(relay, route->src);
641 	c->nconn -= 1;
642 	mta_connect(c);
643 	mta_route_unref(route); /* from mta_find_route() */
644 	mta_relay_unref(relay); /* from mta_connect() */
645 }
646 
647 struct mta_task *
648 mta_route_next_task(struct mta_relay *relay, struct mta_route *route)
649 {
650 	struct mta_task	*task;
651 
652 	if ((task = TAILQ_FIRST(&relay->tasks))) {
653 		TAILQ_REMOVE(&relay->tasks, task, entry);
654 		relay->ntask -= 1;
655 		task->relay = NULL;
656 
657 		/* When the number of tasks is down to lowat, query some evp */
658 		if (relay->ntask == (size_t)relay->limits->task_lowat) {
659 			if (relay->state & RELAY_ONHOLD) {
660 				log_info("smtp-out: back to lowat on %s: releasing",
661 				    mta_relay_to_text(relay));
662 				relay->state &= ~RELAY_ONHOLD;
663 			}
664 			if (relay->state & RELAY_HOLDQ) {
665 				m_create(p_queue, IMSG_MTA_HOLDQ_RELEASE, 0, 0, -1);
666 				m_add_id(p_queue, relay->id);
667 				m_add_int(p_queue, relay->limits->task_release);
668 				m_close(p_queue);
669 			}
670 		}
671 		else if (relay->ntask == 0 && relay->state & RELAY_HOLDQ) {
672 			m_create(p_queue, IMSG_MTA_HOLDQ_RELEASE, 0, 0, -1);
673 			m_add_id(p_queue, relay->id);
674 			m_add_int(p_queue, 0);
675 			m_close(p_queue);
676 		}
677 	}
678 
679 	return (task);
680 }
681 
682 static void
683 mta_handle_envelope(struct envelope *evp, const char *smarthost)
684 {
685 	struct mta_relay	*relay;
686 	struct mta_task		*task;
687 	struct mta_envelope	*e;
688 	struct dispatcher	*dispatcher;
689 	struct mailaddr		 maddr;
690 	struct relayhost	 relayh;
691 	char			 buf[LINE_MAX];
692 
693 	dispatcher = dict_xget(env->sc_dispatchers, evp->dispatcher);
694 	if (dispatcher->u.remote.smarthost && smarthost == NULL) {
695 		mta_query_smarthost(evp);
696 		return;
697 	}
698 
699 	memset(&relayh, 0, sizeof(relayh));
700 	relayh.tls = RELAY_TLS_OPPORTUNISTIC;
701 	if (smarthost && !text_to_relayhost(&relayh, smarthost)) {
702 		log_warnx("warn: Failed to parse smarthost %s", smarthost);
703 		m_create(p_queue, IMSG_MTA_DELIVERY_TEMPFAIL, 0, 0, -1);
704 		m_add_evpid(p_queue, evp->id);
705 		m_add_string(p_queue, "Cannot parse smarthost");
706 		m_add_int(p_queue, ESC_OTHER_STATUS);
707 		m_close(p_queue);
708 		return;
709 	}
710 
711 	if (relayh.flags & RELAY_AUTH && dispatcher->u.remote.auth == NULL) {
712 		log_warnx("warn: No auth table on action \"%s\" for relay %s",
713 		    evp->dispatcher, smarthost);
714 		m_create(p_queue, IMSG_MTA_DELIVERY_TEMPFAIL, 0, 0, -1);
715 		m_add_evpid(p_queue, evp->id);
716 		m_add_string(p_queue, "No auth table for relaying");
717 		m_add_int(p_queue, ESC_OTHER_STATUS);
718 		m_close(p_queue);
719 		return;
720 	}
721 
722 	if (dispatcher->u.remote.tls_required) {
723 		/* Reject relay if smtp+notls:// is requested */
724 		if (relayh.tls == RELAY_TLS_NO) {
725 			log_warnx("warn: TLS required for action \"%s\"",
726 			    evp->dispatcher);
727 			m_create(p_queue, IMSG_MTA_DELIVERY_TEMPFAIL, 0, 0, -1);
728 			m_add_evpid(p_queue, evp->id);
729 			m_add_string(p_queue, "TLS required for relaying");
730 			m_add_int(p_queue, ESC_OTHER_STATUS);
731 			m_close(p_queue);
732 			return;
733 		}
734 		/* Update smtp:// to smtp+tls:// */
735 		if (relayh.tls == RELAY_TLS_OPPORTUNISTIC)
736 			relayh.tls = RELAY_TLS_STARTTLS;
737 	}
738 
739 	relay = mta_relay(evp, &relayh);
740 	/* ignore if we don't know the limits yet */
741 	if (relay->limits &&
742 	    relay->ntask >= (size_t)relay->limits->task_hiwat) {
743 		if (!(relay->state & RELAY_ONHOLD)) {
744 			log_info("smtp-out: hiwat reached on %s: holding envelopes",
745 			    mta_relay_to_text(relay));
746 			relay->state |= RELAY_ONHOLD;
747 		}
748 	}
749 
750 	/*
751 	 * If the relay has too many pending tasks, tell the
752 	 * scheduler to hold it until further notice
753 	 */
754 	if (relay->state & RELAY_ONHOLD) {
755 		relay->state |= RELAY_HOLDQ;
756 		m_create(p_queue, IMSG_MTA_DELIVERY_HOLD, 0, 0, -1);
757 		m_add_evpid(p_queue, evp->id);
758 		m_add_id(p_queue, relay->id);
759 		m_close(p_queue);
760 		mta_relay_unref(relay); /* from here */
761 		return;
762 	}
763 
764 	task = NULL;
765 	TAILQ_FOREACH(task, &relay->tasks, entry)
766 		if (task->msgid == evpid_to_msgid(evp->id))
767 			break;
768 
769 	if (task == NULL) {
770 		task = xmalloc(sizeof *task);
771 		TAILQ_INIT(&task->envelopes);
772 		task->relay = relay;
773 		relay->ntask += 1;
774 		TAILQ_INSERT_TAIL(&relay->tasks, task, entry);
775 		task->msgid = evpid_to_msgid(evp->id);
776 		if (evp->sender.user[0] || evp->sender.domain[0])
777 			(void)snprintf(buf, sizeof buf, "%s@%s",
778 			    evp->sender.user, evp->sender.domain);
779 		else
780 			buf[0] = '\0';
781 
782 		if (dispatcher->u.remote.mail_from && evp->sender.user[0]) {
783 			memset(&maddr, 0, sizeof (maddr));
784 			if (text_to_mailaddr(&maddr,
785 				dispatcher->u.remote.mail_from)) {
786 				(void)snprintf(buf, sizeof buf, "%s@%s",
787 				    maddr.user[0] ? maddr.user : evp->sender.user,
788 				    maddr.domain[0] ? maddr.domain : evp->sender.domain);
789 			}
790 		}
791 
792 		task->sender = xstrdup(buf);
793 		stat_increment("mta.task", 1);
794 	}
795 
796 	e = xcalloc(1, sizeof *e);
797 	e->id = evp->id;
798 	e->creation = evp->creation;
799 	e->smtpname = xstrdup(evp->smtpname);
800 	(void)snprintf(buf, sizeof buf, "%s@%s",
801 	    evp->dest.user, evp->dest.domain);
802 	e->dest = xstrdup(buf);
803 	(void)snprintf(buf, sizeof buf, "%s@%s",
804 	    evp->rcpt.user, evp->rcpt.domain);
805 	if (strcmp(buf, e->dest))
806 		e->rcpt = xstrdup(buf);
807 	e->task = task;
808 	if (evp->dsn_orcpt.user[0] && evp->dsn_orcpt.domain[0]) {
809 		(void)snprintf(buf, sizeof buf, "%s@%s",
810 	    	    evp->dsn_orcpt.user, evp->dsn_orcpt.domain);
811 		e->dsn_orcpt = xstrdup(buf);
812 	}
813 	(void)strlcpy(e->dsn_envid, evp->dsn_envid,
814 	    sizeof e->dsn_envid);
815 	e->dsn_notify = evp->dsn_notify;
816 	e->dsn_ret = evp->dsn_ret;
817 
818 	TAILQ_INSERT_TAIL(&task->envelopes, e, entry);
819 	log_debug("debug: mta: received evp:%016" PRIx64
820 	    " for <%s>", e->id, e->dest);
821 
822 	stat_increment("mta.envelope", 1);
823 
824 	mta_drain(relay);
825 	mta_relay_unref(relay); /* from here */
826 }
827 
828 static void
829 mta_delivery_flush_event(int fd, short event, void *arg)
830 {
831 	struct mta_envelope	*e;
832 	struct timeval		 tv;
833 
834 	if (tree_poproot(&flush_evp, NULL, (void**)(&e))) {
835 
836 		if (e->delivery == IMSG_MTA_DELIVERY_OK) {
837 			m_create(p_queue, IMSG_MTA_DELIVERY_OK, 0, 0, -1);
838 			m_add_evpid(p_queue, e->id);
839 			m_add_int(p_queue, e->ext);
840 			m_close(p_queue);
841 		} else if (e->delivery == IMSG_MTA_DELIVERY_TEMPFAIL) {
842 			m_create(p_queue, IMSG_MTA_DELIVERY_TEMPFAIL, 0, 0, -1);
843 			m_add_evpid(p_queue, e->id);
844 			m_add_string(p_queue, e->status);
845 			m_add_int(p_queue, ESC_OTHER_STATUS);
846 			m_close(p_queue);
847 		}
848 		else if (e->delivery == IMSG_MTA_DELIVERY_PERMFAIL) {
849 			m_create(p_queue, IMSG_MTA_DELIVERY_PERMFAIL, 0, 0, -1);
850 			m_add_evpid(p_queue, e->id);
851 			m_add_string(p_queue, e->status);
852 			m_add_int(p_queue, ESC_OTHER_STATUS);
853 			m_close(p_queue);
854 		}
855 		else if (e->delivery == IMSG_MTA_DELIVERY_LOOP) {
856 			m_create(p_queue, IMSG_MTA_DELIVERY_LOOP, 0, 0, -1);
857 			m_add_evpid(p_queue, e->id);
858 			m_close(p_queue);
859 		}
860 		else {
861 			log_warnx("warn: bad delivery type %d for %016" PRIx64,
862 			    e->delivery, e->id);
863 			fatalx("aborting");
864 		}
865 
866 		log_debug("debug: mta: flush for %016"PRIx64" (-> %s)", e->id, e->dest);
867 
868 		free(e->smtpname);
869 		free(e->dest);
870 		free(e->rcpt);
871 		free(e->dsn_orcpt);
872 		free(e);
873 
874 		tv.tv_sec = 0;
875 		tv.tv_usec = 0;
876 		evtimer_add(&ev_flush_evp, &tv);
877 	}
878 }
879 
880 void
881 mta_delivery_log(struct mta_envelope *e, const char *source, const char *relay,
882     int delivery, const char *status)
883 {
884 	if (delivery == IMSG_MTA_DELIVERY_OK)
885 		mta_log(e, "Ok", source, relay, status);
886 	else if (delivery == IMSG_MTA_DELIVERY_TEMPFAIL)
887 		mta_log(e, "TempFail", source, relay, status);
888 	else if (delivery == IMSG_MTA_DELIVERY_PERMFAIL)
889 		mta_log(e, "PermFail", source, relay, status);
890 	else if (delivery == IMSG_MTA_DELIVERY_LOOP)
891 		mta_log(e, "PermFail", source, relay, "Loop detected");
892 	else {
893 		log_warnx("warn: bad delivery type %d for %016" PRIx64,
894 		    delivery, e->id);
895 		fatalx("aborting");
896 	}
897 
898 	e->delivery = delivery;
899 	if (status)
900 		(void)strlcpy(e->status, status, sizeof(e->status));
901 }
902 
903 void
904 mta_delivery_notify(struct mta_envelope *e)
905 {
906 	struct timeval	tv;
907 
908 	tree_xset(&flush_evp, e->id, e);
909 	if (tree_count(&flush_evp) == 1) {
910 		tv.tv_sec = 0;
911 		tv.tv_usec = 0;
912 		evtimer_add(&ev_flush_evp, &tv);
913 	}
914 }
915 
916 static void
917 mta_query_mx(struct mta_relay *relay)
918 {
919 	uint64_t	id;
920 
921 	if (relay->status & RELAY_WAIT_MX)
922 		return;
923 
924 	log_debug("debug: mta: querying MX for %s...",
925 	    mta_relay_to_text(relay));
926 
927 	if (waitq_wait(&relay->domain->mxs, mta_on_mx, relay)) {
928 		id = generate_uid();
929 		tree_xset(&wait_mx, id, relay->domain);
930 		if (relay->domain->as_host)
931 			m_create(p_lka,  IMSG_MTA_DNS_HOST, 0, 0, -1);
932 		else
933 			m_create(p_lka,  IMSG_MTA_DNS_MX, 0, 0, -1);
934 		m_add_id(p_lka, id);
935 		m_add_string(p_lka, relay->domain->name);
936 		m_close(p_lka);
937 	}
938 	relay->status |= RELAY_WAIT_MX;
939 	mta_relay_ref(relay);
940 }
941 
942 static void
943 mta_query_limits(struct mta_relay *relay)
944 {
945 	if (relay->status & RELAY_WAIT_LIMITS)
946 		return;
947 
948 	relay->limits = dict_get(env->sc_limits_dict, relay->domain->name);
949 	if (relay->limits == NULL)
950 		relay->limits = dict_get(env->sc_limits_dict, "default");
951 
952 	if (max_seen_conndelay_route < relay->limits->conndelay_route)
953 		max_seen_conndelay_route = relay->limits->conndelay_route;
954 	if (max_seen_discdelay_route < relay->limits->discdelay_route)
955 		max_seen_discdelay_route = relay->limits->discdelay_route;
956 }
957 
958 static void
959 mta_query_secret(struct mta_relay *relay)
960 {
961 	if (relay->status & RELAY_WAIT_SECRET)
962 		return;
963 
964 	log_debug("debug: mta: querying secret for %s...",
965 	    mta_relay_to_text(relay));
966 
967 	tree_xset(&wait_secret, relay->id, relay);
968 	relay->status |= RELAY_WAIT_SECRET;
969 
970 	m_create(p_lka, IMSG_MTA_LOOKUP_CREDENTIALS, 0, 0, -1);
971 	m_add_id(p_lka, relay->id);
972 	m_add_string(p_lka, relay->authtable);
973 	m_add_string(p_lka, relay->authlabel);
974 	m_close(p_lka);
975 
976 	mta_relay_ref(relay);
977 }
978 
979 static void
980 mta_query_smarthost(struct envelope *evp0)
981 {
982 	struct dispatcher *dispatcher;
983 	struct envelope *evp;
984 
985 	evp = malloc(sizeof(*evp));
986 	memmove(evp, evp0, sizeof(*evp));
987 
988 	dispatcher = dict_xget(env->sc_dispatchers, evp->dispatcher);
989 
990 	log_debug("debug: mta: querying smarthost for %s:%s...",
991 	    evp->dispatcher, dispatcher->u.remote.smarthost);
992 
993 	tree_xset(&wait_smarthost, evp->id, evp);
994 
995 	m_create(p_lka, IMSG_MTA_LOOKUP_SMARTHOST, 0, 0, -1);
996 	m_add_id(p_lka, evp->id);
997 	if (dispatcher->u.remote.smarthost_domain)
998 		m_add_string(p_lka, evp->dest.domain);
999 	else
1000 		m_add_string(p_lka, NULL);
1001 	m_add_string(p_lka, dispatcher->u.remote.smarthost);
1002 	m_close(p_lka);
1003 
1004 	log_debug("debug: mta: querying smarthost");
1005 }
1006 
1007 static void
1008 mta_query_preference(struct mta_relay *relay)
1009 {
1010 	if (relay->status & RELAY_WAIT_PREFERENCE)
1011 		return;
1012 
1013 	log_debug("debug: mta: querying preference for %s...",
1014 	    mta_relay_to_text(relay));
1015 
1016 	tree_xset(&wait_preference, relay->id, relay);
1017 	relay->status |= RELAY_WAIT_PREFERENCE;
1018 
1019 	m_create(p_lka,  IMSG_MTA_DNS_MX_PREFERENCE, 0, 0, -1);
1020 	m_add_id(p_lka, relay->id);
1021 	m_add_string(p_lka, relay->domain->name);
1022 	m_add_string(p_lka, relay->backupname);
1023 	m_close(p_lka);
1024 
1025 	mta_relay_ref(relay);
1026 }
1027 
1028 static void
1029 mta_query_source(struct mta_relay *relay)
1030 {
1031 	log_debug("debug: mta: querying source for %s...",
1032 	    mta_relay_to_text(relay));
1033 
1034 	relay->sourceloop += 1;
1035 
1036 	if (relay->sourcetable == NULL) {
1037 		/*
1038 		 * This is a recursive call, but it only happens once, since
1039 		 * another source will not be queried immediately.
1040 		 */
1041 		mta_relay_ref(relay);
1042 		mta_on_source(relay, mta_source(NULL));
1043 		return;
1044 	}
1045 
1046 	m_create(p_lka, IMSG_MTA_LOOKUP_SOURCE, 0, 0, -1);
1047 	m_add_id(p_lka, relay->id);
1048 	m_add_string(p_lka, relay->sourcetable);
1049 	m_close(p_lka);
1050 
1051 	tree_xset(&wait_source, relay->id, relay);
1052 	relay->status |= RELAY_WAIT_SOURCE;
1053 	mta_relay_ref(relay);
1054 }
1055 
1056 static void
1057 mta_on_mx(void *tag, void *arg, void *data)
1058 {
1059 	struct mta_domain	*domain = data;
1060 	struct mta_relay	*relay = arg;
1061 
1062 	log_debug("debug: mta: ... got mx (%p, %s, %s)",
1063 	    tag, domain->name, mta_relay_to_text(relay));
1064 
1065 	switch (domain->mxstatus) {
1066 	case DNS_OK:
1067 		break;
1068 	case DNS_RETRY:
1069 		relay->fail = IMSG_MTA_DELIVERY_TEMPFAIL;
1070 		relay->failstr = "Temporary failure in MX lookup";
1071 		break;
1072 	case DNS_EINVAL:
1073 		relay->fail = IMSG_MTA_DELIVERY_PERMFAIL;
1074 		relay->failstr = "Invalid domain name";
1075 		break;
1076 	case DNS_ENONAME:
1077 		relay->fail = IMSG_MTA_DELIVERY_PERMFAIL;
1078 		relay->failstr = "Domain does not exist";
1079 		break;
1080 	case DNS_ENOTFOUND:
1081 		relay->fail = IMSG_MTA_DELIVERY_TEMPFAIL;
1082 		if (relay->domain->as_host)
1083 			relay->failstr = "Host not found";
1084 		else
1085 			relay->failstr = "No MX found for domain";
1086 		break;
1087 	default:
1088 		fatalx("bad DNS lookup error code");
1089 		break;
1090 	}
1091 
1092 	if (domain->mxstatus)
1093 		log_info("smtp-out: Failed to resolve MX for %s: %s",
1094 		    mta_relay_to_text(relay), relay->failstr);
1095 
1096 	relay->status &= ~RELAY_WAIT_MX;
1097 	mta_drain(relay);
1098 	mta_relay_unref(relay); /* from mta_drain() */
1099 }
1100 
1101 static void
1102 mta_on_secret(struct mta_relay *relay, const char *secret)
1103 {
1104 	log_debug("debug: mta: ... got secret for %s: %s",
1105 	    mta_relay_to_text(relay), secret);
1106 
1107 	if (secret)
1108 		relay->secret = strdup(secret);
1109 
1110 	if (relay->secret == NULL) {
1111 		log_warnx("warn: Failed to retrieve secret "
1112 			    "for %s", mta_relay_to_text(relay));
1113 		relay->fail = IMSG_MTA_DELIVERY_TEMPFAIL;
1114 		relay->failstr = "Could not retrieve credentials";
1115 	}
1116 
1117 	relay->status &= ~RELAY_WAIT_SECRET;
1118 	mta_drain(relay);
1119 	mta_relay_unref(relay); /* from mta_query_secret() */
1120 }
1121 
1122 static void
1123 mta_on_smarthost(struct envelope *evp, const char *smarthost)
1124 {
1125 	if (smarthost == NULL) {
1126 		log_warnx("warn: Failed to retrieve smarthost "
1127 			    "for envelope %"PRIx64, evp->id);
1128 		m_create(p_queue, IMSG_MTA_DELIVERY_TEMPFAIL, 0, 0, -1);
1129 		m_add_evpid(p_queue, evp->id);
1130 		m_add_string(p_queue, "Cannot retrieve smarthost");
1131 		m_add_int(p_queue, ESC_OTHER_STATUS);
1132 		m_close(p_queue);
1133 		return;
1134 	}
1135 
1136 	log_debug("debug: mta: ... got smarthost for %016"PRIx64": %s",
1137 	    evp->id, smarthost);
1138 	mta_handle_envelope(evp, smarthost);
1139 	free(evp);
1140 }
1141 
1142 static void
1143 mta_on_preference(struct mta_relay *relay, int preference)
1144 {
1145 	log_debug("debug: mta: ... got preference for %s: %d",
1146 	    mta_relay_to_text(relay), preference);
1147 
1148 	relay->backuppref = preference;
1149 
1150 	relay->status &= ~RELAY_WAIT_PREFERENCE;
1151 	mta_drain(relay);
1152 	mta_relay_unref(relay); /* from mta_query_preference() */
1153 }
1154 
1155 static void
1156 mta_on_source(struct mta_relay *relay, struct mta_source *source)
1157 {
1158 	struct mta_connector	*c;
1159 	void			*iter;
1160 	int			 delay, errmask;
1161 
1162 	log_debug("debug: mta: ... got source for %s: %s",
1163 	    mta_relay_to_text(relay), source ? mta_source_to_text(source) : "NULL");
1164 
1165 	relay->lastsource = time(NULL);
1166 	delay = DELAY_CHECK_SOURCE_SLOW;
1167 
1168 	if (source) {
1169 		c = mta_connector(relay, source);
1170 		if (c->flags & CONNECTOR_NEW) {
1171 			c->flags &= ~CONNECTOR_NEW;
1172 			delay = DELAY_CHECK_SOURCE;
1173 		}
1174 		mta_connect(c);
1175 		if ((c->flags & CONNECTOR_ERROR) == 0)
1176 			relay->sourceloop = 0;
1177 		else
1178 			delay = DELAY_CHECK_SOURCE_FAST;
1179 		mta_source_unref(source); /* from constructor */
1180 	}
1181 	else {
1182 		log_warnx("warn: Failed to get source address for %s",
1183 		    mta_relay_to_text(relay));
1184 	}
1185 
1186 	if (tree_count(&relay->connectors) == 0) {
1187 		relay->fail = IMSG_MTA_DELIVERY_TEMPFAIL;
1188 		relay->failstr = "Could not retrieve source address";
1189 	}
1190 	if (tree_count(&relay->connectors) < relay->sourceloop) {
1191 		relay->fail = IMSG_MTA_DELIVERY_TEMPFAIL;
1192 		relay->failstr = "No valid route to remote MX";
1193 
1194 		errmask = 0;
1195 		iter = NULL;
1196 		while (tree_iter(&relay->connectors, &iter, NULL, (void **)&c))
1197 			errmask |= c->flags;
1198 
1199 		if (errmask & CONNECTOR_ERROR_ROUTE_SMTP)
1200 			relay->failstr = "Destination seem to reject all mails";
1201 		else if (errmask & CONNECTOR_ERROR_ROUTE_NET)
1202 			relay->failstr = "Network error on destination MXs";
1203 		else if (errmask & CONNECTOR_ERROR_MX)
1204 			relay->failstr = "No MX found for destination";
1205 		else if (errmask & CONNECTOR_ERROR_FAMILY)
1206 			relay->failstr = "Address family mismatch on destination MXs";
1207 		else if (errmask & CONNECTOR_ERROR_BLOCKED)
1208 			relay->failstr = "All routes to destination blocked";
1209 		else
1210 			relay->failstr = "No valid route to destination";
1211 	}
1212 
1213 	relay->nextsource = relay->lastsource + delay;
1214 	relay->status &= ~RELAY_WAIT_SOURCE;
1215 	mta_drain(relay);
1216 	mta_relay_unref(relay); /* from mta_query_source() */
1217 }
1218 
1219 static void
1220 mta_connect(struct mta_connector *c)
1221 {
1222 	struct mta_route	*route;
1223 	struct mta_mx		*mx;
1224 	struct mta_limits	*l = c->relay->limits;
1225 	int			 limits;
1226 	time_t			 nextconn, now;
1227 
1228 	/* toggle the block flag */
1229 	if (mta_is_blocked(c->source, c->relay->domain->name))
1230 		c->flags |= CONNECTOR_ERROR_BLOCKED;
1231 	else
1232 		c->flags &= ~CONNECTOR_ERROR_BLOCKED;
1233 
1234     again:
1235 
1236 	log_debug("debug: mta: connecting with %s", mta_connector_to_text(c));
1237 
1238 	/* Do not connect if this connector has an error. */
1239 	if (c->flags & CONNECTOR_ERROR) {
1240 		log_debug("debug: mta: connector error");
1241 		return;
1242 	}
1243 
1244 	if (c->flags & CONNECTOR_WAIT) {
1245 		log_debug("debug: mta: cancelling connector timeout");
1246 		runq_cancel(runq_connector, c);
1247 		c->flags &= ~CONNECTOR_WAIT;
1248 	}
1249 
1250 	/* No job. */
1251 	if (c->relay->ntask == 0) {
1252 		log_debug("debug: mta: no task for connector");
1253 		return;
1254 	}
1255 
1256 	/* Do not create more connections than necessary */
1257 	if ((c->relay->nconn_ready >= c->relay->ntask) ||
1258 	    (c->relay->nconn > 2 && c->relay->nconn >= c->relay->ntask / 2)) {
1259 		log_debug("debug: mta: enough connections already");
1260 		return;
1261 	}
1262 
1263 	limits = 0;
1264 	nextconn = now = time(NULL);
1265 
1266 	if (c->relay->domain->lastconn + l->conndelay_domain > nextconn) {
1267 		log_debug("debug: mta: cannot use domain %s before %llus",
1268 		    c->relay->domain->name,
1269 		    (unsigned long long) c->relay->domain->lastconn + l->conndelay_domain - now);
1270 		nextconn = c->relay->domain->lastconn + l->conndelay_domain;
1271 	}
1272 	if (c->relay->domain->nconn >= l->maxconn_per_domain) {
1273 		log_debug("debug: mta: hit domain limit");
1274 		limits |= CONNECTOR_LIMIT_DOMAIN;
1275 	}
1276 
1277 	if (c->source->lastconn + l->conndelay_source > nextconn) {
1278 		log_debug("debug: mta: cannot use source %s before %llus",
1279 		    mta_source_to_text(c->source),
1280 		    (unsigned long long) c->source->lastconn + l->conndelay_source - now);
1281 		nextconn = c->source->lastconn + l->conndelay_source;
1282 	}
1283 	if (c->source->nconn >= l->maxconn_per_source) {
1284 		log_debug("debug: mta: hit source limit");
1285 		limits |= CONNECTOR_LIMIT_SOURCE;
1286 	}
1287 
1288 	if (c->lastconn + l->conndelay_connector > nextconn) {
1289 		log_debug("debug: mta: cannot use %s before %llus",
1290 		    mta_connector_to_text(c),
1291 		    (unsigned long long) c->lastconn + l->conndelay_connector - now);
1292 		nextconn = c->lastconn + l->conndelay_connector;
1293 	}
1294 	if (c->nconn >= l->maxconn_per_connector) {
1295 		log_debug("debug: mta: hit connector limit");
1296 		limits |= CONNECTOR_LIMIT_CONN;
1297 	}
1298 
1299 	if (c->relay->lastconn + l->conndelay_relay > nextconn) {
1300 		log_debug("debug: mta: cannot use %s before %llus",
1301 		    mta_relay_to_text(c->relay),
1302 		    (unsigned long long) c->relay->lastconn + l->conndelay_relay - now);
1303 		nextconn = c->relay->lastconn + l->conndelay_relay;
1304 	}
1305 	if (c->relay->nconn >= l->maxconn_per_relay) {
1306 		log_debug("debug: mta: hit relay limit");
1307 		limits |= CONNECTOR_LIMIT_RELAY;
1308 	}
1309 
1310 	/* We can connect now, find a route */
1311 	if (!limits && nextconn <= now)
1312 		route = mta_find_route(c, now, &limits, &nextconn, &mx);
1313 	else
1314 		route = NULL;
1315 
1316 	/* No route */
1317 	if (route == NULL) {
1318 
1319 		if (c->flags & CONNECTOR_ERROR) {
1320 			/* XXX we might want to clear this flag later */
1321 			log_debug("debug: mta-routing: no route available for %s: errors on connector",
1322 			    mta_connector_to_text(c));
1323 			return;
1324 		}
1325 		else if (limits) {
1326 			log_debug("debug: mta-routing: no route available for %s: limits reached",
1327 			    mta_connector_to_text(c));
1328 			nextconn = now + DELAY_CHECK_LIMIT;
1329 		}
1330 		else {
1331 			log_debug("debug: mta-routing: no route available for %s: must wait a bit",
1332 			    mta_connector_to_text(c));
1333 		}
1334 		log_debug("debug: mta: retrying to connect on %s in %llus...",
1335 		    mta_connector_to_text(c),
1336 		    (unsigned long long) nextconn - time(NULL));
1337 		c->flags |= CONNECTOR_WAIT;
1338 		runq_schedule_at(runq_connector, nextconn, c);
1339 		return;
1340 	}
1341 
1342 	log_debug("debug: mta-routing: spawning new connection on %s",
1343 		    mta_route_to_text(route));
1344 
1345 	c->nconn += 1;
1346 	c->lastconn = time(NULL);
1347 
1348 	c->relay->nconn += 1;
1349 	c->relay->lastconn = c->lastconn;
1350 	c->relay->domain->nconn += 1;
1351 	c->relay->domain->lastconn = c->lastconn;
1352 	route->nconn += 1;
1353 	route->lastconn = c->lastconn;
1354 	route->src->nconn += 1;
1355 	route->src->lastconn = c->lastconn;
1356 	route->dst->nconn += 1;
1357 	route->dst->lastconn = c->lastconn;
1358 
1359 	mta_session(c->relay, route, mx->mxname);	/* this never fails synchronously */
1360 	mta_relay_ref(c->relay);
1361 
1362     goto again;
1363 }
1364 
1365 static void
1366 mta_on_timeout(struct runq *runq, void *arg)
1367 {
1368 	struct mta_connector	*connector = arg;
1369 	struct mta_relay	*relay = arg;
1370 	struct mta_route	*route = arg;
1371 	struct hoststat		*hs = arg;
1372 
1373 	if (runq == runq_relay) {
1374 		log_debug("debug: mta: ... timeout for %s",
1375 		    mta_relay_to_text(relay));
1376 		relay->status &= ~RELAY_WAIT_CONNECTOR;
1377 		mta_drain(relay);
1378 		mta_relay_unref(relay); /* from mta_drain() */
1379 	}
1380 	else if (runq == runq_connector) {
1381 		log_debug("debug: mta: ... timeout for %s",
1382 		    mta_connector_to_text(connector));
1383 		connector->flags &= ~CONNECTOR_WAIT;
1384 		mta_connect(connector);
1385 	}
1386 	else if (runq == runq_route) {
1387 		route->flags &= ~ROUTE_RUNQ;
1388 		mta_route_enable(route);
1389 		mta_route_unref(route);
1390 	}
1391 	else if (runq == runq_hoststat) {
1392 		log_debug("debug: mta: ... timeout for hoststat %s",
1393 			hs->name);
1394 		mta_hoststat_remove_entry(hs);
1395 		free(hs);
1396 	}
1397 }
1398 
1399 static void
1400 mta_route_disable(struct mta_route *route, int penalty, int reason)
1401 {
1402 	unsigned long long	delay;
1403 
1404 	route->penalty += penalty;
1405 	route->lastpenalty = time(NULL);
1406 	delay = (unsigned long long)DELAY_ROUTE_BASE * route->penalty * route->penalty;
1407 	if (delay > DELAY_ROUTE_MAX)
1408 		delay = DELAY_ROUTE_MAX;
1409 #if 0
1410 	delay = 60;
1411 #endif
1412 
1413 	log_info("smtp-out: Disabling route %s for %llus",
1414 	    mta_route_to_text(route), delay);
1415 
1416 	if (route->flags & ROUTE_DISABLED)
1417 		runq_cancel(runq_route, route);
1418 	else
1419 		mta_route_ref(route);
1420 
1421 	route->flags |= reason & ROUTE_DISABLED;
1422 	runq_schedule(runq_route, delay, route);
1423 }
1424 
1425 static void
1426 mta_route_enable(struct mta_route *route)
1427 {
1428 	if (route->flags & ROUTE_DISABLED) {
1429 		log_info("smtp-out: Enabling route %s",
1430 		    mta_route_to_text(route));
1431 		route->flags &= ~ROUTE_DISABLED;
1432 		route->flags |= ROUTE_NEW;
1433 		route->nerror = 0;
1434 	}
1435 
1436 	if (route->penalty) {
1437 #if DELAY_QUADRATIC
1438 		route->penalty -= 1;
1439 		route->lastpenalty = time(NULL);
1440 #else
1441 		route->penalty = 0;
1442 #endif
1443 	}
1444 }
1445 
1446 static void
1447 mta_drain(struct mta_relay *r)
1448 {
1449 	char			 buf[64];
1450 
1451 	log_debug("debug: mta: draining %s "
1452 	    "refcount=%d, ntask=%zu, nconnector=%zu, nconn=%zu",
1453 	    mta_relay_to_text(r),
1454 	    r->refcount, r->ntask, tree_count(&r->connectors), r->nconn);
1455 
1456 	/*
1457 	 * All done.
1458 	 */
1459 	if (r->ntask == 0) {
1460 		log_debug("debug: mta: all done for %s", mta_relay_to_text(r));
1461 		return;
1462 	}
1463 
1464 	/*
1465 	 * If we know that this relay is failing flush the tasks.
1466 	 */
1467 	if (r->fail) {
1468 		mta_flush(r, r->fail, r->failstr);
1469 		return;
1470 	}
1471 
1472 	/* Query secret if needed. */
1473 	if (r->flags & RELAY_AUTH && r->secret == NULL)
1474 		mta_query_secret(r);
1475 
1476 	/* Query our preference if needed. */
1477 	if (r->backupname && r->backuppref == -1)
1478 		mta_query_preference(r);
1479 
1480 	/* Query the domain MXs if needed. */
1481 	if (r->domain->lastmxquery == 0)
1482 		mta_query_mx(r);
1483 
1484 	/* Query the limits if needed. */
1485 	if (r->limits == NULL)
1486 		mta_query_limits(r);
1487 
1488 	/* Wait until we are ready to proceed. */
1489 	if (r->status & RELAY_WAITMASK) {
1490 		buf[0] = '\0';
1491 		if (r->status & RELAY_WAIT_MX)
1492 			(void)strlcat(buf, " MX", sizeof buf);
1493 		if (r->status & RELAY_WAIT_PREFERENCE)
1494 			(void)strlcat(buf, " preference", sizeof buf);
1495 		if (r->status & RELAY_WAIT_SECRET)
1496 			(void)strlcat(buf, " secret", sizeof buf);
1497 		if (r->status & RELAY_WAIT_SOURCE)
1498 			(void)strlcat(buf, " source", sizeof buf);
1499 		if (r->status & RELAY_WAIT_CONNECTOR)
1500 			(void)strlcat(buf, " connector", sizeof buf);
1501 		log_debug("debug: mta: %s waiting for%s",
1502 		    mta_relay_to_text(r), buf);
1503 		return;
1504 	}
1505 
1506 	/*
1507 	 * We have pending task, and it's maybe time too try a new source.
1508 	 */
1509 	if (r->nextsource <= time(NULL))
1510 		mta_query_source(r);
1511 	else {
1512 		log_debug("debug: mta: scheduling relay %s in %llus...",
1513 		    mta_relay_to_text(r),
1514 		    (unsigned long long) r->nextsource - time(NULL));
1515 		runq_schedule_at(runq_relay, r->nextsource, r);
1516 		r->status |= RELAY_WAIT_CONNECTOR;
1517 		mta_relay_ref(r);
1518 	}
1519 }
1520 
1521 static void
1522 mta_flush(struct mta_relay *relay, int fail, const char *error)
1523 {
1524 	struct mta_envelope	*e;
1525 	struct mta_task		*task;
1526 	const char     		*domain;
1527 	void			*iter;
1528 	struct mta_connector	*c;
1529 	size_t			 n, r;
1530 
1531 	log_debug("debug: mta_flush(%s, %d, \"%s\")",
1532 	    mta_relay_to_text(relay), fail, error);
1533 
1534 	if (fail != IMSG_MTA_DELIVERY_TEMPFAIL && fail != IMSG_MTA_DELIVERY_PERMFAIL)
1535 		fatalx("unexpected delivery status %d", fail);
1536 
1537 	n = 0;
1538 	while ((task = TAILQ_FIRST(&relay->tasks))) {
1539 		TAILQ_REMOVE(&relay->tasks, task, entry);
1540 		while ((e = TAILQ_FIRST(&task->envelopes))) {
1541 			TAILQ_REMOVE(&task->envelopes, e, entry);
1542 
1543 			/*
1544 			 * host was suspended, cache envelope id in hoststat tree
1545 			 * so that it can be retried when a delivery succeeds for
1546 			 * that domain.
1547 			 */
1548 			domain = strchr(e->dest, '@');
1549 			if (fail == IMSG_MTA_DELIVERY_TEMPFAIL && domain) {
1550 				r = 0;
1551 				iter = NULL;
1552 				while (tree_iter(&relay->connectors, &iter,
1553 					NULL, (void **)&c)) {
1554 					if (c->flags & CONNECTOR_ERROR_ROUTE)
1555 						r++;
1556 				}
1557 				if (tree_count(&relay->connectors) == r)
1558 					mta_hoststat_cache(domain+1, e->id);
1559 			}
1560 
1561 			mta_delivery_log(e, NULL, relay->domain->name, fail, error);
1562 			mta_delivery_notify(e);
1563 
1564 			n++;
1565 		}
1566 		free(task->sender);
1567 		free(task);
1568 	}
1569 
1570 	stat_decrement("mta.task", relay->ntask);
1571 	stat_decrement("mta.envelope", n);
1572 	relay->ntask = 0;
1573 
1574 	/* release all waiting envelopes for the relay */
1575 	if (relay->state & RELAY_HOLDQ) {
1576 		m_create(p_queue, IMSG_MTA_HOLDQ_RELEASE, 0, 0, -1);
1577 		m_add_id(p_queue, relay->id);
1578 		m_add_int(p_queue, -1);
1579 		m_close(p_queue);
1580 	}
1581 }
1582 
1583 /*
1584  * Find a route to use for this connector
1585  */
1586 static struct mta_route *
1587 mta_find_route(struct mta_connector *c, time_t now, int *limits,
1588     time_t *nextconn, struct mta_mx **pmx)
1589 {
1590 	struct mta_route	*route, *best;
1591 	struct mta_limits	*l = c->relay->limits;
1592 	struct mta_mx		*mx;
1593 	int			 level, limit_host, limit_route;
1594 	int			 family_mismatch, seen, suspended_route;
1595 	time_t			 tm;
1596 
1597 	log_debug("debug: mta-routing: searching new route for %s...",
1598 	    mta_connector_to_text(c));
1599 
1600 	tm = 0;
1601 	limit_host = 0;
1602 	limit_route = 0;
1603 	suspended_route = 0;
1604 	family_mismatch = 0;
1605 	level = -1;
1606 	best = NULL;
1607 	seen = 0;
1608 
1609 	TAILQ_FOREACH(mx, &c->relay->domain->mxs, entry) {
1610 		/*
1611 		 * New preference level
1612 		 */
1613 		if (mx->preference > level) {
1614 #ifndef IGNORE_MX_PREFERENCE
1615 			/*
1616 			 * Use the current best MX if found.
1617 			 */
1618 			if (best)
1619 				break;
1620 
1621 			/*
1622 			 * No candidate found.  There are valid MXs at this
1623 			 * preference level but they reached their limit, or
1624 			 * we can't connect yet.
1625 			 */
1626 			if (limit_host || limit_route || tm)
1627 				break;
1628 
1629 			/*
1630 			 *  If we are a backup MX, do not relay to MXs with
1631 			 *  a greater preference value.
1632 			 */
1633 			if (c->relay->backuppref >= 0 &&
1634 			    mx->preference >= c->relay->backuppref)
1635 				break;
1636 
1637 			/*
1638 			 * Start looking at MXs on this preference level.
1639 			 */
1640 #endif
1641 			level = mx->preference;
1642 		}
1643 
1644 		if (mx->host->flags & HOST_IGNORE)
1645 			continue;
1646 
1647 		/* Found a possibly valid mx */
1648 		seen++;
1649 
1650 		if ((c->source->sa &&
1651 		     c->source->sa->sa_family != mx->host->sa->sa_family) ||
1652 		    (l->family && l->family != mx->host->sa->sa_family)) {
1653 			log_debug("debug: mta-routing: skipping host %s: AF mismatch",
1654 			    mta_host_to_text(mx->host));
1655 			family_mismatch = 1;
1656 			continue;
1657 		}
1658 
1659 		if (mx->host->nconn >= l->maxconn_per_host) {
1660 			log_debug("debug: mta-routing: skipping host %s: too many connections",
1661 			    mta_host_to_text(mx->host));
1662 			limit_host = 1;
1663 			continue;
1664 		}
1665 
1666 		if (mx->host->lastconn + l->conndelay_host > now) {
1667 			log_debug("debug: mta-routing: skipping host %s: cannot use before %llus",
1668 			    mta_host_to_text(mx->host),
1669 			    (unsigned long long) mx->host->lastconn + l->conndelay_host - now);
1670 			if (tm == 0 || mx->host->lastconn + l->conndelay_host < tm)
1671 				tm = mx->host->lastconn + l->conndelay_host;
1672 			continue;
1673 		}
1674 
1675 		route = mta_route(c->source, mx->host);
1676 
1677 		if (route->flags & ROUTE_DISABLED) {
1678 			log_debug("debug: mta-routing: skipping route %s: suspend",
1679 			    mta_route_to_text(route));
1680 			suspended_route |= route->flags & ROUTE_DISABLED;
1681 			mta_route_unref(route); /* from here */
1682 			continue;
1683 		}
1684 
1685 		if (route->nconn && (route->flags & ROUTE_NEW)) {
1686 			log_debug("debug: mta-routing: skipping route %s: not validated yet",
1687 			    mta_route_to_text(route));
1688 			limit_route = 1;
1689 			mta_route_unref(route); /* from here */
1690 			continue;
1691 		}
1692 
1693 		if (route->nconn >= l->maxconn_per_route) {
1694 			log_debug("debug: mta-routing: skipping route %s: too many connections",
1695 			    mta_route_to_text(route));
1696 			limit_route = 1;
1697 			mta_route_unref(route); /* from here */
1698 			continue;
1699 		}
1700 
1701 		if (route->lastconn + l->conndelay_route > now) {
1702 			log_debug("debug: mta-routing: skipping route %s: cannot use before %llus (delay after connect)",
1703 			    mta_route_to_text(route),
1704 			    (unsigned long long) route->lastconn + l->conndelay_route - now);
1705 			if (tm == 0 || route->lastconn + l->conndelay_route < tm)
1706 				tm = route->lastconn + l->conndelay_route;
1707 			mta_route_unref(route); /* from here */
1708 			continue;
1709 		}
1710 
1711 		if (route->lastdisc + l->discdelay_route > now) {
1712 			log_debug("debug: mta-routing: skipping route %s: cannot use before %llus (delay after disconnect)",
1713 			    mta_route_to_text(route),
1714 			    (unsigned long long) route->lastdisc + l->discdelay_route - now);
1715 			if (tm == 0 || route->lastdisc + l->discdelay_route < tm)
1716 				tm = route->lastdisc + l->discdelay_route;
1717 			mta_route_unref(route); /* from here */
1718 			continue;
1719 		}
1720 
1721 		/* Use the route with the lowest number of connections. */
1722 		if (best && route->nconn >= best->nconn) {
1723 			log_debug("debug: mta-routing: skipping route %s: current one is better",
1724 			    mta_route_to_text(route));
1725 			mta_route_unref(route); /* from here */
1726 			continue;
1727 		}
1728 
1729 		if (best)
1730 			mta_route_unref(best); /* from here */
1731 		best = route;
1732 		*pmx = mx;
1733 		log_debug("debug: mta-routing: selecting candidate route %s",
1734 		    mta_route_to_text(route));
1735 	}
1736 
1737 	if (best)
1738 		return (best);
1739 
1740 	/* Order is important */
1741 	if (seen == 0) {
1742 		log_info("smtp-out: No MX found for %s",
1743 		    mta_connector_to_text(c));
1744 		c->flags |= CONNECTOR_ERROR_MX;
1745 	}
1746 	else if (limit_route) {
1747 		log_debug("debug: mta: hit route limit");
1748 		*limits |= CONNECTOR_LIMIT_ROUTE;
1749 	}
1750 	else if (limit_host) {
1751 		log_debug("debug: mta: hit host limit");
1752 		*limits |= CONNECTOR_LIMIT_HOST;
1753 	}
1754 	else if (tm) {
1755 		if (tm > *nextconn)
1756 			*nextconn = tm;
1757 	}
1758 	else if (family_mismatch) {
1759 		log_info("smtp-out: Address family mismatch on %s",
1760 		    mta_connector_to_text(c));
1761 		c->flags |= CONNECTOR_ERROR_FAMILY;
1762 	}
1763 	else if (suspended_route) {
1764 		log_info("smtp-out: No valid route for %s",
1765 		    mta_connector_to_text(c));
1766 		if (suspended_route & ROUTE_DISABLED_NET)
1767 			c->flags |= CONNECTOR_ERROR_ROUTE_NET;
1768 		if (suspended_route & ROUTE_DISABLED_SMTP)
1769 			c->flags |= CONNECTOR_ERROR_ROUTE_SMTP;
1770 	}
1771 
1772 	return (NULL);
1773 }
1774 
1775 static void
1776 mta_log(const struct mta_envelope *evp, const char *prefix, const char *source,
1777     const char *relay, const char *status)
1778 {
1779 	log_info("%016"PRIx64" mta delivery evpid=%016"PRIx64" "
1780 	    "from=<%s> to=<%s> rcpt=<%s> source=\"%s\" "
1781 	    "relay=\"%s\" delay=%s result=\"%s\" stat=\"%s\"",
1782 	    evp->session,
1783 	    evp->id,
1784 	    evp->task->sender,
1785 	    evp->dest,
1786 	    evp->rcpt ? evp->rcpt : "-",
1787 	    source ? source : "-",
1788 	    relay,
1789 	    duration_to_text(time(NULL) - evp->creation),
1790 	    prefix,
1791 	    status);
1792 }
1793 
1794 static struct mta_relay *
1795 mta_relay(struct envelope *e, struct relayhost *relayh)
1796 {
1797 	struct dispatcher	*dispatcher;
1798 	struct mta_relay	 key, *r;
1799 
1800 	dispatcher = dict_xget(env->sc_dispatchers, e->dispatcher);
1801 
1802 	memset(&key, 0, sizeof key);
1803 
1804 	key.pki_name = dispatcher->u.remote.pki;
1805 	key.ca_name = dispatcher->u.remote.ca;
1806 	key.authtable = dispatcher->u.remote.auth;
1807 	key.sourcetable = dispatcher->u.remote.source;
1808 	key.helotable = dispatcher->u.remote.helo_source;
1809 	key.heloname = dispatcher->u.remote.helo;
1810 	key.srs = dispatcher->u.remote.srs;
1811 
1812 	if (relayh->hostname[0]) {
1813 		key.domain = mta_domain(relayh->hostname, 1);
1814 	}
1815 	else {
1816 		key.domain = mta_domain(e->dest.domain, 0);
1817 		if (dispatcher->u.remote.backup) {
1818 			key.backupname = dispatcher->u.remote.backupmx;
1819 			if (key.backupname == NULL)
1820 				key.backupname = e->smtpname;
1821 		}
1822 	}
1823 
1824 	key.tls = relayh->tls;
1825 	key.flags |= relayh->flags;
1826 	key.port = relayh->port;
1827 	key.authlabel = relayh->authlabel;
1828 	if (!key.authlabel[0])
1829 		key.authlabel = NULL;
1830 
1831 	if ((key.tls == RELAY_TLS_STARTTLS || key.tls == RELAY_TLS_SMTPS) &&
1832 	    dispatcher->u.remote.tls_noverify == 0)
1833 		key.flags |= RELAY_TLS_VERIFY;
1834 
1835 	if ((r = SPLAY_FIND(mta_relay_tree, &relays, &key)) == NULL) {
1836 		r = xcalloc(1, sizeof *r);
1837 		TAILQ_INIT(&r->tasks);
1838 		r->id = generate_uid();
1839 		r->dispatcher = dispatcher;
1840 		r->tls = key.tls;
1841 		r->flags = key.flags;
1842 		r->domain = key.domain;
1843 		r->backupname = key.backupname ?
1844 		    xstrdup(key.backupname) : NULL;
1845 		r->backuppref = -1;
1846 		r->port = key.port;
1847 		r->pki_name = key.pki_name ? xstrdup(key.pki_name) : NULL;
1848 		r->ca_name = key.ca_name ? xstrdup(key.ca_name) : NULL;
1849 		if (key.authtable)
1850 			r->authtable = xstrdup(key.authtable);
1851 		if (key.authlabel)
1852 			r->authlabel = xstrdup(key.authlabel);
1853 		if (key.sourcetable)
1854 			r->sourcetable = xstrdup(key.sourcetable);
1855 		if (key.helotable)
1856 			r->helotable = xstrdup(key.helotable);
1857 		if (key.heloname)
1858 			r->heloname = xstrdup(key.heloname);
1859 		r->srs = key.srs;
1860 		SPLAY_INSERT(mta_relay_tree, &relays, r);
1861 		stat_increment("mta.relay", 1);
1862 	} else {
1863 		mta_domain_unref(key.domain); /* from here */
1864 	}
1865 
1866 	r->refcount++;
1867 	return (r);
1868 }
1869 
1870 static void
1871 mta_relay_ref(struct mta_relay *r)
1872 {
1873 	r->refcount++;
1874 }
1875 
1876 static void
1877 mta_relay_unref(struct mta_relay *relay)
1878 {
1879 	struct mta_connector	*c;
1880 
1881 	if (--relay->refcount)
1882 		return;
1883 
1884 	/* Make sure they are no envelopes held for this relay */
1885 	if (relay->state & RELAY_HOLDQ) {
1886 		m_create(p_queue, IMSG_MTA_HOLDQ_RELEASE, 0, 0, -1);
1887 		m_add_id(p_queue, relay->id);
1888 		m_add_int(p_queue, 0);
1889 		m_close(p_queue);
1890 	}
1891 
1892 	log_debug("debug: mta: freeing %s", mta_relay_to_text(relay));
1893 	SPLAY_REMOVE(mta_relay_tree, &relays, relay);
1894 
1895 	while ((tree_poproot(&relay->connectors, NULL, (void**)&c)))
1896 		mta_connector_free(c);
1897 
1898 	free(relay->authlabel);
1899 	free(relay->authtable);
1900 	free(relay->backupname);
1901 	free(relay->pki_name);
1902 	free(relay->ca_name);
1903 	free(relay->helotable);
1904 	free(relay->heloname);
1905 	free(relay->secret);
1906 	free(relay->sourcetable);
1907 
1908 	mta_domain_unref(relay->domain); /* from constructor */
1909 	free(relay);
1910 	stat_decrement("mta.relay", 1);
1911 }
1912 
1913 const char *
1914 mta_relay_to_text(struct mta_relay *relay)
1915 {
1916 	static char	 buf[1024];
1917 	char		 tmp[32];
1918 	const char	*sep = ",";
1919 
1920 	(void)snprintf(buf, sizeof buf, "[relay:%s", relay->domain->name);
1921 
1922 	if (relay->port) {
1923 		(void)strlcat(buf, sep, sizeof buf);
1924 		(void)snprintf(tmp, sizeof tmp, "port=%d", (int)relay->port);
1925 		(void)strlcat(buf, tmp, sizeof buf);
1926 	}
1927 
1928 	(void)strlcat(buf, sep, sizeof buf);
1929 	switch(relay->tls) {
1930 	case RELAY_TLS_OPPORTUNISTIC:
1931 		(void)strlcat(buf, "smtp", sizeof buf);
1932 		break;
1933 	case RELAY_TLS_STARTTLS:
1934 		(void)strlcat(buf, "smtp+tls", sizeof buf);
1935 		break;
1936 	case RELAY_TLS_SMTPS:
1937 		(void)strlcat(buf, "smtps", sizeof buf);
1938 		break;
1939 	case RELAY_TLS_NO:
1940 		if (relay->flags & RELAY_LMTP)
1941 			(void)strlcat(buf, "lmtp", sizeof buf);
1942 		else
1943 			(void)strlcat(buf, "smtp+notls", sizeof buf);
1944 		break;
1945 	default:
1946 		(void)strlcat(buf, "???", sizeof buf);
1947 	}
1948 
1949 	if (relay->flags & RELAY_AUTH) {
1950 		(void)strlcat(buf, sep, sizeof buf);
1951 		(void)strlcat(buf, "auth=", sizeof buf);
1952 		(void)strlcat(buf, relay->authtable, sizeof buf);
1953 		(void)strlcat(buf, ":", sizeof buf);
1954 		(void)strlcat(buf, relay->authlabel, sizeof buf);
1955 	}
1956 
1957 	if (relay->pki_name) {
1958 		(void)strlcat(buf, sep, sizeof buf);
1959 		(void)strlcat(buf, "pki_name=", sizeof buf);
1960 		(void)strlcat(buf, relay->pki_name, sizeof buf);
1961 	}
1962 
1963 	if (relay->domain->as_host) {
1964 		(void)strlcat(buf, sep, sizeof buf);
1965 		(void)strlcat(buf, "mx", sizeof buf);
1966 	}
1967 
1968 	if (relay->backupname) {
1969 		(void)strlcat(buf, sep, sizeof buf);
1970 		(void)strlcat(buf, "backup=", sizeof buf);
1971 		(void)strlcat(buf, relay->backupname, sizeof buf);
1972 	}
1973 
1974 	if (relay->sourcetable) {
1975 		(void)strlcat(buf, sep, sizeof buf);
1976 		(void)strlcat(buf, "sourcetable=", sizeof buf);
1977 		(void)strlcat(buf, relay->sourcetable, sizeof buf);
1978 	}
1979 
1980 	if (relay->helotable) {
1981 		(void)strlcat(buf, sep, sizeof buf);
1982 		(void)strlcat(buf, "helotable=", sizeof buf);
1983 		(void)strlcat(buf, relay->helotable, sizeof buf);
1984 	}
1985 
1986 	if (relay->heloname) {
1987 		(void)strlcat(buf, sep, sizeof buf);
1988 		(void)strlcat(buf, "heloname=", sizeof buf);
1989 		(void)strlcat(buf, relay->heloname, sizeof buf);
1990 	}
1991 
1992 	(void)strlcat(buf, "]", sizeof buf);
1993 
1994 	return (buf);
1995 }
1996 
1997 static void
1998 mta_relay_show(struct mta_relay *r, struct mproc *p, uint32_t id, time_t t)
1999 {
2000 	struct mta_connector	*c;
2001 	void			*iter;
2002 	char			 buf[1024], flags[1024], dur[64];
2003 	time_t			 to;
2004 
2005 	flags[0] = '\0';
2006 
2007 #define SHOWSTATUS(f, n) do {							\
2008 		if (r->status & (f)) {						\
2009 			if (flags[0])						\
2010 				(void)strlcat(flags, ",", sizeof(flags));	\
2011 			(void)strlcat(flags, (n), sizeof(flags));		\
2012 		}								\
2013 	} while(0)
2014 
2015 	SHOWSTATUS(RELAY_WAIT_MX, "MX");
2016 	SHOWSTATUS(RELAY_WAIT_PREFERENCE, "preference");
2017 	SHOWSTATUS(RELAY_WAIT_SECRET, "secret");
2018 	SHOWSTATUS(RELAY_WAIT_LIMITS, "limits");
2019 	SHOWSTATUS(RELAY_WAIT_SOURCE, "source");
2020 	SHOWSTATUS(RELAY_WAIT_CONNECTOR, "connector");
2021 #undef SHOWSTATUS
2022 
2023 	if (runq_pending(runq_relay, r, &to))
2024 		(void)snprintf(dur, sizeof(dur), "%s", duration_to_text(to - t));
2025 	else
2026 		(void)strlcpy(dur, "-", sizeof(dur));
2027 
2028 	(void)snprintf(buf, sizeof(buf), "%s refcount=%d ntask=%zu nconn=%zu lastconn=%s timeout=%s wait=%s%s",
2029 	    mta_relay_to_text(r),
2030 	    r->refcount,
2031 	    r->ntask,
2032 	    r->nconn,
2033 	    r->lastconn ? duration_to_text(t - r->lastconn) : "-",
2034 	    dur,
2035 	    flags,
2036 	    (r->state & RELAY_ONHOLD) ? "ONHOLD" : "");
2037 	m_compose(p, IMSG_CTL_MTA_SHOW_RELAYS, id, 0, -1, buf, strlen(buf) + 1);
2038 
2039 	iter = NULL;
2040 	while (tree_iter(&r->connectors, &iter, NULL, (void **)&c)) {
2041 
2042 		if (runq_pending(runq_connector, c, &to))
2043 			(void)snprintf(dur, sizeof(dur), "%s", duration_to_text(to - t));
2044 		else
2045 			(void)strlcpy(dur, "-", sizeof(dur));
2046 
2047 		flags[0] = '\0';
2048 
2049 #define SHOWFLAG(f, n) do {							\
2050 		if (c->flags & (f)) {						\
2051 			if (flags[0])						\
2052 				(void)strlcat(flags, ",", sizeof(flags));	\
2053 			(void)strlcat(flags, (n), sizeof(flags));		\
2054 		}								\
2055 	} while(0)
2056 
2057 		SHOWFLAG(CONNECTOR_NEW,		"NEW");
2058 		SHOWFLAG(CONNECTOR_WAIT,	"WAIT");
2059 
2060 		SHOWFLAG(CONNECTOR_ERROR_FAMILY,	"ERROR_FAMILY");
2061 		SHOWFLAG(CONNECTOR_ERROR_SOURCE,	"ERROR_SOURCE");
2062 		SHOWFLAG(CONNECTOR_ERROR_MX,		"ERROR_MX");
2063 		SHOWFLAG(CONNECTOR_ERROR_ROUTE_NET,	"ERROR_ROUTE_NET");
2064 		SHOWFLAG(CONNECTOR_ERROR_ROUTE_SMTP,	"ERROR_ROUTE_SMTP");
2065 		SHOWFLAG(CONNECTOR_ERROR_BLOCKED,	"ERROR_BLOCKED");
2066 
2067 		SHOWFLAG(CONNECTOR_LIMIT_HOST,		"LIMIT_HOST");
2068 		SHOWFLAG(CONNECTOR_LIMIT_ROUTE,		"LIMIT_ROUTE");
2069 		SHOWFLAG(CONNECTOR_LIMIT_SOURCE,	"LIMIT_SOURCE");
2070 		SHOWFLAG(CONNECTOR_LIMIT_RELAY,		"LIMIT_RELAY");
2071 		SHOWFLAG(CONNECTOR_LIMIT_CONN,		"LIMIT_CONN");
2072 		SHOWFLAG(CONNECTOR_LIMIT_DOMAIN,	"LIMIT_DOMAIN");
2073 #undef SHOWFLAG
2074 
2075 		(void)snprintf(buf, sizeof(buf),
2076 		    "  connector %s refcount=%d nconn=%zu lastconn=%s timeout=%s flags=%s",
2077 		    mta_source_to_text(c->source),
2078 		    c->refcount,
2079 		    c->nconn,
2080 		    c->lastconn ? duration_to_text(t - c->lastconn) : "-",
2081 		    dur,
2082 		    flags);
2083 		m_compose(p, IMSG_CTL_MTA_SHOW_RELAYS, id, 0, -1, buf,
2084 		    strlen(buf) + 1);
2085 
2086 
2087 	}
2088 }
2089 
2090 static int
2091 mta_relay_cmp(const struct mta_relay *a, const struct mta_relay *b)
2092 {
2093 	int	r;
2094 
2095 	if (a->domain < b->domain)
2096 		return (-1);
2097 	if (a->domain > b->domain)
2098 		return (1);
2099 
2100 	if (a->tls < b->tls)
2101 		return (-1);
2102 	if (a->tls > b->tls)
2103 		return (1);
2104 
2105 	if (a->flags < b->flags)
2106 		return (-1);
2107 	if (a->flags > b->flags)
2108 		return (1);
2109 
2110 	if (a->port < b->port)
2111 		return (-1);
2112 	if (a->port > b->port)
2113 		return (1);
2114 
2115 	if (a->authtable == NULL && b->authtable)
2116 		return (-1);
2117 	if (a->authtable && b->authtable == NULL)
2118 		return (1);
2119 	if (a->authtable && ((r = strcmp(a->authtable, b->authtable))))
2120 		return (r);
2121 	if (a->authlabel == NULL && b->authlabel)
2122 		return (-1);
2123 	if (a->authlabel && b->authlabel == NULL)
2124 		return (1);
2125 	if (a->authlabel && ((r = strcmp(a->authlabel, b->authlabel))))
2126 		return (r);
2127 	if (a->sourcetable == NULL && b->sourcetable)
2128 		return (-1);
2129 	if (a->sourcetable && b->sourcetable == NULL)
2130 		return (1);
2131 	if (a->sourcetable && ((r = strcmp(a->sourcetable, b->sourcetable))))
2132 		return (r);
2133 	if (a->helotable == NULL && b->helotable)
2134 		return (-1);
2135 	if (a->helotable && b->helotable == NULL)
2136 		return (1);
2137 	if (a->helotable && ((r = strcmp(a->helotable, b->helotable))))
2138 		return (r);
2139 	if (a->heloname == NULL && b->heloname)
2140 		return (-1);
2141 	if (a->heloname && b->heloname == NULL)
2142 		return (1);
2143 	if (a->heloname && ((r = strcmp(a->heloname, b->heloname))))
2144 		return (r);
2145 
2146 	if (a->pki_name == NULL && b->pki_name)
2147 		return (-1);
2148 	if (a->pki_name && b->pki_name == NULL)
2149 		return (1);
2150 	if (a->pki_name && ((r = strcmp(a->pki_name, b->pki_name))))
2151 		return (r);
2152 
2153 	if (a->ca_name == NULL && b->ca_name)
2154 		return (-1);
2155 	if (a->ca_name && b->ca_name == NULL)
2156 		return (1);
2157 	if (a->ca_name && ((r = strcmp(a->ca_name, b->ca_name))))
2158 		return (r);
2159 
2160 	if (a->backupname == NULL && b->backupname)
2161 		return (-1);
2162 	if (a->backupname && b->backupname == NULL)
2163 		return (1);
2164 	if (a->backupname && ((r = strcmp(a->backupname, b->backupname))))
2165 		return (r);
2166 
2167 	if (a->srs < b->srs)
2168 		return (-1);
2169 	if (a->srs > b->srs)
2170 		return (1);
2171 
2172 	return (0);
2173 }
2174 
2175 SPLAY_GENERATE(mta_relay_tree, mta_relay, entry, mta_relay_cmp);
2176 
2177 static struct mta_host *
2178 mta_host(const struct sockaddr *sa)
2179 {
2180 	struct mta_host		key, *h;
2181 	struct sockaddr_storage	ss;
2182 
2183 	memmove(&ss, sa, sa->sa_len);
2184 	key.sa = (struct sockaddr*)&ss;
2185 	h = SPLAY_FIND(mta_host_tree, &hosts, &key);
2186 
2187 	if (h == NULL) {
2188 		h = xcalloc(1, sizeof(*h));
2189 		h->sa = xmemdup(sa, sa->sa_len);
2190 		SPLAY_INSERT(mta_host_tree, &hosts, h);
2191 		stat_increment("mta.host", 1);
2192 	}
2193 
2194 	h->refcount++;
2195 	return (h);
2196 }
2197 
2198 static void
2199 mta_host_ref(struct mta_host *h)
2200 {
2201 	h->refcount++;
2202 }
2203 
2204 static void
2205 mta_host_unref(struct mta_host *h)
2206 {
2207 	if (--h->refcount)
2208 		return;
2209 
2210 	SPLAY_REMOVE(mta_host_tree, &hosts, h);
2211 	free(h->sa);
2212 	free(h->ptrname);
2213 	free(h);
2214 	stat_decrement("mta.host", 1);
2215 }
2216 
2217 const char *
2218 mta_host_to_text(struct mta_host *h)
2219 {
2220 	static char buf[1024];
2221 
2222 	if (h->ptrname)
2223 		(void)snprintf(buf, sizeof buf, "%s (%s)",
2224 		    sa_to_text(h->sa), h->ptrname);
2225 	else
2226 		(void)snprintf(buf, sizeof buf, "%s", sa_to_text(h->sa));
2227 
2228 	return (buf);
2229 }
2230 
2231 static int
2232 mta_host_cmp(const struct mta_host *a, const struct mta_host *b)
2233 {
2234 	if (a->sa->sa_len < b->sa->sa_len)
2235 		return (-1);
2236 	if (a->sa->sa_len > b->sa->sa_len)
2237 		return (1);
2238 	return (memcmp(a->sa, b->sa, a->sa->sa_len));
2239 }
2240 
2241 SPLAY_GENERATE(mta_host_tree, mta_host, entry, mta_host_cmp);
2242 
2243 static struct mta_domain *
2244 mta_domain(char *name, int as_host)
2245 {
2246 	struct mta_domain	key, *d;
2247 
2248 	key.name = name;
2249 	key.as_host = as_host;
2250 	d = SPLAY_FIND(mta_domain_tree, &domains, &key);
2251 
2252 	if (d == NULL) {
2253 		d = xcalloc(1, sizeof(*d));
2254 		d->name = xstrdup(name);
2255 		d->as_host = as_host;
2256 		TAILQ_INIT(&d->mxs);
2257 		SPLAY_INSERT(mta_domain_tree, &domains, d);
2258 		stat_increment("mta.domain", 1);
2259 	}
2260 
2261 	d->refcount++;
2262 	return (d);
2263 }
2264 
2265 #if 0
2266 static void
2267 mta_domain_ref(struct mta_domain *d)
2268 {
2269 	d->refcount++;
2270 }
2271 #endif
2272 
2273 static void
2274 mta_domain_unref(struct mta_domain *d)
2275 {
2276 	struct mta_mx	*mx;
2277 
2278 	if (--d->refcount)
2279 		return;
2280 
2281 	while ((mx = TAILQ_FIRST(&d->mxs))) {
2282 		TAILQ_REMOVE(&d->mxs, mx, entry);
2283 		mta_host_unref(mx->host); /* from IMSG_DNS_HOST */
2284 		free(mx->mxname);
2285 		free(mx);
2286 	}
2287 
2288 	SPLAY_REMOVE(mta_domain_tree, &domains, d);
2289 	free(d->name);
2290 	free(d);
2291 	stat_decrement("mta.domain", 1);
2292 }
2293 
2294 static int
2295 mta_domain_cmp(const struct mta_domain *a, const struct mta_domain *b)
2296 {
2297 	if (a->as_host < b->as_host)
2298 		return (-1);
2299 	if (a->as_host > b->as_host)
2300 		return (1);
2301 	return (strcasecmp(a->name, b->name));
2302 }
2303 
2304 SPLAY_GENERATE(mta_domain_tree, mta_domain, entry, mta_domain_cmp);
2305 
2306 static struct mta_source *
2307 mta_source(const struct sockaddr *sa)
2308 {
2309 	struct mta_source	key, *s;
2310 	struct sockaddr_storage	ss;
2311 
2312 	if (sa) {
2313 		memmove(&ss, sa, sa->sa_len);
2314 		key.sa = (struct sockaddr*)&ss;
2315 	} else
2316 		key.sa = NULL;
2317 	s = SPLAY_FIND(mta_source_tree, &sources, &key);
2318 
2319 	if (s == NULL) {
2320 		s = xcalloc(1, sizeof(*s));
2321 		if (sa)
2322 			s->sa = xmemdup(sa, sa->sa_len);
2323 		SPLAY_INSERT(mta_source_tree, &sources, s);
2324 		stat_increment("mta.source", 1);
2325 	}
2326 
2327 	s->refcount++;
2328 	return (s);
2329 }
2330 
2331 static void
2332 mta_source_ref(struct mta_source *s)
2333 {
2334 	s->refcount++;
2335 }
2336 
2337 static void
2338 mta_source_unref(struct mta_source *s)
2339 {
2340 	if (--s->refcount)
2341 		return;
2342 
2343 	SPLAY_REMOVE(mta_source_tree, &sources, s);
2344 	free(s->sa);
2345 	free(s);
2346 	stat_decrement("mta.source", 1);
2347 }
2348 
2349 static const char *
2350 mta_source_to_text(struct mta_source *s)
2351 {
2352 	static char buf[1024];
2353 
2354 	if (s->sa == NULL)
2355 		return "[]";
2356 	(void)snprintf(buf, sizeof buf, "%s", sa_to_text(s->sa));
2357 	return (buf);
2358 }
2359 
2360 static int
2361 mta_source_cmp(const struct mta_source *a, const struct mta_source *b)
2362 {
2363 	if (a->sa == NULL)
2364 		return ((b->sa == NULL) ? 0 : -1);
2365 	if (b->sa == NULL)
2366 		return (1);
2367 	if (a->sa->sa_len < b->sa->sa_len)
2368 		return (-1);
2369 	if (a->sa->sa_len > b->sa->sa_len)
2370 		return (1);
2371 	return (memcmp(a->sa, b->sa, a->sa->sa_len));
2372 }
2373 
2374 SPLAY_GENERATE(mta_source_tree, mta_source, entry, mta_source_cmp);
2375 
2376 static struct mta_connector *
2377 mta_connector(struct mta_relay *relay, struct mta_source *source)
2378 {
2379 	struct mta_connector	*c;
2380 
2381 	c = tree_get(&relay->connectors, (uintptr_t)(source));
2382 	if (c == NULL) {
2383 		c = xcalloc(1, sizeof(*c));
2384 		c->relay = relay;
2385 		c->source = source;
2386 		c->flags |= CONNECTOR_NEW;
2387 		mta_source_ref(source);
2388 		tree_xset(&relay->connectors, (uintptr_t)(source), c);
2389 		stat_increment("mta.connector", 1);
2390 		log_debug("debug: mta: new %s", mta_connector_to_text(c));
2391 	}
2392 
2393 	return (c);
2394 }
2395 
2396 static void
2397 mta_connector_free(struct mta_connector *c)
2398 {
2399 	log_debug("debug: mta: freeing %s",
2400 	    mta_connector_to_text(c));
2401 
2402 	if (c->flags & CONNECTOR_WAIT) {
2403 		log_debug("debug: mta: cancelling timeout for %s",
2404 		    mta_connector_to_text(c));
2405 		runq_cancel(runq_connector, c);
2406 	}
2407 	mta_source_unref(c->source); /* from constructor */
2408 	free(c);
2409 
2410 	stat_decrement("mta.connector", 1);
2411 }
2412 
2413 static const char *
2414 mta_connector_to_text(struct mta_connector *c)
2415 {
2416 	static char buf[1024];
2417 
2418 	(void)snprintf(buf, sizeof buf, "[connector:%s->%s,0x%x]",
2419 	    mta_source_to_text(c->source),
2420 	    mta_relay_to_text(c->relay),
2421 	    c->flags);
2422 	return (buf);
2423 }
2424 
2425 static struct mta_route *
2426 mta_route(struct mta_source *src, struct mta_host *dst)
2427 {
2428 	struct mta_route	key, *r;
2429 	static uint64_t		rid = 0;
2430 
2431 	key.src = src;
2432 	key.dst = dst;
2433 	r = SPLAY_FIND(mta_route_tree, &routes, &key);
2434 
2435 	if (r == NULL) {
2436 		r = xcalloc(1, sizeof(*r));
2437 		r->src = src;
2438 		r->dst = dst;
2439 		r->flags |= ROUTE_NEW;
2440 		r->id = ++rid;
2441 		SPLAY_INSERT(mta_route_tree, &routes, r);
2442 		mta_source_ref(src);
2443 		mta_host_ref(dst);
2444 		stat_increment("mta.route", 1);
2445 	}
2446 	else if (r->flags & ROUTE_RUNQ) {
2447 		log_debug("debug: mta: mta_route_ref(): cancelling runq for route %s",
2448 		    mta_route_to_text(r));
2449 		r->flags &= ~(ROUTE_RUNQ | ROUTE_KEEPALIVE);
2450 		runq_cancel(runq_route, r);
2451 		r->refcount--; /* from mta_route_unref() */
2452 	}
2453 
2454 	r->refcount++;
2455 	return (r);
2456 }
2457 
2458 static void
2459 mta_route_ref(struct mta_route *r)
2460 {
2461 	r->refcount++;
2462 }
2463 
2464 static void
2465 mta_route_unref(struct mta_route *r)
2466 {
2467 	time_t	sched, now;
2468 	int	delay;
2469 
2470 	if (--r->refcount)
2471 		return;
2472 
2473 	/*
2474 	 * Nothing references this route, but we might want to keep it alive
2475 	 * for a while.
2476 	 */
2477 	now = time(NULL);
2478 	sched = 0;
2479 
2480 	if (r->penalty) {
2481 #if DELAY_QUADRATIC
2482 		delay = DELAY_ROUTE_BASE * r->penalty * r->penalty;
2483 #else
2484 		delay = 15 * 60;
2485 #endif
2486 		if (delay > DELAY_ROUTE_MAX)
2487 			delay = DELAY_ROUTE_MAX;
2488 		sched = r->lastpenalty + delay;
2489 		log_debug("debug: mta: mta_route_unref(): keeping route %s alive for %llus (penalty %d)",
2490 		    mta_route_to_text(r), (unsigned long long) sched - now, r->penalty);
2491 	} else if (!(r->flags & ROUTE_KEEPALIVE)) {
2492 		if (r->lastconn + max_seen_conndelay_route > now)
2493 			sched = r->lastconn + max_seen_conndelay_route;
2494 		if (r->lastdisc + max_seen_discdelay_route > now &&
2495 		    r->lastdisc + max_seen_discdelay_route < sched)
2496 			sched = r->lastdisc + max_seen_discdelay_route;
2497 
2498 		if (sched > now)
2499 			log_debug("debug: mta: mta_route_unref(): keeping route %s alive for %llus (imposed delay)",
2500 			    mta_route_to_text(r), (unsigned long long) sched - now);
2501 	}
2502 
2503 	if (sched > now) {
2504 		r->flags |= ROUTE_RUNQ;
2505 		runq_schedule_at(runq_route, sched, r);
2506 		r->refcount++;
2507 		return;
2508 	}
2509 
2510 	log_debug("debug: mta: mta_route_unref(): really discarding route %s",
2511 	    mta_route_to_text(r));
2512 
2513 	SPLAY_REMOVE(mta_route_tree, &routes, r);
2514 	mta_source_unref(r->src); /* from constructor */
2515 	mta_host_unref(r->dst); /* from constructor */
2516 	free(r);
2517 	stat_decrement("mta.route", 1);
2518 }
2519 
2520 static const char *
2521 mta_route_to_text(struct mta_route *r)
2522 {
2523 	static char	buf[1024];
2524 
2525 	(void)snprintf(buf, sizeof buf, "%s <-> %s",
2526 	    mta_source_to_text(r->src),
2527 	    mta_host_to_text(r->dst));
2528 
2529 	return (buf);
2530 }
2531 
2532 static int
2533 mta_route_cmp(const struct mta_route *a, const struct mta_route *b)
2534 {
2535 	if (a->src < b->src)
2536 		return (-1);
2537 	if (a->src > b->src)
2538 		return (1);
2539 
2540 	if (a->dst < b->dst)
2541 		return (-1);
2542 	if (a->dst > b->dst)
2543 		return (1);
2544 
2545 	return (0);
2546 }
2547 
2548 SPLAY_GENERATE(mta_route_tree, mta_route, entry, mta_route_cmp);
2549 
2550 void
2551 mta_block(struct mta_source *src, char *dom)
2552 {
2553 	struct mta_block key, *b;
2554 
2555 	key.source = src;
2556 	key.domain = dom;
2557 
2558 	b = SPLAY_FIND(mta_block_tree, &blocks, &key);
2559 	if (b != NULL)
2560 		return;
2561 
2562 	b = xcalloc(1, sizeof(*b));
2563 	if (dom)
2564 		b->domain = xstrdup(dom);
2565 	b->source = src;
2566 	mta_source_ref(src);
2567 	SPLAY_INSERT(mta_block_tree, &blocks, b);
2568 }
2569 
2570 void
2571 mta_unblock(struct mta_source *src, char *dom)
2572 {
2573 	struct mta_block key, *b;
2574 
2575 	key.source = src;
2576 	key.domain = dom;
2577 
2578 	b = SPLAY_FIND(mta_block_tree, &blocks, &key);
2579 	if (b == NULL)
2580 		return;
2581 
2582 	SPLAY_REMOVE(mta_block_tree, &blocks, b);
2583 
2584 	mta_source_unref(b->source);
2585 	free(b->domain);
2586 	free(b);
2587 }
2588 
2589 int
2590 mta_is_blocked(struct mta_source *src, char *dom)
2591 {
2592 	struct mta_block key;
2593 
2594 	key.source = src;
2595 	key.domain = dom;
2596 
2597 	if (SPLAY_FIND(mta_block_tree, &blocks, &key))
2598 		return (1);
2599 
2600 	return (0);
2601 }
2602 
2603 static
2604 int
2605 mta_block_cmp(const struct mta_block *a, const struct mta_block *b)
2606 {
2607 	if (a->source < b->source)
2608 		return (-1);
2609 	if (a->source > b->source)
2610 		return (1);
2611 	if (!a->domain && b->domain)
2612 		return (-1);
2613 	if (a->domain && !b->domain)
2614 		return (1);
2615 	if (a->domain == b->domain)
2616 		return (0);
2617 	return (strcasecmp(a->domain, b->domain));
2618 }
2619 
2620 SPLAY_GENERATE(mta_block_tree, mta_block, entry, mta_block_cmp);
2621 
2622 
2623 
2624 /* hoststat errors are not critical, we do best effort */
2625 void
2626 mta_hoststat_update(const char *host, const char *error)
2627 {
2628 	struct hoststat	*hs = NULL;
2629 	char		 buf[HOST_NAME_MAX+1];
2630 
2631 	if (!lowercase(buf, host, sizeof buf))
2632 		return;
2633 
2634 	hs = dict_get(&hoststat, buf);
2635 	if (hs == NULL) {
2636 		if ((hs = calloc(1, sizeof *hs)) == NULL)
2637 			return;
2638 		tree_init(&hs->deferred);
2639 		runq_schedule(runq_hoststat, HOSTSTAT_EXPIRE_DELAY, hs);
2640 	}
2641 	(void)strlcpy(hs->name, buf, sizeof hs->name);
2642 	(void)strlcpy(hs->error, error, sizeof hs->error);
2643 	hs->tm = time(NULL);
2644 	dict_set(&hoststat, buf, hs);
2645 
2646 	runq_cancel(runq_hoststat, hs);
2647 	runq_schedule(runq_hoststat, HOSTSTAT_EXPIRE_DELAY, hs);
2648 }
2649 
2650 void
2651 mta_hoststat_cache(const char *host, uint64_t evpid)
2652 {
2653 	struct hoststat	*hs = NULL;
2654 	char buf[HOST_NAME_MAX+1];
2655 
2656 	if (!lowercase(buf, host, sizeof buf))
2657 		return;
2658 
2659 	hs = dict_get(&hoststat, buf);
2660 	if (hs == NULL)
2661 		return;
2662 
2663 	if (tree_count(&hs->deferred) >= env->sc_mta_max_deferred)
2664 		return;
2665 
2666 	tree_set(&hs->deferred, evpid, NULL);
2667 }
2668 
2669 void
2670 mta_hoststat_uncache(const char *host, uint64_t evpid)
2671 {
2672 	struct hoststat	*hs = NULL;
2673 	char buf[HOST_NAME_MAX+1];
2674 
2675 	if (!lowercase(buf, host, sizeof buf))
2676 		return;
2677 
2678 	hs = dict_get(&hoststat, buf);
2679 	if (hs == NULL)
2680 		return;
2681 
2682 	tree_pop(&hs->deferred, evpid);
2683 }
2684 
2685 void
2686 mta_hoststat_reschedule(const char *host)
2687 {
2688 	struct hoststat	*hs = NULL;
2689 	char		 buf[HOST_NAME_MAX+1];
2690 	uint64_t	 evpid;
2691 
2692 	if (!lowercase(buf, host, sizeof buf))
2693 		return;
2694 
2695 	hs = dict_get(&hoststat, buf);
2696 	if (hs == NULL)
2697 		return;
2698 
2699 	while (tree_poproot(&hs->deferred, &evpid, NULL)) {
2700 		m_compose(p_queue, IMSG_MTA_SCHEDULE, 0, 0, -1,
2701 		    &evpid, sizeof evpid);
2702 	}
2703 }
2704 
2705 static void
2706 mta_hoststat_remove_entry(struct hoststat *hs)
2707 {
2708 	while (tree_poproot(&hs->deferred, NULL, NULL))
2709 		;
2710 	dict_pop(&hoststat, hs->name);
2711 	runq_cancel(runq_hoststat, hs);
2712 }
2713