Index: pjproject/trunk/pjsip/include/pjsip-simple/publish.h
===================================================================
--- pjproject/trunk/pjsip/include/pjsip-simple/publish.h	(revision 4172)
+++ pjproject/trunk/pjsip/include/pjsip-simple/publish.h	(revision 4173)
@@ -238,4 +238,20 @@
 
 /**
+ * Set the "sent-by" field of the Via header for outgoing requests.
+ *
+ * @param pubc	    The client publication structure.
+ * @param via_addr  Set via_addr to use for the Via header or NULL to use
+ *                  the transport's published name.
+ * @param via_tp    via_addr will only be used if we are using via_tp
+ *                  transport.
+ *
+ * @return	    PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_publishc_set_via_sent_by(pjsip_publishc *pubc,
+				                    pjsip_host_port *via_addr,
+                                                    pjsip_transport *via_tp);
+
+
+/**
  * Create PUBLISH request for the specified client publication structure.
  * Application can use this function to both create initial publication
Index: pjproject/trunk/pjsip/include/pjsip-ua/sip_regc.h
===================================================================
--- pjproject/trunk/pjsip/include/pjsip-ua/sip_regc.h	(revision 4172)
+++ pjproject/trunk/pjsip/include/pjsip-ua/sip_regc.h	(revision 4173)
@@ -192,4 +192,19 @@
 
 /**
+ * Set the "sent-by" field of the Via header for outgoing requests.
+ *
+ * @param regc	    The client registration structure.
+ * @param via_addr  Set via_addr to use for the Via header or NULL to use
+ *                  the transport's published name.
+ * @param via_tp    via_addr will only be used if we are using via_tp
+ *                  transport.
+ *
+ * @return	    PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_regc_set_via_sent_by(pjsip_regc *regc,
+				                pjsip_host_port *via_addr,
+                                                pjsip_transport *via_tp);
+
+/**
  * Set the number of seconds to refresh the client registration before
  * the registration expires.
Index: pjproject/trunk/pjsip/include/pjsip/sip_dialog.h
===================================================================
--- pjproject/trunk/pjsip/include/pjsip/sip_dialog.h	(revision 4172)
+++ pjproject/trunk/pjsip/include/pjsip/sip_dialog.h	(revision 4173)
@@ -174,4 +174,12 @@
     /** Module specific data. */
     void	       *mod_data[PJSIP_MAX_MODULE]; /**< Module data.	    */
+
+    /**
+     * If via_addr is set, it will be used as the "sent-by" field of the
+     * Via header for outgoing requests as long as the request uses via_tp
+     * transport. Normally application should not use or access these fields.
+     */
+    pjsip_host_port     via_addr;   /**< Via address.	                    */
+    const void         *via_tp;     /**< Via transport.	                    */
 };
 
@@ -299,4 +307,20 @@
 
 /**
+ * Set the "sent-by" field of the Via header for outgoing requests.
+ *
+ * @param dlg	    The dialog instance.
+ * @param via_addr  Set via_addr to use for the Via header or NULL to use
+ *                  the transport's published name.
+ * @param via_tp    via_addr will only be used if we are using via_tp
+ *                  transport.
+ *
+ * @return	    PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_set_via_sent_by(pjsip_dialog *dlg,
+				               pjsip_host_port *via_addr,
+                                               pjsip_transport *via_tp);
+
+
+/**
  * Create a new (forked) dialog on receipt on forked response in rdata. 
  * The new dialog will be created from original_dlg, except that it will have
@@ -403,5 +427,5 @@
  */
 PJ_DECL(pj_bool_t) pjsip_dlg_has_usage(pjsip_dialog *dlg,
-					  pjsip_module *module);
+				       pjsip_module *module);
 
 /**
Index: pjproject/trunk/pjsip/include/pjsip/sip_transport.h
===================================================================
--- pjproject/trunk/pjsip/include/pjsip/sip_transport.h	(revision 4172)
+++ pjproject/trunk/pjsip/include/pjsip/sip_transport.h	(revision 4173)
@@ -585,4 +585,12 @@
      */
     void		    *mod_data[PJSIP_MAX_MODULE];
