Initial keep-alive support for the client socket.
[privoxy.git] / loadcfg.c
index aeb409b..4942ca4 100644 (file)
--- a/loadcfg.c
+++ b/loadcfg.c
@@ -1,4 +1,4 @@
-const char loadcfg_rcs[] = "$Id: loadcfg.c,v 1.91 2009/03/09 17:29:08 fabiankeil Exp $";
+const char loadcfg_rcs[] = "$Id: loadcfg.c,v 1.98 2009/04/24 15:29:43 fabiankeil Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/loadcfg.c,v $
@@ -35,6 +35,30 @@ const char loadcfg_rcs[] = "$Id: loadcfg.c,v 1.91 2009/03/09 17:29:08 fabiankeil
  *
  * Revisions   :
  *    $Log: loadcfg.c,v $
+ *    Revision 1.98  2009/04/24 15:29:43  fabiankeil
+ *    Allow to limit the number of of client connections.
+ *
+ *    Revision 1.97  2009/04/17 11:45:19  fabiankeil
+ *    Replace HAVE_GETADDRINFO and HAVE_GETNAMEINFO macros
+ *    with HAVE_RFC2553 macro. Original patch by Petr Pisar.
+ *
+ *    Revision 1.96  2009/04/17 11:38:28  fabiankeil
+ *    Add and use parse_forwarder_address() to reduce code duplication.
+ *
+ *    Revision 1.95  2009/04/17 11:34:34  fabiankeil
+ *    Style cosmetics for the IPv6 code.
+ *
+ *    Revision 1.94  2009/04/17 11:27:49  fabiankeil
+ *    Petr Pisar's privoxy-3.0.12-ipv6-3.diff.
+ *
+ *    Revision 1.93  2009/03/18 21:46:26  fabiankeil
+ *    Revert the last commit as there's a better way.
+ *
+ *    Revision 1.92  2009/03/18 20:43:19  fabiankeil
+ *    Don't enable LOG_LEVEL_INFO by default and don't apply the user's
+ *    debug settings until the logfile has been opened (if there is one).
+ *    Patch submitted by Roland in #2624120.
+ *
  *    Revision 1.91  2009/03/09 17:29:08  fabiankeil
  *    As of r1.88, the show-status page can use a single line for
  *    warnings about ignored directives and the names of the ignored
@@ -626,6 +650,7 @@ static struct file_list *current_configfile = NULL;
 #define hash_listen_address              1255650842ul /* "listen-address" */
 #define hash_logdir                          422889ul /* "logdir" */
 #define hash_logfile                        2114766ul /* "logfile" */
+#define hash_max_client_connections      3595884446ul /* "max-client-connections" */
 #define hash_permit_access               3587953268ul /* "permit-access" */
 #define hash_proxy_info_url              3903079059ul /* "proxy-info-url" */
 #define hash_single_threaded             4250084780ul /* "single-threaded" */
@@ -777,9 +802,6 @@ struct configuration_spec * load_config(void)
    unsigned long linenum = 0;
    int i;
    char *logfile = NULL;
-#ifdef FEATURE_CONNECTION_KEEP_ALIVE
-   int keep_alive_timeout = DEFAULT_KEEP_ALIVE_TIMEOUT;
-#endif
 
    if (!check_file_changed(current_configfile, configfile, &fs))
    {
@@ -827,12 +849,16 @@ struct configuration_spec * load_config(void)
     * Set to defaults
     */
    config->multi_threaded            = 1;
-   config->hport                     = HADDR_PORT;
    config->buffer_limit              = 4096 * 1024;
    config->usermanual                = strdup(USER_MANUAL_URL);
    config->proxy_args                = strdup("");
    config->forwarded_connect_retries = 0;
+   config->max_client_connections    = 0;
    config->socket_timeout            = 300; /* XXX: Should be a macro. */
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+   config->keep_alive_timeout        = DEFAULT_KEEP_ALIVE_TIMEOUT;
+   config->feature_flags            &= ~RUNTIME_FEATURE_CONNECTION_KEEP_ALIVE;
+#endif
    config->feature_flags            &= ~RUNTIME_FEATURE_CGI_TOGGLE;
    config->feature_flags            &= ~RUNTIME_FEATURE_SPLIT_LARGE_FORMS;
    config->feature_flags            &= ~RUNTIME_FEATURE_ACCEPT_INTERCEPTED_REQUESTS;
@@ -1036,6 +1062,12 @@ struct configuration_spec * load_config(void)
                   break;
                }
             }
