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;
};
/**
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;
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++;
}
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
)
{
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);
if (strlen(var) > 4 && strcEQn(var, "SSL_", 4))
result = NULL;
- else if (strcEQ(var, "REMOTE_ADDR"))
- result = c->remote_ip;
}
/*
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);
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.
*/
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)
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;
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"));
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;
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;
} 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)
{
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) {
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
*/
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)) = ',';
}
remote = parse_remote;
}
break;
+
}
addrbyte = (unsigned char *) &temp_sa->sa.sin.sin_addr;
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 */
}
}
- 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;
}
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) = {
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;
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) ||
*/
{
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)) {
* 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.
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);
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);
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";
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
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)
{
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);
}
/*
}
}
- 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);
*/
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);
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);
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
};
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;
#else
return "off";
#endif
- case 3:
+ case 2:
return c->log_id;
default:
ap_assert(0);
"CONTEXT_PREFIX", /* 25 */
"CONTEXT_DOCUMENT_ROOT", /* 26 */
"REQUEST_STATUS", /* 27 */
+ "REMOTE_ADDR", /* 28 */
NULL
};
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;
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)