Index: pjproject/trunk/pjlib-util/include/pjlib-util/dns.h
===================================================================
--- pjproject/trunk/pjlib-util/include/pjlib-util/dns.h	(revision 5349)
+++ pjproject/trunk/pjlib-util/include/pjlib-util/dns.h	(revision 5350)
@@ -428,4 +428,20 @@
 
 /**
+ * Initialize DNS record as DNS AAAA record.
+ *
+ * @param rec		The DNS resource record to be initialized as DNS
+ *			AAAA record.
+ * @param res_name	Resource name.
+ * @param dnsclass	DNS class.
+ * @param ttl		Resource TTL value.
+ * @param ip_addr	Host address.
+ */
+PJ_DECL(void) pj_dns_init_aaaa_rr(pj_dns_parsed_rr *rec,
+				  const pj_str_t *res_name,
+				  unsigned dnsclass,
+				  unsigned ttl,
+				  const pj_in6_addr *ip_addr);
+
+/**
  * Dump DNS packet to standard log.
  *
Index: pjproject/trunk/pjlib-util/src/pjlib-util/dns.c
===================================================================
--- pjproject/trunk/pjlib-util/src/pjlib-util/dns.c	(revision 5349)
+++ pjproject/trunk/pjlib-util/src/pjlib-util/dns.c	(revision 5350)
@@ -750,2 +750,17 @@
 }
 
+
+PJ_DEF(void) pj_dns_init_aaaa_rr(pj_dns_parsed_rr *rec,
+				 const pj_str_t *res_name,
+				 unsigned dnsclass,
+				 unsigned ttl,
+				 const pj_in6_addr *ip_addr)
+{
+    pj_bzero(rec, sizeof(*rec));
+    rec->name = *res_name;
+    rec->type = PJ_DNS_TYPE_AAAA;
+    rec->dnsclass = (pj_uint16_t) dnsclass;
+    rec->ttl = ttl;
+    rec->rdata.aaaa.ip_addr = *ip_addr;
+}
+
Index: pjproject/trunk/pjlib-util/src/pjlib-util/dns_server.c
===================================================================
--- pjproject/trunk/pjlib-util/src/pjlib-util/dns_server.c	(revision 5349)
+++ pjproject/trunk/pjlib-util/src/pjlib-util/dns_server.c	(revision 5350)
@@ -312,4 +312,18 @@
 	size -= 6;
 
+    } else if (rr->type == PJ_DNS_TYPE_AAAA) {
+
+	if (size < 18)
+	    return -1;
+
+	/* RDLEN is 16 */
+	write16(p, 16);
+
+	/* Address */
+	pj_memcpy(p+2, &rr->rdata.aaaa.ip_addr, 16);
+
+	p += 18;
+	size -= 18;
+    
     } else if (rr->type == PJ_DNS_TYPE_CNAME ||
 	       rr->type == PJ_DNS_TYPE_NS ||
Index: pjproject/trunk/pjnath/src/pjnath-test/ice_test.c
===================================================================
--- pjproject/trunk/pjnath/src/pjnath-test/ice_test.c	(revision 5349)
+++ pjproject/trunk/pjnath/src/pjnath-test/ice_test.c	(revision 5350)
@@ -40,10 +40,12 @@
     WRONG_TURN	= 1,
     DEL_ON_ERR	= 2,
+    CLIENT_IPV4	= 4,
+    CLIENT_IPV6	= 8
 };
