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