summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam A. Rowe Jr <wrowe@apache.org>2016-02-11 22:58:45 +0100
committerWilliam A. Rowe Jr <wrowe@apache.org>2016-02-11 22:58:45 +0100
commit1dd2be03ad7ec020f249e7b244a29a8b5e5e563a (patch)
tree206a49357b87948f0e47e91b0f309956d8ccaedd
parentRevert r1729897, 1729898, my copy of core.c was polluted by a different patch (diff)
downloadapache2-1dd2be03ad7ec020f249e7b244a29a8b5e5e563a.tar.xz
apache2-1dd2be03ad7ec020f249e7b244a29a8b5e5e563a.zip
Introduce an ap_get_useragent_host() accessor to replace the old
ap_get_remote_host() in most applications, but preserve the original behavior for all ap_get_remote_host() consumers (mostly, because we don't have the request_rec in the first place, and also to avoid any unintended consequences). This accessor continues to store the remote_host of connection based uesr agents within the conn_rec for optimization. Only where some other module modifies the useragent_addr will we perform a per-request query of the remote_host. (Committed previously, but backed out due to unrelated core.c changes) git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1729901 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--CHANGES5
-rw-r--r--include/ap_mmn.h4
-rw-r--r--include/http_core.h28
-rw-r--r--include/httpd.h10
-rw-r--r--server/core.c99
5 files changed, 134 insertions, 12 deletions
diff --git a/CHANGES b/CHANGES
index 188fa778ac..e7df1730c5 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,11 @@
-*- coding: utf-8 -*-
Changes with Apache 2.5.0
+ *) core: Track the useragent_host per-request when mod_remoteip or similar
+ modules track a per-request useragent_ip. Modules should be updated
+ to inquire for ap_get_useragent_host() in place of ap_get_remote_host().
+ [William Rowe]
+
*) mod_proxy: Play/restore the TLS-SNI on new backend connections which
had to be issued because the remote closed the previous/reusable one
during idle (keep-alive) time. [Yann Ylavic]
diff --git a/include/ap_mmn.h b/include/ap_mmn.h
index b25abcd4ce..aca47eb497 100644
--- a/include/ap_mmn.h
+++ b/include/ap_mmn.h
@@ -500,6 +500,8 @@
* 20150222.9 (2.5.0-dev) Add epxr_hander to core_dir_config.
* 20150222.10 (2.5.0-dev) Add new ap_update_child_status...() methods,
* add protocol to worker_score in scoreboard.h
+ * 20150222.11 (2.5.0-dev) Split useragent_host from the conn_rec into
+ * the request_rec, with ap_get_useragent_host()
*/
#define MODULE_MAGIC_COOKIE 0x41503235UL /* "AP25" */
@@ -507,7 +509,7 @@
#ifndef MODULE_MAGIC_NUMBER_MAJOR
#define MODULE_MAGIC_NUMBER_MAJOR 20150222
#endif
-#define MODULE_MAGIC_NUMBER_MINOR 10 /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 11 /* 0...n */
/**
* Determine if the server's current MODULE_MAGIC_NUMBER is at least a
diff --git a/include/http_core.h b/include/http_core.h
index 684fba49cf..a6f1d28b8b 100644
--- a/include/http_core.h
+++ b/include/http_core.h
@@ -159,6 +159,32 @@ AP_DECLARE(int) ap_allow_overrides(request_rec *r);
AP_DECLARE(const char *) ap_document_root(request_rec *r);
/**
+ * Lookup the remote user agent's DNS name or IP address
+ * @ingroup get_remote_hostname
+ * @param req The current request
+ * @param type The type of lookup to perform. One of:
+ * <pre>
+ * REMOTE_HOST returns the hostname, or NULL if the hostname
+ * lookup fails. It will force a DNS lookup according to the
+ * HostnameLookups setting.
+ * REMOTE_NAME returns the hostname, or the dotted quad if the
+ * hostname lookup fails. It will force a DNS lookup according
+ * to the HostnameLookups setting.
+ * REMOTE_NOLOOKUP is like REMOTE_NAME except that a DNS lookup is
+ * never forced.
+ * REMOTE_DOUBLE_REV will always force a DNS lookup, and also force
+ * a double reverse lookup, regardless of the HostnameLookups
+ * setting. The result is the (double reverse checked)
+ * hostname, or NULL if any of the lookups fail.
+ * </pre>
+ * @param str_is_ip unless NULL is passed, this will be set to non-zero on
+ * output when an IP address string is returned
+ * @return The remote hostname (based on the request useragent_ip)
+ */
+AP_DECLARE(const char *) ap_get_useragent_host(request_rec *req, int type,
+ int *str_is_ip);
+
+/**
* Lookup the remote client's DNS name or IP address
* @ingroup get_remote_host
* @param conn The current connection
@@ -180,7 +206,7 @@ AP_DECLARE(const char *) ap_document_root(request_rec *r);
* </pre>
* @param str_is_ip unless NULL is passed, this will be set to non-zero on output when an IP address
* string is returned
- * @return The remote hostname
+ * @return The remote hostname (based on the connection client_ip)
*/
AP_DECLARE(const char *) ap_get_remote_host(conn_rec *conn, void *dir_config, int type, int *str_is_ip);
diff --git a/include/httpd.h b/include/httpd.h
index 196de1d6e1..28d275b1d3 100644
--- a/include/httpd.h
+++ b/include/httpd.h
@@ -1056,6 +1056,16 @@ struct request_rec {
apr_table_t *trailers_in;
/** MIME trailer environment from the response */
apr_table_t *trailers_out;
+
+ /** Originator'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
+ * ap_get_useragent_host() */
+ char *useragent_host;
+ /** have we done double-reverse DNS? -1 yes/failure, 0 not yet,
+ * 1 yes/success
+ * TODO: 2 bit signed bitfield when this structure is compacted
+ */
+ int double_reverse;
};
/**
diff --git a/server/core.c b/server/core.c
index 6de6474624..6b540296de 100644
--- a/server/core.c
+++ b/server/core.c
@@ -887,27 +887,30 @@ char *ap_response_code_string(request_rec *r, int error_index)
/* Code from Harald Hanche-Olsen <hanche@imf.unit.no> */
-static APR_INLINE void do_double_reverse (conn_rec *conn)
+static APR_INLINE void do_double_reverse (int *double_reverse,
+ const char *remote_host,
+ apr_sockaddr_t *client_addr,
+ apr_pool_t *pool)
{
apr_sockaddr_t *sa;
apr_status_t rv;
- if (conn->double_reverse) {
+ if (*double_reverse) {
/* already done */
return;
}
- if (conn->remote_host == NULL || conn->remote_host[0] == '\0') {
+ if (remote_host == NULL || remote_host[0] == '\0') {
/* single reverse failed, so don't bother */
- conn->double_reverse = -1;
+ *double_reverse = -1;
return;
}
- rv = apr_sockaddr_info_get(&sa, conn->remote_host, APR_UNSPEC, 0, 0, conn->pool);
+ rv = apr_sockaddr_info_get(&sa, remote_host, APR_UNSPEC, 0, 0, pool);
if (rv == APR_SUCCESS) {
while (sa) {
- if (apr_sockaddr_equal(sa, conn->client_addr)) {
- conn->double_reverse = 1;
+ if (apr_sockaddr_equal(sa, client_addr)) {
+ *double_reverse = 1;
return;
}
@@ -915,7 +918,7 @@ static APR_INLINE void do_double_reverse (conn_rec *conn)
}
}
- conn->double_reverse = -1;
+ *double_reverse = -1;
}
AP_DECLARE(const char *) ap_get_remote_host(conn_rec *conn, void *dir_config,
@@ -953,7 +956,8 @@ AP_DECLARE(const char *) ap_get_remote_host(conn_rec *conn, void *dir_config,
ap_str_tolower(conn->remote_host);
if (hostname_lookups == HOSTNAME_LOOKUP_DOUBLE) {
- do_double_reverse(conn);
+ do_double_reverse(&conn->double_reverse, conn->remote_host,
+ conn->client_addr, conn->pool)
if (conn->double_reverse != 1) {
conn->remote_host = NULL;
}
@@ -967,7 +971,8 @@ AP_DECLARE(const char *) ap_get_remote_host(conn_rec *conn, void *dir_config,
}
if (type == REMOTE_DOUBLE_REV) {
- do_double_reverse(conn);
+ do_double_reverse(&conn->double_reverse, conn->remote_host,
+ conn->client_addr, conn->pool)
if (conn->double_reverse == -1) {
return NULL;
}
@@ -992,6 +997,80 @@ AP_DECLARE(const char *) ap_get_remote_host(conn_rec *conn, void *dir_config,
}
}
+AP_DECLARE(const char *) ap_get_useragent_host(request_rec *r,
+ int type, int *str_is_ip)
+{
+ conn_rec *conn = r->connection;
+ int hostname_lookups;
+ int ignored_str_is_ip;
+
+ if (req->useragent_addr == conn->client_addr) {
+ return ap_get_remote_host(conn, r->per_dir_config, type, str_is_ip);
+ }
+
+ if (!str_is_ip) { /* caller doesn't want to know */
+ str_is_ip = &ignored_str_is_ip;
+ }
+ *str_is_ip = 0;
+
+ hostname_lookups = ((core_dir_config *)
+ ap_get_core_module_config(r->per_dir_config))
+ ->hostname_lookups;
+ if (hostname_lookups == HOSTNAME_LOOKUP_UNSET) {
+ hostname_lookups = HOSTNAME_LOOKUP_OFF;
+ }
+
+ if (type != REMOTE_NOLOOKUP
+ && r->useragent_host == NULL
+ && (type == REMOTE_DOUBLE_REV
+ || hostname_lookups != HOSTNAME_LOOKUP_OFF)) {
+
+ if (apr_getnameinfo(&r->useragent_host, r->useragent_addr, 0)
+ == APR_SUCCESS) {
+ ap_str_tolower(r->useragent_host);
+
+ if (hostname_lookups == HOSTNAME_LOOKUP_DOUBLE) {
+ do_double_reverse(&r->double_reverse, r->useragent_host,
+ r->useragent_addr, r->pool)
+ if (r->double_reverse != 1) {
+ r->useragent_host = NULL;
+ }
+ }
+ }
+
+ /* if failed, set it to the NULL string to indicate error */
+ if (r->useragent_host == NULL) {
+ r->useragent_host = "";
+ }
+ }
+
+ if (type == REMOTE_DOUBLE_REV) {
+ do_double_reverse(&r->double_reverse, r->useragent_host,
+ r->useragent_addr, r->pool)
+ if (r->double_reverse == -1) {
+ return NULL;
+ }
+ }
+
+ /*
+ * Return the desired information; either the remote DNS name, if found,
+ * or either NULL (if the hostname was requested) or the IP address
+ * (if any identifier was requested).
+ */
+ if (r->useragent_host != NULL && r->useragent_host[0] != '\0') {
+ return r->useragent_host;
+ }
+ else {
+ if (type == REMOTE_HOST || type == REMOTE_DOUBLE_REV) {
+ return NULL;
+ }
+ else {
+ *str_is_ip = 1;
+ return r->useragent_ip;
+ }
+ }
+}
+
/*
* Optional function coming from mod_ident, used for looking up ident user
*/