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