-
 
 /* Test results */
 struct test_result
 {
+    pj_status_t start_status;	/* start ice successful?	*/	
     pj_status_t	init_status;	/* init successful?		*/
     pj_status_t	nego_status;	/* negotiation successful?	*/
@@ -102,5 +104,6 @@
     struct sess_param	*param;
 
-    test_server		*server;
+    test_server		*server1;   /* Test server for IPv4.	*/
+    test_server		*server2;   /* Test server for IPv6.	*/
 
     pj_thread_t		*worker_threads[MAX_THREADS];
@@ -122,7 +125,63 @@
 static void destroy_sess(struct test_sess *sess, unsigned wait_msec);
 
+static void set_stun_turn_cfg(struct ice_ept *ept, 
+				     pj_ice_strans_cfg *ice_cfg, 
+				     char *serverip,
+				     pj_bool_t use_ipv6) 
+{        
+    if (ept->cfg.enable_stun & YES) {
+	unsigned stun_idx = ice_cfg->stun_tp_cnt++;
+	pj_ice_strans_stun_cfg_default(&ice_cfg->stun_tp[stun_idx]);
+
+	if ((ept->cfg.enable_stun & SRV) == SRV) {
+	    ice_cfg->stun_tp[stun_idx].server = pj_str(SRV_DOMAIN);
+	} else {
+	    ice_cfg->stun_tp[stun_idx].server = pj_str(serverip);
+	}
+	ice_cfg->stun_tp[stun_idx].port = STUN_SERVER_PORT;
+
+	ice_cfg->stun_tp[stun_idx].af = GET_AF(use_ipv6);
+    }
+    ice_cfg->stun.af = GET_AF(use_ipv6);
+    if (ept->cfg.enable_host == 0) {	
+	ice_cfg->stun.max_host_cands = 0;
+    } else {
+	//ice_cfg.stun.no_host_cands = PJ_FALSE;	
+	ice_cfg->stun.loop_addr = PJ_TRUE;
+    }
+
+    if (ept->cfg.enable_turn & YES) {
+	unsigned turn_idx = ice_cfg->turn_tp_cnt++;	
+	pj_ice_strans_turn_cfg_default(&ice_cfg->turn_tp[turn_idx]);
+
+	if ((ept->cfg.enable_turn & SRV) == SRV) {
+	    ice_cfg->turn_tp[turn_idx].server = pj_str(SRV_DOMAIN);
+	} else {
+	    ice_cfg->turn_tp[turn_idx].server = pj_str(serverip);
+	}
+	ice_cfg->turn_tp[turn_idx].port = TURN_SERVER_PORT;
+	ice_cfg->turn_tp[turn_idx].conn_type = PJ_TURN_TP_UDP;
+	ice_cfg->turn_tp[turn_idx].auth_cred.type = PJ_STUN_AUTH_CRED_STATIC;
+	ice_cfg->turn_tp[turn_idx].auth_cred.data.static_cred.realm =
+	    pj_str(SRV_DOMAIN);
+	if (ept->cfg.client_flag & WRONG_TURN)
+	    ice_cfg->turn_tp[turn_idx].auth_cred.data.static_cred.username =
+	    pj_str("xxx");
+	else
+	    ice_cfg->turn_tp[turn_idx].auth_cred.data.static_cred.username =
+	    pj_str(TURN_USERNAME);
+
+	ice_cfg->turn_tp[turn_idx].auth_cred.data.static_cred.data_type =
+	    PJ_STUN_PASSWD_PLAIN;
+	ice_cfg->turn_tp[turn_idx].auth_cred.data.static_cred.data =
+	    pj_str(TURN_PASSWD);
+	
+	ice_cfg->turn_tp[turn_idx].af = GET_AF(use_ipv6);
+    }    
+}
+
 /* Create ICE stream transport */
 static int create_ice_strans(struct test_sess *test_sess,
-			     struct ice_ept *ept,
+			     struct ice_ept *ept,			     
 			     pj_ice_strans **p_ice)
 {
@@ -131,6 +190,8 @@
     pj_ice_strans_cfg ice_cfg;
     pj_sockaddr hostip;
-    char serverip[PJ_INET6_ADDRSTRLEN];
+    char serveripv4[PJ_INET6_ADDRSTRLEN];
+    char serveripv6[PJ_INET6_ADDRSTRLEN];
     pj_status_t status;
+    unsigned flag = (ept->cfg.client_flag)?ept->cfg.client_flag:CLIENT_IPV4;
 
     status = pj_gethostip(pj_AF_INET(), &hostip);
@@ -138,5 +199,13 @@
 	return -1030;
 
-    pj_sockaddr_print(&hostip, serverip, sizeof(serverip), 0);
+    pj_sockaddr_print(&hostip, serveripv4, sizeof(serveripv4), 0);
+
+    if (flag & CLIENT_IPV6) {
+	status = pj_gethostip(pj_AF_INET6(), &hostip);    
+	if (status != PJ_SUCCESS)
+	    return -1031;
+
+	pj_sockaddr_print(&hostip, serveripv6, sizeof(serveripv6), 0);
+    }
 
     /* Init callback structure */
@@ -151,37 +220,10 @@
 	ice_cfg.resolver = test_sess->resolver;
 
-    if (ept->cfg.enable_stun & YES) {
-	if ((ept->cfg.enable_stun & SRV) == SRV) {
-	    ice_cfg.stun.server = pj_str(SRV_DOMAIN);
-	} else {
-	    ice_cfg.stun.server = pj_str(serverip);
-	}
-	ice_cfg.stun.port = STUN_SERVER_PORT;
-    }
-
-    if (ept->cfg.enable_host == 0) {
-	ice_cfg.stun.max_host_cands = 0;
-    } else {
-	//ice_cfg.stun.no_host_cands = PJ_FALSE;
-	ice_cfg.stun.loop_addr = PJ_TRUE;
-    }
-
-
-    if (ept->cfg.enable_turn & YES) {
-	if ((ept->cfg.enable_turn & SRV) == SRV) {
-	    ice_cfg.turn.server = pj_str(SRV_DOMAIN);
-	} else {
-	    ice_cfg.turn.server = pj_str(serverip);
-	}
-	ice_cfg.turn.port = TURN_SERVER_PORT;
-	ice_cfg.turn.conn_type = PJ_TURN_TP_UDP;
-	ice_cfg.turn.auth_cred.type = PJ_STUN_AUTH_CRED_STATIC;
-	ice_cfg.turn.auth_cred.data.static_cred.realm = pj_str(SRV_DOMAIN);
-	if (ept->cfg.client_flag & WRONG_TURN)
-	    ice_cfg.turn.auth_cred.data.static_cred.username = pj_str("xxx");
-	else
-	    ice_cfg.turn.auth_cred.data.static_cred.username = pj_str(TURN_USERNAME);
-	ice_cfg.turn.auth_cred.data.static_cred.data_type = PJ_STUN_PASSWD_PLAIN;
-	ice_cfg.turn.auth_cred.data.static_cred.data = pj_str(TURN_PASSWD);
+    if (flag & CLIENT_IPV4) {
+	set_stun_turn_cfg(ept, &ice_cfg, serveripv4, PJ_FALSE);
+    }
+
+    if (flag & CLIENT_IPV6) {
+	set_stun_turn_cfg(ept, &ice_cfg, serveripv6, PJ_TRUE);
     }
 
@@ -216,5 +258,5 @@
     pj_uint16_t ns_port;
     unsigned flags;
-    pj_status_t status;
+    pj_status_t status = PJ_SUCCESS;
 
     /* Create session structure */
@@ -233,5 +275,14 @@
     /* Create server */
     flags = server_flag;
-    status = create_test_server(stun_cfg, flags, SRV_DOMAIN, &sess->server);
+    if (flags & SERVER_IPV4) {
+	status = create_test_server(stun_cfg, (flags & ~SERVER_IPV6), 
+				    SRV_DOMAIN, &sess->server1);
+    }
+
+    if ((status == PJ_SUCCESS) && (flags & SERVER_IPV6)) {
+	status = create_test_server(stun_cfg, (flags & ~SERVER_IPV4), 
+				    SRV_DOMAIN, &sess->server2);
+    }
+
     if (status != PJ_SUCCESS) {
 	app_perror(INDENT "error: create_test_server()", status);
@@ -239,23 +290,36 @@
 	return -10;
     }
-    sess->server->turn_respond_allocate =
-	sess->server->turn_respond_refresh = PJ_TRUE;
+    if (flags & SERVER_IPV4) {
+	sess->server1->turn_respond_allocate =
+	    sess->server1->turn_respond_refresh = PJ_TRUE;
+    }
+
+    if (flags & SERVER_IPV6) {
+	sess->server2->turn_respond_allocate =
+	    sess->server2->turn_respond_refresh = PJ_TRUE;
+    }
 
     /* Create resolver */
-    status = pj_dns_resolver_create(mem, NULL, 0, stun_cfg->timer_heap,
-				    stun_cfg->ioqueue, &sess->resolver);
-    if (status != PJ_SUCCESS) {
-	app_perror(INDENT "error: pj_dns_resolver_create()", status);
-	destroy_sess(sess, 500);
-	return -20;
-    }
-
-    ns_ip = pj_str("127.0.0.1");
-    ns_port = (pj_uint16_t)DNS_SERVER_PORT;
-    status = pj_dns_resolver_set_ns(sess->resolver, 1, &ns_ip, &ns_port);
-    if (status != PJ_SUCCESS) {
-	app_perror( INDENT "error: pj_dns_resolver_set_ns()", status);
-	destroy_sess(sess, 500);
-	return -21;
+    if ((sess->callee.cfg.enable_stun & SRV)==SRV || 
+	(sess->callee.cfg.enable_turn & SRV)==SRV ||
+	(sess->caller.cfg.enable_stun & SRV)==SRV || 
+	(sess->caller.cfg.enable_turn & SRV)==SRV) 
+    {
+	status = pj_dns_resolver_create(mem, NULL, 0, stun_cfg->timer_heap,
+					stun_cfg->ioqueue, &sess->resolver);
+	if (status != PJ_SUCCESS) {
+	    app_perror(INDENT "error: pj_dns_resolver_create()", status);
+	    destroy_sess(sess, 500);
+	    return -20;
+	}
+
+	ns_ip =  (flags & SERVER_IPV6)?pj_str("::1"):pj_str("127.0.0.1");
+	ns_port = (pj_uint16_t)DNS_SERVER_PORT;
+	status = pj_dns_resolver_set_ns(sess->resolver, 1, &ns_ip, &ns_port);
+	if (status != PJ_SUCCESS) {
+	    app_perror(INDENT "error: pj_dns_resolver_set_ns()", status);
+	    destroy_sess(sess, 500);
+	    return -21;
+	}
     }
 
@@ -306,7 +370,12 @@
     }
 
-    if (sess->server) {
-	destroy_test_server(sess->server);
-	sess->server = NULL;
+    if (sess->server1) {
+	destroy_test_server(sess->server1);
+	sess->server1 = NULL;
+    }
+
+    if (sess->server2) {
+	destroy_test_server(sess->server2);
+	sess->server2 = NULL;
     }
 
@@ -385,10 +454,11 @@
     status = pj_ice_strans_start_ice(ept->ice, &remote->ufrag, &remote->pass,
 				     rcand_cnt, rcand);
-    if (status != PJ_SUCCESS) {
+
+    if (status != ept->cfg.expected.start_status) {
 	app_perror(INDENT "err: pj_ice_strans_start_ice()", status);
 	return status;
     }
 
-    return PJ_SUCCESS;
+    return status;
 }
 
@@ -499,10 +569,23 @@
     unsigned i;
     int rc;
-
-    PJ_LOG(3,(THIS_FILE, INDENT "%s", title));
+    char add_title1[16];
+    char add_title2[16];
+    pj_bool_t client_mix_test = ((callee_cfg->client_flag &
+				 (CLIENT_IPV4+CLIENT_IPV6)) !=
+				 (caller_cfg->client_flag &
+				 (CLIENT_IPV4+CLIENT_IPV6)));
+
+    sprintf(add_title1, "%s%s%s", (server_flag & SERVER_IPV4)?"IPv4":"", 
+	    ((server_flag & SERVER_IPV4)&&(server_flag & SERVER_IPV6))?"+":"",
+	    (server_flag & SERVER_IPV6)?"IPv6":"");
+    
+    sprintf(add_title2, "%s", client_mix_test?"Mix test":"");
+
+    PJ_LOG(3,(THIS_FILE, INDENT "%s (%s) %s", title, add_title1, add_title2));
 
     capture_pjlib_state(stun_cfg, &pjlib_state);
 
-    rc = create_sess(stun_cfg, server_flag, caller_cfg, callee_cfg, test_param, &sess);
+    rc = create_sess(stun_cfg, server_flag, caller_cfg, callee_cfg, test_param,
+		     &sess);
     if (rc != 0)
 	return rc;
@@ -558,6 +641,7 @@
     rc = start_ice(&sess->callee, &sess->caller);
     if (rc != PJ_SUCCESS) {
-	destroy_sess(sess, 500);
-	return -120;
+	int retval = (rc == sess->callee.cfg.expected.start_status)?0:-120;
+	destroy_sess(sess, 500);	
+	return retval;
     }
     /* Wait for callee's answer_delay */
@@ -566,6 +650,7 @@
     rc = start_ice(&sess->caller, &sess->callee);
     if (rc != PJ_SUCCESS) {
-	destroy_sess(sess, 500);
-	return -130;
+	int retval = (rc == sess->caller.cfg.expected.start_status)?0:-130;
+	destroy_sess(sess, 500);
+	return retval;
     }
 
@@ -664,4 +749,21 @@
 }
 
+static void set_client_server_flag(unsigned server_flag,
+				   unsigned caller_flag,
+				   unsigned callee_flag,
+				   unsigned *res_server_flag,
+				   unsigned *res_caller_flag,
+				   unsigned *res_callee_flag)
+{
+    enum {
+	RST_CLT_FLAG = CLIENT_IPV4+CLIENT_IPV6,
+	RST_SRV_FLAG = SERVER_IPV4+SERVER_IPV6
+    };
+
+    *res_server_flag = (*res_server_flag & ~RST_SRV_FLAG) | server_flag;
+    *res_caller_flag = (*res_caller_flag & ~RST_CLT_FLAG) | caller_flag;
+    *res_callee_flag = (*res_callee_flag & ~RST_CLT_FLAG) | callee_flag;
+}
+
 static int perform_test(const char *title,
                         pj_stun_config *stun_cfg,
@@ -671,8 +773,65 @@
 {
     struct sess_param test_param;
+    int rc;
+    int expected_caller_start_ice = caller_cfg->expected.start_status;
+    int expected_callee_start_ice = callee_cfg->expected.start_status;
+
+    set_client_server_flag(SERVER_IPV4, CLIENT_IPV4, CLIENT_IPV4,
+			   &server_flag, &caller_cfg->client_flag, 
+			   &callee_cfg->client_flag);
+
 
     pj_bzero(&test_param, sizeof(test_param));
-    return perform_test2(title, stun_cfg, server_flag, caller_cfg,
-                         callee_cfg, &test_param);
+
+    rc = perform_test2(title, stun_cfg, server_flag, caller_cfg,
+		       callee_cfg, &test_param);
+
+#if USE_IPV6
+    /* Test for IPV6. */
+    if (rc == PJ_SUCCESS) {
+	pj_bzero(&test_param, sizeof(test_param));
+	set_client_server_flag(SERVER_IPV6, CLIENT_IPV6, CLIENT_IPV6,
+			       &server_flag, &caller_cfg->client_flag,
+			       &callee_cfg->client_flag);
+
+	rc = perform_test2(title, stun_cfg, server_flag, caller_cfg,
+			   callee_cfg, &test_param);
+    }
+
+    /* Test for IPV4+IPV6. */
+    if (rc == PJ_SUCCESS) {
+	pj_bzero(&test_param, sizeof(test_param));
+	set_client_server_flag(SERVER_IPV4+SERVER_IPV6, 
+			       CLIENT_IPV4+CLIENT_IPV6,
+			       CLIENT_IPV4+CLIENT_IPV6, 
+			       &server_flag,
+			       &caller_cfg->client_flag, 
+			       &callee_cfg->client_flag);
+
+	rc = perform_test2(title, stun_cfg, server_flag, caller_cfg,
+			   callee_cfg, &test_param);
+    }
+
+    /* Test controller(IPV4) vs controlled(IPV6). */
+    if (rc == PJ_SUCCESS) {
+	pj_bzero(&test_param, sizeof(test_param));
+	set_client_server_flag(SERVER_IPV4+SERVER_IPV6, 
+			       CLIENT_IPV4,
+			       CLIENT_IPV6, 
+			       &server_flag,
+			       &caller_cfg->client_flag, 
+			       &callee_cfg->client_flag);
+	caller_cfg->expected.start_status = PJ_ENOTFOUND;
+	callee_cfg->expected.start_status = PJ_ENOTFOUND;
+
+	rc = perform_test2(title, stun_cfg, server_flag, caller_cfg,
+			   callee_cfg, &test_param);
+    }
+
+#endif
+    callee_cfg->expected.start_status = expected_callee_start_ice;
+    caller_cfg->expected.start_status = expected_caller_start_ice;
+
+    return rc;
 }
 
@@ -696,37 +855,37 @@
 	{
 	    "hosts candidates only",
-	    0xFFFF,
-	    {ROLE1, 1,	    YES,    NO,	    NO,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}},
-	    {ROLE2, 1,	    YES,    NO,	    NO,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}}
+	    0x1FFF,
+	    {ROLE1, 1,	    YES,    NO,	    NO,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}},
+	    {ROLE2, 1,	    YES,    NO,	    NO,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}}
 	},
 	{
 	    "host and srflxes",
-	    0xFFFF,
-	    {ROLE1, 1,	    YES,    YES,    NO,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}},
-	    {ROLE2, 1,	    YES,    YES,    NO,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}}
+	    0x1FFF,
+	    {ROLE1, 1,	    YES,    YES,    NO,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}},
+	    {ROLE2, 1,	    YES,    YES,    NO,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}}
 	},
 	{
 	    "host vs relay",
-	    0xFFFF,
-	    {ROLE1, 1,	    YES,    NO,    NO,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}},
-	    {ROLE2, 1,	    NO,     NO,    YES,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}}
+	    0x1FFF,
+	    {ROLE1, 1,	    YES,    NO,    NO,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}},
+	    {ROLE2, 1,	    NO,     NO,    YES,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}}
 	},
 	{
 	    "relay vs host",
-	    0xFFFF,
-	    {ROLE1, 1,	    NO,	    NO,   YES,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}},
-	    {ROLE2, 1,	   YES,     NO,    NO,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}}
+	    0x1FFF,
+	    {ROLE1, 1,	    NO,	    NO,   YES,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}},
+	    {ROLE2, 1,	   YES,     NO,    NO,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}}
 	},
 	{
 	    "relay vs relay",
-	    0xFFFF,
-	    {ROLE1, 1,	    NO,	    NO,   YES,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}},
-	    {ROLE2, 1,	    NO,     NO,   YES,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}}
+	    0x1FFF,
+	    {ROLE1, 1,	    NO,	    NO,   YES,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}},
+	    {ROLE2, 1,	    NO,     NO,   YES,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}}
 	},
 	{
 	    "all candidates",
-	    0xFFFF,
-	    {ROLE1, 1,	   YES,	   YES,   YES,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}},
-	    {ROLE2, 1,	   YES,    YES,   YES,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}}
+	    0x1FFF,
+	    {ROLE1, 1,	   YES,	   YES,   YES,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}},
+	    {ROLE2, 1,	   YES,    YES,   YES,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}}
 	},
     };
