/** * 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; }
static void cleanup_tcp_handler(netio_type *netio, netio_handler_type *handler) { struct tcp_handler_data *data = (struct tcp_handler_data *) handler->user_data; netio_remove_handler(netio, handler); close(handler->fd); slowaccept = 0; /* * Enable the TCP accept handlers when the current number of * TCP connections is about to drop below the maximum number * of TCP connections. */ if (data->nsd->current_tcp_count == data->nsd->maximum_tcp_count) { configure_handler_event_types(data->tcp_accept_handler_count, data->tcp_accept_handlers, NETIO_EVENT_READ); } --data->nsd->current_tcp_count; assert(data->nsd->current_tcp_count >= 0); region_destroy(data->region); }
/** * Update zones. * */ void engine_update_zones(engine_type* engine, ods_status zl_changed) { ldns_rbnode_t* node = LDNS_RBTREE_NULL; zone_type* zone = NULL; zone_type* delzone = NULL; task_type* task = NULL; ods_status status = ODS_STATUS_OK; unsigned wake_up = 0; int warnings = 0; time_t now = 0; if (!engine || !engine->zonelist || !engine->zonelist->zones) { return; } now = time_now(); ods_log_debug("[%s] commit zone list changes", engine_str); lock_basic_lock(&engine->zonelist->zl_lock); node = ldns_rbtree_first(engine->zonelist->zones); while (node && node != LDNS_RBTREE_NULL) { zone = (zone_type*) node->data; task = NULL; /* reset task */ if (zone->zl_status == ZONE_ZL_REMOVED) { node = ldns_rbtree_next(node); lock_basic_lock(&zone->zone_lock); delzone = zonelist_del_zone(engine->zonelist, zone); if (delzone) { lock_basic_lock(&engine->taskq->schedule_lock); task = unschedule_task(engine->taskq, (task_type*) zone->task); lock_basic_unlock(&engine->taskq->schedule_lock); } task_cleanup(task); task = NULL; lock_basic_unlock(&zone->zone_lock); netio_remove_handler(engine->xfrhandler->netio, &zone->xfrd->handler); zone_cleanup(zone); zone = NULL; continue; } else if (zone->zl_status == ZONE_ZL_ADDED) { lock_basic_lock(&zone->zone_lock); ods_log_assert(!zone->task); /* set notify nameserver command */ if (engine->config->notify_command && !zone->notify_ns) { set_notify_ns(zone, engine->config->notify_command); } /* create task */ task = task_create(TASK_SIGNCONF, now, zone); lock_basic_unlock(&zone->zone_lock); if (!task) { ods_log_crit("[%s] unable to create task for zone %s: " "task_create() failed", engine_str, zone->name); node = ldns_rbtree_next(node); continue; } } /* load adapter config */ status = adapter_load_config(zone->adinbound); if (status != ODS_STATUS_OK) { ods_log_error("[%s] unable to load config for inbound adapter " "for zone %s: %s", engine_str, zone->name, ods_status2str(status)); } status = adapter_load_config(zone->adoutbound); if (status != ODS_STATUS_OK) { ods_log_error("[%s] unable to load config for outbound adapter " "for zone %s: %s", engine_str, zone->name, ods_status2str(status)); } /* for dns adapters */ warnings += dnsconfig_zone(engine, zone); if (zone->zl_status == ZONE_ZL_ADDED) { ods_log_assert(task); lock_basic_lock(&zone->zone_lock); zone->task = task; lock_basic_unlock(&zone->zone_lock); lock_basic_lock(&engine->taskq->schedule_lock); status = schedule_task(engine->taskq, task, 0); lock_basic_unlock(&engine->taskq->schedule_lock); } else if (zl_changed == ODS_STATUS_OK) { /* always try to update signconf */ lock_basic_lock(&zone->zone_lock); status = zone_reschedule_task(zone, engine->taskq, TASK_SIGNCONF); lock_basic_unlock(&zone->zone_lock); } if (status != ODS_STATUS_OK) { ods_log_crit("[%s] unable to schedule task for zone %s: %s", engine_str, zone->name, ods_status2str(status)); } else { wake_up = 1; zone->zl_status = ZONE_ZL_OK; } node = ldns_rbtree_next(node); } lock_basic_unlock(&engine->zonelist->zl_lock); if (engine->dnshandler) { dnshandler_fwd_notify(engine->dnshandler, (uint8_t*) ODS_SE_NOTIFY_CMD, strlen(ODS_SE_NOTIFY_CMD)); } else if (warnings) { ods_log_warning("[%s] no dnshandler/listener configured, but zones " "are configured with dns adapters: notify and zone transfer " "requests will not work properly", engine_str); } if (wake_up) { engine_wakeup_workers(engine); } return; }