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