Modify transport to use generic sockaddr address

git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@105 74dad513-b988-da41-8d7b-12977e46ad98
diff --git a/pjlib/build/pjlib_test.dsp b/pjlib/build/pjlib_test.dsp
index ca88fb4..394bc56 100644
--- a/pjlib/build/pjlib_test.dsp
+++ b/pjlib/build/pjlib_test.dsp
@@ -50,7 +50,7 @@
 # ADD BSC32 /nologo

 LINK32=link.exe

 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386

-# ADD LINK32 netapi32.lib mswsock.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../bin/pjlib-test-i386-win32-vc6-release.exe"

+# ADD LINK32 netapi32.lib mswsock.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /profile /debug /machine:I386 /out:"../bin/pjlib-test-i386-win32-vc6-release.exe"

 

 !ELSEIF  "$(CFG)" == "pjlib_test - Win32 Debug"

 

diff --git a/pjsip/build/test_pjsip.dsp b/pjsip/build/test_pjsip.dsp
index 91d8d24..2ca4666 100644
--- a/pjsip/build/test_pjsip.dsp
+++ b/pjsip/build/test_pjsip.dsp
@@ -93,7 +93,7 @@
 # End Source File

 # Begin Source File

 

-SOURCE="..\src\test-pjsip\msg.c"

+SOURCE="..\src\test-pjsip\msg_test.c"

 # End Source File

 # Begin Source File

 

@@ -101,7 +101,7 @@
 # End Source File

 # Begin Source File

 

-SOURCE="..\src\test-pjsip\uri.c"

+SOURCE="..\src\test-pjsip\uri_test.c"

 # End Source File

 # End Group

 # Begin Group "Header Files"

diff --git a/pjsip/docs/PJSIP-Dev-Guide.pdf b/pjsip/docs/PJSIP-Dev-Guide.pdf
index a783c35..3a4dc15 100644
--- a/pjsip/docs/PJSIP-Dev-Guide.pdf
+++ b/pjsip/docs/PJSIP-Dev-Guide.pdf
Binary files differ
diff --git a/pjsip/include/pjsip/sip_config.h b/pjsip/include/pjsip/sip_config.h
index 972a080..592aea4 100644
--- a/pjsip/include/pjsip/sip_config.h
+++ b/pjsip/include/pjsip/sip_config.h
@@ -29,8 +29,8 @@
 /* Transport related constants. */
 #define PJSIP_MAX_TRANSPORTS		(PJ_IOQUEUE_MAX_HANDLES)
 #define PJSIP_MAX_PKT_LEN		1500
-#define PJSIP_POOL_LEN_RDATA		2500
-#define PJSIP_POOL_INC_RDATA		512
+#define PJSIP_POOL_RDATA_LEN		4000
+#define PJSIP_POOL_RDATA_INC		4000
 #define PJSIP_POOL_LEN_TRANSPORT	512
 #define PJSIP_POOL_INC_TRANSPORT	512
 #define PJSIP_POOL_LEN_TDATA		2500
diff --git a/pjsip/include/pjsip/sip_endpoint.h b/pjsip/include/pjsip/sip_endpoint.h
index 3e0702f..8254d50 100644
--- a/pjsip/include/pjsip/sip_endpoint.h
+++ b/pjsip/include/pjsip/sip_endpoint.h
@@ -248,7 +248,7 @@
  */
 PJ_DECL(void) pjsip_endpt_resolve( pjsip_endpoint *endpt,
 				   pj_pool_t *pool,
-				   pjsip_host_port *target,
+				   pjsip_host_info *target,
 				   void *token,
 				   pjsip_resolver_callback *cb);
 
@@ -280,7 +280,8 @@
  */
 PJ_DECL(pj_status_t) pjsip_endpt_alloc_transport( pjsip_endpoint *endpt,
 						  pjsip_transport_type_e type,
-						  const pj_sockaddr_in *remote,
+						  const pj_sockaddr *remote,
+						  int addr_len,
 						  pjsip_transport **p_transport);
 
 /**
diff --git a/pjsip/include/pjsip/sip_resolve.h b/pjsip/include/pjsip/sip_resolve.h
index 673de2a..b9fbe0d 100644
--- a/pjsip/include/pjsip/sip_resolve.h
+++ b/pjsip/include/pjsip/sip_resolve.h
@@ -59,7 +59,10 @@
 	pjsip_transport_type_e	type;
 
 	/** The server's address. */
-	pj_sockaddr_in		addr;
+	pj_sockaddr		addr;
+
+	/** Address length. */
+	int			addr_len;
 
     } entry[PJSIP_MAX_RESOLVED_ADDRESSES];
 
@@ -107,7 +110,7 @@
  */
 PJ_DECL(void) pjsip_resolve( pjsip_resolver_t *resolver,
 			     pj_pool_t *pool,
-			     pjsip_host_port *target,
+			     pjsip_host_info *target,
 			     void *token,
 			     pjsip_resolver_callback *cb);
 
diff --git a/pjsip/include/pjsip/sip_transaction.h b/pjsip/include/pjsip/sip_transaction.h
index e95c66b..c0627aa 100644
--- a/pjsip/include/pjsip/sip_transaction.h
+++ b/pjsip/include/pjsip/sip_transaction.h
@@ -107,7 +107,7 @@
      * Transport.
      */
     pjsip_tsx_transport_state_e	transport_state;/**< Transport's state.     */
-    pjsip_host_port		dest_name;      /**< Destination address.   */
+    pjsip_host_info		dest_name;      /**< Destination address.   */
     pjsip_server_addresses	remote_addr;    /**< Addresses resolved.    */
     int				current_addr;   /**< Address currently used. */
 
diff --git a/pjsip/include/pjsip/sip_transport.h b/pjsip/include/pjsip/sip_transport.h
index dac608f..14175dc 100644
--- a/pjsip/include/pjsip/sip_transport.h
+++ b/pjsip/include/pjsip/sip_transport.h
@@ -174,10 +174,16 @@
 	int			 len;
 
 	/** The source address from which the packet was received. */
-	pj_sockaddr_in		 addr;
+	pj_sockaddr		 src_addr;
 
 	/** The length of the source address. */
-	int			 addr_len;
+	int			 src_addr_len;
+
+	/** The IP source address string (NULL terminated). */
+	char			 src_name[16];
+
+	/** The IP source port number. */
+	int			 src_port;
 
     } pkt_info;
 
@@ -407,14 +413,21 @@
     pj_lock_t		   *lock;	    /**< Lock object.		    */
     int			    tracing;	    /**< Tracing enabled?	    */
 
-    pjsip_transport_type_e  type;	    /**< Transport type.	    */
-    char		    type_name[8];   /**< Type name.		    */
+    /** Key for indexing this transport in hash table. */
+    struct {
+	pjsip_transport_type_e  type;	    /**< Transport type.	    */
+	pj_sockaddr		rem_addr;   /**< Remote addr (zero for UDP) */
+    } key;
+
+    char		   *type_name;	    /**< Type name.		    */
     unsigned		    flag;	    /**< #pjsip_transport_flags_e   */
+    char		   *info;	    /**< Transport info/description.*/
 
