Index: pjproject/trunk/pjsip/src/pjsip/sip_transport_tls.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsip/sip_transport_tls.c	(revision 4259)
+++ pjproject/trunk/pjsip/src/pjsip/sip_transport_tls.c	(revision 4262)
@@ -56,4 +56,5 @@
     pjsip_tpmgr		    *tpmgr;
     pj_ssl_sock_t	    *ssock;
+    pj_sockaddr		     bound_addr;
     pj_ssl_cert_t	    *cert;
     pjsip_tls_setting	     tls_setting;
@@ -148,6 +149,6 @@
 			      pj_ssl_sock_t *ssock, 
 			      pj_bool_t is_server,
-			      const pj_sockaddr_in *local,
-			      const pj_sockaddr_in *remote,
+			      const pj_sockaddr *local,
+			      const pj_sockaddr *remote,
 			      const pj_str_t *remote_name,
 			      struct tls_transport **p_tls);
@@ -167,8 +168,8 @@
 static void sockaddr_to_host_port( pj_pool_t *pool,
 				   pjsip_host_port *host_port,
-				   const pj_sockaddr_in *addr )
+				   const pj_sockaddr *addr )
 {
     host_port->host.ptr = (char*) pj_pool_alloc(pool, PJ_INET6_ADDRSTRLEN+4);
-    pj_sockaddr_print(addr, host_port->host.ptr, PJ_INET6_ADDRSTRLEN+4, 2);
+    pj_sockaddr_print(addr, host_port->host.ptr, PJ_INET6_ADDRSTRLEN+4, 0);
     host_port->host.slen = pj_ansi_strlen(host_port->host.ptr);
     host_port->port = pj_sockaddr_get_port(addr);
@@ -236,13 +237,31 @@
 PJ_DEF(pj_status_t) pjsip_tls_transport_start (pjsip_endpoint *endpt,
 					       const pjsip_tls_setting *opt,
-					       const pj_sockaddr_in *local,
+					       const pj_sockaddr_in *local_in,
 					       const pjsip_host_port *a_name,
 					       unsigned async_cnt,
 					       pjsip_tpfactory **p_factory)
 {
+    pj_sockaddr local;
+
+    if (local_in)
+	pj_sockaddr_cp(&local, local_in);
+
+    return pjsip_tls_transport_start2(endpt, opt, (local_in? &local : NULL),
+                                      a_name, async_cnt, p_factory);
+}
+
+PJ_DEF(pj_status_t) pjsip_tls_transport_start2( pjsip_endpoint *endpt,
+ 					        const pjsip_tls_setting *opt,
+					        const pj_sockaddr *local,
+					        const pjsip_host_port *a_name,
+					        unsigned async_cnt,
+					        pjsip_tpfactory **p_factory)
+{
     pj_pool_t *pool;
+    pj_bool_t is_ipv6;
+    int af;
     struct tls_listener *listener;
     pj_ssl_sock_param ssock_param;
-    pj_sockaddr_in *listener_addr;
+    pj_sockaddr *listener_addr;
     pj_bool_t has_listener;
     pj_status_t status;
@@ -251,12 +270,15 @@
     PJ_ASSERT_RETURN(endpt && async_cnt, PJ_EINVAL);
 
+    is_ipv6 = (local && local->addr.sa_family == pj_AF_INET6());
+    af = is_ipv6 ? pj_AF_INET6() : pj_AF_INET();
+
     /* Verify that address given in a_name (if any) is valid */
     if (a_name && a_name->host.slen) {
-	pj_sockaddr_in tmp;
-
-	status = pj_sockaddr_in_init(&tmp, &a_name->host, 
-				     (pj_uint16_t)a_name->port);
-	if (status != PJ_SUCCESS || tmp.sin_addr.s_addr == PJ_INADDR_ANY ||
-	    tmp.sin_addr.s_addr == PJ_INADDR_NONE)
+	pj_sockaddr tmp;
+
+	status = pj_sockaddr_init(af, &tmp, &a_name->host,
+				  (pj_uint16_t)a_name->port);
+	if (status != PJ_SUCCESS || !pj_sockaddr_has_addr(&tmp) ||
+	    (!is_ipv6 && tmp.ipv4.sin_addr.s_addr == PJ_INADDR_NONE))
 	{
 	    /* Invalid address */
@@ -271,10 +293,16 @@
     listener = PJ_POOL_ZALLOC_T(pool, struct tls_listener);
     listener->factory.pool = pool;
-    listener->factory.type = PJSIP_TRANSPORT_TLS;
-    listener->factory.type_name = "tls";
+    if (is_ipv6)
+	listener->factory.type = PJSIP_TRANSPORT_TLS6;
+    else
+	listener->factory.type = PJSIP_TRANSPORT_TLS;
+    listener->factory.type_name = (char*)
+		pjsip_transport_get_type_name(listener->factory.type);
     listener->factory.flag = 
-	pjsip_transport_get_flag_from_type(PJSIP_TRANSPORT_TLS);
+	pjsip_transport_get_flag_from_type(listener->factory.type);
 
     pj_ansi_strcpy(listener->factory.obj_name, "tlslis");
+    if (is_ipv6)
+	pj_ansi_strcat(listener->factory.obj_name, "6");
 
     if (opt)
@@ -283,5 +311,5 @@
 	pjsip_tls_setting_default(&listener->tls_setting);
 
-    status = pj_lock_create_recursive_mutex(pool, "tlslis", 
+    status = pj_lock_create_recursive_mutex(pool, listener->factory.obj_name,
 					    &listener->factory.lock);
     if (status != PJ_SUCCESS)
@@ -293,4 +321,5 @@
     /* Build SSL socket param */
     pj_ssl_sock_param_default(&ssock_param);
+    ssock_param.sock_af = af;
     ssock_param.cb.on_accept_complete = &on_accept_complete;
     ssock_param.cb.on_data_read = &on_data_read;
@@ -339,10 +368,15 @@
 	goto on_error;
 
-    listener_addr = (pj_sockaddr_in*)&listener->factory.local_addr;
+    /* Bind address may be different than factory.local_addr because
+     * factory.local_addr will be resolved below.
+     */
+    listener_addr = &listener->factory.local_addr;
     if (local) {
 	pj_sockaddr_cp((pj_sockaddr_t*)listener_addr, 
 		       (const pj_sockaddr_t*)local);
+	pj_sockaddr_cp(&listener->bound_addr, local);
     } else {
-	pj_sockaddr_in_init(listener_addr, NULL, 0);
+	pj_sockaddr_init(af, listener_addr, NULL, 0);
+	pj_sockaddr_init(af, &listener->bound_addr, NULL, 0);
     }
 
@@ -402,12 +436,12 @@
 	 * interface address as the transport's address.
 	 */
-	if (listener_addr->sin_addr.s_addr == 0) {
+	if (!pj_sockaddr_has_addr(listener_addr)) {
 	    pj_sockaddr hostip;
 
-	    status = pj_gethostip(pj_AF_INET(), &hostip);
+	    status = pj_gethostip(af, &hostip);
 	    if (status != PJ_SUCCESS)
 		goto on_error;
 
-	    listener_addr->sin_addr.s_addr = hostip.ipv4.sin_addr.s_addr;
+	    pj_sockaddr_copy_addr(listener_addr, &hostip);
 	}
 
@@ -419,5 +453,5 @@
     /* If port is zero, get the bound port */
     if (listener->factory.addr_name.port == 0) {
-	listener->factory.addr_name.port = pj_ntohs(listener_addr->sin_port);
+	listener->factory.addr_name.port = pj_sockaddr_get_port(listener_addr);
     }
 
@@ -536,6 +570,6 @@
 			       pj_ssl_sock_t *ssock,
 			       pj_bool_t is_server,
-			       const pj_sockaddr_in *local,
-			       const pj_sockaddr_in *remote,
+			       const pj_sockaddr *local,
+			       const pj_sockaddr *remote,
 			       const pj_str_t *remote_name,
 			       struct tls_transport **p_tls)
@@ -543,4 +577,5 @@
     struct tls_transport *tls;
     const pj_str_t ka_pkt = PJSIP_TLS_KEEP_ALIVE_DATA;
+    char print_addr[PJ_INET6_ADDRSTRLEN+10];
     pj_status_t status;
     
@@ -580,15 +615,18 @@
 	pj_strdup(pool, &tls->remote_name, remote_name);
 
-    tls->base.key.type = PJSIP_TRANSPORT_TLS;
-    pj_memcpy(&tls->base.key.rem_addr, remote, sizeof(pj_sockaddr_in));
-    tls->base.type_name = "tls";
-    tls->base.flag = pjsip_transport_get_flag_from_type(PJSIP_TRANSPORT_TLS);
+    tls->base.key.type = listener->factory.type;
+    pj_sockaddr_cp(&tls->base.key.rem_addr, remote);
+    tls->base.type_name = (char*)
+			  pjsip_transport_get_type_name(tls->base.key.type);
+    tls->base.flag = pjsip_transport_get_flag_from_type(tls->base.key.type);
 
     tls->base.info = (char*) pj_pool_alloc(pool, 64);
-    pj_ansi_snprintf(tls->base.info, 64, "TLS to %s:%d",
-		     pj_inet_ntoa(remote->sin_addr), 
-		     (int)pj_ntohs(remote->sin_port));
-
-    tls->base.addr_len = sizeof(pj_sockaddr_in);
+    pj_ansi_snprintf(tls->base.info, 64, "%s to %s",
+                     tls->base.type_name,
+                     pj_sockaddr_print(remote, print_addr,
+                                       sizeof(print_addr), 3));
+
+
+    tls->base.addr_len = pj_sockaddr_get_len(remote);
     tls->base.dir = is_server? PJSIP_TP_DIR_INCOMING : PJSIP_TP_DIR_OUTGOING;
     
@@ -601,9 +639,8 @@
     }
     
-    sockaddr_to_host_port(pool, &tls->base.local_name, 
-			  (pj_sockaddr_in*)&tls->base.local_addr);
+    sockaddr_to_host_port(pool, &tls->base.local_name, &tls->base.local_addr);
     if (tls->remote_name.slen) {
 	tls->base.remote_name.host = tls->remote_name;
-	tls->base.remote_name.port = pj_sockaddr_in_get_port(remote);
+	tls->base.remote_name.port = pj_sockaddr_get_port(remote);
     } else {
 	sockaddr_to_host_port(pool, &tls->base.remote_name, remote);
@@ -795,5 +832,5 @@
     pj_pool_t *pool;
     pj_ssize_t size;
-    pj_sockaddr_in *rem_addr;
+    pj_sockaddr *rem_addr;
     void *readbuf[1];
     pj_status_t status;
@@ -818,9 +855,9 @@
 
     tls->rdata.pkt_info.src_addr = tls->base.key.rem_addr;
-    tls->rdata.pkt_info.src_addr_len = sizeof(pj_sockaddr_in);
-    rem_addr = (pj_sockaddr_in*) &tls->base.key.rem_addr;
-    pj_ansi_strcpy(tls->rdata.pkt_info.src_name,
-		   pj_inet_ntoa(rem_addr->sin_addr));
-    tls->rdata.pkt_info.src_port = pj_ntohs(rem_addr->sin_port);
+    tls->rdata.pkt_info.src_addr_len = sizeof(tls->rdata.pkt_info.src_addr);
+    rem_addr = &tls->base.key.rem_addr;
+    pj_sockaddr_print(rem_addr, tls->rdata.pkt_info.src_name,
+                          sizeof(tls->rdata.pkt_info.src_name), 0);
+    tls->rdata.pkt_info.src_port = pj_sockaddr_get_port(rem_addr);
 
     size = sizeof(tls->rdata.pkt_info.packet);
@@ -855,5 +892,5 @@
     pj_ssl_sock_t *ssock;
     pj_ssl_sock_param ssock_param;
-    pj_sockaddr_in local_addr;
+    pj_sockaddr local_addr;
     pj_str_t remote_name;
     pj_status_t status;
@@ -863,7 +900,9 @@
 		     addr_len && p_transport, PJ_EINVAL);
 
-    /* Check that address is a sockaddr_in */
-    PJ_ASSERT_RETURN(rem_addr->addr.sa_family == pj_AF_INET() &&
-		     addr_len == sizeof(pj_sockaddr_in), PJ_EINVAL);
+    /* Check that address is a sockaddr_in or sockaddr_in6*/
+    PJ_ASSERT_RETURN((rem_addr->addr.sa_family == pj_AF_INET() &&
+		      addr_len == sizeof(pj_sockaddr_in)) ||
+		     (rem_addr->addr.sa_family == pj_AF_INET6() &&
+		      addr_len == sizeof(pj_sockaddr_in6)), PJ_EINVAL);
 
 
@@ -882,4 +921,6 @@
     /* Build SSL socket param */
     pj_ssl_sock_param_default(&ssock_param);
+    ssock_param.sock_af = (factory->type & PJSIP_TRANSPORT_IPV6) ?
+			    pj_AF_INET6() : pj_AF_INET();
     ssock_param.cb.on_connect_complete = &on_connect_complete;
     ssock_param.cb.on_data_read = &on_data_read;
@@ -932,10 +973,12 @@
     }
 
-    /* Initially set bind address to PJ_INADDR_ANY port 0 */
-    pj_sockaddr_in_init(&local_addr, NULL, 0);
+    /* Initially set bind address to listener's bind address */
+    pj_sockaddr_init(listener->bound_addr.addr.sa_family,
+		     &local_addr, NULL, 0);
+    pj_sockaddr_copy_addr(&local_addr, &listener->bound_addr);
 
     /* Create the transport descriptor */
     status = tls_create(listener, pool, ssock, PJ_FALSE, &local_addr, 
-			(pj_sockaddr_in*)rem_addr, &remote_name, &tls);
+			rem_addr, &remote_name, &tls);
     if (status != PJ_SUCCESS)
 	return status;
@@ -984,5 +1027,5 @@
 
 	    sockaddr_to_host_port(tls->base.pool, &tls->base.local_name,
-				  (pj_sockaddr_in*)&tls->base.local_addr);
+				  &tls->base.local_addr);
 	}
 
