Proxy negotiation saves socket timeout values.
authorTodd Lyons <tlyons@exim.org>
Mon, 30 Dec 2013 23:02:21 +0000 (15:02 -0800)
committerTodd Lyons <tlyons@exim.org>
Mon, 30 Dec 2013 23:56:37 +0000 (15:56 -0800)
Rename proxy expansions conforming to Exim standards.
Update documentation to reflect rename.
Seperate restore socket function

doc/doc-txt/experimental-spec.txt
src/src/expand.c
src/src/globals.c
src/src/globals.h
src/src/receive.c
src/src/smtp_in.c

index 92790ae33a158bfd05fc748c0aafc0b32f16bb55..b80e02b4cfa2a6a89cf3381c3ebec5392c28a55f 100644 (file)
@@ -1066,28 +1066,28 @@ Proxy Protocol server at 192.168.1.2 will look like this:
 
 3. In the ACL's the following expansion variables are available.
 
-proxy_host     The src IP of the proxy server making the connection
-proxy_port     The src port the proxy server is using
-proxy_session  Boolean, yes/no, the connected host is required to use
-               Proxy Protocol.
+proxy_host_address  The src IP of the proxy server making the connection
+proxy_host_port     The src port the proxy server is using
+proxy_session       Boolean, yes/no, the connected host is required to use
+                    Proxy Protocol.
 
 There is no expansion for a failed proxy session, however you can detect
 it by checking if $proxy_session is true but $proxy_host is empty.  As
 an example, in my connect ACL, I have:
 
   warn    condition      = ${if and{ {bool{$proxy_session}} \
-                                     {eq{$proxy_host}{}} } }
+                                     {eq{$proxy_host_address}{}} } }
           log_message    = Failed required proxy protocol negotiation \
                            from $sender_host_name [$sender_host_address]
 
   warn    condition      = ${if and{ {bool{$proxy_session}} \
-                                     {!eq{$proxy_host}{}} } }
+                                     {!eq{$proxy_host_address}{}} } }
           # But don't log health probes from the proxy itself
-          condition      = ${if eq{$proxy_host}{$sender_host_address} \
+          condition      = ${if eq{$proxy_host_address}{$sender_host_address} \
                                 {false}{true}}
           log_message    = Successfully proxied from $sender_host_name \
                            [$sender_host_address] through proxy protocol \
-                           host $proxy_host
+                           host $proxy_host_address
 
 4. Runtime issues to be aware of:
    - Since the real connections are all coming from your proxy, and the
index 325b05178890d13bc544204155860d908cea090c..de52e600043a859e019e82ede88b729a32d49714 100644 (file)
@@ -559,8 +559,8 @@ static var_entry var_table[] = {
   { "pid",                 vtype_pid,         NULL },
   { "primary_hostname",    vtype_stringptr,   &primary_hostname },
 #ifdef EXPERIMENTAL_PROXY
-  { "proxy_host",          vtype_stringptr,   &proxy_host },
-  { "proxy_port",          vtype_int,         &proxy_port },
+  { "proxy_host_address",  vtype_stringptr,   &proxy_host_address },
+  { "proxy_host_port",     vtype_int,         &proxy_host_port },
   { "proxy_session",       vtype_bool,        &proxy_session },
 #endif
   { "prvscheck_address",   vtype_stringptr,   &prvscheck_address },
index ec6700df5fa5432a2b3bd41bc51bfd7fe4d1715d..1572461ec6e76ef70e88a77f2469ef168c6d3577 100644 (file)
@@ -919,8 +919,8 @@ uschar *process_log_path       = NULL;
 BOOL    prod_requires_admin    = TRUE;
 
 #ifdef EXPERIMENTAL_PROXY
-uschar *proxy_host             = US"";
-int     proxy_port             = 0;
+uschar *proxy_host_address     = US"";
+int     proxy_host_port        = 0;
 uschar *proxy_required_hosts   = US"";
 BOOL    proxy_session          = FALSE;
 BOOL    proxy_session_failed   = FALSE;
index 5661489a7b66d1ff0b9a14e8fcbc0a6256823809..bf54fb41fdcad439078bf746ca4894b57bd8a8ab 100644 (file)
@@ -594,8 +594,8 @@ extern uschar *process_log_path;       /* Alternate path */
 extern BOOL    prod_requires_admin;    /* TRUE if prodding requires admin */
 
 #ifdef EXPERIMENTAL_PROXY
-extern uschar *proxy_host;             /* IP of proxy server */
-extern int     proxy_port;             /* Port of proxy server */
+extern uschar *proxy_host_address;     /* IP of proxy server */
+extern int     proxy_host_port;        /* Port of proxy server */
 extern uschar *proxy_required_hosts;   /* Hostlist which (require) use proxy protocol */
 extern BOOL    proxy_session;          /* TRUE if receiving mail from valid proxy  */
 extern BOOL    proxy_session_failed;   /* TRUE if required proxy negotiation failed */
index 02db23f946fe501443314b1258f1ba6249533bed..0295b7e54ed9ef6bfd425239b424800f5f1d77f4 100644 (file)
@@ -3759,7 +3759,7 @@ if (prdr_requested)
 if (proxy_session &&
     (log_extra_selector & LX_proxy) != 0)
   {
-  s = string_append(s, &size, &sptr, 2, US" PRX=", proxy_host);
+  s = string_append(s, &size, &sptr, 2, US" PRX=", proxy_host_address);
   }
 #endif
 
index 144ad28a22e82fef88638a6fd5326eca8b130404..95c615e37f678a8909cfb4e59ce6f3c2f3cf92e4 100644 (file)
@@ -554,6 +554,25 @@ exim_exit(EXIT_FAILURE);
 
 
 #ifdef EXPERIMENTAL_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)
+  setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tvtmp, vslen);
+}
+
 /*************************************************
 *       Check if host is required proxy host     *
 *************************************************/
