Index: /pjproject/branches/1.x/pjlib-util/src/pjlib-util/resolver.c
===================================================================
--- /pjproject/branches/1.x/pjlib-util/src/pjlib-util/resolver.c	(revision 4396)
+++ /pjproject/branches/1.x/pjlib-util/src/pjlib-util/resolver.c	(revision 4397)
@@ -181,5 +181,6 @@
     unsigned char	 udp_tx_pkt[UDPSZ];/**< UDP receive buffer.	    */
     pj_ssize_t		 udp_len;	/**< Length of received packet.	    */
-    pj_ioqueue_op_key_t	 udp_op_key;	/**< UDP read operation key.	    */
+    pj_ioqueue_op_key_t	 udp_op_rx_key;	/**< UDP read operation key.	    */
+    pj_ioqueue_op_key_t	 udp_op_tx_key;	/**< UDP write operation key.	    */
     pj_sockaddr_in	 udp_src_addr;	/**< Source address of packet	    */
     int			 udp_addr_len;	/**< Source address length.	    */
@@ -222,4 +223,61 @@
 				      unsigned *count,
 				      unsigned servers[]);
+
+
+/* Close UDP socket */
+static void close_sock(pj_dns_resolver *resv)
+{
+    /* Close existing socket */
+    if (resv->udp_key != NULL) {
+	pj_ioqueue_unregister(resv->udp_key);
+	resv->udp_key = NULL;
+	resv->udp_sock = PJ_INVALID_SOCKET;
+    } else if (resv->udp_sock != PJ_INVALID_SOCKET) {
+	pj_sock_close(resv->udp_sock);
+	resv->udp_sock = PJ_INVALID_SOCKET;
+    }
+}
+
+
+/* Initialize UDP socket */
+static pj_status_t init_sock(pj_dns_resolver *resv)
+{
+    pj_ioqueue_callback socket_cb;
+    pj_status_t status;
+
+    /* Create the UDP socket */
+    status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &resv->udp_sock);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    /* Bind to any address/port */
+    status = pj_sock_bind_in(resv->udp_sock, 0, 0);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    /* Register to ioqueue */
+    pj_bzero(&socket_cb, sizeof(socket_cb));
+    socket_cb.on_read_complete = &on_read_complete;
+    status = pj_ioqueue_register_sock(resv->pool, resv->ioqueue,
+				      resv->udp_sock, resv, &socket_cb,
+				      &resv->udp_key);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    pj_ioqueue_op_key_init(&resv->udp_op_rx_key, sizeof(resv->udp_op_rx_key));
+    pj_ioqueue_op_key_init(&resv->udp_op_tx_key, sizeof(resv->udp_op_tx_key));
+
+    /* Start asynchronous read to the UDP socket */
+    resv->udp_len = sizeof(resv->udp_rx_pkt);
+    resv->udp_addr_len = sizeof(resv->udp_src_addr);
+    status = pj_ioqueue_recvfrom(resv->udp_key, &resv->udp_op_rx_key,
+				 resv->udp_rx_pkt, &resv->udp_len,
+				 PJ_IOQUEUE_ALWAYS_ASYNC,
+				 &resv->udp_src_addr, &resv->udp_addr_len);
+    if (status != PJ_EPENDING)
+	return status;
+
+    return PJ_SUCCESS;
+}
 
 
@@ -248,5 +306,4 @@
     pj_pool_t *pool;
     pj_dns_resolver *resv;
-    pj_ioqueue_callback socket_cb;
     pj_status_t status;
 
@@ -303,34 +360,8 @@
     pj_list_init(&resv->query_free_nodes);
 
-    /* Create the UDP socket */
-    status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &resv->udp_sock);
+    /* Initialize the UDP socket */
+    status = init_sock(resv);
     if (status != PJ_SUCCESS)
 	goto on_error;
