Exemplo n.º 1
0
/* ------------------------------------------- */
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;
}
Exemplo n.º 2
0
/* 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;
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
long get_file_next_counter() {
    return get_file_counter();
}