Exemplo n.º 1
0
static void
engine_stop_drudgers(engine_type* engine)
{
#if HAVE_DRUDGERS
    size_t i = 0;
#endif

    ods_log_assert(engine);
    ods_log_assert(engine->config);
    ods_log_debug("[%s] stop drudgers", engine_str);
#if HAVE_DRUDGERS
    /* tell them to exit and wake up sleepyheads */
    for (i=0; i < (size_t) engine->config->num_signer_threads; i++) {
        engine->drudgers[i]->need_to_exit = 1;
    }
    worker_notify_all(&engine->signq->q_lock, &engine->signq->q_threshold);

    /* head count */
    for (i=0; i < (size_t) engine->config->num_signer_threads; i++) {
        ods_log_debug("[%s] join drudger %i", engine_str, i+1);
        ods_thread_join(engine->drudgers[i]->thread_id);
        engine->drudgers[i]->engine = NULL;
    }
#endif
    return;
}
Exemplo n.º 2
0
/**
 * Make sure that no appointed jobs have failed.
 *
 */
static ods_status
worker_check_jobs(worker_type* worker, task_type* task) {
    ods_log_assert(worker);
    ods_log_assert(task);
    lock_basic_lock(&worker->worker_lock);
    if (worker->jobs_failed) {
        ods_log_error("[%s[%i]] sign zone %s failed: %u RRsets failed",
            worker2str(worker->type), worker->thread_num,
            task_who2str(task), worker->jobs_failed);
        lock_basic_unlock(&worker->worker_lock);
        return ODS_STATUS_ERR;
    } else if (worker->jobs_completed != worker->jobs_appointed) {
        ods_log_error("[%s[%i]] sign zone %s failed: processed %u of %u "
            "RRsets", worker2str(worker->type), worker->thread_num,
            task_who2str(task), worker->jobs_completed,
            worker->jobs_appointed);
        lock_basic_unlock(&worker->worker_lock);
        return ODS_STATUS_ERR;
    } else if (worker->need_to_exit) {
        ods_log_debug("[%s[%i]] sign zone %s failed: worker needs to exit",
            worker2str(worker->type), worker->thread_num, task_who2str(task));
        lock_basic_unlock(&worker->worker_lock);
        return ODS_STATUS_ERR;
    } else {
        ods_log_debug("[%s[%i]] sign zone %s ok: %u of %u RRsets "
            "succeeded", worker2str(worker->type), worker->thread_num,
            task_who2str(task), worker->jobs_completed,
            worker->jobs_appointed);
        ods_log_assert(worker->jobs_appointed == worker->jobs_completed);
    }
    lock_basic_unlock(&worker->worker_lock);
    return ODS_STATUS_OK;
}
Exemplo n.º 3
0
/**
 * (Create) and change ownership of directories
 *
 */
void
ods_chown(const char* file, uid_t uid, gid_t gid, int getdir)
{
    char* dir = NULL;

    if (!file) {
        ods_log_warning("[%s] no filename given for chown()", file_str);
        return;
    }

    if (!getdir) {
        ods_log_debug("[%s] create and chown %s with user=%ld group=%ld",
           file_str, file, (signed long) uid, (signed long) gid);
        if (chown(file, uid, gid) != 0) {
            ods_log_error("[%s] chown() %s failed: %s", file_str, file,
                strerror(errno));
        }
    } else if ((dir = ods_dir_name(file)) != NULL) {
        ods_log_debug("[%s] create and chown %s with user=%ld group=%ld",
            file_str, dir, (signed long) uid, (signed long) gid);
        if (chown(dir, uid, gid) != 0) {
            ods_log_error("[%s] chown() %s failed: %s", file_str,
                dir, strerror(errno));
        }
        free((void*) dir);
    } else {
        ods_log_warning("[%s] use of relative path: %s", file_str, file);
    }
}
Exemplo n.º 4
0
/**
 * Work.
 *
 */
void
worker_start(worker_type* worker)
{
    ods_log_assert(worker);

    while (worker->need_to_exit == 0) {
        ods_log_debug("[worker[%i]]: report for duty", worker->thread_num);

        /* When no task available this call blocks and waits for event.
         * Then it will return NULL; */
        worker->task = schedule_pop_task(worker->engine->taskq);
        if (worker->task) {
            ods_log_debug("[worker[%i]] start working", worker->thread_num);
            worker_perform_task(worker);
            ods_log_debug("[worker[%i]] finished working", worker->thread_num);
            if (worker->task) {
                if (schedule_task(worker->engine->taskq, worker->task) !=
                    ODS_STATUS_OK)
                {
                    ods_log_error("[worker[%i]] unable to schedule task",
                        worker->thread_num);
                }
                worker->task = NULL;
            }
        }
    }
}
Exemplo n.º 5
0
/**
 * Process TSIG RR.
 *
 */
