Logo Search packages:      
Sourcecode: unbound version File versions  Download package

int worker_init ( struct worker worker,
struct config_file cfg,
struct listen_port ports,
int  do_sigs 
)

Initialize worker. Allocates event base, listens to ports

Parameters:
worker,: worker to initialize, created with worker_create.
cfg,: configuration settings.
ports,: list of shared query ports.
do_sigs,: if true, worker installs signal handlers.
Returns:
: false on error.

Definition at line 932 of file worker.c.

References module_env::alloc, worker::alloc, alloc_init(), alloc_set_id_cleanup(), module_env::attach_sub, worker::back, worker::base, module_env::cfg, worker::cmd_com, worker::cmd_recv_fd, comm_base_create(), comm_base_timept(), comm_point_create_local(), comm_signal_bind(), comm_signal_create(), comm_timer_create(), worker::comsig, worker::daemon, module_env::detach_subs, module_env::detect_cycle, config_file::do_ip4, config_file::do_ip6, config_file::do_tcp, worker::env, daemon::env, worker::front, config_file::incoming_num_tcp, module_env::infra_cache, module_env::kill_sub, listen_create(), log_err(), log_set_time(), module_env::mesh, mesh_attach_sub(), mesh_create(), mesh_detach_subs(), mesh_detect_cycle(), mesh_state_delete(), daemon::mods, config_file::msg_buffer_size, worker::need_to_exit, module_env::now, module_env::now_tv, config_file::num_out_ifs, config_file::num_queries_per_thread, worker::numports, config_file::out_ifs, config_file::outgoing_num_ports, config_file::outgoing_num_tcp, outside_network_create(), worker::ports, regional_create_custom(), worker::request_size, module_env::rnd, worker::rndstate, module_env::scratch, module_env::scratch_buffer, worker::scratchpad, module_env::send_packet, module_env::send_query, server_stats_init(), config_file::stat_interval, worker::stat_timer, worker::stats, daemon::superalloc, worker::thread_num, ub_initstate(), ub_thread_sig_unblock(), config_file::use_caps_bits_for_id, VERB_ALGO, verbose(), module_env::worker, worker_alloc_cleanup(), worker_delete(), worker_handle_control_cmd(), worker_handle_request(), worker_mem_report(), worker_restart_timer(), worker_send_packet(), worker_send_query(), worker_sighandler(), and worker_stat_timer_cb().

Referenced by daemon_fork(), and thread_start().

{
      unsigned int seed;
      worker->need_to_exit = 0;
      worker->base = comm_base_create();
      if(!worker->base) {
            log_err("could not create event handling base");
            worker_delete(worker);
            return 0;
      }
      if(do_sigs) {
            ub_thread_sig_unblock(SIGHUP);
            ub_thread_sig_unblock(SIGINT);
            ub_thread_sig_unblock(SIGQUIT);
            ub_thread_sig_unblock(SIGTERM);
#ifndef LIBEVENT_SIGNAL_PROBLEM
            worker->comsig = comm_signal_create(worker->base, 
                  worker_sighandler, worker);
            if(!worker->comsig || !comm_signal_bind(worker->comsig, SIGHUP)
                  || !comm_signal_bind(worker->comsig, SIGINT)
                  || !comm_signal_bind(worker->comsig, SIGTERM)
                  || !comm_signal_bind(worker->comsig, SIGQUIT)) {
                  log_err("could not create signal handlers");
                  worker_delete(worker);
                  return 0;
            }
#endif /* LIBEVENT_SIGNAL_PROBLEM */
      } else { /* !do_sigs */
            worker->comsig = 0;
      }
      seed = (unsigned int)time(NULL) ^ (unsigned int)getpid() ^
            (((unsigned int)worker->thread_num)<<17);
            /* shift thread_num so it does not match out pid bits */
      if(!(worker->rndstate = ub_initstate(seed, NULL))) {
            seed = 0;
            log_err("could not init random numbers.");
            worker_delete(worker);
            return 0;
      }
      seed = 0;
      worker->front = listen_create(worker->base, ports,
            cfg->msg_buffer_size, (int)cfg->incoming_num_tcp, 
            worker_handle_request, worker);
      if(!worker->front) {
            log_err("could not create listening sockets");
            worker_delete(worker);
            return 0;
      }
      worker->back = outside_network_create(worker->base,
            cfg->msg_buffer_size, (size_t)cfg->outgoing_num_ports, 
            cfg->out_ifs, cfg->num_out_ifs, cfg->do_ip4, cfg->do_ip6, 
            cfg->do_tcp?cfg->outgoing_num_tcp:0, 
            worker->daemon->env->infra_cache, worker->rndstate,
            cfg->use_caps_bits_for_id, worker->ports, worker->numports);
      if(!worker->back) {
            log_err("could not create outgoing sockets");
            worker_delete(worker);
            return 0;
      }
      if(worker->thread_num != 0) {
            /* start listening to commands */
            if(!(worker->cmd_com=comm_point_create_local(worker->base, 
                  worker->cmd_recv_fd, cfg->msg_buffer_size, 
                  worker_handle_control_cmd, worker))) {
                  log_err("could not create control compt.");
                  worker_delete(worker);
                  return 0;
            }
      }
      worker->stat_timer = comm_timer_create(worker->base, 
            worker_stat_timer_cb, worker);
      if(!worker->stat_timer) {
            log_err("could not create statistics timer");
      }

      /* we use the msg_buffer_size as a good estimate for what the 
       * user wants for memory usage sizes */
      worker->scratchpad = regional_create_custom(cfg->msg_buffer_size);
      if(!worker->scratchpad) {
            log_err("malloc failure");
            worker_delete(worker);
            return 0;
      }
      worker->request_size = cfg->num_queries_per_thread;

      server_stats_init(&worker->stats);
      alloc_init(&worker->alloc, &worker->daemon->superalloc, 
            worker->thread_num);
      alloc_set_id_cleanup(&worker->alloc, &worker_alloc_cleanup, worker);
      worker->env = *worker->daemon->env;
      comm_base_timept(worker->base, &worker->env.now, &worker->env.now_tv);
      if(worker->thread_num == 0)
            log_set_time(worker->env.now);
      worker->env.worker = worker;
      worker->env.send_packet = &worker_send_packet;
      worker->env.send_query = &worker_send_query;
      worker->env.alloc = &worker->alloc;
      worker->env.rnd = worker->rndstate;
      worker->env.scratch = worker->scratchpad;
      worker->env.mesh = mesh_create(&worker->daemon->mods, &worker->env);
      worker->env.detach_subs = &mesh_detach_subs;
      worker->env.attach_sub = &mesh_attach_sub;
      worker->env.kill_sub = &mesh_state_delete;
      worker->env.detect_cycle = &mesh_detect_cycle;
      worker->env.scratch_buffer = ldns_buffer_new(cfg->msg_buffer_size);
      if(!worker->env.mesh || !worker->env.scratch_buffer) {
            worker_delete(worker);
            return 0;
      }
      worker_mem_report(worker, NULL);
      /* if statistics enabled start timer */
      if(worker->env.cfg->stat_interval > 0) {
            verbose(VERB_ALGO, "set statistics interval %d secs", 
                  worker->env.cfg->stat_interval);
            worker_restart_timer(worker);
      }
      return 1;
}


Generated by  Doxygen 1.6.0   Back to index