]> granicus.if.org Git - apache/commitdiff
Backport:
authorGraham Leggett <minfrin@apache.org>
Wed, 30 Nov 2011 11:03:03 +0000 (11:03 +0000)
committerGraham Leggett <minfrin@apache.org>
Wed, 30 Nov 2011 11:03:03 +0000 (11:03 +0000)
Introduce a per request version of the remote IP address, which can be
optionally modified by a module when the effective IP of the client
is not the same as the real IP of the client (such as a load balancer).
Introduce a per connection "peer_ip" and a per request "client_ip" to
distinguish between the raw IP address of the connection and the effective
IP address of the request.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1208378 13f79535-47bb-0310-9956-ffa450edef68

31 files changed:
CHANGES
STATUS
docs/manual/expr.xml
docs/manual/mod/core.xml
docs/manual/mod/mod_log_config.xml
docs/manual/mod/mod_remoteip.xml
include/ap_mmn.h
include/httpd.h
modules/aaa/mod_access_compat.c
modules/aaa/mod_authz_host.c
modules/arch/netware/mod_nw_ssl.c
modules/cluster/mod_heartmonitor.c
modules/echo/mod_echo.c
modules/filters/mod_ext_filter.c
modules/http/http_request.c
modules/loggers/mod_log_config.c
modules/lua/lua_request.c
modules/mappers/mod_rewrite.c
modules/metadata/mod_ident.c
modules/metadata/mod_remoteip.c
modules/metadata/mod_setenvif.c
modules/proxy/ajp_header.c
modules/proxy/mod_proxy_http.c
modules/ssl/ssl_engine_kernel.c
modules/ssl/ssl_engine_vars.c
server/core.c
server/log.c
server/protocol.c
server/request.c
server/util_expr_eval.c
server/util_script.c

diff --git a/CHANGES b/CHANGES
index 5473fb91e527484ff61c9d3078300e114714fe7f..5875f52ccce060cde80b4deac8a8f5f177ad14da 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,13 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.4.0
 
+  *) Introduce a per request version of the remote IP address, which can be
+     optionally modified by a module when the effective IP of the client
+     is not the same as the real IP of the client (such as a load balancer).
+     Introduce a per connection "peer_ip" and a per request "client_ip" to
+     distinguish between the raw IP address of the connection and the effective
+     IP address of the request. [Graham Leggett]
+
   *) ap_pass_brigade_fchk() function added. [Jim Jagielski]
 
   *) core: Pass ap_errorlog_info struct to error log hook. [Stefan Fritsch]
diff --git a/STATUS b/STATUS
index 7d03584e1b24ba4aa9db535b60a5a7c85780f367..09720436ff97be5acf65cdcb2468a801bbf65fad 100644 (file)
--- a/STATUS
+++ b/STATUS
@@ -94,12 +94,6 @@ RELEASE SHOWSTOPPERS:
     See https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x/docs/STATUS 
     under 'modules docs' for a comprehensive list of undocumented modules.
 
