Index: pjproject/trunk/pjsip/include/pjsip-ua/sip_regc.h
===================================================================
--- pjproject/trunk/pjsip/include/pjsip-ua/sip_regc.h	(revision 877)
+++ pjproject/trunk/pjsip/include/pjsip-ua/sip_regc.h	(revision 879)
@@ -27,4 +27,5 @@
 #include <pjsip/sip_types.h>
 #include <pjsip/sip_auth.h>
+#include <pjsip/sip_transport.h>
 
 
@@ -199,4 +200,30 @@
 					      const pjsip_route_hdr*route_set);
 
+
+/**
+ * Lock/bind client registration to a specific transport/listener. 
+ * This is optional, as normally transport will be selected automatically
+ * based on the destination of requests upon resolver completion. 
+ * When the client registration is explicitly bound to the specific 
+ * transport/listener, all UAC transactions originated by the client
+ * registration will use the specified transport/listener when sending 
+ * outgoing requests.
+ *
+ * Note that this doesn't affect the Contact header set for this client
+ * registration. Application must manually update the Contact header if
+ * necessary, to adjust the address according to the transport being
+ * selected.
+ *
+ * @param regc	    The client registration instance.
+ * @param sel	    Transport selector containing the specification of
+ *		    transport or listener to be used by this session
+ *		    to send requests.
+ *
+ * @return	    PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_regc_set_transport(pjsip_regc *regc,
+					      const pjsip_tpselector *sel);
+
+
 /**
  * Add headers to be added to outgoing REGISTER requests.
Index: pjproject/trunk/pjsip/include/pjsip/sip_dialog.h
===================================================================
--- pjproject/trunk/pjsip/include/pjsip/sip_dialog.h	(revision 877)
+++ pjproject/trunk/pjsip/include/pjsip/sip_dialog.h	(revision 879)
@@ -29,4 +29,5 @@
 #include <pjsip/sip_auth.h>
 #include <pjsip/sip_errno.h>
+#include <pjsip/sip_transport.h>
 #include <pj/sock.h>
 #include <pj/assert.h>
@@ -135,4 +136,7 @@
     int			tsx_count;  /**< Number of pending transactions.    */
 
+    /** Transport selector. */
+    pjsip_tpselector	tp_sel;
+
     /* Dialog usages. */
     unsigned		usage_cnt;  /**< Number of registered usages.	    */
@@ -225,4 +229,28 @@
 
 /**
+ * Lock/bind dialog to a specific transport/listener. This is optional,
+ * as normally transport will be selected automatically based on the 
+ * destination of requests upon resolver completion. When the dialog is 
+ * explicitly bound to the specific transport/listener, all UAC transactions
+ * originated by this dialog will use the specified transport/listener
+ * when sending outgoing requests.
+ *
+ * Note that this doesn't affect the Contact header generated by this
+ * dialog. Application must manually update the Contact header if
+ * necessary, to adjust the address according to the transport being
+ * selected.
+ *
+ * @param dlg	    The dialog instance.
+ * @param sel	    Transport selector containing the specification of
+ *		    transport or listener to be used by this dialog
+ *		    to send requests.
+ *
+ * @return	    PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_set_transport(pjsip_dialog *dlg,
+					     const pjsip_tpselector *sel);
+
+
+/**
  * Create a new (forked) dialog on receipt on forked response in rdata. 
  * The new dialog will be created from original_dlg, except that it will have
Index: pjproject/trunk/pjsip/include/pjsip/sip_endpoint.h
===================================================================
--- pjproject/trunk/pjsip/include/pjsip/sip_endpoint.h	(revision 877)
+++ pjproject/trunk/pjsip/include/pjsip/sip_endpoint.h	(revision 879)
@@ -353,9 +353,19 @@
 /**
  * Find a SIP transport suitable for sending SIP message to the specified
- * address. This function will complete asynchronously when the transport is
- * ready (for example, when TCP socket is connected), and when it completes,
- * the callback will be called with the status of the operation.
- *
- * @see pjsip_transport_get
+ * address. If transport selector ("sel") is set, then the function will
+ * check if the transport selected is suitable to send requests to the
+ * specified address.
+ *
+ * @see pjsip_tpmgr_acquire_transport
+ *
+ * @param endpt	    The SIP endpoint instance.
+ * @param type	    The type of transport to be acquired.
+ * @param remote    The remote address to send message to.
+ * @param addr_len  Length of the remote address.
+ * @param sel	    Optional pointer to transport selector instance which is
+ *		    used to find explicit transport, if required.
+ * @param p_tp	    Pointer to receive the transport instance, if one is found.
+ *
+ * @return	    PJ_SUCCESS on success, or the appropriate error code.
  */
 PJ_DECL(pj_status_t) 
