Index: /pjproject/trunk/pjlib-util/include/pjlib-util/srv_resolver.h
===================================================================
--- /pjproject/trunk/pjlib-util/include/pjlib-util/srv_resolver.h	(revision 1356)
+++ /pjproject/trunk/pjlib-util/include/pjlib-util/srv_resolver.h	(revision 1357)
@@ -76,13 +76,6 @@
 
 /**
- * Maximum server address entries per one SRV record
- */
-#ifndef PJ_DNS_SRV_MAX_ADDR
-#   define PJ_DNS_SRV_MAX_ADDR	    8
-#endif
-
-
-/**
- * The server addresses returned by the resolver.
+ * This structure represents DNS SRV records as the result of DNS SRV
+ * resolution using #pj_dns_srv_resolve().
  */
 typedef struct pj_dns_srv_record
@@ -93,5 +86,5 @@
     /** Address records. */
     struct
-    {
+v    {
 	/** Server priority (the lower the higher the priority). */
 	unsigned		priority;
@@ -100,9 +93,9 @@
 	unsigned		weight;
 
-	/** The server's address. */
-	pj_sockaddr		addr;
+	/** Port number. */
+	pj_uint16_t		port;
 
-	/** Address length. */
-	int			addr_len;
+	/** The host address. */
+	pj_dns_a_record		server;
 
     } entry[PJ_DNS_SRV_MAX_ADDR];
@@ -139,4 +132,7 @@
  * @param cb		Pointer to callback function to receive the
  *			notification when the resolution process completes.
+ * @param p_query	Optional pointer to receive the query object, if one
+ *			was started. If this pointer is specified, a NULL may
+ *			be returned if response cache is available immediately.
  *
  * @return		PJ_SUCCESS on success, or the appropriate error code.
@@ -149,5 +145,6 @@
 					pj_bool_t fallback_a,
 					void *token,
-					pj_dns_srv_resolver_cb *cb);
+					pj_dns_srv_resolver_cb *cb,
+					pj_dns_async_query **p_query);
 
 
Index: /pjproject/trunk/pjlib-util/src/pjlib-util/srv_resolver.c
===================================================================
--- /pjproject/trunk/pjlib-util/src/pjlib-util/srv_resolver.c	(revision 1356)
+++ /pjproject/trunk/pjlib-util/src/pjlib-util/srv_resolver.c	(revision 1357)
@@ -29,5 +29,5 @@
 #define THIS_FILE   "srv_resolver.c"
 
-#define ADDR_MAX_COUNT	    8
+#define ADDR_MAX_COUNT	    PJ_DNS_MAX_IP_IN_A_REC
 
 struct srv_target
@@ -53,5 +53,4 @@
     void		    *token;
     pj_dns_srv_resolver_cb  *cb;
-    pj_dns_async_query	    *qobject;
     pj_status_t		     last_error;
 
@@ -89,5 +88,6 @@
 					pj_bool_t fallback_a,
 					void *token,
-					pj_dns_srv_resolver_cb *cb)
+					pj_dns_srv_resolver_cb *cb,
+					pj_dns_async_query **p_query)
 {
     int len;
@@ -128,12 +128,13 @@
 
     PJ_LOG(5, (query_job->objname, 
-	       "Starting async DNS %s query_job: target=%.*s",
+	       "Starting async DNS %s query_job: target=%.*s:%d",
 	       pj_dns_get_type_name(query_job->dns_state),
-	       (int)target_name.slen, target_name.ptr));
+	       (int)target_name.slen, target_name.ptr,
+	       def_port));
 
     status = pj_dns_resolver_start_query(resolver, &target_name, 
 				         query_job->dns_state, 0, 
 					 &dns_callback,
-    					 query_job, &query_job->qobject);
+    					 query_job, p_query);
     return status;
 }
