X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fsrc%2Fsmtp_out.c;h=0fa4ccd4846c8ee722b39822cbdded3f6eeaf215;hb=b1b05573117d62c3b95d854d8ac5a447df19e82e;hp=2caa775fc4e41645566d5ec547403004ff0d8d1c;hpb=8e669ac162fe3b1040297f1d021de10778dce9d9;p=user%2Fhenk%2Fcode%2Fexim.git diff --git a/src/src/smtp_out.c b/src/src/smtp_out.c index 2caa775fc..0fa4ccd48 100644 --- a/src/src/smtp_out.c +++ b/src/src/smtp_out.c @@ -1,10 +1,8 @@ -/* $Cambridge: exim/src/src/smtp_out.c,v 1.4 2005/02/17 11:58:26 ph10 Exp $ */ - /************************************************* * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2005 */ +/* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ /* A number of functions for driving outgoing SMTP calls. */ @@ -155,26 +153,31 @@ 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). In other cases, the default passed as an argument is used. +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 + 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 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) + int timeout, BOOL keepalive, const uschar *dscp) { int on = 1; int save_errno = 0; +int dscp_value; +int dscp_level; +int dscp_option; int sock; if (host->port != PORT_NONE) @@ -184,6 +187,7 @@ if (host->port != PORT_NONE) host->port); port = host->port; } +else host->port = port; /* Set the port actually used */ HDEBUG(D_transport|D_acl|D_v) { @@ -202,6 +206,25 @@ if ((sock = ip_socket(SOCK_STREAM, host_af)) < 0) return -1; setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (uschar *)(&on), sizeof(on)); +/* Set DSCP value, if we can. For now, if we fail to set the value, we don't +bomb out, just log it and continue in default traffic class. */ + +if (dscp && dscp_lookup(dscp, host_af, &dscp_level, &dscp_option, &dscp_value)) + { + HDEBUG(D_transport|D_acl|D_v) + debug_printf("DSCP \"%s\"=%x ", dscp, dscp_value); + if (setsockopt(sock, dscp_level, dscp_option, &dscp_value, sizeof(dscp_value)) < 0) + HDEBUG(D_transport|D_acl|D_v) + debug_printf("failed to set DSCP: %s ", strerror(errno)); + /* If the kernel supports IPv4 and IPv6 on an IPv6 socket, we need to set the + 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. */ @@ -230,7 +253,7 @@ if (save_errno != 0) debug_printf(" (timeout=%s)", readconf_printtime(timeout)); debug_printf("\n"); } - close(sock); + (void)close(sock); errno = save_errno; return -1; } @@ -239,7 +262,18 @@ if (save_errno != 0) else { + union sockaddr_46 interface_sock; + EXIM_SOCKLEN_T size = sizeof(interface_sock); HDEBUG(D_transport|D_acl|D_v) debug_printf("connected\n"); + if (getsockname(sock, (struct sockaddr *)(&interface_sock), &size) == 0) + sending_ip_address = host_ntoa(-1, &interface_sock, NULL, &sending_port); + else + { + log_write(0, LOG_MAIN | ((errno == ECONNRESET)? 0 : LOG_PANIC), + "getsockname() failed: %s", strerror(errno)); + close(sock); + return -1; + } if (keepalive) ip_keepalive(sock, host->address, TRUE); return sock; } @@ -266,8 +300,8 @@ flush_buffer(smtp_outblock *outblock) int rc; #ifdef SUPPORT_TLS -if (tls_active == outblock->sock) - rc = tls_write(outblock->buffer, outblock->ptr - outblock->buffer); +if (tls_out.active == outblock->sock) + rc = tls_write(FALSE, outblock->buffer, outblock->ptr - outblock->buffer); else #endif @@ -305,7 +339,7 @@ Returns: 0 if command added to pipelining buffer, with nothing transmitted */ int -smtp_write_command(smtp_outblock *outblock, BOOL noflush, char *format, ...) +smtp_write_command(smtp_outblock *outblock, BOOL noflush, const char *format, ...) { int count; int rc = 0;