@@ -1018,4 +1061,5 @@
     char addr[PJ_INET6_ADDRSTRLEN+10];
     pjsip_tp_state_callback state_cb;
+    pj_sockaddr tmp_src_addr;
     pj_bool_t is_shutdown;
     pj_status_t status;
@@ -1045,4 +1089,8 @@
     }
 
+    /* Copy to larger buffer, just in case */
+    pj_bzero(&tmp_src_addr, sizeof(tmp_src_addr));
+    pj_sockaddr_cp(&tmp_src_addr, src_addr);
+
     /* 
      * Incoming connection!
@@ -1050,6 +1098,6 @@
      */
     status = tls_create( listener, NULL, new_ssock, PJ_TRUE,
-			 (const pj_sockaddr_in*)&listener->factory.local_addr,
-			 (const pj_sockaddr_in*)src_addr, NULL, &tls);
+			 &listener->factory.local_addr,
+			 &tmp_src_addr, NULL, &tls);
     
     if (status != PJ_SUCCESS)
@@ -1201,7 +1249,7 @@
     
     /* Check the address is supported */
-    PJ_ASSERT_RETURN(rem_addr && addr_len==sizeof(pj_sockaddr_in), PJ_EINVAL);
-
-
+    PJ_ASSERT_RETURN(rem_addr && (addr_len==sizeof(pj_sockaddr_in) ||
+	                          addr_len==sizeof(pj_sockaddr_in6)),
+	             PJ_EINVAL);
 
     /* Init op key. */
@@ -1385,5 +1433,5 @@
     struct tls_transport *tls;
     pj_ssl_sock_info ssl_info;
-    pj_sockaddr_in addr, *tp_addr;
+    pj_sockaddr addr, *tp_addr;
     pjsip_tp_state_callback state_cb;
     pj_bool_t is_shutdown;
@@ -1423,10 +1471,9 @@
      * on some systems, like old Win32 probably?).
      */
-    tp_addr = (pj_sockaddr_in*)&tls->base.local_addr;
+    tp_addr = &tls->base.local_addr;
     pj_sockaddr_cp((pj_sockaddr_t*)&addr, 
 		   (pj_sockaddr_t*)&ssl_info.local_addr);
-    if (tp_addr->sin_addr.s_addr != addr.sin_addr.s_addr) {
-	tp_addr->sin_addr.s_addr = addr.sin_addr.s_addr;
-	tp_addr->sin_port = addr.sin_port;
+    if (pj_sockaddr_cmp(tp_addr, &addr) != 0) {
+	pj_sockaddr_cp(tp_addr, &addr);
 	sockaddr_to_host_port(tls->base.pool, &tls->base.local_name,
 			      tp_addr);
