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