@@ -746,6 +905,6 @@
 	    0x0,
 	    /*  Role    comp#   host?   stun?   turn?   flag?  ans_del snd_del des_del */
-	    {ROLE1,	1,	YES,     NO,	    NO,	    0,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}},
-	    {ROLE2,	1,	YES,     NO,	    NO,	    0,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}}
+	    {ROLE1,	1,	YES,     NO,	    NO,	    0,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}},
+	    {ROLE2,	1,	YES,     NO,	    NO,	    0,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}}
 	};
 
@@ -771,6 +930,6 @@
 	    0xFFFF,
 	    /*  Role    comp#   host?   stun?   turn?   flag?  ans_del snd_del des_del */
-	    {ROLE1,	1,	YES,    YES,	    NO,	    0,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}},
-	    {ROLE2,	1,	YES,    YES,	    NO,	    0,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}}
+	    {ROLE1,	1,	YES,    YES,	    NO,	    0,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}},
+	    {ROLE2,	1,	YES,    YES,	    NO,	    0,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}}
 	};
 
@@ -797,6 +956,6 @@
 	    0xFFFF,
 	    /*  Role    comp#   host?   stun?   turn?   flag?  ans_del snd_del des_del */
-	    {ROLE1,	1,	 NO,     NO,	  YES,	    0,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}},
-	    {ROLE2,	1,	 NO,     NO,	  YES,	    0,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}}
+	    {ROLE1,	1,	 NO,     NO,	  YES,	    0,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}},
+	    {ROLE2,	1,	 NO,     NO,	  YES,	    0,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}}
 	};
 