static ldns_pkt_rcode
query_process_tsig(query_type* q)
{
    if (!q || !q->tsig_rr) {
        return LDNS_RCODE_SERVFAIL;
    }
    if (q->tsig_rr->status == TSIG_ERROR) {
        return LDNS_RCODE_FORMERR;
    }
    if (q->tsig_rr->status == TSIG_OK) {
        if (!tsig_rr_lookup(q->tsig_rr)) {
            ods_log_debug("[%s] tsig unknown key/algorithm", query_str);
            return LDNS_RCODE_REFUSED;
        }
        buffer_set_limit(q->buffer, q->tsig_rr->position);
        buffer_pkt_set_arcount(q->buffer, buffer_pkt_arcount(q->buffer)-1);
        tsig_rr_prepare(q->tsig_rr);
        tsig_rr_update(q->tsig_rr, q->buffer, buffer_limit(q->buffer));
        if (!tsig_rr_verify(q->tsig_rr)) {
            ods_log_debug("[%s] bad tsig signature", query_str);
            return LDNS_RCODE_NOTAUTH;
        }
    }
    return LDNS_RCODE_NOERROR;
}
Exemplo n.º 6
0
/**
 * IXFR.
 *
 */
static query_state
query_process_ixfr(query_type* q)
{
    uint16_t count = 0;
    ods_log_assert(q);
    ods_log_assert(q->buffer);
    ods_log_assert(buffer_pkt_qdcount(q->buffer) == 1);
    /* skip header and question section */
    buffer_skip(q->buffer, BUFFER_PKT_HEADER_SIZE);
    if (!buffer_skip_rr(q->buffer, 1)) {
        ods_log_error("[%s] dropped packet: zone %s received bad ixfr "
            "request (bad question section)", query_str, q->zone->name);
        return QUERY_DISCARDED;
    }
    /* answer section is empty */
    ods_log_assert(buffer_pkt_ancount(q->buffer) == 0);
    /* examine auth section */
    q->startpos = buffer_position(q->buffer);
    count = buffer_pkt_nscount(q->buffer);
    if (count) {
        if (!buffer_skip_dname(q->buffer) ||
            !query_parse_soa(q->buffer, &(q->serial))) {
            ods_log_error("[%s] dropped packet: zone %s received bad ixfr "
                "request (bad soa in auth section)", query_str, q->zone->name);
            return QUERY_DISCARDED;
        }
        ods_log_debug("[%s] found ixfr request zone %s serial=%u", query_str,
            q->zone->name, q->serial);
        return QUERY_PROCESSED;
    }
    ods_log_debug("[%s] ixfr request zone %s has no auth section", query_str,
        q->zone->name);
    q->serial = 0;
    return QUERY_PROCESSED;
}
Exemplo n.º 7
0
/**
 * Handle signals.
 *
 */
void *
signal_handler(sig_atomic_t sig)
{
    switch (sig) {
        case SIGHUP:
            ods_log_debug("[%s] SIGHUP received", signal_str);
            signal_hup_recvd++;
            if (signal_engine) {
                lock_basic_lock(&signal_engine->signal_lock);
                /* [LOCK] signal */
                lock_basic_alarm(&signal_engine->signal_cond);
                /* [UNLOCK] signal */
                lock_basic_unlock(&signal_engine->signal_lock);
            }
            break;
        case SIGINT:
        case SIGTERM:
            ods_log_debug("[%s] SIGTERM received", signal_str);
            signal_term_recvd++;
            if (signal_engine) {
                lock_basic_lock(&signal_engine->signal_lock);
                /* [LOCK] signal */
                lock_basic_alarm(&signal_engine->signal_cond);
                /* [UNLOCK] signal */
                lock_basic_unlock(&signal_engine->signal_lock);
            }
            break;
        default:
            break;
    }
    return NULL;
}
Exemplo n.º 8
0
/**
 * Start zone transfer handler.
 *
 */
void
xfrhandler_start(xfrhandler_type* xfrhandler)
{
    ods_log_assert(xfrhandler);
    ods_log_assert(xfrhandler->engine);
    ods_log_debug("[%s] start", xfrh_str);
    /* setup */
    xfrhandler->start_time = time_now();
    /* handlers */
    netio_add_handler(xfrhandler->netio, &xfrhandler->dnshandler);
    /* service */
    while (xfrhandler->need_to_exit == 0) {
        /* dispatch may block for a longer period, so current is gone */
        xfrhandler->got_time = 0;
        ods_log_deeebug("[%s] netio dispatch", xfrh_str);
        if (netio_dispatch(xfrhandler->netio, NULL, NULL) == -1) {
            if (errno != EINTR) {
                ods_log_error("[%s] unable to dispatch netio: %s", xfrh_str,
                    strerror(errno));
            }
        }
    }
    /* shutdown */
    ods_log_debug("[%s] shutdown", xfrh_str);
}
Exemplo n.º 9
0
/**
 * Work.
 *
 */
