Request: new request session flag to mark those files opened by FDT

This patch aims to fix a potential DDoS problem that can be caused
in the server quering repetitive non-existent resources.

When serving a static file, the core use Vhost FDT mechanism, but if
it sends a static error page it does a direct open(2). When closing
the resources for the same request it was just calling mk_vhost_close()
which did not clear properly the file descriptor.

This patch adds a new field on the struct session_request called 'fd_is_fdt',
which contains MK_TRUE or MK_FALSE depending of how fd_file was opened.

Thanks to Matthew Daley <mattd@bugfuzz.com> for report and troubleshoot this
problem.

Signed-off-by: Eduardo Silva <eduardo@monkey.io>
void mk_vhost_init(char *path)
{
    DIR *dir;
    unsigned long len;
    char *buf = 0;
    char *sites = 0;
    char *file;
    struct host *p_host;     /* debug */
    struct dirent *ent;
    struct file_info f_info;
    int ret;

    /* Read default virtual host file */
    mk_string_build(&sites, &len, "%s/%s/", path, config->sites_conf_dir);
    ret = mk_file_get_info(sites, &f_info);
    if (ret == -1 || f_info.is_directory == MK_FALSE) {
        mk_mem_free(sites);
        sites = config->sites_conf_dir;
    }

    mk_string_build(&buf, &len, "%s/default", sites);

    p_host = mk_vhost_read(buf);
    if (!p_host) {
        mk_err("Error parsing main configuration file 'default'");
    }
    mk_list_add(&p_host->_head, &config->hosts);
    config->nhosts++;
    mk_mem_free(buf);
    buf = NULL;


    /* Read all virtual hosts defined in sites/ */
    if (!(dir = opendir(sites))) {
        mk_mem_free(sites);
        mk_err("Could not open %s", sites);
        exit(EXIT_FAILURE);
    }

    /* Reading content */
    while ((ent = readdir(dir)) != NULL) {
        if (ent->d_name[0] == '.') {
            continue;
        }
        if (strcmp((char *) ent->d_name, "..") == 0) {
            continue;
        }
        if (ent->d_name[strlen(ent->d_name) - 1] ==  '~') {
            continue;
        }
        if (strcasecmp((char *) ent->d_name, "default") == 0) {
            continue;
        }
        file = NULL;
        mk_string_build(&file, &len, "%s/%s", sites, ent->d_name);

        p_host = mk_vhost_read(file);
        mk_mem_free(file);
        if (!p_host) {
            continue;
        }
        else {
            mk_list_add(&p_host->_head, &config->hosts);
            config->nhosts++;
        }
    }
    closedir(dir);
    mk_mem_free(sites);
}

void mk_vhost_init(char *path)
{
    DIR *dir;
    unsigned long len;
    char *buf = 0;
    char *sites = 0;
    char *file;
    struct host *p_host;     /* debug */
    struct dirent *ent;
    struct file_info f_info;
    int ret;

    /* Read default virtual host file */
    mk_string_build(&sites, &len, "%s/%s/", path, config->sites_conf_dir);
    ret = mk_file_get_info(sites, &f_info);
    if (ret == -1 || f_info.is_directory == MK_FALSE) {
        mk_mem_free(sites);
        sites = config->sites_conf_dir;
    }

    mk_string_build(&buf, &len, "%s/default", sites);

    p_host = mk_vhost_read(buf);
    if (!p_host) {
        mk_err("Error parsing main configuration file 'default'");
    }
    mk_list_add(&p_host->_head, &config->hosts);
    config->nhosts++;
    mk_mem_free(buf);
    buf = NULL;


    /* Read all virtual hosts defined in sites/ */
    if (!(dir = opendir(sites))) {
        mk_mem_free(sites);
        mk_err("Could not open %s", sites);
        exit(EXIT_FAILURE);
    }

    /* Reading content */
    while ((ent = readdir(dir)) != NULL) {
        if (ent->d_name[0] == '.') {
            continue;
        }
        if (strcmp((char *) ent->d_name, "..") == 0) {
            continue;
        }
        if (ent->d_name[strlen(ent->d_name) - 1] ==  '~') {
            continue;
        }
        if (strcasecmp((char *) ent->d_name, "default") == 0) {
            continue;
        }
        file = NULL;
        mk_string_build(&file, &len, "%s/%s", sites, ent->d_name);

        p_host = mk_vhost_read(file);
        mk_mem_free(file);
        if (!p_host) {
            continue;
        }
        else {
            mk_list_add(&p_host->_head, &config->hosts);
            config->nhosts++;
        }
    }
    closedir(dir);
    mk_mem_free(sites);
}