@@ -823,6 +982,6 @@
 	    0x0,
 	    /*  Role    comp#   host?   stun?   turn?   flag?  ans_del snd_del des_del */
-	    {ROLE1,	2,	 NO,    YES,	    NO,	    0,	    0,	    0,	    0, {PJNATH_ESTUNTIMEDOUT, -1}},
-	    {ROLE2,	2,	 NO,    YES,	    NO,	    0,	    0,	    0,	    0, {PJNATH_ESTUNTIMEDOUT, -1}}
+	    {ROLE1,	2,	 NO,    YES,	    NO,	    0,	    0,	    0,	    0, {PJ_SUCCESS, PJNATH_ESTUNTIMEDOUT, -1}},
+	    {ROLE2,	2,	 NO,    YES,	    NO,	    0,	    0,	    0,	    0, {PJ_SUCCESS, PJNATH_ESTUNTIMEDOUT, -1}}
 	};
 
@@ -849,6 +1008,6 @@
 	    0xFFFF,
 	    /*  Role    comp#   host?   stun?   turn?   flag?  ans_del snd_del des_del */
-	    {ROLE1,	2,	 NO,    NO,	YES, WRONG_TURN,    0,	    0,	    0, {PJ_STATUS_FROM_STUN_CODE(401), -1}},
-	    {ROLE2,	2,	 NO,    NO,	YES, WRONG_TURN,    0,	    0,	    0, {PJ_STATUS_FROM_STUN_CODE(401), -1}}
+	    {ROLE1,	2,	 NO,    NO,	YES, WRONG_TURN,    0,	    0,	    0, {PJ_SUCCESS, PJ_STATUS_FROM_STUN_CODE(401), -1}},
+	    {ROLE2,	2,	 NO,    NO,	YES, WRONG_TURN,    0,	    0,	    0, {PJ_SUCCESS, PJ_STATUS_FROM_STUN_CODE(401), -1}}
 	};
 
@@ -876,6 +1035,6 @@
 	    0xFFFF & (~(CREATE_STUN_SERVER)),
 	    /*  Role    comp#   host?   stun?   turn?   flag?  ans_del snd_del des_del */
-	    {ROLE1,	1,	 YES,    YES,	YES,	0,    0,	    0,	    0, {PJNATH_ESTUNTIMEDOUT, -1}},
-	    {ROLE2,	1,	 YES,    YES,	YES,	0,    0,	    0,	    0, {PJNATH_ESTUNTIMEDOUT, -1}}
+	    {ROLE1,	1,	 YES,    YES,	YES,	0,    0,	    0,	    0, {PJ_SUCCESS, PJNATH_ESTUNTIMEDOUT, -1}},
+	    {ROLE2,	1,	 YES,    YES,	YES,	0,    0,	    0,	    0, {PJ_SUCCESS, PJNATH_ESTUNTIMEDOUT, -1}}
 	};
 
@@ -970,8 +1129,8 @@
     {
 	"Concurrency test",
-	0xFFFF,
+	0x1FFF,
 	/*  Role    comp#   host?   stun?   turn?   flag?  ans_del snd_del des_del */
-	{ROLE1,	1,	YES,     YES,	    YES,    0,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}},
-	{ROLE2,	1,	YES,     YES,	    YES,    0,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}}
+	{ROLE1,	1,	YES,     YES,	    YES,    CLIENT_IPV4,    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}},
+	{ROLE2,	1,	YES,     YES,	    YES,    CLIENT_IPV4,    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}}
     };
     struct sess_param test_param;
Index: pjproject/trunk/pjnath/src/pjnath-test/server.c
===================================================================
--- pjproject/trunk/pjnath/src/pjnath-test/server.c	(revision 5349)
+++ pjproject/trunk/pjnath/src/pjnath-test/server.c	(revision 5350)
@@ -54,8 +54,9 @@
     char strbuf[100];
     pj_status_t status;
+    pj_bool_t use_ipv6 = flags & SERVER_IPV6;
 
     PJ_ASSERT_RETURN(stun_cfg && domain && p_test_srv, PJ_EINVAL);
 
-    status = pj_gethostip(pj_AF_INET(), &hostip);
+    status = pj_gethostip(GET_AF(use_ipv6), &hostip);
     if (status != PJ_SUCCESS)
 	return status;