void
worker_start(worker_type* worker)
{
    time_t now, timeout = 1;
    task_type *task_that_was_worked_on;

    ods_log_assert(worker);

    while (worker->need_to_exit == 0) {
        ods_log_debug("[worker[%i]]: report for duty", worker->thread_num);

        lock_basic_lock(&worker->engine->taskq->schedule_lock);
        /* [LOCK] schedule */

        worker->task = schedule_pop_task(worker->engine->taskq);
        if (worker->task) {

            /* [UNLOCK] schedule */
            lock_basic_unlock(&worker->engine->taskq->schedule_lock);

            ods_log_debug("[worker[%i]] start working", worker->thread_num);

            worker->clock_in = time(NULL);
            worker_perform_task(worker);

            task_that_was_worked_on = worker->task;
            worker->task = NULL;
            
            ods_log_debug("[worker[%i]] finished working", worker->thread_num);
            
            if (task_that_was_worked_on)
                (void) lock_and_schedule_task(worker->engine->taskq,
                                                 task_that_was_worked_on, 1);
            
            timeout = 1;
        } else {
            ods_log_debug("[worker[%i]] nothing to do", worker->thread_num);

            worker->task = schedule_get_first_task(worker->engine->taskq);

            /* [UNLOCK] schedule */
            lock_basic_unlock(&worker->engine->taskq->schedule_lock);

            now = time_now();
            if (worker->task && !worker->engine->taskq->loading) {
                timeout = (worker->task->when - now);
            } else {
                timeout *= 2;
                if (timeout > ODS_SE_MAX_BACKOFF) {
                    timeout = ODS_SE_MAX_BACKOFF;
                }
            }
            worker->task = NULL;
            worker_sleep(worker, timeout);
        }
    }
    return;
}
Exemplo n.º 10
0
/**
 * Find TSIG RR.
 *
 */
static int
query_find_tsig(query_type* q)
{
    size_t saved_pos = 0;
    size_t rrcount = 0;
    size_t i = 0;

    ods_log_assert(q);
    ods_log_assert(q->tsig_rr);
    ods_log_assert(q->buffer);
    if (buffer_pkt_arcount(q->buffer) == 0) {
        q->tsig_rr->status = TSIG_NOT_PRESENT;
        return 1;
    }
    saved_pos = buffer_position(q->buffer);
    rrcount = buffer_pkt_qdcount(q->buffer) + buffer_pkt_ancount(q->buffer) +
        buffer_pkt_nscount(q->buffer);
    buffer_set_position(q->buffer, BUFFER_PKT_HEADER_SIZE);
    for (i=0; i < rrcount; i++) {
        if (!buffer_skip_rr(q->buffer, i < buffer_pkt_qdcount(q->buffer))) {
             buffer_set_position(q->buffer, saved_pos);
             return 0;
        }
    }

    rrcount = buffer_pkt_arcount(q->buffer);
    ods_log_assert(rrcount != 0);
    if (!tsig_rr_parse(q->tsig_rr, q->buffer)) {
        ods_log_debug("[%s] got bad tsig", query_str);
        return 0;
    }
    if (q->tsig_rr->status != TSIG_NOT_PRESENT) {
        --rrcount;
    }
    if (rrcount) {
        if (edns_rr_parse(q->edns_rr, q->buffer)) {
            --rrcount;
        }
    }
    if (rrcount && q->tsig_rr->status == TSIG_NOT_PRESENT) {
        /* see if tsig is after the edns record */
        if (!tsig_rr_parse(q->tsig_rr, q->buffer)) {
            ods_log_debug("[%s] got bad tsig", query_str);
            return 0;
        }
        if (q->tsig_rr->status != TSIG_NOT_PRESENT) {
            --rrcount;
        }
    }
    if (rrcount > 0) {
        ods_log_debug("[%s] too many additional rrs", query_str);
        return 0;
    }
    buffer_set_position(q->buffer, saved_pos);
    return 1;
}
Exemplo n.º 11
0
/**
 * QUERY.
 *
 */
static query_state
query_process_query(query_type* q, ldns_rr_type qtype, engine_type* engine)
{
    dnsout_type* dnsout = NULL;
    if (!q || !q->zone) {
        return QUERY_DISCARDED;
    }
    ods_log_assert(q->zone->name);
    ods_log_debug("[%s] incoming query qtype=%s for zone %s", query_str,
        rrset_type2str(qtype), q->zone->name);
    /* sanity checks */
    if (buffer_pkt_qdcount(q->buffer) != 1 || buffer_pkt_tc(q->buffer)) {
        buffer_pkt_set_flags(q->buffer, 0);
        return query_formerr(q);
    }
    if (buffer_pkt_ancount(q->buffer) != 0 ||
        (qtype != LDNS_RR_TYPE_IXFR && buffer_pkt_nscount(q->buffer) != 0)) {
        buffer_pkt_set_flags(q->buffer, 0);
        return query_formerr(q);
    }
    /* acl */
    if (!q->zone->adoutbound || q->zone->adoutbound->type != ADAPTER_DNS) {
        ods_log_error("[%s] zone %s is not configured to have output dns "
            "adapter", query_str, q->zone->name);
        return query_refused(q);
    }
    ods_log_assert(q->zone->adoutbound->config);
    dnsout = (dnsout_type*) q->zone->adoutbound->config;
    /* acl also in use for soa and other queries */
    if (!acl_find(dnsout->provide_xfr, &q->addr, q->tsig_rr)) {
        return query_refused(q);
    }
    /* ixfr? */
    if (qtype == LDNS_RR_TYPE_IXFR) {
        if (query_process_ixfr(q) != QUERY_PROCESSED) {
            buffer_pkt_set_flags(q->buffer, 0);
            return query_formerr(q);
        }
        query_prepare(q);
        ods_log_assert(q->zone->name);
        ods_log_debug("[%s] incoming ixfr request serial=%u for zone %s",
            query_str, q->serial, q->zone->name);
        return ixfr(q, engine);
    }

    query_prepare(q);
    /* axfr? */
    if (qtype == LDNS_RR_TYPE_AXFR) {
        ods_log_assert(q->zone->name);
        ods_log_debug("[%s] incoming axfr request for zone %s",
            query_str, q->zone->name);
        return axfr(q, engine);
    }
    /* (soa) query */
    return query_response(q, qtype);
}
Exemplo n.º 12
0
/**
 * Open a file.
 *
 */
