/* ------------------------------------------- */ static int vlimit_logging(const char *msg, request_rec *r, vlimit_config *cfg, SHM_DATA *limit_stat) { int len; time_t t; char *log_time; char *vlimit_log_buf; if (access(VLIMIT_LOG_FLAG_FILE, F_OK) == 0) { time(&t); log_time = (char *)ctime(&t); len = strlen(log_time); log_time[len - 1] = '\0'; vlimit_log_buf = (char *)apr_psprintf(r->pool , "[%s] pid=[%d] name=[%s] client=[%s] %s ip_count: %d/%d file_count: %d/%d file=[%s] \n" , log_time , getpid() , apr_table_get(r->headers_in, "HOST") , r->connection->remote_ip , msg , get_ip_counter(limit_stat, r) , cfg->ip_limit , get_file_counter(limit_stat, r) , cfg->file_limit , r->filename ); apr_file_puts(vlimit_log_buf, vlimit_log_fp); apr_file_flush(vlimit_log_fp); return 0; } return -1; }
/* Generic function to check a request against a config. */ static int vlimit_check_limit(request_rec *r, vlimit_config *cfg) { const char *header_name; int ip_count = 0; int file_count = 0; int counter_stat = 0; if (!ap_is_initial_req(r)) { VLIMIT_DEBUG_SYSLOG("vlimit_check_limit: ", "SKIPPED: Initial Reqeusts.", r->pool); return DECLINED; } if (cfg->ip_limit <= 0 && cfg->file_limit <= 0) { VLIMIT_DEBUG_SYSLOG("vlimit_check_limit: ", "SKIPPED: cfg->ip_limit <= 0 && cfg->file_limit <= 0", r->pool); return DECLINED; } header_name = apr_table_get(r->headers_in, "HOST"); vlimit_debug_log_buf = apr_psprintf(r->pool, "client info: address=(%s) header_name=(%s)" , r->connection->remote_ip , header_name ); VLIMIT_DEBUG_SYSLOG("vlimit_check_limit: ", vlimit_debug_log_buf, r->pool); SHM_DATA *limit_stat; limit_stat = shm_base + cfg->conf_id; if (make_ip_slot_list(limit_stat, r) != -1) VLIMIT_DEBUG_SYSLOG("vlimit_check_limit: ", "make_ip_slot_list exec. create list(" VLIMIT_IP_STAT_FILE ").", r->pool); if (make_file_slot_list(limit_stat, r) != -1) VLIMIT_DEBUG_SYSLOG("vlimit_check_limit: ", "make_file_slot_list exec. create list(" VLIMIT_FILE_STAT_FILE ").", r->pool); if (check_virtualhost_name(r)) { VLIMIT_DEBUG_SYSLOG("vlimit_check_limit: ", "header_name != server_hostname. return OK.", r->pool); return OK; } // vlimit_mutex lock VLIMIT_DEBUG_SYSLOG("vlimit_check_limit: ", "vlimit_mutex locked.", r->pool); if (apr_global_mutex_lock(vlimit_mutex) != APR_SUCCESS) { VLIMIT_DEBUG_SYSLOG("vlimit_check_limit: ", "vlimit_mutex lock failed.", r->pool); return OK; } if (cfg->file_limit > 0) { VLIMIT_DEBUG_SYSLOG("vlimit_check_limit: ", "type File: file_count++", r->pool); counter_stat = inc_file_counter(limit_stat, r); if (counter_stat == -1) { VLIMIT_DEBUG_SYSLOG("vlimit_check_limit: ", "file counter slot full. maxclients?", r->pool); return HTTP_SERVICE_UNAVAILABLE; } file_count = get_file_counter(limit_stat, r); cfg->file_match = 1; } else if (cfg->ip_limit > 0) { VLIMIT_DEBUG_SYSLOG("vlimit_check_limit: ", "type IP: ip_count++", r->pool); counter_stat = inc_ip_counter(limit_stat, r); if (counter_stat == -1) { VLIMIT_DEBUG_SYSLOG("vlimit_check_limit: ", "ip counter slot full. maxclients?", r->pool); return HTTP_SERVICE_UNAVAILABLE; } ip_count = get_ip_counter(limit_stat, r); cfg->ip_match = 1; } // vlimit_mutex unlock VLIMIT_DEBUG_SYSLOG("vlimit_check_limit: ", "vlimit_mutex unlocked.", r->pool); if (apr_global_mutex_unlock(vlimit_mutex) != APR_SUCCESS){ VLIMIT_DEBUG_SYSLOG("vlimit_check_limit: ", "vlimit_mutex unlock failed.", r->pool); return OK; } vlimit_debug_log_buf = apr_psprintf(r->pool , "conf_id: %d name: %s uri: %s ip_count: %d/%d file_count: %d/%d" , cfg->conf_id , r->server->server_hostname , r->filename , ip_count , cfg->ip_limit , file_count , cfg->file_limit ); VLIMIT_DEBUG_SYSLOG("vlimit_check_limit: ", vlimit_debug_log_buf, r->pool); if (cfg->ip_limit > 0 && ip_count > cfg->ip_limit) { vlimit_debug_log_buf = apr_psprintf(r->pool , "Rejected, too many connections from this host(%s) to the file(%s) by VlimitIP[ip_limig=(%d) docroot=(%s)]." , r->connection->remote_ip , header_name , cfg->ip_limit , cfg->full_path ); VLIMIT_DEBUG_SYSLOG("vlimit_check_limit: ", vlimit_debug_log_buf, r->pool); if (counter_stat != -2) vlimit_logging("RESULT: 503 INC", r, cfg, limit_stat); return HTTP_SERVICE_UNAVAILABLE; } else if (cfg->file_limit > 0 && file_count > cfg->file_limit) { vlimit_debug_log_buf = apr_psprintf(r->pool , "Rejected, too many connections to the file(%s) by VlimitFile[limit=(%d) docroot=(%s)]." , header_name , cfg->file_limit , cfg->full_path ); VLIMIT_DEBUG_SYSLOG("vlimit_check_limit: ", vlimit_debug_log_buf, r->pool); if (counter_stat != -2) vlimit_logging("RESULT: 503 INC", r, cfg, limit_stat); return HTTP_SERVICE_UNAVAILABLE; //return HTTP_NOT_FOUND; } else { VLIMIT_DEBUG_SYSLOG("vlimit_check_limit: ", "OK: Passed all checks", r->pool); if (counter_stat != -2) vlimit_logging("RESULT: OK INC", r, cfg, limit_stat); return OK; } return OK; }
static int vlimit_response_end(request_rec *r) { int counter_stat = -2; VLIMIT_DEBUG_SYSLOG("vlimit_response_end: ", "start", r->pool); vlimit_config *cfg = (vlimit_config *) ap_get_module_config(r->per_dir_config, &vlimit_module); SHM_DATA *limit_stat; limit_stat = shm_base + cfg->conf_id; // vlimit_mutex lock VLIMIT_DEBUG_SYSLOG("vlimit_response_end: ", "vlimit_mutex locked.", r->pool); if (apr_global_mutex_lock(vlimit_mutex) != APR_SUCCESS) { VLIMIT_DEBUG_SYSLOG("vlimit_response_end: ", "vlimit_mutex lock failed.", r->pool); return OK; } if (cfg->conf_id != 0 && cfg->file_match == 1) { VLIMIT_DEBUG_SYSLOG("vlimit_response_end: ", "type FILE: file_count--", r->pool); if (get_file_counter(limit_stat, r) > 0) counter_stat = dec_file_counter(limit_stat, r); if (get_file_counter(limit_stat, r) == 0) unset_file_counter(limit_stat, r); cfg->file_match = 0; if (counter_stat != -2) vlimit_logging("RESULT: END DEC", r, cfg, limit_stat); } if (cfg->conf_id != 0 && cfg->ip_match == 1) { VLIMIT_DEBUG_SYSLOG("vlimit_response_end: ", "type IP: ip_count--", r->pool); if (get_ip_counter(limit_stat, r) > 0) counter_stat = dec_ip_counter(limit_stat, r); if (get_ip_counter(limit_stat, r) == 0) unset_ip_counter(limit_stat, r); cfg->ip_match = 0; if (counter_stat != -2) vlimit_logging("RESULT: END DEC", r, cfg, limit_stat); } // vlimit_mutex unlock VLIMIT_DEBUG_SYSLOG("vlimit_response_end: ", "vlimit_mutex unlocked.", r->pool); if (apr_global_mutex_unlock(vlimit_mutex) != APR_SUCCESS) { VLIMIT_DEBUG_SYSLOG("vlimit_response_end: ", "vlimit_mutex unlock failed.", r->pool); return OK; } vlimit_debug_log_buf = apr_psprintf(r->pool , "conf_id: %d name: %s uri: %s ip_count: %d/%d file_count: %d/%d" , cfg->conf_id , r->server->server_hostname , r->filename , get_ip_counter(limit_stat, r) , cfg->ip_limit , get_file_counter(limit_stat, r) , cfg->file_limit ); VLIMIT_DEBUG_SYSLOG("vlimit_response_end: ", vlimit_debug_log_buf, r->pool); VLIMIT_DEBUG_SYSLOG("vlimit_response_end: ", "end", r->pool); return OK; }
long get_file_next_counter() { return get_file_counter(); }