OpenSSL: tidy DH and ECDH param setup
[exim.git] / src / src / transport.c
index 39b8c411abe688239360b08557af2f99870c3a00..ef523657ea05b36f122ade55b8c838a22e9d2a50 100644 (file)
@@ -3,7 +3,7 @@
 *************************************************/
 
 /* Copyright (c) University of Cambridge 1995 - 2018 */
-/* Copyright (c) The Exim Maintainers 2020 */
+/* Copyright (c) The Exim Maintainers 2020 - 2021 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 /* General functions concerned with transportation, and generic options for all
@@ -253,7 +253,6 @@ for (int i = 0; i < 100; i++)
 
   for(;;)
     {
-    fd_set fds;
     /* This code makes use of alarm() in order to implement the timeout. This
     isn't a very tidy way of doing things. Using non-blocking I/O with select()
     provides a neater approach. However, I don't know how to do this when TLS is
@@ -281,8 +280,7 @@ for (int i = 0; i < 100; i++)
     if (rc >= 0 || errno != ENOTCONN || connretry <= 0)
       break;
 
-    FD_ZERO(&fds); FD_SET(fd, &fds);
-    select(fd+1, NULL, &fds, NULL, NULL);      /* could set timout? */
+    poll_one_fd(fd, POLLOUT, -1);              /* could set timeout? retval check? */
     connretry--;
     }
 
@@ -959,10 +957,10 @@ if (!(tctx->options & topt_no_headers))
 
   if (tctx->options & topt_add_return_path)
     {
-    uschar buffer[ADDRESS_MAXLENGTH + 20];
-    int n = sprintf(CS buffer, "Return-path: <%.*s>\n", ADDRESS_MAXLENGTH,
-      return_path);
-    if (!write_chunk(tctx, buffer, n)) goto bad;
+    int n;
+    uschar * s = string_sprintf("Return-path: <%.*s>\n%n",
+                          EXIM_EMAILADDR_MAX, return_path, &n);
+    if (!write_chunk(tctx, s, n)) goto bad;
     }
 
   /* Add envelope-to: if requested */
@@ -1398,7 +1396,7 @@ if (write_pid > 0)
         yield = FALSE;
        }
       else if (!ok)
-        {
+        {              /* Try to drain the pipe; read fails are don't care */
        int dummy = read(pfd[pipe_read], (void *)&save_errno, sizeof(int));
         dummy = read(pfd[pipe_read], (void *)&tctx->addr->more_errno, sizeof(int));
         dummy = read(pfd[pipe_read], (void *)&tctx->addr->delivery_time, sizeof(struct timeval));
@@ -1729,7 +1727,7 @@ while (1)
     {
     msgq[i].bKeep = TRUE;
 
-    Ustrncpy_nt(msgq[i].message_id, host_record->text + (i * MESSAGE_ID_LENGTH), 
+    Ustrncpy_nt(msgq[i].message_id, host_record->text + (i * MESSAGE_ID_LENGTH),
       MESSAGE_ID_LENGTH);
     msgq[i].message_id[MESSAGE_ID_LENGTH] = 0;
     }
@@ -1880,9 +1878,21 @@ void
 transport_do_pass_socket(const uschar *transport_name, const uschar *hostname,
   const uschar *hostaddress, uschar *id, int socket_fd)
 {
-int i = 27;
+int i = 13;
 const uschar **argv;
 
+#ifndef DISABLE_TLS
+if (smtp_peer_options & OPTION_TLS) i += 6;
+#endif
+#ifdef EXPERIMENTAL_ESMTP_LIMITS
+if (continue_limit_mail || continue_limit_rcpt || continue_limit_rcptdom)
+                                   i += 4;
+#endif
+if (queue_run_pid != (pid_t)0)     i += 3;
+#ifdef SUPPORT_SOCKS
+if (proxy_session)                 i += 5;
+#endif
+
 /* Set up the calling arguments; use the standard function for the basics,
 but we have a number of extras that may be added. */
 
@@ -1916,6 +1926,16 @@ if (smtp_peer_options & OPTION_TLS)
     argv[i++] = US"-MCT";
 #endif
 
+#ifdef EXPERIMENTAL_ESMTP_LIMITS
+if (continue_limit_rcpt || continue_limit_rcptdom)
+  {
+  argv[i++] = US"-MCL";
+  argv[i++] = string_sprintf("%u", continue_limit_mail);
+  argv[i++] = string_sprintf("%u", continue_limit_rcpt);
+  argv[i++] = string_sprintf("%u", continue_limit_rcptdom);
+  }
+#endif
+
 if (queue_run_pid != (pid_t)0)
   {
   argv[i++] = US"-MCQ";
@@ -1976,13 +1996,23 @@ Returns:          FALSE if fork fails; TRUE otherwise
 
 BOOL
 transport_pass_socket(const uschar *transport_name, const uschar *hostname,
-  const uschar *hostaddress, uschar *id, int socket_fd)
+  const uschar *hostaddress, uschar *id, int socket_fd
+#ifdef EXPERIMENTAL_ESMTP_LIMITS
+  , unsigned peer_limit_mail, unsigned peer_limit_rcpt, unsigned peer_limit_rcptdom
+#endif
+  )
 {
 pid_t pid;
 int status;
 
 DEBUG(D_transport) debug_printf("transport_pass_socket entered\n");
 
+#ifdef EXPERIMENTAL_ESMTP_LIMITS
+continue_limit_mail = peer_limit_mail;
+continue_limit_rcpt = peer_limit_rcpt;
+continue_limit_rcptdom = peer_limit_rcptdom;
+#endif
+
 if ((pid = exim_fork(US"continued-transport-interproc")) == 0)
   {
   /* Disconnect entirely from the parent process. If we are running in the
@@ -2247,12 +2277,12 @@ if (expand_arguments)
         }
 
       /* If we are not just able to replace the slot that contained
-       * $address_pipe (address_pipe_argcount == 1)
-       * We have to move the existing argv by address_pipe_argcount - 1
-       * Visually if address_pipe_argcount == 2:
-       * [argv 0][argv 1][argv 2($address_pipe)][argv 3][0]
-       * [argv 0][argv 1][ap_arg0][ap_arg1][old argv 3][0]
-       */
+      $address_pipe (address_pipe_argcount == 1)
+      We have to move the existing argv by address_pipe_argcount - 1
+      Visually if address_pipe_argcount == 2:
+      [argv 0][argv 1][argv 2($address_pipe)][argv 3][0]
+      [argv 0][argv 1][ap_arg0][ap_arg1][old argv 3][0] */
+
       if (address_pipe_argcount > 1)
         memmove(
           /* current position + additional args */
@@ -2264,15 +2294,12 @@ if (expand_arguments)
         );
 
       /* Now we fill in the slots we just moved argv out of
-       * [argv 0][argv 1][argv 2=pipeargv[0]][argv 3=pipeargv[1]][old argv 3][0]
-       */
+      [argv 0][argv 1][argv 2=pipeargv[0]][argv 3=pipeargv[1]][old argv 3][0] */
+
       for (int address_pipe_i = 0;
            address_pipe_argv[address_pipe_i] != US 0;
-           address_pipe_i++)
-        {
+           address_pipe_i++, argcount++)
         argv[i++] = address_pipe_argv[address_pipe_i];
-        argcount++;
-        }
 
       /* Subtract one since we replace $address_pipe */
       argcount--;