@@ -466,91 +467,63 @@
 	/* Check that we really have answer */
 	if (status==PJ_SUCCESS && pkt->hdr.anscount != 0) {
-	    int ans_idx = -1;
-
-	    /* Find the first DNS A record in the answer while processing
-	     * the CNAME info found in the response.
-	     */
-	    for (i=0; i < pkt->hdr.anscount; ++i) {
-
-		pj_dns_parsed_rr *rr = &pkt->ans[i];
-
-		if (rr->type == PJ_DNS_TYPE_A) {
-
-		    if (ans_idx == -1)
-			ans_idx = i;
-
-		} else if (rr->type == PJ_DNS_TYPE_CNAME) {
-		    /* Find which server entry to be updated with
-		     * the CNAME information.
-		     */
-		    unsigned j;
-		    pj_str_t cname = rr->rdata.cname.name;
-
-		    for (j=0; j<query_job->srv_cnt; ++j) 
-		    {
-			struct srv_target *srv = &query_job->srv[j];
-			if (pj_stricmp(&rr->name, &srv->target_name)==0)
-			{
-			    /* Update CNAME info for this server entry */
-			    srv->cname.ptr = srv->cname_buf;
-			    pj_strncpy(&srv->cname, &cname, 
-				       sizeof(srv->cname_buf));
-			    break;
-			}
-		    }
-		}
-	    }
-
-	    if (ans_idx == -1) {
-		/* There's no DNS A answer! */
-		PJ_LOG(5,(query_job->objname, 
-			  "No DNS A record in response!"));
-		status = PJLIB_UTIL_EDNSNOANSWERREC;
+	    unsigned srv_idx;
+	    struct srv_target *srv = NULL;
+	    pj_dns_a_record rec;
+
+	    /* Parse response */
+	    status = pj_dns_parse_a_response(pkt, &rec);
+	    if (status != PJ_SUCCESS)
 		goto on_error;
-	    }
-
-	    /* Update IP address of the corresponding hostname or CNAME */
-	    for (i=0; i<query_job->srv_cnt; ++i) {
-		pj_dns_parsed_rr *rr = &pkt->ans[ans_idx];
-		struct srv_target *srv = &query_job->srv[i];
-
-		if (pj_stricmp(&rr->name, &srv->target_name)==0 ||
-		    pj_stricmp(&rr->name, &srv->cname)==0) 
-		{
+
+	    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 (i == query_job->srv_cnt) {
-		PJ_LOG(4,(query_job->objname, 
-			  "Received answer to DNS A request with no matching "
-			  "SRV record! The unknown name is %.*s",
-			  (int)pkt->ans[ans_idx].name.slen, 
-			  pkt->ans[ans_idx].name.ptr));
+	    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. */
+	    if (rec.alias.slen) {
+		pj_assert(rec.alias.slen <= sizeof(srv->cname_buf));
+		srv->cname.ptr = srv->cname_buf;
+		pj_strcpy(&srv->cname, &rec.alias);
 	    } else {
-		unsigned j;
-
-		query_job->srv[i].addr[query_job->srv[i].addr_cnt++].s_addr =
-		    pkt->ans[ans_idx].rdata.a.ip_addr.s_addr;
+		srv->cname.slen = 0;
+	    }
+
+	    /* Update IP address of the corresponding hostname or CNAME */
+	    if (srv->addr_cnt < ADDR_MAX_COUNT) {
+		srv->addr[srv->addr_cnt++].s_addr = rec.addr[0].s_addr;
 
 		PJ_LOG(5,(query_job->objname, 
 			  "DNS A for %.*s: %s",
-			  (int)query_job->srv[i].target_name.slen, 
-			  query_job->srv[i].target_name.ptr,
-			  pj_inet_ntoa(pkt->ans[ans_idx].rdata.a.ip_addr)));
-
-		/* Check for multiple IP addresses */
-		for (j=ans_idx+1; j<pkt->hdr.anscount && 
-			    query_job->srv[i].addr_cnt < ADDR_MAX_COUNT; ++j)
-		{
-		    query_job->srv[i].addr[query_job->srv[i].addr_cnt++].s_addr = 
-			pkt->ans[j].rdata.a.ip_addr.s_addr;
-
-		    PJ_LOG(5,(query_job->objname, 
-			      "Additional DNS A for %.*s: %s",
-			      (int)query_job->srv[i].target_name.slen, 
-			      query_job->srv[i].target_name.ptr,
-			      pj_inet_ntoa(pkt->ans[j].rdata.a.ip_addr)));
-		}
+			  (int)srv->target_name.slen, 
+			  srv->target_name.ptr,
+			  pj_inet_ntoa(rec.addr[0])));
+	    }
+
+	    /* Check for multiple IP addresses */
+	    for (i=1; i<rec.addr_count && srv->addr_cnt < ADDR_MAX_COUNT; ++i)
+	    {
+		srv->addr[srv->addr_cnt++].s_addr = rec.addr[i].s_addr;
+
+		PJ_LOG(5,(query_job->objname, 
+			  "Additional DNS A for %.*s: %s",
+			  (int)srv->target_name.slen, 
+			  srv->target_name.ptr,
+			  pj_inet_ntoa(rec.addr[i])));
 	    }
 
@@ -578,37 +551,31 @@
     if (query_job->host_resolved == query_job->srv_cnt) {
 	/* Got all answers, build server addresses */
-	pj_dns_srv_record svr_addr;
-
-	svr_addr.count = 0;
+	pj_dns_srv_record srv_rec;
+
+	srv_rec.count = 0;
 	for (i=0; i<query_job->srv_cnt; ++i) {
 	    unsigned j;
-
-	    /* Do we have IP address for this server? */
-	    /* This log is redundant really.
-	    if (query_job->srv[i].addr_cnt == 0) {
-		PJ_LOG(5,(query_job->objname, 
-			  " SRV target %.*s:%d does not have IP address!",
-			  (int)query_job->srv[i].target_name.slen,
-			  query_job->srv[i].target_name.ptr,
-			  query_job->srv[i].port));
-		continue;
-	    }
-	    */
-
-	    for (j=0; j<query_job->srv[i].addr_cnt; ++j) {
-		unsigned idx = svr_addr.count;
-		pj_sockaddr_in *addr;
-
-		svr_addr.entry[idx].priority = query_job->srv[i].priority;
-		svr_addr.entry[idx].weight = query_job->srv[i].weight;
-		svr_addr.entry[idx].addr_len = sizeof(pj_sockaddr_in);
-	     
-		addr = (pj_sockaddr_in*)&svr_addr.entry[idx].addr;
-		pj_bzero(addr, sizeof(pj_sockaddr_in));
-		addr->sin_family = PJ_AF_INET;
-		addr->sin_addr = query_job->srv[i].addr[j];
-		addr->sin_port = pj_htons((pj_uint16_t)query_job->srv[i].port);
-
-		++svr_addr.count;
+	    struct srv_target *srv = &query_job->srv[i];
+
+	    srv_rec.entry[srv_rec.count].priority = srv->priority;
+	    srv_rec.entry[srv_rec.count].weight = srv->weight;
+	    srv_rec.entry[srv_rec.count].port = (pj_uint16_t)srv->port ;
+
+	    srv_rec.entry[srv_rec.count].server.name = srv->target_name;
+	    srv_rec.entry[srv_rec.count].server.alias = srv->cname;
+	    srv_rec.entry[srv_rec.count].server.addr_count = 0;
+
+	    pj_assert(srv->addr_cnt <= PJ_DNS_MAX_IP_IN_A_REC);
+
+	    for (j=0; j<srv->addr_cnt; ++j) {
+		srv_rec.entry[srv_rec.count].server.addr[j].s_addr = 
+		    srv->addr[j].s_addr;
+		++srv_rec.entry[srv_rec.count].server.addr_count;
+	    }
+
+	    if (srv->addr_cnt > 0) {
+		++srv_rec.count;
+		if (srv_rec.count == PJ_DNS_SRV_MAX_ADDR)
+		    break;
 	    }
 	}
@@ -616,8 +583,8 @@
 	PJ_LOG(5,(query_job->objname, 
 		  "Server resolution complete, %d server entry(s) found",
-		  svr_addr.count));
-
-
-	if (svr_addr.count > 0)
+		  srv_rec.count));
+
+
+	if (srv_rec.count > 0)
 	    status = PJ_SUCCESS;
 	else {
@@ -628,5 +595,5 @@
 
 	/* Call the callback */
-	(*query_job->cb)(query_job->token, status, &svr_addr);
+	(*query_job->cb)(query_job->token, status, &srv_rec);
     }
 
Index: /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c	(revision 1356)
+++ /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c	(revision 1357)
@@ -743,6 +743,9 @@
     }
 
-    pj_memcpy(&pjsua_var.stun_srv, &rec->entry[0].addr, 
-	      rec->entry[0].addr_len);
+    pj_assert(rec->count != 0 && rec->entry[0].server.addr_count != 0);
+    pj_sockaddr_in_init(&pjsua_var.stun_srv.ipv4, NULL,
+			rec->entry[0].port);
+    pjsua_var.stun_srv.ipv4.sin_addr.s_addr = 
+	rec->entry[0].server.addr[0].s_addr;
 
     PJ_LOG(3,(THIS_FILE, "_stun._udp.%.*s resolved, found %d entry(s):",
@@ -755,6 +758,6 @@
 		  " %d: prio=%d, weight=%d  %s:%d", 
 		  i, rec->entry[i].priority, rec->entry[i].weight,
-		  pj_inet_ntoa(rec->entry[i].addr.ipv4.sin_addr),
-		  (int)pj_ntohs(rec->entry[i].addr.ipv4.sin_port)));
+		  pj_inet_ntoa(rec->entry[i].server.addr[0]),
+		  (int)rec->entry[i].port));
     }
 
@@ -794,5 +797,5 @@
 		pj_dns_srv_resolve(&pjsua_var.ua_cfg.stun_domain, &res_type,
 				   3478, pjsua_var.pool, pjsua_var.resolver,
-				   0, NULL, &stun_dns_srv_resolver_cb);
+				   0, NULL, &stun_dns_srv_resolver_cb, NULL);
 	    if (status != PJ_SUCCESS) {
 		pjsua_perror(THIS_FILE, "Error starting DNS SRV resolution", 