@@ -650,15 +669,25 @@ uschar *tmpip;
 const char v2sig[13] = "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A\x02";
 uschar *iptype;  /* To display debug info */
 struct timeval tv;
+int get_ok = 0;
+socklen_t vslen = 0;
+struct timeval tvtmp;
+
+vslen = sizeof(struct timeval);
 
 fd = fileno(smtp_in);
 
+/* Save current socket timeout values */
+get_ok = getsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&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));
+
 do
   {
   ret = recv(fd, &hdr, sizeof(hdr), MSG_PEEK);
@@ -666,7 +695,10 @@ do
   while (ret == -1 && errno == EINTR);
 
 if (ret == -1)
+  {
+  restore_socket_timeout(fd, get_ok, tvtmp, vslen);
   return (errno == EAGAIN) ? 0 : ERRNO_PROXYFAIL;
+  }
 
 if (ret >= 16 &&
     memcmp(&hdr.v2, v2sig, 13) == 0)
@@ -768,7 +800,7 @@ else if (ret >= 8 &&
       debug_printf("Proxied src arg is not an %s address\n", iptype);
     goto proxyfail;
     }
-  proxy_host = sender_host_address;
+  proxy_host_address = sender_host_address;
   sender_host_address = p;
   p = sp + 1;
   if ((sp = Ustrchr(p, ' ')) == NULL)
@@ -799,7 +831,7 @@ else if (ret >= 8 &&
       debug_printf("Proxied src port '%s' not an integer\n", p);
     goto proxyfail;
     }
-  proxy_port = sender_host_port;
+  proxy_host_port = sender_host_port;
   sender_host_port = tmp_port;
   p = sp + 1;
   if ((sp = Ustrchr(p, '\0')) == NULL)
@@ -826,11 +858,13 @@ else
   }
 
 proxyfail:
+restore_socket_timeout(fd, get_ok, tvtmp, vslen);
 /* Don't flush any potential buffer contents. Any input should cause a
 synchronization failure or we just don't want to speak SMTP to them */
 return FALSE;
 
 done:
+restore_socket_timeout(fd, get_ok, tvtmp, vslen);
 flush_input();
 DEBUG(D_receive)
   debug_printf("Valid %s sender from Proxy Protocol header\n",
@@ -839,8 +873,6 @@ return proxy_session;
 }
 #endif
 
-
-
 /*************************************************
 *           Read one command line                *
 *************************************************/