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