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