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