[Privoxy-commits] [privoxy] 01/06: Check the listening address when deciding whether or not a client tag matches

User Git git at git.privoxy.org
Wed Feb 25 16:23:59 CET 2026


This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch master
in repository privoxy.

commit 447bf260fb67772f01d907e2fb1efea4aff647ea
Author: Fabian Keil <fk at fabiankeil.de>
AuthorDate: Sat Dec 6 08:38:24 2025 +0100

    Check the listening address when deciding whether or not a client tag matches
    
    This allows to use different client tags for different clients running
    on the same host.
---
 cgisimple.c           |  5 ++--
 client-tags.c         | 75 ++++++++++++++++++++++++++++++++++-----------------
 client-tags.h         |  7 +++--
 jbsockets.c           |  3 ++-
 jcc.c                 |  6 +++--
 templates/client-tags |  4 +--
 6 files changed, 66 insertions(+), 34 deletions(-)

diff --git a/cgisimple.c b/cgisimple.c
index 58e5ae6b..a6a8fada 100644
--- a/cgisimple.c
+++ b/cgisimple.c
@@ -374,7 +374,8 @@ jb_err cgi_show_client_tags(struct client_state *csp,
          int tag_state;
 
          privoxy_mutex_lock(&client_tags_mutex);
-         tag_state = client_has_requested_tag(csp->client_address, this_tag->name);
+         tag_state = client_has_requested_tag(csp->client_address,
+            csp->listen_addr_str, this_tag->name);
          privoxy_mutex_unlock(&client_tags_mutex);
          if (!err) err = string_append(&client_tag_status, "<tr><td>");
          if (!err) err = string_append(&client_tag_status, this_tag->name);
@@ -404,7 +405,7 @@ jb_err cgi_show_client_tags(struct client_state *csp,
          return JB_ERR_MEMORY;
       }
    }
