]> granicus.if.org Git - apache/commitdiff
Introduce a per request version of the remote IP address, which can be
authorGraham Leggett <minfrin@apache.org>
Tue, 22 Nov 2011 13:10:39 +0000 (13:10 +0000)
committerGraham Leggett <minfrin@apache.org>
Tue, 22 Nov 2011 13:10:39 +0000 (13:10 +0000)
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).

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1204968 13f79535-47bb-0310-9956-ffa450edef68

18 files changed:
include/httpd.h
modules/aaa/mod_access_compat.c
modules/aaa/mod_authz_host.c
modules/arch/netware/mod_nw_ssl.c
modules/filters/mod_ext_filter.c
modules/http/http_request.c
modules/loggers/mod_log_config.c
modules/mappers/mod_rewrite.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/log.c
server/protocol.c
server/request.c
server/util_expr_eval.c

index 39d10e1c4c4d90ee40e1d0b80411a0081142fa7d..c56a88b5b27dc5e7dbfd3a93e64702f0ea3c1410 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 *remote_addr;
+    char *remote_ip;
 };
 
 /**
index 3d5d535f44c4239cb3140774db4354f340b03260..00352bada9341b47c78b294999293a1e4bed7d71 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->remote_addr)) {
                 return 1;
             }
             break;
index 2bc7f20e87d85cc989971e2637b98e60fd3dfff5..f418cbe140b51ffb09d94b9a07257b340af3c10b 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->remote_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->remote_addr)
+         || apr_ipsubnet_test(localhost_v4, r->remote_addr)
 #if APR_HAVE_IPV6
-         || apr_ipsubnet_test(localhost_v6, r->connection->remote_addr)
+         || apr_ipsubnet_test(localhost_v6, r->remote_addr)
 #endif
         )
      {
index 7b64ebfa2fc99c72b64de937f45ed7d87c9b8a1c..ce7a4171a51961d14b589623e2bc504b123ba250 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->remote_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 1fd0a9ef6babdd957a16100a498c91c76faec64d..558e990e4a45dc73cdce6f2c35dfb68a99321987 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->remote_ip,
                     err,
                     apr_strerror(err, errbuf, sizeof(errbuf)),
                     description);
index 9d67a29a9d5446d31cda329a83e68ea99430ac6d..66da594930949f2dcb9e8de32866213a8257f1a4 100644 (file)
@@ -439,6 +439,9 @@ static request_rec *internal_internal_redirect(const char *new_uri,
     new->prev = r;
     r->next   = new;
 
+    new->remote_addr = r->remote_addr;
+    new->remote_ip = r->remote_ip;
+
     /* Must have prev and next pointers set before calling create_request
      * hook.
      */
index fc7b83ae1e33427b31bf0cf3723fef3ba1cfc8da..1f7642771c2b283dd73efd12499618e64cdcdef9 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->remote_ip;
+    }
+    else {
+        return r->remote_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->remote_addr->port;
     }
     else if (!strcasecmp(a, "local")) {
         port = r->connection->local_addr->port;
index 014f591110fcf84d0d631a18933664094ed02b96..1cb4f1ca7420a8dcd55cfc09b51f77d87fce8624 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->remote_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->remote_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->remote_addr->port);
                 }
                 break;
 
index 246937bac7a1e2be8469b2ace33e3f0ab92f0d70..43622eb9ec387fd61b4b011d6d723c700bbe460b 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 *remote_addr;
+    char *remote_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,54 +216,34 @@ 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
 
     while (remote) {
 
@@ -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,14 +347,13 @@ 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 */
@@ -408,64 +367,41 @@ static int remoteip_modify_connection(request_rec *r)
             }
         }
 