FILE*
ods_fopen(const char* file, const char* dir, const char* mode)
{
    FILE* fd = NULL;
    size_t len_file = 0;
    size_t len_dir = 0;
    size_t len_total = 0;
    char* openf = NULL;

    ods_log_assert(mode);
    ods_log_deeebug("[%s] open file %s%s file=%s mode=%s", file_str,
        (dir?"dir=":""), (dir?dir:""), (file?file:"(null)"),
        ods_file_mode2str(mode));

    if (dir) {
        len_dir= strlen(dir);
    }
    if (file) {
        len_file= strlen(file);
    }
    len_total = len_dir + len_file;
    if (len_total > 0) {
        openf = (char*) malloc(sizeof(char)*(len_total + 1));
        if (!openf) {
            ods_log_error("[%s] unable to open file %s%s%s for %s: malloc() "
                "failed", file_str, (dir?dir:""), (dir?"/":""),
                (file?file:"(null)"), ods_file_mode2str(mode));
            return NULL;
        }
        if (dir) {
           strncpy(openf, dir, len_dir);
           openf[len_dir] = '\0';
           if (file) {
               strncat(openf, file, len_file);
           }
        } else if (file) {
           strncpy(openf, file, len_file);
        }
        openf[len_total] = '\0';

        if (len_file) {
            fd = fopen(openf, mode);
            if (!fd) {
                ods_log_debug("[%s] unable to open file %s for %s: %s",
                    file_str, openf[0]?openf:"(null)",
                    ods_file_mode2str(mode), strerror(errno));
            } else {
                file_count++;
                ods_log_debug("[%s] openfile %s count %u", file_str, openf[0]?openf:"(null)", file_count);
            }
        }
        free((void*) openf);
    }
    return fd;
}
Exemplo n.º 13
0
/**
 * Update zone list.
 *
 */
ods_status
zonelist_update(zonelist_type* zl, const char* zlfile)
{
    zonelist_type* new_zlist = NULL;
    allocator_type* tmp_alloc = NULL;
    time_t st_mtime = 0;
    ods_status status = ODS_STATUS_OK;
    char* datestamp = NULL;

    ods_log_debug("[%s] update zone list", zl_str);
    if (!zl|| !zl->zones || !zlfile) {
        return ODS_STATUS_ASSERT_ERR;
    }
    /* is the file updated? */
    st_mtime = ods_file_lastmodified(zlfile);
    if (st_mtime <= zl->last_modified) {
        (void)time_datestamp(zl->last_modified, "%Y-%m-%d %T", &datestamp);
        ods_log_debug("[%s] zonelist file %s is unchanged since %s",
                      zl_str, zlfile, datestamp?datestamp:"Unknown");
        free((void*)datestamp);
        return ODS_STATUS_UNCHANGED;
    }
    /* create new zonelist */
    tmp_alloc = allocator_create(malloc, free);
    if (!tmp_alloc) {
        return ODS_STATUS_MALLOC_ERR;
    }
    new_zlist = zonelist_create(tmp_alloc);
    if (!new_zlist) {
        ods_log_error("[%s] unable to update zonelist: zonelist_create() "
                      "failed", zl_str);
        allocator_cleanup(tmp_alloc);
        return ODS_STATUS_ERR;
    }
    /* read zonelist */
    status = zonelist_read(new_zlist, zlfile);
    if (status == ODS_STATUS_OK) {
        zl->just_removed = 0;
        zl->just_added = 0;
        zl->just_updated = 0;
        new_zlist->last_modified = st_mtime;
        zonelist_merge(zl, new_zlist);
        (void)time_datestamp(zl->last_modified, "%Y-%m-%d %T", &datestamp);
        ods_log_debug("[%s] file %s is modified since %s", zl_str, zlfile,
                      datestamp?datestamp:"Unknown");
        free((void*)datestamp);
    } else {
        ods_log_error("[%s] unable to update zonelist: read file %s failed "
                      "(%s)", zl_str, zlfile, ods_status2str(status));
    }
    zonelist_free(new_zlist);
    allocator_cleanup(tmp_alloc);
    return status;
}
Exemplo n.º 14
0
/**
 * Handle notify.
 *
 */
