xref: /netbsd-src/external/ibm-public/postfix/dist/src/smtp/smtp_connect.c (revision c48c605c14fd8622b523d1d6a3f0c0bad133ea89)
1 /*	$NetBSD: smtp_connect.c,v 1.5 2023/12/23 20:30:45 christos Exp $	*/
2 
3 /*++
4 /* NAME
5 /*	smtp_connect 3
6 /* SUMMARY
7 /*	connect to SMTP/LMTP server and deliver
8 /* SYNOPSIS
9 /*	#include "smtp.h"
10 /*
11 /*	int	smtp_connect(state)
12 /*	SMTP_STATE *state;
13 /* DESCRIPTION
14 /*	This module implements SMTP/LMTP connection management and controls
15 /*	mail delivery.
16 /*
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.
23 /*
24 /*	This layer also controls what connections are retrieved from
25 /*	the connection cache, and what connections are saved to the cache.
26 /*
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".
32 /*
33 /*	With SMTP, or with SRV record lookup enabled, the Internet
34 /*	domain name service is queried for mail
35 /*	exchanger hosts. Quote the domain name with `[' and `]' to
36 /*	suppress mail exchanger lookups.
37 /*
38 /*	Numerical address information should always be quoted with `[]'.
39 /* DIAGNOSTICS
40 /*	The delivery status is the result value.
41 /* SEE ALSO
42 /*	smtp_proto(3) SMTP client protocol
43 /* LICENSE
44 /* .ad
45 /* .fi
46 /*	The Secure Mailer license must be distributed with this software.
47 /* AUTHOR(S)
48 /*	Wietse Venema
49 /*	IBM T.J. Watson Research
50 /*	P.O. Box 704
51 /*	Yorktown Heights, NY 10598, USA
52 /*
53 /*	Wietse Venema
54 /*	Google, Inc.
55 /*	111 8th Avenue
56 /*	New York, NY 10011, USA
57 /*
58 /*	Connection caching in cooperation with:
59 /*	Victor Duchovni
60 /*	Morgan Stanley
61 /*--*/
62 
63 /* System library. */
64 
65 #include <sys_defs.h>
66 #include <stdlib.h>
67 #include <sys/socket.h>
68 #include <sys/un.h>
69 #include <netinet/in.h>
70 #include <arpa/inet.h>
71 #include <errno.h>
72 #include <netdb.h>
73 #include <stdlib.h>
74 #include <string.h>
75 #include <unistd.h>
76 #include <fcntl.h>
77 #include <ctype.h>
78 
79 #ifndef IPPORT_SMTP
80 #define IPPORT_SMTP 25
81 #endif
82 
83 /* Utility library. */
84 
85 #include <msg.h>
86 #include <vstream.h>
87 #include <vstring.h>
88 #include <split_at.h>
89 #include <mymalloc.h>
90 #include <inet_addr_list.h>
91 #include <iostuff.h>
92 #include <timed_connect.h>
93 #include <stringops.h>
94 #include <host_port.h>
95 #include <sane_connect.h>
96 #include <myaddrinfo.h>
97 #include <sock_addr.h>
98 #include <inet_proto.h>
99 #include <known_tcp_ports.h>
100 
101 /* Global library. */
102 
103 #include <mail_params.h>
104 #include <own_inet_addr.h>
105 #include <deliver_pass.h>
106 #include <mail_error.h>
107 #include <dsn_buf.h>
108 #include <mail_addr.h>
109 
110 /* DNS library. */
111 
112 #include <dns.h>
113 
114 /* Application-specific. */
115 
116 #include <smtp.h>
117 #include <smtp_addr.h>
118 #include <smtp_reuse.h>
119 
120  /*
121   * Forward declaration.
122   */
123 static SMTP_SESSION *smtp_connect_sock(int, struct sockaddr *, int,
124 				               SMTP_ITERATOR *, DSN_BUF *,
125 				               int);
126 
127 /* smtp_connect_unix - connect to UNIX-domain address */
128 
smtp_connect_unix(SMTP_ITERATOR * iter,DSN_BUF * why,int sess_flags)129 static SMTP_SESSION *smtp_connect_unix(SMTP_ITERATOR *iter, DSN_BUF *why,
130 				               int sess_flags)
131 {
132     const char *myname = "smtp_connect_unix";
133     struct sockaddr_un sock_un;
134     const char *addr = STR(iter->addr);
135     int     len = strlen(addr);
136     int     sock;
137 
138     dsb_reset(why);				/* Paranoia */
139 
140     /*
141      * Sanity checks.
142      */
143     if (len >= (int) sizeof(sock_un.sun_path)) {
144 	msg_warn("unix-domain name too long: %s", addr);
145 	dsb_simple(why, "4.3.5", "Server configuration error");
146 	return (0);
147     }
148 
149     /*
150      * Initialize.
151      */
152     memset((void *) &sock_un, 0, sizeof(sock_un));
153     sock_un.sun_family = AF_UNIX;
154 #ifdef HAS_SUN_LEN
155     sock_un.sun_len = len + 1;
156 #endif
157     memcpy(sock_un.sun_path, addr, len + 1);
158 
159     /*
160      * Create a client socket.
161      */
162     if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
163 	msg_fatal("%s: socket: %m", myname);
164 
165     /*
166      * Connect to the server.
167      */
168     if (msg_verbose)
169 	msg_info("%s: trying: %s...", myname, addr);
170 
171     return (smtp_connect_sock(sock, (struct sockaddr *) &sock_un,
172 			      sizeof(sock_un), iter, why, sess_flags));
173 }
174 
175 /* smtp_connect_addr - connect to explicit address */
176 
smtp_connect_addr(SMTP_ITERATOR * iter,DSN_BUF * why,int sess_flags)177 static SMTP_SESSION *smtp_connect_addr(SMTP_ITERATOR *iter, DSN_BUF *why,
178 				               int sess_flags)
179 {
180     const char *myname = "smtp_connect_addr";
181     struct sockaddr_storage ss;		/* remote */
182     struct sockaddr *sa = (struct sockaddr *) &ss;
183     SOCKADDR_SIZE salen = sizeof(ss);
184     MAI_HOSTADDR_STR hostaddr;
185     DNS_RR *addr = iter->rr;
186     unsigned port = iter->port;
187     int     sock;
188     char   *bind_addr;
189     char   *bind_var;
190     char   *saved_bind_addr = 0;
191     char   *tail;
192 
193     dsb_reset(why);				/* Paranoia */
194 
195     /*
196      * Sanity checks.
197      */
198     if (dns_rr_to_sa(addr, port, sa, &salen) != 0) {
199 	msg_warn("%s: skip address type %s: %m",
200 		 myname, dns_strtype(addr->type));
201 	dsb_simple(why, "4.4.0", "network address conversion failed: %m");
202 	return (0);
203     }
204 
205     /*
206      * Initialize.
207      */
208     if ((sock = socket(sa->sa_family, SOCK_STREAM, 0)) < 0)
209 	msg_fatal("%s: socket: %m", myname);
210 
211 #define RETURN_EARLY() do { \
212 	if (saved_bind_addr) \
213 	    myfree(saved_bind_addr); \
214 	(void) close(sock); \
215 	return (0); \
216     } while (0)
217 
218     if (inet_windowsize > 0)
219 	set_inet_windowsize(sock, inet_windowsize);
220 
221     /*
222      * Allow the sysadmin to specify the source address, for example, as "-o
223      * smtp_bind_address=x.x.x.x" in the master.cf file.
224      */
225 #ifdef HAS_IPV6
226     if (sa->sa_family == AF_INET6) {
227 	bind_addr = var_smtp_bind_addr6;
228 	bind_var = VAR_LMTP_SMTP(BIND_ADDR6);
229     } else
230 #endif
231     if (sa->sa_family == AF_INET) {
232 	bind_addr = var_smtp_bind_addr;
233 	bind_var = VAR_LMTP_SMTP(BIND_ADDR);
234     } else
235 	bind_var = bind_addr = "";
236     if (*bind_addr) {
237 	int     aierr;
238 	struct addrinfo *res0;
239 
240 	if (*bind_addr == '[') {
241 	    saved_bind_addr = mystrdup(bind_addr + 1);
242 	    if ((tail = split_at(saved_bind_addr, ']')) == 0 || *tail)
243 		msg_fatal("%s: malformed %s parameter: %s",
244 			  myname, bind_var, bind_addr);
245 	    bind_addr = saved_bind_addr;
246 	}
247 	if ((aierr = hostaddr_to_sockaddr(bind_addr, (char *) 0, 0, &res0)) != 0)
248 	    msg_fatal("%s: bad %s parameter: %s: %s",
249 		      myname, bind_var, bind_addr, MAI_STRERROR(aierr));
250 	if (bind(sock, res0->ai_addr, res0->ai_addrlen) < 0) {
251 	    msg_warn("%s: bind %s: %m", myname, bind_addr);
252 	    if (var_smtp_bind_addr_enforce) {
253 		freeaddrinfo(res0);
254 		dsb_simple(why, "4.4.0", "server configuration error");
255 		RETURN_EARLY();
256 	    }
257 	} else if (msg_verbose)
258 	    msg_info("%s: bind %s", myname, bind_addr);
259 	if (saved_bind_addr)
260 	    myfree(saved_bind_addr);
261 	freeaddrinfo(res0);
262     }
263 
264     /*
265      * When running as a virtual host, bind to the virtual interface so that
266      * the mail appears to come from the "right" machine address.
267      *
268      * XXX The IPv6 patch expands the null host (as client endpoint) and uses
269      * the result as the loopback address list.
270      */
271     else {
272 	int     count = 0;
273 	struct sockaddr *own_addr = 0;
274 	INET_ADDR_LIST *addr_list = own_inet_addr_list();
275 	struct sockaddr_storage *s;
276 
277 	for (s = addr_list->addrs; s < addr_list->addrs + addr_list->used; s++) {
278 	    if (SOCK_ADDR_FAMILY(s) == sa->sa_family) {
279 		if (count++ > 0)
280 		    break;
281 		own_addr = SOCK_ADDR_PTR(s);
282 	    }
283 	}
284 	if (count == 1 && !sock_addr_in_loopback(own_addr)) {
285 	    if (bind(sock, own_addr, SOCK_ADDR_LEN(own_addr)) < 0) {
286 		SOCKADDR_TO_HOSTADDR(own_addr, SOCK_ADDR_LEN(own_addr),
287 				     &hostaddr, (MAI_SERVPORT_STR *) 0, 0);
288 		msg_warn("%s: bind %s: %m", myname, hostaddr.buf);
289 	    } else if (msg_verbose) {
290 		SOCKADDR_TO_HOSTADDR(own_addr, SOCK_ADDR_LEN(own_addr),
291 				     &hostaddr, (MAI_SERVPORT_STR *) 0, 0);
292 		msg_info("%s: bind %s", myname, hostaddr.buf);
293 	    }
294 	}
295     }
296 
297     /*
298      * Connect to the server.
299      */
300     if (msg_verbose)
301 	msg_info("%s: trying: %s[%s] port %d...",
302 		 myname, STR(iter->host), STR(iter->addr), ntohs(port));
303 
304     return (smtp_connect_sock(sock, sa, salen, iter, why, sess_flags));
305 }
306 
307 /* smtp_connect_sock - connect a socket over some transport */
308 
smtp_connect_sock(int sock,struct sockaddr * sa,int salen,SMTP_ITERATOR * iter,DSN_BUF * why,int sess_flags)309 static SMTP_SESSION *smtp_connect_sock(int sock, struct sockaddr *sa,
310 				               int salen,
311 				               SMTP_ITERATOR *iter,
312 				               DSN_BUF *why,
313 				               int sess_flags)
314 {
315     int     conn_stat;
316     int     saved_errno;
317     VSTREAM *stream;
318     time_t  start_time;
319     const char *name = STR(iter->host);
320     const char *addr = STR(iter->addr);
321     unsigned port = iter->port;
322 
323     start_time = time((time_t *) 0);
324     if (var_smtp_conn_tmout > 0) {
325 	non_blocking(sock, NON_BLOCKING);
326 	conn_stat = timed_connect(sock, sa, salen, var_smtp_conn_tmout);
327 	saved_errno = errno;
328 	non_blocking(sock, BLOCKING);
329 	errno = saved_errno;
330     } else {
331 	conn_stat = sane_connect(sock, sa, salen);
332     }
333     if (conn_stat < 0) {
334 	if (port)
335 	    dsb_simple(why, "4.4.1", "connect to %s[%s]:%d: %m",
336 		       name, addr, ntohs(port));
337 	else
338 	    dsb_simple(why, "4.4.1", "connect to %s[%s]: %m", name, addr);
339 	close(sock);
340 	return (0);
341     }
342     stream = vstream_fdopen(sock, O_RDWR);
343 
344     /*
345      * Avoid poor performance when TCP MSS > VSTREAM_BUFSIZE.
346      */
347     if (sa->sa_family == AF_INET
348 #ifdef AF_INET6
349 	|| sa->sa_family == AF_INET6
350 #endif
351 	)
352 	vstream_tweak_tcp(stream);
353 
354     /*
355      * Bundle up what we have into a nice SMTP_SESSION object.
356      */
357     return (smtp_session_alloc(stream, iter, start_time, sess_flags));
358 }
359 
360 /* smtp_parse_destination - parse host/port destination */
361 
smtp_parse_destination(char * destination,char * def_service,char ** hostp,char ** servicep,unsigned * portp)362 static char *smtp_parse_destination(char *destination, char *def_service,
363 				            char **hostp, char **servicep,
364 				            unsigned *portp)
365 {
366     char   *buf = mystrdup(destination);
367     char   *service;
368     struct servent *sp;
369     char   *protocol = "tcp";		/* XXX configurable? */
370     unsigned port;
371     const char *err;
372 
373     if (msg_verbose)
374 	msg_info("smtp_parse_destination: %s %s", destination, def_service);
375 
376     /*
377      * Parse the host/port information. We're working with a copy of the
378      * destination argument so the parsing can be destructive.
379      */
380     if ((err = host_port(buf, hostp, (char *) 0, servicep, def_service)) != 0)
381 	msg_fatal("%s in server description: %s", err, destination);
382 
383     /*
384      * Convert service to port number, network byte order.
385      */
386     service = (char *) filter_known_tcp_port(*servicep);
387     if (alldig(service)) {
388 	if ((port = atoi(service)) >= 65536 || port == 0)
389 	    msg_fatal("bad network port: %s for destination: %s",
390 		      service, destination);
391 	*portp = htons(port);
392     } else {
393 	if ((sp = getservbyname(service, protocol)) == 0)
394 	    msg_fatal("unknown service: %s/%s", service, protocol);
395 	*portp = sp->s_port;
396     }
397     return (buf);
398 }
399 
400 /* smtp_cleanup_session - clean up after using a session */
401 
smtp_cleanup_session(SMTP_STATE * state)402 static void smtp_cleanup_session(SMTP_STATE *state)
403 {
404     DELIVER_REQUEST *request = state->request;
405     SMTP_SESSION *session = state->session;
406     int     throttled;
407 
408     /*
409      * Inform the postmaster of trouble.
410      *
411      * XXX Don't send notifications about errors while sending notifications.
412      */
413 #define POSSIBLE_NOTIFICATION(sender) \
414 	(*sender == 0 || strcmp(sender, mail_addr_double_bounce()) == 0)
415 
416     if (session->history != 0
417 	&& (session->error_mask & name_mask(VAR_NOTIFY_CLASSES,
418 					    mail_error_masks,
419 					    var_notify_classes)) != 0
420 	&& POSSIBLE_NOTIFICATION(request->sender) == 0)
421 	smtp_chat_notify(session);
422 
423     /*
424      * When session caching is enabled, cache the first good session for this
425      * delivery request under the next-hop destination, and cache all good
426      * sessions under their server network address (destroying the session in
427      * the process).
428      *
429      * Caching under the next-hop destination name (rather than the fall-back
430      * destination) allows us to skip over non-responding primary or backup
431      * hosts. In fact, this is the only benefit of caching logical to
432      * physical bindings; caching a session under its own hostname provides
433      * no performance benefit, given the way smtp_connect() works.
434      */
435     throttled = THIS_SESSION_IS_THROTTLED;	/* smtp_quit() may fail */
436     if (THIS_SESSION_IS_EXPIRED)
437 	smtp_quit(state);			/* also disables caching */
438     if (THIS_SESSION_IS_CACHED
439     /* Redundant tests for safety... */
440 	&& vstream_ferror(session->stream) == 0
441 	&& vstream_feof(session->stream) == 0) {
442 	smtp_save_session(state, SMTP_KEY_MASK_SCACHE_DEST_LABEL,
443 			  SMTP_KEY_MASK_SCACHE_ENDP_LABEL);
444     } else {
445 	smtp_session_free(session);
446     }
447     state->session = 0;
448 
449     /*
450      * If this session was good, reset the scache next-hop destination, so
451      * that we won't cache connections to less-preferred servers under the
452      * same next-hop destination. Otherwise we could end up skipping over the
453      * available and more-preferred servers.
454      */
455     if (HAVE_SCACHE_REQUEST_NEXTHOP(state) && !throttled)
456 	CLEAR_SCACHE_REQUEST_NEXTHOP(state);
457 
458     /*
459      * Clean up the lists with todo and dropped recipients.
460      */
461     smtp_rcpt_cleanup(state);
462 
463     /*
464      * Reset profiling info.
465      *
466      * XXX When one delivery request results in multiple sessions, the set-up
467      * and transmission latencies of the earlier sessions will count as
468      * connection set-up time for the later sessions.
469      *
470      * XXX On the other hand, when we first try to connect to one or more dead
471      * hosts before we reach a good host, then all that time must be counted
472      * as connection set-up time for the session with the good host.
473      *
474      * XXX So this set-up attribution problem exists only when we actually
475      * engage in a session, spend a lot of time delivering a message, find
476      * that it fails, and then connect to an alternate host.
477      */
478     memset((void *) &request->msg_stats.conn_setup_done, 0,
479 	   sizeof(request->msg_stats.conn_setup_done));
480     memset((void *) &request->msg_stats.deliver_done, 0,
481 	   sizeof(request->msg_stats.deliver_done));
482     request->msg_stats.reuse_count = 0;
483 }
484 
smtp_cache_policy(SMTP_STATE * state,const char * dest)485 static void smtp_cache_policy(SMTP_STATE *state, const char *dest)
486 {
487     DELIVER_REQUEST *request = state->request;
488 
489     state->misc_flags &= ~SMTP_MISC_FLAG_CONN_CACHE_MASK;
490 
491     if (smtp_cache_dest && string_list_match(smtp_cache_dest, dest)) {
492 	state->misc_flags |= SMTP_MISC_FLAG_CONN_CACHE_MASK;
493     } else if (var_smtp_cache_demand) {
494 	if (request->flags & DEL_REQ_FLAG_CONN_LOAD)
495 	    state->misc_flags |= SMTP_MISC_FLAG_CONN_LOAD;
496 	if (request->flags & DEL_REQ_FLAG_CONN_STORE)
497 	    state->misc_flags |= SMTP_MISC_FLAG_CONN_STORE;
498     }
499 }
500 
501 /* smtp_connect_local - connect to local server */
502 
smtp_connect_local(SMTP_STATE * state,const char * path)503 static void smtp_connect_local(SMTP_STATE *state, const char *path)
504 {
505     const char *myname = "smtp_connect_local";
506     SMTP_ITERATOR *iter = state->iterator;
507     SMTP_SESSION *session;
508     DSN_BUF *why = state->why;
509 
510     /*
511      * Do not silently ignore an unused setting.
512      */
513     if (*var_fallback_relay)
514 	msg_warn("ignoring \"%s = %s\" setting for non-TCP connections",
515 		 VAR_LMTP_FALLBACK, var_fallback_relay);
516 
517     /*
518      * It's too painful to weave this code into the SMTP connection
519      * management routine.
520      *
521      * Connection cache management is based on the UNIX-domain pathname, without
522      * the "unix:" prefix.
523      */
524     smtp_cache_policy(state, path);
525     if (state->misc_flags & SMTP_MISC_FLAG_CONN_CACHE_MASK)
526 	SET_SCACHE_REQUEST_NEXTHOP(state, path);
527 
528     /*
529      * Here we ensure that the iter->addr member refers to a copy of the
530      * UNIX-domain pathname, so that smtp_save_session() will cache the
531      * connection using the pathname as the physical endpoint name.
532      *
533      * We set dest=path for backwards compatibility.
534      */
535 #define NO_PORT	0
536 
537     SMTP_ITER_INIT(iter, path, var_myhostname, path, NO_PORT, state);
538 
539     /*
540      * Opportunistic TLS for unix domain sockets does not make much sense,
541      * since the channel is private, mere encryption without authentication
542      * is just wasted cycles and opportunity for breakage. Since we are not
543      * willing to retry after TLS handshake failures here, we downgrade "may"
544      * no "none". Nothing is lost, and much waste is avoided.
545      *
546      * We don't know who is authenticating whom, so if a client cert is
547      * available, "encrypt" may be a sensible policy. Otherwise, we also
548      * downgrade "encrypt" to "none", this time just to avoid waste.
549      *
550      * We use smtp_reuse_nexthop() instead of smtp_reuse_addr(), so that we can
551      * reuse a SASL-authenticated connection (however unlikely this scenario
552      * may be). The smtp_reuse_addr() interface currently supports only reuse
553      * of SASL-unauthenticated connections.
554      */
555 #ifdef USE_TLS
556     if (!smtp_tls_policy_cache_query(why, state->tls, iter)) {
557 	msg_warn("TLS policy lookup error for %s/%s: %s",
558 		 STR(iter->host), STR(iter->addr), STR(why->reason));
559 	return;
560     }
561 #endif
562     if ((state->misc_flags & SMTP_MISC_FLAG_CONN_LOAD) == 0
563 	|| (session = smtp_reuse_nexthop(state,
564 				     SMTP_KEY_MASK_SCACHE_DEST_LABEL)) == 0)
565 	session = smtp_connect_unix(iter, why, state->misc_flags);
566     if ((state->session = session) != 0) {
567 	session->state = state;
568 #ifdef USE_TLS
569 	session->tls_nexthop = var_myhostname;	/* for TLS_LEV_SECURE */
570 	if (state->tls->level == TLS_LEV_MAY) {
571 	    msg_warn("%s: opportunistic TLS encryption is not appropriate "
572 		     "for unix-domain destinations.", myname);
573 	    state->tls->level = TLS_LEV_NONE;
574 	}
575 #endif
576 	/* All delivery errors bounce or defer. */
577 	state->misc_flags |= SMTP_MISC_FLAG_FINAL_SERVER;
578 
579 	/*
580 	 * When a TLS handshake fails, the stream is marked "dead" to avoid
581 	 * further I/O over a broken channel.
582 	 */
583 	if ((session->features & SMTP_FEATURE_FROM_CACHE) == 0
584 	    && smtp_helo(state) != 0) {
585 	    if (!THIS_SESSION_IS_FORBIDDEN
586 		&& vstream_ferror(session->stream) == 0
587 		&& vstream_feof(session->stream) == 0)
588 		smtp_quit(state);
589 	} else {
590 	    smtp_xfer(state);
591 	}
592 
593 	/*
594 	 * With opportunistic TLS disabled we don't expect to be asked to
595 	 * retry connections without TLS, and so we expect the final server
596 	 * flag to stay on.
597 	 */
598 	if ((state->misc_flags & SMTP_MISC_FLAG_FINAL_SERVER) == 0)
599 	    msg_panic("%s: unix-domain destination not final!", myname);
600 	smtp_cleanup_session(state);
601     }
602 
603     /*
604      * Cleanup.
605      */
606     if (HAVE_SCACHE_REQUEST_NEXTHOP(state))
607 	CLEAR_SCACHE_REQUEST_NEXTHOP(state);
608 }
609 
610 /* smtp_scrub_address_list - delete all cached addresses from list */
611 
smtp_scrub_addr_list(HTABLE * cached_addr,DNS_RR ** addr_list)612 static void smtp_scrub_addr_list(HTABLE *cached_addr, DNS_RR **addr_list)
613 {
614     MAI_HOSTADDR_STR hostaddr;
615     DNS_RR *addr;
616     DNS_RR *next;
617 
618     /*
619      * XXX Extend the DNS_RR structure with fields for the printable address
620      * and/or binary sockaddr representations, so that we can avoid repeated
621      * binary->string transformations for the same address.
622      */
623     for (addr = *addr_list; addr; addr = next) {
624 	next = addr->next;
625 	if (dns_rr_to_pa(addr, &hostaddr) == 0) {
626 	    msg_warn("cannot convert type %s record to printable address",
627 		     dns_strtype(addr->type));
628 	    continue;
629 	}
630 	if (htable_locate(cached_addr, hostaddr.buf))
631 	    *addr_list = dns_rr_remove(*addr_list, addr);
632     }
633 }
634 
635 /* smtp_update_addr_list - common address list update */
636 
smtp_update_addr_list(DNS_RR ** addr_list,const char * server_addr,int session_count)637 static void smtp_update_addr_list(DNS_RR **addr_list, const char *server_addr,
638 				          int session_count)
639 {
640     DNS_RR *addr;
641     DNS_RR *next;
642     int     aierr;
643     struct addrinfo *res0;
644 
645     if (*addr_list == 0)
646 	return;
647 
648     /*
649      * Truncate the address list if we are not going to use it anyway.
650      */
651     if (session_count == var_smtp_mxsess_limit
652 	|| session_count == var_smtp_mxaddr_limit) {
653 	dns_rr_free(*addr_list);
654 	*addr_list = 0;
655 	return;
656     }
657 
658     /*
659      * Convert server address to internal form, and look it up in the address
660      * list.
661      *
662      * XXX smtp_reuse_session() breaks if we remove two or more adjacent list
663      * elements but do not truncate the list to zero length.
664      *
665      * XXX Extend the SMTP_SESSION structure with sockaddr information so that
666      * we can avoid repeated string->binary transformations for the same
667      * address.
668      *
669      * XXX SRV support: this should match the port, too, otherwise we may
670      * eliminate too many list entries.
671      */
672     if ((aierr = hostaddr_to_sockaddr(server_addr, (char *) 0, 0, &res0)) != 0) {
673 	msg_warn("hostaddr_to_sockaddr %s: %s",
674 		 server_addr, MAI_STRERROR(aierr));
675     } else {
676 	for (addr = *addr_list; addr; addr = next) {
677 	    next = addr->next;
678 	    if (DNS_RR_EQ_SA(addr, (struct sockaddr *) res0->ai_addr)) {
679 		*addr_list = dns_rr_remove(*addr_list, addr);
680 		break;
681 	    }
682 	}
683 	freeaddrinfo(res0);
684     }
685 }
686 
687 /* smtp_reuse_session - try to use existing connection, return session count */
688 
smtp_reuse_session(SMTP_STATE * state,DNS_RR ** addr_list,int domain_best_pref)689 static int smtp_reuse_session(SMTP_STATE *state, DNS_RR **addr_list,
690 			              int domain_best_pref)
691 {
692     int     session_count = 0;
693     DNS_RR *addr;
694     DNS_RR *next;
695     MAI_HOSTADDR_STR hostaddr;
696     SMTP_SESSION *session;
697     SMTP_ITERATOR *iter = state->iterator;
698     DSN_BUF *why = state->why;
699 
700     /*
701      * This code is called after server address/port lookup, before
702      * iter->host, iter->addr, iter->rr and iter->mx are assigned concrete
703      * values, and while iter->port still corresponds to the nexthop service,
704      * or the default service configured with smtp_tcp_port or lmtp_tcp_port.
705      *
706      * When a connection is reused by nexthop/service or by server address/port,
707      * iter->host, iter->addr and iter->port are updated with actual values
708      * from the cached session. Additionally, when a connection is searched
709      * by nexthop/service, iter->rr remains null, and when a connection is
710      * searched by server address/port, iter->rr is updated with an actual
711      * server address/port before the search is made.
712      *
713      * First, search the cache by delivery request nexthop. We truncate the
714      * server address list when all the sessions for this destination are
715      * used up, to reduce the number of variables that need to be checked
716      * later.
717      *
718      * Note: connection reuse by delivery request nexthop restores the "best MX"
719      * bit.
720      *
721      * smtp_reuse_nexthop() clobbers the iterators's "dest" attribute. We save
722      * and restore it here, so that subsequent connections will use the
723      * proper nexthop information.
724      *
725      * We don't use TLS level info for nexthop-based connection cache storage
726      * keys. The combination of (service, nexthop, etc.) should be stable
727      * over the time range of interest, and the policy is still enforced on
728      * an individual connection to an MX host, before that connection is
729      * stored under a nexthop- or host-based storage key.
730      */
731 #ifdef USE_TLS
732     smtp_tls_policy_dummy(state->tls);
733 #endif
734     SMTP_ITER_SAVE_DEST(state->iterator);
735     if (*addr_list && SMTP_RCPT_LEFT(state) > 0
736 	&& HAVE_SCACHE_REQUEST_NEXTHOP(state)
737 	&& (session = smtp_reuse_nexthop(state, SMTP_KEY_MASK_SCACHE_DEST_LABEL)) != 0) {
738 	session_count = 1;
739 	smtp_update_addr_list(addr_list, STR(iter->addr), session_count);
740 	if ((state->misc_flags & SMTP_MISC_FLAG_FINAL_NEXTHOP)
741 	    && *addr_list == 0)
742 	    state->misc_flags |= SMTP_MISC_FLAG_FINAL_SERVER;
743 	smtp_xfer(state);
744 	smtp_cleanup_session(state);
745     }
746     SMTP_ITER_RESTORE_DEST(state->iterator);
747 
748     /*
749      * Second, search the cache by primary MX address. Again, we use address
750      * list truncation so that we have to check fewer variables later.
751      *
752      * XXX This loop is safe because smtp_update_addr_list() either truncates
753      * the list to zero length, or removes at most one list element.
754      *
755      * Currently, we use smtp_reuse_addr() only for SASL-unauthenticated
756      * connections. Furthermore, we rely on smtp_reuse_addr() to look up an
757      * existing SASL-unauthenticated connection only when a new connection
758      * would be guaranteed not to require SASL authentication.
759      *
760      * In addition, we rely on smtp_reuse_addr() to look up an existing
761      * plaintext connection only when a new connection would be guaranteed
762      * not to use TLS.
763      *
764      * For more precise control over reuse, the iterator should look up SASL and
765      * TLS policy as it evaluates mail exchangers in order, instead of
766      * relying on duplicate lookup request code in smtp_reuse(3) and
767      * smtp_session(3).
768      */
769     for (addr = *addr_list; SMTP_RCPT_LEFT(state) > 0 && addr; addr = next) {
770 	if (addr->pref != domain_best_pref)
771 	    break;
772 	next = addr->next;
773 	if (dns_rr_to_pa(addr, &hostaddr) == 0) {
774 	    msg_warn("cannot convert type %s record to printable address",
775 		     dns_strtype(addr->type));
776 	    /* XXX Assume there is no code at the end of this loop. */
777 	    continue;
778 	}
779 	SMTP_ITER_UPDATE_HOST(iter, SMTP_HNAME(addr), hostaddr.buf, addr);
780 #ifdef USE_TLS
781 	if (!smtp_tls_policy_cache_query(why, state->tls, iter)) {
782 	    msg_warn("TLS policy lookup error for %s/%s: %s",
783 		     STR(iter->dest), STR(iter->host), STR(why->reason));
784 	    continue;
785 	    /* XXX Assume there is no code at the end of this loop. */
786 	}
787 #endif
788 	if ((session = smtp_reuse_addr(state,
789 				   SMTP_KEY_MASK_SCACHE_ENDP_LABEL)) != 0) {
790 	    session->features |= SMTP_FEATURE_BEST_MX;
791 	    session_count += 1;
792 	    smtp_update_addr_list(addr_list, STR(iter->addr), session_count);
793 	    if (*addr_list == 0)
794 		next = 0;
795 	    if ((state->misc_flags & SMTP_MISC_FLAG_FINAL_NEXTHOP)
796 		&& next == 0)
797 		state->misc_flags |= SMTP_MISC_FLAG_FINAL_SERVER;
798 	    smtp_xfer(state);
799 	    smtp_cleanup_session(state);
800 	}
801     }
802     return (session_count);
803 }
804 
805 /* smtp_connect_inet - establish network connection */
806 
smtp_connect_inet(SMTP_STATE * state,const char * nexthop,char * def_service)807 static void smtp_connect_inet(SMTP_STATE *state, const char *nexthop,
808 			              char *def_service)
809 {
810     DELIVER_REQUEST *request = state->request;
811     SMTP_ITERATOR *iter = state->iterator;
812     ARGV   *sites;
813     char   *dest;
814     char  **cpp;
815     int     non_fallback_sites;
816     int     retry_plain = 0;
817     DSN_BUF *why = state->why;
818 
819     /*
820      * For sanity, require that at least one of INET or INET6 is enabled.
821      * Otherwise, we can't look up interface information, and we can't
822      * convert names or addresses.
823      */
824     if (inet_proto_info()->ai_family_list[0] == 0) {
825 	dsb_simple(why, "4.4.4", "all network protocols are disabled");
826 	return;
827     }
828 
829     /*
830      * Do a null destination sanity check in case the primary destination is
831      * a list that consists of only separators.
832      */
833     sites = argv_split(nexthop, CHARS_COMMA_SP);
834     if (sites->argc == 0)
835 	msg_panic("null destination: \"%s\"", nexthop);
836     non_fallback_sites = sites->argc;
837     argv_split_append(sites, var_fallback_relay, CHARS_COMMA_SP);
838 
839     /*
840      * Don't give up after a hard host lookup error until we have tried the
841      * fallback relay servers.
842      *
843      * Don't bounce mail after a host lookup problem with a relayhost or with a
844      * fallback relay.
845      *
846      * Don't give up after a qualifying soft error until we have tried all
847      * qualifying backup mail servers.
848      *
849      * All this means that error handling and error reporting depends on whether
850      * the error qualifies for trying to deliver to a backup mail server, or
851      * whether we're looking up a relayhost or fallback relay. The challenge
852      * then is to build this into the pre-existing SMTP client without
853      * getting lost in the complexity.
854      */
855 #define IS_FALLBACK_RELAY(cpp, sites, non_fallback_sites) \
856 	    (*(cpp) && (cpp) >= (sites)->argv + (non_fallback_sites))
857 
858     for (cpp = sites->argv, (state->misc_flags |= SMTP_MISC_FLAG_FIRST_NEXTHOP);
859 	 SMTP_RCPT_LEFT(state) > 0 && (dest = *cpp) != 0;
860 	 cpp++, (state->misc_flags &= ~SMTP_MISC_FLAG_FIRST_NEXTHOP)) {
861 	char   *dest_buf;
862 	char   *domain;
863 	unsigned port;
864 	char   *service;
865 	DNS_RR *addr_list;
866 	DNS_RR *addr;
867 	DNS_RR *next;
868 	int     addr_count;
869 	int     sess_count;
870 	SMTP_SESSION *session;
871 	int     lookup_mx;
872 	int     non_dns_or_literal;
873 	int     i_am_mx;
874 	unsigned domain_best_pref;
875 	MAI_HOSTADDR_STR hostaddr;
876 
877 	if (cpp[1] == 0)
878 	    state->misc_flags |= SMTP_MISC_FLAG_FINAL_NEXTHOP;
879 
880 	/*
881 	 * Parse the destination. If no TCP port is specified, use the port
882 	 * that is reserved for the protocol (SMTP or LMTP).
883 	 *
884 	 * The 'service' variable corresponds to the remote service specified
885 	 * with the nexthop, or the default service configured with
886 	 * smtp_tcp_port or lmtp_tcp_port. The 'port' variable and
887 	 * SMTP_ITERATOR.port initially correspond to that service. This
888 	 * determines what loop prevention will be in effect.
889 	 *
890 	 * The SMTP_ITERATOR.port will be overwritten after SRV record lookup.
891 	 * This guarantees that the connection cache key contains the correct
892 	 * port value when caching and retrieving a connection by its server
893 	 * address (and port).
894 	 *
895 	 * By design, the connection cache key contains NO port information when
896 	 * caching or retrieving a connection by its nexthop destination.
897 	 * Instead, the cache key contains the master.cf service name (a
898 	 * proxy for all the parameter settings including the default service
899 	 * from smtp_tcp_port or lmtp_tcp_port), together with the nexthop
900 	 * destination and sender-dependent info. This should be sufficient
901 	 * to avoid cross talk between mail streams that should be separated.
902 	 */
903 	dest_buf = smtp_parse_destination(dest, def_service, &domain,
904 					  &service, &port);
905 	if (var_helpful_warnings && var_smtp_tls_wrappermode == 0
906 	    && ntohs(port) == 465) {
907 	    msg_info("SMTPS wrappermode (TCP port 465) requires setting "
908 		     "\"%s = yes\", and \"%s = encrypt\" (or stronger)",
909 		     VAR_LMTP_SMTP(TLS_WRAPPER), VAR_LMTP_SMTP(TLS_LEVEL));
910 	}
911 #define NO_HOST	""				/* safety */
912 #define NO_ADDR	""				/* safety */
913 
914 	SMTP_ITER_INIT(iter, dest, NO_HOST, NO_ADDR, port, state);
915 
916 	/*
917 	 * Resolve an SMTP or LMTP server. Skip MX or SRV lookups when a
918 	 * quoted domain is specified or when DNS lookups are disabled.
919 	 */
920 	if (msg_verbose)
921 	    msg_info("connecting to %s service %s", domain, service);
922 	non_dns_or_literal = (smtp_dns_support == SMTP_DNS_DISABLED
923 			      || *dest == '[');
924 	if (smtp_mode) {
925 	    if (ntohs(port) == IPPORT_SMTP)
926 		state->misc_flags |= SMTP_MISC_FLAG_LOOP_DETECT;
927 	    else
928 		state->misc_flags &= ~SMTP_MISC_FLAG_LOOP_DETECT;
929 	    lookup_mx = !non_dns_or_literal;
930 	} else
931 	    lookup_mx = 0;
932 
933 	/*
934 	 * Look up SRV and address records and fall back to non-SRV lookups
935 	 * if permitted by configuration settings, or look up MX and address
936 	 * records, or look up address records only.
937 	 */
938 	i_am_mx = 0;
939 	addr_list = 0;
940 	if (!non_dns_or_literal && smtp_use_srv_lookup
941 	    && string_list_match(smtp_use_srv_lookup, service)) {
942 	    if (lookup_mx)
943 		state->misc_flags |= SMTP_MISC_FLAG_FALLBACK_SRV_TO_MX;
944 	    else
945 		state->misc_flags &= ~SMTP_MISC_FLAG_FALLBACK_SRV_TO_MX;
946 	    addr_list = smtp_service_addr(domain, service, &iter->mx,
947 					  state->misc_flags, why, &i_am_mx);
948 	} else if (!lookup_mx) {
949 	    /* Non-DNS, literal, or non-SMTP service */
950 	    addr_list = smtp_host_addr(domain, state->misc_flags, why);
951 	    /* XXX We could be an MX host for this destination... */
952 	} else {
953 	    addr_list = smtp_domain_addr(domain, &iter->mx, state->misc_flags,
954 					 why, &i_am_mx);
955 	}
956 	/* If we're MX host, don't connect to non-MX backups. */
957 	if (i_am_mx)
958 	    state->misc_flags |= SMTP_MISC_FLAG_FINAL_NEXTHOP;
959 
960 	/*
961 	 * Don't try fall-back hosts if mail loops to myself. That would just
962 	 * make the problem worse.
963 	 */
964 	if (addr_list == 0 && SMTP_HAS_LOOP_DSN(why))
965 	    state->misc_flags |= SMTP_MISC_FLAG_FINAL_NEXTHOP;
966 
967 	/*
968 	 * No early loop exit or we have a memory leak with dest_buf.
969 	 */
970 	if (addr_list)
971 	    domain_best_pref = addr_list->pref;
972 
973 	/*
974 	 * When connection caching is enabled, store the first good
975 	 * connection for this delivery request under the delivery request
976 	 * next-hop name. Good connections will also be stored under their
977 	 * specific server IP address.
978 	 *
979 	 * XXX smtp_session_cache_destinations specifies domain names without
980 	 * :port, because : is already used for maptype:mapname. Because of
981 	 * this limitation we use the bare domain without the optional [] or
982 	 * non-default TCP port.
983 	 *
984 	 * Opportunistic (a.k.a. on-demand) session caching on request by the
985 	 * queue manager. This is turned temporarily when a destination has a
986 	 * high volume of mail in the active queue. When the surge reaches
987 	 * its end, the queue manager requests that connections be retrieved
988 	 * but not stored.
989 	 */
990 	if (addr_list && (state->misc_flags & SMTP_MISC_FLAG_FIRST_NEXTHOP)) {
991 	    smtp_cache_policy(state, domain);
992 	    if (state->misc_flags & SMTP_MISC_FLAG_CONN_CACHE_MASK)
993 		SET_SCACHE_REQUEST_NEXTHOP(state, dest);
994 	}
995 
996 	/*
997 	 * Delete visited cached hosts from the address list.
998 	 *
999 	 * Optionally search the connection cache by domain name or by primary
1000 	 * MX address before we try to create new connections.
1001 	 *
1002 	 * Enforce the MX session and MX address counts per next-hop or
1003 	 * fall-back destination. smtp_reuse_session() will truncate the
1004 	 * address list when either limit is reached.
1005 	 */
1006 	if (addr_list && (state->misc_flags & SMTP_MISC_FLAG_CONN_LOAD)) {
1007 	    if (state->cache_used->used > 0)
1008 		smtp_scrub_addr_list(state->cache_used, &addr_list);
1009 	    sess_count = addr_count =
1010 		smtp_reuse_session(state, &addr_list, domain_best_pref);
1011 	} else
1012 	    sess_count = addr_count = 0;
1013 
1014 	/*
1015 	 * Connect to an SMTP server: create primary MX connections, and
1016 	 * reuse or create backup MX connections.
1017 	 *
1018 	 * At the start of an SMTP session, all recipients are unmarked. In the
1019 	 * course of an SMTP session, recipients are marked as KEEP (deliver
1020 	 * to alternate mail server) or DROP (remove from recipient list). At
1021 	 * the end of an SMTP session, weed out the recipient list. Unmark
1022 	 * any left-over recipients and try to deliver them to a backup mail
1023 	 * server.
1024 	 *
1025 	 * Cache the first good session under the next-hop destination name.
1026 	 * Cache all good sessions under their physical endpoint.
1027 	 *
1028 	 * Don't query the session cache for primary MX hosts. We already did
1029 	 * that in smtp_reuse_session(), and if any were found in the cache,
1030 	 * they were already deleted from the address list.
1031 	 *
1032 	 * Currently, we use smtp_reuse_addr() only for SASL-unauthenticated
1033 	 * connections. Furthermore, we rely on smtp_reuse_addr() to look up
1034 	 * an existing SASL-unauthenticated connection only when a new
1035 	 * connection would be guaranteed not to require SASL authentication.
1036 	 *
1037 	 * In addition, we rely on smtp_reuse_addr() to look up an existing
1038 	 * plaintext connection only when a new connection would be
1039 	 * guaranteed not to use TLS.
1040 	 */
1041 	for (addr = addr_list; SMTP_RCPT_LEFT(state) > 0 && addr; addr = next) {
1042 	    next = addr->next;
1043 	    if (++addr_count == var_smtp_mxaddr_limit)
1044 		next = 0;
1045 	    if (dns_rr_to_pa(addr, &hostaddr) == 0) {
1046 		msg_warn("cannot convert type %s record to printable address",
1047 			 dns_strtype(addr->type));
1048 		/* XXX Assume there is no code at the end of this loop. */
1049 		continue;
1050 	    }
1051 	    SMTP_ITER_UPDATE_HOST(iter, SMTP_HNAME(addr), hostaddr.buf, addr);
1052 #ifdef USE_TLS
1053 	    if (!smtp_tls_policy_cache_query(why, state->tls, iter)) {
1054 		msg_warn("TLS policy lookup for %s/%s: %s",
1055 			 STR(iter->dest), STR(iter->host), STR(why->reason));
1056 		continue;
1057 		/* XXX Assume there is no code at the end of this loop. */
1058 	    }
1059 	    if (var_smtp_tls_wrappermode
1060 		&& state->tls->level < TLS_LEV_ENCRYPT) {
1061 		msg_warn("%s requires \"%s = encrypt\" (or stronger)",
1062 		      VAR_LMTP_SMTP(TLS_WRAPPER), VAR_LMTP_SMTP(TLS_LEVEL));
1063 		continue;
1064 		/* XXX Assume there is no code at the end of this loop. */
1065 	    }
1066 	    /* Disable TLS when retrying after a handshake failure */
1067 	    if (retry_plain) {
1068 		state->tls->level = TLS_LEV_NONE;
1069 		retry_plain = 0;
1070 	    }
1071 #endif
1072 	    if ((state->misc_flags & SMTP_MISC_FLAG_CONN_LOAD) == 0
1073 		|| addr->pref == domain_best_pref
1074 		|| !(session = smtp_reuse_addr(state,
1075 					  SMTP_KEY_MASK_SCACHE_ENDP_LABEL)))
1076 		session = smtp_connect_addr(iter, why, state->misc_flags);
1077 	    if ((state->session = session) != 0) {
1078 		session->state = state;
1079 #ifdef USE_TLS
1080 		session->tls_nexthop = domain;
1081 #endif
1082 		if (addr->pref == domain_best_pref)
1083 		    session->features |= SMTP_FEATURE_BEST_MX;
1084 		/* Don't count handshake errors towards the session limit. */
1085 		if ((state->misc_flags & SMTP_MISC_FLAG_FINAL_NEXTHOP)
1086 		    && next == 0)
1087 		    state->misc_flags |= SMTP_MISC_FLAG_FINAL_SERVER;
1088 		if ((session->features & SMTP_FEATURE_FROM_CACHE) == 0
1089 		    && smtp_helo(state) != 0) {
1090 #ifdef USE_TLS
1091 
1092 		    /*
1093 		     * When an opportunistic TLS handshake fails, try the
1094 		     * same address again, with TLS disabled. See also the
1095 		     * RETRY_AS_PLAINTEXT macro.
1096 		     */
1097 		    if ((retry_plain = session->tls_retry_plain) != 0) {
1098 			--addr_count;
1099 			next = addr;
1100 		    }
1101 #endif
1102 
1103 		    /*
1104 		     * When a TLS handshake fails, the stream is marked
1105 		     * "dead" to avoid further I/O over a broken channel.
1106 		     */
1107 		    if (!THIS_SESSION_IS_FORBIDDEN
1108 			&& vstream_ferror(session->stream) == 0
1109 			&& vstream_feof(session->stream) == 0)
1110 			smtp_quit(state);
1111 		} else {
1112 		    /* Do count delivery errors towards the session limit. */
1113 		    if (++sess_count == var_smtp_mxsess_limit)
1114 			next = 0;
1115 		    if ((state->misc_flags & SMTP_MISC_FLAG_FINAL_NEXTHOP)
1116 			&& next == 0)
1117 			state->misc_flags |= SMTP_MISC_FLAG_FINAL_SERVER;
1118 		    smtp_xfer(state);
1119 #ifdef USE_TLS
1120 
1121 		    /*
1122 		     * When opportunistic TLS fails after the STARTTLS
1123 		     * handshake, try the same address again, with TLS
1124 		     * disabled. See also the RETRY_AS_PLAINTEXT macro.
1125 		     */
1126 		    if ((retry_plain = session->tls_retry_plain) != 0) {
1127 			--sess_count;
1128 			--addr_count;
1129 			next = addr;
1130 		    }
1131 #endif
1132 		}
1133 		smtp_cleanup_session(state);
1134 	    } else {
1135 		/* The reason already includes the IP address and TCP port. */
1136 		msg_info("%s", STR(why->reason));
1137 	    }
1138 	    /* XXX Code above assumes there is no code at this loop ending. */
1139 	}
1140 	dns_rr_free(addr_list);
1141 	if (iter->mx) {
1142 	    dns_rr_free(iter->mx);
1143 	    iter->mx = 0;			/* Just in case */
1144 	}
1145 	myfree(dest_buf);
1146 	if (state->misc_flags & SMTP_MISC_FLAG_FINAL_NEXTHOP)
1147 	    break;
1148     }
1149 
1150     /*
1151      * We still need to deliver, bounce or defer some left-over recipients:
1152      * either mail loops or some backup mail server was unavailable.
1153      */
1154     if (SMTP_RCPT_LEFT(state) > 0) {
1155 
1156 	/*
1157 	 * In case of a "no error" indication we make up an excuse: we did
1158 	 * find the host address, but we did not attempt to connect to it.
1159 	 * This can happen when the fall-back relay was already tried via a
1160 	 * cached connection, so that the address list scrubber left behind
1161 	 * an empty list.
1162 	 */
1163 	if (!SMTP_HAS_DSN(why)) {
1164 	    dsb_simple(why, "4.3.0",
1165 		       "server unavailable or unable to receive mail");
1166 	}
1167 
1168 	/*
1169 	 * Pay attention to what could be configuration problems, and pretend
1170 	 * that these are recoverable rather than bouncing the mail.
1171 	 */
1172 	else if (!SMTP_HAS_SOFT_DSN(why)) {
1173 
1174 	    /*
1175 	     * The fall-back destination did not resolve as expected, or it
1176 	     * is refusing to talk to us, or mail for it loops back to us.
1177 	     */
1178 	    if (IS_FALLBACK_RELAY(cpp, sites, non_fallback_sites)) {
1179 		msg_warn("%s configuration problem", VAR_SMTP_FALLBACK);
1180 		vstring_strcpy(why->status, "4.3.5");
1181 		/* XXX Keep the diagnostic code and MTA. */
1182 	    }
1183 
1184 	    /*
1185 	     * The next-hop relayhost did not resolve as expected, or it is
1186 	     * refusing to talk to us, or mail for it loops back to us.
1187 	     *
1188 	     * XXX There is no equivalent safety net for mis-configured
1189 	     * sender-dependent relay hosts. The trivial-rewrite resolver
1190 	     * would have to flag the result, and the queue manager would
1191 	     * have to provide that information to delivery agents.
1192 	     */
1193 	    else if (smtp_mode && strcmp(sites->argv[0], var_relayhost) == 0) {
1194 		msg_warn("%s configuration problem", VAR_RELAYHOST);
1195 		vstring_strcpy(why->status, "4.3.5");
1196 		/* XXX Keep the diagnostic code and MTA. */
1197 	    }
1198 
1199 	    /*
1200 	     * Mail for the next-hop destination loops back to myself. Pass
1201 	     * the mail to the best_mx_transport or bounce it.
1202 	     */
1203 	    else if (smtp_mode && SMTP_HAS_LOOP_DSN(why) && *var_bestmx_transp) {
1204 		dsb_reset(why);			/* XXX */
1205 		state->status = deliver_pass_all(MAIL_CLASS_PRIVATE,
1206 						 var_bestmx_transp,
1207 						 request);
1208 		SMTP_RCPT_LEFT(state) = 0;	/* XXX */
1209 	    }
1210 	}
1211     }
1212 
1213     /*
1214      * Cleanup.
1215      */
1216     if (HAVE_SCACHE_REQUEST_NEXTHOP(state))
1217 	CLEAR_SCACHE_REQUEST_NEXTHOP(state);
1218     argv_free(sites);
1219 }
1220 
1221 /* smtp_connect - establish SMTP connection */
1222 
smtp_connect(SMTP_STATE * state)1223 int     smtp_connect(SMTP_STATE *state)
1224 {
1225     DELIVER_REQUEST *request = state->request;
1226     char   *destination = request->nexthop;
1227 
1228     /*
1229      * All deliveries proceed along the same lines, whether they are over TCP
1230      * or UNIX-domain sockets, and whether they use SMTP or LMTP: get a
1231      * connection from the cache or create a new connection; deliver mail;
1232      * update the connection cache or disconnect.
1233      *
1234      * The major differences appear at a higher level: the expansion from
1235      * destination to address list, and whether to stop before we reach the
1236      * end of that list.
1237      */
1238 
1239     /*
1240      * With LMTP we have direct-to-host delivery only. The destination may
1241      * have multiple IP addresses.
1242      */
1243     if (!smtp_mode) {
1244 	if (strncmp(destination, "unix:", 5) == 0) {
1245 	    smtp_connect_local(state, destination + 5);
1246 	} else {
1247 	    if (strncmp(destination, "inet:", 5) == 0)
1248 		destination += 5;
1249 	    smtp_connect_inet(state, destination, var_smtp_tcp_port);
1250 	}
1251     }
1252 
1253     /*
1254      * XXX We don't add support for "unix:" or "inet:" prefixes in SMTP
1255      * destinations, because that would break compatibility with existing
1256      * Postfix configurations that have a host with such a name.
1257      */
1258     else {
1259 	smtp_connect_inet(state, destination, var_smtp_tcp_port);
1260     }
1261 
1262     /*
1263      * We still need to bounce or defer some left-over recipients: either
1264      * (SMTP) mail loops or some server was unavailable.
1265      *
1266      * We could avoid this (and the "final server" complexity) by keeping one
1267      * DSN structure per recipient in memory, by updating those in-memory
1268      * structures with each delivery attempt, and by always flushing all
1269      * deferred recipients at the end. We'd probably still want to bounce
1270      * recipients immediately, so we'd end up with another chunk of code for
1271      * defer logging only.
1272      */
1273     if (SMTP_RCPT_LEFT(state) > 0) {
1274 	state->misc_flags |= SMTP_MISC_FLAG_FINAL_SERVER;	/* XXX */
1275 	smtp_sess_fail(state);
1276 
1277 	/*
1278 	 * Sanity check. Don't silently lose recipients.
1279 	 */
1280 	smtp_rcpt_cleanup(state);
1281 	if (SMTP_RCPT_LEFT(state) > 0)
1282 	    msg_panic("smtp_connect: left-over recipients");
1283     }
1284     return (state->status);
1285 }
1286