+
+    /**
+     * If via_addr is set, it will be used as the "sent-by" field of the
+     * Via header for outgoing requests as long as the request uses via_tp
+     * transport. Normally application should not use or access these fields.
+     */
+    pjsip_host_port          via_addr;      /**< Via address.	        */
+    const void              *via_tp;        /**< Via transport.	        */
 };
 
Index: pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h
===================================================================
--- pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h	(revision 4172)
+++ pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h	(revision 4173)
@@ -2819,4 +2819,14 @@
 
     /**
+     * This option is used to overwrite the "sent-by" field of the Via header
+     * for outgoing messages with the same interface address as the one in
+     * the REGISTER request, as long as the request uses the same transport
+     * instance as the previous REGISTER request.
+     *
+     * Default: 1 (yes)
+     */
+    pj_bool_t        allow_via_rewrite;
+
+    /**
      * Control the use of SIP outbound feature. SIP outbound is described in
      * RFC 5626 to enable proxies or registrar to send inbound requests back
Index: pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h
===================================================================
--- pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h	(revision 4172)
+++ pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h	(revision 4173)
@@ -213,4 +213,7 @@
 				         It may be different than acc
 				         contact if outbound is used    */
+    pjsip_host_port  via_addr;      /**< Address for Via header         */
+    pjsip_transport *via_tp;        /**< Transport associated with
+                                         the Via address                */
 
     pj_str_t	     srv_domain;    /**< Host part of reg server.	*/
Index: pjproject/trunk/pjsip/src/pjsip-simple/publishc.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsip-simple/publishc.c	(revision 4172)
+++ pjproject/trunk/pjsip/src/pjsip-simple/publishc.c	(revision 4173)
@@ -95,4 +95,6 @@
     pjsip_route_hdr		 route_set;
     pjsip_hdr			 usr_hdr;
+    pjsip_host_port              via_addr;
+    const void                  *via_tp;
 
     /* Authorization sessions. */
@@ -342,4 +344,19 @@
 	h = h->next;
     }
+
+    return PJ_SUCCESS;
+}
+
+PJ_DEF(pj_status_t) pjsip_publishc_set_via_sent_by(pjsip_publishc *pubc,
+				                   pjsip_host_port *via_addr,
+                                                   pjsip_transport *via_tp)
+{
+    PJ_ASSERT_RETURN(pubc, PJ_EINVAL);
+
+    if (!via_addr)
+        pj_bzero(&pubc->via_addr, sizeof(pubc->via_addr));
+    else
+        pubc->via_addr = *via_addr;
+    pubc->via_tp = via_tp;
 
     return PJ_SUCCESS;
@@ -740,4 +757,10 @@
     pj_mutex_unlock(pubc->mutex);
 
+    /* If via_addr is set, use this address for the Via header. */
+    if (pubc->via_addr.host.slen > 0) {
+        tdata->via_addr = pubc->via_addr;
+        tdata->via_tp = pubc->via_tp;
+    }
+
     /* Invalidate message buffer. */
     pjsip_tx_data_invalidate_msg(tdata);
Index: pjproject/trunk/pjsip/src/pjsip-ua/sip_reg.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsip-ua/sip_reg.c	(revision 4172)
+++ pjproject/trunk/pjsip/src/pjsip-ua/sip_reg.c	(revision 4173)
@@ -91,4 +91,6 @@
     pjsip_route_hdr		 route_set;
     pjsip_hdr			 hdr_list;
+    pjsip_host_port              via_addr;
+    const void                  *via_tp;
 
     /* Authorization sessions. */
@@ -807,4 +809,19 @@
         regc->next_reg.sec += delay.sec;
     }