static void
notify_handle_zone(netio_type* ATTR_UNUSED(netio),
    netio_handler_type* handler, netio_events_type event_types)
{
    notify_type* notify = NULL;
    xfrhandler_type* xfrhandler = NULL;
    zone_type* zone = NULL;
    if (!handler) {
        return;
    }
    notify = (notify_type*) handler->user_data;
    ods_log_assert(notify);
    xfrhandler = (xfrhandler_type*) notify->xfrhandler;
    zone = (zone_type*) notify->zone;
    ods_log_assert(xfrhandler);
    ods_log_assert(zone);
    ods_log_assert(zone->name);
    ods_log_debug("[%s] handle notify for zone %s", notify_str, zone->name);

    if (notify->is_waiting) {
        ods_log_debug("[%s] already waiting, skipping notify for zone %s",
            notify_str, zone->name);
        ods_log_assert(notify->handler.fd == -1);
        return;
    }
    if (event_types & NETIO_EVENT_READ) {
        ods_log_debug("[%s] read notify ok for zone %s", notify_str,
            zone->name);
        ods_log_assert(notify->handler.fd != -1);
        if (notify_udp_read_packet(notify)) {
            if (notify_handle_reply(notify)) {
                notify_next(notify);
            }
        }
    } else if(event_types & NETIO_EVENT_TIMEOUT) {
        ods_log_debug("[%s] notify timeout for zone %s", notify_str,
            zone->name);
        /* timeout, try again */
    }
    /* see if notify is still enabled */
    if (notify->secondary) {
        ods_log_assert(notify->secondary->address);
        notify->retry++;
        if (notify->retry > NOTIFY_MAX_RETRY) {
            ods_log_verbose("[%s] notify max retry for zone %s, %s unreachable",
                notify_str, zone->name, notify->secondary->address);
            notify_next(notify);
        } else {
            notify_send(notify);
        }
    }
    return;
}
Exemplo n.º 15
0
/**
 * Update DNS configuration for zone.
 *
 */
static int
dnsconfig_zone(engine_type* engine, zone_type* zone)
{
    int numdns = 0;
    ods_log_assert(engine);
    ods_log_assert(engine->xfrhandler);
    ods_log_assert(engine->xfrhandler->netio);
    ods_log_assert(zone);
    ods_log_assert(zone->adinbound);
    ods_log_assert(zone->adoutbound);
    ods_log_assert(zone->name);

    if (zone->adinbound->type == ADAPTER_DNS) {
        /* zone transfer handler */
        if (!zone->xfrd) {
            ods_log_debug("[%s] add transfer handler for zone %s",
                engine_str, zone->name);
            zone->xfrd = xfrd_create((void*) engine->xfrhandler,
                (void*) zone);
            ods_log_assert(zone->xfrd);
            netio_add_handler(engine->xfrhandler->netio,
                &zone->xfrd->handler);
        } else if (!zone->xfrd->serial_disk_acquired) {
            xfrd_set_timer_now(zone->xfrd);
        }
        numdns++;
    } else if (zone->xfrd) {
        netio_remove_handler(engine->xfrhandler->netio,
            &zone->xfrd->handler);
        xfrd_cleanup(zone->xfrd);
        zone->xfrd = NULL;
    }
    if (zone->adoutbound->type == ADAPTER_DNS) {
        /* notify handler */
        if (!zone->notify) {
            ods_log_debug("[%s] add notify handler for zone %s",
                engine_str, zone->name);
            zone->notify = notify_create((void*) engine->xfrhandler,
                (void*) zone);
            ods_log_assert(zone->notify);
            netio_add_handler(engine->xfrhandler->netio,
                &zone->notify->handler);
        }
        numdns++;
    } else if (zone->notify) {
        netio_remove_handler(engine->xfrhandler->netio,
            &zone->notify->handler);
        notify_cleanup(zone->notify);
        zone->notify = NULL;
    }
    return numdns;
}
Exemplo n.º 16
0
static void
engine_stop_dnshandler(engine_type* engine)
{
    if (!engine || !engine->dnshandler || !engine->dnshandler->thread_id) {
        return;
    }
    ods_log_debug("[%s] stop dnshandler", engine_str);
    engine->dnshandler->need_to_exit = 1;
    dnshandler_signal(engine->dnshandler);
    ods_log_debug("[%s] join dnshandler", engine_str);
    ods_thread_join(engine->dnshandler->thread_id);
    engine->dnshandler->engine = NULL;
}
Exemplo n.º 17
0
/**
 * Enable notify.
 *
 */
