Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option for dual stack IPv4&IPv6 account config #3590

Merged
merged 5 commits into from
Jun 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions pjsip-apps/src/pjsua/pjsua_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -1713,7 +1713,7 @@ static pj_status_t app_init(void)

app_config_init_video(&acc_cfg);
acc_cfg.rtp_cfg = app_config.rtp_cfg;
acc_cfg.ipv6_media_use = PJSUA_IPV6_ENABLED;
// acc_cfg.ipv6_media_use = PJSUA_IPV6_ENABLED;
pjsua_acc_modify(aid, &acc_cfg);
}

Expand Down Expand Up @@ -1778,7 +1778,7 @@ static pj_status_t app_init(void)

app_config_init_video(&acc_cfg);
acc_cfg.rtp_cfg = app_config.rtp_cfg;
acc_cfg.ipv6_media_use = PJSUA_IPV6_ENABLED;
// acc_cfg.ipv6_media_use = PJSUA_IPV6_ENABLED;
pjsua_acc_modify(aid, &acc_cfg);
}

Expand Down Expand Up @@ -1846,7 +1846,7 @@ static pj_status_t app_init(void)

app_config_init_video(&acc_cfg);
acc_cfg.rtp_cfg = app_config.rtp_cfg;
acc_cfg.ipv6_media_use = PJSUA_IPV6_ENABLED;
// acc_cfg.ipv6_media_use = PJSUA_IPV6_ENABLED;
pjsua_acc_modify(aid, &acc_cfg);
}

Expand Down
2 changes: 1 addition & 1 deletion pjsip-apps/src/pjsua/pjsua_app_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ static void usage(void)
puts ("");
puts ("Transport Options:");
#if defined(PJ_HAS_IPV6) && PJ_HAS_IPV6
puts (" --ipv6 Use IPv6 instead for SIP and media.");
puts (" --ipv6 Create SIP IPv6 transports.");
#endif
puts (" --set-qos Enable QoS tagging for SIP and media.");
puts (" --local-port=port Set TCP/UDP port. This implicitly enables both ");
Expand Down
6 changes: 5 additions & 1 deletion pjsip-apps/src/swig/symbols.i
Original file line number Diff line number Diff line change
Expand Up @@ -816,7 +816,11 @@ typedef enum pjsua_sip_timer_use
typedef enum pjsua_ipv6_use
{
PJSUA_IPV6_DISABLED,
PJSUA_IPV6_ENABLED
PJSUA_IPV6_ENABLED = 1,
PJSUA_IPV6_ENABLED_NO_PREFERENCE = 1,
PJSUA_IPV6_ENABLED_PREFER_IPV4,
PJSUA_IPV6_ENABLED_PREFER_IPV6,
PJSUA_IPV6_ENABLED_USE_IPV6_ONLY
} pjsua_ipv6_use;

typedef enum pjsua_nat64_opt
Expand Down
38 changes: 20 additions & 18 deletions pjsip/include/pjsip/sip_resolve.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,25 @@ PJ_BEGIN_DECL
* - RFC 3263: Locating SIP Servers
*/

/** Address records. */
typedef struct pjsip_server_address_record
{
/** Preferable transport to be used to contact this address. */
pjsip_transport_type_e type;

/** Server priority (the lower the higher the priority). */
unsigned priority;

/** Server weight (the higher the more load it can handle). */
unsigned weight;

/** The server's address. */
pj_sockaddr addr;

/** Address length. */
int addr_len;
} pjsip_server_address_record;

/**
* The server addresses returned by the resolver.
*/
Expand All @@ -180,24 +199,7 @@ typedef struct pjsip_server_addresses
unsigned count;

/** Address records. */
struct
{
/** Preferable transport to be used to contact this address. */
pjsip_transport_type_e type;

/** Server priority (the lower the higher the priority). */
unsigned priority;

/** Server weight (the higher the more load it can handle). */
unsigned weight;

/** The server's address. */
pj_sockaddr addr;

/** Address length. */
int addr_len;

} entry[PJSIP_MAX_RESOLVED_ADDRESSES];
pjsip_server_address_record entry[PJSIP_MAX_RESOLVED_ADDRESSES];

} pjsip_server_addresses;

Expand Down
40 changes: 36 additions & 4 deletions pjsip/include/pjsip/sip_transport.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,36 @@ typedef enum pjsip_tpselector_type
/** Use the specific listener to send request. */
PJSIP_TPSELECTOR_LISTENER,

