diff --git a/include/asterisk/dundi.h b/include/asterisk/dundi.h
index 0dc548c69d7b20246113c35365d44d8b10a6c830..8bd22ddc46fb6e189357a877fdc7ccba3225f9f7 100755
--- a/include/asterisk/dundi.h
+++ b/include/asterisk/dundi.h
@@ -141,6 +141,7 @@ struct dundi_cause {
 #define DUNDI_IE_EMAIL				26	/* E-mail addy, for EIDQUERY (string) */
 #define DUNDI_IE_PHONE				27	/* Contact Phone, for EIDQUERY (string) */
 #define DUNDI_IE_IPADDR				28	/* IP Address, for EIDQUERY (string) */
+#define DUNDI_IE_CACHEBYPASS		29	/* Bypass cache (empty) */
 
 #define DUNDI_FLUFF_TIME			2000	/* Amount of time for answer */
 #define DUNDI_TTL_TIME				200		/* Incremental average time */
@@ -180,7 +181,7 @@ struct dundi_entity_info {
 
 /* Lookup the given number in the given dundi context (or e164 if unspecified) using the given callerid (if specified) and return up to maxret results in the array specified.
    returns the number of results found or -1 on a hangup of teh channel. */
-int dundi_lookup(struct dundi_result *result, int maxret, struct ast_channel *chan, const char *dcontext, const char *number);
+int dundi_lookup(struct dundi_result *result, int maxret, struct ast_channel *chan, const char *dcontext, const char *number, int nocache);
 
 /* Retrieve information on a specific EID */
 int dundi_query_eid(struct dundi_entity_info *dei, const char *dcontext, dundi_eid eid);
diff --git a/pbx/dundi-parser.c b/pbx/dundi-parser.c
index 99c74f88df608eeb2de10ed377d72c23796893fa..f9f96bcdbe3824e4a9a0a8ef6b93db770a2e9b1b 100755
--- a/pbx/dundi-parser.c
+++ b/pbx/dundi-parser.c
@@ -115,6 +115,12 @@ static void dump_string(char *output, int maxlen, void *value, int len)
 	output[maxlen] = '\0';
 }
 
+static void dump_cbypass(char *output, int maxlen, void *value, int len)
+{
+	strncpy(output, "Bypass Caches", maxlen);
+	output[maxlen] = '\0';
+}
+
 static void dump_eid(char *output, int maxlen, void *value, int len)
 {
 	if (len == 6)
@@ -358,6 +364,7 @@ static struct dundi_ie {
 	{ DUNDI_IE_EMAIL, "EMAIL", dump_string },
 	{ DUNDI_IE_PHONE, "PHONE", dump_string },
 	{ DUNDI_IE_IPADDR, "ADDRESS", dump_string },
+	{ DUNDI_IE_CACHEBYPASS, "CBYPASS", dump_cbypass },
 };
 
 const char *dundi_ie2str(int ie)
@@ -380,7 +387,7 @@ static void dump_ies(unsigned char *iedata, int spaces, int len)
 	char tmp[1024];
 	if (len < 2)
 		return;
-	while(len > 2) {
+	while(len >= 2) {
 		ie = iedata[0];
 		ielen = iedata[1];
 		/* Encrypted data is the remainder */
@@ -441,7 +448,8 @@ void dundi_showframe(struct dundi_hdr *fhi, int rx, struct sockaddr_in *sin, int
 		"REGRESPONSE ",
 		"CANCEL      ",
 		"ENCRYPT     ",
-		"ENCREJ      " };
+		"ENCREJ      ",
+		"PRECACHE    " };
 	char class2[20];
 	char *class;
 	char subclass2[20];
@@ -784,6 +792,9 @@ int dundi_parse_ies(struct dundi_ies *ies, unsigned char *data, int datalen)
 				errorf(tmp);
 			}
 			break;
+		case DUNDI_IE_CACHEBYPASS:
+			ies->cbypass = 1;
+			break;
 		default:
 			snprintf(tmp, (int)sizeof(tmp), "Ignoring unknown information element '%s' (%d) of length %d\n", dundi_ie2str(ie), ie, len);
 			outputf(tmp);
diff --git a/pbx/dundi-parser.h b/pbx/dundi-parser.h
index c50dd1ed5c0f2dec3828132122b09fb16eee6a0f..0035c18cd3da467c4cac77786658544c7ce05e59 100755
--- a/pbx/dundi-parser.h
+++ b/pbx/dundi-parser.h
@@ -48,6 +48,7 @@ struct dundi_ies {
 	unsigned long keycrc32;
 	struct dundi_encblock *encblock;
 	int enclen;
+	int cbypass;
 };
 
 struct dundi_ie_data {
diff --git a/pbx/pbx_dundi.c b/pbx/pbx_dundi.c
index d60799987bb50424cc3ed3b1937b2cd645428c6c..43f673dc562afd741fc30938d0b3d5089866a802 100755
--- a/pbx/pbx_dundi.c
+++ b/pbx/pbx_dundi.c
@@ -186,6 +186,7 @@ struct dundi_request {
 	int maxcount;
 	int respcount;
 	int expiration;
+	int cbypass;
 	int pfds[2];
 	unsigned long crc32;							/* CRC-32 of all but root EID's in avoid list */
 	struct dundi_transaction *trans;	/* Transactions */
@@ -295,7 +296,7 @@ static int str2tech(char *str)
 		return -1;
 }
 
-static int dundi_lookup_internal(struct dundi_result *result, int maxret, struct ast_channel *chan, const char *dcontext, const char *number, int ttl, int blockempty, struct dundi_hint_metadata *md, int *expiration, dundi_eid *avoid[], int direct[]);
+static int dundi_lookup_internal(struct dundi_result *result, int maxret, struct ast_channel *chan, const char *dcontext, const char *number, int ttl, int blockempty, struct dundi_hint_metadata *md, int *expiration, int cybpass, dundi_eid *avoid[], int direct[]);
 static struct dundi_transaction *create_transaction(struct dundi_peer *p);
 static struct dundi_transaction *find_transaction(struct dundi_hdr *hdr, struct sockaddr_in *sin)
 {
@@ -479,6 +480,7 @@ struct dundi_query_state {
 	char called_number[AST_MAX_EXTENSION];
 	struct dundi_mapping *maps;
 	int nummaps;
+	int nocache;
 	struct dundi_transaction *trans;
 	void *chal;
 	int challen;
@@ -593,7 +595,7 @@ static void *dundi_lookup_thread(void *data)
 		
 	if (max) {
 		/* If we do not have a canonical result, keep looking */
-		res = dundi_lookup_internal(dr + ouranswers, MAX_RESULTS - ouranswers, NULL, st->called_context, st->called_number, st->ttl, 1, &hmd, &expiration, st->eids, st->directs);
+		res = dundi_lookup_internal(dr + ouranswers, MAX_RESULTS - ouranswers, NULL, st->called_context, st->called_number, st->ttl, 1, &hmd, &expiration, st->nocache, st->eids, st->directs);
 		if (res > 0) {
 			/* Append answer in result */
 			ouranswers += res;
@@ -793,6 +795,7 @@ static int dundi_answer_query(struct dundi_transaction *trans, struct dundi_ies
 		strncpy(st->called_number, ies->called_number, sizeof(st->called_number) - 1);
 		st->trans = trans;
 		st->ttl = ies->ttl - 1;
+		st->nocache = ies->cbypass;
 		if (st->ttl < 0)
 			st->ttl = 0;
 		s = st->fluffy;
@@ -2062,10 +2065,17 @@ static int dundi_do_lookup(int fd, int argc, char *argv[])
 	char fs[80] = "";
 	char *context;
 	int x;
+	int bypass = 0;
 	struct dundi_result dr[MAX_RESULTS];
 	struct timeval start;
-	if ((argc < 3) || (argc > 3))
+	if ((argc < 3) || (argc > 4))
 		return RESULT_SHOWUSAGE;
+	if (argc > 3) {
+		if (!strcasecmp(argv[3], "bypass"))
+			bypass=1;
+		else
+			return RESULT_SHOWUSAGE;
+	}
 	strncpy(tmp, argv[2], sizeof(tmp) - 1);
 	context = strchr(tmp, '@');
 	if (context) {
@@ -2073,7 +2083,7 @@ static int dundi_do_lookup(int fd, int argc, char *argv[])
 		context++;
 	}
 	gettimeofday(&start, NULL);
-	res = dundi_lookup(dr, MAX_RESULTS, NULL, context, tmp);
+	res = dundi_lookup(dr, MAX_RESULTS, NULL, context, tmp, bypass);
 	
 	if (res < 0) 
 		ast_cli(fd, "DUNDi lookup returned error.\n");
@@ -2388,10 +2398,10 @@ static char show_requests_usage[] =
 "       Lists all known pending DUNDi requests.\n";
 
 static char lookup_usage[] =
-"Usage: dundi lookup <number>[@context]\n"
+"Usage: dundi lookup <number>[@context] [bypass]\n"
 "       Lookup the given number within the given DUNDi context\n"
-"(or e164 if none is specified).\n"
-"if specified.\n";
+"(or e164 if none is specified).  Bypasses cache if 'bypass'\n"
+"keyword is specified.\n";
 
 static char query_usage[] =
 "Usage: dundi query <entity>[@context]\n"
@@ -2561,7 +2571,7 @@ static void destroy_trans(struct dundi_transaction *trans, int fromtimeout)
 				peer->qualtrans = NULL;
 			}
 			if (trans->flags & FLAG_STOREHIST) {
-				if (trans->parent) {
+				if (trans->parent && !ast_strlen_zero(trans->parent->number)) {
 					if (!dundi_eid_cmp(&trans->them_eid, &peer->eid)) {
 						peer->avgms = 0;
 						cnt = 0;
@@ -2787,6 +2797,8 @@ static int dundi_discover(struct dundi_transaction *trans)
 	dundi_ie_append_str(&ied, DUNDI_IE_CALLED_NUMBER, trans->parent->number);
 	dundi_ie_append_str(&ied, DUNDI_IE_CALLED_CONTEXT, trans->parent->dcontext);
 	dundi_ie_append_short(&ied, DUNDI_IE_TTL, trans->ttl);
+	if (trans->parent->cbypass)
+		dundi_ie_append(&ied, DUNDI_IE_CACHEBYPASS);
 	if (trans->autokilltimeout)
 		trans->autokillid = ast_sched_add(sched, trans->autokilltimeout, do_autokill, trans);
 	return dundi_send(trans, DUNDI_COMMAND_DPDISCOVER, 0, 0, &ied);
@@ -2953,7 +2965,7 @@ static void abort_request(struct dundi_request *dr)
 	ast_mutex_unlock(&peerlock);
 }
 
-static void build_transactions(struct dundi_request *dr, int ttl, int order, int *foundcache, int *skipped, int blockempty, dundi_eid *avoid[], int directs[])
+static void build_transactions(struct dundi_request *dr, int ttl, int order, int *foundcache, int *skipped, int blockempty, int nocache, dundi_eid *avoid[], int directs[])
 {
 	struct dundi_peer *p;
 	int x;
@@ -2967,7 +2979,8 @@ static void build_transactions(struct dundi_request *dr, int ttl, int order, int
 				/* Check order first, then check cache, regardless of
 				   omissions, this gets us more likely to not have an
 				   affected answer. */
-				if (!(res = cache_lookup(dr, &p->eid, dr->crc32, &dr->expiration))) {
+				if(nocache || !(res = cache_lookup(dr, &p->eid, dr->crc32, &dr->expiration))) {
+					res = 0;
 					/* Make sure we haven't already seen it and that it won't
 					   affect our answer */
 					for (x=0;avoid[x];x++) {
@@ -3080,7 +3093,7 @@ static unsigned long avoid_crc32(dundi_eid *avoid[])
 	return acrc32;
 }
 
-static int dundi_lookup_internal(struct dundi_result *result, int maxret, struct ast_channel *chan, const char *dcontext, const char *number, int ttl, int blockempty, struct dundi_hint_metadata *hmd, int *expiration, dundi_eid *avoid[], int direct[])
+static int dundi_lookup_internal(struct dundi_result *result, int maxret, struct ast_channel *chan, const char *dcontext, const char *number, int ttl, int blockempty, struct dundi_hint_metadata *hmd, int *expiration, int cbypass, dundi_eid *avoid[], int direct[])
 {
 	int res;
 	struct dundi_request dr, *pending;
@@ -3112,6 +3125,7 @@ static int dundi_lookup_internal(struct dundi_result *result, int maxret, struct
 	dr.hmd = hmd;
 	dr.maxcount = maxret;
 	dr.expiration = *expiration;
+	dr.cbypass = cbypass;
 	dr.crc32 = avoid_crc32(avoid);
 	strncpy(dr.dcontext, dcontext ? dcontext : "e164", sizeof(dr.dcontext) - 1);
 	strncpy(dr.number, number, sizeof(dr.number) - 1);
@@ -3145,7 +3159,7 @@ static int dundi_lookup_internal(struct dundi_result *result, int maxret, struct
 		order = skipped;
 		skipped = 0;
 		foundcache = 0;
-		build_transactions(&dr, ttl, order, &foundcache, &skipped, blockempty, avoid, direct);
+		build_transactions(&dr, ttl, order, &foundcache, &skipped, blockempty, cbypass, avoid, direct);
 	} while (skipped && !foundcache && !dr.trans);
 	/* If no TTL, abort and return 0 now after setting TTL expired hint.  Couldn't
 	   do this earlier because we didn't know if we were going to have transactions
@@ -3180,7 +3194,7 @@ static int dundi_lookup_internal(struct dundi_result *result, int maxret, struct
 	return res;
 }
 
-int dundi_lookup(struct dundi_result *result, int maxret, struct ast_channel *chan, const char *dcontext, const char *number)
+int dundi_lookup(struct dundi_result *result, int maxret, struct ast_channel *chan, const char *dcontext, const char *number, int cbypass)
 {
 	struct dundi_hint_metadata hmd;
 	dundi_eid *avoid[1] = { NULL, };
@@ -3188,7 +3202,7 @@ int dundi_lookup(struct dundi_result *result, int maxret, struct ast_channel *ch
 	int expiration = DUNDI_DEFAULT_CACHE_TIME;
 	memset(&hmd, 0, sizeof(hmd));
 	hmd.flags = DUNDI_HINT_DONT_ASK | DUNDI_HINT_UNAFFECTED;
-	return dundi_lookup_internal(result, maxret, chan, dcontext, number, dundi_ttl, 0, &hmd, &expiration, avoid, direct);
+	return dundi_lookup_internal(result, maxret, chan, dcontext, number, dundi_ttl, 0, &hmd, &expiration, cbypass, avoid, direct);
 }
 
 static int dundi_query_eid_internal(struct dundi_entity_info *dei, const char *dcontext, dundi_eid *eid, struct dundi_hint_metadata *hmd, int ttl, int blockempty, dundi_eid *avoid[])
@@ -3215,7 +3229,7 @@ static int dundi_query_eid_internal(struct dundi_entity_info *dei, const char *d
 	if (rooteid)
 		dr.root_eid = *rooteid;
 	/* Create transactions */
-	build_transactions(&dr, ttl, 9999, &foundcache, &skipped, blockempty, avoid, NULL);
+	build_transactions(&dr, ttl, 9999, &foundcache, &skipped, blockempty, 0, avoid, NULL);
 
 	/* If no TTL, abort and return 0 now after setting TTL expired hint.  Couldn't
 	   do this earlier because we didn't know if we were going to have transactions
@@ -3726,7 +3740,7 @@ static int dundi_helper(struct ast_channel *chan, const char *context, const cha
 		if (!data || ast_strlen_zero(data))
 			data = context;
 	}
-	res = dundi_lookup(results, MAX_RESULTS, chan, data, exten);
+	res = dundi_lookup(results, MAX_RESULTS, chan, data, exten, 0);
 	for (x=0;x<res;x++) {
 		if (results[x].flags & flag)
 			found++;
@@ -3777,7 +3791,7 @@ static int dundi_exec(struct ast_channel *chan, const char *context, const char
 		if (!data || ast_strlen_zero(data))
 			data = context;
 	}
-	res = dundi_lookup(results, MAX_RESULTS, chan, data, exten);
+	res = dundi_lookup(results, MAX_RESULTS, chan, data, exten, 0);
 	if (res > 0) {
 		sort_results(results, res);
 		for (x=0;x<res;x++) {