X-Git-Url: https://vcs.fsf.org/?p=exim.git;a=blobdiff_plain;f=src%2Fsrc%2Fsmtp_out.c;h=88dde8301fd694574388ec0ec14c36df827853fd;hp=530fcfec75687954629ba0d9471820191e290bc9;hb=055e2cb463e4e4adf2d9292a50ac274938f9a5ac;hpb=c1cc0506c3069a9d93d71321f9578150662ede91 diff --git a/src/src/smtp_out.c b/src/src/smtp_out.c index 530fcfec7..88dde8301 100644 --- a/src/src/smtp_out.c +++ b/src/src/smtp_out.c @@ -2,13 +2,14 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2009 */ +/* Copyright (c) University of Cambridge 1995 - 2015 */ /* See the file NOTICE for conditions of use and distribution. */ /* A number of functions for driving outgoing SMTP calls. */ #include "exim.h" +#include "transports/smtp.h" @@ -37,7 +38,7 @@ BOOL smtp_get_interface(uschar *istring, int host_af, address_item *addr, BOOL *changed, uschar **interface, uschar *msg) { -uschar *expint; +const uschar * expint; uschar *iface; int sep = 0; @@ -143,75 +144,26 @@ return TRUE; -/************************************************* -* Connect to remote host * -*************************************************/ - -/* Create a socket, and connect it to a remote host. IPv6 addresses are -detected by checking for a colon in the address. AF_INET6 is defined even on -non-IPv6 systems, to enable the code to be less messy. However, on such systems -host->address will always be an IPv4 address. - -The port field in the host item is used if it is set (usually router from SRV -records or elsewhere). In other cases, the default passed as an argument is -used, and the host item is updated with its value. - -Arguments: - host host item containing name and address (and sometimes port) - host_af AF_INET or AF_INET6 - port default remote port to connect to, in host byte order, for those - hosts whose port setting is PORT_NONE - interface outgoing interface address or NULL - timeout timeout value or 0 - keepalive TRUE to use keepalive - dscp DSCP value to assign to socket - event event expansion - -Returns: connected socket number, or -1 with errno set -*/ - int -smtp_connect(host_item *host, int host_af, int port, uschar *interface, - int timeout, BOOL keepalive, const uschar *dscp -#ifdef EXPERIMENTAL_EVENT - , uschar * event -#endif - ) +smtp_sock_connect(host_item * host, int host_af, int port, uschar * interface, + transport_instance * tb, int timeout) { -int on = 1; -int save_errno = 0; +smtp_transport_options_block * ob = + (smtp_transport_options_block *)tb->options_block; +const uschar * dscp = ob->dscp; int dscp_value; int dscp_level; int dscp_option; int sock; - -if (host->port != PORT_NONE) - { - HDEBUG(D_transport|D_acl|D_v) - debug_printf("Transport port=%d replaced by host-specific port=%d\n", port, - host->port); - port = host->port; - } -else host->port = port; /* Set the port actually used */ - -HDEBUG(D_transport|D_acl|D_v) - { - if (interface == NULL) - debug_printf("Connecting to %s [%s]:%d ... ",host->name,host->address,port); - else - debug_printf("Connecting to %s [%s]:%d from %s ... ", host->name, - host->address, port, interface); - } +int on = 1; +int save_errno = 0; #ifdef EXPERIMENTAL_EVENT - deliver_host_address = host->address; - deliver_host_port = port; - if (event_raise(event, US"tcp:connect", NULL)) return -1; - /* Logging? Debug? */ +deliver_host_address = host->address; +deliver_host_port = port; +if (event_raise(tb->event_action, US"tcp:connect", NULL)) return -1; #endif -/* Create the socket */ - if ((sock = ip_socket(SOCK_STREAM, host_af)) < 0) return -1; /* Set TCP_NODELAY; Exim does its own buffering. */ @@ -232,15 +184,13 @@ if (dscp && dscp_lookup(dscp, host_af, &dscp_level, &dscp_option, &dscp_value)) option for both; ignore failures here */ if (host_af == AF_INET6 && dscp_lookup(dscp, AF_INET, &dscp_level, &dscp_option, &dscp_value)) - { (void) setsockopt(sock, dscp_level, dscp_option, &dscp_value, sizeof(dscp_value)); - } } /* Bind to a specific interface if requested. Caller must ensure the interface is the same type (IPv4 or IPv6) as the outgoing address. */ -if (interface != NULL && ip_bind(sock, host_af, interface, 0) < 0) +if (interface && ip_bind(sock, host_af, interface, 0) < 0) { save_errno = errno; HDEBUG(D_transport|D_acl|D_v) @@ -286,11 +236,76 @@ else close(sock); return -1; } - if (keepalive) ip_keepalive(sock, host->address, TRUE); + if (ob->keepalive) ip_keepalive(sock, host->address, TRUE); return sock; } } +/************************************************* +* Connect to remote host * +*************************************************/ + +/* Create a socket, and connect it to a remote host. IPv6 addresses are +detected by checking for a colon in the address. AF_INET6 is defined even on +non-IPv6 systems, to enable the code to be less messy. However, on such systems +host->address will always be an IPv4 address. + +The port field in the host item is used if it is set (usually router from SRV +records or elsewhere). In other cases, the default passed as an argument is +used, and the host item is updated with its value. + +Arguments: + host host item containing name and address (and sometimes port) + host_af AF_INET or AF_INET6 + port default remote port to connect to, in host byte order, for those + hosts whose port setting is PORT_NONE + interface outgoing interface address or NULL + timeout timeout value or 0 + tb transport + +Returns: connected socket number, or -1 with errno set +*/ + +int +smtp_connect(host_item *host, int host_af, int port, uschar *interface, + int timeout, transport_instance * tb) +{ +#ifdef EXPERIMENTAL_SOCKS +smtp_transport_options_block * ob = + (smtp_transport_options_block *)tb->options_block; +#endif + +if (host->port != PORT_NONE) + { + HDEBUG(D_transport|D_acl|D_v) + debug_printf("Transport port=%d replaced by host-specific port=%d\n", port, + host->port); + port = host->port; + } +else host->port = port; /* Set the port actually used */ + +callout_address = string_sprintf("[%s]:%d", host->address, port); + +HDEBUG(D_transport|D_acl|D_v) + { + uschar * s = US" "; + if (interface) s = string_sprintf(" from %s ", interface); +#ifdef EXPERIMENTAL_SOCKS + if (ob->socks_proxy) s = string_sprintf("%svia proxy ", s); +#endif + debug_printf("Connecting to %s %s%s... ", host->name, callout_address, s); + } + +/* Create and connect the socket */ + +#ifdef EXPERIMENTAL_SOCKS +if (ob->socks_proxy) + return socks_sock_connect(host, host_af, port, interface, tb, timeout); +#endif + +return smtp_sock_connect(host, host_af, port, interface, tb, timeout); +} + /************************************************* * Flush outgoing command buffer * @@ -581,3 +596,5 @@ return buffer[0] == okdigit; } /* End of smtp_out.c */ +/* vi: aw ai sw=2 +*/