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