+}
+
+PJ_DEF(pj_status_t) pjsip_regc_set_via_sent_by( pjsip_regc *regc,
+				                pjsip_host_port *via_addr,
+                                                pjsip_transport *via_tp)
+{
+    PJ_ASSERT_RETURN(regc, PJ_EINVAL);
+
+    if (!via_addr)
+        pj_bzero(&regc->via_addr, sizeof(regc->via_addr));
+    else
+        regc->via_addr = *via_addr;
+    regc->via_tp = via_tp;
+
+    return PJ_SUCCESS;
 }
 
@@ -1263,4 +1280,10 @@
     pjsip_tx_data_add_ref(tdata);
 
+    /* If via_addr is set, use this address for the Via header. */
+    if (regc->via_addr.host.slen > 0) {
+        tdata->via_addr = regc->via_addr;
+        tdata->via_tp = regc->via_tp;
+    }
+
     /* Need to unlock the regc temporarily while sending the message to
      * prevent deadlock (https://trac.pjsip.org/repos/ticket/1247).
Index: pjproject/trunk/pjsip/src/pjsip/sip_dialog.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsip/sip_dialog.c	(revision 4172)
+++ pjproject/trunk/pjsip/src/pjsip/sip_dialog.c	(revision 4173)
@@ -586,4 +586,22 @@
 }
 
+/*
+ * Set "sent-by" field of Via header.
+ */
+PJ_DEF(pj_status_t) pjsip_dlg_set_via_sent_by( pjsip_dialog *dlg,
+				               pjsip_host_port *via_addr,
+                                               pjsip_transport *via_tp)
+{
+    PJ_ASSERT_RETURN(dlg, PJ_EINVAL);
+
+    if (!via_addr)
+        pj_bzero(&dlg->via_addr, sizeof(dlg->via_addr));
+    else
+        dlg->via_addr = *via_addr;
+    dlg->via_tp = via_tp;
+
+    return PJ_SUCCESS;
+}
+
 
 /*
@@ -1163,4 +1181,10 @@
     /* Lock and increment session */
     pjsip_dlg_inc_lock(dlg);
+
+    /* If via_addr is set, use this address for the Via header. */
+    if (dlg->via_addr.host.slen > 0) {
+        tdata->via_addr = dlg->via_addr;
+        tdata->via_tp = dlg->via_tp;
+    }
 
     /* Update dialog's CSeq and message's CSeq if request is not
Index: pjproject/trunk/pjsip/src/pjsip/sip_util.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsip/sip_util.c	(revision 4172)
+++ pjproject/trunk/pjsip/src/pjsip/sip_util.c	(revision 4173)
@@ -1193,5 +1193,11 @@
 
 	via->transport = pj_str(stateless_data->cur_transport->type_name);
-	via->sent_by = stateless_data->cur_transport->local_name;
+        if (tdata->via_addr.host.slen > 0 &&
+            tdata->via_tp == (void *)stateless_data->cur_transport)
+        {
+            via->sent_by = tdata->via_addr;
+        } else {
+	    via->sent_by = stateless_data->cur_transport->local_name;
+        }
 	via->rport_param = pjsip_cfg()->endpt.disable_rport ? -1 : 0;
 
Index: pjproject/trunk/pjsip/src/pjsua-lib/pjsua_acc.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsua-lib/pjsua_acc.c	(revision 4172)
+++ pjproject/trunk/pjsip/src/pjsua-lib/pjsua_acc.c	(revision 4173)
@@ -625,4 +625,6 @@
     acc->valid = PJ_FALSE;
     acc->contact.slen = 0;
+    pj_bzero(&acc->via_addr, sizeof(acc->via_addr));
+    acc->via_tp = NULL;
 
     /* Remove from array */
@@ -1091,4 +1093,23 @@
     }
 
