--- mod_limitipconn.c.orig 2012-04-25 22:19:48 UTC +++ mod_limitipconn.c @@ -42,6 +42,9 @@ typedef struct { /* array of MIME types to limit check; all other types are exempt */ apr_array_header_t *excl_limit; + apr_array_header_t *local_ip; /* array of local ip exempt from limit + checking */ + } limitipconn_config; static limitipconn_config *create_config(apr_pool_t *p) @@ -53,6 +56,7 @@ static limitipconn_config *create_config(apr_pool_t *p cfg->limit = 0; cfg->no_limit = apr_array_make(p, 0, sizeof(char *)); cfg->excl_limit = apr_array_make(p, 0, sizeof(char *)); + cfg->local_ip = apr_array_make(p, 0, sizeof(char *)); return cfg; } @@ -75,6 +79,7 @@ static int check_limit(request_rec *r, limitipconn_con /* convert Apache arrays to normal C arrays */ char **nolim = (char **) cfg->no_limit->elts; char **exlim = (char **) cfg->excl_limit->elts; + char **localip = (char **) cfg->local_ip->elts; const char *address; @@ -112,7 +117,7 @@ static int check_limit(request_rec *r, limitipconn_con /* Only check the MIME-type if we have MIME-type stuff in our config. The extra subreq can be quite expensive. */ - if(cfg->no_limit->nelts > 0 || cfg->excl_limit->nelts > 0) { + if(cfg->no_limit->nelts > 0 || cfg->excl_limit->nelts > 0 || cfg->local_ip->nelts) { /* Look up the Content-type of this request. We need a subrequest * here since this module might be called before the URI has been * translated into a MIME type. */ @@ -129,6 +134,20 @@ static int check_limit(request_rec *r, limitipconn_con "mod_limitipconn: uri: %s Content-Type: %s", r->uri, content_type); + /* Cycle through the local ip list; if the ip is local, + * return OK */ + + for (i = 0; i < cfg->local_ip->nelts; i++) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "mod_limitipconn: ip check: \"%s\" ? \"%s\"", address, localip[i]); + if ((ap_strcasecmp_match(address, localip[i]) == 0) + || (strncmp(localip[i], address, strlen(localip[i])) == 0)) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "mod_limitipconn: ip exempt: %s", address); + return DECLINED; + } + } + /* Cycle through the exempt list; if our content_type is exempt, * return OK */ #if AP_MODULE_MAGIC_AT_LEAST(20090131, 0) @@ -328,6 +347,24 @@ static const char *excl_limit_config_cmd(cmd_parms *pa return NULL; } +/* Parse the LocalIP directive */ +static const char *local_ip_config_cmd(cmd_parms *parms, void *mconfig, + const char *arg) +{ + limitipconn_config *cfg = (limitipconn_config *) mconfig; + limitipconn_config *scfg = (limitipconn_config *) + ap_get_module_config(parms->server->module_config, &limitipconn_module); + + if (parms->path != NULL) { + /* Per-directory context */ + *(char **) apr_array_push(cfg->local_ip) = apr_pstrdup(parms->pool, arg); + } else { + /* global context */ + *(char **) apr_array_push(scfg->local_ip) = apr_pstrdup(parms->pool, arg); + } + return NULL; +} + /* Array describing structure of configuration directives */ static command_rec limitipconn_cmds[] = { AP_INIT_TAKE1("MaxConnPerIP", limit_config_cmd, NULL, OR_LIMIT|RSRC_CONF, @@ -336,6 +373,8 @@ static command_rec limitipconn_cmds[] = { "MIME types for which limit checking is disabled"), AP_INIT_ITERATE("OnlyIPLimit", excl_limit_config_cmd, NULL, OR_LIMIT|RSRC_CONF, "restrict limit checking to these MIME types only"), + AP_INIT_ITERATE("LocalIP", local_ip_config_cmd, NULL, OR_LIMIT|RSRC_CONF, + "no checking on local IP"), {NULL}, };