@@ -364,5 +374,6 @@
 			       const pj_sockaddr_t *remote,
 			       int addr_len,
-			       pjsip_transport **p_transport);
+			       const pjsip_tpselector *sel,
+			       pjsip_transport **p_tp);
 
 
Index: pjproject/trunk/pjsip/include/pjsip/sip_errno.h
===================================================================
--- pjproject/trunk/pjsip/include/pjsip/sip_errno.h	(revision 877)
+++ pjproject/trunk/pjsip/include/pjsip/sip_errno.h	(revision 879)
@@ -215,4 +215,12 @@
  */
 #define PJSIP_EBUFDESTROYED     (PJSIP_ERRNO_START_PJSIP + 63)	/* 171063 */
+/**
+ * @hideinitializer
+ * Unsuitable transport selected. This error occurs when application
+ * has explicitly requested to use a particular transport/listener,
+ * but the selected transport is not suitable to send request to
+ * the specified destination.
+ */
+#define PJSIP_ETPNOTSUITABLE	(PJSIP_ERRNO_START_PJSIP + 64)	/* 171064 */
 
 
Index: pjproject/trunk/pjsip/include/pjsip/sip_transaction.h
===================================================================
--- pjproject/trunk/pjsip/include/pjsip/sip_transaction.h	(revision 877)
+++ pjproject/trunk/pjsip/include/pjsip/sip_transaction.h	(revision 879)
@@ -27,4 +27,5 @@
 #include <pjsip/sip_msg.h>
 #include <pjsip/sip_util.h>
+#include <pjsip/sip_transport.h>
 #include <pj/timer.h>
 
@@ -97,4 +98,5 @@
     pj_uint32_t			hashed_key;	/**< Key's hashed value.    */
     pj_str_t			branch;         /**< The branch Id.         */
+    pjsip_tpselector		tp_sel;		/**< Transport selector.    */
 
     /*
@@ -215,4 +217,24 @@
 
 /**
+ * Lock/bind transaction to a specific transport/listener. This is optional,
+ * as normally transport will be selected automatically based on the 
+ * destination of the request upon resolver completion. Also it's only valid
+ * for UAC transaction (to send outgoing request), since for UAS the
+ * transport will be selected according to rules about handling incoming
+ * request (most likely it will use the transport where the request is
+ * coming from if ";rport" parameter is present in Via header).
+ *
+ * @param tsx	    The UAC transaction.
+ * @param sel	    Transport selector containing the specification of
+ *		    transport or listener to be used by this transaction
+ *		    to send requests.
+ *
+ * @return	    PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_tsx_set_transport(pjsip_transaction *tsx,
+					     const pjsip_tpselector *sel);
+
+
+/**
  * Call this function to manually feed a message to the transaction.
  * For UAS transaction, application MUST call this function after
Index: pjproject/trunk/pjsip/include/pjsip/sip_transport.h
===================================================================
--- pjproject/trunk/pjsip/include/pjsip/sip_transport.h	(revision 877)
+++ pjproject/trunk/pjsip/include/pjsip/sip_transport.h	(revision 879)
@@ -55,4 +55,11 @@
  *
  *****************************************************************************/