-
-    /* Bind to any address/port */
-    status = pj_sock_bind_in(resv->udp_sock, 0, 0);
-    if (status != PJ_SUCCESS)
-	goto on_error;
-
-    /* Register to ioqueue */
-    pj_bzero(&socket_cb, sizeof(socket_cb));
-    socket_cb.on_read_complete = &on_read_complete;
-    status = pj_ioqueue_register_sock(pool, resv->ioqueue, resv->udp_sock,
-				      resv, &socket_cb, &resv->udp_key);
-    if (status != PJ_SUCCESS)
-	goto on_error;
-
-    pj_ioqueue_op_key_init(&resv->udp_op_key, sizeof(resv->udp_op_key));
-
-    /* Start asynchronous read to the UDP socket */
-    resv->udp_len = sizeof(resv->udp_rx_pkt);
-    resv->udp_addr_len = sizeof(resv->udp_src_addr);
-    status = pj_ioqueue_recvfrom(resv->udp_key, &resv->udp_op_key, 
-				 resv->udp_rx_pkt, &resv->udp_len, 
-				 PJ_IOQUEUE_ALWAYS_ASYNC,
-				 &resv->udp_src_addr, &resv->udp_addr_len);
-    if (status != PJ_EPENDING)
-	goto on_error;
-
 
     /* Looks like everything is okay */
@@ -393,12 +424,5 @@
     }
 
-    if (resolver->udp_key != NULL) {
-	pj_ioqueue_unregister(resolver->udp_key);
-	resolver->udp_key = NULL;
-	resolver->udp_sock = PJ_INVALID_SOCKET;
-    } else if (resolver->udp_sock != PJ_INVALID_SOCKET) {
-	pj_sock_close(resolver->udp_sock);
-	resolver->udp_sock = PJ_INVALID_SOCKET;
-    }
+    close_sock(resolver);
 
     if (resolver->own_ioqueue && resolver->ioqueue) {
@@ -562,13 +586,4 @@
     pj_status_t status;
 
-    /* Create DNS query packet */
-    pkt_size = sizeof(resolver->udp_tx_pkt);
-    name = pj_str(q->key.name);
-    status = pj_dns_make_query(resolver->udp_tx_pkt, &pkt_size, 
-			       q->id, q->key.qtype, &name);
-    if (status != PJ_SUCCESS) {
-	return status;
-    }
-
     /* Select which nameserver(s) to send requests to. */
     server_cnt = PJ_ARRAY_SIZE(servers);
@@ -596,4 +611,26 @@
     }
 
+    /* Check if the socket is available for sending */
+    if (pj_ioqueue_is_pending(resolver->udp_key, &resolver->udp_op_tx_key)) {
+	++q->transmit_cnt;
+	PJ_LOG(4,(resolver->name.ptr,
+		  "Socket busy in transmitting DNS %s query for %s%s",
+		  pj_dns_get_type_name(q->key.qtype),
+		  q->key.name,
+		  (q->transmit_cnt < resolver->settings.qretr_count?
+		   ", will try again later":"")));
+	return PJ_SUCCESS;
+    }
+
+    /* Create DNS query packet */
+    pkt_size = sizeof(resolver->udp_tx_pkt);
+    name = pj_str(q->key.name);
+    status = pj_dns_make_query(resolver->udp_tx_pkt, &pkt_size,
+			       q->id, q->key.qtype, &name);
+    if (status != PJ_SUCCESS) {
+	pj_timer_heap_cancel(resolver->timer, &q->timer_entry);
+	return status;
+    }
+
     /* Get current time. */
     pj_gettimeofday(&now);
@@ -604,11 +641,14 @@
 	struct nameserver *ns = &resolver->ns[servers[i]];
 
-	pj_sock_sendto(resolver->udp_sock, resolver->udp_tx_pkt, &sent, 0,
-		       &resolver->ns[servers[i]].addr, sizeof(pj_sockaddr_in));
-
-	PJ_LOG(4,(resolver->name.ptr, 
+	status = pj_ioqueue_sendto(resolver->udp_key,
+				   &resolver->udp_op_tx_key,
+				   resolver->udp_tx_pkt, &sent, 0,
+				   &resolver->ns[servers[i]].addr,
+				   sizeof(pj_sockaddr_in));
+
+	PJ_PERROR(4,(resolver->name.ptr, status,
 		  "%s %d bytes to NS %d (%s:%d): DNS %s query for %s",
 		  (q->transmit_cnt==0? "Transmitting":"Re-transmitting"),
-		  (int)sent, servers[i],
+		  (int)pkt_size, servers[i],
 		  pj_inet_ntoa(ns->addr.sin_addr), 
 		  (int)pj_ntohs(ns->addr.sin_port),
