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);