+
+/*
+ * Forward declaration for transport factory (since it is referenced by
+ * the transport factory itself).
+ */
+typedef struct pjsip_tpfactory pjsip_tpfactory;
+
 
 /**
@@ -157,4 +164,74 @@
 
 
+
+/*****************************************************************************
+ *
+ * TRANSPORT SELECTOR.
+ *
+ *****************************************************************************/
+
+/**
+ * This structure describes the type of data in pjsip_tpselector.
+ */
+typedef enum pjsip_tpselector_type
+{
+    /** Transport is not specified. */
+    PJSIP_TPSELECTOR_NONE,
+
+    /** Use the specific transport to send request. */
+    PJSIP_TPSELECTOR_TRANSPORT,
+
+    /** Use the specific listener to send request. */
+    PJSIP_TPSELECTOR_LISTENER,
+
+} pjsip_tpselector_type;
+
+
+/**
+ * This structure describes the transport/listener preference to be used
+ * when sending outgoing requests.
+ *
+ * Normally transport will be selected automatically according to rules about
+ * sending requests. But some applications (such as proxies or B2BUAs) may 
+ * want to explicitly use specific transport to send requests, for example
+ * when they want to make sure that outgoing request should go from a specific
+ * network interface.
+ *
+ * The pjsip_tpselector structure is used for that purpose, i.e. to allow
+ * application specificly request that a particular transport/listener
+ * should be used to send request. This structure is used when calling
+ * pjsip_tsx_set_transport() and pjsip_dlg_set_transport().
+ */
+typedef struct pjsip_tpselector
+{
+    /** The type of data in the union */
+    pjsip_tpselector_type   type;
+
+    /** Union representing the transport/listener criteria to be used. */
+    union {
+	pjsip_transport	*transport;
+	pjsip_tpfactory	*listener;
+    } u;
+
+} pjsip_tpselector;
+
+
+/**
+ * Add transport/listener reference in the selector to prevent the specified
+ * transport/listener from being destroyed while application still has
+ * reference to it.
+ *
+ * @param sel	The transport selector.
+ */
+PJ_DECL(void) pjsip_tpselector_add_ref(pjsip_tpselector *sel);
+
+
+/**
+ * Decrement transport/listener reference in the selector.
+ * @param sel	The transport selector
+ */
+PJ_DECL(void) pjsip_tpselector_dec_ref(pjsip_tpselector *sel);
+
+
 /*****************************************************************************
  *
@@ -432,4 +509,12 @@
 	int		     dst_port;	    /**< Destination port.	*/
     } tp_info;
+
+    /** 
+     * Transport selector, to specify which transport to be used. 
+     * The value here must be set with pjsip_tx_data_set_transport(),
+     * to allow reference counter to be set properly.
+     */
+    pjsip_tpselector	    tp_sel;
+
 };
 
@@ -499,4 +584,18 @@
  */
 PJ_DECL(char*) pjsip_tx_data_get_info( pjsip_tx_data *tdata );
+
+/**
+ * Set the explicit transport to be used when sending this transmit data.
+ * Application should not need to call this function, but rather use
+ * pjsip_tsx_set_transport() and pjsip_dlg_set_transport() instead (which
+ * will call this function).
+ *
+ * @param tdata	    The transmit buffer.
+ * @param sel	    Transport selector.
+ *
+ * @return	    PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_tx_data_set_transport(pjsip_tx_data *tdata,
+						 const pjsip_tpselector *sel);
 
 
@@ -707,10 +806,4 @@
  *****************************************************************************/
 
-/*
- * Forward declaration for transport factory (since it is referenced by
- * the transport factory itself).
- */
-typedef struct pjsip_tpfactory pjsip_tpfactory;
-
 
 /**
@@ -860,4 +953,18 @@
  * Find transport to be used to send message to remote destination. If no
  * suitable transport is found, a new one will be created.
+ *
+ * This is an internal function since normally application doesn't have access
+ * to transport manager. Application should use pjsip_endpt_acquire_transport()
+ * instead.
+ *
+ * @param mgr	    The transport manager instance.
+ * @param type	    The type of transport to be acquired.
+ * @param remote    The remote address to send message to.
+ * @param addr_len  Length of the remote address.
+ * @param sel	    Optional pointer to transport selector instance which is
+ *		    used to find explicit transport, if required.
+ * @param tp	    Pointer to receive the transport instance, if one is found.
+ *
+ * @return	    PJ_SUCCESS on success, or the appropriate error code.
  */
 PJ_DECL(pj_status_t) pjsip_tpmgr_acquire_transport(pjsip_tpmgr *mgr,
@@ -865,4 +972,5 @@
 						   const pj_sockaddr_t *remote,
 						   int addr_len,
+						   const pjsip_tpselector *sel,
 						   pjsip_transport **tp);
 
Index: pjproject/trunk/pjsip/src/pjsip-ua/sip_reg.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsip-ua/sip_reg.c	(revision 877)
+++ pjproject/trunk/pjsip/src/pjsip-ua/sip_reg.c	(revision 879)
@@ -77,4 +77,7 @@
     pj_time_val			 next_reg;
     pj_timer_entry		 timer;
+
+    /* Transport selector */
+    pjsip_tpselector		 tp_sel;
 };
 
