Index: /pjproject/trunk/pjlib-util/include/pjlib-util/srv_resolver.h
===================================================================
--- /pjproject/trunk/pjlib-util/include/pjlib-util/srv_resolver.h	(revision 2386)
+++ /pjproject/trunk/pjlib-util/include/pjlib-util/srv_resolver.h	(revision 2387)
@@ -137,4 +137,7 @@
 } pj_dns_srv_record;
 
+
+/** Opaque declaration for DNS SRV query */
+typedef struct pj_dns_srv_async_query pj_dns_srv_async_query;
 
 /**
@@ -185,5 +188,18 @@
 					void *token,
 					pj_dns_srv_resolver_cb *cb,
-					pj_dns_async_query **p_query);
+					pj_dns_srv_async_query **p_query);
+
+
+/**
+ * Cancel an outstanding DNS SRV query.
+ *
+ * @param query	    The pending asynchronous query to be cancelled.
+ * @param notify    If non-zero, the callback will be called with failure
+ *		    status to notify that the query has been cancelled.
+ *
+ * @return	    PJ_SUCCESS on success, or the appropriate error code,
+ */
+PJ_DECL(pj_status_t) pj_dns_srv_cancel_query(pj_dns_srv_async_query *query,
+					     pj_bool_t notify);
 
 
Index: /pjproject/trunk/pjlib-util/src/pjlib-util/srv_resolver.c
===================================================================
--- /pjproject/trunk/pjlib-util/src/pjlib-util/srv_resolver.c	(revision 2386)
+++ /pjproject/trunk/pjlib-util/src/pjlib-util/srv_resolver.c	(revision 2387)
@@ -22,4 +22,5 @@
 #include <pj/assert.h>
 #include <pj/log.h>
+#include <pj/os.h>
 #include <pj/pool.h>
 #include <pj/rand.h>
@@ -31,7 +32,15 @@
 #define ADDR_MAX_COUNT	    PJ_DNS_MAX_IP_IN_A_REC
 
+struct common
+{
+    pj_dns_type		     type;	    /**< Type of this structure.*/
+};
+
 struct srv_target
 {
+    struct common	    common;
+    pj_dns_srv_async_query *parent;
     pj_str_t		    target_name;
+    pj_dns_async_query	   *q_a;
     char		    target_buf[PJ_MAX_HOSTNAME];
     pj_str_t		    cname;
@@ -45,11 +54,13 @@
 };
 
-typedef struct pj_dns_srv_resolver_job
-{
+struct pj_dns_srv_async_query
+{
+    struct common	     common;
     char		    *objname;
 
+    pj_dns_type		     dns_state;	    /**< DNS type being resolved.   */
     pj_dns_resolver	    *resolver;	    /**< Resolver SIP instance.	    */
-    pj_dns_type		     dns_state;	    /**< DNS type being resolved.   */
     void		    *token;
+    pj_dns_async_query	    *q_srv;
     pj_dns_srv_resolver_cb  *cb;
     pj_status_t		     last_error;
@@ -68,5 +79,5 @@
     unsigned		     host_resolved;
 
-} pj_dns_srv_resolver_job;
+};
 
 
@@ -89,9 +100,9 @@
 					void *token,
 					pj_dns_srv_resolver_cb *cb,
-					pj_dns_async_query **p_query)
+					pj_dns_srv_async_query **p_query)
 {
     int len;
     pj_str_t target_name;
-    pj_dns_srv_resolver_job *query_job;
+    pj_dns_srv_async_query *query_job;
     pj_status_t status;
 
@@ -112,5 +123,6 @@
 
     /* Build the query_job state */
-    query_job = PJ_POOL_ZALLOC_T(pool, pj_dns_srv_resolver_job);
+    query_job = PJ_POOL_ZALLOC_T(pool, pj_dns_srv_async_query);
+    query_job->common.type = PJ_DNS_TYPE_SRV;
     query_job->objname = target_name.ptr;
     query_job->resolver = resolver;
@@ -136,8 +148,42 @@
 				         query_job->dns_state, 0, 
 					 &dns_callback,
-    					 query_job, p_query);
+    					 query_job, &query_job->q_srv);
+    if (status==PJ_SUCCESS && p_query)
+	*p_query = query_job;
+
     return status;
 }
 
+
+/*
+ * Cancel pending query.
+ */
+PJ_DEF(pj_status_t) pj_dns_srv_cancel_query(pj_dns_srv_async_query *query,
+					    pj_bool_t notify)
+{
+    pj_bool_t has_pending = PJ_FALSE;
+    unsigned i;
+
+    if (query->q_srv) {
+	pj_dns_resolver_cancel_query(query->q_srv, PJ_FALSE);
+	query->q_srv = NULL;
+	has_pending = PJ_TRUE;
+    }
+
+    for (i=0; i<query->srv_cnt; ++i) {
+	struct srv_target *srv = &query->srv[i];
+	if (srv->q_a) {
+	    pj_dns_resolver_cancel_query(srv->q_a, PJ_FALSE);
+	    srv->q_a = NULL;
+	    has_pending = PJ_TRUE;
+	}
+    }
+
+    if (has_pending && notify && query->cb) {
+	(*query->cb)(query->token, PJ_ECANCELLED, NULL);
+    }
+
+    return has_pending? PJ_SUCCESS : PJ_EINVALIDOP;
+}
 
 
@@ -153,5 +199,5 @@
 
 /* Build server entries in the query_job based on received SRV response */
