Returns: none
*/
static void
-restore_socket_timeout(int fd, int get_ok, struct timeval tvtmp, socklen_t vslen)
+restore_socket_timeout(int fd, int get_ok, struct timeval * tvtmp, socklen_t vslen)
{
if (get_ok == 0)
- setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tvtmp, vslen);
+ (void) setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, CS tvtmp, vslen);
}
/*************************************************
includes an incorrect number of spaces separating args.
Arguments: none
-Returns: int
+Returns: Boolean success
*/
static BOOL
struct sockaddr_in6 tmpaddr6;
int get_ok = 0;
-int size, ret, fd;
+int size, ret;
+int fd = fileno(smtp_in);
const char v2sig[12] = "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A";
uschar *iptype; /* To display debug info */
struct timeval tv;
-socklen_t vslen = 0;
struct timeval tvtmp;
-
-vslen = sizeof(struct timeval);
-
-fd = fileno(smtp_in);
+socklen_t vslen = sizeof(struct timeval);
/* Save current socket timeout values */
-get_ok = getsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tvtmp,
- &vslen);
+get_ok = getsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, CS &tvtmp, &vslen);
/* Proxy Protocol host must send header within a short time
(default 3 seconds) or it's considered invalid */
tv.tv_sec = PROXY_NEGOTIATION_TIMEOUT_SEC;
tv.tv_usec = PROXY_NEGOTIATION_TIMEOUT_USEC;
-setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,
- sizeof(struct timeval));
+if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, CS &tv, sizeof(tv)) < 0)
+ return FALSE;
do
{
while (ret == -1 && errno == EINTR);
if (ret == -1)
- {
- restore_socket_timeout(fd, get_ok, tvtmp, vslen);
- return (errno == EAGAIN) ? 0 : ERRNO_PROXYFAIL;
- }
+ goto proxyfail;
if (ret >= 16 &&
memcmp(&hdr.v2, v2sig, 12) == 0)
if (!string_is_ip_address(US tmpip,NULL))
{
DEBUG(D_receive) debug_printf("Invalid %s source IP\n", iptype);
- return ERRNO_PROXYFAIL;
+ goto proxyfail;
}
proxy_local_address = sender_host_address;
sender_host_address = string_copy(US tmpip);
if (!string_is_ip_address(US tmpip,NULL))
{
DEBUG(D_receive) debug_printf("Invalid %s dest port\n", iptype);
- return ERRNO_PROXYFAIL;
+ goto proxyfail;
}
proxy_external_address = string_copy(US tmpip);
tmpport = ntohs(hdr.v2.addr.ip4.dst_port);
if (!string_is_ip_address(US tmpip6,NULL))
{
DEBUG(D_receive) debug_printf("Invalid %s source IP\n", iptype);
- return ERRNO_PROXYFAIL;
+ goto proxyfail;
}
proxy_local_address = sender_host_address;
sender_host_address = string_copy(US tmpip6);
if (!string_is_ip_address(US tmpip6,NULL))
{
DEBUG(D_receive) debug_printf("Invalid %s dest port\n", iptype);
- return ERRNO_PROXYFAIL;
+ goto proxyfail;
}
proxy_external_address = string_copy(US tmpip6);
tmpport = ntohs(hdr.v2.addr.ip6.dst_port);
}
proxyfail:
-restore_socket_timeout(fd, get_ok, tvtmp, vslen);
+restore_socket_timeout(fd, get_ok, &tvtmp, vslen);
/* Don't flush any potential buffer contents. Any input should cause a
synchronization failure */
return FALSE;
done:
-restore_socket_timeout(fd, get_ok, tvtmp, vslen);
+restore_socket_timeout(fd, get_ok, &tvtmp, vslen);
DEBUG(D_receive)
debug_printf("Valid %s sender from Proxy Protocol header\n", iptype);
return proxy_session;
uschar *
smtp_get_connection_info(void)
{
-uschar *hostname = (sender_fullhost == NULL)?
- sender_host_address : sender_fullhost;
+const uschar * hostname = sender_fullhost
+ ? sender_fullhost : sender_host_address;
if (host_checking)
return string_sprintf("SMTP connection from %s", hostname);
proxy_session = FALSE;
proxy_session_failed = FALSE;
if (check_proxy_protocol_host())
- if (setup_proxy_protocol_host() == FALSE)
+ if (!setup_proxy_protocol_host())
{
proxy_session_failed = TRUE;
DEBUG(D_receive)
}
#endif
+#ifdef TCP_QUICKACK
+ if (smtp_in) /* Avoid pure-ACKs while in cmd pingpong phase */
+ (void) setsockopt(fileno(smtp_in), IPPROTO_TCP, TCP_QUICKACK,
+ US &off, sizeof(off));
+#endif
+
switch(smtp_read_command(TRUE))
{
/* The AUTH command is not permitted to occur inside a transaction, and may
there may be a delay in this, re-check for a synchronization error
afterwards, unless pipelining was advertised. */
- if (recipients_discarded) rc = DISCARD; else
- {
- rc = acl_check(ACL_WHERE_RCPT, recipient, acl_smtp_rcpt, &user_msg,
- &log_msg);
- if (rc == OK && !pipelining_advertised && !check_sync())
+ if (recipients_discarded)
+ rc = DISCARD;
+ else
+ if ( (rc = acl_check(ACL_WHERE_RCPT, recipient, acl_smtp_rcpt, &user_msg,
+ &log_msg)) == OK
+ && !pipelining_advertised && !check_sync())
goto SYNC_FAILURE;
- }
/* The ACL was happy */
if (rc == OK)
{
- if (user_msg == NULL) smtp_printf("250 Accepted\r\n");
- else smtp_user_msg(US"250", user_msg);
+ if (user_msg)
+ smtp_user_msg(US"250", user_msg);
+ else
+ smtp_printf("250 Accepted\r\n");
receive_add_recipient(recipient, -1);
/* Set the dsn flags in the recipients_list */
else if (rc == DISCARD)
{
- if (user_msg == NULL) smtp_printf("250 Accepted\r\n");
- else smtp_user_msg(US"250", user_msg);
+ if (user_msg)
+ smtp_user_msg(US"250", user_msg);
+ else
+ smtp_printf("250 Accepted\r\n");
rcpt_fail_count++;
discarded = TRUE;
log_write(0, LOG_MAIN|LOG_REJECT, "%s F=<%s> RCPT %s: "
}
if (chunking_state > CHUNKING_OFFERED)
- { /* No predata ACL or go-ahead output for BDAT */
- rc = OK;
- }
+ rc = OK; /* No predata ACL or go-ahead output for BDAT */
else
{
/* If there is an ACL, re-check the synchronization afterwards, since the
"354 Enter message, ending with \".\" on a line by itself\r\n");
}
+#ifdef TCP_QUICKACK
+ if (smtp_in) /* all ACKs needed to ramp window up for bulk data */
+ (void) setsockopt(fileno(smtp_in), IPPROTO_TCP, TCP_QUICKACK,
+ US &on, sizeof(on));
+#endif
done = 3;
message_ended = END_NOTENDED; /* Indicate in middle of data */