#ifdef SUPPORT_PROXY
-/*************************************************
-* Restore socket timeout to previous value *
-*************************************************/
-/* If the previous value was successfully retrieved, restore
-it before returning control to the non-proxy routines
-
-Arguments: fd - File descriptor for input
- get_ok - Successfully retrieved previous values
- tvtmp - Time struct with previous values
- vslen - Length of time struct
-Returns: none
-*/
-static void
-restore_socket_timeout(int fd, int get_ok, struct timeval * tvtmp, socklen_t vslen)
-{
-if (get_ok == 0)
- (void) setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, CS tvtmp, vslen);
-}
-
/*************************************************
* Check if host is required proxy host *
*************************************************/
while (capacity > 0)
{
- do { ret = read(fd, to, 1); } while (ret == -1 && errno == EINTR);
+ do { ret = read(fd, to, 1); } while (ret == -1 && errno == EINTR && !had_command_timeout);
if (ret == -1)
return -1;
have++;
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;
-struct timeval tvtmp;
socklen_t vslen = sizeof(struct timeval);
BOOL yield = FALSE;
-/* Save current socket timeout values */
-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;
-if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, CS &tv, sizeof(tv)) < 0)
- goto bad;
+os_non_restarting_signal(SIGALRM, command_timeout_handler);
+ALARM(proxy_protocol_timeout);
do
{
immediately with TLS handshake. */
ret = read(fd, &hdr, PROXY_INITIAL_READ);
}
- while (ret == -1 && errno == EINTR);
+ while (ret == -1 && errno == EINTR && !had_command_timeout);
if (ret == -1)
goto proxyfail;
do
{
retmore = read(fd, (uschar*)&hdr + ret, PROXY_V2_HEADER_SIZE - PROXY_INITIAL_READ);
- } while (retmore == -1 && errno == EINTR);
+ } while (retmore == -1 && errno == EINTR && !had_command_timeout);
if (retmore == -1)
goto proxyfail;
ret += retmore;
do
{
retmore = read(fd, (uschar*)&hdr + ret, size-ret);
- } while (retmore == -1 && errno == EINTR);
+ } while (retmore == -1 && errno == EINTR && !had_command_timeout);
if (retmore == -1)
goto proxyfail;
ret += retmore;
should cause a synchronization failure */
proxyfail:
- restore_socket_timeout(fd, get_ok, &tvtmp, vslen);
+ DEBUG(D_receive) if (had_command_timeout)
+ debug_printf("Timeout while reading proxy header\n");
bad:
if (yield)
debug_printf("Failure to extract proxied host, only QUIT allowed\n");
}
+ALARM(0);
return;
}
#endif
if (getsockopt(fileno(smtp_out), IPPROTO_TCP, TCP_FASTOPEN, &is_fastopen, &len) == 0)
{
- if (is_fastopen)
+ if (is_fastopen)
{
DEBUG(D_receive)
debug_printf("TFO mode connection (TCP_FASTOPEN getsockopt)\n");
if (smtp_batched_input) return TRUE;
/* If valid Proxy Protocol source is connecting, set up session.
- * Failure will not allow any SMTP function other than QUIT. */
+Failure will not allow any SMTP function other than QUIT. */
#ifdef SUPPORT_PROXY
proxy_session = FALSE;
setup_proxy_protocol_host();
#endif
+#ifdef TCP_QUICKACK /* Avoid pure-ACKs while in tls protocol pingpong phase */
+(void) setsockopt(fileno(smtp_in), IPPROTO_TCP, TCP_QUICKACK,
+ US &off, sizeof(off));
+#endif
+
/* Start up TLS if tls_on_connect is set. This is for supporting the legacy
smtps port for use with older style SSL MTAs. */
#ifndef DISABLE_TLS
- if (tls_in.on_connect)
- {
- if (tls_server_start(&user_msg) != OK)
- return smtp_log_tls_fail(user_msg);
- cmd_list[CMD_LIST_TLS_AUTH].is_mail_cmd = TRUE;
- }
+if (tls_in.on_connect)
+ {
+ if (tls_server_start(&user_msg) != OK)
+ return smtp_log_tls_fail(user_msg);
+ cmd_list[CMD_LIST_TLS_AUTH].is_mail_cmd = TRUE;
+ }
#endif
/* Run the connect ACL if it exists */
log_write(0, LOG_MAIN|LOG_PANIC, "ACL for QUIT returned ERROR: %s",
*log_msgp);
-#ifdef TCP_CORK
-(void) setsockopt(fileno(smtp_out), IPPROTO_TCP, TCP_CORK, US &on, sizeof(on));
+#ifdef EXIM_TCP_CORK
+(void) setsockopt(fileno(smtp_out), IPPROTO_TCP, EXIM_TCP_CORK, US &on, sizeof(on));
#endif
if (*user_msgp)
if (smtp_batched_input) return smtp_setup_batch_msg();
+#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
+
/* Deal with SMTP commands. This loop is exited by setting done to a POSITIVE
value. The values are 2 larger than the required yield of the function. */
}
#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(
#ifndef DISABLE_PIPE_CONNECT
!fl.pipe_connect_acceptable,
/* If not serializing, do the exec right away. Otherwise, fork down
into another process. */
- if ( !smtp_etrn_serialize
+ if ( !smtp_etrn_serialize
|| (pid = exim_fork(US"etrn-serialised-command")) == 0)
{
DEBUG(D_exec) debug_print_argv(argv);
g = string_append(g, 2, US";\n\tauth=pass (", sender_host_auth_pubname);
-if (Ustrcmp(sender_host_auth_pubname, "tls") != 0)
- g = string_append(g, 2, US") smtp.auth=", authenticated_id);
-else if (authenticated_id)
- g = string_append(g, 2, US") x509.auth=", authenticated_id);
+if (Ustrcmp(sender_host_auth_pubname, "tls") == 0)
+ g = authenticated_id
+ ? string_append(g, 2, US") x509.auth=", authenticated_id)
+ : string_cat(g, US") reason=x509.auth");
else
- g = string_catn(g, US") reason=x509.auth", 17);
+ g = authenticated_id
+ ? string_append(g, 2, US") smtp.auth=", authenticated_id)
+ : string_cat(g, US", no id saved)");
if (authenticated_sender)
g = string_append(g, 2, US" smtp.mailfrom=", authenticated_sender);