X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/3634fc257bd0667daef14d72005cd87c735bbb24..e9477a08d2d1f528b1f127f1d563d77e2cf24a22:/src/src/smtp_out.c diff --git a/src/src/smtp_out.c b/src/src/smtp_out.c index d6cfbba7d..530fcfec7 100644 --- a/src/src/smtp_out.c +++ b/src/src/smtp_out.c @@ -164,16 +164,25 @@ Arguments: 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) + int timeout, BOOL keepalive, const uschar *dscp +#ifdef EXPERIMENTAL_EVENT + , uschar * event +#endif + ) { int on = 1; int save_errno = 0; +int dscp_value; +int dscp_level; +int dscp_option; int sock; if (host->port != PORT_NONE) @@ -194,6 +203,13 @@ HDEBUG(D_transport|D_acl|D_v) host->address, port, interface); } +#ifdef EXPERIMENTAL_EVENT + deliver_host_address = host->address; + deliver_host_port = port; + if (event_raise(event, US"tcp:connect", NULL)) return -1; + /* Logging? Debug? */ +#endif + /* Create the socket */ if ((sock = ip_socket(SOCK_STREAM, host_af)) < 0) return -1; @@ -202,6 +218,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. */ @@ -277,8 +312,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 @@ -329,6 +364,10 @@ if (!string_vformat(big_buffer, big_buffer_size, CS format, ap)) va_end(ap); count = Ustrlen(big_buffer); +if (count > outblock->buffersize) + log_write(0, LOG_MAIN|LOG_PANIC_DIE, "overlong write_command in outgoing " + "SMTP"); + if (count > outblock->buffersize - (outblock->ptr - outblock->buffer)) { rc = outblock->cmd_count; /* flush resets */