diff -ruN unbound-1.3.3-orig/daemon/remote.c unbound-1.3.3-notify/daemon/remote.c --- unbound-1.3.3-orig/daemon/remote.c 2009-07-06 06:34:47.000000000 -0300 +++ unbound-1.3.3-notify/daemon/remote.c 2009-10-05 13:52:12.449816453 -0300 @@ -1161,7 +1161,7 @@ } /** remove all rrsets and keys from zone from cache */ -static void +void do_flush_zone(SSL* ssl, struct worker* worker, char* arg) { uint8_t* nm; diff -ruN unbound-1.3.3-orig/daemon/remote.h unbound-1.3.3-notify/daemon/remote.h --- unbound-1.3.3-orig/daemon/remote.h 2009-06-11 06:43:23.000000000 -0300 +++ unbound-1.3.3-notify/daemon/remote.h 2009-10-05 13:52:12.449816453 -0300 @@ -171,4 +171,7 @@ */ int ssl_read_line(SSL* ssl, char* buf, size_t max); +/** remove all rrsets and keys from zone from cache */ +void do_flush_zone(SSL* ssl, struct worker* worker, char* arg); + #endif /* DAEMON_REMOTE_H */ diff -ruN unbound-1.3.3-orig/daemon/worker.c unbound-1.3.3-notify/daemon/worker.c --- unbound-1.3.3-orig/daemon/worker.c 2009-06-16 09:03:41.000000000 -0300 +++ unbound-1.3.3-notify/daemon/worker.c 2009-10-04 23:42:07.827833891 -0300 @@ -294,7 +294,8 @@ verbose(VERB_QUERY, "request bad, has TC bit on"); return LDNS_RCODE_FORMERR; } - if(LDNS_OPCODE_WIRE(ldns_buffer_begin(pkt)) != LDNS_PACKET_QUERY) { + if((LDNS_OPCODE_WIRE(ldns_buffer_begin(pkt)) != LDNS_PACKET_QUERY) && + (LDNS_OPCODE_WIRE(ldns_buffer_begin(pkt)) != LDNS_PACKET_NOTIFY)) { verbose(VERB_QUERY, "request unknown opcode %d", LDNS_OPCODE_WIRE(ldns_buffer_begin(pkt))); return LDNS_RCODE_NOTIMPL; @@ -688,6 +689,7 @@ struct query_info qinfo; struct edns_data edns; enum acl_access acl; + char buf[257]; if(error != NETEVENT_NOERROR) { /* some bad tcp query DNS formats give these error calls */ @@ -726,7 +728,6 @@ comm_point_drop_reply(repinfo); return 0; } - worker->stats.num_queries++; /* see if query is in the cache */ if(!query_info_parse(&qinfo, c->buffer)) { verbose(VERB_ALGO, "worker parse request: formerror."); @@ -738,6 +739,17 @@ server_stats_insrcode(&worker->stats, c->buffer); return 1; } + if(LDNS_OPCODE_WIRE(ldns_buffer_begin(c->buffer)) == LDNS_PACKET_NOTIFY) { + verbose(VERB_ALGO, "received notify."); + log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen); + dname_str(qinfo.qname, buf); + do_flush_zone(NULL, worker, buf); + LDNS_QR_SET(ldns_buffer_begin(c->buffer)); + ldns_buffer_rewind(c->buffer); + comm_point_send_reply(repinfo); + return 0; + } + worker->stats.num_queries++; if(qinfo.qtype == LDNS_RR_TYPE_AXFR || qinfo.qtype == LDNS_RR_TYPE_IXFR) { verbose(VERB_ALGO, "worker request: refused zone transfer."); diff -ruN unbound-1.3.3-orig/util/data/msgreply.c unbound-1.3.3-notify/util/data/msgreply.c --- unbound-1.3.3-orig/util/data/msgreply.c 2009-06-16 09:03:41.000000000 -0300 +++ unbound-1.3.3-notify/util/data/msgreply.c 2009-10-04 12:48:04.277814668 -0300 @@ -498,7 +498,8 @@ /* minimum size: header + \0 + qtype + qclass */ if(ldns_buffer_limit(query) < LDNS_HEADER_SIZE + 5) return 0; - if(LDNS_OPCODE_WIRE(q) != LDNS_PACKET_QUERY || + if((LDNS_OPCODE_WIRE(q) != LDNS_PACKET_QUERY && + LDNS_OPCODE_WIRE(q) != LDNS_PACKET_NOTIFY) || LDNS_QDCOUNT(q) != 1 || ldns_buffer_position(query) != 0) return 0; ldns_buffer_skip(query, LDNS_HEADER_SIZE);