void
notify_enable(notify_type* notify, ldns_rr* soa)
{
    xfrhandler_type* xfrhandler = NULL;
    zone_type* zone = NULL;
    dnsout_type* dnsout = NULL;
    if (!notify) {
        return;
    }
    xfrhandler = (xfrhandler_type*) notify->xfrhandler;
    ods_log_assert(xfrhandler);
    zone = (zone_type*) notify->zone;
    ods_log_assert(zone);
    ods_log_assert(zone->name);
    ods_log_assert(zone->adoutbound);
    ods_log_assert(zone->adoutbound->config);
    ods_log_assert(zone->adoutbound->type == ADAPTER_DNS);
    dnsout = (dnsout_type*) zone->adoutbound->config;
    if (!dnsout->do_notify) {
        ods_log_warning("[%s] zone %s has no notify acl", notify_str,
            zone->name);
        return; /* nothing to do */
    }
    notify_update_soa(notify, soa);
    if (notify->is_waiting) {
        ods_log_debug("[%s] zone %s already on waiting list", notify_str,
            zone->name);
       return;
    }
    if (xfrhandler->notify_udp_num < NOTIFY_MAX_UDP) {
        notify_setup(notify);
        xfrhandler->notify_udp_num++;
        ods_log_debug("[%s] zone %s notify enabled", notify_str,
            zone->name);
        return;
    }
    /* put it in waiting list */
    notify->secondary = dnsout->do_notify;
    notify->is_waiting = 1;
    notify->waiting_next = NULL;
    if (xfrhandler->notify_waiting_last) {
        xfrhandler->notify_waiting_last->waiting_next = notify;
    } else {
        xfrhandler->notify_waiting_first = notify;
    }
    xfrhandler->notify_waiting_last = notify;
    notify->handler.timeout = NULL;
    ods_log_debug("[%s] zone %s notify on waiting list", notify_str,
        zone->name);
    return;
}
Exemplo n.º 18
0
/**
 * Run engine, run!.
 *
 */
static void
engine_run(engine_type* engine, int single_run)
{
    if (!engine) {
        return;
    }
    engine_start_workers(engine);
    engine_start_drudgers(engine);

    lock_basic_lock(&engine->signal_lock);
    engine->signal = SIGNAL_RUN;
    lock_basic_unlock(&engine->signal_lock);

    while (!engine->need_to_exit && !engine->need_to_reload) {
        lock_basic_lock(&engine->signal_lock);
        engine->signal = signal_capture(engine->signal);
        switch (engine->signal) {
            case SIGNAL_RUN:
                ods_log_assert(1);
                break;
            case SIGNAL_RELOAD:
                engine->need_to_reload = 1;
                break;
            case SIGNAL_SHUTDOWN:
                engine->need_to_exit = 1;
                break;
            default:
                ods_log_warning("[%s] invalid signal %d captured, "
                    "keep running", engine_str, signal);
                engine->signal = SIGNAL_RUN;
                break;
        }
        lock_basic_unlock(&engine->signal_lock);

        if (single_run) {
           engine->need_to_exit = engine_all_zones_processed(engine);
        }
        lock_basic_lock(&engine->signal_lock);
        if (engine->signal == SIGNAL_RUN && !single_run) {
           ods_log_debug("[%s] taking a break", engine_str);
           lock_basic_sleep(&engine->signal_cond, &engine->signal_lock, 3600);
        }
        lock_basic_unlock(&engine->signal_lock);
    }
    ods_log_debug("[%s] signer halted", engine_str);
    engine_stop_drudgers(engine);
    engine_stop_workers(engine);
    (void)lhsm_reopen(engine->config->cfg_filename);
    return;
}
Exemplo n.º 19
0
/**
 * Read and match a string from backup file.
 *
 */
int
backup_read_check_str(FILE* in, const char* str)
{
    char *p = backup_read_token(in);
    if (!p) {
        ods_log_debug("[%s] cannot read check string \'%s\'", backup_str, str);
        return 0;
    }
    if (ods_strcmp(p, str) != 0) {
        ods_log_debug("[%s] \'%s\' does not match \'%s\'", backup_str, p, str);
        return 0;
    }
    return 1;
}
Exemplo n.º 20
0
/**
 * Inspect head of queue and wakeup a worker now or set alarm.
 * Caller SHOULD hold schedule->schedule_lock. Failing to do so
 * could possibly cause a thread to miss the wakeup.
 */
static void
set_alarm(schedule_type* schedule)
{
    time_t now = time_now();
    task_type *task = get_first_task(schedule);
    if (!task || task->when == -1) {
        ods_log_debug("[%s] no alarm set", schedule_str);
    } else if (task->when == 0 || task->when <= now) {
        ods_log_debug("[%s] signal now", schedule_str);
        pthread_cond_signal(&schedule->schedule_cond);
    } else {
        ods_log_debug("[%s] SIGALRM set", schedule_str);
        alarm(task->when - now);
    }
}
Exemplo n.º 21
0
/**
 * Create worker.
 *
 */
worker_type*
worker_create(allocator_type* allocator, int num, worker_id type)
{
    worker_type* worker;
    if (!allocator) {
        return NULL;
    }
    worker = (worker_type*) allocator_alloc(allocator, sizeof(worker_type));
    if (!worker) {
        return NULL;
    }
    ods_log_debug("[%s[%i]] create", worker2str(type), num+1);
    lock_basic_init(&worker->worker_lock);
    lock_basic_set(&worker->worker_alarm);
    lock_basic_lock(&worker->worker_lock);
    worker->allocator = allocator;
    worker->thread_num = num +1;
    worker->engine = NULL;
    worker->task = NULL;
    worker->working_with = TASK_NONE;
    worker->need_to_exit = 0;
    worker->type = type;
    worker->clock_in = 0;
    worker->jobs_appointed = 0;
    worker->jobs_completed = 0;
    worker->jobs_failed = 0;
    worker->sleeping = 0;
    worker->waiting = 0;
    lock_basic_unlock(&worker->worker_lock);
    return worker;
}
Exemplo n.º 22
0
/**
 * Load zone signconf.
 *
 */
