*** mod_limitipconn.c.orig Sun Mar 2 23:06:20 2008 --- mod_limitipconn.c Thu Feb 4 17:32:21 2010 *************** *** 42,47 **** --- 42,50 ---- /* 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,58 **** --- 56,62 ---- 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,80 **** --- 79,85 ---- /* 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; *************** *** 108,114 **** /* 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) { /* 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. */ --- 113,119 ---- /* 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 || 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. */ *************** *** 123,128 **** --- 128,147 ---- "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 */ for (i = 0; i < cfg->no_limit->nelts; i++) { *************** *** 311,316 **** --- 330,353 ---- 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, *************** *** 319,324 **** --- 356,363 ---- "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}, };