-  * mod_remoteip works around httpd's non-existent IP address API by leaking
-    from c->pool and allowing pointers from r->pool to live beyond r->pool's
-    lifetime. Provide an actual API for mod_remoteip to use so these hacks
-    are no longer needed, or remove mod_remoteip (minfrin: which I really
-    don't want us to have to do).
-
   * mod_cache: Either fix or remove http://svn.apache.org/viewvc?view=revision&revision=1070179
     as per the following thread:
     http://www.gossamer-threads.com/lists/apache/dev/395830?do=post_view_threaded#395830
index 97fd517df1ca326c47a703487a48cadd6607a565..417f7935221b2ee2f1a2243ee12709932ffbc379 100644 (file)
@@ -237,6 +237,9 @@ listfunction ::= listfuncname "<strong>(</strong>" word "<strong>)</strong>"
     <tr><td><code>CONN_LOG_ID</code></td>
         <td>The error log id of the connection (see
             <directive module="core">ErrorLogFormat</directive>)</td></tr>
+    <tr><td><code>CONN_REMOTE_ADDR</code></td>
+        <td>The raw IP address of the remote host (see the
+            <module>mod_remoteip</module> module)</td></tr>
 
     </table>
 
index 7b3cbf5b1b81d7631876591ceaa117faf3b16c4f..203c1cb0c89d1fdd33a509396a1f8060cd82fc89 100644 (file)
@@ -1377,6 +1377,10 @@ in case of an error</description>
     <tr><td><code>%a</code></td>
         <td>Remote IP-address and port</td></tr>
 
+    <tr><td><code>%{c}a</code></td>
+        <td>Actual remote IP-address and port (see the
+            <module>mod_remoteip</module> module)</td></tr>
+
     <tr><td><code>%A</code></td>
         <td>Local IP-address and port</td></tr>
 
index 1943d5c2660d41fd4bd0b5bf0d874a5680b22975..907bfda4a2da4ff36079e2128eff3cba4a7d84c0 100644 (file)
     <tr><td><code>%a</code></td>
         <td>Remote IP-address.</td></tr>
 
+    <tr><td><code>%{c}a</code></td>
+        <td>Actual remote IP-address and port (see the
+        <module>mod_remoteip</module> module)</td></tr>
+
     <tr><td><code>%A</code></td>
         <td>Local IP-address.</td></tr>
 
index 695f4b2205485ee7ac8552a6c251ec1f6ae75567..547542c748bb34d5668b73cab949031d13ed0633 100644 (file)
@@ -23,9 +23,9 @@
 <modulesynopsis metafile="mod_remoteip.xml.meta">
 
 <name>mod_remoteip</name>
-<description>Replaces the apparent client remote IP address and hostname
-for the request with the IP address list presented by a proxies or a load
-balancer via the request headers.
+<description>Replaces the apparent client remote IP address for the request
+with the IP address list presented by a proxies or a load balancer via the
+request headers.
 </description>
 
 <status>Base</status>
@@ -38,22 +38,19 @@ balancer via the request headers.
     purposes of authorization and logging, even where that remote host is
     behind a load balancer, front end server, or proxy server.</p>
 
-    <p>The module replaces the apparent remote (client) IP/hostname for
+    <p>The module overrides the apparent remote (client) IP for
     the request with the IP address reported in the request header
     configured with the <directive>RemoteIPHeader</directive> directive.</p>
 
     <p>Once replaced as instructed, this apparent IP address is then used
-    for <module>mod_authz_host</module> features
-    <directive module="mod_authz_host" type="section">Require host</directive>
-    and <directive module="mod_authz_host" type="section">Require ip</directive>,
+    for the <module>mod_authz_host</module>
+    <directive module="mod_authz_host" type="section">Require ip</directive> feature,
     is reported by <module>mod_status</module>, and is recorded by
-    <module>mod_log_config</module> <code>%a</code> and <code>%h</code>
-    directives.  It also determines the machine probed for an inetd
-    identity by <module>mod_ident</module> based on the
-    <directive module="mod_ident">IdentityCheck</directive> configuration.</p>
+    <module>mod_log_config</module> <code>%a</code> and <module>core</module>
+    <code>%a</code> format strings. The original remote IP of the connection is
+    available in the <code>%{c}a</code> format string.</p>
 
     <note type="warning">It is critical to only enable this behavior from
-
     intermediate hosts (proxies, etc) which are trusted by this server, since
     it is trivial for the remote client to impersonate another client.</note>
 </summary>
@@ -61,7 +58,6 @@ balancer via the request headers.
 <seealso><module>mod_authz_host</module></seealso>
 <seealso><module>mod_status</module></seealso>
 <seealso><module>mod_log_config</module></seealso>
-<seealso><module>mod_ident</module></seealso>
 
 <section id="processing"><title>Remote IP Processing</title>
 
@@ -72,13 +68,12 @@ balancer via the request headers.
 
     <p>mod_remoteip replaces the true remote_ip with the advertised remote_ip as
     provided by a proxy, for every evaluation of the client that occurs in the
-    server, and resets the remote_host and remote_logname values to trigger a
-    fresh dns or ident query of the remote IP address.</p>
+    server.</p>
 
     <p>When multiple, comma delimited remote IP addresses are listed in the
     header value, they are processed in Right-to-Left order.  Processing
     halts when a given remote IP address is not trusted to present the
-    preceeding IP address.  The header field is updated to this remaining
+    preceding IP address.  The header field is updated to this remaining
     list of unconfirmed IP addresses, or if all IP addresses were trusted,
     this header is removed from the request altogether.</p>
 
index d5a702fea655719187d1371fc7c8d2b5baf23d07..e37c67b47f2f45db57ee7b0d241bc05819d77986 100644 (file)
  * 20111122.0 (2.4.0-dev)  Remove parts of conn_state_t that are private to the MPM
  * 20111123.0 (2.4.0-dev)  Pass ap_errorlog_info struct to error_log hook,
  *                         add pool to ap_errorlog_info.
+ * 20111130.0 (2.4.0-dev)  c->remote_ip becomes c->peer_ip and r->client_ip,
+ *                         c->remote_addr becomes c->peer_addr and r->client_addr
  */
 
 #define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */
 
 #ifndef MODULE_MAGIC_NUMBER_MAJOR
-#define MODULE_MAGIC_NUMBER_MAJOR 20111123
+#define MODULE_MAGIC_NUMBER_MAJOR 20111130
 #endif
 #define MODULE_MAGIC_NUMBER_MINOR 0                   /* 0...n */
 
index 39d10e1c4c4d90ee40e1d0b80411a0081142fa7d..d7f7784dfd9a620c9efd7d23bb02762462858fed 100644 (file)
@@ -1003,6 +1003,12 @@ struct request_rec {
     apr_uri_t parsed_uri;
     /**  finfo.protection (st_mode) set to zero if no such file */
     apr_finfo_t finfo;
+
+    /** remote address information from conn_rec, can be overridden if
+     * necessary by a module.
+     */
+    apr_sockaddr_t *client_addr;
+    char *client_ip;
 };
 
 /**
@@ -1046,10 +1052,10 @@ struct conn_rec {
     /** local address */
     apr_sockaddr_t *local_addr;
     /** remote address */
-    apr_sockaddr_t *remote_addr;
+    apr_sockaddr_t *peer_addr;
 
     /** Client's IP address */
-    char *remote_ip;
+    char *peer_ip;
     /** Client's DNS name, if known.  NULL if DNS hasn't been checked,
      *  "" if it has and no address was found.  N.B. Only access this though
      * get_remote_host() */
index 3d5d535f44c4239cb3140774db4354f340b03260..e3cc74f79fc565bac5a19c7195bbd8f3b264d34d 100644 (file)
@@ -271,7 +271,7 @@ static int find_allowdeny(request_rec *r, apr_array_header_t *a, int method)
             return 1;
 
         case T_IP:
-            if (apr_ipsubnet_test(ap[i].x.ip, r->connection->remote_addr)) {
+            if (apr_ipsubnet_test(ap[i].x.ip, r->client_addr)) {
                 return 1;
             }
             break;
index 2bc7f20e87d85cc989971e2637b98e60fd3dfff5..180172a40e26c0d1c0b3d51c18d3973eef59e238 100644 (file)
@@ -153,7 +153,7 @@ static authz_status ip_check_authorization(request_rec *r,
     apr_ipsubnet_t **ip = (apr_ipsubnet_t **)parsed_require_line;
 
     while (*ip) {
-        if (apr_ipsubnet_test(*ip, r->connection->remote_addr))
+        if (apr_ipsubnet_test(*ip, r->client_addr))
             return AUTHZ_GRANTED;
         ip++;
     }
@@ -201,10 +201,10 @@ static authz_status local_check_authorization(request_rec *r,
                                               const void *parsed_require_line)
 {
      if (   apr_sockaddr_equal(r->connection->local_addr,
-                               r->connection->remote_addr)
-         || apr_ipsubnet_test(localhost_v4, r->connection->remote_addr)
+                               r->client_addr)
+         || apr_ipsubnet_test(localhost_v4, r->client_addr)
 #if APR_HAVE_IPV6
-         || apr_ipsubnet_test(localhost_v6, r->connection->remote_addr)
+         || apr_ipsubnet_test(localhost_v6, r->client_addr)
 #endif
         )
      {
index 7b64ebfa2fc99c72b64de937f45ed7d87c9b8a1c..3e20edb569e6124e77eb138a4d4a305894d16598 100644 (file)
@@ -1000,6 +1000,8 @@ char *ssl_var_lookup(apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r,
                 result = r->uri;
             else if (strcEQ(var, "REQUEST_FILENAME"))
                 result = r->filename;
+            else if (strcEQ(var, "REMOTE_ADDR"))
+                result = r->client_ip;
             else if (strcEQ(var, "REMOTE_HOST"))
                 result = ap_get_remote_host(r->connection, r->per_dir_config,
                                             REMOTE_NAME, NULL);
@@ -1055,8 +1057,6 @@ char *ssl_var_lookup(apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r,
 
                 if (strlen(var) > 4 && strcEQn(var, "SSL_", 4))
                         result = NULL;
-        else if (strcEQ(var, "REMOTE_ADDR"))
-            result = c->remote_ip;
     }
 
     /*
index 538f3a6de2584a30fdb8096c725b96ba00d77155..3c2b41493e44e3fd96939fcbb8f447bb84d9570e 100644 (file)
@@ -757,7 +757,7 @@ static int hm_handler(request_rec *r)
     buf[len] = '\0';
     tbl = apr_table_make(r->pool, 10);
     qs_to_table(buf, tbl, r->pool);
-    apr_sockaddr_ip_get(&ip, r->connection->remote_addr);
+    apr_sockaddr_ip_get(&ip, r->connection->peer_addr);
     hmserver.ip = ip;
     hmserver.port = 80;
     if (apr_table_get(tbl, "port") != NULL)
index 161ceed651f515e4f7025ea80a253fd4ba139743..49a9d93362dc0e1e8834cd40abb372d1e710ea8f 100644 (file)
@@ -154,7 +154,7 @@ static int process_echo_connection(conn_rec *c)
             if (!APR_STATUS_IS_EOF(rv) && ! APR_STATUS_IS_TIMEUP(rv))
                 ap_log_error(APLOG_MARK, APLOG_INFO, rv, c->base_server,
                              "ProtocolEcho: Failure reading from %s",
-                             c->remote_ip);
+                             c->peer_ip);
             break;
         }
 
@@ -163,7 +163,7 @@ static int process_echo_connection(conn_rec *c)
             apr_brigade_cleanup(bb);
             ap_log_error(APLOG_MARK, APLOG_INFO, rv, c->base_server,
                          "ProtocolEcho: Error - read empty brigade from %s!",
-                         c->remote_ip);
+                         c->peer_ip);
             break;
         }
 
@@ -181,7 +181,7 @@ static int process_echo_connection(conn_rec *c)
         if (rv != APR_SUCCESS) {
             ap_log_error(APLOG_MARK, APLOG_INFO, rv, c->base_server,
                          "ProtocolEcho: Failure writing to %s",
-                         c->remote_ip);
+                         c->peer_ip);
             break;
         }
         apr_brigade_cleanup(bb);
index 1fd0a9ef6babdd957a16100a498c91c76faec64d..1e3beab7f4ba2cae422e9e67030455c0fc51639b 100644 (file)
@@ -406,7 +406,7 @@ static void child_errfn(apr_pool_t *pool, apr_status_t err, const char *descript
     apr_file_printf(stderr_log,
                     "[%s] [client %s] mod_ext_filter (%d)%s: %s\n",
                     time_str,
-                    r->connection->remote_ip,
+                    r->client_ip,
                     err,
                     apr_strerror(err, errbuf, sizeof(errbuf)),
                     description);
index 9d67a29a9d5446d31cda329a83e68ea99430ac6d..36cff2d913ba24d747f60e4175fea096eefa0350 100644 (file)
@@ -439,6 +439,9 @@ static request_rec *internal_internal_redirect(const char *new_uri,
     new->prev = r;
     r->next   = new;
 
+    new->client_addr = r->client_addr;
+    new->client_ip = r->client_ip;
+
     /* Must have prev and next pointers set before calling create_request
      * hook.
      */
index fc7b83ae1e33427b31bf0cf3723fef3ba1cfc8da..e3b050a809cc1620f562d363f4e64b89325de092 100644 (file)
@@ -310,7 +310,12 @@ static const char *log_remote_host(request_rec *r, char *a)
 
 static const char *log_remote_address(request_rec *r, char *a)
 {
-    return r->connection->remote_ip;
+    if (a && !strcmp(a, "c")) {
+        return r->connection->peer_ip;
+    }
+    else {
+        return r->client_ip;
+    }
 }
 
 static const char *log_local_address(request_rec *r, char *a)
@@ -758,7 +763,7 @@ static const char *log_server_port(request_rec *r, char *a)
         port = r->server->port ? r->server->port : ap_default_port(r);
     }
     else if (!strcasecmp(a, "remote")) {
-        port = r->connection->remote_addr->port;
+        port = r->client_addr->port;
     }
     else if (!strcasecmp(a, "local")) {
         port = r->connection->local_addr->port;
index ffb3088650a2540bcb03375306946e4060b0b403..5d7d8f537e35ce3dcba5234befa02d133a1b4a06 100644 (file)
@@ -743,7 +743,7 @@ AP_LUA_DECLARE(void) ap_lua_push_connection(lua_State *L, conn_rec *c)
     ap_lua_push_apr_table(L, c->notes);
     lua_setfield(L, -2, "notes");
 
-    lua_pushstring(L, c->remote_ip);
+    lua_pushstring(L, c->peer_ip);
     lua_setfield(L, -2, "remote_ip");
 
     lua_pop(L, 1);
index 014f591110fcf84d0d631a18933664094ed02b96..7d7e899eb4038cc2300bdcc86adb1817061dfb27 100644 (file)
@@ -1860,7 +1860,7 @@ static char *lookup_variable(char *var, rewrite_ctx *ctx)
             else if (!strcmp(var, "IPV6")) {
                 int flag = FALSE;
 #if APR_HAVE_IPV6
-                apr_sockaddr_t *addr = r->connection->remote_addr;
+                apr_sockaddr_t *addr = r->client_addr;
                 flag = (addr->family == AF_INET6 &&
                         !IN6_IS_ADDR_V4MAPPED((struct in6_addr *)addr->ipaddr_ptr));
                 rewritelog((r, 1, ctx->perdir, "IPV6='%s'", flag ? "on" : "off"));
@@ -1966,7 +1966,7 @@ static char *lookup_variable(char *var, rewrite_ctx *ctx)
 
             case 'D':
                 if (*var == 'R' && !strcmp(var, "REMOTE_ADDR")) {
-                    result = r->connection->remote_ip;
+                    result = r->client_ip;
                 }
                 else if (!strcmp(var, "SERVER_ADDR")) {
                     result = r->connection->local_ip;
@@ -2005,7 +2005,7 @@ static char *lookup_variable(char *var, rewrite_ctx *ctx)
                                                 REMOTE_NAME, NULL);
                 }
                 else if (!strcmp(var, "REMOTE_PORT")) {
-                    return apr_itoa(r->pool, r->connection->remote_addr->port);
+                    return apr_itoa(r->pool, r->client_addr->port);
                 }
                 break;
 
index bd2c54d52e1407f7c585d783d96be31f268745c3..1ba520800a05ee0ceeabeda00f76ab1362d282aa 100644 (file)
@@ -101,14 +101,14 @@ static apr_status_t rfc1413_connect(apr_socket_t **newsock, conn_rec *conn,
         return rv;
     }
 
-    if ((rv = apr_sockaddr_info_get(&destsa, conn->remote_ip,
+    if ((rv = apr_sockaddr_info_get(&destsa, conn->peer_ip,
                               localsa->family, /* has to match */
                               RFC1413_PORT, 0, conn->pool)) != APR_SUCCESS) {
         /* This should not fail since we have a numeric address string
          * as the host. */
         ap_log_error(APLOG_MARK, APLOG_CRIT, rv, srv,
                      "rfc1413: apr_sockaddr_info_get(%s) failed",
-                     conn->remote_ip);
+                     conn->peer_ip);
         return rv;
     }
 
@@ -167,7 +167,7 @@ static apr_status_t rfc1413_query(apr_socket_t *sock, conn_rec *conn,
     apr_size_t buflen;
 
     sav_our_port = conn->local_addr->port;
-    sav_rmt_port = conn->remote_addr->port;
+    sav_rmt_port = conn->peer_addr->port;
 
     /* send the data */
     buflen = apr_snprintf(buffer, sizeof(buffer), "%hu,%hu\r\n", sav_rmt_port,
index 246937bac7a1e2be8469b2ace33e3f0ab92f0d70..c72e8d8ad9e33550f57d3f0f795186d9954a0cf2 100644 (file)
@@ -51,19 +51,13 @@ typedef struct {
 } remoteip_config_t;
 
 typedef struct {
-    /** The previous proxy-via request header value */
-    const char *prior_remote;
-    /** The unmodified original ip and address */
-    const char *orig_ip;
-    apr_sockaddr_t *orig_addr;
+    apr_sockaddr_t *client_addr;
+    char *client_ip;
     /** The list of proxy ip's ignored as remote ip's */
     const char *proxy_ips;
     /** The remaining list of untrusted proxied remote ip's */
     const char *proxied_remote;
-    /** The most recently modified ip and address record */
-    const char *proxied_ip;
-    apr_sockaddr_t proxied_addr;
-} remoteip_conn_t;
+} remoteip_req_t;
 
 static void *create_remoteip_server_config(apr_pool_t *p, server_rec *s)
 {
@@ -222,65 +216,45 @@ static const char *proxylist_read(cmd_parms *cmd, void *cfg,
     return NULL;
 }
 
-static int remoteip_modify_connection(request_rec *r)
+static int remoteip_modify_request(request_rec *r)
 {
     conn_rec *c = r->connection;
     remoteip_config_t *config = (remoteip_config_t *)
         ap_get_module_config(r->server->module_config, &remoteip_module);
-    remoteip_conn_t *conn;
-#ifdef REMOTEIP_OPTIMIZED
-    apr_sockaddr_t temp_sa_buff;
-    apr_sockaddr_t *temp_sa = &temp_sa_buff;
-#else
+    remoteip_req_t *req = NULL;
+
     apr_sockaddr_t *temp_sa;
-#endif
+
     apr_status_t rv;
-    char *remote = (char *) apr_table_get(r->headers_in, config->header_name);
+    char *remote;
     char *proxy_ips = NULL;
     char *parse_remote;
     char *eos;
     unsigned char *addrbyte;
     void *internal = NULL;
 
-    apr_pool_userdata_get((void*)&conn, "mod_remoteip-conn", c->pool);
-
-    if (conn) {
-        if (remote && (strcmp(remote, conn->prior_remote) == 0)) {
-            /* TODO: Recycle r-> overrides from previous request
-             */
-            goto ditto_request_rec;
-        }
-        else {
-            /* TODO: Revert connection from previous request
-             */
-            c->remote_addr = conn->orig_addr;
-            c->remote_ip = (char *) conn->orig_ip;
-        }
+    if (!config->header_name) {
+        return DECLINED;
     }
 
+    remote = (char *) apr_table_get(r->headers_in, config->header_name);
     if (!remote) {
         return OK;
     }
-
     remote = apr_pstrdup(r->pool, remote);
 
-#ifdef REMOTEIP_OPTIMIZED
-    memcpy(temp_sa, c->remote_addr, sizeof(*temp_sa));
-    temp_sa->pool = r->pool;
-#else
-    temp_sa = c->remote_addr;
-#endif
+    temp_sa = c->peer_addr;
 
     while (remote) {
 
-        /* verify c->remote_addr is trusted if there is a trusted proxy list
+        /* verify c->peer_addr is trusted if there is a trusted proxy list
          */
         if (config->proxymatch_ip) {
             int i;
             remoteip_proxymatch_t *match;
             match = (remoteip_proxymatch_t *)config->proxymatch_ip->elts;
             for (i = 0; i < config->proxymatch_ip->nelts; ++i) {
-                if (apr_ipsubnet_test(match[i].ip, c->remote_addr)) {
+                if (apr_ipsubnet_test(match[i].ip, c->peer_addr)) {
                     internal = match[i].internal;
                     break;
                 }
@@ -317,21 +291,6 @@ static int remoteip_modify_connection(request_rec *r)
             break;
         }
 
-#ifdef REMOTEIP_OPTIMIZED
-        /* Decode remote_addr - sucks; apr_sockaddr_vars_set isn't 'public' */
-        if (inet_pton(AF_INET, parse_remote,
-                      &temp_sa->sa.sin.sin_addr) > 0) {
-            apr_sockaddr_vars_set(temp_sa, APR_INET, temp_sa.port);
-        }
-#if APR_HAVE_IPV6
-        else if (inet_pton(AF_INET6, parse_remote,
-                           &temp_sa->sa.sin6.sin6_addr) > 0) {
-            apr_sockaddr_vars_set(temp_sa, APR_INET6, temp_sa.port);
-        }
-#endif
-        else {
-            rv = apr_get_netos_error();
-#else /* !REMOTEIP_OPTIMIZED */
         /* We map as IPv4 rather than IPv6 for equivilant host names
          * or IPV4OVERIPV6
          */
@@ -339,11 +298,11 @@ static int remoteip_modify_connection(request_rec *r)
                                    APR_UNSPEC, temp_sa->port,
                                    APR_IPV4_ADDR_OK, r->pool);
         if (rv != APR_SUCCESS) {
-#endif
             ap_log_rerror(APLOG_MARK, APLOG_DEBUG,  rv, r,
                           "RemoteIP: Header %s value of %s cannot be parsed "
                           "as a client IP",
                           config->header_name, parse_remote);
+
             if (remote) {
                 *(remote + strlen(remote)) = ',';
             }
@@ -351,6 +310,7 @@ static int remoteip_modify_connection(request_rec *r)
                 remote = parse_remote;
             }
             break;
+
         }
 
         addrbyte = (unsigned char *) &temp_sa->sa.sin.sin_addr;
@@ -387,85 +347,61 @@ static int remoteip_modify_connection(request_rec *r)
             else {
                 remote = parse_remote;
             }
+
             break;
         }
 
-        if (!conn) {
-            conn = (remoteip_conn_t *) apr_palloc(c->pool, sizeof(*conn));
-            apr_pool_userdata_set(conn, "mod_remoteip-conn", NULL, c->pool);
-            conn->orig_addr = c->remote_addr;
-            conn->orig_ip = c->remote_ip;
+        /* save away our results */
+        if (!req) {
+            req = (remoteip_req_t *) apr_palloc(r->pool, sizeof(remoteip_req_t));
         }
 
-        /* Set remote_ip string */
+        /* Set peer_ip string */
         if (!internal) {
             if (proxy_ips) {
                 proxy_ips = apr_pstrcat(r->pool, proxy_ips, ", ",
-                                        c->remote_ip, NULL);
+                                        c->peer_ip, NULL);
             }
             else {
-                proxy_ips = c->remote_ip;
+                proxy_ips = c->peer_ip;
             }
         }
 
-        c->remote_addr = temp_sa;
-        apr_sockaddr_ip_get(&c->remote_ip, c->remote_addr);
+        req->client_addr = temp_sa;
+        apr_sockaddr_ip_get(&req->client_ip, req->client_addr);
     }
 
     /* Nothing happened? */
-    if (!conn || (c->remote_addr == conn->orig_addr)) {
+    if (!req) {
         return OK;
     }
 
-    /* Fixups here, remote becomes the new Via header value, etc
-     * In the heavy operations above we used request scope, to limit
-     * conn pool memory growth on keepalives, so here we must scope
-     * the final results to the connection pool lifetime.
-     * To limit memory growth, we keep recycling the same buffer
-     * for the final apr_sockaddr_t in the remoteip conn rec.
-     */
-    c->remote_ip = apr_pstrdup(c->pool, c->remote_ip);
-    conn->proxied_ip = c->remote_ip;
-    memcpy(&conn->proxied_addr, temp_sa, sizeof(*temp_sa));
-    conn->proxied_addr.pool = c->pool;
-    c->remote_addr = &conn->proxied_addr;
-
-    if (remote) {
-        remote = apr_pstrdup(c->pool, remote);
-    }
-    conn->proxied_remote = remote;
-    conn->prior_remote = apr_pstrdup(c->pool, apr_table_get(r->headers_in,
-                                                      config->header_name));
-    if (proxy_ips) {
-        proxy_ips = apr_pstrdup(c->pool, proxy_ips);
-    }
-    conn->proxy_ips = proxy_ips;
+    req->proxied_remote = remote;
+    req->proxy_ips = proxy_ips;
 
-    /* Unset remote_host string DNS lookups */
-    c->remote_host = NULL;
-    c->remote_logname = NULL;
-
-ditto_request_rec:
-    if (conn->proxied_remote) {
+    if (req->proxied_remote) {
         apr_table_setn(r->headers_in, config->header_name,
-                       conn->proxied_remote);
+                       req->proxied_remote);
     }
     else {
         apr_table_unset(r->headers_in, config->header_name);
     }
-    if (conn->proxy_ips) {
-        apr_table_setn(r->notes, "remoteip-proxy-ip-list", conn->proxy_ips);
+    if (req->proxy_ips) {
+        apr_table_setn(r->notes, "remoteip-proxy-ip-list", req->proxy_ips);
         if (config->proxies_header_name) {
             apr_table_setn(r->headers_in, config->proxies_header_name,
-                           conn->proxy_ips);
+                           req->proxy_ips);
         }
     }
 
+    r->client_addr = req->client_addr;
+    r->client_ip = req->client_ip;
+
     ap_log_rerror(APLOG_MARK, APLOG_INFO|APLOG_NOERRNO, 0, r,
-                  conn->proxy_ips
+                  req->proxy_ips
                       ? "Using %s as client's IP by proxies %s"
                       : "Using %s as client's IP by internal proxies",
-                  conn->proxied_ip, conn->proxy_ips);
+                  req->client_ip, req->proxy_ips);
     return OK;
 }
 
@@ -497,7 +433,7 @@ static const command_rec remoteip_cmds[] =
 
 static void register_hooks(apr_pool_t *p)
 {
-    ap_hook_post_read_request(remoteip_modify_connection, NULL, NULL, APR_HOOK_FIRST);
+    ap_hook_post_read_request(remoteip_modify_request, NULL, NULL, APR_HOOK_FIRST);
 }
 
 AP_DECLARE_MODULE(remoteip) = {
index e773719b427efcfb83f45326c0cae5daeda23a7a..5a2ee71bb9cc0c982b72d875605fa0ac56b10ece 100644 (file)
@@ -527,7 +527,7 @@ static int match_headers(request_rec *r)
                 last_name = b->name;
                 switch (b->special_type) {
                 case SPECIAL_REMOTE_ADDR:
-                    val = r->connection->remote_ip;
+                    val = r->client_ip;
                     break;
                 case SPECIAL_SERVER_ADDR:
                     val = r->connection->local_ip;
index 0fc8e195ff991397d777f76428e08e16be85e037..310b8254bfc6ccde14404277bb0506f7ea341116 100644 (file)
@@ -247,7 +247,7 @@ static apr_status_t ajp_marshal_into_msgb(ajp_msg_t *msg,
         ajp_msg_append_uint8(msg, (apr_byte_t) method)           ||
         ajp_msg_append_string(msg, r->protocol)                  ||
         ajp_msg_append_string(msg, uri->path)                    ||
-        ajp_msg_append_string(msg, r->connection->remote_ip)     ||
+        ajp_msg_append_string(msg, r->client_ip)                 ||
         ajp_msg_append_string(msg, remote_host)                  ||
         ajp_msg_append_string(msg, ap_get_server_name(r))        ||
         ajp_msg_append_uint16(msg, (apr_uint16_t)r->connection->local_addr->port) ||
@@ -413,7 +413,7 @@ static apr_status_t ajp_marshal_into_msgb(ajp_msg_t *msg,
      */
     {
         const char *key = SC_A_REQ_REMOTE_PORT;
-        char *val = apr_itoa(r->pool, r->connection->remote_addr->port);
+        char *val = apr_itoa(r->pool, r->client_addr->port);
         if (ajp_msg_append_uint8(msg, SC_A_REQ_ATTRIBUTE) ||
             ajp_msg_append_string(msg, key)   ||
             ajp_msg_append_string(msg, val)) {
index cd61563ae6604e8e6e9bbb3b2edabb82cbae198e..b3186b59f814dd05f13ea12ecc87eaece562c538 100644 (file)
@@ -532,7 +532,7 @@ static int stream_reqbody_cl(apr_pool_t *p,
     if (bytes_streamed != cl_val) {
         ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                       "client %s given Content-Length did not match"
-                      " number of body bytes read", r->connection->remote_ip);
+                      " number of body bytes read", r->connection->peer_ip);
         return HTTP_BAD_REQUEST;
     }
 
@@ -858,7 +858,7 @@ int ap_proxy_http_request(apr_pool_t *p, request_rec *r,
             * determine, where the original request came from.
             */
            apr_table_mergen(r->headers_in, "X-Forwarded-For",
-                            c->remote_ip);
+                            r->client_ip);
 
            /* Add X-Forwarded-Host: so that upstream knows what the
             * original request hostname was.
@@ -1002,7 +1002,7 @@ int ap_proxy_http_request(apr_pool_t *p, request_rec *r,
         ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
                       "client %s (%s) requested Transfer-Encoding "
                       "chunked body with Content-Length (C-L ignored)",
-                      c->remote_ip, c->remote_host ? c->remote_host: "");
+                      c->peer_ip, c->remote_host ? c->remote_host: "");
         apr_table_unset(r->headers_in, "Content-Length");
         old_cl_val = NULL;
         origin->keepalive = AP_CONN_CLOSE;
@@ -1027,7 +1027,7 @@ int ap_proxy_http_request(apr_pool_t *p, request_rec *r,
                           "prefetch request body failed to %pI (%s)"
                           " from %s (%s)",
                           p_conn->addr, p_conn->hostname ? p_conn->hostname: "",
-                          c->remote_ip, c->remote_host ? c->remote_host: "");
+                          c->peer_ip, c->remote_host ? c->remote_host: "");
             return HTTP_BAD_REQUEST;
         }
 
@@ -1049,7 +1049,7 @@ int ap_proxy_http_request(apr_pool_t *p, request_rec *r,
                           "processing prefetched request body failed"
                           " to %pI (%s) from %s (%s)",
                           p_conn->addr, p_conn->hostname ? p_conn->hostname: "",
-                          c->remote_ip, c->remote_host ? c->remote_host: "");
+                          c->peer_ip, c->remote_host ? c->remote_host: "");
             return HTTP_INTERNAL_SERVER_ERROR;
         }
 
@@ -1188,7 +1188,7 @@ skip_body:
         ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                       "pass request body failed to %pI (%s) from %s (%s)",
                       p_conn->addr, p_conn->hostname ? p_conn->hostname: "",
-                      c->remote_ip, c->remote_host ? c->remote_host: "");
+                      c->peer_ip, c->remote_host ? c->remote_host: "");
         return rv;
     }
 
index 0ba483125fd95239c63957784da53dd52809b60b..cd003f0222a881c80f25531b45cedae47613b3a8 100644 (file)
@@ -917,7 +917,7 @@ int ssl_hook_Access(request_rec *r)
             ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
                           "Access to %s denied for %s "
                           "(requirement expression not fulfilled)",
-                          r->filename, r->connection->remote_ip);
+                          r->filename, r->client_ip);
 
             ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
                           "Failed expression: %s", req->cpExpr);
index c0e933d303dbaa0fb83939816a6b63e00b475cf2..4155bc34802cf08f3285c82232307ec7058486f4 100644 (file)
@@ -187,6 +187,8 @@ char *ssl_var_lookup(apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r,
                 result = r->uri;
             else if (strcEQ(var, "REQUEST_FILENAME"))
                 result = r->filename;
+            else if (strcEQ(var, "REMOTE_ADDR"))
+                result = r->client_ip;
             else if (strcEQ(var, "REMOTE_HOST"))
                 result = ap_get_remote_host(r->connection, r->per_dir_config,
                                             REMOTE_NAME, NULL);
@@ -242,8 +244,6 @@ char *ssl_var_lookup(apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r,
         if (strlen(var) > 4 && strcEQn(var, "SSL_", 4)
             && sslconn && sslconn->ssl)
             result = ssl_var_lookup_ssl(p, c, r, var+4);
-        else if (strcEQ(var, "REMOTE_ADDR"))
-            result = c->remote_ip;
         else if (strcEQ(var, "HTTPS")) {
             if (sslconn && sslconn->ssl)
                 result = "on";
index b96fe7632b587208e965fc84f387268f06d69d4e..ac0a9fac0cf50961af9d9bad8989ee538b7554bd 100644 (file)
@@ -829,7 +829,7 @@ static APR_INLINE void do_double_reverse (conn_rec *conn)
     rv = apr_sockaddr_info_get(&sa, conn->remote_host, APR_UNSPEC, 0, 0, conn->pool);
     if (rv == APR_SUCCESS) {
         while (sa) {
-            if (apr_sockaddr_equal(sa, conn->remote_addr)) {
+            if (apr_sockaddr_equal(sa, conn->peer_addr)) {
                 conn->double_reverse = 1;
                 return;
             }
@@ -871,7 +871,7 @@ AP_DECLARE(const char *) ap_get_remote_host(conn_rec *conn, void *dir_config,
         && (type == REMOTE_DOUBLE_REV
         || hostname_lookups != HOSTNAME_LOOKUP_OFF)) {
 
-        if (apr_getnameinfo(&conn->remote_host, conn->remote_addr, 0)
+        if (apr_getnameinfo(&conn->remote_host, conn->peer_addr, 0)
             == APR_SUCCESS) {
             ap_str_tolower(conn->remote_host);
 
@@ -910,7 +910,7 @@ AP_DECLARE(const char *) ap_get_remote_host(conn_rec *conn, void *dir_config,
         }
         else {
             *str_is_ip = 1;
-            return conn->remote_ip;
+            return conn->peer_ip;
         }
     }
 }
@@ -4511,7 +4511,7 @@ static conn_rec *core_create_conn(apr_pool_t *ptrans, server_rec *server,
     }
 
     apr_sockaddr_ip_get(&c->local_ip, c->local_addr);
-    if ((rv = apr_socket_addr_get(&c->remote_addr, APR_REMOTE, csd))
+    if ((rv = apr_socket_addr_get(&c->peer_addr, APR_REMOTE, csd))
         != APR_SUCCESS) {
         ap_log_error(APLOG_MARK, APLOG_INFO, rv, server,
                      "apr_socket_addr_get(APR_REMOTE)");
@@ -4519,7 +4519,7 @@ static conn_rec *core_create_conn(apr_pool_t *ptrans, server_rec *server,
         return NULL;
     }
 
-    apr_sockaddr_ip_get(&c->remote_ip, c->remote_addr);
+    apr_sockaddr_ip_get(&c->peer_ip, c->peer_addr);
     c->base_server = server;
 
     c->id = id;
index 605d75bbeabb0b2cba9651fa7b2e564bdc6bcf9c..4b73a451086685e8bbe5c20df276c3647b6c1be0 100644 (file)
@@ -561,9 +561,12 @@ static int cpystrn(char *buf, const char *arg, int buflen)
 static int log_remote_address(const ap_errorlog_info *info, const char *arg,
                               char *buf, int buflen)
 {
-    if (info->c)
-        return apr_snprintf(buf, buflen, "%s:%d", info->c->remote_ip,
-                            info->c->remote_addr->port);
+    if (info->r && !(arg && *arg == 'c'))
+        return apr_snprintf(buf, buflen, "%s:%d", info->r->client_ip,
+                            info->r->client_addr->port);
+    else if (info->c)
+        return apr_snprintf(buf, buflen, "%s:%d", info->c->peer_ip,
+                            info->c->peer_addr->port);
     else
         return 0;
 }
@@ -958,14 +961,19 @@ static int do_errorlog_default(const ap_errorlog_info *info, char *buf,
         }
     }
 
-    if (info->c) {
-        /*
-         * remote_ip can be client or backend server. If we have a scoreboard
-         * handle, it is likely a client.
-         */
+    /*
+     * client_ip/peer_ip can be client or backend server. If we have a scoreboard
+     * handle, it is likely a client.
+     */
+    if (info->r) {
+        len += apr_snprintf(buf + len, buflen - len,
+                            info->r->connection->sbh ? "[client %s:%d] " : "[remote %s:%d] ",
+                            info->r->client_ip, info->r->client_addr->port);
+    }
+    else if (info->c) {
         len += apr_snprintf(buf + len, buflen - len,
                             info->c->sbh ? "[client %s:%d] " : "[remote %s:%d] ",
-                            info->c->remote_ip, info->c->remote_addr->port);
+                            info->c->peer_ip, info->c->peer_addr->port);
     }
 
     /* the actual error message */
index 2d2bc05ca092c11b1f8c523503cc2c81a495cc46..a79adaac6c6df181f50509dd6bea017e4ef3d72a 100644 (file)
@@ -979,6 +979,9 @@ request_rec *ap_read_request(conn_rec *conn)
      */
     r->used_path_info = AP_REQ_DEFAULT_PATH_INFO;
 
+    r->client_addr = conn->peer_addr;
+    r->client_ip = conn->peer_ip;
+
     tmp_bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
 
     ap_run_pre_read_request(r, conn);
index f8f0605674a0f166f716414fb1b834ba2ba1eed8..71122cffea0e1f42d338b65ff289174f304950e4 100644 (file)
@@ -1832,6 +1832,9 @@ static request_rec *make_sub_request(const request_rec *r,
         rnew->output_filters = r->proto_output_filters;
     }
 
+    rnew->client_addr = r->client_addr;
+    rnew->client_ip = r->client_ip;
+
     /* no input filters for a subrequest */
 
     ap_set_sub_req_protocol(rnew, r);
index 720cab230fe71f64e4235baba4f0d49a1dd5d509..d4233e401c2adc1516c8d6c9bd81610b8c1916bd 100644 (file)
@@ -1183,10 +1183,10 @@ APR_DECLARE_OPTIONAL_FN(int, ssl_is_https, (conn_rec *));
 static APR_OPTIONAL_FN_TYPE(ssl_is_https) *is_https = NULL;
 
 static const char *conn_var_names[] = {
-    "REMOTE_ADDR",              /*  0 */
-    "HTTPS",                    /*  1 */
-    "IPV6",                     /*  2 */
-    "CONN_LOG_ID",              /*  3 */
+    "HTTPS",                    /*  0 */
+    "IPV6",                     /*  1 */
+    "CONN_LOG_ID",              /*  2 */
+    "CONN_REMOTE_ADDR",         /*  3 */
     NULL
 };
 
@@ -1199,16 +1199,14 @@ static const char *conn_var_fn(ap_expr_eval_ctx_t *ctx, const void *data)
 
     switch (index) {
     case 0:
-        return c->remote_ip;
-    case 1:
         if (is_https && is_https(c))
             return "on";
         else
             return "off";
-    case 2:
+    case 1:
 #if APR_HAVE_IPV6
         {
-            apr_sockaddr_t *addr = c->remote_addr;
+            apr_sockaddr_t *addr = c->peer_addr;
             if (addr->family == AF_INET6
                 && !IN6_IS_ADDR_V4MAPPED((struct in6_addr *)addr->ipaddr_ptr))
                 return "on";
@@ -1218,8 +1216,10 @@ static const char *conn_var_fn(ap_expr_eval_ctx_t *ctx, const void *data)
 #else
         return "off";
 #endif
-    case 3:
+    case 2:
         return c->log_id;
+    case 3:
+        return c->peer_ip;
     default:
         ap_assert(0);
         return NULL;
@@ -1255,6 +1255,7 @@ static const char *request_var_names[] = {
     "CONTEXT_PREFIX",           /* 25 */
     "CONTEXT_DOCUMENT_ROOT",    /* 26 */
     "REQUEST_STATUS",           /* 27 */
+    "REMOTE_ADDR",              /* 28 */
     NULL
 };
 
@@ -1340,6 +1341,8 @@ static const char *request_var_fn(ap_expr_eval_ctx_t *ctx, const void *data)
         return ap_context_document_root(r);
     case 27:
         return r->status ? apr_psprintf(ctx->p, "%d", r->status) : "";
+    case 28:
+        return r->client_ip;
     default:
         ap_assert(0);
         return NULL;
@@ -1485,10 +1488,10 @@ static int op_R(ap_expr_eval_ctx_t *ctx, const void *data, const char *arg1)
 
     AP_DEBUG_ASSERT(subnet != NULL);
 
-    if (!ctx->c)
+    if (!ctx->r)
         return FALSE;
 
-    return apr_ipsubnet_test(subnet, ctx->c->remote_addr);
+    return apr_ipsubnet_test(subnet, ctx->r->client_addr);
 }
 
 static int op_T(ap_expr_eval_ctx_t *ctx, const void *data, const char *arg)
index 243d5093ac176a885bac905efdc5fd942edc3c5d..907dd3607992166142880848dea2e19b8bd583ea 100644 (file)
@@ -235,7 +235,7 @@ AP_DECLARE(void) ap_add_common_vars(request_rec *r)
                   apr_psprintf(r->pool, "%u", ap_get_server_port(r)));
     add_unless_null(e, "REMOTE_HOST",
                     ap_get_remote_host(c, r->per_dir_config, REMOTE_HOST, NULL));
-    apr_table_addn(e, "REMOTE_ADDR", c->remote_ip);
+    apr_table_addn(e, "REMOTE_ADDR", r->client_ip);
     apr_table_addn(e, "DOCUMENT_ROOT", ap_document_root(r));    /* Apache */
     apr_table_setn(e, "REQUEST_SCHEME", ap_http_scheme(r));
     apr_table_addn(e, "CONTEXT_PREFIX", ap_context_prefix(r));
@@ -243,7 +243,7 @@ AP_DECLARE(void) ap_add_common_vars(request_rec *r)
     apr_table_addn(e, "SERVER_ADMIN", s->server_admin); /* Apache */
     apr_table_addn(e, "SCRIPT_FILENAME", r->filename);  /* Apache */
 
-    rport = c->remote_addr->port;
+    rport = c->peer_addr->port;
     apr_table_addn(e, "REMOTE_PORT", apr_itoa(r->pool, rport));
 
     if (r->user) {