Sync usage with man page.
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / smtp / smtp_connect.c
blobcd4d099ae822e5928834509e61905fa08ee4e98b
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* smtp_connect 3
6 /* SUMMARY
7 /* connect to SMTP/LMTP server and deliver
8 /* SYNOPSIS
9 /* #include "smtp.h"
11 /* int smtp_connect(state)
12 /* SMTP_STATE *state;
13 /* DESCRIPTION
14 /* This module implements SMTP/LMTP connection management and controls
15 /* mail delivery.
17 /* smtp_connect() attempts to establish an SMTP/LMTP session with a host
18 /* that represents the destination domain, or with an optional fallback
19 /* relay when {the destination cannot be found, or when all the
20 /* destination servers are unavailable}. It skips over IP addresses
21 /* that fail to complete the SMTP/LMTP handshake and tries to find
22 /* an alternate server when an SMTP/LMTP session fails to deliver.
24 /* This layer also controls what connections are retrieved from
25 /* the connection cache, and what connections are saved to the cache.
27 /* The destination is either a host (or domain) name or a numeric
28 /* address. Symbolic or numeric service port information may be
29 /* appended, separated by a colon (":"). In the case of LMTP,
30 /* destinations may be specified as "unix:pathname", "inet:host"
31 /* or "inet:host:port".
33 /* With SMTP, the Internet domain name service is queried for mail
34 /* exchanger hosts. Quote the domain name with `[' and `]' to
35 /* suppress mail exchanger lookups.
37 /* Numerical address information should always be quoted with `[]'.
38 /* DIAGNOSTICS
39 /* The delivery status is the result value.
40 /* SEE ALSO
41 /* smtp_proto(3) SMTP client protocol
42 /* LICENSE
43 /* .ad
44 /* .fi
45 /* The Secure Mailer license must be distributed with this software.
46 /* AUTHOR(S)
47 /* Wietse Venema
48 /* IBM T.J. Watson Research
49 /* P.O. Box 704
50 /* Yorktown Heights, NY 10598, USA
52 /* Connection caching in cooperation with:
53 /* Victor Duchovni
54 /* Morgan Stanley
55 /*--*/
57 /* System library. */
59 #include <sys_defs.h>
60 #include <stdlib.h>
61 #include <sys/socket.h>
62 #include <sys/un.h>
63 #include <netinet/in.h>
64 #include <arpa/inet.h>
65 #include <errno.h>
66 #include <netdb.h>
67 #include <stdlib.h>
68 #include <string.h>
69 #include <unistd.h>
70 #include <fcntl.h>
71 #include <ctype.h>
73 #ifndef IPPORT_SMTP
74 #define IPPORT_SMTP 25
75 #endif
77 /* Utility library. */
79 #include <msg.h>
80 #include <vstream.h>
81 #include <vstring.h>
82 #include <split_at.h>
83 #include <mymalloc.h>
84 #include <inet_addr_list.h>
85 #include <iostuff.h>
86 #include <timed_connect.h>
87 #include <stringops.h>
88 #include <host_port.h>
89 #include <sane_connect.h>
90 #include <myaddrinfo.h>
91 #include <sock_addr.h>
93 /* Global library. */
95 #include <mail_params.h>
96 #include <own_inet_addr.h>
97 #include <deliver_pass.h>
98 #include <mail_error.h>
99 #include <dsn_buf.h>
101 /* DNS library. */
103 #include <dns.h>
105 /* Application-specific. */
107 #include <smtp.h>
108 #include <smtp_addr.h>
109 #include <smtp_reuse.h>
112 * Forward declaration.
114 static SMTP_SESSION *smtp_connect_sock(int, struct sockaddr *, int,
115 const char *, const char *,
116 unsigned,
117 const char *, DSN_BUF *,
118 int);
120 /* smtp_connect_unix - connect to UNIX-domain address */
122 static SMTP_SESSION *smtp_connect_unix(const char *addr,
123 DSN_BUF *why,
124 int sess_flags)
126 const char *myname = "smtp_connect_unix";
127 struct sockaddr_un sock_un;
128 int len = strlen(addr);
129 int sock;
131 dsb_reset(why); /* Paranoia */
134 * Sanity checks.
136 if (len >= (int) sizeof(sock_un.sun_path)) {
137 msg_warn("unix-domain name too long: %s", addr);
138 dsb_simple(why, "4.3.5", "Server configuration error");
139 return (0);
143 * Initialize.
145 memset((char *) &sock_un, 0, sizeof(sock_un));
146 sock_un.sun_family = AF_UNIX;
147 #ifdef HAS_SUN_LEN
148 sock_un.sun_len = len + 1;
149 #endif
150 memcpy(sock_un.sun_path, addr, len + 1);
153 * Create a client socket.
155 if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
156 msg_fatal("%s: socket: %m", myname);
159 * Connect to the server.
161 if (msg_verbose)
162 msg_info("%s: trying: %s...", myname, addr);
164 return (smtp_connect_sock(sock, (struct sockaddr *) & sock_un,
165 sizeof(sock_un), var_myhostname, addr,
166 0, addr, why, sess_flags));
169 /* smtp_connect_addr - connect to explicit address */
171 static SMTP_SESSION *smtp_connect_addr(const char *destination, DNS_RR *addr,
172 unsigned port, DSN_BUF *why,
173 int sess_flags)
175 const char *myname = "smtp_connect_addr";
176 struct sockaddr_storage ss; /* remote */
177 struct sockaddr *sa = (struct sockaddr *) & ss;
178 SOCKADDR_SIZE salen = sizeof(ss);
179 MAI_HOSTADDR_STR hostaddr;
180 int sock;
181 char *bind_addr;
182 char *bind_var;
184 dsb_reset(why); /* Paranoia */
187 * Sanity checks.
189 if (dns_rr_to_sa(addr, port, sa, &salen) != 0) {
190 msg_warn("%s: skip address type %s: %m",
191 myname, dns_strtype(addr->type));
192 dsb_simple(why, "4.4.0", "network address conversion failed: %m");
193 return (0);
197 * Initialize.
199 if ((sock = socket(sa->sa_family, SOCK_STREAM, 0)) < 0)
200 msg_fatal("%s: socket: %m", myname);
202 if (inet_windowsize > 0)
203 set_inet_windowsize(sock, inet_windowsize);
206 * Allow the sysadmin to specify the source address, for example, as "-o
207 * smtp_bind_address=x.x.x.x" in the master.cf file.
209 #ifdef HAS_IPV6
210 if (sa->sa_family == AF_INET6) {
211 bind_addr = var_smtp_bind_addr6;
212 bind_var = VAR_SMTP_BIND_ADDR6;
213 } else
214 #endif
215 if (sa->sa_family == AF_INET) {
216 bind_addr = var_smtp_bind_addr;
217 bind_var = VAR_SMTP_BIND_ADDR;
218 } else
219 bind_var = bind_addr = "";
220 if (*bind_addr) {
221 int aierr;
222 struct addrinfo *res0;
224 if ((aierr = hostaddr_to_sockaddr(bind_addr, (char *) 0, 0, &res0)) != 0)
225 msg_fatal("%s: bad %s parameter: %s: %s",
226 myname, bind_var, bind_addr, MAI_STRERROR(aierr));
227 if (bind(sock, res0->ai_addr, res0->ai_addrlen) < 0)
228 msg_warn("%s: bind %s: %m", myname, bind_addr);
229 else if (msg_verbose)
230 msg_info("%s: bind %s", myname, bind_addr);
231 freeaddrinfo(res0);
235 * When running as a virtual host, bind to the virtual interface so that
236 * the mail appears to come from the "right" machine address.
238 * XXX The IPv6 patch expands the null host (as client endpoint) and uses
239 * the result as the loopback address list.
241 else {
242 int count = 0;
243 struct sockaddr *own_addr = 0;
244 INET_ADDR_LIST *addr_list = own_inet_addr_list();
245 struct sockaddr_storage *s;
247 for (s = addr_list->addrs; s < addr_list->addrs + addr_list->used; s++) {
248 if (SOCK_ADDR_FAMILY(s) == sa->sa_family) {
249 if (count++ > 0)
250 break;
251 own_addr = SOCK_ADDR_PTR(s);
254 if (count == 1 && !sock_addr_in_loopback(own_addr)) {
255 if (bind(sock, own_addr, SOCK_ADDR_LEN(own_addr)) < 0) {
256 SOCKADDR_TO_HOSTADDR(own_addr, SOCK_ADDR_LEN(own_addr),
257 &hostaddr, (MAI_SERVPORT_STR *) 0, 0);
258 msg_warn("%s: bind %s: %m", myname, hostaddr.buf);
259 } else if (msg_verbose) {
260 SOCKADDR_TO_HOSTADDR(own_addr, SOCK_ADDR_LEN(own_addr),
261 &hostaddr, (MAI_SERVPORT_STR *) 0, 0);
262 msg_info("%s: bind %s", myname, hostaddr.buf);
268 * Connect to the server.
270 SOCKADDR_TO_HOSTADDR(sa, salen, &hostaddr, (MAI_SERVPORT_STR *) 0, 0);
271 if (msg_verbose)
272 msg_info("%s: trying: %s[%s] port %d...",
273 myname, SMTP_HNAME(addr), hostaddr.buf, ntohs(port));
275 return (smtp_connect_sock(sock, sa, salen, SMTP_HNAME(addr), hostaddr.buf,
276 port, destination, why, sess_flags));
279 /* smtp_connect_sock - connect a socket over some transport */
281 static SMTP_SESSION *smtp_connect_sock(int sock, struct sockaddr * sa,
282 int salen, const char *name,
283 const char *addr,
284 unsigned port,
285 const char *destination,
286 DSN_BUF *why,
287 int sess_flags)
289 int conn_stat;
290 int saved_errno;
291 VSTREAM *stream;
292 time_t start_time;
294 start_time = time((time_t *) 0);
295 if (var_smtp_conn_tmout > 0) {
296 non_blocking(sock, NON_BLOCKING);
297 conn_stat = timed_connect(sock, sa, salen, var_smtp_conn_tmout);
298 saved_errno = errno;
299 non_blocking(sock, BLOCKING);
300 errno = saved_errno;
301 } else {
302 conn_stat = sane_connect(sock, sa, salen);
304 if (conn_stat < 0) {
305 if (port)
306 dsb_simple(why, "4.4.1", "connect to %s[%s]:%d: %m",
307 name, addr, ntohs(port));
308 else
309 dsb_simple(why, "4.4.1", "connect to %s[%s]: %m", name, addr);
310 close(sock);
311 return (0);
313 stream = vstream_fdopen(sock, O_RDWR);
316 * Avoid poor performance when TCP MSS > VSTREAM_BUFSIZE.
318 if (sa->sa_family == AF_INET
319 #ifdef AF_INET6
320 || sa->sa_family == AF_INET6
321 #endif
323 vstream_tweak_tcp(stream);
326 * Bundle up what we have into a nice SMTP_SESSION object.
328 return (smtp_session_alloc(stream, destination, name, addr,
329 port, start_time, sess_flags));
332 /* smtp_parse_destination - parse host/port destination */
334 static char *smtp_parse_destination(char *destination, char *def_service,
335 char **hostp, unsigned *portp)
337 char *buf = mystrdup(destination);
338 char *service;
339 struct servent *sp;
340 char *protocol = "tcp"; /* XXX configurable? */
341 unsigned port;
342 const char *err;
344 if (msg_verbose)
345 msg_info("smtp_parse_destination: %s %s", destination, def_service);
348 * Parse the host/port information. We're working with a copy of the
349 * destination argument so the parsing can be destructive.
351 if ((err = host_port(buf, hostp, (char *) 0, &service, def_service)) != 0)
352 msg_fatal("%s in server description: %s", err, destination);
355 * Convert service to port number, network byte order.
357 if (alldig(service)) {
358 if ((port = atoi(service)) >= 65536 || port == 0)
359 msg_fatal("bad network port in destination: %s", destination);
360 *portp = htons(port);
361 } else {
362 if ((sp = getservbyname(service, protocol)) == 0)
363 msg_fatal("unknown service: %s/%s", service, protocol);
364 *portp = sp->s_port;
366 return (buf);
369 /* smtp_cleanup_session - clean up after using a session */
371 static void smtp_cleanup_session(SMTP_STATE *state)
373 DELIVER_REQUEST *request = state->request;
374 SMTP_SESSION *session = state->session;
375 int bad_session;
378 * Inform the postmaster of trouble.
380 if (session->history != 0
381 && (session->error_mask & name_mask(VAR_NOTIFY_CLASSES,
382 mail_error_masks,
383 var_notify_classes)) != 0)
384 smtp_chat_notify(session);
387 * When session caching is enabled, cache the first good session for this
388 * delivery request under the next-hop destination, and cache all good
389 * sessions under their server network address (destroying the session in
390 * the process).
392 * Caching under the next-hop destination name (rather than the fall-back
393 * destination) allows us to skip over non-responding primary or backup
394 * hosts. In fact, this is the only benefit of caching logical to
395 * physical bindings; caching a session under its own hostname provides
396 * no performance benefit, given the way smtp_connect() works.
398 bad_session = THIS_SESSION_IS_BAD; /* smtp_quit() may fail */
399 if (THIS_SESSION_IS_EXPIRED)
400 smtp_quit(state); /* also disables caching */
401 if (THIS_SESSION_IS_CACHED
402 /* Redundant tests for safety... */
403 && vstream_ferror(session->stream) == 0
404 && vstream_feof(session->stream) == 0) {
405 smtp_save_session(state);
406 } else {
407 smtp_session_free(session);
409 state->session = 0;
412 * If this session was good, reset the logical next-hop state, so that we
413 * won't cache connections to alternate servers under the logical
414 * next-hop destination. Otherwise we could end up skipping over the
415 * available and more preferred servers.
417 if (HAVE_NEXTHOP_STATE(state) && !bad_session)
418 FREE_NEXTHOP_STATE(state);
421 * Clean up the lists with todo and dropped recipients.
423 smtp_rcpt_cleanup(state);
426 * Reset profiling info.
428 * XXX When one delivery request results in multiple sessions, the set-up
429 * and transmission latencies of the earlier sessions will count as
430 * connection set-up time for the later sessions.
432 * XXX On the other hand, when we first try to connect to one or more dead
433 * hosts before we reach a good host, then all that time must be counted
434 * as connection set-up time for the session with the good host.
436 * XXX So this set-up attribution problem exists only when we actually
437 * engage in a session, spend a lot of time delivering a message, find
438 * that it fails, and then connect to an alternate host.
440 memset((char *) &request->msg_stats.conn_setup_done, 0,
441 sizeof(request->msg_stats.conn_setup_done));
442 memset((char *) &request->msg_stats.deliver_done, 0,
443 sizeof(request->msg_stats.deliver_done));
444 request->msg_stats.reuse_count = 0;
447 static void smtp_cache_policy(SMTP_STATE *state, const char *dest)
449 DELIVER_REQUEST *request = state->request;
451 state->misc_flags &= ~SMTP_MISC_FLAG_CONN_CACHE_MASK;
454 * XXX Disable connection caching when sender-dependent authentication is
455 * enabled. We must not send someone elses mail over an authenticated
456 * connection, and we must not send mail that requires authentication
457 * over a connection that wasn't authenticated.
459 if (var_smtp_sender_auth)
460 return;
462 if (smtp_cache_dest && string_list_match(smtp_cache_dest, dest)) {
463 state->misc_flags |= SMTP_MISC_FLAG_CONN_CACHE_MASK;
464 } else if (var_smtp_cache_demand) {
465 if (request->flags & DEL_REQ_FLAG_CONN_LOAD)
466 state->misc_flags |= SMTP_MISC_FLAG_CONN_LOAD;
467 if (request->flags & DEL_REQ_FLAG_CONN_STORE)
468 state->misc_flags |= SMTP_MISC_FLAG_CONN_STORE;
472 /* smtp_connect_local - connect to local server */
474 static void smtp_connect_local(SMTP_STATE *state, const char *path)
476 const char *myname = "smtp_connect_local";
477 SMTP_SESSION *session;
478 DSN_BUF *why = state->why;
481 * It's too painful to weave this code into the SMTP connection
482 * management routine.
484 * Connection cache management is based on the UNIX-domain pathname, without
485 * the "unix:" prefix.
487 smtp_cache_policy(state, path);
490 * XXX We assume that the session->addr member refers to a copy of the
491 * UNIX-domain pathname, so that smtp_save_session() will cache the
492 * connection using the pathname as the physical endpoint name.
494 #define NO_PORT 0
497 * Opportunistic TLS for unix domain sockets does not make much sense,
498 * since the channel is private, mere encryption without authentication
499 * is just wasted cycles and opportunity for breakage. Since we are not
500 * willing to retry after TLS handshake failures here, we downgrade "may"
501 * no "none". Nothing is lost, and much waste is avoided.
503 * We don't know who is authenticating whom, so if a client cert is
504 * available, "encrypt" may be a sensible policy. Otherwise, we also
505 * downgrade "encrypt" to "none", this time just to avoid waste.
507 if ((state->misc_flags & SMTP_MISC_FLAG_CONN_LOAD) == 0
508 || (session = smtp_reuse_addr(state, path, NO_PORT)) == 0)
509 session = smtp_connect_unix(path, why, state->misc_flags);
510 if ((state->session = session) != 0) {
511 session->state = state;
512 #ifdef USE_TLS
513 session->tls_nexthop = var_myhostname; /* for TLS_LEV_SECURE */
514 if (session->tls_level == TLS_LEV_MAY) {
515 msg_warn("%s: opportunistic TLS encryption is not appropriate "
516 "for unix-domain destinations.", myname);
517 session->tls_level = TLS_LEV_NONE;
519 #endif
520 /* All delivery errors bounce or defer. */
521 state->misc_flags |= SMTP_MISC_FLAG_FINAL_SERVER;
524 * When a TLS handshake fails, the stream is marked "dead" to avoid
525 * further I/O over a broken channel.
527 if ((session->features & SMTP_FEATURE_FROM_CACHE) == 0
528 && smtp_helo(state) != 0) {
529 if (!THIS_SESSION_IS_DEAD
530 && vstream_ferror(session->stream) == 0
531 && vstream_feof(session->stream) == 0)
532 smtp_quit(state);
533 } else {
534 smtp_xfer(state);
538 * With opportunistic TLS disabled we don't expect to be asked to
539 * retry connections without TLS, and so we expect the final server
540 * flag to stay on.
542 if ((state->misc_flags & SMTP_MISC_FLAG_FINAL_SERVER) == 0)
543 msg_panic("%s: unix-domain destination not final!", myname);
544 smtp_cleanup_session(state);
548 /* smtp_scrub_address_list - delete all cached addresses from list */
550 static void smtp_scrub_addr_list(HTABLE *cached_addr, DNS_RR **addr_list)
552 MAI_HOSTADDR_STR hostaddr;
553 DNS_RR *addr;
554 DNS_RR *next;
557 * XXX Extend the DNS_RR structure with fields for the printable address
558 * and/or binary sockaddr representations, so that we can avoid repeated
559 * binary->string transformations for the same address.
561 for (addr = *addr_list; addr; addr = next) {
562 next = addr->next;
563 if (dns_rr_to_pa(addr, &hostaddr) == 0) {
564 msg_warn("cannot convert type %s resource record to socket address",
565 dns_strtype(addr->type));
566 continue;
568 if (htable_locate(cached_addr, hostaddr.buf))
569 *addr_list = dns_rr_remove(*addr_list, addr);
573 /* smtp_update_addr_list - common address list update */
575 static void smtp_update_addr_list(DNS_RR **addr_list, const char *server_addr,
576 int session_count)
578 DNS_RR *addr;
579 DNS_RR *next;
580 int aierr;
581 struct addrinfo *res0;
583 if (*addr_list == 0)
584 return;
587 * Truncate the address list if we are not going to use it anyway.
589 if (session_count == var_smtp_mxsess_limit
590 || session_count == var_smtp_mxaddr_limit) {
591 dns_rr_free(*addr_list);
592 *addr_list = 0;
593 return;
597 * Convert server address to internal form, and look it up in the address
598 * list.
600 * XXX smtp_reuse_session() breaks if we remove two or more adjacent list
601 * elements but do not truncate the list to zero length.
603 * XXX Extend the SMTP_SESSION structure with sockaddr information so that
604 * we can avoid repeated string->binary transformations for the same
605 * address.
607 if ((aierr = hostaddr_to_sockaddr(server_addr, (char *) 0, 0, &res0)) != 0) {
608 msg_warn("hostaddr_to_sockaddr %s: %s",
609 server_addr, MAI_STRERROR(aierr));
610 } else {
611 for (addr = *addr_list; addr; addr = next) {
612 next = addr->next;
613 if (DNS_RR_EQ_SA(addr, (struct sockaddr *) res0->ai_addr)) {
614 *addr_list = dns_rr_remove(*addr_list, addr);
615 break;
618 freeaddrinfo(res0);
622 /* smtp_reuse_session - try to use existing connection, return session count */
624 static int smtp_reuse_session(SMTP_STATE *state, int lookup_mx,
625 const char *domain, unsigned port,
626 DNS_RR **addr_list, int domain_best_pref)
628 int session_count = 0;
629 DNS_RR *addr;
630 DNS_RR *next;
631 MAI_HOSTADDR_STR hostaddr;
632 SMTP_SESSION *session;
635 * First, search the cache by logical destination. We truncate the server
636 * address list when all the sessions for this destination are used up,
637 * to reduce the number of variables that need to be checked later.
639 * Note: lookup by logical destination restores the "best MX" bit.
641 if (*addr_list && SMTP_RCPT_LEFT(state) > 0
642 && (session = smtp_reuse_domain(state, lookup_mx, domain, port)) != 0) {
643 session_count = 1;
644 smtp_update_addr_list(addr_list, session->addr, session_count);
645 if ((state->misc_flags & SMTP_MISC_FLAG_FINAL_NEXTHOP)
646 && *addr_list == 0)
647 state->misc_flags |= SMTP_MISC_FLAG_FINAL_SERVER;
648 smtp_xfer(state);
649 smtp_cleanup_session(state);
653 * Second, search the cache by primary MX address. Again, we use address
654 * list truncation so that we have to check fewer variables later.
656 * XXX This loop is safe because smtp_update_addr_list() either truncates
657 * the list to zero length, or removes at most one list element.
659 for (addr = *addr_list; SMTP_RCPT_LEFT(state) > 0 && addr; addr = next) {
660 if (addr->pref != domain_best_pref)
661 break;
662 next = addr->next;
663 if (dns_rr_to_pa(addr, &hostaddr) != 0
664 && (session = smtp_reuse_addr(state, hostaddr.buf, port)) != 0) {
665 session->features |= SMTP_FEATURE_BEST_MX;
666 session_count += 1;
667 smtp_update_addr_list(addr_list, session->addr, session_count);
668 if (*addr_list == 0)
669 next = 0;
670 if ((state->misc_flags & SMTP_MISC_FLAG_FINAL_NEXTHOP)
671 && next == 0)
672 state->misc_flags |= SMTP_MISC_FLAG_FINAL_SERVER;
673 smtp_xfer(state);
674 smtp_cleanup_session(state);
677 return (session_count);
680 /* smtp_connect_remote - establish remote connection */
682 static void smtp_connect_remote(SMTP_STATE *state, const char *nexthop,
683 char *def_service)
685 DELIVER_REQUEST *request = state->request;
686 ARGV *sites;
687 char *dest;
688 char **cpp;
689 int non_fallback_sites;
690 int retry_plain = 0;
691 DSN_BUF *why = state->why;
694 * First try to deliver to the indicated destination, then try to deliver
695 * to the optional fall-back relays.
697 * Future proofing: do a null destination sanity check in case we allow the
698 * primary destination to be a list (it could be just separators).
700 sites = argv_alloc(1);
701 argv_add(sites, nexthop, (char *) 0);
702 if (sites->argc == 0)
703 msg_panic("null destination: \"%s\"", nexthop);
704 non_fallback_sites = sites->argc;
705 if ((state->misc_flags & SMTP_MISC_FLAG_USE_LMTP) == 0)
706 argv_split_append(sites, var_fallback_relay, ", \t\r\n");
709 * Don't give up after a hard host lookup error until we have tried the
710 * fallback relay servers.
712 * Don't bounce mail after a host lookup problem with a relayhost or with a
713 * fallback relay.
715 * Don't give up after a qualifying soft error until we have tried all
716 * qualifying backup mail servers.
718 * All this means that error handling and error reporting depends on whether
719 * the error qualifies for trying to deliver to a backup mail server, or
720 * whether we're looking up a relayhost or fallback relay. The challenge
721 * then is to build this into the pre-existing SMTP client without
722 * getting lost in the complexity.
724 #define IS_FALLBACK_RELAY(cpp, sites, non_fallback_sites) \
725 (*(cpp) && (cpp) >= (sites)->argv + (non_fallback_sites))
727 for (cpp = sites->argv, (state->misc_flags |= SMTP_MISC_FLAG_FIRST_NEXTHOP);
728 SMTP_RCPT_LEFT(state) > 0 && (dest = *cpp) != 0;
729 cpp++, (state->misc_flags &= ~SMTP_MISC_FLAG_FIRST_NEXTHOP)) {
730 char *dest_buf;
731 char *domain;
732 unsigned port;
733 DNS_RR *addr_list;
734 DNS_RR *addr;
735 DNS_RR *next;
736 int addr_count;
737 int sess_count;
738 SMTP_SESSION *session;
739 int lookup_mx;
740 unsigned domain_best_pref;
741 MAI_HOSTADDR_STR hostaddr;
743 if (cpp[1] == 0)
744 state->misc_flags |= SMTP_MISC_FLAG_FINAL_NEXTHOP;
747 * Parse the destination. Default is to use the SMTP port. Look up
748 * the address instead of the mail exchanger when a quoted host is
749 * specified, or when DNS lookups are disabled.
751 dest_buf = smtp_parse_destination(dest, def_service, &domain, &port);
754 * Resolve an SMTP server. Skip mail exchanger lookups when a quoted
755 * host is specified, or when DNS lookups are disabled.
757 if (msg_verbose)
758 msg_info("connecting to %s port %d", domain, ntohs(port));
759 if ((state->misc_flags & SMTP_MISC_FLAG_USE_LMTP) == 0) {
760 if (ntohs(port) == IPPORT_SMTP)
761 state->misc_flags |= SMTP_MISC_FLAG_LOOP_DETECT;
762 else
763 state->misc_flags &= ~SMTP_MISC_FLAG_LOOP_DETECT;
764 lookup_mx = (var_disable_dns == 0 && *dest != '[');
765 } else
766 lookup_mx = 0;
767 if (!lookup_mx) {
768 addr_list = smtp_host_addr(domain, state->misc_flags, why);
769 /* XXX We could be an MX host for this destination... */
770 } else {
771 int i_am_mx = 0;
773 addr_list = smtp_domain_addr(domain, state->misc_flags,
774 why, &i_am_mx);
775 /* If we're MX host, don't connect to non-MX backups. */
776 if (i_am_mx)
777 state->misc_flags |= SMTP_MISC_FLAG_FINAL_NEXTHOP;
781 * Don't try fall-back hosts if mail loops to myself. That would just
782 * make the problem worse.
784 if (addr_list == 0 && SMTP_HAS_LOOP_DSN(why))
785 state->misc_flags |= SMTP_MISC_FLAG_FINAL_NEXTHOP;
788 * No early loop exit or we have a memory leak with dest_buf.
790 if (addr_list)
791 domain_best_pref = addr_list->pref;
794 * When session caching is enabled, store the first good session for
795 * this delivery request under the next-hop destination name. All
796 * good sessions will be stored under their specific server IP
797 * address.
799 * XXX Replace sites->argv by (lookup_mx, domain, port) triples so we
800 * don't have to make clumsy ad-hoc copies and keep track of who
801 * free()s the memory.
803 * XXX smtp_session_cache_destinations specifies domain names without
804 * :port, because : is already used for maptype:mapname. Because of
805 * this limitation we use the bare domain without the optional [] or
806 * non-default TCP port.
808 * Opportunistic (a.k.a. on-demand) session caching on request by the
809 * queue manager. This is turned temporarily when a destination has a
810 * high volume of mail in the active queue.
812 * XXX Disable connection caching when sender-dependent authentication
813 * is enabled. We must not send someone elses mail over an
814 * authenticated connection, and we must not send mail that requires
815 * authentication over a connection that wasn't authenticated.
817 if (addr_list && (state->misc_flags & SMTP_MISC_FLAG_FIRST_NEXTHOP)) {
818 smtp_cache_policy(state, domain);
819 if (state->misc_flags & SMTP_MISC_FLAG_CONN_STORE)
820 SET_NEXTHOP_STATE(state, lookup_mx, domain, port);
824 * Delete visited cached hosts from the address list.
826 * Optionally search the connection cache by domain name or by primary
827 * MX address before we try to create new connections.
829 * Enforce the MX session and MX address counts per next-hop or
830 * fall-back destination. smtp_reuse_session() will truncate the
831 * address list when either limit is reached.
833 if (addr_list && (state->misc_flags & SMTP_MISC_FLAG_CONN_LOAD)) {
834 if (state->cache_used->used > 0)
835 smtp_scrub_addr_list(state->cache_used, &addr_list);
836 sess_count = addr_count =
837 smtp_reuse_session(state, lookup_mx, domain, port,
838 &addr_list, domain_best_pref);
839 } else
840 sess_count = addr_count = 0;
843 * Connect to an SMTP server: create primary MX connections, and
844 * reuse or create backup MX connections.
846 * At the start of an SMTP session, all recipients are unmarked. In the
847 * course of an SMTP session, recipients are marked as KEEP (deliver
848 * to alternate mail server) or DROP (remove from recipient list). At
849 * the end of an SMTP session, weed out the recipient list. Unmark
850 * any left-over recipients and try to deliver them to a backup mail
851 * server.
853 * Cache the first good session under the next-hop destination name.
854 * Cache all good sessions under their physical endpoint.
856 * Don't query the session cache for primary MX hosts. We already did
857 * that in smtp_reuse_session(), and if any were found in the cache,
858 * they were already deleted from the address list.
860 for (addr = addr_list; SMTP_RCPT_LEFT(state) > 0 && addr; addr = next) {
861 next = addr->next;
862 if (++addr_count == var_smtp_mxaddr_limit)
863 next = 0;
864 if ((state->misc_flags & SMTP_MISC_FLAG_CONN_LOAD) == 0
865 || addr->pref == domain_best_pref
866 || dns_rr_to_pa(addr, &hostaddr) == 0
867 || !(session = smtp_reuse_addr(state, hostaddr.buf, port)))
868 session = smtp_connect_addr(dest, addr, port, why,
869 state->misc_flags);
870 if ((state->session = session) != 0) {
871 session->state = state;
872 if (addr->pref == domain_best_pref)
873 session->features |= SMTP_FEATURE_BEST_MX;
874 /* Don't count handshake errors towards the session limit. */
875 if ((state->misc_flags & SMTP_MISC_FLAG_FINAL_NEXTHOP)
876 && next == 0)
877 state->misc_flags |= SMTP_MISC_FLAG_FINAL_SERVER;
878 #ifdef USE_TLS
879 /* Disable TLS when retrying after a handshake failure */
880 if (retry_plain) {
881 if (session->tls_level >= TLS_LEV_ENCRYPT)
882 msg_panic("Plain-text retry wrong for mandatory TLS");
883 session->tls_level = TLS_LEV_NONE;
884 retry_plain = 0;
886 session->tls_nexthop = domain; /* for TLS_LEV_SECURE */
887 #endif
888 if ((session->features & SMTP_FEATURE_FROM_CACHE) == 0
889 && smtp_helo(state) != 0) {
890 #ifdef USE_TLS
893 * When an opportunistic TLS handshake fails, try the
894 * same address again, with TLS disabled. See also the
895 * RETRY_AS_PLAINTEXT macro.
897 if ((retry_plain = session->tls_retry_plain) != 0) {
898 --addr_count;
899 next = addr;
901 #endif
904 * When a TLS handshake fails, the stream is marked
905 * "dead" to avoid further I/O over a broken channel.
907 if (!THIS_SESSION_IS_DEAD
908 && vstream_ferror(session->stream) == 0
909 && vstream_feof(session->stream) == 0)
910 smtp_quit(state);
911 } else {
912 /* Do count delivery errors towards the session limit. */
913 if (++sess_count == var_smtp_mxsess_limit)
914 next = 0;
915 if ((state->misc_flags & SMTP_MISC_FLAG_FINAL_NEXTHOP)
916 && next == 0)
917 state->misc_flags |= SMTP_MISC_FLAG_FINAL_SERVER;
918 smtp_xfer(state);
920 smtp_cleanup_session(state);
921 } else {
922 /* The reason already includes the IP address and TCP port. */
923 msg_info("%s", STR(why->reason));
925 /* Insert: test if we must skip the remaining MX hosts. */
927 dns_rr_free(addr_list);
928 myfree(dest_buf);
929 if (state->misc_flags & SMTP_MISC_FLAG_FINAL_NEXTHOP)
930 break;
934 * We still need to deliver, bounce or defer some left-over recipients:
935 * either mail loops or some backup mail server was unavailable.
937 if (SMTP_RCPT_LEFT(state) > 0) {
940 * In case of a "no error" indication we make up an excuse: we did
941 * find the host address, but we did not attempt to connect to it.
942 * This can happen when the fall-back relay was already tried via a
943 * cached connection, so that the address list scrubber left behind
944 * an empty list.
946 if (!SMTP_HAS_DSN(why)) {
947 dsb_simple(why, "4.3.0",
948 "server unavailable or unable to receive mail");
952 * Pay attention to what could be configuration problems, and pretend
953 * that these are recoverable rather than bouncing the mail.
955 else if (!SMTP_HAS_SOFT_DSN(why)
956 && (state->misc_flags & SMTP_MISC_FLAG_USE_LMTP) == 0) {
959 * The fall-back destination did not resolve as expected, or it
960 * is refusing to talk to us, or mail for it loops back to us.
962 if (IS_FALLBACK_RELAY(cpp, sites, non_fallback_sites)) {
963 msg_warn("%s configuration problem", VAR_SMTP_FALLBACK);
964 vstring_strcpy(why->status, "4.3.5");
965 /* XXX Keep the diagnostic code and MTA. */
969 * The next-hop relayhost did not resolve as expected, or it is
970 * refusing to talk to us, or mail for it loops back to us.
972 else if (strcmp(sites->argv[0], var_relayhost) == 0) {
973 msg_warn("%s configuration problem", VAR_RELAYHOST);
974 vstring_strcpy(why->status, "4.3.5");
975 /* XXX Keep the diagnostic code and MTA. */
979 * Mail for the next-hop destination loops back to myself. Pass
980 * the mail to the best_mx_transport or bounce it.
982 else if (SMTP_HAS_LOOP_DSN(why) && *var_bestmx_transp) {
983 dsb_reset(why); /* XXX */
984 state->status = deliver_pass_all(MAIL_CLASS_PRIVATE,
985 var_bestmx_transp,
986 request);
987 SMTP_RCPT_LEFT(state) = 0; /* XXX */
993 * Cleanup.
995 if (HAVE_NEXTHOP_STATE(state))
996 FREE_NEXTHOP_STATE(state);
997 argv_free(sites);
1000 /* smtp_connect - establish SMTP connection */
1002 int smtp_connect(SMTP_STATE *state)
1004 DELIVER_REQUEST *request = state->request;
1005 char *destination = request->nexthop;
1008 * All deliveries proceed along the same lines, whether they are over TCP
1009 * or UNIX-domain sockets, and whether they use SMTP or LMTP: get a
1010 * connection from the cache or create a new connection; deliver mail;
1011 * update the connection cache or disconnect.
1013 * The major differences appear at a higher level: the expansion from
1014 * destination to address list, and whether to stop before we reach the
1015 * end of that list.
1017 #define DEF_LMTP_SERVICE var_lmtp_tcp_port
1018 #define DEF_SMTP_SERVICE "smtp"
1021 * With LMTP we have direct-to-host delivery only. The destination may
1022 * have multiple IP addresses.
1024 if (state->misc_flags & SMTP_MISC_FLAG_USE_LMTP) {
1025 if (strncmp(destination, "unix:", 5) == 0) {
1026 smtp_connect_local(state, destination + 5);
1027 } else {
1028 if (strncmp(destination, "inet:", 5) == 0)
1029 destination += 5;
1030 smtp_connect_remote(state, destination, DEF_LMTP_SERVICE);
1035 * With SMTP we can have indirection via MX host lookup, as well as an
1036 * optional fall-back relayhost that we must avoid when we are MX host.
1038 * XXX We don't add support for "unix:" or "inet:" prefixes in SMTP
1039 * destinations, because that would break compatibility with existing
1040 * Postfix configurations that have a host with such a name.
1042 else {
1043 smtp_connect_remote(state, destination, DEF_SMTP_SERVICE);
1047 * We still need to bounce or defer some left-over recipients: either
1048 * (SMTP) mail loops or some server was unavailable.
1050 * We could avoid this (and the "final server" complexity) by keeping one
1051 * DSN structure per recipient in memory, by updating those in-memory
1052 * structures with each delivery attempt, and by always flushing all
1053 * deferred recipients at the end. We'd probably still want to bounce
1054 * recipients immediately, so we'd end up with another chunk of code for
1055 * defer logging only.
1057 if (SMTP_RCPT_LEFT(state) > 0) {
1058 state->misc_flags |= SMTP_MISC_FLAG_FINAL_SERVER; /* XXX */
1059 smtp_sess_fail(state);
1062 * Sanity check. Don't silently lose recipients.
1064 smtp_rcpt_cleanup(state);
1065 if (SMTP_RCPT_LEFT(state) > 0)
1066 msg_panic("smtp_connect: left-over recipients");
1068 return (state->status);