@@ -125,4 +128,5 @@
 	regc->cb = NULL;
     } else {
+	pjsip_tpselector_dec_ref(&regc->tp_sel);
 	pjsip_endpt_release_pool(regc->endpt, regc->pool);
     }
@@ -310,4 +314,21 @@
     return PJ_SUCCESS;
 }
+
+
+/*
+ * Bind client registration to a specific transport/listener. 
+ */
+PJ_DEF(pj_status_t) pjsip_regc_set_transport( pjsip_regc *regc,
+					      const pjsip_tpselector *sel)
+{
+    PJ_ASSERT_RETURN(regc && sel, PJ_EINVAL);
+
+    pjsip_tpselector_dec_ref(&regc->tp_sel);
+    pj_memcpy(&regc->tp_sel, sel, sizeof(*sel));
+    pjsip_tpselector_add_ref(&regc->tp_sel);
+
+    return PJ_SUCCESS;
+}
+
 
 PJ_DEF(pj_status_t) pjsip_regc_add_headers( pjsip_regc *regc,
Index: pjproject/trunk/pjsip/src/pjsip/sip_dialog.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsip/sip_dialog.c	(revision 877)
+++ pjproject/trunk/pjsip/src/pjsip/sip_dialog.c	(revision 879)
@@ -507,4 +507,32 @@
 
 /*
+ * Bind dialog to a specific transport/listener.
+ */
+PJ_DEF(pj_status_t) pjsip_dlg_set_transport( pjsip_dialog *dlg,
+					     const pjsip_tpselector *sel)
+{
+    /* Validate */
+    PJ_ASSERT_RETURN(dlg && sel, PJ_EINVAL);
+
+    /* Start locking the dialog. */
+    pjsip_dlg_inc_lock(dlg);
+
+    /* Decrement reference counter of previous transport selector */
+    pjsip_tpselector_dec_ref(&dlg->tp_sel);
+
+    /* Copy transport selector structure .*/
+    pj_memcpy(&dlg->tp_sel, sel, sizeof(*sel));
+
+    /* Increment reference counter */
+    pjsip_tpselector_add_ref(&dlg->tp_sel);
+
+    /* Unlock dialog. */
+    pjsip_dlg_dec_lock(dlg);
+
+    return PJ_SUCCESS;
+}
+
+
+/*
  * Create forked dialog from a response.
  */
@@ -1066,4 +1094,8 @@
 	    goto on_error;
 
+	/* Set transport selector */
+	status = pjsip_tsx_set_transport(tsx, &dlg->tp_sel);
+	pj_assert(status == PJ_SUCCESS);
+
 	/* Attach this dialog to the transaction, so that user agent
 	 * will dispatch events to this dialog.
@@ -1087,4 +1119,8 @@
 
     } else {
+	/* Set transport selector */
+	pjsip_tx_data_set_transport(tdata, &dlg->tp_sel);
+
+	/* Send request */
 	status = pjsip_endpt_send_request_stateless(dlg->endpt, tdata, 
 						    NULL, NULL);
Index: pjproject/trunk/pjsip/src/pjsip/sip_endpoint.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsip/sip_endpoint.c	(revision 877)
+++ pjproject/trunk/pjsip/src/pjsip/sip_endpoint.c	(revision 879)
@@ -1044,8 +1044,9 @@
 						  const pj_sockaddr_t *remote,
 						  int addr_len,
+						  const pjsip_tpselector *sel,
 						  pjsip_transport **transport)
 {
     return pjsip_tpmgr_acquire_transport(endpt->transport_mgr, type, 
-					 remote, addr_len, transport);
+					 remote, addr_len, sel, transport);
 }
 
Index: pjproject/trunk/pjsip/src/pjsip/sip_transaction.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsip/sip_transaction.c	(revision 877)
+++ pjproject/trunk/pjsip/src/pjsip/sip_transaction.c	(revision 879)
@@ -932,4 +932,7 @@
 	tsx->transport = NULL;
     }
