Index: pjproject/trunk/pjsip/include/pjsip/sip_transport_udp.h
===================================================================
--- pjproject/trunk/pjsip/include/pjsip/sip_transport_udp.h	(revision 5283)
+++ pjproject/trunk/pjsip/include/pjsip/sip_transport_udp.h	(revision 5284)
@@ -27,4 +27,5 @@
 
 #include <pjsip/sip_transport.h>
+#include <pj/sock_qos.h>
 
 PJ_BEGIN_DECL
@@ -58,4 +59,97 @@
     PJSIP_UDP_TRANSPORT_DESTROY_SOCKET	= 2
 };
+
+
+/**
+ * Settings to be specified when creating the UDP transport. Application 
+ * should initialize this structure with its default values by calling 
+ * pjsip_udp_transport_cfg_default().
+ */
+typedef struct pjsip_udp_transport_cfg
+{
+    /**
+     * Address family to use. Valid values are pj_AF_INET() and
+     * pj_AF_INET6(). Default is pj_AF_INET().
+     */
+    int			af;
+
+    /**
+     * Address to bind the socket to.
+     */
+    pj_sockaddr		bind_addr;
+
+    /**
+     * Optional published address, which is the address to be
+     * advertised as the address of this SIP transport. 
+     * By default the bound address will be used as the published address.
+     */
+    pjsip_host_port	addr_name;
+
+    /**
+     * Number of simultaneous asynchronous accept() operations to be 
+     * supported. It is recommended that the number here corresponds to 
+     * the number of processors in the system (or the number of SIP
+     * worker threads).
+     *
+     * Default: 1
+     */
+    unsigned	        async_cnt;
+
+    /**
+     * QoS traffic type to be set on this transport. When application wants
+     * to apply QoS tagging to the transport, it's preferable to set this
+     * field rather than \a qos_param fields since this is more portable.
+     *
+     * Default is QoS not set.
+     */
+    pj_qos_type		qos_type;
+
+    /**
+     * Set the low level QoS parameters to the transport. This is a lower
+     * level operation than setting the \a qos_type field and may not be
+     * supported on all platforms.
+     *
+     * Default is QoS not set.
+     */
+    pj_qos_params	qos_params;
+
+    /**
+     * Specify options to be set on the transport. 
+     *
+     * By default there is no options.
+     * 
+     */
+    pj_sockopt_params	sockopt_params;
+
+} pjsip_udp_transport_cfg;
+
+
+/**
+ * Initialize pjsip_udp_transport_cfg structure with default values for
+ * the specifed address family.
+ *
+ * @param cfg		The structure to initialize.
+ * @param af		Address family to be used.
+ */
+PJ_DECL(void) pjsip_udp_transport_cfg_default(pjsip_udp_transport_cfg *cfg,
+					      int af);
+
+
+/**
+ * Start UDP IPv4/IPv6 transport.
+ *
+ * @param endpt		The SIP endpoint.
+ * @param cfg		UDP transport settings. Application should initialize
+ *			this setting with #pjsip_udp_transport_cfg_default().
+ * @param p_transport	Pointer to receive the transport.
+ *
+ * @return		PJ_SUCCESS when the transport has been successfully
+ *			started and registered to transport manager, or
+ *			the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_udp_transport_start2(
+					pjsip_endpoint *endpt,
+					const pjsip_udp_transport_cfg *cfg,
+					pjsip_transport **p_transport);
 
 
Index: pjproject/trunk/pjsip/src/pjsip/sip_transport_udp.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsip/sip_transport_udp.c	(revision 5283)
+++ pjproject/trunk/pjsip/src/pjsip/sip_transport_udp.c	(revision 5284)
@@ -870,4 +870,79 @@
 }
 
+
+/*
+ * Initialize pjsip_udp_transport_cfg structure with default values.
+ */
+PJ_DEF(void) pjsip_udp_transport_cfg_default(pjsip_udp_transport_cfg *cfg,
+					     int af)
+{
+    pj_bzero(cfg, sizeof(*cfg));
+    cfg->af = af;
+    pj_sockaddr_init(cfg->af, &cfg->bind_addr, NULL, 0);
+    cfg->async_cnt = 1;
+}
+
+
+/*
+ * pjsip_udp_transport_start2()
+ *
+ * Create a UDP socket in the specified address and start a transport.
+ */
+PJ_DEF(pj_status_t) pjsip_udp_transport_start2(
+					pjsip_endpoint *endpt,
+					const pjsip_udp_transport_cfg *cfg,
+					pjsip_transport **p_transport)
+{
+    pj_sock_t sock;
+    pj_status_t status;
+    pjsip_host_port addr_name;
+    char addr_buf[PJ_INET6_ADDRSTRLEN];
+    pjsip_transport_type_e transport_type;
+    pj_uint16_t af;
+    int addr_len;
+
+    PJ_ASSERT_RETURN(endpt && cfg && cfg->async_cnt, PJ_EINVAL);
+
+    if (cfg->bind_addr.addr.sa_family == pj_AF_INET()) {
+	af = pj_AF_INET();
+	transport_type = PJSIP_TRANSPORT_UDP;
+	addr_len = sizeof(pj_sockaddr_in);
+    } else {
+	af = pj_AF_INET6();
+	transport_type = PJSIP_TRANSPORT_UDP6;
+	addr_len = sizeof(pj_sockaddr_in6);
+    }
+
+    status = create_socket(af, &cfg->bind_addr, addr_len, &sock);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    /* Apply QoS, if specified */
+    pj_sock_apply_qos2(sock, cfg->qos_type, &cfg->qos_params,
+		       2, THIS_FILE, "SIP UDP transport");
+
+    /* Apply sockopt, if specified */
+    if (cfg->sockopt_params.cnt)
+	pj_sock_setsockopt_params(sock, &cfg->sockopt_params);
+
+    if (cfg->addr_name.host.slen == 0) {
+	/* Address name is not specified.
+	 * Build a name based on bound address.
+	 */
+	status = get_published_name(sock, addr_buf, sizeof(addr_buf),
+				    &addr_name);
+	if (status != PJ_SUCCESS) {
+	    pj_sock_close(sock);
+	    return status;
+	}
+    } else {
+	addr_name = cfg->addr_name;
+    }
+
+    return pjsip_udp_transport_attach2(endpt, transport_type, sock,
+				       &addr_name, cfg->async_cnt,
+				       p_transport);
+}
+
 /*
  * pjsip_udp_transport_start()
@@ -881,34 +956,15 @@
 					       pjsip_transport **p_transport)
 {
-    pj_sock_t sock;
-    pj_status_t status;
-    char addr_buf[PJ_INET6_ADDRSTRLEN];
-    pjsip_host_port bound_name;
-
-    PJ_ASSERT_RETURN(endpt && async_cnt, PJ_EINVAL);
-
-    status = create_socket(pj_AF_INET(), local_a, sizeof(pj_sockaddr_in), 
-			   &sock);
-    if (status != PJ_SUCCESS)
-	return status;
-
-    if (a_name == NULL) {
-	/* Address name is not specified. 
-	 * Build a name based on bound address.
-	 */
-	status = get_published_name(sock, addr_buf, sizeof(addr_buf), 
-				    &bound_name);
-	if (status != PJ_SUCCESS) {
-	    pj_sock_close(sock);
-	    return status;
-	}
-
-	a_name = &bound_name;
-    }
-
-    return pjsip_udp_transport_attach( endpt, sock, a_name, async_cnt, 
-				       p_transport );
-}
-
+    pjsip_udp_transport_cfg cfg;
+
+    pjsip_udp_transport_cfg_default(&cfg, pj_AF_INET());
+    if (local_a)
+	pj_sockaddr_cp(&cfg.bind_addr, local_a);
+    if (a_name)
+	cfg.addr_name = *a_name;
+    cfg.async_cnt = async_cnt;
+
+    return pjsip_udp_transport_start2(endpt, &cfg, p_transport);
+}
 
 /*
@@ -923,32 +979,14 @@
 					       pjsip_transport **p_transport)
 {
-    pj_sock_t sock;
-    pj_status_t status;
-    char addr_buf[PJ_INET6_ADDRSTRLEN];
-    pjsip_host_port bound_name;
-
-    PJ_ASSERT_RETURN(endpt && async_cnt, PJ_EINVAL);
-
-    status = create_socket(pj_AF_INET6(), local_a, sizeof(pj_sockaddr_in6), 
-			   &sock);
-    if (status != PJ_SUCCESS)
-	return status;
-
-    if (a_name == NULL) {
-	/* Address name is not specified. 
-	 * Build a name based on bound address.
-	 */
-	status = get_published_name(sock, addr_buf, sizeof(addr_buf), 
-				    &bound_name);
-	if (status != PJ_SUCCESS) {
-	    pj_sock_close(sock);
-	    return status;
-	}
-
-	a_name = &bound_name;
-    }
-
-    return pjsip_udp_transport_attach2(endpt, PJSIP_TRANSPORT_UDP6,
-				       sock, a_name, async_cnt, p_transport);
+    pjsip_udp_transport_cfg cfg;
+
+    pjsip_udp_transport_cfg_default(&cfg, pj_AF_INET6());
+    if (local_a)
+	pj_sockaddr_cp(&cfg.bind_addr, local_a);
+    if (a_name)
+	cfg.addr_name = *a_name;
+    cfg.async_cnt = async_cnt;
+
+    return pjsip_udp_transport_start2(endpt, &cfg, p_transport);
 }
 
