Ticket #515 (Update Contact header in REGISTER for TCP/TLS transport)
git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@1889 74dad513-b988-da41-8d7b-12977e46ad98
This commit is contained in:
parent
1add4d5206
commit
e8554ef92f
|
@ -694,7 +694,7 @@ static pj_status_t parse_args(int argc, char *argv[],
|
|||
break;
|
||||
|
||||
case OPT_AUTO_UPDATE_NAT: /* OPT_AUTO_UPDATE_NAT */
|
||||
cur_acc->auto_update_nat = pj_strtoul(pj_cstr(&tmp, pj_optarg));
|
||||
cur_acc->allow_contact_rewrite = pj_strtoul(pj_cstr(&tmp, pj_optarg));
|
||||
break;
|
||||
|
||||
case OPT_USE_COMPACT_FORM:
|
||||
|
@ -1148,10 +1148,10 @@ static void write_account_settings(int acc_index, pj_str_t *result)
|
|||
}
|
||||
|
||||
/* */
|
||||
//if (acc_cfg->auto_update_nat)
|
||||
if (acc_cfg->allow_contact_rewrite==0)
|
||||
{
|
||||
pj_ansi_sprintf(line, "--auto-update-nat %i\n",
|
||||
(int)acc_cfg->auto_update_nat);
|
||||
pj_ansi_sprintf(line, "--contact-rewrite %i\n",
|
||||
(int)acc_cfg->allow_contact_rewrite);
|
||||
pj_strcat2(result, line);
|
||||
}
|
||||
|
||||
|
|
|
@ -2026,17 +2026,18 @@ typedef struct pjsua_acc_config
|
|||
pjsua_transport_id transport_id;
|
||||
|
||||
/**
|
||||
* This option is useful for keeping the UDP transport address up to
|
||||
* date with the NAT public mapped address. When this option is
|
||||
* enabled and STUN is configured, the library will keep track of
|
||||
* the public IP address from the response of REGISTER request. Once
|
||||
* it detects that the address has changed, it will unregister current
|
||||
* Contact, update the UDP transport address, and register a new
|
||||
* Contact to the registrar.
|
||||
* This option is used to update the UDP transport address and the Contact
|
||||
* header of REGISTER request. When this option is enabled, the library
|
||||
* will keep track of the public IP address from the response of REGISTER
|
||||
* request. Once it detects that the address has changed, it will
|
||||
* unregister current Contact, update the Contact with transport address
|
||||
* learned from Via header, and register a new Contact to the registrar.
|
||||
* This will also update the public name of UDP transport if STUN is
|
||||
* configured.
|
||||
*
|
||||
* Default: 1 (yes)
|
||||
*/
|
||||
pj_bool_t auto_update_nat;
|
||||
pj_bool_t allow_contact_rewrite;
|
||||
|
||||
/**
|
||||
* Set the interval for periodic keep-alive transmission for this account.
|
||||
|
|
|
@ -84,6 +84,7 @@ typedef struct pjsua_acc
|
|||
int index; /**< Index in accounts array. */
|
||||
pj_str_t display; /**< Display name, if any. */
|
||||
pj_str_t user_part; /**< User part of local URI. */
|
||||
pj_str_t contact; /**< Our Contact URI for REGISTER */
|
||||
|
||||
pj_str_t srv_domain; /**< Host part of reg server. */
|
||||
int srv_port; /**< Port number of reg server. */
|
||||
|
|
|
@ -484,31 +484,43 @@ static pj_bool_t acc_check_nat_addr(pjsua_acc *acc,
|
|||
{
|
||||
pjsip_transport *tp;
|
||||
const pj_str_t *via_addr;
|
||||
pj_pool_t *pool;
|
||||
int rport;
|
||||
pjsip_sip_uri *uri;
|
||||
pjsip_via_hdr *via;
|
||||
|
||||
tp = param->rdata->tp_info.transport;
|
||||
|
||||
/* Only update if account is configured to auto-update */
|
||||
if (acc->cfg.auto_update_nat == PJ_FALSE)
|
||||
if (acc->cfg.allow_contact_rewrite == PJ_FALSE)
|
||||
return PJ_FALSE;
|
||||
|
||||
/* Only update if registration uses UDP transport */
|
||||
if (tp->key.type != PJSIP_TRANSPORT_UDP)
|
||||
return PJ_FALSE;
|
||||
#if 0
|
||||
// Always update
|
||||
// See http://lists.pjsip.org/pipermail/pjsip_lists.pjsip.org/2008-March/002178.html
|
||||
|
||||
/* Only update if STUN is enabled (for now) */
|
||||
if (pjsua_var.ua_cfg.stun_domain.slen == 0 &&
|
||||
pjsua_var.ua_cfg.stun_host.slen == 0)
|
||||
/* For UDP, only update if STUN is enabled (for now).
|
||||
* For TCP/TLS, always check.
|
||||
*/
|
||||
if ((tp->key.type == PJSIP_TRANSPORT_UDP &&
|
||||
(pjsua_var.ua_cfg.stun_domain.slen != 0 ||
|
||||
(pjsua_var.ua_cfg.stun_host.slen != 0)) ||
|
||||
(tp->key.type == PJSIP_TRANSPORT_TCP) ||
|
||||
(tp->key.type == PJSIP_TRANSPORT_TLS))
|
||||
{
|
||||
/* Yes we will check */
|
||||
} else {
|
||||
return PJ_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Get the received and rport info */
|
||||
via = param->rdata->msg_info.via;
|
||||
if (via->rport_param < 1) {
|
||||
/* Remote doesn't support rport */
|
||||
rport = via->sent_by.port;
|
||||
if (rport==0)
|
||||
rport = pjsip_transport_get_default_port_for_type(tp->key.type);
|
||||
} else
|
||||
rport = via->rport_param;
|
||||
|
||||
|
@ -517,11 +529,21 @@ static pj_bool_t acc_check_nat_addr(pjsua_acc *acc,
|
|||
else
|
||||
via_addr = &via->sent_by.host;
|
||||
|
||||
/* Compare received and rport with transport published address */
|
||||
if (tp->local_name.port == rport &&
|
||||
pj_stricmp(&tp->local_name.host, via_addr)==0)
|
||||
/* Compare received and rport with the URI in our registration */
|
||||
pool = pjsua_pool_create("tmp", 512, 512);
|
||||
uri = (pjsip_sip_uri*)
|
||||
pjsip_parse_uri(pool, acc->contact.ptr, acc->contact.slen, 0);
|
||||
pj_assert(uri != NULL);
|
||||
uri = pjsip_uri_get_uri(uri);
|
||||
|
||||
if (uri->port == 0)
|
||||
uri->port = pjsip_transport_get_default_port_for_type(tp->key.type);
|
||||
|
||||
if (uri->port == rport &&
|
||||
pj_stricmp(&uri->host, via_addr)==0)
|
||||
{
|
||||
/* Address doesn't change */
|
||||
pj_pool_release(pool);
|
||||
return PJ_FALSE;
|
||||
}
|
||||
|
||||
|
@ -531,9 +553,9 @@ static pj_bool_t acc_check_nat_addr(pjsua_acc *acc,
|
|||
PJ_LOG(3,(THIS_FILE, "IP address change detected for account %d "
|
||||
"(%.*s:%d --> %.*s:%d). Updating registration..",
|
||||
acc->index,
|
||||
(int)tp->local_name.host.slen,
|
||||
tp->local_name.host.ptr,
|
||||
tp->local_name.port,
|
||||
(int)uri->host.slen,
|
||||
uri->host.ptr,
|
||||
uri->port,
|
||||
(int)via_addr->slen,
|
||||
via_addr->ptr,
|
||||
rport));
|
||||
|
@ -545,13 +567,44 @@ static pj_bool_t acc_check_nat_addr(pjsua_acc *acc,
|
|||
acc->regc = NULL;
|
||||
}
|
||||
|
||||
/* Update transport address */
|
||||
pj_strdup_with_null(tp->pool, &tp->local_name.host, via_addr);
|
||||
tp->local_name.port = rport;
|
||||
/* Update account's Contact header */
|
||||
{
|
||||
char *tmp;
|
||||
int len;
|
||||
|
||||
tmp = pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE);
|
||||
len = pj_ansi_snprintf(tmp, PJSIP_MAX_URL_SIZE,
|
||||
"<sip:%.*s@%.*s:%d;transport=%s>",
|
||||
(int)acc->user_part.slen,
|
||||
acc->user_part.ptr,
|
||||
(int)via_addr->slen,
|
||||
via_addr->ptr,
|
||||
rport,
|
||||
tp->type_name);
|
||||
if (len < 1) {
|
||||
PJ_LOG(1,(THIS_FILE, "URI too long"));
|
||||
pj_pool_release(pool);
|
||||
return PJ_FALSE;
|
||||
}
|
||||
pj_strdup2(pjsua_var.pool, &acc->contact, tmp);
|
||||
}
|
||||
|
||||
/* For UDP transport, if STUN is enabled then update the transport's
|
||||
* published name as well.
|
||||
*/
|
||||
if (tp->key.type==PJSIP_TRANSPORT_UDP &&
|
||||
(pjsua_var.ua_cfg.stun_domain.slen != 0 ||
|
||||
pjsua_var.ua_cfg.stun_host.slen != 0))
|
||||
{
|
||||
pj_strdup_with_null(tp->pool, &tp->local_name.host, via_addr);
|
||||
tp->local_name.port = rport;
|
||||
}
|
||||
|
||||
/* Perform new registration */
|
||||
pjsua_acc_set_registration(acc->index, PJ_TRUE);
|
||||
|
||||
pj_pool_release(pool);
|
||||
|
||||
return PJ_TRUE;
|
||||
}
|
||||
|
||||
|
@ -863,7 +916,6 @@ static void regc_cb(struct pjsip_regc_cbparam *param)
|
|||
static pj_status_t pjsua_regc_init(int acc_id)
|
||||
{
|
||||
pjsua_acc *acc;
|
||||
pj_str_t contact;
|
||||
pj_pool_t *pool;
|
||||
pj_status_t status;
|
||||
|
||||
|
@ -893,23 +945,30 @@ static pj_status_t pjsua_regc_init(int acc_id)
|
|||
}
|
||||
|
||||
pool = pjsua_pool_create("tmpregc", 512, 512);
|
||||
status = pjsua_acc_create_uac_contact( pool, &contact,
|
||||
acc_id, &acc->cfg.reg_uri);
|
||||
if (status != PJ_SUCCESS) {
|
||||
pjsua_perror(THIS_FILE, "Unable to generate suitable Contact header"
|
||||
" for registration",
|
||||
status);
|
||||
pjsip_regc_destroy(acc->regc);
|
||||
pj_pool_release(pool);
|
||||
acc->regc = NULL;
|
||||
return status;
|
||||
|
||||
if (acc->contact.slen == 0) {
|
||||
pj_str_t tmp_contact;
|
||||
|
||||
status = pjsua_acc_create_uac_contact( pool, &tmp_contact,
|
||||
acc_id, &acc->cfg.reg_uri);
|
||||
if (status != PJ_SUCCESS) {
|
||||
pjsua_perror(THIS_FILE, "Unable to generate suitable Contact header"
|
||||
" for registration",
|
||||
status);
|
||||
pjsip_regc_destroy(acc->regc);
|
||||
pj_pool_release(pool);
|
||||
acc->regc = NULL;
|
||||
return status;
|
||||
}
|
||||
|
||||
pj_strdup_with_null(pjsua_var.pool, &acc->contact, &tmp_contact);
|
||||
}
|
||||
|
||||
status = pjsip_regc_init( acc->regc,
|
||||
&acc->cfg.reg_uri,
|
||||
&acc->cfg.id,
|
||||
&acc->cfg.id,
|
||||
1, &contact,
|
||||
1, &acc->contact,
|
||||
acc->cfg.reg_timeout);
|
||||
if (status != PJ_SUCCESS) {
|
||||
pjsua_perror(THIS_FILE,
|
||||
|
|
|
@ -142,7 +142,7 @@ PJ_DEF(void) pjsua_acc_config_default(pjsua_acc_config *cfg)
|
|||
|
||||
cfg->reg_timeout = PJSUA_REG_INTERVAL;
|
||||
cfg->transport_id = PJSUA_INVALID_ID;
|
||||
cfg->auto_update_nat = PJ_TRUE;
|
||||
cfg->allow_contact_rewrite = PJ_TRUE;
|
||||
cfg->require_100rel = pjsua_var.ua_cfg.require_100rel;
|
||||
cfg->ka_interval = 15;
|
||||
cfg->ka_data = pj_str("\r\n");
|
||||
|
|
Loading…
Reference in New Issue