+    /* Decrement reference counter in transport selector */
+    pjsip_tpselector_dec_ref(&tsx->tp_sel);
+
     /* Free last transmitted message. */
     if (tsx->last_tx) {
@@ -1364,4 +1367,34 @@
 
 /*
+ * Bind transaction to a specific transport/listener. 
+ */
+PJ_DEF(pj_status_t) pjsip_tsx_set_transport(pjsip_transaction *tsx,
+					    const pjsip_tpselector *sel)
+{
+    struct tsx_lock_data lck;
+
+    /* Must be UAC transaction */
+    PJ_ASSERT_RETURN(tsx && sel && tsx->role == PJSIP_ROLE_UAC, PJ_EINVAL);
+
+    /* Start locking the transaction. */
+    lock_tsx(tsx, &lck);
+
+    /* Decrement reference counter of previous transport selector */
+    pjsip_tpselector_dec_ref(&tsx->tp_sel);
+
+    /* Copy transport selector structure .*/
+    pj_memcpy(&tsx->tp_sel, sel, sizeof(*sel));
+
+    /* Increment reference counter */
+    pjsip_tpselector_add_ref(&tsx->tp_sel);
+
+    /* Unlock transaction. */
+    unlock_tsx(tsx, &lck);
+
+    return PJ_SUCCESS;
+}
+
+
+/*
  * Set transaction status code and reason.
  */
@@ -1424,9 +1457,15 @@
     /* Dispatch to transaction. */
     lock_tsx(tsx, &lck);
+
+    /* Set transport selector to tdata */
+    pjsip_tx_data_set_transport(tdata, &tsx->tp_sel);
+
+    /* Dispatch to state handler */
     status = (*tsx->state_handler)(tsx, &event);
+
     unlock_tsx(tsx, &lck);
 
-    /* Will always decrement tdata reference counter
-     * (consistent with other send functions.
+    /* Only decrement reference counter when it returns success.
+     * (This is the specification from the .PDF design document).
      */
     if (status == PJ_SUCCESS) {
Index: pjproject/trunk/pjsip/src/pjsip/sip_transport.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsip/sip_transport.c	(revision 877)
+++ pjproject/trunk/pjsip/src/pjsip/sip_transport.c	(revision 879)
@@ -260,4 +260,35 @@
 }
 
+
+/*****************************************************************************
+ *
+ * TRANSPORT SELECTOR
+ *
+ *****************************************************************************/
+
+/*
+ * Add transport/listener reference in the selector.
+ */
+PJ_DEF(void) pjsip_tpselector_add_ref(pjsip_tpselector *sel)
+{
+    if (sel->type == PJSIP_TPSELECTOR_TRANSPORT && sel->u.transport != NULL)
+	pjsip_transport_add_ref(sel->u.transport);
+    else if (sel->type == PJSIP_TPSELECTOR_LISTENER && sel->u.listener != NULL)
+	; /* Hmm.. looks like we don't have reference counter for listener */
+}
+
+
+/*
+ * Decrement transport/listener reference in the selector.
+ */
+PJ_DEF(void) pjsip_tpselector_dec_ref(pjsip_tpselector *sel)
+{
+    if (sel->type == PJSIP_TPSELECTOR_TRANSPORT && sel->u.transport != NULL)
+	pjsip_transport_dec_ref(sel->u.transport);
+    else if (sel->type == PJSIP_TPSELECTOR_LISTENER && sel->u.listener != NULL)
+	; /* Hmm.. looks like we don't have reference counter for listener */
+}
+
+
 /*****************************************************************************
  *
@@ -331,4 +362,5 @@
 	PJ_LOG(5,(tdata->obj_name, "Destroying txdata %s",
 		  pjsip_tx_data_get_info(tdata)));
+	pjsip_tpselector_dec_ref(&tdata->tp_sel);
 #if defined(PJ_DEBUG) && PJ_DEBUG!=0
 	pj_atomic_dec( tdata->mgr->tdata_counter );
@@ -408,4 +440,22 @@
     return tdata->info;
 }
+
+PJ_DEF(pj_status_t) pjsip_tx_data_set_transport(pjsip_tx_data *tdata,
+						const pjsip_tpselector *sel)
+{
+    PJ_ASSERT_RETURN(tdata && sel, PJ_EINVAL);
+
+    pj_lock_acquire(tdata->lock);
+
+    pjsip_tpselector_dec_ref(&tdata->tp_sel);
+
+    pj_memcpy(&tdata->tp_sel, sel, sizeof(*sel));
+    pjsip_tpselector_add_ref(&tdata->tp_sel);
+
+    pj_lock_release(tdata->lock);
+
+    return PJ_SUCCESS;
+}
+
 
 PJ_DEF(char*) pjsip_rx_data_get_info(pjsip_rx_data *rdata)
@@ -912,5 +962,5 @@
 	pj_sockaddr_in_init(&remote, NULL, 0);
 	status = pjsip_tpmgr_acquire_transport(tpmgr, type, &remote,
-					       sizeof(remote), &tp);
+					       sizeof(remote), NULL, &tp);
 
 	if (status == PJ_SUCCESS) {
@@ -1201,9 +1251,7 @@
 						  const pj_sockaddr_t *remote,
 						  int addr_len,
+						  const pjsip_tpselector *sel,
 						  pjsip_transport **tp)
 {
-    struct transport_key key;
-    int key_len;
-    pjsip_transport *transport;
     pjsip_tpfactory *factory;
     pj_status_t status;
@@ -1216,72 +1264,133 @@
     pj_lock_acquire(mgr->lock);
 
-    key_len = sizeof(key.type) + addr_len;
-
-    /* First try to get exact destination. */
-    key.type = type;
-    pj_memcpy(&key.addr, remote, addr_len);
-
-    transport = pj_hash_get(mgr->table, &key, key_len, NULL);
-    if (transport == NULL) {
-	unsigned flag = pjsip_transport_get_flag_from_type(type);
-	const pj_sockaddr *remote_addr = (const pj_sockaddr*)remote;
-
-	/* Ignore address for loop transports. */
-	if (type == PJSIP_TRANSPORT_LOOP ||
-	         type == PJSIP_TRANSPORT_LOOP_DGRAM)
-	{
-	    pj_sockaddr_in *addr = (pj_sockaddr_in*)&key.addr;
-
-	    pj_bzero(addr, sizeof(pj_sockaddr_in));
-	    key_len = sizeof(key.type) + sizeof(pj_sockaddr_in);
-	    transport = pj_hash_get(mgr->table, &key, key_len, NULL);
-	}
-	/* For datagram INET transports, try lookup with zero address.
+    /* If transport is specified, then just use it if it is suitable
+     * for the destination.
+     */
+    if (sel && sel->type == PJSIP_TPSELECTOR_TRANSPORT &&
+	sel->u.transport) 
+    {
+	pjsip_transport *seltp = sel->u.transport;
+
+	/* See if the transport is (not) suitable */
+	if (seltp->key.type != type) {
+	    pj_lock_release(mgr->lock);
+	    return PJSIP_ETPNOTSUITABLE;
+	}
+
+	/* We could also verify that the destination address is reachable
+	 * from this transport (i.e. both are equal), but if application
+	 * has requested a specific transport to be used, assume that
+	 * it knows what to do.
+	 *
+	 * In other words, I don't think destination verification is a good
+	 * idea for now.
 	 */
-	else if ((flag & PJSIP_TRANSPORT_DATAGRAM) && 
-	         (remote_addr->sa_family == PJ_AF_INET)) 
-	{
-	    pj_sockaddr_in *addr = (pj_sockaddr_in*)&key.addr;
-
-	    pj_bzero(addr, sizeof(pj_sockaddr_in));
-	    addr->sin_family = PJ_AF_INET;
-
-	    key_len = sizeof(key.type) + sizeof(pj_sockaddr_in);
-	    transport = pj_hash_get(mgr->table, &key, key_len, NULL);
-	}
-    }
+
+	/* Transport looks to be suitable to use, so just use it. */
+	pjsip_transport_add_ref(seltp);
+	pj_lock_release(mgr->lock);
+	*tp = seltp;
+
+	TRACE_((THIS_FILE, "Transport %s acquired", seltp->obj_name));
+	return PJ_SUCCESS;
+
+
+    } else if (sel && sel->type == PJSIP_TPSELECTOR_LISTENER &&
+	       sel->u.listener)
+    {
+	/* Application has requested that a specific listener is to
+	 * be used. In this case, skip transport hash table lookup.
+	 */
+
+	/* Verify that the listener type matches the destination type */
+	if (sel->u.listener->type != type) {
+	    pj_lock_release(mgr->lock);
+	    return PJSIP_ETPNOTSUITABLE;
+	}
+
+	/* We'll use this listener to create transport */
+	factory = sel->u.listener;
+
+    } else {
+
+	/*
+	 * This is the "normal" flow, where application doesn't specify
+	 * specific transport/listener to be used to send message to.
+	 * In this case, lookup the transport from the hash table.
+	 */
+	struct transport_key key;
+	int key_len;
+	pjsip_transport *transport;
+
+	key_len = sizeof(key.type) + addr_len;
+
+	/* First try to get exact destination. */
+	key.type = type;
+	pj_memcpy(&key.addr, remote, addr_len);
+
+	transport = pj_hash_get(mgr->table, &key, key_len, NULL);
+	if (transport == NULL) {
+	    unsigned flag = pjsip_transport_get_flag_from_type(type);
+	    const pj_sockaddr *remote_addr = (const pj_sockaddr*)remote;
+
+	    /* Ignore address for loop transports. */
+	    if (type == PJSIP_TRANSPORT_LOOP ||
+		     type == PJSIP_TRANSPORT_LOOP_DGRAM)
+	    {
+		pj_sockaddr_in *addr = (pj_sockaddr_in*)&key.addr;
+
+		pj_bzero(addr, sizeof(pj_sockaddr_in));
+		key_len = sizeof(key.type) + sizeof(pj_sockaddr_in);
+		transport = pj_hash_get(mgr->table, &key, key_len, NULL);
+	    }
+	    /* For datagram INET transports, try lookup with zero address.
+	     */
+	    else if ((flag & PJSIP_TRANSPORT_DATAGRAM) && 
+		     (remote_addr->sa_family == PJ_AF_INET)) 
+	    {
+		pj_sockaddr_in *addr = (pj_sockaddr_in*)&key.addr;
+
+		pj_bzero(addr, sizeof(pj_sockaddr_in));
+		addr->sin_family = PJ_AF_INET;
+
+		key_len = sizeof(key.type) + sizeof(pj_sockaddr_in);
+		transport = pj_hash_get(mgr->table, &key, key_len, NULL);
+	    }
+	}
+
+	if (transport!=NULL && !transport->is_shutdown) {
+	    /*
+	     * Transport found!
+	     */
+	    pjsip_transport_add_ref(transport);
+	    pj_lock_release(mgr->lock);
+	    *tp = transport;
+
+	    TRACE_((THIS_FILE, "Transport %s acquired", transport->obj_name));
+	    return PJ_SUCCESS;
+	}
+
+	/*
+	 * Transport not found!
+	 * Find factory that can create such transport.
+	 */
+	factory = mgr->factory_list.next;
+	while (factory != &mgr->factory_list) {
+	    if (factory->type == type)
+		break;
+	    factory = factory->next;
+	}
+
+	if (factory == &mgr->factory_list) {
+	    /* No factory can create the transport! */
+	    pj_lock_release(mgr->lock);
+	    TRACE_((THIS_FILE, "No suitable factory was found either"));
+	    return PJSIP_EUNSUPTRANSPORT;
+	}
+
+    }
+
     
-    if (transport!=NULL && !transport->is_shutdown) {
-	/*
-	 * Transport found!
-	 */
-	pjsip_transport_add_ref(transport);
-	pj_lock_release(mgr->lock);
-	*tp = transport;
-
-	TRACE_((THIS_FILE, "Transport %s acquired", transport->obj_name));
-	return PJ_SUCCESS;
-    }
-
-    /*
-     * Transport not found!
-     * Find factory that can create such transport.
-     */
-    factory = mgr->factory_list.next;
-    while (factory != &mgr->factory_list) {
-	if (factory->type == type)
-	    break;
-	factory = factory->next;
-    }
-
-    if (factory == &mgr->factory_list) {
-	/* No factory can create the transport! */
-	pj_lock_release(mgr->lock);
-	TRACE_((THIS_FILE, "No suitable factory was found either"));
-	return PJSIP_EUNSUPTRANSPORT;
-    }
-
-    TRACE_((THIS_FILE, "%s, creating new one from factory",
-	   (transport?"Transport is shutdown":"No transport found")));
+    TRACE_((THIS_FILE, "Creating new transport from factory"));
 
     /* Request factory to create transport. */
Index: pjproject/trunk/pjsip/src/pjsip/sip_util.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsip/sip_util.c	(revision 877)
+++ pjproject/trunk/pjsip/src/pjsip/sip_util.c	(revision 879)
@@ -838,4 +838,5 @@
 						cur_addr,
 						cur_addr_len,
+						&tdata->tp_sel,
 						&stateless_data->cur_transport);
 	if (status != PJ_SUCCESS) {
@@ -1112,4 +1113,5 @@
 					    &addr->entry[0].addr,
 					    addr->entry[0].addr_len,
+					    &send_state->tdata->tp_sel,
 					    &send_state->cur_transport);
     if (status != PJ_SUCCESS) {
