diff options
Diffstat (limited to 'contrib/unbound/daemon/daemon.c')
-rw-r--r-- | contrib/unbound/daemon/daemon.c | 100 |
1 files changed, 81 insertions, 19 deletions
diff --git a/contrib/unbound/daemon/daemon.c b/contrib/unbound/daemon/daemon.c index b91683f..aed22c2 100644 --- a/contrib/unbound/daemon/daemon.c +++ b/contrib/unbound/daemon/daemon.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @@ -56,12 +56,16 @@ #include <openssl/engine.h> #endif +#ifdef HAVE_TIME_H +#include <time.h> +#endif +#include <sys/time.h> + #ifdef HAVE_NSS /* nss3 */ #include "nss.h" #endif -#include <ldns/ldns.h> #include "daemon/daemon.h" #include "daemon/worker.h" #include "daemon/remote.h" @@ -80,6 +84,7 @@ #include "util/random.h" #include "util/tube.h" #include "util/net_help.h" +#include "ldns/keyraw.h" #include <signal.h> /** How many quit requests happened. */ @@ -203,7 +208,7 @@ daemon_init(void) OPENSSL_config("unbound"); # endif # ifdef USE_GOST - (void)ldns_key_EVP_load_gost_id(); + (void)sldns_key_EVP_load_gost_id(); # endif OpenSSL_add_all_algorithms(); # if HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS @@ -250,9 +255,55 @@ daemon_open_shared_ports(struct daemon* daemon) { log_assert(daemon); if(daemon->cfg->port != daemon->listening_port) { - listening_ports_free(daemon->ports); - if(!(daemon->ports=listening_ports_open(daemon->cfg))) + size_t i; + int reuseport = 0; + struct listen_port* p0; + /* free and close old ports */ + if(daemon->ports != NULL) { + for(i=0; i<daemon->num_ports; i++) + listening_ports_free(daemon->ports[i]); + free(daemon->ports); + daemon->ports = NULL; + } + /* see if we want to reuseport */ +#if defined(__linux__) && defined(SO_REUSEPORT) + if(daemon->cfg->so_reuseport && daemon->cfg->num_threads > 0) + reuseport = 1; +#endif + /* try to use reuseport */ + p0 = listening_ports_open(daemon->cfg, &reuseport); + if(!p0) { + listening_ports_free(p0); return 0; + } + if(reuseport) { + /* reuseport was successful, allocate for it */ + daemon->num_ports = (size_t)daemon->cfg->num_threads; + } else { + /* do the normal, singleportslist thing, + * reuseport not enabled or did not work */ + daemon->num_ports = 1; + } + if(!(daemon->ports = (struct listen_port**)calloc( + daemon->num_ports, sizeof(*daemon->ports)))) { + listening_ports_free(p0); + return 0; + } + daemon->ports[0] = p0; + if(reuseport) { + /* continue to use reuseport */ + for(i=1; i<daemon->num_ports; i++) { + if(!(daemon->ports[i]= + listening_ports_open(daemon->cfg, + &reuseport)) || !reuseport ) { + for(i=0; i<daemon->num_ports; i++) + listening_ports_free(daemon->ports[i]); + free(daemon->ports); + daemon->ports = NULL; + return 0; + } + } + } daemon->listening_port = daemon->cfg->port; } if(!daemon->cfg->remote_control_enable && daemon->rc_port) { @@ -389,6 +440,7 @@ static void* thread_start(void* arg) { struct worker* worker = (struct worker*)arg; + int port_num = 0; log_thread_set(&worker->thread_num); ub_thread_blocksigs(); #ifdef THREADS_DISABLED @@ -396,7 +448,14 @@ thread_start(void* arg) tube_close_write(worker->cmd); close_other_pipes(worker->daemon, worker->thread_num); #endif - if(!worker_init(worker, worker->daemon->cfg, worker->daemon->ports, 0)) +#if defined(__linux__) && defined(SO_REUSEPORT) + if(worker->daemon->cfg->so_reuseport) + port_num = worker->thread_num; + else + port_num = 0; +#endif + if(!worker_init(worker, worker->daemon->cfg, + worker->daemon->ports[port_num], 0)) fatal_exit("Could not initialize thread"); worker_work(worker); @@ -469,7 +528,7 @@ daemon_fork(struct daemon* daemon) #if defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP) /* in libev the first inited base gets signals */ - if(!worker_init(daemon->workers[0], daemon->cfg, daemon->ports, 1)) + if(!worker_init(daemon->workers[0], daemon->cfg, daemon->ports[0], 1)) fatal_exit("Could not initialize main thread"); #endif @@ -483,7 +542,7 @@ daemon_fork(struct daemon* daemon) */ #if !(defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)) /* libevent has the last inited base get signals (or any base) */ - if(!worker_init(daemon->workers[0], daemon->cfg, daemon->ports, 1)) + if(!worker_init(daemon->workers[0], daemon->cfg, daemon->ports[0], 1)) fatal_exit("Could not initialize main thread"); #endif signal_handling_playback(daemon->workers[0]); @@ -529,11 +588,14 @@ daemon_cleanup(struct daemon* daemon) void daemon_delete(struct daemon* daemon) { + size_t i; if(!daemon) return; modstack_desetup(&daemon->mods, daemon->env); daemon_remote_delete(daemon->rc); - listening_ports_free(daemon->ports); + for(i = 0; i < daemon->num_ports; i++) + listening_ports_free(daemon->ports[i]); + free(daemon->ports); listening_ports_free(daemon->rc_ports); if(daemon->env) { slabhash_delete(daemon->env->msg_cache); @@ -558,7 +620,7 @@ daemon_delete(struct daemon* daemon) /* libcrypto cleanup */ #ifdef HAVE_SSL # if defined(USE_GOST) && defined(HAVE_LDNS_KEY_EVP_UNLOAD_GOST) - ldns_key_EVP_unload_gost(); + sldns_key_EVP_unload_gost(); # endif # if HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS && HAVE_DECL_SK_SSL_COMP_POP_FREE # ifndef S_SPLINT_S |