diff options
| author | Dag-Erling Smørgrav <des@FreeBSD.org> | 2018-09-10 16:31:49 +0000 |
|---|---|---|
| committer | Dag-Erling Smørgrav <des@FreeBSD.org> | 2018-09-10 16:31:49 +0000 |
| commit | 4aea2433fa04a7a86c8972869bd021b7a3622dc8 (patch) | |
| tree | 7f4f9830855c0cb429f2c902b18e688a8020f299 /daemon | |
| parent | 7b6fdf425a9ef38fe9e16779b3af25863104d9c0 (diff) | |
Notes
Diffstat (limited to 'daemon')
| -rw-r--r-- | daemon/cachedump.c | 42 | ||||
| -rw-r--r-- | daemon/cachedump.h | 7 | ||||
| -rw-r--r-- | daemon/remote.c | 535 | ||||
| -rw-r--r-- | daemon/remote.h | 27 |
4 files changed, 314 insertions, 297 deletions
diff --git a/daemon/cachedump.c b/daemon/cachedump.c index 81061870b581..5a72e9d1106f 100644 --- a/daemon/cachedump.c +++ b/daemon/cachedump.c @@ -62,7 +62,7 @@ /** dump one rrset zonefile line */ static int -dump_rrset_line(SSL* ssl, struct ub_packed_rrset_key* k, time_t now, size_t i) +dump_rrset_line(RES* ssl, struct ub_packed_rrset_key* k, time_t now, size_t i) { char s[65535]; if(!packed_rr_to_string(k, i, now, s, sizeof(s))) { @@ -73,7 +73,7 @@ dump_rrset_line(SSL* ssl, struct ub_packed_rrset_key* k, time_t now, size_t i) /** dump rrset key and data info */ static int -dump_rrset(SSL* ssl, struct ub_packed_rrset_key* k, +dump_rrset(RES* ssl, struct ub_packed_rrset_key* k, struct packed_rrset_data* d, time_t now) { size_t i; @@ -99,7 +99,7 @@ dump_rrset(SSL* ssl, struct ub_packed_rrset_key* k, /** dump lruhash rrset cache */ static int -dump_rrset_lruhash(SSL* ssl, struct lruhash* h, time_t now) +dump_rrset_lruhash(RES* ssl, struct lruhash* h, time_t now) { struct lruhash_entry* e; /* lruhash already locked by caller */ @@ -118,7 +118,7 @@ dump_rrset_lruhash(SSL* ssl, struct lruhash* h, time_t now) /** dump rrset cache */ static int -dump_rrset_cache(SSL* ssl, struct worker* worker) +dump_rrset_cache(RES* ssl, struct worker* worker) { struct rrset_cache* r = worker->env.rrset_cache; size_t slab; @@ -137,7 +137,7 @@ dump_rrset_cache(SSL* ssl, struct worker* worker) /** dump message to rrset reference */ static int -dump_msg_ref(SSL* ssl, struct ub_packed_rrset_key* k) +dump_msg_ref(RES* ssl, struct ub_packed_rrset_key* k) { char* nm, *tp, *cl; nm = sldns_wire2str_dname(k->rk.dname, k->rk.dname_len); @@ -164,7 +164,7 @@ dump_msg_ref(SSL* ssl, struct ub_packed_rrset_key* k) /** dump message entry */ static int -dump_msg(SSL* ssl, struct query_info* k, struct reply_info* d, +dump_msg(RES* ssl, struct query_info* k, struct reply_info* d, time_t now) { size_t i; @@ -246,7 +246,7 @@ copy_msg(struct regional* region, struct lruhash_entry* e, /** dump lruhash msg cache */ static int -dump_msg_lruhash(SSL* ssl, struct worker* worker, struct lruhash* h) +dump_msg_lruhash(RES* ssl, struct worker* worker, struct lruhash* h) { struct lruhash_entry* e; struct query_info* k; @@ -274,7 +274,7 @@ dump_msg_lruhash(SSL* ssl, struct worker* worker, struct lruhash* h) /** dump msg cache */ static int -dump_msg_cache(SSL* ssl, struct worker* worker) +dump_msg_cache(RES* ssl, struct worker* worker) { struct slabhash* sh = worker->env.msg_cache; size_t slab; @@ -291,7 +291,7 @@ dump_msg_cache(SSL* ssl, struct worker* worker) } int -dump_cache(SSL* ssl, struct worker* worker) +dump_cache(RES* ssl, struct worker* worker) { if(!dump_rrset_cache(ssl, worker)) return 0; @@ -302,7 +302,7 @@ dump_cache(SSL* ssl, struct worker* worker) /** read a line from ssl into buffer */ static int -ssl_read_buf(SSL* ssl, sldns_buffer* buf) +ssl_read_buf(RES* ssl, sldns_buffer* buf) { return ssl_read_line(ssl, (char*)sldns_buffer_begin(buf), sldns_buffer_capacity(buf)); @@ -310,7 +310,7 @@ ssl_read_buf(SSL* ssl, sldns_buffer* buf) /** check fixed text on line */ static int -read_fixed(SSL* ssl, sldns_buffer* buf, const char* str) +read_fixed(RES* ssl, sldns_buffer* buf, const char* str) { if(!ssl_read_buf(ssl, buf)) return 0; return (strcmp((char*)sldns_buffer_begin(buf), str) == 0); @@ -318,7 +318,7 @@ read_fixed(SSL* ssl, sldns_buffer* buf, const char* str) /** load an RR into rrset */ static int -load_rr(SSL* ssl, sldns_buffer* buf, struct regional* region, +load_rr(RES* ssl, sldns_buffer* buf, struct regional* region, struct ub_packed_rrset_key* rk, struct packed_rrset_data* d, unsigned int i, int is_rrsig, int* go_on, time_t now) { @@ -435,7 +435,7 @@ move_into_cache(struct ub_packed_rrset_key* k, /** load an rrset entry */ static int -load_rrset(SSL* ssl, sldns_buffer* buf, struct worker* worker) +load_rrset(RES* ssl, sldns_buffer* buf, struct worker* worker) { char* s = (char*)sldns_buffer_begin(buf); struct regional* region = worker->scratchpad; @@ -519,7 +519,7 @@ load_rrset(SSL* ssl, sldns_buffer* buf, struct worker* worker) /** load rrset cache */ static int -load_rrset_cache(SSL* ssl, struct worker* worker) +load_rrset_cache(RES* ssl, struct worker* worker) { sldns_buffer* buf = worker->env.scratch_buffer; if(!read_fixed(ssl, buf, "START_RRSET_CACHE")) return 0; @@ -575,7 +575,7 @@ load_qinfo(char* str, struct query_info* qinfo, struct regional* region) /** load a msg rrset reference */ static int -load_ref(SSL* ssl, sldns_buffer* buf, struct worker* worker, +load_ref(RES* ssl, sldns_buffer* buf, struct worker* worker, struct regional *region, struct ub_packed_rrset_key** rrset, int* go_on) { @@ -620,7 +620,7 @@ load_ref(SSL* ssl, sldns_buffer* buf, struct worker* worker, /** load a msg entry */ static int -load_msg(SSL* ssl, sldns_buffer* buf, struct worker* worker) +load_msg(RES* ssl, sldns_buffer* buf, struct worker* worker) { struct regional* region = worker->scratchpad; struct query_info qinf; @@ -685,7 +685,7 @@ load_msg(SSL* ssl, sldns_buffer* buf, struct worker* worker) /** load msg cache */ static int -load_msg_cache(SSL* ssl, struct worker* worker) +load_msg_cache(RES* ssl, struct worker* worker) { sldns_buffer* buf = worker->env.scratch_buffer; if(!read_fixed(ssl, buf, "START_MSG_CACHE")) return 0; @@ -698,7 +698,7 @@ load_msg_cache(SSL* ssl, struct worker* worker) } int -load_cache(SSL* ssl, struct worker* worker) +load_cache(RES* ssl, struct worker* worker) { if(!load_rrset_cache(ssl, worker)) return 0; @@ -709,7 +709,7 @@ load_cache(SSL* ssl, struct worker* worker) /** print details on a delegation point */ static void -print_dp_details(SSL* ssl, struct worker* worker, struct delegpt* dp) +print_dp_details(RES* ssl, struct worker* worker, struct delegpt* dp) { char buf[257]; struct delegpt_addr* a; @@ -785,7 +785,7 @@ print_dp_details(SSL* ssl, struct worker* worker, struct delegpt* dp) /** print main dp info */ static void -print_dp_main(SSL* ssl, struct delegpt* dp, struct dns_msg* msg) +print_dp_main(RES* ssl, struct delegpt* dp, struct dns_msg* msg) { size_t i, n_ns, n_miss, n_addr, n_res, n_avail; @@ -813,7 +813,7 @@ print_dp_main(SSL* ssl, struct delegpt* dp, struct dns_msg* msg) return; } -int print_deleg_lookup(SSL* ssl, struct worker* worker, uint8_t* nm, +int print_deleg_lookup(RES* ssl, struct worker* worker, uint8_t* nm, size_t nmlen, int ATTR_UNUSED(nmlabs)) { /* deep links into the iterator module */ diff --git a/daemon/cachedump.h b/daemon/cachedump.h index 0f2feabcb7f4..72c172d4414e 100644 --- a/daemon/cachedump.h +++ b/daemon/cachedump.h @@ -72,6 +72,7 @@ #ifndef DAEMON_DUMPCACHE_H #define DAEMON_DUMPCACHE_H struct worker; +#include "daemon/remote.h" /** * Dump cache(s) to text @@ -80,7 +81,7 @@ struct worker; * ptrs to the caches. * @return false on ssl print error. */ -int dump_cache(SSL* ssl, struct worker* worker); +int dump_cache(RES* ssl, struct worker* worker); /** * Load cache(s) from text @@ -89,7 +90,7 @@ int dump_cache(SSL* ssl, struct worker* worker); * ptrs to the caches. * @return false on ssl error. */ -int load_cache(SSL* ssl, struct worker* worker); +int load_cache(RES* ssl, struct worker* worker); /** * Print the delegation used to lookup for this name. @@ -101,7 +102,7 @@ int load_cache(SSL* ssl, struct worker* worker); * @param nmlabs: labels in name. * @return false on ssl error. */ -int print_deleg_lookup(SSL* ssl, struct worker* worker, uint8_t* nm, +int print_deleg_lookup(RES* ssl, struct worker* worker, uint8_t* nm, size_t nmlen, int nmlabs); #endif /* DAEMON_DUMPCACHE_H */ diff --git a/daemon/remote.c b/daemon/remote.c index cfc91eb98b3a..011c55e659f2 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -142,130 +142,20 @@ timeval_divide(struct timeval* avg, const struct timeval* sum, long long d) #endif } -/* - * The following function was generated using the openssl utility, using - * the command : "openssl dhparam -C 2048" - * (some openssl versions reject DH that is 'too small', eg. 512). - */ -#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL) -#ifndef S_SPLINT_S -static DH *get_dh2048(void) -{ - static unsigned char dh2048_p[]={ - 0xE7,0x36,0x28,0x3B,0xE4,0xC3,0x32,0x1C,0x01,0xC3,0x67,0xD6, - 0xF5,0xF3,0xDA,0xDC,0x71,0xC0,0x42,0x8B,0xE6,0xEB,0x8D,0x80, - 0x35,0x7F,0x09,0x45,0x30,0xE5,0xB2,0x92,0x81,0x3F,0x08,0xCD, - 0x36,0x5E,0x19,0x83,0x62,0xCC,0xAE,0x9B,0x81,0x66,0x24,0xEE, - 0x16,0x6F,0xA9,0x9E,0xF4,0x82,0x1B,0xDD,0x46,0xC7,0x33,0x5D, - 0xF4,0xCA,0xE6,0x8F,0xFC,0xD4,0xD8,0x58,0x94,0x24,0x5D,0xFF, - 0x0A,0xE8,0xEF,0x3D,0xCE,0xBB,0x50,0x94,0xE0,0x5F,0xE8,0x41, - 0xC3,0x35,0x30,0x37,0xD5,0xCB,0x8F,0x3D,0x95,0x15,0x1A,0x77, - 0x42,0xB2,0x06,0x86,0xF6,0x09,0x66,0x0E,0x9A,0x25,0x94,0x3E, - 0xD2,0x04,0x25,0x25,0x1D,0x23,0xEB,0xDC,0x4D,0x0C,0x83,0x28, - 0x2E,0x15,0x81,0x2D,0xC1,0xAF,0x8D,0x36,0x64,0xE3,0x9A,0x83, - 0x78,0xC2,0x8D,0xC0,0x9D,0xD9,0x3A,0x1C,0xC5,0x2B,0x50,0x68, - 0x07,0xA9,0x4B,0x8C,0x07,0x57,0xD6,0x15,0x03,0x4E,0x9E,0x01, - 0xF2,0x6F,0x35,0xAC,0x26,0x9C,0x92,0x68,0x61,0x13,0xFB,0x01, - 0xBA,0x22,0x36,0x01,0x55,0xB6,0x62,0xD9,0xB2,0x98,0xCE,0x5D, - 0x4B,0xA5,0x41,0xD6,0xE5,0x70,0x78,0x12,0x1F,0x64,0xB6,0x6F, - 0xB0,0x91,0x51,0x91,0x92,0xC0,0x94,0x3A,0xD1,0x28,0x4D,0x30, - 0x84,0x3E,0xE4,0xE4,0x7F,0x47,0x89,0xB1,0xB6,0x8C,0x8E,0x0E, - 0x26,0xDB,0xCD,0x17,0x07,0x2A,0x21,0x7A,0xCC,0x68,0xE8,0x57, - 0x94,0x9E,0x59,0x61,0xEC,0x20,0x34,0x26,0x0D,0x66,0x44,0xEB, - 0x6F,0x02,0x58,0xE2,0xED,0xF6,0xF3,0x1B,0xBF,0x9E,0x45,0x52, - 0x5A,0x49,0xA1,0x5B, - }; - static unsigned char dh2048_g[]={ - 0x02, - }; - DH *dh = NULL; - BIGNUM *p = NULL, *g = NULL; - - dh = DH_new(); - p = BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL); - g = BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL); - if (!dh || !p || !g) - goto err; - -#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL) - dh->p = p; - dh->g = g; -#else - if (!DH_set0_pqg(dh, p, NULL, g)) - goto err; -#endif - return dh; -err: - if (p) - BN_free(p); - if (g) - BN_free(g); - if (dh) - DH_free(dh); - return NULL; -} -#endif /* SPLINT */ -#endif /* OPENSSL_VERSION_NUMBER < 0x10100000 */ - -struct daemon_remote* -daemon_remote_create(struct config_file* cfg) +static int +remote_setup_ctx(struct daemon_remote* rc, struct config_file* cfg) { char* s_cert; char* s_key; - struct daemon_remote* rc = (struct daemon_remote*)calloc(1, - sizeof(*rc)); - if(!rc) { - log_err("out of memory in daemon_remote_create"); - return NULL; - } - rc->max_active = 10; - - if(!cfg->remote_control_enable) { - rc->ctx = NULL; - return rc; - } rc->ctx = SSL_CTX_new(SSLv23_server_method()); if(!rc->ctx) { log_crypto_err("could not SSL_CTX_new"); - free(rc); - return NULL; + return 0; } if(!listen_sslctx_setup(rc->ctx)) { - daemon_remote_delete(rc); - return NULL; + return 0; } - if (cfg->remote_control_use_cert == 0) { - /* No certificates are requested */ -#if defined(SSL_OP_NO_TLSv1_3) - /* in openssl 1.1.1, negotiation code for tls 1.3 does - * not allow the unauthenticated aNULL and eNULL ciphers */ - SSL_CTX_set_options(rc->ctx, SSL_OP_NO_TLSv1_3); -#endif -#ifdef HAVE_SSL_CTX_SET_SECURITY_LEVEL - SSL_CTX_set_security_level(rc->ctx, 0); -#endif - if(!SSL_CTX_set_cipher_list(rc->ctx, "aNULL:eNULL")) { - log_crypto_err("Failed to set aNULL cipher list"); - daemon_remote_delete(rc); - return NULL; - } - - /* in openssl 1.1, the securitylevel 0 allows eNULL, that - * does not need the DH */ -#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL) - /* Since we have no certificates and hence no source of - * DH params, let's generate and set them - */ - if(!SSL_CTX_set_tmp_dh(rc->ctx,get_dh2048())) { - log_crypto_err("Wanted to set DH param, but failed"); - daemon_remote_delete(rc); - return NULL; - } -#endif - return rc; - } - rc->use_cert = 1; s_cert = fname_after_chroot(cfg->server_cert_file, cfg, 1); s_key = fname_after_chroot(cfg->server_key_file, cfg, 1); if(!s_cert || !s_key) { @@ -294,14 +184,46 @@ daemon_remote_create(struct config_file* cfg) setup_error: free(s_cert); free(s_key); - daemon_remote_delete(rc); - return NULL; + return 0; } SSL_CTX_set_client_CA_list(rc->ctx, SSL_load_client_CA_file(s_cert)); SSL_CTX_set_verify(rc->ctx, SSL_VERIFY_PEER, NULL); free(s_cert); free(s_key); + return 1; +} + +struct daemon_remote* +daemon_remote_create(struct config_file* cfg) +{ + struct daemon_remote* rc = (struct daemon_remote*)calloc(1, + sizeof(*rc)); + if(!rc) { + log_err("out of memory in daemon_remote_create"); + return NULL; + } + rc->max_active = 10; + if(!cfg->remote_control_enable) { + rc->ctx = NULL; + return rc; + } + if(options_remote_is_address(cfg) && cfg->control_use_cert) { + if(!remote_setup_ctx(rc, cfg)) { + daemon_remote_delete(rc); + return NULL; + } + rc->use_cert = 1; + } else { + struct config_strlist* p; + rc->ctx = NULL; + rc->use_cert = 0; + if(!options_remote_is_address(cfg)) + for(p = cfg->control_ifs.first; p; p = p->next) { + if(p->str && p->str[0] != '/') + log_warn("control-interface %s is not using TLS, but plain transfer, because first control-interface in config file is a local socket (starts with a /).", p->str); + } + } return rc; } @@ -442,9 +364,9 @@ struct listen_port* daemon_remote_open_ports(struct config_file* cfg) { struct listen_port* l = NULL; log_assert(cfg->remote_control_enable && cfg->control_port); - if(cfg->control_ifs) { + if(cfg->control_ifs.first) { struct config_strlist* p; - for(p = cfg->control_ifs; p; p = p->next) { + for(p = cfg->control_ifs.first; p; p = p->next) { if(!add_open(p->str, cfg->control_port, &l, 1, cfg)) { listening_ports_free(l); return NULL; @@ -551,6 +473,7 @@ int remote_accept_callback(struct comm_point* c, void* arg, int err, log_err("out of memory"); goto close_exit; } + n->fd = newfd; /* start in reading state */ n->c = comm_point_create_raw(rc->worker->base, newfd, 0, &remote_control_callback, n); @@ -565,22 +488,26 @@ int remote_accept_callback(struct comm_point* c, void* arg, int err, comm_point_start_listening(n->c, -1, REMOTE_CONTROL_TCP_TIMEOUT); memcpy(&n->c->repinfo.addr, &addr, addrlen); n->c->repinfo.addrlen = addrlen; - n->shake_state = rc_hs_read; - n->ssl = SSL_new(rc->ctx); - if(!n->ssl) { - log_crypto_err("could not SSL_new"); - comm_point_delete(n->c); - free(n); - goto close_exit; - } - SSL_set_accept_state(n->ssl); - (void)SSL_set_mode(n->ssl, SSL_MODE_AUTO_RETRY); - if(!SSL_set_fd(n->ssl, newfd)) { - log_crypto_err("could not SSL_set_fd"); - SSL_free(n->ssl); - comm_point_delete(n->c); - free(n); - goto close_exit; + if(rc->use_cert) { + n->shake_state = rc_hs_read; + n->ssl = SSL_new(rc->ctx); + if(!n->ssl) { + log_crypto_err("could not SSL_new"); + comm_point_delete(n->c); + free(n); + goto close_exit; + } + SSL_set_accept_state(n->ssl); + (void)SSL_set_mode(n->ssl, SSL_MODE_AUTO_RETRY); + if(!SSL_set_fd(n->ssl, newfd)) { + log_crypto_err("could not SSL_set_fd"); + SSL_free(n->ssl); + comm_point_delete(n->c); + free(n); + goto close_exit; + } + } else { + n->ssl = NULL; } n->rc = rc; @@ -622,27 +549,45 @@ clean_point(struct daemon_remote* rc, struct rc_state* s) } int -ssl_print_text(SSL* ssl, const char* text) +ssl_print_text(RES* res, const char* text) { int r; - if(!ssl) + if(!res) return 0; - ERR_clear_error(); - if((r=SSL_write(ssl, text, (int)strlen(text))) <= 0) { - if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) { - verbose(VERB_QUERY, "warning, in SSL_write, peer " - "closed connection"); + if(res->ssl) { + ERR_clear_error(); + if((r=SSL_write(res->ssl, text, (int)strlen(text))) <= 0) { + if(SSL_get_error(res->ssl, r) == SSL_ERROR_ZERO_RETURN) { + verbose(VERB_QUERY, "warning, in SSL_write, peer " + "closed connection"); + return 0; + } + log_crypto_err("could not SSL_write"); return 0; } - log_crypto_err("could not SSL_write"); - return 0; + } else { + size_t at = 0; + while(at < strlen(text)) { + ssize_t r = send(res->fd, text+at, strlen(text)-at, 0); + if(r == -1) { + if(errno == EAGAIN || errno == EINTR) + continue; +#ifndef USE_WINSOCK + log_err("could not send: %s", strerror(errno)); +#else + log_err("could not send: %s", wsa_strerror(WSAGetLastError())); +#endif + return 0; + } + at += r; + } } return 1; } /** print text over the ssl connection */ static int -ssl_print_vmsg(SSL* ssl, const char* format, va_list args) +ssl_print_vmsg(RES* ssl, const char* format, va_list args) { char msg[1024]; vsnprintf(msg, sizeof(msg), format, args); @@ -650,7 +595,7 @@ ssl_print_vmsg(SSL* ssl, const char* format, va_list args) } /** printf style printing to the ssl connection */ -int ssl_printf(SSL* ssl, const char* format, ...) +int ssl_printf(RES* ssl, const char* format, ...) { va_list args; int ret; @@ -661,21 +606,42 @@ int ssl_printf(SSL* ssl, const char* format, ...) } int -ssl_read_line(SSL* ssl, char* buf, size_t max) +ssl_read_line(RES* res, char* buf, size_t max) { int r; size_t len = 0; - if(!ssl) + if(!res) return 0; while(len < max) { - ERR_clear_error(); - if((r=SSL_read(ssl, buf+len, 1)) <= 0) { - if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) { - buf[len] = 0; - return 1; + if(res->ssl) { + ERR_clear_error(); + if((r=SSL_read(res->ssl, buf+len, 1)) <= 0) { + if(SSL_get_error(res->ssl, r) == SSL_ERROR_ZERO_RETURN) { + buf[len] = 0; + return 1; + } + log_crypto_err("could not SSL_read"); + return 0; + } + } else { + while(1) { + ssize_t rr = recv(res->fd, buf+len, 1, 0); + if(rr <= 0) { + if(rr == 0) { + buf[len] = 0; + return 1; + } + if(errno == EINTR || errno == EAGAIN) + continue; +#ifndef USE_WINSOCK + log_err("could not recv: %s", strerror(errno)); +#else + log_err("could not recv: %s", wsa_strerror(WSAGetLastError())); +#endif + return 0; + } + break; } - log_crypto_err("could not SSL_read"); - return 0; } if(buf[len] == '\n') { /* return string without \n */ @@ -700,14 +666,14 @@ skipwhite(char* str) } /** send the OK to the control client */ -static void send_ok(SSL* ssl) +static void send_ok(RES* ssl) { (void)ssl_printf(ssl, "ok\n"); } /** do the stop command */ static void -do_stop(SSL* ssl, struct daemon_remote* rc) +do_stop(RES* ssl, struct daemon_remote* rc) { rc->worker->need_to_exit = 1; comm_base_exit(rc->worker->base); @@ -716,7 +682,7 @@ do_stop(SSL* ssl, struct daemon_remote* rc) /** do the reload command */ static void -do_reload(SSL* ssl, struct daemon_remote* rc) +do_reload(RES* ssl, struct daemon_remote* rc) { rc->worker->need_to_exit = 0; comm_base_exit(rc->worker->base); @@ -725,7 +691,7 @@ do_reload(SSL* ssl, struct daemon_remote* rc) /** do the verbosity command */ static void -do_verbosity(SSL* ssl, char* str) +do_verbosity(RES* ssl, char* str) { int val = atoi(str); if(val == 0 && strcmp(str, "0") != 0) { @@ -738,7 +704,7 @@ do_verbosity(SSL* ssl, char* str) /** print stats from statinfo */ static int -print_stats(SSL* ssl, const char* nm, struct ub_stats_info* s) +print_stats(RES* ssl, const char* nm, struct ub_stats_info* s) { struct timeval sumwait, avg; if(!ssl_printf(ssl, "%s.num.queries"SQ"%lu\n", nm, @@ -797,7 +763,7 @@ print_stats(SSL* ssl, const char* nm, struct ub_stats_info* s) /** print stats for one thread */ static int -print_thread_stats(SSL* ssl, int i, struct ub_stats_info* s) +print_thread_stats(RES* ssl, int i, struct ub_stats_info* s) { char nm[32]; snprintf(nm, sizeof(nm), "thread%d", i); @@ -807,7 +773,7 @@ print_thread_stats(SSL* ssl, int i, struct ub_stats_info* s) /** print long number */ static int -print_longnum(SSL* ssl, const char* desc, size_t x) +print_longnum(RES* ssl, const char* desc, size_t x) { if(x > 1024*1024*1024) { /* more than a Gb */ @@ -822,7 +788,7 @@ print_longnum(SSL* ssl, const char* desc, size_t x) /** print mem stats */ static int -print_mem(SSL* ssl, struct worker* worker, struct daemon* daemon) +print_mem(RES* ssl, struct worker* worker, struct daemon* daemon) { size_t msg, rrset, val, iter, respip; #ifdef CLIENT_SUBNET @@ -885,7 +851,7 @@ print_mem(SSL* ssl, struct worker* worker, struct daemon* daemon) /** print uptime stats */ static int -print_uptime(SSL* ssl, struct worker* worker, int reset) +print_uptime(RES* ssl, struct worker* worker, int reset) { struct timeval now = *worker->env.now_tv; struct timeval up, dt; @@ -904,7 +870,7 @@ print_uptime(SSL* ssl, struct worker* worker, int reset) /** print extended histogram */ static int -print_hist(SSL* ssl, struct ub_stats_info* s) +print_hist(RES* ssl, struct ub_stats_info* s) { struct timehist* hist; size_t i; @@ -932,7 +898,7 @@ print_hist(SSL* ssl, struct ub_stats_info* s) /** print extended stats */ static int -print_ext(SSL* ssl, struct ub_stats_info* s) +print_ext(RES* ssl, struct ub_stats_info* s) { int i; char nm[16]; @@ -1089,7 +1055,7 @@ print_ext(SSL* ssl, struct ub_stats_info* s) /** do the stats command */ static void -do_stats(SSL* ssl, struct daemon_remote* rc, int reset) +do_stats(RES* ssl, struct daemon_remote* rc, int reset) { struct daemon* daemon = rc->worker->daemon; struct ub_stats_info total; @@ -1123,7 +1089,7 @@ do_stats(SSL* ssl, struct daemon_remote* rc, int reset) /** parse commandline argument domain name */ static int -parse_arg_name(SSL* ssl, char* str, uint8_t** res, size_t* len, int* labs) +parse_arg_name(RES* ssl, char* str, uint8_t** res, size_t* len, int* labs) { uint8_t nm[LDNS_MAX_DOMAINLEN+1]; size_t nmlen = sizeof(nm); @@ -1149,7 +1115,7 @@ parse_arg_name(SSL* ssl, char* str, uint8_t** res, size_t* len, int* labs) /** find second argument, modifies string */ static int -find_arg2(SSL* ssl, char* arg, char** arg2) +find_arg2(RES* ssl, char* arg, char** arg2) { char* as = strchr(arg, ' '); char* at = strchr(arg, '\t'); @@ -1174,7 +1140,7 @@ find_arg2(SSL* ssl, char* arg, char** arg2) /** Add a new zone */ static int -perform_zone_add(SSL* ssl, struct local_zones* zones, char* arg) +perform_zone_add(RES* ssl, struct local_zones* zones, char* arg) { uint8_t* nm; int nmlabs; @@ -1214,7 +1180,7 @@ perform_zone_add(SSL* ssl, struct local_zones* zones, char* arg) /** Do the local_zone command */ static void -do_zone_add(SSL* ssl, struct local_zones* zones, char* arg) +do_zone_add(RES* ssl, struct local_zones* zones, char* arg) { if(!perform_zone_add(ssl, zones, arg)) return; @@ -1223,7 +1189,7 @@ do_zone_add(SSL* ssl, struct local_zones* zones, char* arg) /** Do the local_zones command */ static void -do_zones_add(SSL* ssl, struct local_zones* zones) +do_zones_add(RES* ssl, struct local_zones* zones) { char buf[2048]; int num = 0; @@ -1242,7 +1208,7 @@ do_zones_add(SSL* ssl, struct local_zones* zones) /** Remove a zone */ static int -perform_zone_remove(SSL* ssl, struct local_zones* zones, char* arg) +perform_zone_remove(RES* ssl, struct local_zones* zones, char* arg) { uint8_t* nm; int nmlabs; @@ -1263,7 +1229,7 @@ perform_zone_remove(SSL* ssl, struct local_zones* zones, char* arg) /** Do the local_zone_remove command */ static void -do_zone_remove(SSL* ssl, struct local_zones* zones, char* arg) +do_zone_remove(RES* ssl, struct local_zones* zones, char* arg) { if(!perform_zone_remove(ssl, zones, arg)) return; @@ -1272,7 +1238,7 @@ do_zone_remove(SSL* ssl, struct local_zones* zones, char* arg) /** Do the local_zones_remove command */ static void -do_zones_remove(SSL* ssl, struct local_zones* zones) +do_zones_remove(RES* ssl, struct local_zones* zones) { char buf[2048]; int num = 0; @@ -1291,7 +1257,7 @@ do_zones_remove(SSL* ssl, struct local_zones* zones) /** Add new RR data */ static int -perform_data_add(SSL* ssl, struct local_zones* zones, char* arg) +perform_data_add(RES* ssl, struct local_zones* zones, char* arg) { if(!local_zones_add_RR(zones, arg)) { ssl_printf(ssl,"error in syntax or out of memory, %s\n", arg); @@ -1302,7 +1268,7 @@ perform_data_add(SSL* ssl, struct local_zones* zones, char* arg) /** Do the local_data command */ static void -do_data_add(SSL* ssl, struct local_zones* zones, char* arg) +do_data_add(RES* ssl, struct local_zones* zones, char* arg) { if(!perform_data_add(ssl, zones, arg)) return; @@ -1311,7 +1277,7 @@ do_data_add(SSL* ssl, struct local_zones* zones, char* arg) /** Do the local_datas command */ static void -do_datas_add(SSL* ssl, struct local_zones* zones) +do_datas_add(RES* ssl, struct local_zones* zones) { char buf[2048]; int num = 0; @@ -1330,7 +1296,7 @@ do_datas_add(SSL* ssl, struct local_zones* zones) /** Remove RR data */ static int -perform_data_remove(SSL* ssl, struct local_zones* zones, char* arg) +perform_data_remove(RES* ssl, struct local_zones* zones, char* arg) { uint8_t* nm; int nmlabs; @@ -1345,7 +1311,7 @@ perform_data_remove(SSL* ssl, struct local_zones* zones, char* arg) /** Do the local_data_remove command */ static void -do_data_remove(SSL* ssl, struct local_zones* zones, char* arg) +do_data_remove(RES* ssl, struct local_zones* zones, char* arg) { if(!perform_data_remove(ssl, zones, arg)) return; @@ -1354,7 +1320,7 @@ do_data_remove(SSL* ssl, struct local_zones* zones, char* arg) /** Do the local_datas_remove command */ static void -do_datas_remove(SSL* ssl, struct local_zones* zones) +do_datas_remove(RES* ssl, struct local_zones* zones) { char buf[2048]; int num = 0; @@ -1373,7 +1339,7 @@ do_datas_remove(SSL* ssl, struct local_zones* zones) /** Add a new zone to view */ static void -do_view_zone_add(SSL* ssl, struct worker* worker, char* arg) +do_view_zone_add(RES* ssl, struct worker* worker, char* arg) { char* arg2; struct view* v; @@ -1406,7 +1372,7 @@ do_view_zone_add(SSL* ssl, struct worker* worker, char* arg) /** Remove a zone from view */ static void -do_view_zone_remove(SSL* ssl, struct worker* worker, char* arg) +do_view_zone_remove(RES* ssl, struct worker* worker, char* arg) { char* arg2; struct view* v; @@ -1429,7 +1395,7 @@ do_view_zone_remove(SSL* ssl, struct worker* worker, char* arg) /** Add new RR data to view */ static void -do_view_data_add(SSL* ssl, struct worker* worker, char* arg) +do_view_data_add(RES* ssl, struct worker* worker, char* arg) { char* arg2; struct view* v; @@ -1454,7 +1420,7 @@ do_view_data_add(SSL* ssl, struct worker* worker, char* arg) /** Remove RR data from view */ static void -do_view_data_remove(SSL* ssl, struct worker* worker, char* arg) +do_view_data_remove(RES* ssl, struct worker* worker, char* arg) { char* arg2; struct view* v; @@ -1477,7 +1443,7 @@ do_view_data_remove(SSL* ssl, struct worker* worker, char* arg) /** cache lookup of nameservers */ static void -do_lookup(SSL* ssl, struct worker* worker, char* arg) +do_lookup(RES* ssl, struct worker* worker, char* arg) { uint8_t* nm; int nmlabs; @@ -1515,7 +1481,7 @@ do_cache_remove(struct worker* worker, uint8_t* nm, size_t nmlen, /** flush a type */ static void -do_flush_type(SSL* ssl, struct worker* worker, char* arg) +do_flush_type(RES* ssl, struct worker* worker, char* arg) { uint8_t* nm; int nmlabs; @@ -1535,7 +1501,7 @@ do_flush_type(SSL* ssl, struct worker* worker, char* arg) /** flush statistics */ static void -do_flush_stats(SSL* ssl, struct worker* worker) +do_flush_stats(RES* ssl, struct worker* worker) { worker_stats_clear(worker); send_ok(ssl); @@ -1590,7 +1556,7 @@ infra_del_host(struct lruhash_entry* e, void* arg) /** flush infra cache */ static void -do_flush_infra(SSL* ssl, struct worker* worker, char* arg) +do_flush_infra(RES* ssl, struct worker* worker, char* arg) { struct sockaddr_storage addr; socklen_t len; @@ -1624,7 +1590,7 @@ do_flush_infra(SSL* ssl, struct worker* worker, char* arg) /** flush requestlist */ static void -do_flush_requestlist(SSL* ssl, struct worker* worker) +do_flush_requestlist(RES* ssl, struct worker* worker) { mesh_delete_all(worker->env.mesh); send_ok(ssl); @@ -1682,7 +1648,7 @@ zone_del_kcache(struct lruhash_entry* e, void* arg) /** remove all rrsets and keys from zone from cache */ static void -do_flush_zone(SSL* ssl, struct worker* worker, char* arg) +do_flush_zone(RES* ssl, struct worker* worker, char* arg) { uint8_t* nm; int nmlabs; @@ -1760,7 +1726,7 @@ bogus_del_kcache(struct lruhash_entry* e, void* arg) /** remove all bogus rrsets, msgs and keys from cache */ static void -do_flush_bogus(SSL* ssl, struct worker* worker) +do_flush_bogus(RES* ssl, struct worker* worker) { struct del_info inf; /* what we do is to set them all expired */ @@ -1835,7 +1801,7 @@ negative_del_kcache(struct lruhash_entry* e, void* arg) /** remove all negative(NODATA,NXDOMAIN), and servfail messages from cache */ static void -do_flush_negative(SSL* ssl, struct worker* worker) +do_flush_negative(RES* ssl, struct worker* worker) { struct del_info inf; /* what we do is to set them all expired */ @@ -1863,7 +1829,7 @@ do_flush_negative(SSL* ssl, struct worker* worker) /** remove name rrset from cache */ static void -do_flush_name(SSL* ssl, struct worker* w, char* arg) +do_flush_name(RES* ssl, struct worker* w, char* arg) { uint8_t* nm; int nmlabs; @@ -1887,7 +1853,7 @@ do_flush_name(SSL* ssl, struct worker* w, char* arg) /** printout a delegation point info */ static int -ssl_print_name_dp(SSL* ssl, const char* str, uint8_t* nm, uint16_t dclass, +ssl_print_name_dp(RES* ssl, const char* str, uint8_t* nm, uint16_t dclass, struct delegpt* dp) { char buf[257]; @@ -1921,7 +1887,7 @@ ssl_print_name_dp(SSL* ssl, const char* str, uint8_t* nm, uint16_t dclass, /** print root forwards */ static int -print_root_fwds(SSL* ssl, struct iter_forwards* fwds, uint8_t* root) +print_root_fwds(RES* ssl, struct iter_forwards* fwds, uint8_t* root) { struct delegpt* dp; dp = forwards_lookup(fwds, root, LDNS_RR_CLASS_IN); @@ -1934,7 +1900,7 @@ print_root_fwds(SSL* ssl, struct iter_forwards* fwds, uint8_t* root) /** parse args into delegpt */ static struct delegpt* -parse_delegpt(SSL* ssl, char* args, uint8_t* nm, int allow_names) +parse_delegpt(RES* ssl, char* args, uint8_t* nm, int allow_names) { /* parse args and add in */ char* p = args; @@ -1997,7 +1963,7 @@ parse_delegpt(SSL* ssl, char* args, uint8_t* nm, int allow_names) /** do the status command */ static void -do_forward(SSL* ssl, struct worker* worker, char* args) +do_forward(RES* ssl, struct worker* worker, char* args) { struct iter_forwards* fwd = worker->env.fwds; uint8_t* root = (uint8_t*)"\000"; @@ -2028,7 +1994,7 @@ do_forward(SSL* ssl, struct worker* worker, char* args) } static int -parse_fs_args(SSL* ssl, char* args, uint8_t** nm, struct delegpt** dp, +parse_fs_args(RES* ssl, char* args, uint8_t** nm, struct delegpt** dp, int* insecure, int* prime) { char* zonename; @@ -2073,7 +2039,7 @@ parse_fs_args(SSL* ssl, char* args, uint8_t** nm, struct delegpt** dp, /** do the forward_add command */ static void -do_forward_add(SSL* ssl, struct worker* worker, char* args) +do_forward_add(RES* ssl, struct worker* worker, char* args) { struct iter_forwards* fwd = worker->env.fwds; int insecure = 0; @@ -2101,7 +2067,7 @@ do_forward_add(SSL* ssl, struct worker* worker, char* args) /** do the forward_remove command */ static void -do_forward_remove(SSL* ssl, struct worker* worker, char* args) +do_forward_remove(RES* ssl, struct worker* worker, char* args) { struct iter_forwards* fwd = worker->env.fwds; int insecure = 0; @@ -2118,7 +2084,7 @@ do_forward_remove(SSL* ssl, struct worker* worker, char* args) /** do the stub_add command */ static void -do_stub_add(SSL* ssl, struct worker* worker, char* args) +do_stub_add(RES* ssl, struct worker* worker, char* args) { struct iter_forwards* fwd = worker->env.fwds; int insecure = 0, prime = 0; @@ -2159,7 +2125,7 @@ do_stub_add(SSL* ssl, struct worker* worker, char* args) /** do the stub_remove command */ static void -do_stub_remove(SSL* ssl, struct worker* worker, char* args) +do_stub_remove(RES* ssl, struct worker* worker, char* args) { struct iter_forwards* fwd = worker->env.fwds; int insecure = 0; @@ -2177,7 +2143,7 @@ do_stub_remove(SSL* ssl, struct worker* worker, char* args) /** do the insecure_add command */ static void -do_insecure_add(SSL* ssl, struct worker* worker, char* arg) +do_insecure_add(RES* ssl, struct worker* worker, char* arg) { size_t nmlen; int nmlabs; @@ -2198,7 +2164,7 @@ do_insecure_add(SSL* ssl, struct worker* worker, char* arg) /** do the insecure_remove command */ static void -do_insecure_remove(SSL* ssl, struct worker* worker, char* arg) +do_insecure_remove(RES* ssl, struct worker* worker, char* arg) { size_t nmlen; int nmlabs; @@ -2213,7 +2179,7 @@ do_insecure_remove(SSL* ssl, struct worker* worker, char* arg) } static void -do_insecure_list(SSL* ssl, struct worker* worker) +do_insecure_list(RES* ssl, struct worker* worker) { char buf[257]; struct trust_anchor* a; @@ -2229,7 +2195,7 @@ do_insecure_list(SSL* ssl, struct worker* worker) /** do the status command */ static void -do_status(SSL* ssl, struct worker* worker) +do_status(RES* ssl, struct worker* worker) { int i; time_t uptime; @@ -2250,9 +2216,12 @@ do_status(SSL* ssl, struct worker* worker) uptime = (time_t)time(NULL) - (time_t)worker->daemon->time_boot.tv_sec; if(!ssl_printf(ssl, "uptime: " ARG_LL "d seconds\n", (long long)uptime)) return; - if(!ssl_printf(ssl, "options:%s%s\n" , + if(!ssl_printf(ssl, "options:%s%s%s%s\n" , (worker->daemon->reuseport?" reuseport":""), - (worker->daemon->rc->accept_list?" control(ssl)":""))) + (worker->daemon->rc->accept_list?" control":""), + (worker->daemon->rc->accept_list && worker->daemon->rc->use_cert?"(ssl)":""), + (worker->daemon->rc->accept_list && worker->daemon->cfg->control_ifs.first && worker->daemon->cfg->control_ifs.first->str && worker->daemon->cfg->control_ifs.first->str[0] == '/'?"(namedpipe)":"") + )) return; if(!ssl_printf(ssl, "unbound (pid %d) is running...\n", (int)getpid())) @@ -2334,7 +2303,7 @@ get_mesh_status(struct mesh_area* mesh, struct mesh_state* m, /** do the dump_requestlist command */ static void -do_dump_requestlist(SSL* ssl, struct worker* worker) +do_dump_requestlist(RES* ssl, struct worker* worker) { struct mesh_area* mesh; struct mesh_state* m; @@ -2373,7 +2342,7 @@ struct infra_arg { /** the infra cache */ struct infra_cache* infra; /** the SSL connection */ - SSL* ssl; + RES* ssl; /** the time now */ time_t now; /** ssl failure? stop writing and skip the rest. If the tcp @@ -2428,7 +2397,7 @@ dump_infra_host(struct lruhash_entry* e, void* arg) /** do the dump_infra command */ static void -do_dump_infra(SSL* ssl, struct worker* worker) +do_dump_infra(RES* ssl, struct worker* worker) { struct infra_arg arg; arg.infra = worker->env.infra_cache; @@ -2440,7 +2409,7 @@ do_dump_infra(SSL* ssl, struct worker* worker) /** do the log_reopen command */ static void -do_log_reopen(SSL* ssl, struct worker* worker) +do_log_reopen(RES* ssl, struct worker* worker) { struct config_file* cfg = worker->env.cfg; send_ok(ssl); @@ -2449,7 +2418,7 @@ do_log_reopen(SSL* ssl, struct worker* worker) /** do the set_option command */ static void -do_set_option(SSL* ssl, struct worker* worker, char* arg) +do_set_option(RES* ssl, struct worker* worker, char* arg) { char* arg2; if(!find_arg2(ssl, arg, &arg2)) @@ -2472,13 +2441,13 @@ do_set_option(SSL* ssl, struct worker* worker, char* arg) /* routine to printout option values over SSL */ void remote_get_opt_ssl(char* line, void* arg) { - SSL* ssl = (SSL*)arg; + RES* ssl = (RES*)arg; (void)ssl_printf(ssl, "%s\n", line); } /** do the get_option command */ static void -do_get_option(SSL* ssl, struct worker* worker, char* arg) +do_get_option(RES* ssl, struct worker* worker, char* arg) { int r; r = config_get_option(worker->env.cfg, arg, remote_get_opt_ssl, ssl); @@ -2490,7 +2459,7 @@ do_get_option(SSL* ssl, struct worker* worker, char* arg) /** do the list_forwards command */ static void -do_list_forwards(SSL* ssl, struct worker* worker) +do_list_forwards(RES* ssl, struct worker* worker) { /* since its a per-worker structure no locks needed */ struct iter_forwards* fwds = worker->env.fwds; @@ -2518,7 +2487,7 @@ do_list_forwards(SSL* ssl, struct worker* worker) /** do the list_stubs command */ static void -do_list_stubs(SSL* ssl, struct worker* worker) +do_list_stubs(RES* ssl, struct worker* worker) { struct iter_hints_stub* z; struct trust_anchor* a; @@ -2546,7 +2515,7 @@ do_list_stubs(SSL* ssl, struct worker* worker) /** do the list_auth_zones command */ static void -do_list_auth_zones(SSL* ssl, struct auth_zones* az) +do_list_auth_zones(RES* ssl, struct auth_zones* az) { struct auth_zone* z; char buf[257], buf2[256]; @@ -2576,7 +2545,7 @@ do_list_auth_zones(SSL* ssl, struct auth_zones* az) /** do the list_local_zones command */ static void -do_list_local_zones(SSL* ssl, struct local_zones* zones) +do_list_local_zones(RES* ssl, struct local_zones* zones) { struct local_zone* z; char buf[257]; @@ -2598,7 +2567,7 @@ do_list_local_zones(SSL* ssl, struct local_zones* zones) /** do the list_local_data command */ static void -do_list_local_data(SSL* ssl, struct worker* worker, struct local_zones* zones) +do_list_local_data(RES* ssl, struct worker* worker, struct local_zones* zones) { struct local_zone* z; struct local_data* d; @@ -2637,7 +2606,7 @@ do_list_local_data(SSL* ssl, struct worker* worker, struct local_zones* zones) /** do the view_list_local_zones command */ static void -do_view_list_local_zones(SSL* ssl, struct worker* worker, char* arg) +do_view_list_local_zones(RES* ssl, struct worker* worker, char* arg) { struct view* v = views_find_view(worker->daemon->views, arg, 0 /* get read lock*/); @@ -2653,7 +2622,7 @@ do_view_list_local_zones(SSL* ssl, struct worker* worker, char* arg) /** do the view_list_local_data command */ static void -do_view_list_local_data(SSL* ssl, struct worker* worker, char* arg) +do_view_list_local_data(RES* ssl, struct worker* worker, char* arg) { struct view* v = views_find_view(worker->daemon->views, arg, 0 /* get read lock*/); @@ -2672,7 +2641,7 @@ struct ratelimit_list_arg { /** the infra cache */ struct infra_cache* infra; /** the SSL to print to */ - SSL* ssl; + RES* ssl; /** all or only ratelimited */ int all; /** current time */ @@ -2719,7 +2688,7 @@ ip_rate_list(struct lruhash_entry* e, void* arg) /** do the ratelimit_list command */ static void -do_ratelimit_list(SSL* ssl, struct worker* worker, char* arg) +do_ratelimit_list(RES* ssl, struct worker* worker, char* arg) { struct ratelimit_list_arg a; a.all = 0; @@ -2737,7 +2706,7 @@ do_ratelimit_list(SSL* ssl, struct worker* worker, char* arg) /** do the ip_ratelimit_list command */ static void -do_ip_ratelimit_list(SSL* ssl, struct worker* worker, char* arg) +do_ip_ratelimit_list(RES* ssl, struct worker* worker, char* arg) { struct ip_ratelimit_list_arg a; a.all = 0; @@ -2755,7 +2724,7 @@ do_ip_ratelimit_list(SSL* ssl, struct worker* worker, char* arg) /** tell other processes to execute the command */ static void -distribute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd) +distribute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd) { int i; if(!cmd || !ssl) @@ -2781,7 +2750,7 @@ cmdcmp(char* p, const char* cmd, size_t len) /** execute a remote control command */ static void -execute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd, +execute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd, struct worker* worker) { char* p = skipwhite(cmd); @@ -2965,7 +2934,7 @@ daemon_remote_exec(struct worker* worker) /** handle remote control request */ static void -handle_req(struct daemon_remote* rc, struct rc_state* s, SSL* ssl) +handle_req(struct daemon_remote* rc, struct rc_state* s, RES* res) { int r; char pre[10]; @@ -2979,12 +2948,31 @@ handle_req(struct daemon_remote* rc, struct rc_state* s, SSL* ssl) fd_set_block(s->c->fd); /* try to read magic UBCT[version]_space_ string */ - ERR_clear_error(); - if((r=SSL_read(ssl, magic, (int)sizeof(magic)-1)) <= 0) { - if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) + if(res->ssl) { + ERR_clear_error(); + if((r=SSL_read(res->ssl, magic, (int)sizeof(magic)-1)) <= 0) { + if(SSL_get_error(res->ssl, r) == SSL_ERROR_ZERO_RETURN) + return; + log_crypto_err("could not SSL_read"); return; - log_crypto_err("could not SSL_read"); - return; + } + } else { + while(1) { + ssize_t rr = recv(res->fd, magic, sizeof(magic)-1, 0); + if(rr <= 0) { + if(rr == 0) return; + if(errno == EINTR || errno == EAGAIN) + continue; +#ifndef USE_WINSOCK + log_err("could not recv: %s", strerror(errno)); +#else + log_err("could not recv: %s", wsa_strerror(WSAGetLastError())); +#endif + return; + } + r = (int)rr; + break; + } } magic[6] = 0; if( r != 6 || strncmp(magic, "UBCT", 4) != 0) { @@ -2994,25 +2982,58 @@ handle_req(struct daemon_remote* rc, struct rc_state* s, SSL* ssl) } /* read the command line */ - if(!ssl_read_line(ssl, buf, sizeof(buf))) { + if(!ssl_read_line(res, buf, sizeof(buf))) { return; } snprintf(pre, sizeof(pre), "UBCT%d ", UNBOUND_CONTROL_VERSION); if(strcmp(magic, pre) != 0) { verbose(VERB_QUERY, "control connection had bad " "version %s, cmd: %s", magic, buf); - ssl_printf(ssl, "error version mismatch\n"); + ssl_printf(res, "error version mismatch\n"); return; } verbose(VERB_DETAIL, "control cmd: %s", buf); /* figure out what to do */ - execute_cmd(rc, ssl, buf, rc->worker); + execute_cmd(rc, res, buf, rc->worker); +} + +/** handle SSL_do_handshake changes to the file descriptor to wait for later */ +static int +remote_handshake_later(struct daemon_remote* rc, struct rc_state* s, + struct comm_point* c, int r, int r2) +{ + if(r2 == SSL_ERROR_WANT_READ) { + if(s->shake_state == rc_hs_read) { + /* try again later */ + return 0; + } + s->shake_state = rc_hs_read; + comm_point_listen_for_rw(c, 1, 0); + return 0; + } else if(r2 == SSL_ERROR_WANT_WRITE) { + if(s->shake_state == rc_hs_write) { + /* try again later */ + return 0; + } + s->shake_state = rc_hs_write; + comm_point_listen_for_rw(c, 0, 1); + return 0; + } else { + if(r == 0) + log_err("remote control connection closed prematurely"); + log_addr(1, "failed connection from", + &s->c->repinfo.addr, s->c->repinfo.addrlen); + log_crypto_err("remote control failed ssl"); + clean_point(rc, s); + } + return 0; } int remote_control_callback(struct comm_point* c, void* arg, int err, struct comm_reply* ATTR_UNUSED(rep)) { + RES res; struct rc_state* s = (struct rc_state*)arg; struct daemon_remote* rc = s->rc; int r; @@ -3022,38 +3043,16 @@ int remote_control_callback(struct comm_point* c, void* arg, int err, clean_point(rc, s); return 0; } - /* (continue to) setup the SSL connection */ - ERR_clear_error(); - r = SSL_do_handshake(s->ssl); - if(r != 1) { - int r2 = SSL_get_error(s->ssl, r); - if(r2 == SSL_ERROR_WANT_READ) { - if(s->shake_state == rc_hs_read) { - /* try again later */ - return 0; - } - s->shake_state = rc_hs_read; - comm_point_listen_for_rw(c, 1, 0); - return 0; - } else if(r2 == SSL_ERROR_WANT_WRITE) { - if(s->shake_state == rc_hs_write) { - /* try again later */ - return 0; - } - s->shake_state = rc_hs_write; - comm_point_listen_for_rw(c, 0, 1); - return 0; - } else { - if(r == 0) - log_err("remote control connection closed prematurely"); - log_addr(1, "failed connection from", - &s->c->repinfo.addr, s->c->repinfo.addrlen); - log_crypto_err("remote control failed ssl"); - clean_point(rc, s); - return 0; + if(s->ssl) { + /* (continue to) setup the SSL connection */ + ERR_clear_error(); + r = SSL_do_handshake(s->ssl); + if(r != 1) { + int r2 = SSL_get_error(s->ssl, r); + return remote_handshake_later(rc, s, c, r, r2); } + s->shake_state = rc_none; } - s->shake_state = rc_none; /* once handshake has completed, check authentication */ if (!rc->use_cert) { @@ -3076,7 +3075,9 @@ int remote_control_callback(struct comm_point* c, void* arg, int err, } /* if OK start to actually handle the request */ - handle_req(rc, s, s->ssl); + res.ssl = s->ssl; + res.fd = c->fd; + handle_req(rc, s, &res); verbose(VERB_ALGO, "remote control operation completed"); clean_point(rc, s); diff --git a/daemon/remote.h b/daemon/remote.h index 190286d474a4..217ea21e80c1 100644 --- a/daemon/remote.h +++ b/daemon/remote.h @@ -73,6 +73,8 @@ struct rc_state { /** the ssl state */ SSL* ssl; #endif + /** file descriptor */ + int fd; /** the rc this is part of */ struct daemon_remote* rc; }; @@ -104,6 +106,19 @@ struct daemon_remote { }; /** + * Connection to print to, either SSL or plain over fd + */ +struct remote_stream { +#ifdef HAVE_SSL + /** SSL structure, nonNULL if using SSL */ + SSL* ssl; +#endif + /** file descriptor for plain transfer */ + int fd; +}; +typedef struct remote_stream RES; + +/** * Create new remote control state for the daemon. * @param cfg: config file with key file settings. * @return new state, or NULL on failure. @@ -166,26 +181,26 @@ void daemon_remote_exec(struct worker* worker); * @param text: the text. * @return false on connection failure. */ -int ssl_print_text(SSL* ssl, const char* text); +int ssl_print_text(RES* ssl, const char* text); /** * printf style printing to the ssl connection - * @param ssl: the SSL connection to print to. Blocking. + * @param ssl: the RES connection to print to. Blocking. * @param format: printf style format string. * @return success or false on a network failure. */ -int ssl_printf(SSL* ssl, const char* format, ...) +int ssl_printf(RES* ssl, const char* format, ...) ATTR_FORMAT(printf, 2, 3); /** * Read until \n is encountered - * If SSL signals EOF, the string up to then is returned (without \n). - * @param ssl: the SSL connection to read from. blocking. + * If stream signals EOF, the string up to then is returned (without \n). + * @param ssl: the RES connection to read from. blocking. * @param buf: buffer to read to. * @param max: size of buffer. * @return false on connection failure. */ -int ssl_read_line(SSL* ssl, char* buf, size_t max); +int ssl_read_line(RES* ssl, char* buf, size_t max); #endif /* HAVE_SSL */ #endif /* DAEMON_REMOTE_H */ |
