Пример #1
0
/** @brief Parse the resource record in its components
 *
 *  For not found values, default values will be used.
 *  Default values are "origin" and "label". "Origin" always exists, but if
 *  "label" does not exist, "origin" will be the "label"
 *
 *  @param[in] rr_line
 *  @param[in,out] label
 *  @param[in,out] origin
 *  @param[in] default_ttl
 *  @param[in] default qclass
 *  @param[out] rr
 *
 *  @retval OK
 *  @retval NOK
 */
ya_result
rr_parse_line(char *src, const u8 *origin, u8 *label, u32 *ttl, resource_record *rr, int *bracket_status)
{
    ya_result                                              return_code = OK;
    char                                                   *needle = NULL;

    /*    ------------------------------------------------------------    */

    if(*bracket_status == BRACKET_CLOSED)
    {
        bool no_ttl = TRUE;
	
        if(FAIL(return_code = rr_check_qname(&src, rr->name, origin, label)))
        {
            return return_code;
        }

        while(*src)
        {
            if(rr->type != 0 )
            {
                break;
            }

            needle = src;
            /* Search for word and cut */
            CUT_WORD(needle);

            if(FAIL(return_code =  parse_u32_check_range(src, &rr->ttl, 0, MAX_U32, /*BASE_*/10)))
            {
                if(FAIL(return_code = get_class_from_name(src, &rr->class)))
                {
                    if(FAIL(return_code = get_type_from_name(src, &rr->type)))
                    {
                        return ZRE_NO_TYPE_FOUND;
                    }
                }
            }
            else
            {
                no_ttl = FALSE;
            }

//            format("rr_parse_line 1: %s\n", src);
            src = needle;
//            format("rr_parse_line 2: %s\n", src);
            SKIP_WHSPACE(src);
//            format("rr_parse_line 3: %s\n", src);
        }
Пример #2
0
static ya_result
config_zone_section_assign(config_data *config)
{
    u32 port = 0;
    ya_result return_code;

    config_zone_section_register(config);

    if(FAIL(return_code = parse_u32_check_range(config->server_port, &port, 1, MAX_U16, 10)))
    {
        osformatln(termerr, "config: zone: wrong dns port set in main '%s': %r", config->server_port, return_code);

        return return_code;
    }

    zone_set_lock(&config->zones);

    treeset_avl_iterator iter;
    treeset_avl_iterator_init(&config->zones.set, &iter);

    while(treeset_avl_iterator_hasnext(&iter))
    {
        treeset_node *zone_node = treeset_avl_iterator_next_node(&iter);
        zone_data *zone = (zone_data *)zone_node->data;

        zone_setdefaults(zone);

        if(!config_check_bounds_s32(SIGNATURE_VALIDITY_INTERVAL_MIN, SIGNATURE_VALIDITY_INTERVAL_MAX, zone->sig_validity_interval, "sig-validity-interval"))
        {
            return ERROR;
        }

        if(!config_check_bounds_s32(SIGNATURE_VALIDITY_REGENERATION_MIN, SIGNATURE_VALIDITY_REGENERATION_MAX, zone->sig_validity_regeneration, "sig-validity-regeneration"))
        {
            return ERROR;
        }

        if(!config_check_bounds_s32(SIGNATURE_VALIDITY_JITTER_MIN, SIGNATURE_VALIDITY_JITTER_MAX, zone->sig_validity_jitter, "sig-validity-jitter"))
        {
            return ERROR;
        }

        if(!config_check_bounds_s32(NOTIFY_RETRY_COUNT_MIN, NOTIFY_RETRY_COUNT_MAX, zone->notify.retry_count, "notify-retry-count"))
        {
            return ERROR;
        }

        if(!config_check_bounds_s32(NOTIFY_RETRY_PERIOD_MIN, NOTIFY_RETRY_PERIOD_MAX, zone->notify.retry_period, "notify-period-count"))
        {
            return ERROR;
        }

        if(!config_check_bounds_s32(NOTIFY_RETRY_PERIOD_INCREASE_MIN, NOTIFY_RETRY_PERIOD_INCREASE_MAX, zone->notify.retry_period_increase, "notify-period-increase"))
        {
            return ERROR;
        }

        zone->ctrl_flags |= ZONE_CTRL_FLAG_READ_FROM_CONF;
    }

    zone_set_unlock(&config->zones);

    return SUCCESS;
}
Пример #3
0
static ya_result
config_main_section_postprocess(struct config_section_descriptor_s *csd)
{
    u32 port = 0;
    u32 cpu_per_core = (sys_has_hyperthreading())?2:1;
    int ret;
    char tmp[PATH_MAX];



    if(FAIL(parse_u32_check_range(g_config->server_port, &port, 1, MAX_U16, 10)))
    {
        port = DNS_DEFAULT_PORT;
        ttylog_err("config: main: wrong dns port set in main '%s', defaulted to %d", g_config->server_port, port);
    }
    
    if(g_config->hostname_chaos == NULL)
    {
#if _BSD_SOURCE || _XOPEN_SOURCE >= 500 || /* Since glibc 2.12: */ _POSIX_C_SOURCE >= 200112L 
        if(gethostname(tmp, sizeof(tmp)) == 0)
        {
            g_config->hostname_chaos = strdup(tmp);
        }
        else
        {
            osformatln(termerr,"config: main: unable to get hostname: %r", ERRNO_ERROR);
            g_config->hostname_chaos = strdup("not disclosed");
        }
#else
        g_config->hostname_chaos = strdup("not disclosed");
#endif
    }
       
    if(g_config->thread_affinity_multiplier == 0)
    {
        g_config->thread_affinity_multiplier = cpu_per_core;
    }
    
    class_ch_set_hostname(g_config->hostname_chaos);    
    class_ch_set_id_server(g_config->serverid_chaos);
    class_ch_set_version(g_config->version_chaos);
    
    host_set_default_port_value(g_config->listen, ntohs(port));

    if(g_config->server_flags & SERVER_FL_CHROOT)
    {
        uid_t euid = geteuid();
        
        if(euid != 0)
        {
            ttylog_err("config: main: chroot has been enabled but euid is not root (%i != 0)", (int)euid);
            return INVALID_STATE_ERROR;
        }
    }
    else // disables the base-path/chroot-path feature
    {
        if(strcmp(g_config->chroot_path, "/") != 0)
        {
            free(g_config->chroot_path);
            g_config->chroot_path = strdup("/");
            chroot_set_path(g_config->chroot_path);
        }
    }
    
    message_edns0_setmaxsize(g_config->edns0_max_size);    
    
    g_config->total_interfaces = host_address_count(g_config->listen);
    
    if(g_config->total_interfaces > MAX_INTERFACES)
    {
        ttylog_err("error: more than %d listening addresses defined.", MAX_INTERFACES);
        return CONFIG_TOO_MANY_HOSTS;
    }

#ifndef SO_REUSEPORT
    if(g_config->network_model == 1)
    {
        ttylog_err("error: network-model 1 requires features not available on this system (SO_REUSEPORT)");
        return FEATURE_NOT_SUPPORTED;
    }
#endif
    
    g_config->axfr_retry_jitter = BOUND(AXFR_RETRY_JITTER_MIN, g_config->axfr_retry_jitter, g_config->axfr_retry_delay);
    
    g_config->dnssec_thread_count = BOUND(1, g_config->dnssec_thread_count, sys_get_cpu_count());
    
    if(g_config->cpu_count_override > 0)
    {
        sys_set_cpu_count(g_config->cpu_count_override);
    }

    if(g_config->thread_count_by_address == 0)
    {
        ttylog_err("config: single thread engine has been removed, thread-count-by-address set to 1");
        g_config->thread_count_by_address = 1;
    }
    
    if(g_config->thread_count_by_address < 0)
    {
        g_config->thread_count_by_address = MAX(sys_get_cpu_count() / cpu_per_core, 1);
    }
    else if((g_config->thread_count_by_address > sys_get_cpu_count()))
    {
        g_config->thread_count_by_address = MAX(sys_get_cpu_count() / cpu_per_core, 1);
        ttylog_err("config: bounding down thread-count-by-address to the number of physical CPUs (%d)", g_config->thread_count_by_address);
    }
    
    g_config->tcp_query_min_rate_us = g_config->tcp_query_min_rate * 0.000001;
    
#if HAS_DNSSEC_SUPPORT
    g_config->dnssec_thread_count = BOUND(1, g_config->dnssec_thread_count, sys_get_cpu_count());

    if(!IS_TYPE_PRIVATE(g_config->sig_signing_type))
    {
        ttylog_err("error: signing type is not in the accepted range: %hx", g_config->sig_signing_type);
        return CONFIG_WRONG_SIG_TYPE;
    }
    
    if(g_config->sig_validity_interval > SIGNATURE_VALIDITY_INTERVAL_MAX)
    {
        ttylog_err("error: signature validity interval too high");
        return CONFIG_WRONG_SIG_VALIDITY;
    }

    if(g_config->sig_validity_regeneration * SIGNATURE_VALIDITY_REGENERATION_S * 2 > g_config->sig_validity_interval * SIGNATURE_VALIDITY_INTERVAL_S)
    {
        ttylog_err("error: default signature regeneration is more than half the interval (%ds * 2 > %ds)",
                g_config->sig_validity_regeneration * SIGNATURE_VALIDITY_REGENERATION_S,
                g_config->sig_validity_interval * SIGNATURE_VALIDITY_INTERVAL_S);
        return CONFIG_WRONG_SIG_REGEN;
    }
#endif


    
    /// @note config_main_verify_and_update_directory updates the folder with the base_path
    
    /**
     * 
     * @note All base paths are updated with the chroot variable so it does not
     *       need to be added all the time.
     * 
     */
    
    const char *base_path = g_config->chroot_path;

    if(FAIL(ret = config_main_verify_and_update_directory(base_path, &g_config->data_path)))
    {
        return ret;
    }
    
    if(FAIL(ret = config_main_verify_and_update_directory(base_path, &g_config->keys_path)))
    {
        return ret;
    }
    
    if(FAIL(ret = config_main_verify_and_update_directory(base_path, &g_config->log_path)))
    {
        return ret;
    }
#if 0 /* fix */
#else
    if(FAIL(ret = config_main_verify_and_update_file(base_path, &g_config->pid_file)))
    {
        return ret;
    }
#endif
    
    g_config->reloadable = TRUE;
    
    if((g_config->server_flags & SERVER_FL_CHROOT) != 0)
    {
        if(FAIL(chroot_manage_path(&g_config->config_file, g_config->config_file, FALSE)))
        {
            log_warn("config file '%s' will not be accessible within the chroot jail '%s' : config reload will not work", g_config->config_file, base_path);
            g_config->reloadable = FALSE;
        }
    }
    
    if(FAIL(ret = config_main_verify_and_update_directory(base_path, &g_config->xfr_path)))
    {
        return ret;
    }
    
#if ZDB_HAS_DNSSEC_SUPPORT
    dnssec_keystore_setpath(g_config->keys_path);
    dnssec_set_xfr_path(g_config->xfr_path);
    journal_set_xfr_path(g_config->xfr_path);
#endif
    
    if((logger_get_uid() != g_config->uid) || (logger_get_gid() != g_config->gid))
    {
        logger_set_uid(g_config->uid);
        logger_set_gid(g_config->gid);
        
        logger_reopen();
    }
    
    return SUCCESS;
}