-        c->remote_addr = temp_sa;
-        apr_sockaddr_ip_get(&c->remote_ip, c->remote_addr);
+        req->remote_addr = temp_sa;
+        apr_sockaddr_ip_get(&req->remote_ip, req->remote_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->remote_addr = req->remote_addr;
+    r->remote_ip = req->remote_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->remote_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..383f6b73e066d67eee9cf536807be760508fcc93 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->remote_ip;
                     break;
                 case SPECIAL_SERVER_ADDR:
                     val = r->connection->local_ip;
index 0fc8e195ff991397d777f76428e08e16be85e037..80977b0a64f1808c7e03f8116a57272a0ec0fbb5 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->remote_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->remote_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..909fe301687f4c8fa32634c6408deb23c206706e 100644 (file)
@@ -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->remote_ip);
 
            /* Add X-Forwarded-Host: so that upstream knows what the
             * original request hostname was.
index 0ba483125fd95239c63957784da53dd52809b60b..cb0b04110b3339a524008396691ebf8bcbd3a2a1 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->remote_ip);
 
             ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
                           "Failed expression: %s", req->cpExpr);
index c0e933d303dbaa0fb83939816a6b63e00b475cf2..5e6edf211836456273eccdb4da76cae8c2e8405c 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->remote_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 605d75bbeabb0b2cba9651fa7b2e564bdc6bcf9c..641d256af60e9727556ec1f5cede31ff11855ba9 100644 (file)
@@ -561,7 +561,10 @@ 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)
+    if (info->r)
+        return apr_snprintf(buf, buflen, "%s:%d", info->r->remote_ip,
+                            info->r->remote_addr->port);
+    else if (info->c)
         return apr_snprintf(buf, buflen, "%s:%d", info->c->remote_ip,
                             info->c->remote_addr->port);
     else
@@ -578,6 +581,16 @@ static int log_local_address(const ap_errorlog_info *info, const char *arg,
         return 0;
 }
 
+static int log_conn_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);
+    else
+        return 0;
+}
+
 static int log_pid(const ap_errorlog_info *info, const char *arg,
                    char *buf, int buflen)
 {
@@ -897,6 +910,7 @@ AP_DECLARE(void) ap_register_log_hooks(apr_pool_t *p)
     ap_register_errorlog_handler(p, "T", log_tid, 0);
     ap_register_errorlog_handler(p, "v", log_virtual_host, 0);
     ap_register_errorlog_handler(p, "V", log_server_name, 0);
+    ap_register_errorlog_handler(p, "d", log_conn_remote_address, 0);
 }
 
 /*
@@ -958,11 +972,16 @@ 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.
-         */
+    /*
+     * remote_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->remote_ip, info->r->remote_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);
index 2d2bc05ca092c11b1f8c523503cc2c81a495cc46..d111e5fb454a79e85c9b7d49c6b1a4452798b4bf 100644 (file)
@@ -979,6 +979,9 @@ request_rec *ap_read_request(conn_rec *conn)
      */
     r->used_path_info = AP_REQ_DEFAULT_PATH_INFO;
 
+    r->remote_addr = conn->remote_addr;
+    r->remote_ip = conn->remote_ip;
+
     tmp_bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
 
     ap_run_pre_read_request(r, conn);
index f8f0605674a0f166f716414fb1b834ba2ba1eed8..a5d0f62f81245958e2c5a1baaeb07c325c9b9242 100644 (file)
@@ -1832,6 +1832,9 @@ static request_rec *make_sub_request(const request_rec *r,
         rnew->output_filters = r->proto_output_filters;
     }
 
+    rnew->remote_addr = r->remote_addr;
+    rnew->remote_ip = r->remote_ip;
+
     /* no input filters for a subrequest */
 
     ap_set_sub_req_protocol(rnew, r);
index 81143e5ac4989b84bd030a8f899215b53b9f1703..d1199d1703095c9835a86e03c6b7db16c666c21f 100644 (file)
@@ -1181,10 +1181,9 @@ 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 */
     NULL
 };
 
@@ -1197,13 +1196,11 @@ 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;
@@ -1216,7 +1213,7 @@ 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;
     default:
         ap_assert(0);
@@ -1253,6 +1250,7 @@ static const char *request_var_names[] = {
     "CONTEXT_PREFIX",           /* 25 */
     "CONTEXT_DOCUMENT_ROOT",    /* 26 */
     "REQUEST_STATUS",           /* 27 */
+    "REMOTE_ADDR",              /* 28 */
     NULL
 };
 
@@ -1338,6 +1336,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->remote_ip;
     default:
         ap_assert(0);
         return NULL;
@@ -1483,10 +1483,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->remote_addr);
 }
 
 static int op_T(ap_expr_eval_ctx_t *ctx, const void *data, const char *arg)