+#ifdef HAVE_RFC2553
+            else
+            {
+               cur_acl->wildcard_dst = 1;
+            }
+#endif /* def HAVE_RFC2553 */
 
             /*
              * Add it to the list.  Note we reverse the list to get the
@@ -1183,18 +1215,9 @@ struct configuration_spec * load_config(void)
 
             if (strcmp(p, ".") != 0)
             {
-               cur_fwd->forward_host = strdup(p);
-
-               if (NULL != (p = strchr(cur_fwd->forward_host, ':')))
-               {
-                  *p++ = '\0';
-                  cur_fwd->forward_port = atoi(p);
-               }
-
-               if (cur_fwd->forward_port <= 0)
-               {
-                  cur_fwd->forward_port = 8000;
-               }
+               cur_fwd->forward_port = 8000;
+               parse_forwarder_address(p, &cur_fwd->forward_host,
+                  &cur_fwd->forward_port);
             }
 
             /* Add to list. */
@@ -1245,19 +1268,12 @@ struct configuration_spec * load_config(void)
             /* Parse the SOCKS proxy host[:port] */
             p = vec[1];
 
+            /* XXX: This check looks like a bug. */
             if (strcmp(p, ".") != 0)
             {
-               cur_fwd->gateway_host = strdup(p);
-
-               if (NULL != (p = strchr(cur_fwd->gateway_host, ':')))
-               {
-                  *p++ = '\0';
-                  cur_fwd->gateway_port = atoi(p);
-               }
-               if (cur_fwd->gateway_port <= 0)
-               {
-                  cur_fwd->gateway_port = 1080;
-               }
+               cur_fwd->gateway_port = 1080;
+               parse_forwarder_address(p, &cur_fwd->gateway_host,
+                  &cur_fwd->gateway_port);
             }
 
             /* Parse the parent HTTP proxy host[:port] */
@@ -1265,18 +1281,9 @@ struct configuration_spec * load_config(void)
 
             if (strcmp(p, ".") != 0)
             {
-               cur_fwd->forward_host = strdup(p);
-
-               if (NULL != (p = strchr(cur_fwd->forward_host, ':')))
-               {
-                  *p++ = '\0';
-                  cur_fwd->forward_port = atoi(p);
-               }
-
-               if (cur_fwd->forward_port <= 0)
-               {
-                  cur_fwd->forward_port = 8000;
-               }
+               cur_fwd->forward_port = 8000;
+               parse_forwarder_address(p, &cur_fwd->forward_host,
+                  &cur_fwd->forward_port);
             }
 
             /* Add to list. */
@@ -1335,35 +1342,18 @@ struct configuration_spec * load_config(void)
             /* Parse the SOCKS proxy host[:port] */
             p = vec[1];
 
-            cur_fwd->gateway_host = strdup(p);
-
-            if (NULL != (p = strchr(cur_fwd->gateway_host, ':')))
-            {
-               *p++ = '\0';
-               cur_fwd->gateway_port = atoi(p);
-            }
-            if (cur_fwd->gateway_port <= 0)
-            {
-               cur_fwd->gateway_port = 1080;
-            }
+            cur_fwd->gateway_port = 1080;
+            parse_forwarder_address(p, &cur_fwd->gateway_host,
+               &cur_fwd->gateway_port);
 
             /* Parse the parent HTTP proxy host[:port] */
             p = vec[2];
 
             if (strcmp(p, ".") != 0)
             {
-               cur_fwd->forward_host = strdup(p);
-
-               if (NULL != (p = strchr(cur_fwd->forward_host, ':')))
-               {
-                  *p++ = '\0';
-                  cur_fwd->forward_port = atoi(p);
-               }
-
-               if (cur_fwd->forward_port <= 0)
-               {
-                  cur_fwd->forward_port = 8000;
-               }
+               cur_fwd->forward_port = 8000;
+               parse_forwarder_address(p, &cur_fwd->forward_host,
+                  &cur_fwd->forward_port);
             }
 
             /* Add to list. */