-    pj_sockaddr_in	    local_addr;	    /**< Bound address.		    */
-    pj_sockaddr_in	    public_addr;    /**< STUN addres.		    */
-    pj_sockaddr_in	    rem_addr;	    /**< Remote addr (zero for UDP) */
-
+    int			    addr_len;	    /**< Length of addresses.	    */
+    pj_sockaddr		    local_addr;	    /**< Bound address.		    */
+    pjsip_host_port	    local_name;	    /**< Published name (eg. STUN). */
+    pjsip_host_port	    remote_name;    /**< Remote address name.	    */
+    
     pjsip_endpoint	   *endpt;	    /**< Endpoint instance.	    */
     pjsip_tpmgr		   *tpmgr;	    /**< Transport manager.	    */
     pj_timer_entry	    idle_timer;	    /**< Timer when ref cnt is zero.*/
@@ -428,6 +441,7 @@
      * @param op_key	    Completion token, which will be supplied to
      *			    caller when pending send operation completes.
      * @param rem_addr	    The remote destination address.
+     * @param addr_len	    Size of remote address.
      * @param callback	    If supplied, the callback will be called
      *			    once a pending transmission has completed. If
      *			    the function completes immediately (i.e. return
@@ -446,7 +460,8 @@
      */
     pj_status_t (*send_msg)(pjsip_transport *transport, 
 			    pjsip_tx_data *tdata,
-			    const pj_sockaddr_in *rem_addr,
+			    const pj_sockaddr_t *rem_addr,
+			    int addr_len,
 			    void *token,
 			    void (*callback)(pjsip_transport *transport,
 					     void *token, 
@@ -522,8 +537,8 @@
     char		    type_name[8];
     unsigned		    flag;
 
-    pj_sockaddr_in	    local_addr;
-    pj_sockaddr_in	    public_addr;
+    pj_sockaddr		    local_addr;
+    pjsip_host_port	    addr_name;
 
     /**
      * Create new outbound connection.
@@ -531,7 +546,7 @@
     pj_status_t (*create_transport)(pjsip_tpfactory *factory,
 				    pjsip_tpmgr *mgr,
 				    pjsip_endpoint *endpt,
-				    const pj_sockaddr_in *rem_addr,
+				    const pj_sockaddr *rem_addr,
 				    pjsip_transport **transport);
 
     /*
@@ -607,9 +622,10 @@
  * suitable transport is found, a new one will be created.
  */
 PJ_DECL(pj_status_t) pjsip_tpmgr_alloc_transport( pjsip_tpmgr *mgr,
-					   pjsip_transport_type_e type,
-					   const pj_sockaddr_in *remote,
-					   pjsip_transport **p_transport );
+						  pjsip_transport_type_e type,
+						  const pj_sockaddr_t *remote,
+						  int addr_len,
+						  pjsip_transport **p_transport );
 
 
 /**
@@ -617,7 +633,8 @@
  */
 PJ_DECL(pj_status_t) pjsip_transport_send( pjsip_transport *tr, 
 					   pjsip_tx_data *tdata,
-					   const pj_sockaddr_in *addr,
+					   const pj_sockaddr_t *addr,
+					   int addr_len,
 					   void *token,
 					   void (*cb)(void *token, 
 						      pjsip_tx_data *tdata,
diff --git a/pjsip/include/pjsip/sip_transport_udp.h b/pjsip/include/pjsip/sip_transport_udp.h
index 99f5ab6..d3fd5d3 100644
--- a/pjsip/include/pjsip/sip_transport_udp.h
+++ b/pjsip/include/pjsip/sip_transport_udp.h
@@ -28,7 +28,9 @@
  *
  * @param endpt		The SIP endpoint.
  * @param local		Local address to bind.
- * @param pub_addr	Public address to advertise.
+ * @param a_name	Published address (only the host and port portion is 
+ *			used). If this argument is NULL, then the bound address
+ *			will be used as the published address.
  * @param async_cnt	Number of simultaneous async operations.
  * @param p_transport	Pointer to receive the transport.
  *
@@ -38,7 +40,7 @@
  */
 PJ_DECL(pj_status_t) pjsip_udp_transport_start(pjsip_endpoint *endpt,
 					       const pj_sockaddr_in *local,
-					       const pj_sockaddr_in *pub_addr,
+					       const pjsip_host_port *a_name,
 					       unsigned async_cnt,
 					       pjsip_transport **p_transport);
 
@@ -47,7 +49,8 @@
  *
  * @param endpt		The SIP endpoint.
  * @param sock		UDP socket to use.
- * @param pub_addr	Public address to advertise.
+ * @param a_name	Published address (only the host and port portion is 
+ *			used).
  * @param async_cnt	Number of simultaneous async operations.
  * @param p_transport	Pointer to receive the transport.
  *
@@ -57,7 +60,7 @@
  */
 PJ_DECL(pj_status_t) pjsip_udp_transport_attach(pjsip_endpoint *endpt,
 						pj_sock_t sock,
-						const pj_sockaddr_in *pub_addr,
+						const pjsip_host_port *a_name,
 						unsigned async_cnt,
 						pjsip_transport **p_transport);
 
diff --git a/pjsip/include/pjsip/sip_types.h b/pjsip/include/pjsip/sip_types.h
index 2f8f2d1..516d50d 100644
--- a/pjsip/include/pjsip/sip_types.h
+++ b/pjsip/include/pjsip/sip_types.h
@@ -145,12 +145,20 @@
  */
 typedef struct pjsip_host_port
 {
-    unsigned flag;	/**< Flags of pjsip_transport_flags_e (not used in Via). */
-    unsigned type;	/**< Transport type (pjsip_transport_type_e), or zero. */
-    pj_str_t host;	/**< Host part. */
+    pj_str_t host;	/**< Host part or IP address. */
     int	     port;	/**< Port number. */
 } pjsip_host_port;
 
+/**
+ * Host information.
+ */
+typedef struct pjsip_host_info
+{
+    unsigned		    flag;   /**< Flags of pjsip_transport_flags_e. */
+    pjsip_transport_type_e  type;   /**< Transport type. */
+    pjsip_host_port	    addr;   /**< Address information. */
+} pjsip_host_info;
+
 
 /**
  * Convert exception ID into pj_status_t status.
diff --git a/pjsip/include/pjsip/sip_util.h b/pjsip/include/pjsip/sip_util.h
index e158212..f55cd7e 100644
--- a/pjsip/include/pjsip/sip_util.h
+++ b/pjsip/include/pjsip/sip_util.h
@@ -180,7 +180,7 @@
 PJ_DECL(pj_status_t) pjsip_get_response_addr(pj_pool_t *pool,
 					     const pjsip_transport *tr,
 					     const pjsip_via_hdr *via,
-					     pjsip_host_port *addr);
+					     pjsip_host_info *addr);
 
 /**
  * @}
diff --git a/pjsip/src/pjsip/sip_endpoint.c b/pjsip/src/pjsip/sip_endpoint.c
index dae3d5b..b3fa2f8 100644
--- a/pjsip/src/pjsip/sip_endpoint.c
+++ b/pjsip/src/pjsip/sip_endpoint.c
@@ -725,8 +725,8 @@
     PJ_LOG(5, (THIS_FILE, "endpt_transport_callback(rdata=%p)", rdata));
 
     if (status != PJ_SUCCESS) {
-	const char *src_addr = pj_inet_ntoa(rdata->pkt_info.addr.sin_addr);
-	int port = pj_ntohs(rdata->pkt_info.addr.sin_port);
+	const char *src_addr = rdata->pkt_info.src_name;
+	int port = rdata->pkt_info.src_port;
 	PJSIP_ENDPT_LOG_ERROR((endpt, "transport", status,
 			       "Src.addr=%s:%d, packet:--\n"
 			       "%s\n"
@@ -740,20 +740,18 @@
      * Ref: RFC3261 Section 18.1.2 Receiving Response
      */
     if (msg->type == PJSIP_RESPONSE_MSG) {
-	const pj_sockaddr_in *addr;
-	const char *addr_addr;
+	const pj_str_t *addr_addr;
 	int port = rdata->msg_info.via->sent_by.port;
 	pj_bool_t mismatch = PJ_FALSE;
 	if (port == 0) {
 	    int type;
-	    type = rdata->tp_info.transport->type;
+	    type = rdata->tp_info.transport->key.type;
 	    port = pjsip_transport_get_default_port_for_type(type);
 	}
-	addr = &rdata->tp_info.transport->public_addr;
-	addr_addr = pj_inet_ntoa(addr->sin_addr);
-	if (pj_strcmp2(&rdata->msg_info.via->sent_by.host, addr_addr) != 0)
+	addr_addr = &rdata->tp_info.transport->local_name.host;
+	if (pj_strcmp(&rdata->msg_info.via->sent_by.host, addr_addr) != 0)
 	    mismatch = PJ_TRUE;
-	else if (port != pj_ntohs(addr->sin_port)) {
+	else if (port != rdata->tp_info.transport->local_name.port) {
 	    /* Port or address mismatch, we should discard response */
 	    /* But we saw one implementation (we don't want to name it to 
 	     * protect the innocence) which put wrong sent-by port although
@@ -761,7 +759,7 @@
 	     * So we discard the response only if the port doesn't match
 	     * both the port in sent-by and rport. We try to be lenient here!
 	     */
-	    if (rdata->msg_info.via->rport_param != pj_sockaddr_in_get_port(addr))
+	    if (rdata->msg_info.via->rport_param != rdata->tp_info.transport->local_name.port)
 		mismatch = PJ_TRUE;
 	    else {
 		PJ_LOG(4,(THIS_FILE, "Response %p has mismatch port in sent-by"
@@ -958,7 +956,7 @@
  */
 PJ_DEF(void) pjsip_endpt_resolve( pjsip_endpoint *endpt,
 				  pj_pool_t *pool,
-				  pjsip_host_port *target,
+				  pjsip_host_info *target,
 				  void *token,
 				  pjsip_resolver_callback *cb)
 {
@@ -987,12 +985,13 @@
  */
 PJ_DEF(pj_status_t) pjsip_endpt_alloc_transport( pjsip_endpoint *endpt,
 						  pjsip_transport_type_e type,
-						  const pj_sockaddr_in *remote,
+						  const pj_sockaddr *remote,
+						  int addr_len,
 						  pjsip_transport **p_transport)
 {
     PJ_LOG(5, (THIS_FILE, "pjsip_endpt_alloc_transport()"));
-    return pjsip_tpmgr_alloc_transport( endpt->transport_mgr, type, remote,
-					p_transport);
+    return pjsip_tpmgr_alloc_transport( endpt->transport_mgr, type, 
+					remote, addr_len, p_transport);
 }
 
 
diff --git a/pjsip/src/pjsip/sip_resolve.c b/pjsip/src/pjsip/sip_resolve.c
index b89b7c0..4be6f56 100644
--- a/pjsip/src/pjsip/sip_resolve.c
+++ b/pjsip/src/pjsip/sip_resolve.c
@@ -56,7 +56,7 @@
 
 PJ_DEF(void) pjsip_resolve( pjsip_resolver_t *resolver,
 			    pj_pool_t *pool,
-			    pjsip_host_port *target,
+			    pjsip_host_info *target,
 			    void *token,
 			    pjsip_resolver_callback *cb)
 {
@@ -72,13 +72,13 @@
     PJ_TODO(SUPPORT_RFC3263_SERVER_RESOLUTION)
 
     /* Is it IP address or hostname?. */
-    is_ip_addr = is_str_ip(&target->host);
+    is_ip_addr = is_str_ip(&target->addr.host);
 
     /* Set the transport type if not explicitly specified. 
      * RFC 3263 section 4.1 specify rules to set up this.
      */
     if (type == PJSIP_TRANSPORT_UNSPECIFIED) {
-	if (is_ip_addr || (target->port != 0)) {
+	if (is_ip_addr || (target->addr.port != 0)) {
 #if PJ_HAS_TCP
 	    if (target->flag & PJSIP_TRANSPORT_SECURE) 
 	    {
@@ -103,23 +103,26 @@
     }
 
     /* Set the port number if not specified. */
-    if (target->port == 0) {
-	target->port = pjsip_transport_get_default_port_for_type(type);
+    if (target->addr.port == 0) {
+	target->addr.port = pjsip_transport_get_default_port_for_type(type);
     }
 
     /* Resolve hostname. */
     if (!is_ip_addr) {
-	status = pj_sockaddr_in_init(&svr_addr.entry[0].addr, &target->host, 
-				     (pj_uint16_t)target->port);
+	status = pj_sockaddr_in_init((pj_sockaddr_in*)&svr_addr.entry[0].addr, 
+				     &target->addr.host, 
+				     (pj_uint16_t)target->addr.port);
     } else {
-	status = pj_sockaddr_in_init(&svr_addr.entry[0].addr, &target->host, 
-				     (pj_uint16_t)target->port);
+	status = pj_sockaddr_in_init((pj_sockaddr_in*)&svr_addr.entry[0].addr, 
+				      &target->addr.host, 
+				     (pj_uint16_t)target->addr.port);
 	pj_assert(status == PJ_SUCCESS);
     }
 
     /* Call the callback. */
     svr_addr.count = (status == PJ_SUCCESS) ? 1 : 0;
     svr_addr.entry[0].type = type;
+    svr_addr.entry[0].addr_len = sizeof(pj_sockaddr_in);
     (*cb)(status, token, &svr_addr);
 }
 
diff --git a/pjsip/src/pjsip/sip_transaction.c b/pjsip/src/pjsip/sip_transaction.c
index eade0a4..bb9eee9 100644
--- a/pjsip/src/pjsip/sip_transaction.c
+++ b/pjsip/src/pjsip/sip_transaction.c
@@ -498,7 +498,7 @@
  */
 static pj_status_t tsx_process_route( pjsip_transaction *tsx,
 				      pjsip_tx_data *tdata,
-				      pjsip_host_port *send_addr )
+				      pjsip_host_info *send_addr )
 {
     const pjsip_uri *new_request_uri, *target_uri;
     const pjsip_name_addr *topmost_route_uri;
@@ -595,16 +595,16 @@
 	pjsip_uri *uri = (pjsip_uri*) target_uri;
 	const pjsip_url *url = (const pjsip_url*)pjsip_uri_get_uri(uri);
 	send_addr->flag |= (PJSIP_TRANSPORT_SECURE | PJSIP_TRANSPORT_RELIABLE);
-	pj_strdup(tdata->pool, &send_addr->host, &url->host);
-        send_addr->port = url->port;
+	pj_strdup(tdata->pool, &send_addr->addr.host, &url->host);
+        send_addr->addr.port = url->port;
 	send_addr->type = 
             pjsip_transport_get_type_from_name(&url->transport_param);
 
     } else if (PJSIP_URI_SCHEME_IS_SIP(target_uri)) {
 	pjsip_uri *uri = (pjsip_uri*) target_uri;
 	const pjsip_url *url = (const pjsip_url*)pjsip_uri_get_uri(uri);
-	pj_strdup(tdata->pool, &send_addr->host, &url->host);
-	send_addr->port = url->port;
+	pj_strdup(tdata->pool, &send_addr->addr.host, &url->host);
+	send_addr->addr.port = url->port;
 	send_addr->type = 
             pjsip_transport_get_type_from_name(&url->transport_param);
 #if PJ_HAS_TCP
@@ -650,18 +650,18 @@
     pjsip_transaction *tsx = token;
     struct tsx_lock_data lck;
 
-    pj_memcpy(addr, tsx->dest_name.host.ptr, tsx->dest_name.host.slen);
-    addr[tsx->dest_name.host.slen] = '\0';
+    pj_memcpy(addr, tsx->dest_name.addr.host.ptr, tsx->dest_name.addr.host.slen);
+    addr[tsx->dest_name.addr.host.slen] = '\0';
 
 
     if (status == PJ_SUCCESS) {
 	PJ_LOG(4, (tsx->obj_name, "%s connected to %s:%d",
 				  tr->type_name,
-				  addr, tsx->dest_name.port));
+				  addr, tsx->dest_name.addr.port));
     } else {
 	PJ_LOG(4, (tsx->obj_name, "%s unable to connect to %s:%d, status=%d", 
 				  tr->type_name,
-				  addr, tsx->dest_name.port, status));
+				  addr, tsx->dest_name.addr.port, status));
     }
 
     /* Lock transaction. */
@@ -737,13 +737,10 @@
     pj_memcpy(&tsx->remote_addr, addr, sizeof(*addr));
 
     /* Create/find the transport for the remote address. */
-    PJ_LOG(5,(tsx->obj_name, "tsx getting transport for %s:%d",
-			     pj_inet_ntoa(addr->entry[0].addr.sin_addr),
-			     pj_ntohs(addr->entry[0].addr.sin_port)));
-
     tsx->transport_state = PJSIP_TSX_TRANSPORT_STATE_CONNECTING;
     status = pjsip_endpt_alloc_transport( tsx->endpt, addr->entry[0].type,
 					  &addr->entry[0].addr,
+					  addr->entry[0].addr_len,
 					  &tp);
     tsx_transport_callback(tp, tsx, status);
 
@@ -851,9 +848,9 @@
      * the callback will be called.
      */
     PJ_LOG(5,(tsx->obj_name, "tsx resolving destination %.*s:%d",
-			     tsx->dest_name.host.slen, 
-			     tsx->dest_name.host.ptr,
-			     tsx->dest_name.port));
+			     tsx->dest_name.addr.host.slen, 
+			     tsx->dest_name.addr.host.ptr,
+			     tsx->dest_name.addr.port));
 
     tsx->transport_state = PJSIP_TSX_TRANSPORT_STATE_RESOLVING;
     pjsip_endpt_resolve( tsx->endpt, tsx->pool, &tsx->dest_name, 
@@ -941,9 +938,9 @@
 
 	tsx->current_addr = 0;
 	tsx->remote_addr.count = 1;
-	tsx->remote_addr.entry[0].type = tsx->transport->type;
+	tsx->remote_addr.entry[0].type = tsx->transport->key.type;
 	pj_memcpy(&tsx->remote_addr.entry[0].addr, 
-		  &rdata->pkt_info.addr, rdata->pkt_info.addr_len);
+		  &rdata->pkt_info.src_addr, rdata->pkt_info.src_addr_len);
 	
     } else {
 	pj_status_t status;
@@ -964,9 +961,9 @@
 	 * the callback will be called.
 	 */
 	PJ_LOG(5,(tsx->obj_name, "tsx resolving destination %.*s:%d",
-				 tsx->dest_name.host.slen, 
-				 tsx->dest_name.host.ptr,
-				 tsx->dest_name.port));
+				 tsx->dest_name.addr.host.slen, 
+				 tsx->dest_name.addr.host.ptr,
+				 tsx->dest_name.addr.port));
 
 	tsx->transport_state = PJSIP_TSX_TRANSPORT_STATE_RESOLVING;
 	pjsip_endpt_resolve( tsx->endpt, tsx->pool, &tsx->dest_name, 
@@ -1023,7 +1020,7 @@
 PJ_DEF(void) pjsip_tsx_on_tx_ack( pjsip_transaction *tsx, pjsip_tx_data *tdata)
 {
     pjsip_msg *msg;
-    pjsip_host_port dest_addr;
+    pjsip_host_info dest_addr;
     pjsip_via_hdr *via;
     struct tsx_lock_data lck;
     pj_status_t status = PJ_SUCCESS;
@@ -1059,8 +1056,8 @@
      */
     if (dest_addr.type == tsx->dest_name.type &&
 	dest_addr.flag == tsx->dest_name.flag &&
-	dest_addr.port == tsx->dest_name.port &&
-	pj_stricmp(&dest_addr.host, &tsx->dest_name.host) == 0)
+	dest_addr.addr.port == tsx->dest_name.addr.port &&
+	pj_stricmp(&dest_addr.addr.host, &tsx->dest_name.addr.host) == 0)
     {
 	/* Equal destination. We can use current transport. */
 	pjsip_tsx_on_tx_msg(tsx, tdata);
@@ -1071,12 +1068,12 @@
 
     /* New destination; we'll have to resolve host and create new transport. */
     pj_memcpy(&tsx->dest_name, &dest_addr, sizeof(dest_addr));
-    pj_strdup(tsx->pool, &tsx->dest_name.host, &dest_addr.host);
+    pj_strdup(tsx->pool, &tsx->dest_name.addr.host, &dest_addr.addr.host);
 
     PJ_LOG(5,(tsx->obj_name, "tsx resolving destination %.*s:%d",
-			     tsx->dest_name.host.slen, 
-			     tsx->dest_name.host.ptr,
-			     tsx->dest_name.port));
+			     tsx->dest_name.addr.host.slen, 
+			     tsx->dest_name.addr.host.ptr,
+			     tsx->dest_name.addr.port));
 
     tsx->transport_state = PJSIP_TSX_TRANSPORT_STATE_RESOLVING;
     pjsip_transport_dec_ref(tsx->transport);
@@ -1215,7 +1212,6 @@
 	 * requests. 
 	 */
 	if (tdata->msg->type == PJSIP_REQUEST_MSG) {
-	    const pj_sockaddr_in *addr_name;
 	    pjsip_via_hdr *via = (pjsip_via_hdr*) 
 		pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL);
 
@@ -1225,12 +1221,11 @@
 
 	    /* Don't update Via sent-by on retransmission. */
 	    if (via->sent_by.host.slen == 0) {
-		addr_name = &tsx->transport->public_addr;
 		pj_strdup2(tdata->pool, &via->transport, 
 			   tsx->transport->type_name);
-		pj_strdup2(tdata->pool, &via->sent_by.host, 
-			   pj_inet_ntoa(addr_name->sin_addr));
-		via->sent_by.port = pj_ntohs(addr_name->sin_port);
+		pj_strdup(tdata->pool, &via->sent_by.host, 
+			  &tsx->transport->local_name.host);
+		via->sent_by.port = tsx->transport->local_name.port;
 	    }
 	}
 
@@ -1242,6 +1237,7 @@
 	tsx->has_unsent_msg = 0;
 	status = pjsip_transport_send(tsx->transport, tdata,
 			&tsx->remote_addr.entry[tsx->current_addr].addr,
+			tsx->remote_addr.entry[tsx->current_addr].addr_len,
 			tsx, &tsx_on_send_complete);
 	if (status != PJ_SUCCESS && status != PJ_EPENDING) {
 	    PJ_TODO(HANDLE_TRANSPORT_ERROR);
diff --git a/pjsip/src/pjsip/sip_transport.c b/pjsip/src/pjsip/sip_transport.c
index 225eabe..7299060 100644
--- a/pjsip/src/pjsip/sip_transport.c
+++ b/pjsip/src/pjsip/sip_transport.c
@@ -46,8 +46,6 @@
     void           (*msg_cb)(pjsip_endpoint*, pj_status_t, pjsip_rx_data*);
 };
 
-
-
 /*****************************************************************************
  *
  * GENERAL TRANSPORT (NAMES, TYPES, ETC.)
@@ -81,6 +79,13 @@
 {
     unsigned i;
 
+    /* Sanity check. 
+     * Check that transport_names[] are indexed on transport type. 
+     */
+    PJ_ASSERT_RETURN(transport_names[PJSIP_TRANSPORT_UDP].type ==
+		     PJSIP_TRANSPORT_UDP, PJSIP_TRANSPORT_UNSPECIFIED);
+
+    /* Get transport type from name. */
     for (i=0; i<PJ_ARRAY_SIZE(transport_names); ++i) {
 	if (pj_stricmp(name, &transport_names[i].name) == 0) {
 	    return transport_names[i].type;
@@ -100,6 +105,13 @@
 {
     unsigned i;
 
+    /* Sanity check. 
+     * Check that transport_names[] are indexed on transport type. 
+     */
+    PJ_ASSERT_RETURN(transport_names[PJSIP_TRANSPORT_UDP].type ==
+		     PJSIP_TRANSPORT_UDP, PJSIP_TRANSPORT_UNSPECIFIED);
+
+    /* Get the transport type for the specified flags. */
     for (i=0; i<PJ_ARRAY_SIZE(transport_names); ++i) {
 	if (transport_names[i].flag == flag) {
 	    return transport_names[i].type;
@@ -113,7 +125,16 @@
 PJ_DEF(unsigned)
 pjsip_transport_get_flag_from_type( pjsip_transport_type_e type )
 {
+    /* Sanity check. 
+     * Check that transport_names[] are indexed on transport type. 
+     */
+    PJ_ASSERT_RETURN(transport_names[PJSIP_TRANSPORT_UDP].type ==
+		     PJSIP_TRANSPORT_UDP, 0);
+
+    /* Check that argument is valid. */
     PJ_ASSERT_RETURN(type < PJ_ARRAY_SIZE(transport_names), 0);
+
+    /* Return transport flag. */
     return transport_names[type].flag;
 }
 
@@ -123,7 +144,16 @@
 PJ_DEF(int) 
 pjsip_transport_get_default_port_for_type(pjsip_transport_type_e type)
 {
+    /* Sanity check. 
+     * Check that transport_names[] are indexed on transport type. 
+     */
+    PJ_ASSERT_RETURN(transport_names[PJSIP_TRANSPORT_UDP].type ==
+		     PJSIP_TRANSPORT_UDP, 0);
+
+    /* Check that argument is valid. */
     PJ_ASSERT_RETURN(type < PJ_ARRAY_SIZE(transport_names), 5060);
+
+    /* Return the port. */
     return transport_names[type].port;
 }
 
@@ -224,17 +254,6 @@
  *
  *****************************************************************************/
 
-/*
- * Transport key for indexing in the hash table.
- */
-typedef struct transport_key
-{
-    pj_uint8_t	type;
-    pj_uint8_t	zero;
-    pj_uint16_t	port;
-    pj_uint32_t	addr;
-} transport_key;
-
 
 /*****************************************************************************
  *
@@ -269,7 +288,8 @@
  */
 PJ_DEF(pj_status_t) pjsip_transport_send(  pjsip_transport *tr, 
 					   pjsip_tx_data *tdata,
-					   const pj_sockaddr_in *addr,
+					   const pj_sockaddr *addr,
+					   int addr_len,
 					   void *token,
 					   void (*cb)(void *token, 
 						      pjsip_tx_data *tdata,
@@ -317,7 +337,7 @@
     tdata->is_pending = 1;
 
     /* Send to transport. */
-    status = (*tr->send_msg)(tr, tdata,  addr, (void*)tdata, 
+    status = (*tr->send_msg)(tr, tdata,  addr, addr_len, (void*)tdata, 
 			     &transport_send_callback);
 
     if (status != PJ_EPENDING) {
@@ -395,7 +415,7 @@
 PJ_DEF(pj_status_t) pjsip_transport_register( pjsip_tpmgr *mgr,
 					      pjsip_transport *tp )
 {
-    transport_key key;
+    int key_len;
 
     /* Init. */
     tp->tpmgr = mgr;
@@ -406,13 +426,9 @@
     /* 
      * Register to hash table.
      */
-    key.type = (pj_uint8_t)tp->type;
-    key.zero = 0;
-    key.addr = pj_ntohl(tp->rem_addr.sin_addr.s_addr);
-    key.port = pj_ntohs(tp->rem_addr.sin_port);
-
+    key_len = sizeof(tp->key.type) + tp->addr_len;
     pj_lock_acquire(mgr->lock);
-    pj_hash_set(tp->pool, mgr->table, &key, sizeof(key), tp);
+    pj_hash_set(tp->pool, mgr->table, &tp->key, key_len, tp);
     pj_lock_release(mgr->lock);
 
     return PJ_SUCCESS;
@@ -425,8 +441,9 @@
 PJ_DEF(pj_status_t) pjsip_transport_unregister( pjsip_tpmgr *mgr,
 						pjsip_transport *tp)
 {
-    transport_key key;
+    int key_len;
 
+    /* Must have no user. */
     PJ_ASSERT_RETURN(pj_atomic_get(tp->ref_cnt) == 0, PJSIP_EBUSY);
 
     pj_lock_acquire(tp->lock);
@@ -444,12 +461,8 @@
     /*
      * Unregister from hash table.
      */
-    key.type = (pj_uint8_t)tp->type;
-    key.zero = 0;
-    key.addr = pj_ntohl(tp->rem_addr.sin_addr.s_addr);
-    key.port = pj_ntohs(tp->rem_addr.sin_port);
-
-    pj_hash_set(tp->pool, mgr->table, &key, sizeof(key), NULL);
+    key_len = sizeof(tp->key.type) + tp->addr_len;
+    pj_hash_set(tp->pool, mgr->table, &tp->key, key_len, NULL);
 
     pj_lock_release(mgr->lock);
 
@@ -601,7 +614,6 @@
 					       pjsip_rx_data *rdata)
 {
     pjsip_transport *tr = rdata->tp_info.transport;
-    pj_str_t s;
 
     char *current_pkt;
     pj_size_t remaining_len;
@@ -682,18 +694,19 @@
 	/* If message is received from address that's different from sent-by,
   	 * MUST add received parameter to the via.
 	 */
-	s = pj_str(pj_inet_ntoa(rdata->pkt_info.addr.sin_addr));
-	if (pj_strcmp(&s, &rdata->msg_info.via->sent_by.host) != 0) {
-	    pj_strdup(rdata->tp_info.pool, 
-		      &rdata->msg_info.via->recvd_param, &s);
+	if (pj_strcmp2(&rdata->msg_info.via->sent_by.host, 
+		       rdata->pkt_info.src_name) != 0) 
+	{
+	    pj_strdup2(rdata->tp_info.pool, 
+		       &rdata->msg_info.via->recvd_param, 
+		       rdata->pkt_info.src_name);
 	}
 
 	/* RFC 3581:
 	 * If message contains "rport" param, put the received port there.
 	 */
 	if (rdata->msg_info.via->rport_param == 0) {
-	    rdata->msg_info.via->rport_param = 
-		pj_ntohs(rdata->pkt_info.addr.sin_port);
+	    rdata->msg_info.via->rport_param = rdata->pkt_info.src_port;
 	}
 
 	/* Drop response message if it has more than one Via.
@@ -735,32 +748,47 @@
  */
 PJ_DEF(pj_status_t) pjsip_tpmgr_alloc_transport( pjsip_tpmgr *mgr,
 						 pjsip_transport_type_e type,
-						 const pj_sockaddr_in *remote,
+						 const pj_sockaddr_t *remote,
+						 int addr_len,
 						 pjsip_transport **p_transport)
 {
-    transport_key key;
+    struct transport_key
+    {
+	pjsip_transport_type_e	type;
+	pj_sockaddr		addr;
+    } key;
+    int key_len;
     pjsip_transport *transport;
     pjsip_tpfactory *factory;
     pj_status_t status;
 
     pj_lock_acquire(mgr->lock);
 
+    key_len = sizeof(key.type) + addr_len;
+
     /* First try to get exact destination. */
-    key.type = (pj_uint8_t)type;
-    key.zero = 0;
-    key.addr = pj_ntohl(remote->sin_addr.s_addr);
-    key.port = pj_ntohs(remote->sin_port);
+    key.type = type;
+    pj_memcpy(&key.addr, remote, addr_len);
 
-    transport = pj_hash_get(mgr->table, &key, sizeof(key));
-    if (transport != NULL) {
+    transport = pj_hash_get(mgr->table, &key, key_len);
+    if (transport == NULL) {
 	unsigned flag = pjsip_transport_get_flag_from_type(type);
-	
-	/* For datagram transports, try lookup with zero address. */
-	if (flag & PJSIP_TRANSPORT_DATAGRAM) {
-	    key.addr = 0;
-	    key.port = 0;
+	const pj_sockaddr *remote_addr = (const pj_sockaddr*)remote;
 
-	    transport = pj_hash_get(mgr->table, &key, sizeof(key));
+	/* For datagram transports, try lookup with zero address. 
+	 */
+	if ( (flag & PJSIP_TRANSPORT_DATAGRAM) && 
+	     (remote_addr->sa_family == PJ_AF_INET)) 
+	{
+	    pj_sockaddr_in *addr = (pj_sockaddr_in*)&key.addr;
+
+	    pj_memset(addr, 0, sizeof(pj_sockaddr_in));
+	    addr->sin_family = PJ_AF_INET;
+	    addr->sin_addr.s_addr = 0;
+	    addr->sin_port = 0;
+
+	    key_len = sizeof(key.type) + sizeof(pj_sockaddr_in);
+	    transport = pj_hash_get(mgr->table, &key, key_len);
 	}
     }
     
@@ -815,22 +843,11 @@
 	PJ_LOG(3, (THIS_FILE, " Dumping transports:"));
 
 	do {
-	    char src_addr[128], dst_addr[128];
-	    int src_port, dst_port;
-	    pjsip_transport *t;
+	    pjsip_transport *t = pj_hash_this(mgr->table, itr);
 
-	    t = pj_hash_this(mgr->table, itr);
-	    pj_native_strcpy(src_addr, pj_inet_ntoa(t->local_addr.sin_addr));
-	    src_port = pj_ntohs(t->local_addr.sin_port);
-
-	    pj_native_strcpy(dst_addr, pj_inet_ntoa(t->rem_addr.sin_addr));
-	    dst_port = pj_ntohs(t->rem_addr.sin_port);
-
-	    PJ_LOG(3, (THIS_FILE, "  %s %s %s:%d --> %s:%d (refcnt=%d)", 
-		       t->type_name,
+	    PJ_LOG(3, (THIS_FILE, "  %s %s (refcnt=%d)", 
 		       t->obj_name,
-		       src_addr, src_port,
-		       dst_addr, dst_port,
+		       t->info,
 		       pj_atomic_get(t->ref_cnt)));
 
 	    itr = pj_hash_next(mgr->table, itr);
diff --git a/pjsip/src/pjsip/sip_transport_udp.c b/pjsip/src/pjsip/sip_transport_udp.c
index 2dc835a..bd6d7ff 100644
--- a/pjsip/src/pjsip/sip_transport_udp.c
+++ b/pjsip/src/pjsip/sip_transport_udp.c
@@ -40,14 +40,14 @@
 
 
 /*
- * on_read_complete()
+ * udp_on_read_complete()
  *
  * This is callback notification from ioqueue that a pending recvfrom()
  * operation has completed.
  */
-static void on_read_complete( pj_ioqueue_key_t *key, 
-			      pj_ioqueue_op_key_t *op_key, 
-			      pj_ssize_t bytes_read)
+static void udp_on_read_complete( pj_ioqueue_key_t *key, 
+				  pj_ioqueue_op_key_t *op_key, 
+				  pj_ssize_t bytes_read)
 {
     enum { MAX_IMMEDIATE_PACKET = 10 };
     pjsip_rx_data_op_key *rdata_op_key = (pjsip_rx_data_op_key*) op_key;
@@ -72,10 +72,16 @@
 	/* Report the packet to transport manager. */
 	if (bytes_read > 0) {
 	    pj_size_t size_eaten;
+	    const pj_sockaddr_in *src_addr = 
+		(pj_sockaddr_in*)&rdata->pkt_info.src_addr;
 
+	    /* Init pkt_info part. */
 	    rdata->pkt_info.len = bytes_read;
 	    rdata->pkt_info.zero = 0;
 	    pj_gettimeofday(&rdata->pkt_info.timestamp);
+	    pj_native_strcpy(rdata->pkt_info.src_name,
+			     pj_inet_ntoa(src_addr->sin_addr));
+	    rdata->pkt_info.src_port = pj_ntohs(src_addr->sin_port);
 
 	    size_eaten = 
 		pjsip_tpmgr_receive_packet(rdata->tp_info.transport->tpmgr, 
@@ -109,12 +115,12 @@
 
 	/* Read next packet. */
 	bytes_read = sizeof(rdata->pkt_info.packet);
-	rdata->pkt_info.addr_len = sizeof(rdata->pkt_info.addr);
+	rdata->pkt_info.src_addr_len = sizeof(rdata->pkt_info.src_addr);
 	status = pj_ioqueue_recvfrom(key, op_key, 
 				     rdata->pkt_info.packet,
 				     &bytes_read, flags,
-				     &rdata->pkt_info.addr, 
-				     &rdata->pkt_info.addr_len);
+				     &rdata->pkt_info.src_addr, 
+				     &rdata->pkt_info.src_addr_len);
 
 	if (status == PJ_SUCCESS) {
 	    /* Continue loop. */
@@ -149,14 +155,14 @@
 }
 
 /*
- * on_write_complete()
+ * udp_on_write_complete()
  *
  * This is callback notification from ioqueue that a pending sendto()
  * operation has completed.
  */
-static void on_write_complete( pj_ioqueue_key_t *key, 
-			       pj_ioqueue_op_key_t *op_key,
-			       pj_ssize_t bytes_sent)
+static void udp_on_write_complete( pj_ioqueue_key_t *key, 
+				   pj_ioqueue_op_key_t *op_key,
+				   pj_ssize_t bytes_sent)
 {
     struct udp_transport *tp = pj_ioqueue_get_user_data(key);
     pjsip_tx_data_op_key *tdata_op_key = (pjsip_tx_data_op_key*)op_key;
@@ -169,18 +175,19 @@
 }
 
 /*
- * transport_send_msg()
+ * udp_send_msg()
  *
  * This function is called by transport manager (by transport->send_msg())
  * to send outgoing message.
  */
-static pj_status_t transport_send_msg( pjsip_transport *transport,
-				       pjsip_tx_data *tdata,
-				       const pj_sockaddr_in *rem_addr,
-				       void *token,
-				       void (*callback)(pjsip_transport*,
-							void *token,
-							pj_ssize_t))
+static pj_status_t udp_send_msg( pjsip_transport *transport,
+				 pjsip_tx_data *tdata,
+				 const pj_sockaddr_t *rem_addr,
+				 int addr_len,
+				 void *token,
+				 void (*callback)(pjsip_transport*,
+						  void *token,
+						  pj_ssize_t))
 {
     struct udp_transport *tp = (struct udp_transport*)transport;
     pj_ssize_t size;
@@ -197,15 +204,15 @@
     size = tdata->buf.cur - tdata->buf.start;
     return pj_ioqueue_sendto(tp->key, (pj_ioqueue_op_key_t*)&tdata->op_key,
 			     tdata->buf.start, &size, 0,
-			     rem_addr, (rem_addr ? sizeof(pj_sockaddr_in):0));
+			     rem_addr, addr_len);
 }
 
 /*
- * transport_destroy()
+ * udp_destroy()
  *
  * This function is called by transport manager (by transport->destroy()).
  */
-static pj_status_t transport_destroy( pjsip_transport *transport )
+static pj_status_t udp_destroy( pjsip_transport *transport )
 {
     struct udp_transport *tp = (struct udp_transport*)transport;
     int i;
@@ -249,7 +256,7 @@
  */
 PJ_DEF(pj_status_t) pjsip_udp_transport_attach( pjsip_endpoint *endpt,
 						pj_sock_t sock,
-						const pj_sockaddr_in *pub_addr,
+						const pjsip_host_port *a_name,
 						unsigned async_cnt,
 						pjsip_transport **p_transport)
 {
@@ -258,33 +265,22 @@
     pj_ioqueue_t *ioqueue;
     pj_ioqueue_callback ioqueue_cb;
     unsigned i;
-    int addrlen;
     pj_status_t status;
 
     /* Create pool. */
     pool = pjsip_endpt_create_pool(endpt, "udp%p", PJSIP_POOL_LEN_TRANSPORT, 
-			       PJSIP_POOL_INC_TRANSPORT);
+				   PJSIP_POOL_INC_TRANSPORT);
     if (!pool)
 	return PJ_ENOMEM;
 
+    /* Create the UDP transport object. */
     tp = pj_pool_zalloc(pool, sizeof(struct udp_transport));
+
+    /* Save pool. */
     tp->base.pool = pool;
-    tp->base.endpt = endpt;
 
-    /* Init type, type_name, and flag */
-    tp->base.type = PJSIP_TRANSPORT_UDP;
-    pj_native_strcpy(tp->base.type_name, "UDP");
-    tp->base.flag = pjsip_transport_get_flag_from_type(PJSIP_TRANSPORT_UDP);
-
-    /* Init addresses. */
-    addrlen = sizeof(tp->base.local_addr);
-    status = pj_sock_getsockname(sock, &tp->base.local_addr, &addrlen);
-    if (status != PJ_SUCCESS) {
-	pjsip_endpt_destroy_pool(endpt, pool);
-	return status;
-    }
-    pj_memcpy(&tp->base.public_addr, pub_addr, sizeof(pj_sockaddr_in));
-    tp->base.rem_addr.sin_family = PJ_AF_INET;
+    /* Object name. */
+    pj_sprintf(tp->base.obj_name, "udp%p", tp);
 
     /* Init reference counter. */
     status = pj_atomic_create(pool, 0, &tp->base.ref_cnt);
@@ -296,22 +292,65 @@
     if (status != PJ_SUCCESS)
 	goto on_error;
 
+    /* Set type. */
+    tp->base.key.type = PJSIP_TRANSPORT_UDP;
+
+    /* Remote address is left zero (except the family) */
+    tp->base.key.rem_addr.sa_family = PJ_AF_INET;
+
+    /* Type name. */
+    tp->base.type_name = "UDP";
+
+    /* Transport flag */
+    tp->base.flag = pjsip_transport_get_flag_from_type(PJSIP_TRANSPORT_UDP);
+
+
+    /* Length of addressess. */
+    tp->base.addr_len = sizeof(pj_sockaddr_in);
+
+    /* Init local address. */
+    status = pj_sock_getsockname(sock, &tp->base.local_addr, 
+				 &tp->base.addr_len);
+    if (status != PJ_SUCCESS)
+	goto on_error;
+
+    /* Init address name (published address) */
+    pj_strdup_with_null(pool, &tp->base.local_name.host, &a_name->host);
+    tp->base.local_name.port = a_name->port;
+
+    /* Init remote name. */
+    tp->base.remote_name.host = pj_str("0.0.0.0");
+    tp->base.remote_name.port = 0;
+
+    /* Transport info. */
+    tp->base.info = pj_pool_alloc(pool, 80);
+    pj_sprintf(tp->base.info, "udp %s:%d [published as %s:%d]",
+			      pj_inet_ntoa(((pj_sockaddr_in*)&tp->base.local_addr)->sin_addr),
+			      pj_ntohs(((pj_sockaddr_in*)&tp->base.local_addr)->sin_port),
+			      tp->base.local_name.host,
+			      tp->base.local_name.port);
+
+    /* Set endpoint. */
+    tp->base.endpt = endpt;
+
+    /* Transport manager and timer will be initialized by tpmgr */
+
     /* Attach socket. */
     tp->sock = sock;
 
     /* Register to ioqueue. */
     ioqueue = pjsip_endpt_get_ioqueue(endpt);
     pj_memset(&ioqueue_cb, 0, sizeof(ioqueue_cb));
-    ioqueue_cb.on_read_complete = &on_read_complete;
-    ioqueue_cb.on_write_complete = &on_write_complete;
+    ioqueue_cb.on_read_complete = &udp_on_read_complete;
+    ioqueue_cb.on_write_complete = &udp_on_write_complete;
     status = pj_ioqueue_register_sock(pool, ioqueue, tp->sock, tp, 
 				      &ioqueue_cb, &tp->key);
     if (status != PJ_SUCCESS)
 	goto on_error;
 
     /* Set functions. */
-    tp->base.send_msg = &transport_send_msg;
-    tp->base.destroy = &transport_destroy;
+    tp->base.send_msg = &udp_send_msg;
+    tp->base.destroy = &udp_destroy;
 
     /* This is a permanent transport, so we initialize the ref count
      * to one so that transport manager don't destroy this transport
@@ -330,8 +369,8 @@
     tp->rdata_cnt = 0;
     for (i=0; i<async_cnt; ++i) {
 	pj_pool_t *rdata_pool = pjsip_endpt_create_pool(endpt, "rtd%p", 
-							PJSIP_POOL_LEN_RDATA,
-							PJSIP_POOL_INC_RDATA);
+							PJSIP_POOL_RDATA_LEN,
+							PJSIP_POOL_RDATA_INC);
 	if (!rdata_pool) {
 	    pj_atomic_set(tp->base.ref_cnt, 0);
 	    pjsip_transport_unregister(tp->base.tpmgr, &tp->base);
@@ -339,6 +378,8 @@
 	}
 
 	tp->rdata[i] = pj_pool_zalloc(rdata_pool, sizeof(pjsip_rx_data));
+
+	/* Init tp_info part. */
 	tp->rdata[i]->tp_info.pool = rdata_pool;
 	tp->rdata[i]->tp_info.transport = &tp->base;
 	pj_ioqueue_op_key_init(&tp->rdata[i]->tp_info.op_key.op_key, 
@@ -352,17 +393,17 @@
 	pj_ssize_t size;
 
 	size = sizeof(tp->rdata[i]->pkt_info.packet);
-	tp->rdata[i]->pkt_info.addr_len = sizeof(tp->rdata[i]->pkt_info.addr);
+	tp->rdata[i]->pkt_info.src_addr_len = sizeof(tp->rdata[i]->pkt_info.src_addr);
 	status = pj_ioqueue_recvfrom(tp->key, 
 				     &tp->rdata[i]->tp_info.op_key.op_key,
 				     tp->rdata[i]->pkt_info.packet,
 				     &size, PJ_IOQUEUE_ALWAYS_ASYNC,
-				     &tp->rdata[i]->pkt_info.addr,
-				     &tp->rdata[i]->pkt_info.addr_len);
+				     &tp->rdata[i]->pkt_info.src_addr,
+				     &tp->rdata[i]->pkt_info.src_addr_len);
 	if (status == PJ_SUCCESS) {
 	    pj_assert(!"Shouldn't happen because PJ_IOQUEUE_ALWAYS_ASYNC!");
-	    on_read_complete(tp->key, &tp->rdata[i]->tp_info.op_key.op_key, 
-			     size);
+	    udp_on_read_complete(tp->key, &tp->rdata[i]->tp_info.op_key.op_key,
+				 size);
 	} else if (status != PJ_EPENDING) {
 	    /* Error! */
 	    pjsip_transport_unregister(tp->base.tpmgr, &tp->base);
@@ -375,23 +416,25 @@
     return PJ_SUCCESS;
 
 on_error:
-    transport_destroy((pjsip_transport*)tp);
+    udp_destroy((pjsip_transport*)tp);
     return status;
 }
 
 /*
  * pjsip_udp_transport_start()
  *
- * Start an UDP transport/listener.
+ * Create a UDP socket in the specified address and start a transport.
  */
 PJ_DEF(pj_status_t) pjsip_udp_transport_start( pjsip_endpoint *endpt,
 					       const pj_sockaddr_in *local,
-					       const pj_sockaddr_in *pub_addr,
+					       const pjsip_host_port *a_name,
 					       unsigned async_cnt,
 					       pjsip_transport **p_transport)
 {
     pj_sock_t sock;
     pj_status_t status;
+    char addr_buf[16];
+    pjsip_host_port bound_name;
 
     status = pj_sock_socket(PJ_AF_INET, PJ_SOCK_DGRAM, 0, &sock);
     if (status != PJ_SUCCESS)
@@ -403,7 +446,14 @@
 	return status;
     }
 
-    return pjsip_udp_transport_attach( endpt, sock, pub_addr, async_cnt, 
+    if (a_name == NULL) {
+	a_name = &bound_name;
+	bound_name.host.ptr = addr_buf;
+	pj_strcpy2(&bound_name.host, pj_inet_ntoa(local->sin_addr));
+	bound_name.port = pj_ntohs(local->sin_port);
+    }
+
+    return pjsip_udp_transport_attach( endpt, sock, a_name, async_cnt, 
 				       p_transport );
 }
 
diff --git a/pjsip/src/pjsip/sip_util.c b/pjsip/src/pjsip/sip_util.c
index 57ef6fb..c227eff 100644
--- a/pjsip/src/pjsip/sip_util.c
+++ b/pjsip/src/pjsip/sip_util.c
@@ -676,7 +676,7 @@
 PJ_DEF(pj_status_t) pjsip_get_response_addr(pj_pool_t *pool,
 					    const pjsip_transport *req_transport,
 					    const pjsip_via_hdr *via,
-					    pjsip_host_port *send_addr)
+					    pjsip_host_info *send_addr)
 {
     /* Determine the destination address (section 18.2.2):
      * - for TCP, SCTP, or TLS, send the response using the transport where
@@ -688,27 +688,25 @@
      * - otherwise send to the address in sent-by.
      */
     send_addr->flag = req_transport->flag;
-    send_addr->type = req_transport->type;
+    send_addr->type = req_transport->key.type;
 
     if (PJSIP_TRANSPORT_IS_RELIABLE(req_transport)) {
-	const pj_sockaddr_in *remote_addr;
-	remote_addr = &req_transport->rem_addr;
-	pj_strdup2(pool, &send_addr->host, 
-		   pj_inet_ntoa(remote_addr->sin_addr));
-	send_addr->port = pj_sockaddr_in_get_port(remote_addr);
+	pj_strdup( pool, &send_addr->addr.host, 
+		   &req_transport->remote_name.host);
+	send_addr->addr.port = req_transport->remote_name.port;
 
     } else {
 	/* Set the host part */
 	if (via->maddr_param.slen) {
-	    pj_strdup(pool, &send_addr->host, &via->maddr_param);
+	    pj_strdup(pool, &send_addr->addr.host, &via->maddr_param);
 	} else if (via->recvd_param.slen) {
-	    pj_strdup(pool, &send_addr->host, &via->recvd_param);
+	    pj_strdup(pool, &send_addr->addr.host, &via->recvd_param);
 	} else {
-	    pj_strdup(pool, &send_addr->host, &via->sent_by.host);
+	    pj_strdup(pool, &send_addr->addr.host, &via->sent_by.host);
 	}
 
 	/* Set the port */
-	send_addr->port = via->sent_by.port;
+	send_addr->addr.port = via->sent_by.port;
     }
 
     return PJ_SUCCESS;
diff --git a/pjsip/src/test-pjsip/msg.c b/pjsip/src/test-pjsip/msg_test.c
similarity index 100%
rename from pjsip/src/test-pjsip/msg.c
rename to pjsip/src/test-pjsip/msg_test.c
diff --git a/pjsip/src/test-pjsip/uri.c b/pjsip/src/test-pjsip/uri_test.c
similarity index 100%
rename from pjsip/src/test-pjsip/uri.c
rename to pjsip/src/test-pjsip/uri_test.c