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