-   refresh_delay = get_next_tag_timeout_for_client(csp->client_address);
+   refresh_delay = get_next_tag_timeout_for_client(csp->client_address, csp->listen_addr_str);
    if (refresh_delay != 0)
    {
       snprintf(buf, sizeof(buf), "%u", csp->config->client_tag_lifetime);
diff --git a/client-tags.c b/client-tags.c
index d8cbb350..cc90250a 100644
--- a/client-tags.c
+++ b/client-tags.c
@@ -4,7 +4,7 @@
  *
  * Purpose     :  Functions related to client-specific tags.
  *
- * Copyright   :  Copyright (C) 2016-2017 Fabian Keil <fk at fabiankeil.de>
+ * Copyright   :  Copyright (C) 2016-2025 Fabian Keil <fk at fabiankeil.de>
  *
  *                This program is free software; you can redistribute it
  *                and/or modify it under the terms of the GNU General
@@ -61,6 +61,7 @@ struct client_specific_tag
 struct requested_tags
 {
    char *client; /**< The IP address of the client that requested the tag */
+   char *listen_address; /**< The listen address the client uses */
 
    /**< List of tags the client requested .... */
    struct client_specific_tag *tags;
@@ -70,7 +71,8 @@ struct requested_tags
 };
 
 struct requested_tags *requested_tags;
-static void remove_tag_for_client(const char *client_address, const char *tag);
+static void remove_tag_for_client(const char *client_address,
+   const char *listen_address, const char *tag);
 
 /*********************************************************************
  *
@@ -185,11 +187,13 @@ static struct client_tag_spec *get_client_specific_tag(
  *
  * Parameters  :
  *          1  :  client_address = Address of the client
+ *          2  :  listen_address = Address the request arrived on.
  *
  * Returns     :  Pointer to tag structure or NULL on error.
  *
  *********************************************************************/
-static struct client_specific_tag *get_tags_for_client(const char *client_address)
+static struct client_specific_tag *get_tags_for_client(const char *client_address,
+                                                       const char *listen_address)
 {
    struct requested_tags *requested_tag;
 
@@ -198,7 +202,10 @@ static struct client_specific_tag *get_tags_for_client(const char *client_addres
    {
       if (!strcmp(requested_tag->client, client_address))
       {
-         return requested_tag->tags;
+         if (!strcmp(requested_tag->listen_address, listen_address))
+         {
+            return requested_tag->tags;
+         }
       }
    }
 
@@ -216,19 +223,21 @@ static struct client_specific_tag *get_tags_for_client(const char *client_addres
  * Parameters  :
  *          1  :  tag_list = The list to fill in.
  *          2  :  client_address = Address of the client
+ *          3  :  listen_address = The address the request arrived on.
  *
  * Returns     :  Pointer to tag list.
  *
  *********************************************************************/
 void get_tag_list_for_client(struct list *tag_list,
-                             const char *client_address)
+                             const char *client_address,
+                             const char *listen_address)
 {
    struct client_specific_tag *enabled_tags;
    const time_t now = time(NULL);
 
    privoxy_mutex_lock(&client_tags_mutex);
 
-   enabled_tags = get_tags_for_client(client_address);
+   enabled_tags = get_tags_for_client(client_address, listen_address);
    while (enabled_tags != NULL)
    {
       if (enabled_tags->end_of_life && (enabled_tags->end_of_life < now))
@@ -238,14 +247,14 @@ void get_tag_list_for_client(struct list *tag_list,
             "Tag '%s' for client %s expired %ld seconds ago. Deleting it.",
             enabled_tags->name, client_address,
             (now - enabled_tags->end_of_life));
-         remove_tag_for_client(client_address, enabled_tags->name);
+         remove_tag_for_client(client_address, listen_address, enabled_tags->name);
          enabled_tags = next_tag;
          continue;
       }
       else
       {
-         log_error(LOG_LEVEL_TAGGING, "Enlisting tag '%s' for client %s.",
-            enabled_tags->name, client_address);
+         log_error(LOG_LEVEL_TAGGING, "Enlisting tag '%s' for client %s using %s.",
+            enabled_tags->name, client_address, listen_address);
          enlist(tag_list, enabled_tags->name);
       }
       enabled_tags = enabled_tags->next;
@@ -264,11 +273,13 @@ void get_tag_list_for_client(struct list *tag_list,
  *
  * Parameters  :
  *          1  :  client_address = Address of the client
+ *          2  :  listen_address = Address the request arrived on.
  *
  * Returns     :  Lowest timeout in seconds
  *
  *********************************************************************/
-time_t get_next_tag_timeout_for_client(const char *client_address)
+time_t get_next_tag_timeout_for_client(const char *client_address,
+                             const char *listen_address)
 {
    struct client_specific_tag *enabled_tags;
    time_t next_timeout = 0;
@@ -276,12 +287,13 @@ time_t get_next_tag_timeout_for_client(const char *client_address)
 
    privoxy_mutex_lock(&client_tags_mutex);
 
-   enabled_tags = get_tags_for_client(client_address);
+   enabled_tags = get_tags_for_client(client_address, listen_address);
    while (enabled_tags != NULL)
    {
       log_error(LOG_LEVEL_TAGGING,
-         "Evaluating tag '%s' for client %s. End of life %ld.",
-         enabled_tags->name, client_address, enabled_tags->end_of_life);
+         "Evaluating tag '%s' for client %s using %s. End of life %ld.",
+         enabled_tags->name, client_address, listen_address,
+         enabled_tags->end_of_life);
       if (enabled_tags->end_of_life)
       {
           time_t time_left = enabled_tags->end_of_life - now;
@@ -341,14 +353,16 @@ static struct client_specific_tag *create_client_specific_tag(const char *name,
  *
  * Parameters  :
  *          1  :  client_address = Address of the client
- *          2  :  tag = The tag to add.
- *          3  :  time_to_live = 0, or the number of seconds
+ *          2  :  listen_address = Address used by the client.
+ *          3  :  tag = The tag to add.
+ *          4  :  time_to_live = 0, or the number of seconds
  *                               the tag remains activated.
  *
  * Returns     :  void
  *
  *********************************************************************/
 static void add_tag_for_client(const char *client_address,
+   const char *listen_address,
    const char *tag, const time_t time_to_live)
 {
    struct requested_tags *clients_with_tags;
@@ -361,6 +375,7 @@ static void add_tag_for_client(const char *client_address,
       /* XXX: Code duplication. */
       requested_tags = zalloc_or_die(sizeof(struct requested_tags));
       requested_tags->client = strdup_or_die(client_address);
+      requested_tags->listen_address = strdup_or_die(listen_address);
       requested_tags->tags = create_client_specific_tag(tag, time_to_live);
 
       validate_requested_tags();
@@ -384,6 +399,7 @@ static void add_tag_for_client(const char *client_address,
          clients_with_tags->next->prev = clients_with_tags;
          clients_with_tags = clients_with_tags->next;
          clients_with_tags->client = strdup_or_die(client_address);
+         clients_with_tags->listen_address = strdup_or_die(listen_address);
          clients_with_tags->tags = create_client_specific_tag(tag, time_to_live);
 
          validate_requested_tags();
@@ -416,12 +432,14 @@ static void add_tag_for_client(const char *client_address,
  *
  * Parameters  :
  *          1  :  client_address = Address of the client
- *          2  :  tag = The tag to remove.
+ *          2  :  listen_address = Address used by the client
+ *          3  :  tag = The tag to remove.
  *
  * Returns     :  void
  *
  *********************************************************************/
-static void remove_tag_for_client(const char *client_address, const char *tag)
+static void remove_tag_for_client(const char *client_address,
+                                  const char *listen_address, const char *tag)
 {
    struct requested_tags *clients_with_tags;
    struct client_specific_tag *enabled_tags;
@@ -431,7 +449,8 @@ static void remove_tag_for_client(const char *client_address, const char *tag)
    clients_with_tags = requested_tags;
    while (clients_with_tags != NULL && clients_with_tags->client != NULL)
    {
-      if (!strcmp(clients_with_tags->client, client_address))
+      if (!strcmp(clients_with_tags->client, client_address) &&
+          !strcmp(clients_with_tags->listen_address, listen_address))
       {
          break;
       }
@@ -486,6 +505,7 @@ static void remove_tag_for_client(const char *client_address, const char *tag)
                requested_tags = NULL;
             }
             freez(clients_with_tags->client);
+            freez(clients_with_tags->listen_address);
             freez(clients_with_tags);
          }
          freez(enabled_tags->name);
@@ -510,16 +530,19 @@ static void remove_tag_for_client(const char *client_address, const char *tag)
  *
  * Parameters  :
  *          1  :  client_address = Address of the client
- *          2  :  tag = Tag to check.
+ *          2  :  listen_address = Address the request arrived on.
+ *          4  :  tag = Tag to check.
  *
  * Returns     :  TRUE or FALSE.
  *
  *********************************************************************/
-int client_has_requested_tag(const char *client_address, const char *tag)
+int client_has_requested_tag(const char *client_address,
+                             const char *listen_address,
+                             const char *tag)
 {
    struct client_specific_tag *enabled_tags;
 
-   enabled_tags = get_tags_for_client(client_address);
+   enabled_tags = get_tags_for_client(client_address, listen_address);
 
    while (enabled_tags != NULL)
    {
@@ -563,7 +586,7 @@ jb_err enable_client_specific_tag(struct client_state *csp,
       return JB_ERR_PARSE;
    }
 
-   if (client_has_requested_tag(csp->client_address, tag_name))
+   if (client_has_requested_tag(csp->client_address, csp->listen_addr_str, tag_name))
    {
       log_error(LOG_LEVEL_TAGGING,
          "Tag '%s' already enabled for client '%s'.",
@@ -571,7 +594,8 @@ jb_err enable_client_specific_tag(struct client_state *csp,
    }
    else
    {
-      add_tag_for_client(csp->client_address, tag_name, time_to_live);
+      add_tag_for_client(csp->client_address, csp->listen_addr_str,
+         tag_name, time_to_live);
       log_error(LOG_LEVEL_TAGGING,
          "Tag '%s' enabled for client '%s'. TTL: %ld.",
          tag->name, csp->client_address, time_to_live);
@@ -609,9 +633,10 @@ jb_err disable_client_specific_tag(struct client_state *csp, const char *tag_nam
       return JB_ERR_PARSE;
    }
 
-   if (client_has_requested_tag(csp->client_address, tag_name))
+   if (client_has_requested_tag(csp->client_address, csp->listen_addr_str,
+         tag_name))
    {
-      remove_tag_for_client(csp->client_address, tag_name);
+      remove_tag_for_client(csp->client_address, csp->listen_addr_str, tag_name);
       log_error(LOG_LEVEL_TAGGING,
          "Tag '%s' disabled for client '%s'.", tag->name, csp->client_address);
    }
diff --git a/client-tags.h b/client-tags.h
index bf694519..5566860e 100644
--- a/client-tags.h
+++ b/client-tags.h
@@ -31,14 +31,17 @@
 extern int client_tag_match(const struct pattern_spec *pattern,
                             const struct list *tags);
 extern void get_tag_list_for_client(struct list *tag_list,
-                                    const char *client_address);
-extern time_t get_next_tag_timeout_for_client(const char *client_address);
+                                    const char *client_address,
+                                    const char *listen_address);
+extern time_t get_next_tag_timeout_for_client(const char *client_address,
+                                              const char *listen_address);
 extern jb_err disable_client_specific_tag(struct client_state *csp,
                                           const char *tag_name);
 extern jb_err enable_client_specific_tag(struct client_state *csp,
                                          const char *tag_name,
                                          const time_t time_to_live);
 extern int client_has_requested_tag(const char *client_address,
+                                    const char *listen_address,
                                     const char *tag);
 extern void set_client_address(struct client_state *csp,
                                const struct list *headers);
diff --git a/jbsockets.c b/jbsockets.c
index 1ff73b34..70ddea4d 100644
--- a/jbsockets.c
+++ b/jbsockets.c
@@ -1084,7 +1084,8 @@ int bind_port(const char *hostnam, int portnum, int backlog, jb_socket *pfd)
  * Function    :  get_host_information
  *
  * Description :  Determines the IP address the client used to
- *                reach us and the hostname associated with it.
+ *                reach us, the hostname associated with it and
+ *                the listening address and port.
  *
  *                XXX: Most of the code has been copy and pasted
  *                from accept_connection() and not all of the
diff --git a/jcc.c b/jcc.c
index dd777a71..f147d61c 100644
--- a/jcc.c
+++ b/jcc.c
@@ -1942,7 +1942,8 @@ static jb_err receive_client_request(struct client_state *csp)
 #ifdef FEATURE_CLIENT_TAGS
    /* XXX: If the headers were enlisted sooner, passing csp would do. */
    set_client_address(csp, headers);
-   get_tag_list_for_client(csp->client_tags, csp->client_address);
+   get_tag_list_for_client(csp->client_tags, csp->client_address,
+      csp->listen_addr_str);
 #endif
 
    /*
@@ -2783,7 +2784,8 @@ static jb_err process_encrypted_request_headers(struct client_state *csp)
    if (csp->client_address == NULL)
    {
       set_client_address(csp, headers);
-      get_tag_list_for_client(csp->client_tags, csp->client_address);
+      get_tag_list_for_client(csp->client_tags, csp->client_address,
+         csp->listen_addr_str);
    }
 #endif
 
diff --git a/templates/client-tags b/templates/client-tags
index b1bc4f59..3233b29f 100644
--- a/templates/client-tags
+++ b/templates/client-tags
@@ -114,8 +114,8 @@
             This page shows the configured
             <a title="Lookup client-specific-tag directive in the user-manual"
              href="@user-manual at config.html#CLIENT-SPECIFIC-TAG">client-specific tags</a>,
-            and whether or not they are enabled for the address your request came from
-            (@client-ip-addr@):
+            and whether or not they are enabled for requests from
+            @client-ip-addr@ that arrive on @my-ip-address@:@my-port@:
           </p>
 
         @client-tags@

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Privoxy-commits mailing list