+    /* Allow via rewrite */
+    if (acc->cfg.allow_via_rewrite != cfg->allow_via_rewrite) {
+        if (acc->regc != NULL) {
+            if (cfg->allow_via_rewrite) {
+                pjsip_regc_set_via_sent_by(acc->regc, &acc->via_addr,
+                                           acc->via_tp);
+            } else
+                pjsip_regc_set_via_sent_by(acc->regc, NULL, NULL);
+        }
+        if (acc->publish_sess != NULL) {
+            if (cfg->allow_via_rewrite) {
+                pjsip_publishc_set_via_sent_by(acc->publish_sess,
+                                               &acc->via_addr, acc->via_tp);
+            } else
+                pjsip_publishc_set_via_sent_by(acc->publish_sess, NULL, NULL);
+        }
+        acc->cfg.allow_via_rewrite = cfg->allow_via_rewrite;
+    }
+
     /* Normalize registration timeout and refresh delay */
     if (acc->cfg.reg_uri.slen ) {
@@ -1314,4 +1335,17 @@
 
     tp = param->rdata->tp_info.transport;
+
+    /* If allow_via_rewrite is enabled, we save the Via "sent-by" address
+     * from the response.
+     */
+    if (acc->cfg.allow_via_rewrite &&
+        (acc->via_addr.host.slen == 0 || acc->via_tp != tp))
+    {
+        via = param->rdata->msg_info.via;
+        if (pj_strcmp(&acc->via_addr.host, &via->sent_by.host))
+            pj_strdup(acc->pool, &acc->via_addr.host, &via->sent_by.host);
+        acc->via_addr.port = via->sent_by.port;
+        acc->via_tp = tp;
+    }
 
     /* Only update if account is configured to auto-update */
@@ -2177,4 +2211,12 @@
 
     if (status == PJ_SUCCESS) {
+        if (pjsua_var.acc[acc_id].cfg.allow_via_rewrite &&
+            pjsua_var.acc[acc_id].via_addr.host.slen > 0)
+        {
+            pjsip_regc_set_via_sent_by(pjsua_var.acc[acc_id].regc,
+                                       &pjsua_var.acc[acc_id].via_addr,
+                                       pjsua_var.acc[acc_id].via_tp);
+        }
+
 	//pjsua_process_msg_data(tdata, NULL);
 	status = pjsip_regc_send( pjsua_var.acc[acc_id].regc, tdata );
@@ -2540,4 +2582,12 @@
 	pjsua_init_tpselector(acc->cfg.transport_id, &tp_sel);
 	pjsip_tx_data_set_transport(tdata, &tp_sel);
+    }
+
+    /* If via_addr is set, use this address for the Via header. */
+    if (pjsua_var.acc[acc_id].cfg.allow_via_rewrite &&
+        pjsua_var.acc[acc_id].via_addr.host.slen > 0)
+    {
+        tdata->via_addr = pjsua_var.acc[acc_id].via_addr;
+        tdata->via_tp = pjsua_var.acc[acc_id].via_tp;
     }
 
Index: pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c	(revision 4172)
+++ pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c	(revision 4173)
@@ -716,4 +716,7 @@
     pjsip_dlg_inc_lock(dlg);
 
+    if (acc->cfg.allow_via_rewrite && acc->via_addr.host.slen > 0)
+        pjsip_dlg_set_via_sent_by(dlg, &acc->via_addr, acc->via_tp);
+
     /* Calculate call's secure level */
     call->secure_level = get_secure_level(acc_id, dest_uri);
@@ -1169,4 +1172,11 @@
 				      NULL, NULL);
 	goto on_return;
+    }
+
+    if (pjsua_var.acc[acc_id].cfg.allow_via_rewrite &&
+        pjsua_var.acc[acc_id].via_addr.host.slen > 0)
+    {
+        pjsip_dlg_set_via_sent_by(dlg, &pjsua_var.acc[acc_id].via_addr,
+                                  pjsua_var.acc[acc_id].via_tp);
     }
 