ods_status
tools_signconf(zone_type* zone)
{
    ods_status status = ODS_STATUS_OK;
    signconf_type* new_signconf = NULL;

    ods_log_assert(zone);
    ods_log_assert(zone->name);
    status = zone_load_signconf(zone, &new_signconf);
    if (status == ODS_STATUS_OK) {
        ods_log_assert(new_signconf);
        /* Denial of Existence Rollover? */
        if (signconf_compare_denial(zone->signconf, new_signconf)
            == TASK_NSECIFY) {
            /**
             * Or NSEC -> NSEC3, or NSEC3 -> NSEC, or NSEC3 params changed.
             * All NSEC(3)s become invalid.
             */
            namedb_wipe_denial(zone->db);
            namedb_cleanup_denials(zone->db);
            namedb_init_denials(zone->db);
        }
        /* all ok, switch signer configuration */
        signconf_cleanup(zone->signconf);
        ods_log_debug("[%s] zone %s switch to new signconf", tools_str,
            zone->name);
        zone->signconf = new_signconf;
        signconf_log(zone->signconf, zone->name);
        zone->default_ttl = (uint32_t) duration2time(zone->signconf->soa_min);
    } else if (status != ODS_STATUS_UNCHANGED) {
        ods_log_error("[%s] unable to load signconf for zone %s: %s",
            tools_str, zone->name, ods_status2str(status));
    }
    return status;
}
Exemplo n.º 23
0
static void
engine_stop_xfrhandler(engine_type* engine)
{
    if (!engine || !engine->xfrhandler) {
        return;
    }
    ods_log_debug("[%s] stop xfrhandler", engine_str);
    engine->xfrhandler->need_to_exit = 1;
    xfrhandler_signal(engine->xfrhandler);
    ods_log_debug("[%s] join xfrhandler", engine_str);
    if (engine->xfrhandler->started) {
    	ods_thread_join(engine->xfrhandler->thread_id);
    	engine->xfrhandler->started = 0;
    }
    engine->xfrhandler->engine = NULL;
}
Exemplo n.º 24
0
/**
 * Push item to queue.
 *
 */
ods_status
fifoq_push(fifoq_type* q, void* item, worker_type* worker, int* tries)
{
    if (!q || !item || !worker) {
        return ODS_STATUS_ASSERT_ERR;
    }
    if (q->count >= FIFOQ_MAX_COUNT) {
        /* #262 if drudgers remain on hold, do additional broadcast */
        if (*tries > FIFOQ_TRIES_COUNT) {
            lock_basic_broadcast(&q->q_threshold);
            ods_log_debug("[%s] queue full, notify drudgers again", fifoq_str);
            /* reset tries */
            *tries = 0;
        }
        return ODS_STATUS_UNCHANGED;
    }
    q->blob[q->count] = item;
    q->owner[q->count] = worker;
    q->count += 1;
    if (q->count == 1) {
        ods_log_deeebug("[%s] threshold %u reached, notify drudgers",
            fifoq_str, q->count);
        lock_basic_broadcast(&q->q_threshold);
    }
    return ODS_STATUS_OK;
}
Exemplo n.º 25
0
int
handled_policy_import_cmd(int sockfd, engine_type* engine, const char *cmd,
                        ssize_t n)
{
    const char *scmd = "policy import";

    cmd = ods_check_command(cmd,n,scmd);
    if (!cmd)
        return 0; // not handled

    ods_log_debug("[%s] %s command", module_str, scmd);

    time_t tstart = time(NULL);
	
   /* perform_policy_import(sockfd, engine->config); */
    perform_update_kasp(sockfd, engine->config);

	//TODO: Need error checking so we only do this if the update succeeds
	perform_hsmkey_gen(sockfd, engine->config, 0 /* automatic */,
					   engine->config->automatic_keygen_duration);

    flush_all_tasks(sockfd, engine);
	
    ods_printf(sockfd,"%s completed in %ld seconds.\n",scmd,time(NULL)-tstart);
    return 1;
}
Exemplo n.º 26
0
int handled_zone_del_cmd(int sockfd, engine_type* engine, const char *cmd, 
						  ssize_t n)
{
    const char *scmd =  "zone delete";
    
    cmd = ods_check_command(cmd,n,scmd);
    if (!cmd)
        return 0; // not handled
    
    ods_log_debug("[%s] %s command", module_str, scmd);

	std::string zone;
    int need_write_xml = 0;
	if (!get_arguments(sockfd,cmd,zone, need_write_xml)) {
		help_zone_del_cmd(sockfd);
		return 1;
	}

    time_t tstart = time(NULL);

    perform_zone_del(sockfd,engine->config, zone.c_str(), need_write_xml, false);

    ods_printf(sockfd,"%s completed in %ld seconds.\n",scmd,time(NULL)-tstart);
    return 1;
}
Exemplo n.º 27
0
/**
 * Sign notify.
 *
 */
