summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2007-09-27 14:07:07 +0000
committerBenny Prijono <bennylp@teluu.com>2007-09-27 14:07:07 +0000
commit4f82e697a033306f77f467f77c0e8b405844fcfb (patch)
tree25474666328032157daf79c79c4b0763d8b3ef41
parent6b8d251db07c478f233cbe2393ff9add63873c6f (diff)
Ticket #381: auto-update the IP address in Contact according to the address/port received in REGISTER response
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@1454 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjsip/build/pjsua_lib.dsp2
-rw-r--r--pjsip/include/pjsua-lib/pjsua.h13
-rw-r--r--pjsip/src/pjsua-lib/pjsua_acc.c87
-rw-r--r--pjsip/src/pjsua-lib/pjsua_core.c1
4 files changed, 103 insertions, 0 deletions
diff --git a/pjsip/build/pjsua_lib.dsp b/pjsip/build/pjsua_lib.dsp
index da7c163f..3defda24 100644
--- a/pjsip/build/pjsua_lib.dsp
+++ b/pjsip/build/pjsua_lib.dsp
@@ -40,6 +40,7 @@ RSC=rc.exe
# PROP Output_Dir ".\output\pjsua-lib-i386-win32-vc6-release"
# PROP Intermediate_Dir ".\output\pjsua-lib-i386-win32-vc6-release"
# PROP Target_Dir ""
+F90=df.exe
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD CPP /nologo /MD /W4 /GX /Zi /O2 /I "../include" /I "../../pjmedia/include" /I "../../pjlib-util/include" /I "../../pjlib/include" /I "../../pjnath/include" /D "NDEBUG" /D PJ_WIN32=1 /D PJ_M_I386=1 /D "WIN32" /D "_MBCS" /D "_LIB" /FR /FD /c
# SUBTRACT CPP /YX
@@ -64,6 +65,7 @@ LIB32=link.exe -lib
# PROP Output_Dir ".\output\pjsua-lib-i386-win32-vc6-debug"
# PROP Intermediate_Dir ".\output\pjsua-lib-i386-win32-vc6-debug"
# PROP Target_Dir ""
+F90=df.exe
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "../include" /I "../../pjmedia/include" /I "../../pjlib-util/include" /I "../../pjlib/include" /I "../../pjnath/include" /D "_DEBUG" /D PJ_WIN32=1 /D PJ_M_I386=1 /D "WIN32" /D "_MBCS" /D "_LIB" /FR /FD /GZ /c
# SUBTRACT CPP /YX
diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h
index f493de5d..870ea8d5 100644
--- a/pjsip/include/pjsua-lib/pjsua.h
+++ b/pjsip/include/pjsua-lib/pjsua.h
@@ -1847,6 +1847,19 @@ 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.
+ *
+ * Default: 1 (yes)
+ */
+ pj_bool_t auto_update_nat;
+
} pjsua_acc_config;
diff --git a/pjsip/src/pjsua-lib/pjsua_acc.c b/pjsip/src/pjsua-lib/pjsua_acc.c
index 854f8cb4..07cba74f 100644
--- a/pjsip/src/pjsua-lib/pjsua_acc.c
+++ b/pjsip/src/pjsua-lib/pjsua_acc.c
@@ -454,6 +454,83 @@ PJ_DEF(pj_status_t) pjsua_acc_set_online_status2( pjsua_acc_id acc_id,
}
+/* Update NAT address from the REGISTER response */
+static pj_bool_t acc_check_nat_addr(pjsua_acc *acc,
+ struct pjsip_regc_cbparam *param)
+{
+ pjsip_transport *tp;
+ const pj_str_t *via_addr;
+ int rport;
+ 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)
+ return PJ_FALSE;
+
+ /* Only update if registration uses UDP transport */
+ if (tp->key.type != PJSIP_TRANSPORT_UDP)
+ return PJ_FALSE;
+
+ /* 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)
+ {
+ return PJ_FALSE;
+ }
+
+ /* 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;
+ } else
+ rport = via->rport_param;
+
+ if (via->recvd_param.slen != 0)
+ via_addr = &via->recvd_param;
+ 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)
+ {
+ /* Address doesn't change */
+ return PJ_FALSE;
+ }
+
+ /* At this point we've detected that the address as seen by registrar.
+ * has changed.
+ */
+ 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)via_addr->slen,
+ via_addr->ptr,
+ rport));
+
+ /* Unregister current contact */
+ pjsua_acc_set_registration(acc->index, PJ_FALSE);
+ if (acc->regc != NULL) {
+ pjsip_regc_destroy(acc->regc);
+ acc->regc = NULL;
+ }
+
+ /* Update transport address */
+ 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);
+
+ return PJ_TRUE;
+}
+
/*
* This callback is called by pjsip_regc when outgoing register
* request has completed.
@@ -463,6 +540,9 @@ static void regc_cb(struct pjsip_regc_cbparam *param)
pjsua_acc *acc = (pjsua_acc*) param->token;
+ if (param->regc != acc->regc)
+ return;
+
PJSUA_LOCK();
/*
@@ -489,6 +569,13 @@ static void regc_cb(struct pjsip_regc_cbparam *param)
PJ_LOG(3,(THIS_FILE, "%s: unregistration success",
pjsua_var.acc[acc->index].cfg.id.ptr));
} else {
+ /* Check NAT bound address */
+ if (acc_check_nat_addr(acc, param)) {
+ /* Update address, don't notify application yet */
+ PJSUA_UNLOCK();
+ return;
+ }
+
PJ_LOG(3, (THIS_FILE,
"%s: registration success, status=%d (%.*s), "
"will re-register in %d seconds",
diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c
index fa55da60..3b512666 100644
--- a/pjsip/src/pjsua-lib/pjsua_core.c
+++ b/pjsip/src/pjsua-lib/pjsua_core.c
@@ -140,6 +140,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;
}
PJ_DEF(void) pjsua_buddy_config_default(pjsua_buddy_config *cfg)