Index: pjproject/trunk/pjlib-util/src/pjlib-util/resolver.c
===================================================================
--- pjproject/trunk/pjlib-util/src/pjlib-util/resolver.c	(revision 4316)
+++ pjproject/trunk/pjlib-util/src/pjlib-util/resolver.c	(revision 4317)
@@ -224,4 +224,60 @@
 
 
+/* 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_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)
+	return status;
+
+    return PJ_SUCCESS;
+}
+
+
 /* Initialize DNS settings with default values */
 PJ_DEF(void) pj_dns_settings_default(pj_dns_settings *s)
@@ -248,5 +304,4 @@
     pj_pool_t *pool;
     pj_dns_resolver *resv;
-    pj_ioqueue_callback socket_cb;
     pj_status_t status;
 
@@ -303,34 +358,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 +422,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) {
@@ -604,11 +626,34 @@
 	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_sock_sendto(resolver->udp_sock, resolver->udp_tx_pkt,
+				&sent, 0, &resolver->ns[servers[i]].addr,
+				sizeof(pj_sockaddr_in));
+
+#if defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \
+	    PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0
+	/* Re-init dead UDP sockets, see ticket #1107 & #1603.
+	 * Note: PJ_STATUS_FROM_OS(EPIPE) == PJ_ERRNO_START_SYS + 32.
+	 */
+	if (status == PJ_ERRNO_START_SYS + 32) {
+	    close_sock(resolver);
+	    status = init_sock(resolver);
+	    if (status != PJ_SUCCESS) {
+		PJ_PERROR(1,(THIS_FILE, status, "Error reinit UDP socket"));
+		return status;
+	    }
+
+	    PJ_LOG(3,(THIS_FILE, "UDP socket reinitialized."));
+
+	    /* Try to send again */
+	    status = pj_sock_sendto(resolver->udp_sock, resolver->udp_tx_pkt,
+				    &sent, 0, &resolver->ns[servers[i]].addr,
+				    sizeof(pj_sockaddr_in));
+	}
+#endif
+
+	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),