-static void build_server_entries(pj_dns_srv_resolver_job *query_job, 
+static void build_server_entries(pj_dns_srv_async_query *query_job, 
 				 pj_dns_parsed_packet *response)
 {
@@ -357,5 +403,5 @@
 
 /* Start DNS A record queries for all SRV records in the query_job structure */
-static pj_status_t resolve_hostnames(pj_dns_srv_resolver_job *query_job)
+static pj_status_t resolve_hostnames(pj_dns_srv_async_query *query_job)
 {
     unsigned i;
@@ -364,14 +410,19 @@
     query_job->dns_state = PJ_DNS_TYPE_A;
     for (i=0; i<query_job->srv_cnt; ++i) {
+	struct srv_target *srv = &query_job->srv[i];
+
 	PJ_LOG(5, (query_job->objname, 
 		   "Starting async DNS A query_job for %.*s",
-		   (int)query_job->srv[i].target_name.slen, 
-		   query_job->srv[i].target_name.ptr));
+		   (int)srv->target_name.slen, 
+		   srv->target_name.ptr));
+
+	srv->common.type = PJ_DNS_TYPE_A;
+	srv->parent = query_job;
 
 	status = pj_dns_resolver_start_query(query_job->resolver,
-					     &query_job->srv[i].target_name,
+					     &srv->target_name,
 					     PJ_DNS_TYPE_A, 0,
 					     &dns_callback,
-					     query_job, NULL);
+					     srv, &srv->q_a);
 	if (status != PJ_SUCCESS) {
 	    query_job->host_resolved++;
@@ -391,12 +442,27 @@
 			 pj_dns_parsed_packet *pkt)
 {
-    pj_dns_srv_resolver_job *query_job = (pj_dns_srv_resolver_job*) user_data;
+    struct common *common = (struct common*) user_data;
+    pj_dns_srv_async_query *query_job;
+    struct srv_target *srv = NULL;
     unsigned i;
 
+    if (common->type == PJ_DNS_TYPE_SRV) {
+	query_job = (pj_dns_srv_async_query*) common;
+	srv = NULL;
+    } else if (common->type == PJ_DNS_TYPE_A) {
+	srv = (struct srv_target*) common;
+	query_job = srv->parent;
+    } else {
+	pj_assert(!"Unexpected user data!");
+	query_job->last_error = status = PJ_EINVALIDOP;
+	goto on_error;
+    }
+
     /* Proceed to next stage */
-
     if (query_job->dns_state == PJ_DNS_TYPE_SRV) {
 
 	/* We are getting SRV response */
+
+	query_job->q_srv = NULL;
 
 	if (status == PJ_SUCCESS && pkt->hdr.anscount != 0) {
@@ -469,8 +535,9 @@
     } else if (query_job->dns_state == PJ_DNS_TYPE_A) {
 
+	/* Clear the outstanding job */
+	srv->q_a = NULL;
+
 	/* Check that we really have answer */
 	if (status==PJ_SUCCESS && pkt->hdr.anscount != 0) {
-	    unsigned srv_idx;
-	    struct srv_target *srv = NULL;
 	    pj_dns_a_record rec;
 
@@ -481,22 +548,4 @@
 
 	    pj_assert(rec.addr_count != 0);
-
-	    /* Find which server entry to be updated. */
-	    for (srv_idx=0; srv_idx<query_job->srv_cnt; ++srv_idx) {
-		srv = &query_job->srv[srv_idx];
-		if (pj_stricmp(&rec.name, &srv->target_name)==0) {
-		    break;
-		}
-	    }
-
-	    if (srv_idx==query_job->srv_cnt) {
-		/* The DNS A response doesn't match any server names
-		 * we're querying!
-		 */
-		status = PJLIB_UTIL_EDNSINANSWER;
-		goto on_error;
-	    }
-
-	    srv = &query_job->srv[srv_idx];
 
 	    /* Update CNAME alias, if present. */
Index: /pjproject/trunk/pjnath/src/pjnath/stun_sock.c
===================================================================
--- /pjproject/trunk/pjnath/src/pjnath/stun_sock.c	(revision 2386)
+++ /pjproject/trunk/pjnath/src/pjnath/stun_sock.c	(revision 2387)
@@ -48,5 +48,5 @@
     pj_sockaddr		 mapped_addr;	/* Our public address	    */
 
-    pj_dns_async_query	*q;		/* Pending DNS query	    */
+    pj_dns_srv_async_query *q;		/* Pending DNS query	    */
     pj_sock_t		 sock_fd;	/* Socket descriptor	    */
     pj_activesock_t	*active_sock;	/* Active socket object	    */
@@ -371,5 +371,5 @@
 {
     if (stun_sock->q) {
-	pj_dns_resolver_cancel_query(stun_sock->q, PJ_FALSE);
+	pj_dns_srv_cancel_query(stun_sock->q, PJ_FALSE);
 	stun_sock->q = NULL;
     }
Index: /pjproject/trunk/pjnath/src/pjnath/turn_session.c
===================================================================
--- /pjproject/trunk/pjnath/src/pjnath/turn_session.c	(revision 2386)
+++ /pjproject/trunk/pjnath/src/pjnath/turn_session.c	(revision 2387)
@@ -87,5 +87,5 @@
     pj_timer_entry	 timer;
 
-    pj_dns_async_query	*dns_async;
+    pj_dns_srv_async_query *dns_async;
     pj_uint16_t		 default_port;
 
@@ -343,5 +343,5 @@
     case PJ_TURN_STATE_RESOLVING:
 	if (sess->dns_async != NULL) {
-	    pj_dns_resolver_cancel_query(sess->dns_async, PJ_FALSE);
+	    pj_dns_srv_cancel_query(sess->dns_async, PJ_FALSE);
 	    sess->dns_async = NULL;
 	}
