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