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