git://git.exim.org
/
exim.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
CHUNKING: pipeline data right after the BDAT command
[exim.git]
/
src
/
src
/
smtp_out.c
diff --git
a/src/src/smtp_out.c
b/src/src/smtp_out.c
index cd3906fc0c439dcb8d4ab058543ebe4e6c315b3f..7ade9ba6763014d2c988b3e6b5668f51a74f10f2 100644
(file)
--- a/
src/src/smtp_out.c
+++ b/
src/src/smtp_out.c
@@
-166,7
+166,7
@@
if ((sock = ip_socket(SOCK_STREAM, host_af)) < 0) return -1;
if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, US &on, sizeof(on)))
HDEBUG(D_transport|D_acl|D_v)
if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, US &on, sizeof(on)))
HDEBUG(D_transport|D_acl|D_v)
- debug_printf("failed to set NODELAY: %s ", strerror(errno));
+ debug_printf
_indent
("failed to set NODELAY: %s ", strerror(errno));
/* 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. */
/* 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. */
@@
-174,10
+174,10
@@
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)
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);
+ debug_printf
_indent
("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)
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));
+ debug_printf
_indent
("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 &&
/* 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 &&
@@
-196,7
+196,7
@@
if (interface && ip_bind(sock, host_af, interface, 0) < 0)
{
save_errno = errno;
HDEBUG(D_transport|D_acl|D_v)
{
save_errno = errno;
HDEBUG(D_transport|D_acl|D_v)
- debug_printf("unable to bind outgoing SMTP call to %s: %s", interface,
+ debug_printf
_indent
("unable to bind outgoing SMTP call to %s: %s", interface,
strerror(errno));
}
strerror(errno));
}
@@
-212,7
+212,7
@@
if (save_errno != 0)
{
HDEBUG(D_transport|D_acl|D_v)
{
{
HDEBUG(D_transport|D_acl|D_v)
{
- debug_printf("failed: %s", CUstrerror(save_errno));
+ debug_printf
_indent
("failed: %s", CUstrerror(save_errno));
if (save_errno == ETIMEDOUT)
debug_printf(" (timeout=%s)", readconf_printtime(timeout));
debug_printf("\n");
if (save_errno == ETIMEDOUT)
debug_printf(" (timeout=%s)", readconf_printtime(timeout));
debug_printf("\n");
@@
-228,7
+228,7
@@
else
{
union sockaddr_46 interface_sock;
EXIM_SOCKLEN_T size = sizeof(interface_sock);
{
union sockaddr_46 interface_sock;
EXIM_SOCKLEN_T size = sizeof(interface_sock);
- HDEBUG(D_transport|D_acl|D_v) debug_printf("connected\n");
+ HDEBUG(D_transport|D_acl|D_v) debug_printf
_indent
("connected\n");
if (getsockname(sock, (struct sockaddr *)(&interface_sock), &size) == 0)
sending_ip_address = host_ntoa(-1, &interface_sock, NULL, &sending_port);
else
if (getsockname(sock, (struct sockaddr *)(&interface_sock), &size) == 0)
sending_ip_address = host_ntoa(-1, &interface_sock, NULL, &sending_port);
else
@@
-280,7
+280,7
@@
smtp_transport_options_block * ob =
if (host->port != PORT_NONE)
{
HDEBUG(D_transport|D_acl|D_v)
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,
+ debug_printf
_indent
("Transport port=%d replaced by host-specific port=%d\n", port,
host->port);
port = host->port;
}
host->port);
port = host->port;
}
@@
-295,7
+295,7
@@
HDEBUG(D_transport|D_acl|D_v)
#ifdef SUPPORT_SOCKS
if (ob->socks_proxy) s = string_sprintf("%svia proxy ", s);
#endif
#ifdef SUPPORT_SOCKS
if (ob->socks_proxy) s = string_sprintf("%svia proxy ", s);
#endif
- debug_printf("Connecting to %s %s%s... ", host->name, callout_address, s);
+ debug_printf
_indent
("Connecting to %s %s%s... ", host->name, callout_address, s);
}
/* Create and connect the socket */
}
/* Create and connect the socket */
@@
-319,27
+319,36
@@
pipelining.
Argument:
outblock the SMTP output block
Argument:
outblock the SMTP output block
+ mode more-expected, or plain
Returns: TRUE if OK, FALSE on error, with errno set
*/
static BOOL
Returns: TRUE if OK, FALSE on error, with errno set
*/
static BOOL
-flush_buffer(smtp_outblock *
outblock
)
+flush_buffer(smtp_outblock *
outblock, int mode
)
{
int rc;
int n = outblock->ptr - outblock->buffer;
{
int rc;
int n = outblock->ptr - outblock->buffer;
-HDEBUG(D_transport|D_acl) debug_printf("cmd buf flush %d bytes\n", n);
+HDEBUG(D_transport|D_acl) debug_printf_indent("cmd buf flush %d bytes%s\n", n,
+ mode == SCMD_MORE ? " (with MORE annotation)" : "");
+
#ifdef SUPPORT_TLS
if (tls_out.active == outblock->sock)
rc = tls_write(FALSE, outblock->buffer, n);
else
#endif
#ifdef SUPPORT_TLS
if (tls_out.active == outblock->sock)
rc = tls_write(FALSE, outblock->buffer, n);
else
#endif
- rc = send(outblock->sock, outblock->buffer, n, 0);
+ rc = send(outblock->sock, outblock->buffer, n,
+#ifdef MSG_MORE
+ mode == SCMD_MORE ? MSG_MORE : 0
+#else
+ 0
+#endif
+ );
if (rc <= 0)
{
if (rc <= 0)
{
- HDEBUG(D_transport|D_acl) debug_printf("send failed: %s\n", strerror(errno));
+ HDEBUG(D_transport|D_acl) debug_printf
_indent
("send failed: %s\n", strerror(errno));
return FALSE;
}
return FALSE;
}
@@
-359,7
+368,7
@@
any error message.
Arguments:
outblock contains buffer for pipelining, and socket
Arguments:
outblock contains buffer for pipelining, and socket
- noflush if TRUE, save the command in the output buffer, for pipelining
+ mode buffer, write-with-more-likely, write
format a format, starting with one of
of HELO, MAIL FROM, RCPT TO, DATA, ".", or QUIT.
If NULL, flush pipeline buffer only.
format a format, starting with one of
of HELO, MAIL FROM, RCPT TO, DATA, ".", or QUIT.
If NULL, flush pipeline buffer only.
@@
-371,7
+380,7
@@
Returns: 0 if command added to pipelining buffer, with nothing transmitted
*/
int
*/
int
-smtp_write_command(smtp_outblock *
outblock, BOOL noflush
, const char *format, ...)
+smtp_write_command(smtp_outblock *
outblock, int mode
, const char *format, ...)
{
int count;
int rc = 0;
{
int count;
int rc = 0;
@@
-393,7
+402,7
@@
if (format)
if (count > outblock->buffersize - (outblock->ptr - outblock->buffer))
{
rc = outblock->cmd_count; /* flush resets */
if (count > outblock->buffersize - (outblock->ptr - outblock->buffer))
{
rc = outblock->cmd_count; /* flush resets */
- if (!flush_buffer(outblock)) return -1;
+ if (!flush_buffer(outblock
, SCMD_FLUSH
)) return -1;
}
Ustrncpy(CS outblock->ptr, big_buffer, count);
}
Ustrncpy(CS outblock->ptr, big_buffer, count);
@@
-420,13
+429,13
@@
if (format)
while (*p != 0) *p++ = '*';
}
while (*p != 0) *p++ = '*';
}
- HDEBUG(D_transport|D_acl|D_v) debug_printf(" SMTP>> %s\n", big_buffer);
+ HDEBUG(D_transport|D_acl|D_v) debug_printf
_indent
(" SMTP>> %s\n", big_buffer);
}
}
-if (
!noflush
)
+if (
mode != SCMD_BUFFER
)
{
rc += outblock->cmd_count; /* flush resets */
{
rc += outblock->cmd_count; /* flush resets */
- if (!flush_buffer(outblock)) return -1;
+ if (!flush_buffer(outblock
, mode
)) return -1;
}
return rc;
}
return rc;
@@
-498,15
+507,20
@@
for (;;)
/* Need to read a new input packet. */
/* Need to read a new input packet. */
- rc = ip_recv(sock, inblock->buffer, inblock->buffersize, timeout);
- if (rc <= 0) break;
+ if((rc = ip_recv(sock, inblock->buffer, inblock->buffersize, timeout)) <= 0)
+ {
+ DEBUG(D_deliver|D_transport|D_acl)
+ debug_printf_indent(errno ? " SMTP(%s)<<\n" : " SMTP(closed)<<\n",
+ strerror(errno));
+ break;
+ }
/* Another block of data has been successfully read. Set up the pointers
and let the loop continue. */
ptrend = inblock->ptrend = inblock->buffer + rc;
ptr = inblock->buffer;
/* Another block of data has been successfully read. Set up the pointers
and let the loop continue. */
ptrend = inblock->ptrend = inblock->buffer + rc;
ptr = inblock->buffer;
- DEBUG(D_transport|D_acl) debug_printf("read response data: size=%d\n", rc);
+ DEBUG(D_transport|D_acl) debug_printf
_indent
("read response data: size=%d\n", rc);
}
/* Get here if there has been some kind of recv() error; errno is set, but we
}
/* Get here if there has been some kind of recv() error; errno is set, but we
@@
-559,7
+573,7
@@
for (;;)
return FALSE;
HDEBUG(D_transport|D_acl|D_v)
return FALSE;
HDEBUG(D_transport|D_acl|D_v)
- debug_printf(" %s %s\n", (ptr == buffer)? "SMTP<<" : " ", ptr);
+ debug_printf
_indent
(" %s %s\n", (ptr == buffer)? "SMTP<<" : " ", ptr);
/* Check the format of the response: it must start with three digits; if
these are followed by a space or end of line, the response is complete. If
/* Check the format of the response: it must start with three digits; if
these are followed by a space or end of line, the response is complete. If