static void
notify_tsig_sign(notify_type* notify, buffer_type* buffer)
{
    tsig_algo_type* algo = NULL;
    if (!notify || !notify->tsig_rr || !notify->secondary ||
        !notify->secondary->tsig || !notify->secondary->tsig->key ||
        !buffer) {
        return; /* no tsig configured */
    }
    algo = tsig_lookup_algo(notify->secondary->tsig->algorithm);
    if (!algo) {
        ods_log_error("[%s] unable to sign notify: tsig unknown algorithm "
            "%s", notify_str, notify->secondary->tsig->algorithm);
        return;
    }
    ods_log_assert(algo);
    tsig_rr_reset(notify->tsig_rr, algo, notify->secondary->tsig->key);
    notify->tsig_rr->original_query_id = buffer_pkt_id(buffer);
    notify->tsig_rr->algo_name =
        ldns_rdf_clone(notify->tsig_rr->algo->wf_name);
    notify->tsig_rr->key_name = ldns_rdf_clone(notify->tsig_rr->key->dname);
    log_dname(notify->tsig_rr->key_name, "tsig sign notify with key %s",
        LOG_DEBUG);
    log_dname(notify->tsig_rr->algo_name, "tsig sign notify with algorithm %s",
        LOG_DEBUG);
    tsig_rr_prepare(notify->tsig_rr);
    tsig_rr_update(notify->tsig_rr, buffer, buffer_position(buffer));
    tsig_rr_sign(notify->tsig_rr);
    ods_log_debug("[%s] tsig append rr to notify id=%u", notify_str,
        buffer_pkt_id(buffer));
    tsig_rr_append(notify->tsig_rr, buffer);
    buffer_pkt_set_arcount(buffer, buffer_pkt_arcount(buffer)+1);
    tsig_rr_prepare(notify->tsig_rr);
    return;
}
Exemplo n.º 28
0
/**
 * Create worker.
 *
 */
worker_type*
worker_create(allocator_type* allocator, int num)
{
    worker_type* worker;

    if (!allocator) {
        return NULL;
    }
    ods_log_assert(allocator);

    worker = (worker_type*) allocator_alloc(allocator, sizeof(worker_type));
    if (!worker) {
        return NULL;
    }

    ods_log_debug("create worker[%i]", num +1);
    worker->allocator = allocator;
    worker->thread_num = num +1;
    worker->engine = NULL;
    worker->task = NULL;
    worker->need_to_exit = 0;
    worker->clock_in = 0;
    worker->jobs_appointed = 0;
    worker->jobs_completed = 0;
    worker->jobs_failed = 0;
    worker->sleeping = 0;
    worker->waiting = 0;
    lock_basic_init(&worker->worker_lock);
    lock_basic_set(&worker->worker_alarm);
    return worker;
}
Exemplo n.º 29
0
/**
 * Drop privileges.
 *
 */
static ods_status
engine_privdrop(engine_type* engine)
{
    ods_status status = ODS_STATUS_OK;
    uid_t uid = -1;
    gid_t gid = -1;
    ods_log_assert(engine);
    ods_log_assert(engine->config);
    ods_log_debug("[%s] drop privileges", engine_str);
    if (engine->config->username && engine->config->group) {
        ods_log_verbose("[%s] drop privileges to user %s, group %s",
           engine_str, engine->config->username, engine->config->group);
    } else if (engine->config->username) {
        ods_log_verbose("[%s] drop privileges to user %s", engine_str,
           engine->config->username);
    } else if (engine->config->group) {
        ods_log_verbose("[%s] drop privileges to group %s", engine_str,
           engine->config->group);
    }
    if (engine->config->chroot) {
        ods_log_verbose("[%s] chroot to %s", engine_str,
            engine->config->chroot);
    }
    status = privdrop(engine->config->username, engine->config->group,
        engine->config->chroot, &uid, &gid);
    engine->uid = uid;
    engine->gid = gid;
    privclose(engine->config->username, engine->config->group);
    return status;
}
Exemplo n.º 30
0
static int
run(int sockfd, cmdhandler_ctx_type* context, const char *cmd)
{
    db_connection_t* dbconn = getconnectioncontext(context);
    engine_type* engine = getglobalcontext(context);
    (void)cmd;

    if (!engine) {
        return 1;
    }
    if (!engine->config) {
        return 1;
    }
    if (!engine->config->zonelist_filename) {
        return 1;
    }
    if (!dbconn) {
        return 1;
    }

    ods_log_debug("[%s] %s command", module_str, zonelist_export_funcblock.cmdname);

    if (zonelist_export(sockfd, dbconn, engine->config->zonelist_filename, 1) != ZONELIST_EXPORT_OK) {
        ods_log_error("[%s] zonelist exported to %s failed", module_str, engine->config->zonelist_filename);
        client_printf_err(sockfd, "Exported zonelist to %s failed!\n", engine->config->zonelist_filename);
        return 1;
    }

    ods_log_info("[%s] zonelist exported to %s successfully", module_str, engine->config->zonelist_filename);
    client_printf(sockfd, "Exported zonelist to %s successfully\n", engine->config->zonelist_filename);
    return 0;
}