Example #1
0
static void*
xfr_query_axfr_load_thread(void *data)
{
    axfr_query_axfr_load_param *aqalp = (axfr_query_axfr_load_param*) data;
    ya_result return_value;

    /*
     * Now that the access has been cut, this could be done in background, with the loading
     */


    /*
     * Load the zone again
     * (other thread, with no zone visible until the very end)
     */

    zdb_zone *newzone = NULL;

    log_info("slave: zone %{dnsname} transferred", aqalp->origin);
    
    /**
     * Behaviour change : loading an zone file (axfr file) into memory will now drop (invalidate) the zone before
     * loading it.  Else loading a zone like .com would lead to potentially twice the amount of memory made readily
     * available to yadifa when most of it will remain untouched.
     * 
     * so:
     * 
     * invalidate the zone
     * drop the zone
     * load the zone
     */

    if(ISOK(return_value = zdb_zone_load((zdb*)aqalp->db, &aqalp->zr, &newzone, g_config->xfr_path, aqalp->origin, ZDB_ZONE_DESTROY_JOURNAL|ZDB_ZONE_IS_SLAVE)))
    {
        zassert(newzone != NULL);
        
        log_info("slave: zone %{dnsname} loaded", aqalp->origin);
        
        aqalp->new_zone = newzone;       
    }
    else
    {
        log_err("slave: zone %{dnsname} failed to load: %r", aqalp->origin, return_value);
        
        if(return_value == DNSSEC_ERROR_NSEC3_INVALIDZONESTATE)
        {
            /** @todo don't try for a while */
        }
    }

    zone_reader_close(&aqalp->zr);

    /*
     * At this point, since we are a slave, we need to start the alarm again.
     */

    scheduler_schedule_task(xfr_query_final_callback, aqalp);

    return NULL;
}
Example #2
0
void
scheduler_schedule_thread(scheduler_task_callback* init_function, thread_pool_function* thread_function, void* args, const char* categoryname)
{
#ifndef NDEBUG
    log_debug("scheduler: scheduler_schedule_thread(%P, %P, %p, %s)", init_function, thread_function, args, categoryname);
#endif
    
    pthread_mutex_lock(&scheduler_delayed_queue_mutex);

    scheduler_thread* thread;

    MALLOC_OR_DIE(scheduler_thread*, thread, sizeof (scheduler_thread), SCHDTHRD_TAG);
    thread->task = thread_function;
    thread->task_init = init_function;
    thread->args = args;
    thread->categoryname = categoryname;

#ifndef NDEBUG
    thread->debug_count = debug_count_current++;

    log_debug("scheduler: enqueue thread %s::(%p, %P, %P, %p@%u)", categoryname, init_function, thread_function, args, thread, thread->debug_count);
#endif


    scheduler_thread_queue_enqueue(&scheduler_delayed_queue, thread);

    // refire

    if(!scheduler_thread_running)
    {
        scheduler_schedule_task(scheduler_task_dequeue_delayed, NULL);
    }

    pthread_mutex_unlock(&scheduler_delayed_queue_mutex);
}
static void*
scheduler_queue_nsec3_update_thread(void* data_)
{
    zdb_zone *zone = (zdb_zone*)data_;

    log_info("nsec3: update %{dnsname} NSEC3", zone->origin);

    zdb_zone_lock(zone, ZDB_ZONE_MUTEX_NSEC3_UPDATER);
    nsec3_update_zone(zone);
    zdb_zone_unlock(zone, ZDB_ZONE_MUTEX_NSEC3_UPDATER);

    log_info("nsec3: update %{dnsname} RRSIG", zone->origin);

    //zdb_zone_lock(zone, ZDB_ZONE_MUTEX_RRSIG_UPDATER|0x80);
    zdb_update_zone_signatures(zone, FALSE);
    //zdb_zone_unlock(zone, ZDB_ZONE_MUTEX_RRSIG_UPDATER|0x80);

    //zdb_zone_write_text_file(zone, "eu-zone.txt.signed", FALSE);

    scheduler_schedule_task(scheduler_queue_nsec3_update_callback, zone);

    /* WARNING: From this point forward, 'zone' cannot be used anymore */

    return NULL;
}
Example #4
0
void battery_init()
{
	//Configure pin for measuring battery voltage
	BATTERY_VOLTAGE_TRIS = 1;
	BATTERY_VOLTAGE_DIGITAL = 0;

	//Configure charger controller for open drain output
	SOLAR_VOLTAGE_LATCH = 1;
	SOLAR_VOLTAGE_OD = 1;
	SOLAR_VOLTAGE_TRIS = 0;
	SOLAR_VOLTAGE_DIGITAL = 1;

	//Store ADC configuration
    batt_adc_config.output_format = kUIntegerFormat;
    batt_adc_config.trigger = kInternalCounter;
    batt_adc_config.reference = kVDDVSS;
    batt_adc_config.enable_in_idle = 0;
    batt_adc_config.sample_autostart = 1;
    batt_adc_config.scan_input = 0;
    batt_adc_config.alternate_muxes = 0;
    batt_adc_config.autosample_wait = 0b11111;

    batt_adc_config.oneshot = 1;
    batt_adc_config.num_samples = 1;

    charging_allowed = 1;

	scheduler_schedule_task(battery_callback, kEvery10Seconds, kScheduleForever, &battery_task);
}
static void*
scheduler_queue_dnskey_create_thread(void* data_)
{
    scheduler_dnskey_create *data = (scheduler_dnskey_create*)data_;
    ya_result return_value;
    
    log_info("dnssec: key create (%{dnsname} %hd %hhd %hd)", data->zone->origin, data->flags, data->algorithm, data->size);

    char origin[MAX_DOMAIN_LENGTH];

    dnsname_to_cstr(origin, data->zone->origin);

    dnssec_key* key;
    
    if(ISOK(return_value = dnssec_key_createnew(DNSKEY_ALGORITHM_RSASHA1_NSEC3, data->size, data->flags, origin, &key)))
    {
        if(ISOK(return_value = dnssec_key_store_private(key)))
        {
            if(ISOK(return_value = dnssec_key_store_dnskey(key)))
            {
                log_info("dnssec: key created (%{dnsname} %hd %hhd %hd)", data->zone->origin, data->flags, data->algorithm, data->size);    
            }
            else
            {
                log_err("dnssec: key store public (%{dnsname} %hd %hhd %hd): %r", data->zone->origin, data->flags, data->algorithm, data->size, return_value);
            }
        }
        else
        {
            log_err("dnssec: key store private (%{dnsname} %hd %hhd %hd): %r", data->zone->origin, data->flags, data->algorithm, data->size, return_value);
        }
    }
    else
    {
        log_err("dnssec: key create failed (%{dnsname} %hd %hhd %hd): %r", data->zone->origin, data->flags, data->algorithm, data->size, return_value);
    }

    if(ISOK(return_value))
    {
        data->key = key;
    }
    else
    {
        dnssec_key_free(key);
        
        data->key = NULL;
    }
    
    scheduler_schedule_task(scheduler_queue_dnskey_create_callback, data);

    /* WARNING: From this point forward, 'data' cannot be used anymore */

    /*
     * The key is still in the keystore.
     *
     */

    return NULL;
}
void
scheduler_task_nsec3_rrsig_update_commit(zdb_packed_ttlrdata *removed_rrsig_sll, zdb_packed_ttlrdata *added_rrsig_sll, nsec3_zone_item *item, zdb_zone *zone, void *context_to_destroy)
{
    schedule_nsec3_rrsig_update *nsec3_rrsig_update;
    
    MALLOC_OR_DIE(schedule_nsec3_rrsig_update*, nsec3_rrsig_update, sizeof(schedule_nsec3_rrsig_update), GENERIC_TAG);

    nsec3_rrsig_update->removed_rrsig_sll = removed_rrsig_sll;
    nsec3_rrsig_update->added_rrsig_sll   = added_rrsig_sll;
    nsec3_rrsig_update->item              = item;
    nsec3_rrsig_update->zone              = zone;
    nsec3_rrsig_update->context           = context_to_destroy;

    scheduler_schedule_task(scheduler_task_nsec3_rrsig_update_commit_task, nsec3_rrsig_update);

    /* WARNING: From this point forward, 'rrsig_update' cannot be used anymore */
}
void
scheduler_task_rrsig_update_commit(zdb_packed_ttlrdata* removed_rrsig_sll, zdb_packed_ttlrdata* added_rrsig_sll, zdb_rr_label* label, zdb_zone* zone, dnsname_stack* name, void* context_to_destroy)
{
    schedule_rrsig_update *rrsig_update;
    
    MALLOC_OR_DIE(schedule_rrsig_update*, rrsig_update, sizeof(schedule_rrsig_update), GENERIC_TAG);

    rrsig_update->removed_rrsig_sll = removed_rrsig_sll;    /* owned (to destroy) */
    rrsig_update->added_rrsig_sll   = added_rrsig_sll;      /* owned (to destroy) */
    rrsig_update->label             = label;                /* owned by the zone */
    rrsig_update->zone              = zone;                 /* the zone */
    rrsig_update->name              = name;                 /* this has to be handled somehow ... */
    rrsig_update->context           = context_to_destroy;   /* ... and that's how */

    scheduler_schedule_task(scheduler_task_rrsig_update_commit_task, rrsig_update);

    /* WARNING: From this point forward, 'rrsig_update' cannot be used anymore */
}
static void*
scheduler_queue_zone_write_thread(void* data_)
{
    char fullname_tmp[MAX_PATH];

    zone_write_param *zwp = (zone_write_param*)data_;
    zdb_zone *zone = zwp->zone;
    u32 serial;

    log_info("zone write text: writing %{dnsname} zone file", zone->origin);
    
    if(ZDB_ZONE_INVALID(zone))
    {
        log_err("zone write text: zone %{dnsname} marked as invalid", zone->origin);
 
        scheduler_schedule_task(scheduler_queue_zone_write_callback, zwp);

        return NULL;
    }

    if(FAIL(zdb_zone_getserial(zone, &serial)))
    {
        log_err("zone write text: no SOA in %{dnsname}", zone->origin);

        scheduler_schedule_task(scheduler_queue_zone_write_callback, zwp);

        return NULL;
    }
    
    if(FAIL(snformat(fullname_tmp, sizeof (fullname_tmp), "%s.%d.tmp", zwp->file_path, serial)))
    {
        log_err("zone write text: path '%s.%d.tmp' is too big", zwp->file_path, serial);

        scheduler_schedule_task(scheduler_queue_zone_write_callback, zwp);

        /* WARNING: From this point forward, 'zone' cannot be used anymore */

        return NULL;
    }
    
    /**
     * @todo check there is not already a zone file writer working here ...
     * 
     */

    /*
     * delete the temp file if it exists already
     */
    
    if(unlink(fullname_tmp) < 0)
    {
        int err = errno;
        
        if(err != ENOENT)
        {
            log_err("zone write text: cannot cleanup '%s': %r", MAKE_ERRNO_ERROR(err));
            
            scheduler_schedule_task(scheduler_queue_zone_write_callback, zwp);

            /* WARNING: From this point forward, 'zone' cannot be used anymore */

            return NULL;
        }
    }
    
    log_info("zone write text: writing '%s'", fullname_tmp);
    
    zdb_zone_lock(zone, ZDB_ZONE_MUTEX_SIMPLEREADER);
    zdb_zone_write_text_file(zone, fullname_tmp, FALSE);
    zdb_zone_unlock(zone, ZDB_ZONE_MUTEX_SIMPLEREADER);
      
    log_info("zone write text: renaming '%s' to '%s'", fullname_tmp, zwp->file_path);
    
    if(rename(fullname_tmp, zwp->file_path) < 0)
    {
        log_err("zone write text: unable to rename tmp zone file into '%s': %r", zwp->file_path, ERRNO_ERROR);
        
        scheduler_schedule_task(scheduler_queue_zone_write_callback, zwp);

        /** @note Calling this so the scheduler gets a SCHEDULER_TASK_FINISHED is mandatory. */

        return NULL;
    }
    
    log_info("zone write text: %{dnsname} zone file written", zone->origin);

    scheduler_schedule_task(scheduler_queue_zone_write_callback, zwp);

    /* WARNING: From this point forward, 'zwp' cannot be used anymore */

    return NULL;
}