diff options
author | Riccardo Spagni <ric@spagni.net> | 2015-05-31 16:36:48 +0200 |
---|---|---|
committer | Riccardo Spagni <ric@spagni.net> | 2015-05-31 16:36:48 +0200 |
commit | 6a1190792b0409e7a996400614e5e2c6ba02e5f6 (patch) | |
tree | fa324d2f9f02668a6d56d2e4d195a59ab1d3710e /external/unbound/daemon | |
parent | fixed static assert test (diff) | |
download | monero-6a1190792b0409e7a996400614e5e2c6ba02e5f6.tar.xz |
update libunbound
Diffstat (limited to 'external/unbound/daemon')
-rw-r--r-- | external/unbound/daemon/remote.c | 126 | ||||
-rw-r--r-- | external/unbound/daemon/worker.c | 38 | ||||
-rw-r--r-- | external/unbound/daemon/worker.h | 4 |
3 files changed, 139 insertions, 29 deletions
diff --git a/external/unbound/daemon/remote.c b/external/unbound/daemon/remote.c index 24008bf17..93d0eda28 100644 --- a/external/unbound/daemon/remote.c +++ b/external/unbound/daemon/remote.c @@ -140,34 +140,45 @@ timeval_divide(struct timeval* avg, const struct timeval* sum, size_t d) /* * The following function was generated using the openssl utility, using - * the command : "openssl dhparam -dsaparam -C 512" + * the command : "openssl dhparam -dsaparam -C 1024" + * (some openssl versions reject DH that is 'too small', eg. 512). */ #ifndef S_SPLINT_S -DH *get_dh512() -{ - static unsigned char dh512_p[]={ - 0xC9,0xD7,0x05,0xDA,0x5F,0xAB,0x14,0xE8,0x11,0x56,0x77,0x85, - 0xB1,0x24,0x2C,0x95,0x60,0xEA,0xE2,0x10,0x6F,0x0F,0x84,0xEC, - 0xF4,0x45,0xE8,0x90,0x7A,0xA7,0x03,0xFF,0x5B,0x88,0x53,0xDE, - 0xC4,0xDE,0xBC,0x42,0x78,0x71,0x23,0x7E,0x24,0xA5,0x5E,0x4E, - 0xEF,0x6F,0xFF,0x5F,0xAF,0xBE,0x8A,0x77,0x62,0xB4,0x65,0x82, - 0x7E,0xC9,0xED,0x2F, - }; - static unsigned char dh512_g[]={ - 0x8D,0x3A,0x52,0xBC,0x8A,0x71,0x94,0x33,0x2F,0xE1,0xE8,0x4C, - 0x73,0x47,0x03,0x4E,0x7D,0x40,0xE5,0x84,0xA0,0xB5,0x6D,0x10, - 0x6F,0x90,0x43,0x05,0x1A,0xF9,0x0B,0x6A,0xD1,0x2A,0x9C,0x25, - 0x0A,0xB9,0xD1,0x14,0xDC,0x35,0x1C,0x48,0x7C,0xC6,0x0C,0x6D, - 0x32,0x1D,0xD3,0xC8,0x10,0xA8,0x82,0x14,0xA2,0x1C,0xF4,0x53, - 0x23,0x3B,0x1C,0xB9, - }; +DH *get_dh1024() +{ + static unsigned char dh1024_p[]={ + 0xB3,0x67,0x2E,0x3B,0x68,0xC5,0xDA,0x58,0x46,0xD6,0x2B,0xD3, + 0x41,0x78,0x97,0xE4,0xE1,0x61,0x71,0x68,0xE6,0x0F,0x1D,0x78, + 0x05,0xAA,0xF0,0xFF,0x30,0xDF,0xAC,0x49,0x7F,0xE0,0x90,0xFE, + 0xB9,0x56,0x4E,0x3F,0xE2,0x98,0x8A,0xED,0xF5,0x28,0x39,0xEF, + 0x2E,0xA6,0xB7,0x67,0xB2,0x43,0xE4,0x53,0xF8,0xEB,0x2C,0x1F, + 0x06,0x77,0x3A,0x6F,0x62,0x98,0xC1,0x3B,0xF7,0xBA,0x4D,0x93, + 0xF7,0xEB,0x5A,0xAD,0xC5,0x5F,0xF0,0xB7,0x24,0x35,0x81,0xF7, + 0x7F,0x1F,0x24,0xC0,0xDF,0xD3,0xD8,0x40,0x72,0x7E,0xF3,0x19, + 0x2B,0x26,0x27,0xF4,0xB6,0xB3,0xD4,0x7D,0x08,0x23,0xBE,0x68, + 0x2B,0xCA,0xB4,0x46,0xA8,0x9E,0xDD,0x6C,0x3D,0x75,0xA6,0x48, + 0xF7,0x44,0x43,0xBF,0x91,0xC2,0xB4,0x49, + }; + static unsigned char dh1024_g[]={ + 0x5F,0x37,0xB5,0x80,0x4D,0xB4,0xC4,0xB2,0x37,0x12,0xD5,0x2F, + 0x56,0x81,0xB0,0xDF,0x3D,0x27,0xA2,0x54,0xE7,0x14,0x65,0x2D, + 0x72,0xA8,0x97,0xE0,0xA9,0x4A,0x09,0x5E,0x89,0xBE,0x34,0x9A, + 0x90,0x98,0xC1,0xE8,0xBB,0x01,0x2B,0xC2,0x74,0x74,0x90,0x59, + 0x0B,0x72,0x62,0x5C,0xFD,0x49,0x63,0x4B,0x38,0x91,0xF1,0x7F, + 0x13,0x25,0xEB,0x52,0x50,0x47,0xA2,0x8C,0x32,0x28,0x42,0xAC, + 0xBD,0x7A,0xCC,0x58,0xBE,0x36,0xDA,0x6A,0x24,0x06,0xC7,0xF1, + 0xDA,0x8D,0x8A,0x3B,0x03,0xFA,0x6F,0x25,0xE5,0x20,0xA7,0xD6, + 0x6F,0x74,0x61,0x53,0x14,0x81,0x29,0x04,0xB5,0x61,0x12,0x53, + 0xA3,0xD6,0x09,0x98,0x0C,0x8F,0x1C,0xBB,0xD7,0x1C,0x2C,0xEE, + 0x56,0x4B,0x74,0x8F,0x4A,0xF8,0xA9,0xD5, + }; DH *dh; if ((dh=DH_new()) == NULL) return(NULL); - dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL); - dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL); + dh->p=BN_bin2bn(dh1024_p,sizeof(dh1024_p),NULL); + dh->g=BN_bin2bn(dh1024_g,sizeof(dh1024_g),NULL); if ((dh->p == NULL) || (dh->g == NULL)) - { DH_free(dh); return(NULL); } + { DH_free(dh); return(NULL); } dh->length = 160; return(dh); } @@ -218,7 +229,7 @@ daemon_remote_create(struct config_file* cfg) /* 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_dh512())) { + if(!SSL_CTX_set_tmp_dh(rc->ctx,get_dh1024())) { log_crypto_err("Wanted to set DH param, but failed"); return NULL; } @@ -1892,6 +1903,21 @@ do_insecure_remove(SSL* ssl, struct worker* worker, char* arg) send_ok(ssl); } +static void +do_insecure_list(SSL* ssl, struct worker* worker) +{ + char buf[257]; + struct trust_anchor* a; + if(worker->env.anchors) { + RBTREE_FOR(a, struct trust_anchor*, worker->env.anchors->tree) { + if(a->numDS == 0 && a->numDNSKEY == 0) { + dname_str(a->name, buf); + ssl_printf(ssl, "%s\n", buf); + } + } + } +} + /** do the status command */ static void do_status(SSL* ssl, struct worker* worker) @@ -2252,6 +2278,54 @@ do_list_local_data(SSL* ssl, struct worker* worker) lock_rw_unlock(&zones->lock); } +/** struct for user arg ratelimit list */ +struct ratelimit_list_arg { + /** the infra cache */ + struct infra_cache* infra; + /** the SSL to print to */ + SSL* ssl; + /** all or only ratelimited */ + int all; + /** current time */ + time_t now; +}; + +/** list items in the ratelimit table */ +static void +rate_list(struct lruhash_entry* e, void* arg) +{ + struct ratelimit_list_arg* a = (struct ratelimit_list_arg*)arg; + struct rate_key* k = (struct rate_key*)e->key; + struct rate_data* d = (struct rate_data*)e->data; + char buf[257]; + int lim = infra_find_ratelimit(a->infra, k->name, k->namelen); + int max = infra_rate_max(d, a->now); + if(a->all == 0) { + if(max < lim) + return; + } + dname_str(k->name, buf); + ssl_printf(a->ssl, "%s %d limit %d\n", buf, max, lim); +} + +/** do the ratelimit_list command */ +static void +do_ratelimit_list(SSL* ssl, struct worker* worker, char* arg) +{ + struct ratelimit_list_arg a; + a.all = 0; + a.infra = worker->env.infra_cache; + a.now = *worker->env.now; + a.ssl = ssl; + arg = skipwhite(arg); + if(strcmp(arg, "+a") == 0) + a.all = 1; + if(a.infra->domain_rates==NULL || + (a.all == 0 && infra_dp_ratelimit == 0)) + return; + slabhash_traverse(a.infra->domain_rates, 0, rate_list, &a); +} + /** tell other processes to execute the command */ static void distribute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd) @@ -2312,12 +2386,18 @@ execute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd, } else if(cmdcmp(p, "list_stubs", 10)) { do_list_stubs(ssl, worker); return; + } else if(cmdcmp(p, "list_insecure", 13)) { + do_insecure_list(ssl, worker); + return; } else if(cmdcmp(p, "list_local_zones", 16)) { do_list_local_zones(ssl, worker); return; } else if(cmdcmp(p, "list_local_data", 15)) { do_list_local_data(ssl, worker); return; + } else if(cmdcmp(p, "ratelimit_list", 14)) { + do_ratelimit_list(ssl, worker, p+14); + return; } else if(cmdcmp(p, "stub_add", 8)) { /* must always distribute this cmd */ if(rc) distribute_cmd(rc, ssl, cmd); diff --git a/external/unbound/daemon/worker.c b/external/unbound/daemon/worker.c index 93481354f..f4e87289a 100644 --- a/external/unbound/daemon/worker.c +++ b/external/unbound/daemon/worker.c @@ -86,6 +86,8 @@ /** Size of an UDP datagram */ #define NORMAL_UDP_SIZE 512 /* bytes */ +/** ratelimit for error responses */ +#define ERROR_RATELIMIT 100 /* qps */ /** * seconds to add to prefetch leeway. This is a TTL that expires old rrsets @@ -291,6 +293,26 @@ worker_handle_service_reply(struct comm_point* c, void* arg, int error, return 0; } +/** ratelimit error replies + * @param worker: the worker struct with ratelimit counter + * @param err: error code that would be wanted. + * @return value of err if okay, or -1 if it should be discarded instead. + */ +static int +worker_err_ratelimit(struct worker* worker, int err) +{ + if(worker->err_limit_time == *worker->env.now) { + /* see if limit is exceeded for this second */ + if(worker->err_limit_count++ > ERROR_RATELIMIT) + return -1; + } else { + /* new second, new limits */ + worker->err_limit_time = *worker->env.now; + worker->err_limit_count = 1; + } + return err; +} + /** check request sanity. * @param pkt: the wire packet to examine for sanity. * @param worker: parameters for checking. @@ -315,32 +337,32 @@ worker_check_request(sldns_buffer* pkt, struct worker* worker) if(LDNS_TC_WIRE(sldns_buffer_begin(pkt))) { LDNS_TC_CLR(sldns_buffer_begin(pkt)); verbose(VERB_QUERY, "request bad, has TC bit on"); - return LDNS_RCODE_FORMERR; + return worker_err_ratelimit(worker, LDNS_RCODE_FORMERR); } if(LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)) != LDNS_PACKET_QUERY) { verbose(VERB_QUERY, "request unknown opcode %d", LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt))); - return LDNS_RCODE_NOTIMPL; + return worker_err_ratelimit(worker, LDNS_RCODE_NOTIMPL); } if(LDNS_QDCOUNT(sldns_buffer_begin(pkt)) != 1) { verbose(VERB_QUERY, "request wrong nr qd=%d", LDNS_QDCOUNT(sldns_buffer_begin(pkt))); - return LDNS_RCODE_FORMERR; + return worker_err_ratelimit(worker, LDNS_RCODE_FORMERR); } if(LDNS_ANCOUNT(sldns_buffer_begin(pkt)) != 0) { verbose(VERB_QUERY, "request wrong nr an=%d", LDNS_ANCOUNT(sldns_buffer_begin(pkt))); - return LDNS_RCODE_FORMERR; + return worker_err_ratelimit(worker, LDNS_RCODE_FORMERR); } if(LDNS_NSCOUNT(sldns_buffer_begin(pkt)) != 0) { verbose(VERB_QUERY, "request wrong nr ns=%d", LDNS_NSCOUNT(sldns_buffer_begin(pkt))); - return LDNS_RCODE_FORMERR; + return worker_err_ratelimit(worker, LDNS_RCODE_FORMERR); } if(LDNS_ARCOUNT(sldns_buffer_begin(pkt)) > 1) { verbose(VERB_QUERY, "request wrong nr ar=%d", LDNS_ARCOUNT(sldns_buffer_begin(pkt))); - return LDNS_RCODE_FORMERR; + return worker_err_ratelimit(worker, LDNS_RCODE_FORMERR); } return 0; } @@ -813,6 +835,10 @@ worker_handle_request(struct comm_point* c, void* arg, int error, if(!query_info_parse(&qinfo, c->buffer)) { verbose(VERB_ALGO, "worker parse request: formerror."); log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen); + if(worker_err_ratelimit(worker, LDNS_RCODE_FORMERR) == -1) { + comm_point_drop_reply(repinfo); + return 0; + } sldns_buffer_rewind(c->buffer); LDNS_QR_SET(sldns_buffer_begin(c->buffer)); LDNS_RCODE_SET(sldns_buffer_begin(c->buffer), diff --git a/external/unbound/daemon/worker.h b/external/unbound/daemon/worker.h index ff69bc1ac..63613430b 100644 --- a/external/unbound/daemon/worker.h +++ b/external/unbound/daemon/worker.h @@ -103,6 +103,10 @@ struct worker { struct comm_point* cmd_com; /** timer for statistics */ struct comm_timer* stat_timer; + /** ratelimit for errors, time value */ + time_t err_limit_time; + /** ratelimit for errors, packet count */ + unsigned int err_limit_count; /** random() table for this worker. */ struct ub_randstate* rndstate; |