diff options
Diffstat (limited to 'src/knot/server/server.c')
-rw-r--r-- | src/knot/server/server.c | 621 |
1 files changed, 220 insertions, 401 deletions
diff --git a/src/knot/server/server.c b/src/knot/server/server.c index 4ac919d..cef3801 100644 --- a/src/knot/server/server.c +++ b/src/knot/server/server.c @@ -24,7 +24,7 @@ #include <assert.h> #include "common/prng.h" -#include "knot/common.h" +#include "knot/knot.h" #include "knot/server/server.h" #include "knot/server/udp-handler.h" #include "knot/server/tcp-handler.h" @@ -39,8 +39,7 @@ /*! \brief Event scheduler loop. */ static int evsched_run(dthread_t *thread) { - iohandler_t *sched_h = (iohandler_t *)thread->data; - evsched_t *s = (evsched_t*)sched_h->data; + evsched_t *s = (evsched_t*)thread->data; if (!s) { return KNOT_EINVAL; } @@ -84,23 +83,13 @@ typedef struct pnode_t { static void server_remove_iface(iface_t *iface) { /* Free UDP handler. */ - iohandler_t *handler = iface->handler[UDP_ID]; - if (handler) { - server_remove_handler(handler->server, handler); - } else { - if (iface->fd[UDP_ID] > -1) { - close(iface->fd[UDP_ID]); - } + if (iface->fd[IO_UDP] > -1) { + close(iface->fd[IO_UDP]); } /* Free TCP handler. */ - handler = iface->handler[TCP_ID]; - if (handler) { - server_remove_handler(handler->server, handler); - } else { - if (iface->fd[TCP_ID] > -1) { - close(iface->fd[TCP_ID]); - } + if (iface->fd[IO_TCP] > -1) { + close(iface->fd[IO_TCP]); } /* Free interface. */ @@ -125,21 +114,30 @@ static int server_init_iface(iface_t *new_if, conf_iface_t *cfg_if) int ret = 0; int sock = 0; char errbuf[256] = {0}; - int opt = 1024 * 1024; - int snd_opt = 1024 * 1024; memset(new_if, 0, sizeof(iface_t)); /* Create UDP socket. */ - ret = socket_create(cfg_if->family, SOCK_DGRAM); + ret = socket_create(cfg_if->family, SOCK_DGRAM, IPPROTO_UDP); if (ret < 0) { - strerror_r(errno, errbuf, sizeof(errbuf)); - log_server_error("Could not create UDP socket: %s.\n", - errbuf); + if (strerror_r(errno, errbuf, sizeof(errbuf)) == 0) { + log_server_error("Could not create UDP socket: %s.\n", + errbuf); + } return ret; } else { sock = ret; } - + + /* Set socket options. */ + int flag = 1; +#ifndef DISABLE_IPV6 + if (cfg_if->family == AF_INET6) { + /* Disable dual-stack for performance reasons. */ + if(setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &flag, sizeof(flag)) < 0) { + dbg_net("udp: failed to set IPV6_V6ONLY to socket, using default config\n"); + } + } +#endif ret = socket_bind(sock, cfg_if->family, cfg_if->address, cfg_if->port); if (ret < 0) { socket_close(sock); @@ -149,36 +147,36 @@ static int server_init_iface(iface_t *new_if, conf_iface_t *cfg_if) return ret; } - new_if->fd[UDP_ID] = sock; - new_if->type[UDP_ID] = cfg_if->family; - - /* Set socket options - voluntary. */ - char ebuf[256] = {0}; - if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &snd_opt, sizeof(snd_opt)) < 0) { - strerror_r(errno, ebuf, sizeof(ebuf)); -// log_server_warning("Failed to configure socket " -// "write buffers: %s.\n", ebuf); - } - if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt)) < 0) { - strerror_r(errno, ebuf, sizeof(ebuf)); -// log_server_warning("Failed to configure socket read buffers: %s.\n", ebuf); - } + new_if->fd[IO_UDP] = sock; + new_if->type = cfg_if->family; + new_if->port = cfg_if->port; + new_if->addr = strdup(cfg_if->address); /* Create TCP socket. */ - ret = socket_create(cfg_if->family, SOCK_STREAM); + ret = socket_create(cfg_if->family, SOCK_STREAM, IPPROTO_TCP); if (ret < 0) { - socket_close(new_if->fd[UDP_ID]); - strerror_r(errno, errbuf, sizeof(errbuf)); - log_server_error("Could not create TCP socket: %s.\n", - errbuf); + socket_close(new_if->fd[IO_UDP]); + if (strerror_r(errno, errbuf, sizeof(errbuf)) == 0) { + log_server_error("Could not create TCP socket: %s.\n", + errbuf); + } return ret; } else { sock = ret; } + /* Set socket options. */ +#ifndef DISABLE_IPV6 + if (cfg_if->family == AF_INET6) { + if(setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &flag, sizeof(flag)) < 0) { + dbg_net("tcp: failed to set IPV6_V6ONLY to socket, using default config\n"); + } + } +#endif ret = socket_bind(sock, cfg_if->family, cfg_if->address, cfg_if->port); if (ret < 0) { - socket_close(new_if->fd[UDP_ID]); + free(new_if->addr); + socket_close(new_if->fd[IO_UDP]); socket_close(sock); log_server_error("Could not bind to " "TCP interface %s port %d.\n", @@ -188,7 +186,8 @@ static int server_init_iface(iface_t *new_if, conf_iface_t *cfg_if) ret = socket_listen(sock, TCP_BACKLOG_SIZE); if (ret < 0) { - socket_close(new_if->fd[UDP_ID]); + free(new_if->addr); + socket_close(new_if->fd[IO_UDP]); socket_close(sock); log_server_error("Failed to listen on " "TCP interface %s port %d.\n", @@ -196,20 +195,35 @@ static int server_init_iface(iface_t *new_if, conf_iface_t *cfg_if) return ret; } - new_if->fd[TCP_ID] = sock; - new_if->type[TCP_ID] = cfg_if->family; - new_if->port = cfg_if->port; - new_if->addr = strdup(cfg_if->address); + new_if->fd[IO_TCP] = sock; return KNOT_EOK; } +static void remove_ifacelist(struct ref_t *p) +{ + ifacelist_t *ifaces = (ifacelist_t *)p; + + /* Remove deprecated interfaces. */ + iface_t *n = NULL, *m = NULL; + WALK_LIST_DELSAFE(n, m, ifaces->u) { + log_server_info("Removing interface %s port %d.\n", + n->addr, n->port); + server_remove_iface(n); + } + WALK_LIST_DELSAFE(n, m, ifaces->l) { + free(n); + } + + free(ifaces); +} + /*! * \brief Update bound sockets according to configuration. * * \param server Server instance. * \return number of added sockets. */ -static int server_bind_sockets(server_t *server) +static int server_bind_sockets(server_t *s) { /*! \todo This requires locking to disable parallel updates (issue #278). * However, this is only used when RCU is read-locked, so count with that. @@ -220,28 +234,18 @@ static int server_bind_sockets(server_t *server) /* Prepare helper lists. */ int bound = 0; - node *m = 0; - list *newlist, unmatched; - newlist = malloc(sizeof(list)); - init_list(newlist); - init_list(&unmatched); + iface_t *m = 0; + ifacelist_t *newlist = malloc(sizeof(ifacelist_t)); + ref_init(&newlist->ref, &remove_ifacelist); + ref_retain(&newlist->ref); + init_list(&newlist->u); + init_list(&newlist->l); + /* Duplicate current list. */ /*! \note Pointers to addr, handlers etc. will be shared. */ - list_dup(&unmatched, server->ifaces, sizeof(iface_t)); - - /* Update pointers. */ - WALK_LIST(m, unmatched) { - - /* Interfaces. */ - iface_t *m_if = (iface_t*)m; - for (int i = 0; i <= TCP_ID; ++i) { - iohandler_t *h = m_if->handler[i]; - if (h) { - h->iface = m_if; - } - - } + if (s->ifaces) { + list_dup(&s->ifaces->u, &s->ifaces->l, sizeof(iface_t)); } /* Update bound interfaces. */ @@ -251,12 +255,10 @@ static int server_bind_sockets(server_t *server) /* Find already matching interface. */ int found_match = 0; conf_iface_t *cfg_if = (conf_iface_t*)n; - WALK_LIST(m, unmatched) { - iface_t *srv_if = (iface_t*)m; - + if (s->ifaces) WALK_LIST(m, s->ifaces->u) { /* Matching port and address. */ - if (cfg_if->port == srv_if->port) { - if (strcmp(cfg_if->address, srv_if->addr) == 0) { + if (cfg_if->port == m->port) { + if (strcmp(cfg_if->address, m->addr) == 0) { found_match = 1; break; } @@ -265,14 +267,14 @@ static int server_bind_sockets(server_t *server) /* Found already bound interface. */ if (found_match) { - rem_node(m); + rem_node((node *)m); } else { log_server_info("Binding to interface %s port %d.\n", cfg_if->address, cfg_if->port); /* Create new interface. */ m = malloc(sizeof(iface_t)); - if (server_init_iface((iface_t*)m, cfg_if) < 0) { + if (server_init_iface(m, cfg_if) < 0) { free(m); m = 0; } @@ -280,128 +282,43 @@ static int server_bind_sockets(server_t *server) /* Move to new list. */ if (m) { - add_tail(newlist, m); + add_tail(&newlist->l, (node *)m); ++bound; } } + /* Publish new list. */ + ifacelist_t *oldlist = rcu_xchg_pointer(&s->ifaces, newlist); + /* Unlock configuration. */ rcu_read_unlock(); - /* Publish new list. */ - list* oldlist = rcu_xchg_pointer(&server->ifaces, newlist); - /* Ensure no one is reading old interfaces. */ synchronize_rcu(); - /* Remove deprecated interfaces. */ - WALK_LIST_DELSAFE(n, m, unmatched) { - iface_t *rm_if = (iface_t*)n; - log_server_info("Removing interface %s port %d.\n", - rm_if->addr, rm_if->port); - server_remove_iface(rm_if); - } - - /* Free original list. */ - WALK_LIST_DELSAFE(n, m, *oldlist) { - /*! \note Need to keep internal pointers, as they are shared - * with the newly published list. */ - free(n); - } - free(oldlist); - - return bound; -} - -/*! - * \brief Update socket handlers according to configuration. - * - * \param server Server instance. - * \retval 0 if successful (EOK). - * \retval <0 on errors (EINVAL). - */ -static int server_bind_handlers(server_t *server) -{ - if (!server || !server->ifaces) { - return KNOT_EINVAL; - } - - /* Lock config. */ - rcu_read_lock(); - - /* Estimate number of threads/manager. */ - int thr_count = 0; - int tcp_unit_size = 0; - if (conf()->workers < 1) { - thr_count = dt_optimal_size(); - tcp_unit_size = (thr_count * 2) + 1; /* Will be always odd. */ - } else { - thr_count = conf()->workers; - tcp_unit_size = thr_count + 1; /* Force configured value. */ - } - - dbg_server("server: configured %d worker%s per UDP iface\n", - thr_count, thr_count > 1 ? "s" : ""); - dbg_server("server: configured %d worker%s per TCP iface\n", - tcp_unit_size - 1, (tcp_unit_size - 1) > 1 ? "s" : ""); - - /* Create socket handlers. */ - node *n = 0; - iohandler_t* h = 0; - WALK_LIST(n, *server->ifaces) { - - iface_t *iface = (iface_t*)n; - assert(iface); - - /* Create UDP handlers. */ - dt_unit_t *unit = 0; - if (!iface->handler[UDP_ID]) { - unit = dt_create_coherent(thr_count, &udp_master, 0); - if (!unit) { - continue; - } - h = server_create_handler(server, iface->fd[UDP_ID], unit); - if (!h) { - dt_delete(&unit); - continue; - } - h->type = iface->type[UDP_ID]; - h->iface = iface; - - /* Save pointer. */ - iface->handler[UDP_ID] = h; /* No need for cmpxchg */ - dbg_server("server: creating UDP socket handlers for '%s:%d'\n", - iface->addr, iface->port); - - } - - /* Create TCP handlers. */ - if (!iface->handler[TCP_ID]) { - unit = dt_create(tcp_unit_size); - if (!unit) { - continue; - } - h = server_create_handler(server, iface->fd[TCP_ID], unit); - if (!h) { - dt_delete(&unit); - continue; - } - tcp_loop_unit(h, unit); - h->type = iface->type[TCP_ID]; - h->iface = iface; - - /* Save pointer. */ - iface->handler[TCP_ID] = h; /* No need for cmpxchg */ - dbg_server("server: creating TCP socket handlers for '%s:%d'\n", - iface->addr, iface->port); + /* Update UDP ifacelist (reload all threads). */ + dt_unit_t *tu = s->h[IO_UDP].unit; + for (unsigned i = 0; i < tu->size; ++i) { + ref_retain((ref_t *)newlist); + s->h[IO_UDP].state[i].s |= ServerReload; + if (s->state & ServerRunning) { + dt_activate(tu->threads[i]); + dt_signalize(tu->threads[i], SIGALRM); } + } + /* Update TCP ifacelist (reload master thread). */ + tu = s->h[IO_TCP].unit; + ref_retain((ref_t *)newlist); + s->h[IO_TCP].state[0].s |= ServerReload; + if (s->state & ServerRunning) { + dt_activate(tu->threads[0]); + dt_signalize(tu->threads[0], SIGALRM); } - /* Unlock config. */ - rcu_read_unlock(); + ref_release(&oldlist->ref); - return KNOT_EOK; + return bound; } server_t *server_create() @@ -414,18 +331,10 @@ server_t *server_create() } memset(server, 0, sizeof(server_t)); - server->state = ServerIdle; - init_list(&server->handlers); - server->ifaces = malloc(sizeof(list)); - init_list(server->ifaces); - // Create event scheduler dbg_server("server: creating event scheduler\n"); server->sched = evsched_new(); - dt_unit_t *unit = dt_create_coherent(1, evsched_run, 0); - iohandler_t *h = server_create_handler(server, -1, unit); - - h->data = server->sched; + server->iosched = dt_create_coherent(1, evsched_run, server->sched); // Create name server dbg_server("server: creating Name Server structure\n"); @@ -439,8 +348,8 @@ server_t *server_create() OpenSSL_add_all_digests(); // Create XFR handler - server->xfr_h = xfr_create(XFR_THREADS_COUNT, server->nameserver); - if (!server->xfr_h) { + server->xfr = xfr_create(XFR_THREADS_COUNT, server->nameserver); + if (!server->xfr) { knot_ns_destroy(&server->nameserver); free(server); return NULL; @@ -450,179 +359,98 @@ server_t *server_create() return server; } -iohandler_t *server_create_handler(server_t *server, int fd, dt_unit_t *unit) +int server_init_handler(iohandler_t * h, server_t *s, dt_unit_t *tu, void *d) { - // Create new worker - iohandler_t *handler = malloc(sizeof(iohandler_t)); - if (handler == 0) { - ERR_ALLOC_FAILED; - return 0; - } - - // Initialize - handler->fd = fd; - handler->type = 0; - handler->state = ServerIdle; - handler->server = server; - handler->unit = unit; - handler->iface = 0; - handler->data = 0; - handler->interrupt = 0; - - // Update unit data object - for (int i = 0; i < unit->size; ++i) { - dthread_t *thread = unit->threads[i]; + /* Initialize */ + memset(h, 0, sizeof(iohandler_t)); + h->server = s; + h->unit = tu; + h->data = d; + h->state = malloc(tu->size * sizeof(iostate_t)); + + /* Update unit data object */ + for (int i = 0; i < tu->size; ++i) { + dthread_t *thread = tu->threads[i]; + h->state[i].h = h; + h->state[i].s = 0; if (thread->run) { - dt_repurpose(thread, thread->run, handler); + dt_repurpose(thread, thread->run, h->state + i); } } - /*! \todo This requires locking to disable parallel updates (issue #278). - * However, this is only used when RCU is read-locked, so count with that. - */ - - /* Lock RCU. */ - rcu_read_lock(); - - // Update list - add_tail(&server->handlers, (node*)handler); - - /* Unlock RCU. */ - rcu_read_unlock(); - - return handler; + return KNOT_EOK; } -int server_remove_handler(server_t *server, iohandler_t *h) +int server_free_handler(iohandler_t *h) { - // Check - if (h == 0) { + if (!h || !h->server) { return KNOT_EINVAL; } - /* Lock RCU. */ - rcu_read_lock(); - - /*! \todo This requires locking to disable parallel updates (issue #278). - * However, this is only used when RCU is read-locked, so count with that. - */ - - // Remove node - rem_node((node*)h); - - // Wait for dispatcher to finish - if (h->state & ServerRunning) { - h->state = ServerIdle; + /* Wait for threads to finish */ + if (h->unit) { dt_stop(h->unit); - - /* Call interrupt handler. */ - if (h->interrupt) { - h->interrupt(h); - } - dt_join(h->unit); } - // Close socket - if (h->fd >= 0) { - socket_close(h->fd); - h->fd = -1; - } - - // Update interface - if (h->iface) { - int id = UDP_ID; - if (h->iface->handler[TCP_ID] == h) { - id = TCP_ID; - } - - h->iface->fd[id] = h->fd; - h->iface->handler[id] = 0; + /* Destroy worker context. */ + if (h->dtor) { + h->dtor(h->data); + h->data = NULL; } - - /* Unlock RCU. */ - rcu_read_unlock(); - - /* RCU synchronize. */ - synchronize_rcu(); - - // Destroy dispatcher and worker dt_delete(&h->unit); - free(h); + free(h->state); + memset(h, 0, sizeof(iohandler_t)); return KNOT_EOK; } -int server_start(server_t *server) +int server_start(server_t *s) { // Check server - if (server == 0) { + if (s == 0) { return KNOT_EINVAL; } dbg_server("server: starting server instance\n"); /* Start XFR handler. */ - xfr_start(server->xfr_h); + xfr_start(s->xfr); - /* Lock configuration. */ - rcu_read_lock(); + /* Start evsched handler. */ + dt_start(s->iosched); - // Start dispatchers + /* Start I/O handlers. */ int ret = KNOT_EOK; - server->state |= ServerRunning; - iohandler_t *h = 0; - WALK_LIST(h, server->handlers) { - - /* Already running. */ - if (h->state & ServerRunning) { - continue; - } - - h->state = ServerRunning; - ret = dt_start(h->unit); - if (ret < 0) { - break; + s->state |= ServerRunning; + if (s->tu_size > 0) { + for (unsigned i = 0; i < IO_COUNT; ++i) { + ret = dt_start(s->h[i].unit); } } - /* Unlock configuration. */ - rcu_read_unlock(); dbg_server("server: server started\n"); return ret; } -int server_wait(server_t *server) +int server_wait(server_t *s) { - /* Join threading unit. */ - xfr_join(server->xfr_h); - - /* Lock RCU. */ - rcu_read_lock(); + if (!s) return KNOT_EINVAL; - // Wait for handlers to finish - int ret = 0; - iohandler_t *h = 0, *nxt = 0; - WALK_LIST_DELSAFE(h, nxt, server->handlers) { - - /* Unlock RCU. */ - rcu_read_unlock(); + xfr_join(s->xfr); + dt_join(s->iosched); + if (s->tu_size == 0) { + return KNOT_EOK; + } - /* Remove handler. */ - int dret = dt_join(h->unit); - if (dret < 0) { - ret = dret; + int ret = KNOT_EOK; + for (unsigned i = 0; i < IO_COUNT; ++i) { + if ((ret = server_free_handler(s->h + i)) != KNOT_EOK) { + break; } - server_remove_handler(server, h); - - /* Relock RCU. */ - rcu_read_lock(); } - /* Unlock RCU. */ - rcu_read_unlock(); - return ret; } @@ -631,7 +459,7 @@ int server_refresh(server_t *server) if (server == NULL || server->nameserver == NULL) { return KNOT_EINVAL; } - + /* Lock RCU and fetch zones. */ rcu_read_lock(); knot_nameserver_t *ns = server->nameserver; @@ -641,7 +469,7 @@ int server_refresh(server_t *server) rcu_read_unlock(); return KNOT_ENOMEM; } - + /* REFRESH zones. */ for (unsigned i = 0; i < knot_zonedb_zone_count(ns->zone_db); ++i) { zonedata_t *zd = (zonedata_t *)zones[i]->data; @@ -656,7 +484,7 @@ int server_refresh(server_t *server) /* Cumulative delay. */ } } - + /* Unlock RCU. */ rcu_read_unlock(); free(zones); @@ -668,7 +496,7 @@ int server_reload(server_t *server, const char *cf) if (!server || !cf) { return KNOT_EINVAL; } - + log_server_info("Reloading configuration...\n"); int cf_ret = conf_open(cf); switch (cf_ret) { @@ -687,82 +515,53 @@ int server_reload(server_t *server, const char *cf) "reload failed.\n"); break; } - + /*! \todo Close and bind to new remote control. */ return cf_ret; } void server_stop(server_t *server) { - dbg_server("server: stopping server\n"); - + log_server_info("Stopping server...\n"); + /* Send termination event. */ evsched_schedule_term(server->sched, 0); /* Interrupt XFR handler execution. */ - if (server->xfr_h->interrupt) { - server->xfr_h->interrupt(server->xfr_h); - } - - /* Lock RCU. */ - rcu_read_lock(); + xfr_stop(server->xfr); - /* Notify servers to stop. */ - log_server_info("Stopping server...\n"); + /* Clear 'running' flag. */ server->state &= ~ServerRunning; - iohandler_t *h = 0; - WALK_LIST(h, server->handlers) { - h->state = ServerIdle; - dt_stop(h->unit); - - /* Call interrupt handler. */ - if (h->interrupt) { - h->interrupt(h); - } - } - - /* Unlock RCU. */ - rcu_read_unlock(); } void server_destroy(server_t **server) { // Check server - if (!server) { + if (!server || !*server) { return; } - if (!*server) { - return; - } - + dbg_server("server: destroying server instance\n"); - - // Free XFR master - xfr_free((*server)->xfr_h); - - // Free interfaces - node *n = 0, *nxt = 0; - if ((*server)->ifaces) { - WALK_LIST_DELSAFE(n, nxt, *(*server)->ifaces) { - iface_t *iface = (iface_t*)n; - server_remove_iface(iface); + + /* Free remaining interfaces. */ + ifacelist_t *ifaces = (*server)->ifaces; + iface_t *n = NULL, *m = NULL; + if (ifaces) { + WALK_LIST_DELSAFE(n, m, ifaces->l) { + server_remove_iface(n); } - free((*server)->ifaces); + free(ifaces); + (*server)->ifaces = NULL; } + xfr_free((*server)->xfr); stat_static_gath_free(); knot_ns_destroy(&(*server)->nameserver); - - // Delete event scheduler evsched_delete(&(*server)->sched); - - /* Delete rate limiting table. */ + dt_delete(&(*server)->iosched); rrl_destroy((*server)->rrl); - free(*server); - EVP_cleanup(); - *server = NULL; } @@ -773,7 +572,37 @@ int server_conf_hook(const struct conf_t *conf, void *data) if (!server) { return KNOT_EINVAL; } - + + /* Estimate number of threads/manager. */ + int ret = KNOT_EOK; + int tu_size = conf->workers; + if (tu_size < 1) { + tu_size = dt_optimal_size(); + } + if ((unsigned)tu_size != server->tu_size) { + /* Free old handlers */ + if (server->tu_size > 0) { + for (unsigned i = 0; i < IO_COUNT; ++i) { + ret = server_free_handler(server->h + i); + } + } + + /* Initialize I/O handlers. */ + size_t udp_size = tu_size; + if (udp_size < 2) udp_size = 2; + dt_unit_t *tu = dt_create_coherent(udp_size, &udp_master, NULL); + server_init_handler(server->h + IO_UDP, server, tu, NULL); + tu = dt_create(tu_size * 2); + server_init_handler(server->h + IO_TCP, server, tu, NULL); + tcp_loop_unit(server->h + IO_TCP, tu); + if (server->state & ServerRunning) { + for (unsigned i = 0; i < IO_COUNT; ++i) { + ret = dt_start(server->h[i].unit); + } + } + server->tu_size = tu_size; + } + /* Rate limiting. */ if (!server->rrl && conf->rrl > 0) { server->rrl = rrl_create(conf->rrl_size); @@ -784,7 +613,7 @@ int server_conf_hook(const struct conf_t *conf, void *data) } } if (server->rrl) { - if (rrl_rate(server->rrl) != conf->rrl) { + if (rrl_rate(server->rrl) != (uint32_t)conf->rrl) { rrl_setrate(server->rrl, conf->rrl); log_server_info("Rate limiting set to %u responses/sec.\n", conf->rrl); @@ -792,39 +621,29 @@ int server_conf_hook(const struct conf_t *conf, void *data) } /* Update bound sockets. */ - int ret = KNOT_EOK; if ((ret = server_bind_sockets(server)) < 0) { log_server_error("Failed to bind configured " "interfaces.\n"); - } else { - /* Update handlers. */ - if ((ret = server_bind_handlers(server)) < 0) { - log_server_error("Failed to create handlers for " - "configured interfaces.\n"); - } } - /* Exit if the server is not running. */ - if (ret != KNOT_EOK || !(server->state & ServerRunning)) { - return KNOT_ENOTRUNNING; - } + return ret; +} - /* Start new handlers. */ - iohandler_t *h = 0; - WALK_LIST(h, server->handlers) { - if (!(h->state & ServerRunning)) { - h->state = ServerRunning; - ret = dt_start(h->unit); - if (ret < 0) { - log_server_error("Handler for '%s@%d' " - "has failed to start.\n", - h->iface->addr, - h->iface->port); - break; - } +ref_t *server_set_ifaces(server_t *s, fdset_t **fds, int *count, int type) +{ + iface_t *i = NULL; + *count = 0; + + rcu_read_lock(); + fdset_destroy(*fds); + *fds = fdset_new(); + if (s->ifaces) { + WALK_LIST(i, s->ifaces->l) { + fdset_add(*fds, i->fd[type], OS_EV_READ); + *count += 1; } - } - return ret; + } + rcu_read_unlock(); + return (ref_t *)s->ifaces; } - |