示例#1
0
文件: dnscore.c 项目: koodaamo/yadifa
void
dnscore_init()
{
    if(dnscore_init_done)
    {
        return;
    }

    dnscore_init_done = TRUE;
    dnscore_arch_checkup();

    //random_init(time(NULL));
    
    thread_pool_setup_random_ctx();
    random_ctx rnd = thread_pool_get_random_ctx();
    
    // random NEEDS to work.
    {
        u32 r0 = random_next(rnd);
        u32 r1 = random_next(rnd);
        u32 r2 = random_next(rnd);
        u32 r3 = random_next(rnd);
       
        if( ((r0 == 0) && (r1 == 0) && (r2 == 0) && (r3 == 0)) || ((r0 == r1) && (r1 == r2) && (r2 == r3)) ) 
        {
            printf("panic: random generation fails. (%08x,%08x,%08x,%08x)\n", r0, r1, r2, r3);
            exit(-1);
        }
    }

    rfc_init();

    format_class_init();
    dnsformat_class_init();
    stdstream_init();
    logger_init();

    dnscore_register_errors();

#if HAS_TSIG_SUPPORT
    tsig_register_algorithms();
#endif

    atexit(dnscore_finalize);

    dnscore_reset_timer();
}
示例#2
0
static ya_result
xfr_query_callback(void* data)
{
    xfr_query_schedule_param *xqsp = (xfr_query_schedule_param*)data;
    ya_result return_value;
	ya_result scheduler_status;
    u32 refreshed_time = 0;
    u32 retried_time = time(NULL);
    
    /*
     * Zone refresh will be enabled (again) here.
     * 
     * xfr_query_mark_zone_loaded
     * 
     */

    
    if(ISOK(xqsp->return_value))
    {
        /* success but type == 0 => transfer done */
        
        if(xqsp->type != 0)
        {
            log_info("slave: %{dnstype}: proceeding with transfer of %{dnsname}", &xqsp->type, xqsp->origin);
        }
    }
    else
    {
        log_err("slave: %{dnstype}: transfer of %{dnsname} failed: %r", &xqsp->type, xqsp->origin, xqsp->return_value);
        
        /*
         * Here (?) put the invalid zone placeholder if it is not there yet
         */
    }

    switch(xqsp->type)
    {
        case TYPE_AXFR:
        {
            /*
             * Load the axfr
             */
            
            if(ISOK(xqsp->return_value))
            {
                axfr_query_axfr_load_param *aqalp;
                MALLOC_OR_DIE(axfr_query_axfr_load_param*, aqalp, sizeof(axfr_query_axfr_load_param), GENERIC_TAG);
                
                log_info("slave: opening AXFR for %{dnsname} %d", xqsp->origin, xqsp->loaded_serial);

                if(ISOK(return_value = zone_axfr_reader_open_with_serial(g_config->xfr_path, xqsp->origin, xqsp->loaded_serial, &aqalp->zr)))
                {
                    /*
                     * The system is ready to load an AXFR
                     * A zone is already in place (by design), there may be an old zone that is now irrelevant.
                     * At this point ...
                     * 
                     * If the serial are not the same
                     *      MT the old zone must be destroyed (if it exist)
                     *       then
                     *      MT The new zone has to be created (loaded from the AXFR file)
                     * Else
                     *      ST The new zone is actually the old zone, and the old zone is non-existent
                     * EndIf
                     * 
                     * then
                     * 
                     * ST The new zone and the placeholder zone have to be swapped, then the placeholder has to be destroyed
                     * 
                     */
                    
                    zdb_zone *zone = zdb_zone_find_from_dnsname((zdb*)xqsp->db, xqsp->origin, CLASS_IN);

                    if(zone != NULL)
                    {
                        zdb_zone_truncate_invalidate(zone);
                    }                    

                    /**
                     * schedule the axfr load
                     */

                    aqalp->old_zone = NULL; /* old zone */
                    aqalp->new_zone = NULL;
                    aqalp->db = xqsp->db;
                    aqalp->origin = dnsname_dup(xqsp->origin);

                    scheduler_status = SCHEDULER_TASK_PROGRESS;

                    thread_pool_schedule_job(xfr_query_axfr_load_thread, aqalp, NULL, "axfr load");
                    
                    break;
                }
            }
            
            /**
             * @todo If the "old_zone" exists, then ... (destroy ? swap back ? expired ?)
             * 
             */
            
            /*
             * An issue occurred (AXFR transfer, load)
             */
			
            log_err("slave: unable to load the axfr (retry set in %d seconds)", g_config->axfr_retry_delay);

            alarm_event_node *event = alarm_event_alloc();

            event->epoch = time(NULL) + g_config->axfr_retry_delay;

            if(g_config->axfr_retry_jitter > 0)
            {
                random_ctx rndctx = thread_pool_get_random_ctx();
                u32 jitter = random_next(rndctx) % g_config->axfr_retry_jitter;
                event->epoch += jitter;
            }

            event->function = scheduler_axfr_query_alarm;
            event->args = xqsp;
            event->key = ALARM_KEY_ZONE_AXFR_QUERY;
            event->flags = ALARM_DUP_NOP;
            event->text = "scheduler_axfr_query_alarm";

            zdb *db = (zdb*)xqsp->db;
            alarm_set(db->alarm_handle, event);

            /* DO NOT FREE xqsp, SO DO NOT BREAK : return now */
            
            return SCHEDULER_TASK_FINISHED;
        }
        
        case TYPE_IXFR:
        {
            /**
             * Load the ixfr (single thread, zone locked)
             */

			scheduler_status = SCHEDULER_TASK_FINISHED;

            if(ISOK(xqsp->return_value))
            {
                zdb_zone *dbzone = zdb_zone_find_from_dnsname((zdb*)xqsp->db, xqsp->origin, CLASS_IN);

                if(dbzone == NULL)
                {
                    log_err("slave: zone %{dnsname} journal has vanished", xqsp->origin);
                    break;
                }
                
                log_info("slave: opening journal for '%{dnsname}'", xqsp->origin);

                zdb_zone_lock(dbzone, ZDB_ZONE_MUTEX_XFR);
                
                if(ISOK(return_value = zdb_icmtl_replay(dbzone, g_config->xfr_path, xqsp->serial_start_offset, xqsp->loaded_serial, ZDB_ICMTL_REPLAY_SERIAL_OFFSET|ZDB_ICMTL_REPLAY_SERIAL_LIMIT)))
                {
                    log_info("slave: replayed %d records changes", return_value);
                    
                    dbzone->apex->flags &= ~ZDB_RR_LABEL_INVALID_ZONE;
                    
                    refreshed_time = time(NULL);
                }
                else
                {
                    log_err("slave: replay error: %r this is bad: invalidate the zone and ask for an AXFR", return_value);
                    
                    /** @todo INVALIDATE AND AXFR */
                }
                
                /** @todo invalitate if retried_time > expired_time */

                zdb_zone_unlock(dbzone, ZDB_ZONE_MUTEX_XFR);
            }
            
            log_info("slave: journal transfer done");

            xfr_query_mark_zone_loaded((zdb*)g_config->database, xqsp->origin, refreshed_time, retried_time);
            
			scheduler_status = SCHEDULER_TASK_FINISHED;
            break;            
        }
        default:
        {
            refreshed_time = time(NULL);
            
            log_info("slave: transfer done");

            xfr_query_mark_zone_loaded((zdb*)g_config->database, xqsp->origin, refreshed_time, retried_time);
            
			scheduler_status = SCHEDULER_TASK_FINISHED;
            break;
        }
    }   /* switch return_value */