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