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:
Benny Prijono 2008-03-22 09:33:52 +00:00
parent 1add4d5206
commit e8554ef92f
5 changed files with 102 additions and 41 deletions

View File

@ -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);
}

View File

@ -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.

View File

@ -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. */

View File

@ -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,

View 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");