Index: /pjproject/trunk/pjsip/build/pjsua_lib.dsp
===================================================================
--- /pjproject/trunk/pjsip/build/pjsua_lib.dsp	(revision 1453)
+++ /pjproject/trunk/pjsip/build/pjsua_lib.dsp	(revision 1454)
@@ -41,4 +41,5 @@
 # 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
@@ -65,4 +66,5 @@
 # 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
Index: /pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h
===================================================================
--- /pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h	(revision 1453)
+++ /pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h	(revision 1454)
@@ -1848,4 +1848,17 @@
     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;
 
Index: /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_acc.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_acc.c	(revision 1453)
+++ /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_acc.c	(revision 1454)
@@ -455,4 +455,81 @@
 
 
+/* 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
@@ -463,4 +540,7 @@
 
     pjsua_acc *acc = (pjsua_acc*) param->token;
+
+    if (param->regc != acc->regc)
+	return;
 
     PJSUA_LOCK();
@@ -490,4 +570,11 @@
 		      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), "
Index: /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c	(revision 1453)
+++ /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c	(revision 1454)
@@ -141,4 +141,5 @@
     cfg->reg_timeout = PJSUA_REG_INTERVAL;
     cfg->transport_id = PJSUA_INVALID_ID;
+    cfg->auto_update_nat = PJ_TRUE;
 }
 