@@ -75,5 +76,5 @@
     if (flags & CREATE_DNS_SERVER) {
 	status = pj_dns_server_create(mem, test_srv->stun_cfg->ioqueue,
-				      pj_AF_INET(), DNS_SERVER_PORT,
+				      GET_AF(use_ipv6), DNS_SERVER_PORT,
 				      0, &test_srv->dns_server);
 	if (status != PJ_SUCCESS) {
@@ -86,9 +87,15 @@
 	    pj_dns_parsed_rr rr;
 	    pj_str_t res_name;
-	    pj_in_addr ip_addr;
 
 	    pj_strdup2(pool, &res_name, domain);
-	    ip_addr = hostip.ipv4.sin_addr;
-	    pj_dns_init_a_rr(&rr, &res_name, PJ_DNS_CLASS_IN, 60, &ip_addr);
+
+	    if (use_ipv6) {
+		pj_dns_init_aaaa_rr(&rr, &res_name, PJ_DNS_CLASS_IN, 60, 
+				    &hostip.ipv6.sin6_addr);
+	    } else {		
+		pj_dns_init_a_rr(&rr, &res_name, PJ_DNS_CLASS_IN, 60, 
+				 &hostip.ipv4.sin_addr);
+	    }
+	    
 	    pj_dns_server_add_rec(test_srv->dns_server, 1, &rr);
 	}
@@ -103,5 +110,6 @@
 	stun_sock_cb.on_data_recvfrom = &stun_on_data_recvfrom;
 
-	pj_sockaddr_in_init(&bound_addr.ipv4, NULL, STUN_SERVER_PORT);
+	pj_sockaddr_init(GET_AF(use_ipv6), &bound_addr, 
+			 NULL, STUN_SERVER_PORT);
 
 	status = pj_activesock_create_udp(pool, &bound_addr, NULL, 
@@ -124,5 +132,4 @@
 	    pj_str_t res_name, target;
 	    pj_dns_parsed_rr rr;
-	    pj_in_addr ip_addr;
 
 	    /* Add DNS entries:
@@ -141,6 +148,11 @@
 
 	    res_name = target;
-	    ip_addr = hostip.ipv4.sin_addr;
-	    pj_dns_init_a_rr(&rr, &res_name, PJ_DNS_CLASS_IN, 60, &ip_addr);
+	    if (use_ipv6) {		
+		pj_dns_init_aaaa_rr(&rr, &res_name, PJ_DNS_CLASS_IN, 60, 
+				    &hostip.ipv6.sin6_addr);
+	    } else {		
+		pj_dns_init_a_rr(&rr, &res_name, PJ_DNS_CLASS_IN, 60, 
+				 &hostip.ipv4.sin_addr);
+	    }
 	    pj_dns_server_add_rec(test_srv->dns_server, 1, &rr);
 	}
@@ -155,5 +167,5 @@
 	turn_sock_cb.on_data_recvfrom = &turn_on_data_recvfrom;
 
-	pj_sockaddr_in_init(&bound_addr.ipv4, NULL, TURN_SERVER_PORT);
+	pj_sockaddr_init(GET_AF(use_ipv6), &bound_addr, NULL, TURN_SERVER_PORT);
 
 	status = pj_activesock_create_udp(pool, &bound_addr, NULL, 
@@ -176,5 +188,4 @@
 	    pj_str_t res_name, target;
 	    pj_dns_parsed_rr rr;
-	    pj_in_addr ip_addr;
 
 	    /* Add DNS entries:
@@ -193,6 +204,12 @@
 
 	    res_name = target;
-	    ip_addr = hostip.ipv4.sin_addr;
-	    pj_dns_init_a_rr(&rr, &res_name, PJ_DNS_CLASS_IN, 60, &ip_addr);
+	    
+	    if (use_ipv6) {		
+		pj_dns_init_aaaa_rr(&rr, &res_name, PJ_DNS_CLASS_IN, 60, 
+				    &hostip.ipv6.sin6_addr);
+	    } else {		
+		pj_dns_init_a_rr(&rr, &res_name, PJ_DNS_CLASS_IN, 60, 
+				 &hostip.ipv4.sin_addr);
+	    }
 	    pj_dns_server_add_rec(test_srv->dns_server, 1, &rr);
 	}
@@ -345,4 +362,5 @@
     unsigned i;
     pj_ssize_t len;
+    pj_bool_t use_ipv6 = PJ_FALSE;
 
     if (status != PJ_SUCCESS)
@@ -352,4 +370,5 @@
 
     test_srv = (test_server*) pj_activesock_get_user_data(asock);
+    use_ipv6 = test_srv->flags & SERVER_IPV6;
     pool = pj_pool_create(test_srv->stun_cfg->pf, NULL, 512, 512, NULL);
 
@@ -481,7 +500,7 @@
 	alloc->pool = pj_pool_create(test_srv->stun_cfg->pf, "alloc", 512, 512, NULL);
 
-	/* Create relay socket */
-	pj_sockaddr_in_init(&alloc->alloc_addr.ipv4, NULL, 0);
-	pj_gethostip(pj_AF_INET(), &alloc->alloc_addr);
+	/* Create relay socket */	
+	pj_sockaddr_init(GET_AF(use_ipv6), &alloc->alloc_addr, NULL, 0);
+	pj_gethostip(GET_AF(use_ipv6), &alloc->alloc_addr);
 
 	status = pj_activesock_create_udp(alloc->pool, &alloc->alloc_addr, NULL, 
@@ -698,4 +717,6 @@
     unsigned i;
 
+    PJ_UNUSED_ARG(addr_len);
+
     if (status != PJ_SUCCESS)
 	return PJ_TRUE;
@@ -708,8 +729,5 @@
     /* Check that this peer has a permission */
     for (i=0; i<alloc->perm_cnt; ++i) {
-	if (pj_sockaddr_get_len(&alloc->perm[i]) == (unsigned)addr_len &&
-	    pj_memcmp(pj_sockaddr_get_addr(&alloc->perm[i]),
-		      pj_sockaddr_get_addr(src_addr),
-		      addr_len) == 0)
+	if (pj_sockaddr_cmp(&alloc->perm[i], src_addr) == 0)
 	{
 	    break;
Index: pjproject/trunk/pjnath/src/pjnath-test/server.h
===================================================================
--- pjproject/trunk/pjnath/src/pjnath-test/server.h	(revision 5349)
+++ pjproject/trunk/pjnath/src/pjnath-test/server.h	(revision 5350)
@@ -40,10 +40,12 @@
     CREATE_A_RECORD_FOR_DOMAIN	= (1 << 1),
 
-    CREATE_STUN_SERVER		= (1 << 5),
-    CREATE_STUN_SERVER_DNS_SRV	= (1 << 6),
+    CREATE_STUN_SERVER		= (1 << 4),
+    CREATE_STUN_SERVER_DNS_SRV	= (1 << 5),
 
-    CREATE_TURN_SERVER		= (1 << 10),
-    CREATE_TURN_SERVER_DNS_SRV	= (1 << 11),
+    CREATE_TURN_SERVER		= (1 << 8),
+    CREATE_TURN_SERVER_DNS_SRV	= (1 << 9),
 
+    SERVER_IPV4			= (1 << 12),
+    SERVER_IPV6			= (1 << 13)
 };
 
Index: pjproject/trunk/pjnath/src/pjnath-test/sess_auth.c
===================================================================
--- pjproject/trunk/pjnath/src/pjnath-test/sess_auth.c	(revision 5349)
+++ pjproject/trunk/pjnath/src/pjnath-test/sess_auth.c	(revision 5350)
@@ -230,5 +230,6 @@
 /* Instantiate standard server */
 static int create_std_server(pj_stun_auth_type auth_type,
-			     pj_bool_t responding)
+			     pj_bool_t responding,
+			     pj_bool_t use_ipv6)
 {
     pj_pool_t *pool;
@@ -267,5 +268,5 @@
 
     /* Create socket */
-    status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &server->sock);
+    status = pj_sock_socket(GET_AF(use_ipv6), pj_SOCK_DGRAM(), 0, &server->sock);
     if (status != PJ_SUCCESS) {
 	destroy_server();
@@ -274,5 +275,5 @@
 
     /* Bind */
-    pj_sockaddr_in_init(&server->addr.ipv4, NULL, 0);
+    pj_sockaddr_init(GET_AF(use_ipv6), &server->addr, NULL, 0);
     status = pj_sock_bind(server->sock, &server->addr, pj_sockaddr_get_len(&server->addr));
     if (status != PJ_SUCCESS) {
@@ -290,5 +291,5 @@
 	}
 
-	status = pj_gethostip(pj_AF_INET(), &addr);
+	status = pj_gethostip(GET_AF(use_ipv6), &addr);
 	if (status != PJ_SUCCESS) {
 	    destroy_server();
@@ -453,5 +454,5 @@
 			   const char *password,
 			   pj_bool_t dummy_mi,
-
+			   pj_bool_t use_ipv6,
 			   pj_bool_t expected_error,
 			   pj_status_t expected_code,
@@ -466,7 +467,8 @@
     pj_stun_tx_data *tdata;
     pj_status_t status;
+    pj_sockaddr addr;
     int rc = 0;
     
-    PJ_LOG(3,(THIS_FILE, "   %s test", title));
+    PJ_LOG(3,(THIS_FILE, "   %s test (%s)", title, use_ipv6?"IPv6":"IPv4"));
 
     /* Create client */
@@ -494,5 +496,5 @@
 
     /* Create client socket */
-    status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &client->sock);
+    status = pj_sock_socket(GET_AF(use_ipv6), pj_SOCK_DGRAM(), 0, &client->sock);
     if (status != PJ_SUCCESS) {
 	destroy_client_server();
@@ -501,5 +503,6 @@
 
     /* Bind client socket */
-    status = pj_sock_bind_in(client->sock, 0, 0);
+    pj_sockaddr_init(GET_AF(use_ipv6), &addr, NULL, 0);
+    status = pj_sock_bind(client->sock, &addr, pj_sockaddr_get_len(&addr));
     if (status != PJ_SUCCESS) {
 	destroy_client_server();
@@ -529,5 +532,5 @@
 
     /* Create the server */
-    status = create_std_server(server_auth_type, server_responding);
+    status = create_std_server(server_auth_type, server_responding, use_ipv6);
     if (status != 0) {
 	destroy_client_server();
@@ -681,4 +684,24 @@
 done:
     destroy_client_server();
+
+    /* If IPv6 is enabled, test again for IPv4. */
+    if ((rc == 0) && use_ipv6) {
+	rc = run_client_test(title,
+			     server_responding,
+			     server_auth_type,
+			     client_auth_type,
+			     realm,
+			     username,
+			     nonce,
+			     password,
+			     dummy_mi,
+			     0,
+			     expected_error,
+			     expected_code,
+			     expected_realm,
+			     expected_nonce,
+			     more_check);
+    }
+
     return rc;
 }
@@ -779,4 +802,5 @@
 			 NULL,		    // password
 			 PJ_FALSE,	    // dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_TRUE,	    // expected error
 			 PJNATH_ESTUNTIMEDOUT,// expected code
@@ -809,4 +833,5 @@
 			 NULL,		    // password
 			 PJ_FALSE,	    // dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_TRUE,	    // expected error
 			 PJ_STATUS_FROM_STUN_CODE(400),// expected code
@@ -833,4 +858,5 @@
 			 "anotherpass",	    // password
 			 PJ_FALSE,	    // dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_TRUE,	    // expected error
 			 PJ_STATUS_FROM_STUN_CODE(401),// expected code
@@ -861,4 +887,5 @@
 			 "anotherpass",	    // password
 			 PJ_FALSE,	    // dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_TRUE,	    // expected error
 			 PJ_STATUS_FROM_STUN_CODE(401),// expected code
@@ -883,4 +910,5 @@
 			 NULL,		    // password
 			 PJ_TRUE,	    // dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_TRUE,	    // expected error
 			 PJ_STATUS_FROM_STUN_CODE(400),	    // expected code
@@ -903,4 +931,5 @@
 			 PASSWORD,	    // password
 			 PJ_FALSE,	    // dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_FALSE,	    // expected error
 			 PJ_SUCCESS,	    // expected code
@@ -929,4 +958,5 @@
 			 PASSWORD,	    // password
 			 PJ_TRUE,	    // dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_TRUE,	    // expected error
 			 PJ_STATUS_FROM_STUN_CODE(401),	    // expected code
@@ -962,4 +992,5 @@
 			 NULL,		    // client password
 			 PJ_FALSE,	    // client dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_TRUE,	    // expected error
 			 PJ_STATUS_FROM_STUN_CODE(401), // expected code
@@ -988,4 +1019,5 @@
 			 PASSWORD,	    // client password
 			 PJ_TRUE,	    // client dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_TRUE,	    // expected error
 			 PJ_STATUS_FROM_STUN_CODE(400), // expected code
@@ -1008,4 +1040,5 @@
 			 PASSWORD,	    // client password
 			 PJ_TRUE,	    // client dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_TRUE,	    // expected error
 			 PJ_STATUS_FROM_STUN_CODE(400), // expected code
@@ -1028,4 +1061,5 @@
 			 PASSWORD,	    // client password
 			 PJ_TRUE,	    // client dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_TRUE,	    // expected error
 			 PJ_STATUS_FROM_STUN_CODE(400), // expected code
@@ -1064,4 +1098,5 @@
 			 "somepassword",    // client password
 			 PJ_FALSE,	    // client dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_TRUE,	    // expected error
 			 PJ_STATUS_FROM_STUN_CODE(401), // expected code
@@ -1084,4 +1119,5 @@
 			 PASSWORD,	    // client password
 			 PJ_FALSE,	    // client dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_FALSE,	    // expected error
 			 0,		    // expected code
@@ -1114,4 +1150,5 @@
 			 PASSWORD,	    // client password
 			 PJ_FALSE,	    // client dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_TRUE,	    // expected error
 			 PJ_STATUS_FROM_STUN_CODE(401), // expected code
Index: pjproject/trunk/pjnath/src/pjnath-test/stun_sock_test.c
===================================================================
--- pjproject/trunk/pjnath/src/pjnath-test/stun_sock_test.c	(revision 5349)
+++ pjproject/trunk/pjnath/src/pjnath-test/stun_sock_test.c	(revision 5350)
@@ -90,13 +90,19 @@
 	/* Add MAPPED-ADDRESS or XOR-MAPPED-ADDRESS (or don't add) */
 	if (srv->flag & WITH_MAPPED) {
-	    pj_sockaddr_in addr;
-
-	    pj_sockaddr_in_init(&addr, &srv->ip_to_send, srv->port_to_send);
+	    pj_sockaddr addr;
+	    pj_bool_t use_ipv6 = (srv->addr.addr.sa_family == pj_AF_INET6());
+	    
+	    pj_sockaddr_init(GET_AF(use_ipv6), &addr, &srv->ip_to_send, 
+			     srv->port_to_send);
+
 	    pj_stun_msg_add_sockaddr_attr(pool, res_msg, PJ_STUN_ATTR_MAPPED_ADDR,
 					  PJ_FALSE, &addr, sizeof(addr));
 	} else if (srv->flag & WITH_XOR_MAPPED) {
-	    pj_sockaddr_in addr;
-
-	    pj_sockaddr_in_init(&addr, &srv->ip_to_send, srv->port_to_send);
+	    pj_sockaddr addr;
+	    pj_bool_t use_ipv6 = (srv->addr.addr.sa_family == pj_AF_INET6());
+	    
+	    pj_sockaddr_init(GET_AF(use_ipv6), &addr, &srv->ip_to_send, 
+			     srv->port_to_send);
+
 	    pj_stun_msg_add_sockaddr_attr(pool, res_msg, 
 					  PJ_STUN_ATTR_XOR_MAPPED_ADDR,
@@ -134,4 +140,5 @@
 				 pj_ioqueue_t *ioqueue,
 				 unsigned flag,
+				 pj_bool_t use_ipv6,
 				 struct stun_srv **p_srv)
 {
@@ -142,8 +149,8 @@
     srv = PJ_POOL_ZALLOC_T(pool, struct stun_srv);
     srv->flag = flag;
-    srv->ip_to_send = pj_str("1.1.1.1");
+    srv->ip_to_send = (use_ipv6)?pj_str("2002:101:101::"):pj_str("1.1.1.1");
     srv->port_to_send = 1000;
 
-    status = pj_sockaddr_in_init(&srv->addr.ipv4, NULL, 0);
+    status = pj_sockaddr_init(GET_AF(use_ipv6), &srv->addr, NULL, 0);
     if (status != PJ_SUCCESS)
 	return status;
@@ -231,5 +238,6 @@
 static pj_status_t create_client(pj_stun_config *cfg,
 				 struct stun_client **p_client,
-				 pj_bool_t destroy_on_err)
+				 pj_bool_t destroy_on_err,
+				 pj_bool_t use_ipv6)
 {
     pj_pool_t *pool;
@@ -248,6 +256,6 @@
     cb.on_status = &stun_sock_on_status;
     cb.on_rx_data = &stun_sock_on_rx_data;
-    status = pj_stun_sock_create(cfg, NULL, pj_AF_INET(), &cb,
-				 &sock_cfg, client, &client->sock);
+    status = pj_stun_sock_create(cfg, NULL, GET_AF(use_ipv6), &cb, &sock_cfg, 
+				 client, &client->sock);
     if (status != PJ_SUCCESS) {
 	app_perror("   pj_stun_sock_create()", status);
@@ -293,5 +301,6 @@
  * Timeout test: scenario when no response is received from server
  */
-static int timeout_test(pj_stun_config *cfg, pj_bool_t destroy_on_err)
+static int timeout_test(pj_stun_config *cfg, pj_bool_t destroy_on_err, 
+			pj_bool_t use_ipv6)
 {
     struct stun_srv *srv;
@@ -302,11 +311,12 @@
     pj_status_t status;
 
-    PJ_LOG(3,(THIS_FILE, "  timeout test [%d]", destroy_on_err));
-
-    status =  create_client(cfg, &client, destroy_on_err);
+    PJ_LOG(3,(THIS_FILE, "  timeout test [%d] - (%s)", destroy_on_err, 
+	   (use_ipv6)?"IPv6":"IPv4"));
+
+    status =  create_client(cfg, &client, destroy_on_err, use_ipv6);
     if (status != PJ_SUCCESS)
 	return -10;
 
-    status = create_server(client->pool, cfg->ioqueue, 0, &srv);
+    status = create_server(client->pool, cfg->ioqueue, 0, use_ipv6, &srv);
     if (status != PJ_SUCCESS) {
 	destroy_client(client);
@@ -314,7 +324,8 @@
     }
 
-    srv_addr = pj_str("127.0.0.1");
+    srv_addr = (use_ipv6)?pj_str("::1"):pj_str("127.0.0.1");
+
     status = pj_stun_sock_start(client->sock, &srv_addr, 
-				pj_ntohs(srv->addr.ipv4.sin_port), NULL);
+				pj_sockaddr_get_port(&srv->addr), NULL);
     if (status != PJ_SUCCESS) {
 	destroy_server(srv);
@@ -362,4 +373,8 @@
     for (i=0; i<7; ++i)
 	handle_events(cfg, 100);
+
+    if ((ret == 0) && use_ipv6)
+	ret = timeout_test(cfg, destroy_on_err, 0);
+
     return ret;
 }
@@ -370,5 +385,6 @@
  * XOR-MAPPED-ADDRESS attribute.
  */
-static int missing_attr_test(pj_stun_config *cfg, pj_bool_t destroy_on_err)
+static int missing_attr_test(pj_stun_config *cfg, pj_bool_t destroy_on_err, 
+			     pj_bool_t use_ipv6)
 {
     struct stun_srv *srv;
@@ -379,19 +395,21 @@
     pj_status_t status;
 
-    PJ_LOG(3,(THIS_FILE, "  missing attribute test [%d]", destroy_on_err));
-
-    status =  create_client(cfg, &client, destroy_on_err);
+    PJ_LOG(3,(THIS_FILE, "  missing attribute test [%d] - (%s)", 
+	   destroy_on_err, (use_ipv6)?"IPv6":"IPv4"));
+
+    status =  create_client(cfg, &client, destroy_on_err, use_ipv6);
     if (status != PJ_SUCCESS)
 	return -110;
 
-    status = create_server(client->pool, cfg->ioqueue, RESPOND_STUN, &srv);
+    status = create_server(client->pool, cfg->ioqueue, RESPOND_STUN, use_ipv6, 
+			   &srv);
     if (status != PJ_SUCCESS) {
 	destroy_client(client);
 	return -120;
     }
-
-    srv_addr = pj_str("127.0.0.1");
+    srv_addr = (use_ipv6)?pj_str("::1"):pj_str("127.0.0.1");
+
     status = pj_stun_sock_start(client->sock, &srv_addr, 
-				pj_ntohs(srv->addr.ipv4.sin_port), NULL);
+				pj_sockaddr_get_port(&srv->addr), NULL);				
     if (status != PJ_SUCCESS) {
 	destroy_server(srv);
@@ -431,4 +449,8 @@
     for (i=0; i<7; ++i)
 	handle_events(cfg, 100);
+
+    if ((ret == 0) && use_ipv6)
+	ret = missing_attr_test(cfg, destroy_on_err, 0);
+
     return ret;
 }
@@ -437,9 +459,9 @@
  * Keep-alive test.
  */
-static int keep_alive_test(pj_stun_config *cfg)
+static int keep_alive_test(pj_stun_config *cfg, pj_bool_t use_ipv6)
 {
     struct stun_srv *srv;
     struct stun_client *client;
-    pj_sockaddr_in mapped_addr;
+    pj_sockaddr mapped_addr;
     pj_stun_sock_info info;
     pj_str_t srv_addr;
@@ -448,11 +470,13 @@
     pj_status_t status;
 
-    PJ_LOG(3,(THIS_FILE, "  normal operation"));
-
-    status =  create_client(cfg, &client, PJ_TRUE);
+    PJ_LOG(3,(THIS_FILE, "  normal operation - (%s)", 
+	   (use_ipv6)?"IPv6":"IPv4"));
+
+    status =  create_client(cfg, &client, PJ_TRUE, use_ipv6);
     if (status != PJ_SUCCESS)
 	return -310;
 
-    status = create_server(client->pool, cfg->ioqueue, RESPOND_STUN|WITH_XOR_MAPPED, &srv);
+    status = create_server(client->pool, cfg->ioqueue, RESPOND_STUN|WITH_XOR_MAPPED, 
+			   use_ipv6, &srv);
     if (status != PJ_SUCCESS) {
 	destroy_client(client);
@@ -464,7 +488,9 @@
      */
     PJ_LOG(3,(THIS_FILE, "    initial Binding request"));
-    srv_addr = pj_str("127.0.0.1");
+
+    srv_addr = (use_ipv6)?pj_str("::1"):pj_str("127.0.0.1");
+
     status = pj_stun_sock_start(client->sock, &srv_addr, 
-				pj_ntohs(srv->addr.ipv4.sin_port), NULL);
+				pj_sockaddr_get_port(&srv->addr), NULL);
     if (status != PJ_SUCCESS) {
 	destroy_server(srv);
@@ -522,5 +548,6 @@
     }
     /* verify the mapped address */
-    pj_sockaddr_in_init(&mapped_addr, &srv->ip_to_send, srv->port_to_send);
+    pj_sockaddr_init(GET_AF(use_ipv6), &mapped_addr, 
+		     &srv->ip_to_send, srv->port_to_send);
     if (pj_sockaddr_cmp(&info.mapped_addr, &mapped_addr) != 0) {
 	PJ_LOG(3,(THIS_FILE, "    error: mapped address mismatched"));
@@ -659,5 +686,5 @@
 
     /* Change mapped address in the response */
-    srv->ip_to_send = pj_str("2.2.2.2");
+    srv->ip_to_send = (use_ipv6)?pj_str("2002:202:202::"):pj_str("2.2.2.2");    
     srv->port_to_send++;
 
@@ -730,5 +757,6 @@
     }
     /* verify the mapped address */
-    pj_sockaddr_in_init(&mapped_addr, &srv->ip_to_send, srv->port_to_send);
+    pj_sockaddr_init(GET_AF(use_ipv6), &mapped_addr, 
+		     &srv->ip_to_send, srv->port_to_send);
     if (pj_sockaddr_cmp(&info.mapped_addr, &mapped_addr) != 0) {
 	PJ_LOG(3,(THIS_FILE, "    error: mapped address mismatched"));
@@ -798,4 +826,8 @@
     for (i=0; i<7; ++i)
 	handle_events(cfg, 100);
+
+    if ((ret == 0) && use_ipv6)
+	ret = keep_alive_test(cfg, 0);
+
     return ret;
 }
@@ -838,11 +870,11 @@
     pj_stun_config_init(&stun_cfg, mem, 0, ioqueue, timer_heap);
 
-    DO_TEST(timeout_test(&stun_cfg, PJ_FALSE));
-    DO_TEST(timeout_test(&stun_cfg, PJ_TRUE));
-
-    DO_TEST(missing_attr_test(&stun_cfg, PJ_FALSE));
-    DO_TEST(missing_attr_test(&stun_cfg, PJ_TRUE));
-
-    DO_TEST(keep_alive_test(&stun_cfg));
+    DO_TEST(timeout_test(&stun_cfg, PJ_FALSE, USE_IPV6));
+    DO_TEST(timeout_test(&stun_cfg, PJ_TRUE, USE_IPV6));
+
+    DO_TEST(missing_attr_test(&stun_cfg, PJ_FALSE, USE_IPV6));
+    DO_TEST(missing_attr_test(&stun_cfg, PJ_TRUE, USE_IPV6));
+
+    DO_TEST(keep_alive_test(&stun_cfg, USE_IPV6));
 
 on_return:
Index: pjproject/trunk/pjnath/src/pjnath-test/test.h
===================================================================
--- pjproject/trunk/pjnath/src/pjnath-test/test.h	(revision 5349)
+++ pjproject/trunk/pjnath/src/pjnath-test/test.h	(revision 5350)
@@ -27,4 +27,12 @@
 #define INCLUDE_TURN_SOCK_TEST	    1
 #define INCLUDE_CONCUR_TEST    	    1
+
+#define GET_AF(use_ipv6) (use_ipv6?pj_AF_INET6():pj_AF_INET())
+
+#if defined(PJ_HAS_IPV6) && PJ_HAS_IPV6
+#   define USE_IPV6	1
+#else
+#   define USE_IPV6	0
+#endif
 
 int stun_test(void);
Index: pjproject/trunk/pjnath/src/pjnath-test/turn_sock_test.c
===================================================================
--- pjproject/trunk/pjnath/src/pjnath-test/turn_sock_test.c	(revision 5349)
+++ pjproject/trunk/pjnath/src/pjnath-test/turn_sock_test.c	(revision 5350)
@@ -103,4 +103,5 @@
     pj_stun_auth_cred cred;
     pj_status_t status;
+    pj_bool_t use_ipv6 = cfg->srv.flags & SERVER_IPV6;
 
     /* Create client */
@@ -114,6 +115,11 @@
     turn_sock_cb.on_rx_data = &turn_on_rx_data;
     turn_sock_cb.on_state = &turn_on_state;
-    status = pj_turn_sock_create(sess->stun_cfg, pj_AF_INET(), PJ_TURN_TP_UDP,
-				 &turn_sock_cb, 0, sess, &sess->turn_sock);
+    status = pj_turn_sock_create(sess->stun_cfg,
+				 GET_AF(use_ipv6),
+				 PJ_TURN_TP_UDP, 
+				 &turn_sock_cb, 
+				 0, 
+				 sess, 
+				 &sess->turn_sock);
     if (status != PJ_SUCCESS) {
 	destroy_session(sess);
@@ -122,6 +128,6 @@
 
     /* Create test server */
-    status = create_test_server(sess->stun_cfg, cfg->srv.flags,
-				SRV_DOMAIN, &sess->test_srv);
+    status = create_test_server(sess->stun_cfg, cfg->srv.flags, SRV_DOMAIN, 
+				&sess->test_srv);
     if (status != PJ_SUCCESS) {
 	destroy_session(sess);
@@ -140,5 +146,5 @@
 
     } else {
-	pj_str_t dns_srv = pj_str("127.0.0.1");
+	pj_str_t dns_srv = use_ipv6?pj_str("::1") : pj_str("127.0.0.1");
 	pj_uint16_t dns_srv_port = (pj_uint16_t) DNS_SERVER_PORT;
 	status = pj_dns_resolver_set_ns(sess->resolver, 1, &dns_srv, &dns_srv_port);
@@ -171,5 +177,5 @@
     } else {
 	/* Explicitly specify server address */
-	pj_str_t host = pj_str("127.0.0.1");
+	pj_str_t host = use_ipv6?pj_str("::1") : pj_str("127.0.0.1");
 	status = pj_turn_sock_alloc(sess->turn_sock, &host, TURN_SERVER_PORT,
 				    NULL, &cred, &alloc_param);
@@ -251,11 +257,19 @@
 /////////////////////////////////////////////////////////////////////
 
-static int state_progression_test(pj_stun_config  *stun_cfg)
+static void set_server_flag(struct test_session_cfg *test_cfg, 
+			    pj_bool_t use_ipv6)
+{
+    test_cfg->srv.flags &= ~(SERVER_IPV4+SERVER_IPV6);
+    test_cfg->srv.flags |= (use_ipv6)?SERVER_IPV6:SERVER_IPV4;
+}
+
+static int state_progression_test(pj_stun_config  *stun_cfg, 
+				  pj_bool_t use_ipv6)
 {
     struct test_session_cfg test_cfg = 
     {
-	{   /* Client cfg */
-	    /* DNS SRV */   /* Destroy on state */
-	    PJ_TRUE,	    0xFFFF
+	{   /* Client cfg */			
+	    PJ_TRUE,	    /* DNS SRV */       
+	    0xFFFF	    /* Destroy on state */
 	},
 	{   /* Server cfg */
@@ -267,8 +281,9 @@
     struct test_session *sess;
     unsigned i;
-    int rc;
-
-    PJ_LOG(3,("", "  state progression tests"));
-
+    int rc = 0;
+
+    PJ_LOG(3,("", "  state progression tests - (%s)",use_ipv6?"IPv6":"IPv4"));
+    
+    set_server_flag(&test_cfg, use_ipv6);
     for (i=0; i<=1; ++i) {
 	enum { TIMEOUT = 60 };
@@ -373,5 +388,8 @@
     }
 
-    return 0;
+    if (use_ipv6)
+	rc = state_progression_test(stun_cfg, 0);
+
+    return rc;
 }
 
@@ -381,11 +399,12 @@
 static int destroy_test(pj_stun_config  *stun_cfg,
 			pj_bool_t with_dns_srv,
-			pj_bool_t in_callback)
+			pj_bool_t in_callback,
+			pj_bool_t use_ipv6)
 {
     struct test_session_cfg test_cfg = 
     {
-	{   /* Client cfg */
-	    /* DNS SRV */   /* Destroy on state */
-	    PJ_TRUE,	    0xFFFF
+	{   /* Client cfg */	    
+	    PJ_TRUE,	    /* DNS SRV */   
+	    0xFFFF	    /* Destroy on state */
 	},
 	{   /* Server cfg */
@@ -405,4 +424,5 @@
 
     test_cfg.client.enable_dns_srv = with_dns_srv;
+    set_server_flag(&test_cfg, use_ipv6);    
 
     for (target_state=PJ_TURN_STATE_RESOLVING; target_state<=PJ_TURN_STATE_READY; ++target_state) {
@@ -496,5 +516,5 @@
     }
 
-    rc = state_progression_test(&stun_cfg);
+    rc = state_progression_test(&stun_cfg, USE_IPV6);
     if (rc != 0) 
 	goto on_return;
@@ -503,5 +523,5 @@
 	int j;
 	for (j=0; j<=1; ++j) {
-	    rc = destroy_test(&stun_cfg, i, j);
+	    rc = destroy_test(&stun_cfg, i, j, USE_IPV6);
 	    if (rc != 0)
 		goto on_return;
Index: pjproject/trunk/pjnath/src/pjnath/stun_msg_dump.c
===================================================================
--- pjproject/trunk/pjnath/src/pjnath/stun_msg_dump.c	(revision 5349)
+++ pjproject/trunk/pjnath/src/pjnath/stun_msg_dump.c	(revision 5350)
@@ -89,17 +89,15 @@
 	    char addr[PJ_INET6_ADDRSTRLEN];
 	    const pj_stun_sockaddr_attr *attr;
+	    pj_uint16_t af;
 
 	    attr = (const pj_stun_sockaddr_attr*)ahdr;
-
-	    if (attr->sockaddr.addr.sa_family == pj_AF_INET()) {
+	    af = attr->sockaddr.addr.sa_family;
+
+	    if ((af == pj_AF_INET()) || (af == pj_AF_INET6())) {
 		len = pj_ansi_snprintf(p, end-p,
-				       ", IPv4 addr=%s:%d\n",
+				       ", %s addr=%s\n",
+				       (af == pj_AF_INET())?"IPv4":"IPv6",
 				       pj_sockaddr_print(&attr->sockaddr,
-				           		 addr, sizeof(addr),0),
-				       pj_sockaddr_get_port(&attr->sockaddr));
-
-	    } else if (attr->sockaddr.addr.sa_family == pj_AF_INET6()) {
-		len = pj_ansi_snprintf(p, end-p,
-				       ", IPv6 addr present\n");
+				           		addr, sizeof(addr),3));
 	    } else {
 		len = pj_ansi_snprintf(p, end-p,