/** Use the IP version criteria to send request. */
PJSIP_TPSELECTOR_IP_VER,

} pjsip_tpselector_type;

/**
* This enumerator describes the IP version criteria for pjsip_tpselector.
*/
typedef enum pjsip_tpselector_ip_ver
{
/** IPv4 only. */
PJSIP_TPSELECTOR_USE_IPV4_ONLY,

/**
* No preference. IP version used will depend on the order of addresses
* returned by pjsip_resolver.
*/
PJSIP_TPSELECTOR_NO_PREFERENCE,

/** IPv4 is preferred. */
PJSIP_TPSELECTOR_PREFER_IPV4,

/** IPv6 is preferred. */
PJSIP_TPSELECTOR_PREFER_IPV6,

/** IPv6 only. */
PJSIP_TPSELECTOR_USE_IPV6_ONLY

} pjsip_tpselector_ip_ver;


/**
* This structure describes the transport/listener preference to be used
Expand Down Expand Up @@ -240,11 +268,15 @@ typedef struct pjsip_tpselector
*/
pj_bool_t disable_connection_reuse;

/** Union representing the transport/listener criteria to be used. */
/**
* Union representing the transport/listener/IP version criteria
* to be used.
*/
union {
pjsip_transport *transport;
pjsip_tpfactory *listener;
void *ptr;
pjsip_transport *transport;
pjsip_tpfactory *listener;
pjsip_tpselector_ip_ver ip_ver;
void *ptr;
} u;

} pjsip_tpselector;
Expand Down
33 changes: 32 additions & 1 deletion pjsip/include/pjsua-lib/pjsua.h
Original file line number Diff line number Diff line change
Expand Up @@ -3677,6 +3677,8 @@ typedef struct pjsua_turn_config

/**
* Specify how IPv6 transport should be used in account config.
* IP version preference only applies for outgoing direction, for incoming
* direction, we will check the corresponding message/offer and match it.
*/
typedef enum pjsua_ipv6_use
{
Expand All @@ -3688,7 +3690,23 @@ typedef enum pjsua_ipv6_use
/**
* IPv6 is enabled.
*/
PJSUA_IPV6_ENABLED
PJSUA_IPV6_ENABLED = 1,
PJSUA_IPV6_ENABLED_NO_PREFERENCE = 1,

/**
* IPv6 is enabled, but IPv4 is preferable.
*/
PJSUA_IPV6_ENABLED_PREFER_IPV4,

/**
* IPv6 is enabled and preferable.
*/
PJSUA_IPV6_ENABLED_PREFER_IPV6,

/**
* Only IPv6 is enabled, IPv4 will not be used.
*/
PJSUA_IPV6_ENABLED_USE_IPV6_ONLY

} pjsua_ipv6_use;

Expand Down Expand Up @@ -4177,8 +4195,21 @@ typedef struct pjsua_acc_config
*/
pjsua_nat64_opt nat64_opt;

/**
* Specify whether IPv6 should be used for SIP signalling.
*
* Default: PJSUA_IPV6_ENABLED_NO_PREFERENCE
* (IP version used will be based on the address resolution
* returned by OS/resolver)
*/
pjsua_ipv6_use ipv6_sip_use;

/**
* Specify whether IPv6 should be used on media.
*
* Default: PJSUA_IPV6_ENABLED_PREFER_IPV4
* (Dual stack media, capable to use IPv4/IPv6.
* Outgoing offer will prefer to use IPv4)
*/
pjsua_ipv6_use ipv6_media_use;

Expand Down
17 changes: 15 additions & 2 deletions pjsip/include/pjsua2/account.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,15 @@ struct AccountSipConfig : public PersistentObject
*/
TransportId transportId;

/**
* Specify whether IPv6 should be used for SIP signalling.
*
* Default: PJSUA_IPV6_ENABLED_NO_PREFERENCE
* (IP version used will be based on the address resolution
* returned by OS/resolver)
*/
pjsua_ipv6_use ipv6Use;