Index: pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c	(revision 4172)
+++ pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c	(revision 4173)
@@ -212,4 +212,5 @@
     cfg->transport_id = PJSUA_INVALID_ID;
     cfg->allow_contact_rewrite = PJ_TRUE;
+    cfg->allow_via_rewrite = PJ_TRUE;
     cfg->require_100rel = pjsua_var.ua_cfg.require_100rel;
     cfg->use_timer = pjsua_var.ua_cfg.use_timer;
Index: pjproject/trunk/pjsip/src/pjsua-lib/pjsua_im.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsua-lib/pjsua_im.c	(revision 4172)
+++ pjproject/trunk/pjsip/src/pjsua-lib/pjsua_im.c	(revision 4173)
@@ -602,4 +602,10 @@
     pjsua_set_msg_route_set(tdata, &acc->route_set);
 
+    /* If via_addr is set, use this address for the Via header. */
+    if (acc->cfg.allow_via_rewrite && acc->via_addr.host.slen > 0) {
+        tdata->via_addr = acc->via_addr;
+        tdata->via_tp = acc->via_tp;
+    }
+
     /* Send request (statefully) */
     status = pjsip_endpt_send_request( pjsua_var.endpt, tdata, -1, 
@@ -685,4 +691,10 @@
     pjsua_set_msg_route_set(tdata, &acc->route_set);
 
+    /* If via_addr is set, use this address for the Via header. */
+    if (acc->cfg.allow_via_rewrite && acc->via_addr.host.slen > 0) {
+        tdata->via_addr = acc->via_addr;
+        tdata->via_tp = acc->via_tp;
+    }
+
     /* Create data to reauthenticate */
     im_data = PJ_POOL_ZALLOC_T(tdata->pool, pjsua_im_data);
Index: pjproject/trunk/pjsip/src/pjsua-lib/pjsua_pres.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsua-lib/pjsua_pres.c	(revision 4172)
+++ pjproject/trunk/pjsip/src/pjsua-lib/pjsua_pres.c	(revision 4173)
@@ -865,4 +865,7 @@
     }
 
+    if (acc->cfg.allow_via_rewrite && acc->via_addr.host.slen > 0)
+        pjsip_dlg_set_via_sent_by(dlg, &acc->via_addr, acc->via_tp);
+
     /* Set credentials and preference. */
     pjsip_auth_clt_set_credentials(&dlg->auth_sess, acc->cred_cnt, acc->cred);
@@ -1229,4 +1232,10 @@
     /* Add headers etc */
     pjsua_process_msg_data(tdata, NULL);
+
+    /* Set Via sent-by */
+    if (acc->cfg.allow_via_rewrite && acc->via_addr.host.slen > 0) {
+        pjsip_publishc_set_via_sent_by(acc->publish_sess, &acc->via_addr,
+                                       acc->via_tp);
+    }
 
     /* Send the PUBLISH request */
@@ -1781,4 +1790,7 @@
     pjsip_dlg_inc_lock(buddy->dlg);
 
+    if (acc->cfg.allow_via_rewrite && acc->via_addr.host.slen > 0)
+        pjsip_dlg_set_via_sent_by(buddy->dlg, &acc->via_addr, acc->via_tp);
+
     status = pjsip_pres_create_uac( buddy->dlg, &pres_callback, 
 				    PJSIP_EVSUB_NO_EVENT_ID, &buddy->sub);
@@ -2097,4 +2109,7 @@
      */
     pjsip_dlg_inc_lock(acc->mwi_dlg);
+
+    if (acc->cfg.allow_via_rewrite && acc->via_addr.host.slen > 0)
+        pjsip_dlg_set_via_sent_by(acc->mwi_dlg, &acc->via_addr, acc->via_tp);
 
     /* Create UAC subscription */