@@ -1402,7 +1392,7 @@ struct configuration_spec * load_config(void)
                if (0 <= timeout)
                {
                   config->feature_flags |= RUNTIME_FEATURE_CONNECTION_KEEP_ALIVE;
-                  keep_alive_timeout = timeout;
+                  config->keep_alive_timeout = timeout;
                }
                else
                {
@@ -1443,6 +1433,20 @@ struct configuration_spec * load_config(void)
             }
             break;
 
+/* *************************************************************************
+ * max-client-connections number
+ * *************************************************************************/
+         case hash_max_client_connections :
+            if (*arg != '\0')
+            {
+               int max_client_connections = atoi(arg);
+               if (0 <= max_client_connections)
+               {
+                  config->max_client_connections = max_client_connections;
+               }
+            }
+            break;
+
 /* *************************************************************************
  * permit-access source-ip[/significant-bits] [dest-ip[/significant-bits]]
  * *************************************************************************/
@@ -1504,6 +1508,12 @@ struct configuration_spec * load_config(void)
                   break;
                }
             }
+#ifdef HAVE_RFC2553
+            else
+            {
+               cur_acl->wildcard_dst = 1;
+            }
+#endif /* def HAVE_RFC2553 */
 
             /*
              * Add it to the list.  Note we reverse the list to get the
@@ -1775,6 +1785,8 @@ struct configuration_spec * load_config(void)
 
    fclose(configfp);
 
+   set_debug_level(config->debug);
+
    freez(config->logfile);
 
    if (!no_daemon)
@@ -1790,14 +1802,12 @@ struct configuration_spec * load_config(void)
       }
    }
 
-   set_debug_level(config->debug);
-
 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
    if (config->feature_flags & RUNTIME_FEATURE_CONNECTION_KEEP_ALIVE)
    {
       if (config->multi_threaded)
       {
-         set_keep_alive_timeout(keep_alive_timeout);
+         set_keep_alive_timeout(config->keep_alive_timeout);
       }
       else
       {
@@ -1806,6 +1816,8 @@ struct configuration_spec * load_config(void)
           * if we didn't bother with enforcing the connection timeout,
           * that might make Tor users sad, even though they shouldn't
           * enable the single-threaded option anyway.
+          *
+          * XXX: We could still use Proxy-Connection: keep-alive.
           */
          config->feature_flags &= ~RUNTIME_FEATURE_CONNECTION_KEEP_ALIVE;
          log_error(LOG_LEVEL_ERROR,
@@ -1843,18 +1855,22 @@ struct configuration_spec * load_config(void)
 
    if ( NULL != config->haddr )
    {
-      if (NULL != (p = strchr(config->haddr, ':')))
+      if ((*config->haddr == '[')
+         && (NULL != (p = strchr(config->haddr, ']')))
+         && (p[1] == ':')
+         && (0 < (config->hport = atoi(p + 2))))
       {
-         *p++ = '\0';
-         if (*p)
-         {
-            config->hport = atoi(p);
-         }
+         *p = '\0';
+         memmove((void *)config->haddr, config->haddr + 1,
+            (size_t)(p - config->haddr));
       }
-
-      if (config->hport <= 0)
+      else if (NULL != (p = strchr(config->haddr, ':'))
+         && (0 < (config->hport = atoi(p + 1))))
+      {
+         *p = '\0';
+      }
+      else
       {
-         *--p = ':';
          log_error(LOG_LEVEL_FATAL, "invalid bind port spec %s", config->haddr);
          /* Never get here - LOG_LEVEL_FATAL causes program exit */
       }