public:
/**
* Read this object from a container node.
Expand Down Expand Up @@ -1033,7 +1042,11 @@ struct AccountMediaConfig : public PersistentObject
SrtpOpt srtpOpt;

/**
* Specify whether IPv6 should be used on media. Default is not used.
* Specify whether IPv6 should be used on media.
*
* Default: PJSUA_IPV6_ENABLED_PREFER_IPV4
* (Dual stack media, capable to use IPv4/IPv6.
* Outgoing offer will prefer to use IPv4)
*/
pjsua_ipv6_use ipv6Use;

Expand Down Expand Up @@ -1082,7 +1095,7 @@ struct AccountMediaConfig : public PersistentObject
streamKaEnabled(false),
srtpUse(PJSUA_DEFAULT_USE_SRTP),
srtpSecureSignaling(PJSUA_DEFAULT_SRTP_SECURE_SIGNALING),
ipv6Use(PJSUA_IPV6_DISABLED),
ipv6Use(PJSUA_IPV6_ENABLED_PREFER_IPV4),
rtcpMuxEnabled(false),
rtcpXrEnabled(PJMEDIA_STREAM_ENABLE_XR),
useLoopMedTp(false),
Expand Down
9 changes: 9 additions & 0 deletions pjsip/src/pjsip/sip_transport.c
Original file line number Diff line number Diff line change
Expand Up @@ -2331,6 +2331,15 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr,
TRACE_((THIS_FILE, "Listener type in tpsel not matched"));
return PJSIP_ETPNOTSUITABLE;
}
} else if (sel && sel->type == PJSIP_TPSELECTOR_IP_VER) {
if ((sel->u.ip_ver == PJSIP_TPSELECTOR_USE_IPV4_ONLY &&
pjsip_transport_type_get_af(type) != pj_AF_INET()) ||
(sel->u.ip_ver == PJSIP_TPSELECTOR_USE_IPV6_ONLY &&
pjsip_transport_type_get_af(type) != pj_AF_INET6()))
{
TRACE_((THIS_FILE, "Address type in tpsel not matched"));
return PJSIP_ETPNOTSUITABLE;
}
}

if (!sel || sel->disable_connection_reuse == PJ_FALSE) {
Expand Down
37 changes: 36 additions & 1 deletion pjsip/src/pjsip/sip_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <pjsip/sip_transaction.h>
#include <pjsip/sip_module.h>
#include <pjsip/sip_errno.h>
#include <pj/array.h>
#include <pj/log.h>
#include <pj/string.h>
#include <pj/guid.h>
Expand All @@ -33,7 +34,7 @@
#include <pj/assert.h>
#include <pj/errno.h>

#define THIS_FILE "endpoint"
#define THIS_FILE "sip_util.c"

static const char *event_str[] =
{
Expand Down Expand Up @@ -1306,6 +1307,29 @@ static void stateless_send_transport_cb( void *token,

}

/* Resort addresses based on preferred address family.
* Note that the order of addresses within the same address family will
* be preserved.
*/
static void resort_address(pjsip_server_addresses *addr, int af)
{
unsigned i = 0, j = 0;

while (j < addr->count) {
if (addr->entry[j].addr.addr.sa_family == af) {
if (i != j) {
pjsip_server_address_record temp;

pj_memcpy(&temp, &addr->entry[j], sizeof(temp));
pj_array_insert(addr->entry, sizeof(addr->entry[0]),
j, i, &temp);
}
i++;
}
j++;
}
}

/* Resolver callback for sending stateless request. */
static void
stateless_send_resolver_callback( pj_status_t status,
Expand Down Expand Up @@ -1382,6 +1406,17 @@ stateless_send_resolver_callback( pj_status_t status,
}
}

if (tdata->tp_sel.type == PJSIP_TPSELECTOR_IP_VER) {
PJ_LOG(5, (THIS_FILE, "Resorting target addresses based on "
"%s preference",
tdata->tp_sel.u.ip_ver == PJSIP_TPSELECTOR_PREFER_IPV4?
"IPv4": "IPv6"));
if (tdata->tp_sel.u.ip_ver == PJSIP_TPSELECTOR_PREFER_IPV4)
resort_address(&tdata->dest_info.addr, pj_AF_INET());
else if (tdata->tp_sel.u.ip_ver == PJSIP_TPSELECTOR_PREFER_IPV6)
resort_address(&tdata->dest_info.addr, pj_AF_INET6());
}

/* Process the addresses. */
stateless_send_transport_cb( stateless_data, tdata, -PJ_EPENDING);
}
Expand Down
Loading