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