Close #1915: Added API pjsip_udp_transport_start2() that can create both IPv4 and IPv6 SIP UDP transports.
git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@5284 74dad513-b988-da41-8d7b-12977e46ad98
This commit is contained in:
parent
4a4d95c8f4
commit
4123ec4ffd
|
@ -26,6 +26,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <pjsip/sip_transport.h>
|
#include <pjsip/sip_transport.h>
|
||||||
|
#include <pj/sock_qos.h>
|
||||||
|
|
||||||
PJ_BEGIN_DECL
|
PJ_BEGIN_DECL
|
||||||
|
|
||||||
|
@ -59,6 +60,99 @@ enum
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start UDP transport.
|
* Start UDP transport.
|
||||||
*
|
*
|
||||||
|
|
|
@ -869,6 +869,81 @@ PJ_DEF(pj_status_t) pjsip_udp_transport_attach2( pjsip_endpoint *endpt,
|
||||||
async_cnt, p_transport);
|
async_cnt, p_transport);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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()
|
* pjsip_udp_transport_start()
|
||||||
*
|
*
|
||||||
|
@ -880,37 +955,18 @@ PJ_DEF(pj_status_t) pjsip_udp_transport_start( pjsip_endpoint *endpt,
|
||||||
unsigned async_cnt,
|
unsigned async_cnt,
|
||||||
pjsip_transport **p_transport)
|
pjsip_transport **p_transport)
|
||||||
{
|
{
|
||||||
pj_sock_t sock;
|
pjsip_udp_transport_cfg cfg;
|
||||||
pj_status_t status;
|
|
||||||
char addr_buf[PJ_INET6_ADDRSTRLEN];
|
|
||||||
pjsip_host_port bound_name;
|
|
||||||
|
|
||||||
PJ_ASSERT_RETURN(endpt && async_cnt, PJ_EINVAL);
|
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;
|
||||||
|
|
||||||
status = create_socket(pj_AF_INET(), local_a, sizeof(pj_sockaddr_in),
|
return pjsip_udp_transport_start2(endpt, &cfg, p_transport);
|
||||||
&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_start()
|
* pjsip_udp_transport_start()
|
||||||
*
|
*
|
||||||
|
@ -922,34 +978,16 @@ PJ_DEF(pj_status_t) pjsip_udp_transport_start6(pjsip_endpoint *endpt,
|
||||||
unsigned async_cnt,
|
unsigned async_cnt,
|
||||||
pjsip_transport **p_transport)
|
pjsip_transport **p_transport)
|
||||||
{
|
{
|
||||||
pj_sock_t sock;
|
pjsip_udp_transport_cfg cfg;
|
||||||
pj_status_t status;
|
|
||||||
char addr_buf[PJ_INET6_ADDRSTRLEN];
|
|
||||||
pjsip_host_port bound_name;
|
|
||||||
|
|
||||||
PJ_ASSERT_RETURN(endpt && async_cnt, PJ_EINVAL);
|
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;
|
||||||
|
|
||||||
status = create_socket(pj_AF_INET6(), local_a, sizeof(pj_sockaddr_in6),
|
return pjsip_udp_transport_start2(endpt, &cfg, p_transport);
|
||||||
&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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue