diff --git a/CHANGES b/CHANGES
index e969d85bf47cb75b735f83aee29bbae2621967ac..4bbe26dc3bda4d2676b1e2c39c07499d6d4ceab1 100644
--- a/CHANGES
+++ b/CHANGES
@@ -141,6 +141,30 @@ app_confbridge
    ConfbridgeWelcome has been added that will send a list of all
    current participants to a new participant.
 
+res_pjsip
+------------------
+  * Two new options have been added to the system and endpoint objects to
+    control whether, on outbound calls, Asterisk will accept updated SDP answers
+    during the initial INVITE transaction when 100rel is not in effect.
+    This usually happens when the INVITE is forked to multiple UASs and more
+    than one sends an SDP answer or when a single UAS needs to change a media
+    port to switch from custom ringback to the actual media destination.
+
+    The 'follow_early_media_forked' option sets whether Asterisk will accept
+    the updated SDP when the To tag on the subsequent response is different than
+    that on the the previous response.  This usually occurs in the forked INVITE
+    scenario. The default value is "yes" which is the current behavior.
+
+    The 'accept_multiple_sdp_answers' flag sets whether Asterisk will accept the
+    updated SDP when the To tag on the subsequent response is the same as that
+    on the previous response. This can occur when a UAS needs to switch media
+    ports from custom ringback to the final media path.  The default value is
+    "no" which is the current behavior.
+
+    These options have to be enabled system-wide in the system config section
+    of pjsip.conf as well as on individual endpoints that require the
+    functionality.
+
 ------------------------------------------------------------------------------
 --- Functionality changes from Asterisk 15.3.0 to Asterisk 15.4.0 ------------
 ------------------------------------------------------------------------------
diff --git a/configs/samples/pjsip.conf.sample b/configs/samples/pjsip.conf.sample
index a39a8675a6ed5f19508987d00d55e6522bd26084..9b64001663e48e7d7151274f5ede97bafc6b60f1 100644
--- a/configs/samples/pjsip.conf.sample
+++ b/configs/samples/pjsip.conf.sample
@@ -809,6 +809,27 @@
                         ; this mailbox will be used when notifying other modules
                         ; of MWI status changes.  If not set, incoming MWI
                         ; NOTIFYs are ignored.
+;follow_early_media_fork = ; On outgoing calls, if the UAS responds with
+                           ; different SDP attributes on subsequent 18X or 2XX
+                           ; responses (such as a port update) AND the To tag
+                           ; on the subsequent response is different than that
+                           ; on the previous one, follow it.  This usually
+                           ; happens when the INVITE is forked to multiple UASs
+                           ; and more than 1 sends an SDP answer.
+                           ; This option must also be enabled in the system
+                           ; section.
+                           ; (default: yes)
+;accept_multiple_sdp_answers =
+                           ; On outgoing calls, if the UAS responds with
+                           ; different SDP attributes on non-100rel 18X or 2XX
+                           ; responses (such as a port update) AND the To tag on
+                           ; the subsequent response is the same as that on the
+                           ; previous one, process it. This can happen when the
+                           ; UAS needs to change ports for some reason such as
+                           ; using a separate port for custom ringback.
+                           ; This option must also be enabled in the system
+                           ; section.
+                           ; (default: no)
 
 ;==========================AUTH SECTION OPTIONS=========================
 ;[auth]
@@ -961,6 +982,27 @@
                         ; Disabling this option has been known to cause interoperability
                         ; issues, so disable at your own risk.
                         ; (default: "yes")
+;follow_early_media_fork = ; On outgoing calls, if the UAS responds with
+                           ; different SDP attributes on subsequent 18X or 2XX
+                           ; responses (such as a port update) AND the To tag
+                           ; on the subsequent response is different than that
+                           ; on the previous one, follow it.  This usually
+                           ; happens when the INVITE is forked to multiple UASs
+                           ; and more than 1 sends an SDP answer.
+                           ; This option must also be enabled on endpoints that
+                           ; require this functionality.
+                           ; (default: yes)
+;accept_multiple_sdp_answers =
+                           ; On outgoing calls, if the UAS responds with
+                           ; different SDP attributes on non-100rel 18X or 2XX
+                           ; responses (such as a port update) AND the To tag on
+                           ; the subsequent response is the same as that on the
+                           ; previous one, process it. This can happen when the
+                           ; UAS needs to change ports for some reason such as
+                           ; using a separate port for custom ringback.
+                           ; This option must also be enabled on endpoints that
+                           ; require this functionality.
+                           ; (default: no)
 ;type=  ; Must be of type system (default: "")
 
 ;==========================GLOBAL SECTION OPTIONS=========================
diff --git a/configure b/configure
index b7d349011fb036795192a3759cf2dc49c09889d0..92c1853ba7ffcc4cfb6a1ed7629f05e61befb672 100755
--- a/configure
+++ b/configure
@@ -924,6 +924,10 @@ PBX_POPT
 POPT_DIR
 POPT_INCLUDE
 POPT_LIB
+PBX_PJSIP_INV_ACCEPT_MULTIPLE_SDP_ANSWERS
+PJSIP_INV_ACCEPT_MULTIPLE_SDP_ANSWERS_DIR
+PJSIP_INV_ACCEPT_MULTIPLE_SDP_ANSWERS_INCLUDE
+PJSIP_INV_ACCEPT_MULTIPLE_SDP_ANSWERS_LIB
 PBX_PJSIP_TSX_LAYER_FIND_TSX2
 PJSIP_TSX_LAYER_FIND_TSX2_DIR
 PJSIP_TSX_LAYER_FIND_TSX2_INCLUDE
@@ -9272,6 +9276,9 @@ $as_echo "#define HAVE_PJSIP_AUTH_CLT_DEINIT 1" >>confdefs.h
 $as_echo "#define HAVE_PJSIP_TSX_LAYER_FIND_TSX2 1" >>confdefs.h
 
 
+$as_echo "#define HAVE_PJSIP_INV_ACCEPT_MULTIPLE_SDP_ANSWERS 1" >>confdefs.h
+
+
 
 
 
@@ -11402,6 +11409,18 @@ PBX_PJSIP_TSX_LAYER_FIND_TSX2=0
 
 
 
+
+PJSIP_INV_ACCEPT_MULTIPLE_SDP_ANSWERS_DESCRIP="PJSIP INVITE Accept Multiple SDP Answers"
+PJSIP_INV_ACCEPT_MULTIPLE_SDP_ANSWERS_OPTION=pjsip
+PJSIP_INV_ACCEPT_MULTIPLE_SDP_ANSWERS_DIR=${PJPROJECT_DIR}
+
+PBX_PJSIP_INV_ACCEPT_MULTIPLE_SDP_ANSWERS=0
+
+
+
+
+
+
 fi
 
 
@@ -25238,6 +25257,46 @@ $as_echo "#define HAVE_PJSIP_TLS_TRANSPORT_PROTO 1" >>confdefs.h
 
 
 
+else
+         { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+	CPPFLAGS="${saved_cppflags}"
+    fi
+
+
+    if test "x${PBX_PJSIP_INV_ACCEPT_MULTIPLE_SDP_ANSWERS}" != "x1" -a "${USE_PJSIP_INV_ACCEPT_MULTIPLE_SDP_ANSWERS}" != "no"; then
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if \"pjsip_cfg()->endpt.accept_multiple_sdp_answers = 0;\" compiles using pjsip.h" >&5
+$as_echo_n "checking if \"pjsip_cfg()->endpt.accept_multiple_sdp_answers = 0;\" compiles using pjsip.h... " >&6; }
+	saved_cppflags="${CPPFLAGS}"
+	if test "x${PJSIP_INV_ACCEPT_MULTIPLE_SDP_ANSWERS_DIR}" != "x"; then
+	    PJSIP_INV_ACCEPT_MULTIPLE_SDP_ANSWERS_INCLUDE="-I${PJSIP_INV_ACCEPT_MULTIPLE_SDP_ANSWERS_DIR}/include"
+	fi
+	CPPFLAGS="${CPPFLAGS} ${PJSIP_INV_ACCEPT_MULTIPLE_SDP_ANSWERS_INCLUDE}"
+
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+ #include <pjsip.h>
+int
+main ()
+{
+ pjsip_cfg()->endpt.accept_multiple_sdp_answers = 0;;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+     { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+		PBX_PJSIP_INV_ACCEPT_MULTIPLE_SDP_ANSWERS=1
+
+$as_echo "#define HAVE_PJSIP_INV_ACCEPT_MULTIPLE_SDP_ANSWERS 1" >>confdefs.h
+
+
+
 else
          { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
diff --git a/configure.ac b/configure.ac
index 5da5afa4dd7c1159a23f1febedcd78a07880b8de..be8de3311b9d990065c37dbb9d08b8ab21d127e2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -515,6 +515,7 @@ AST_EXT_LIB_SETUP_OPTIONAL([PJSIP_EVSUB_GRP_LOCK], [PJSIP EVSUB Group Lock suppo
 AST_EXT_LIB_SETUP_OPTIONAL([PJSIP_INV_SESSION_REF], [PJSIP INVITE Session Reference Count support], [PJPROJECT], [pjsip])
 AST_EXT_LIB_SETUP_OPTIONAL([PJSIP_AUTH_CLT_DEINIT], [pjsip_auth_clt_deinit support], [PJPROJECT], [pjsip])
 AST_EXT_LIB_SETUP_OPTIONAL([PJSIP_TSX_LAYER_FIND_TSX2], [pjsip_tsx_layer_find_tsx2 support], [PJPROJECT], [pjsip])
+AST_EXT_LIB_SETUP_OPTIONAL([PJSIP_INV_ACCEPT_MULTIPLE_SDP_ANSWERS], [PJSIP INVITE Accept Multiple SDP Answers], [PJPROJECT], [pjsip])
 fi
 
 AST_EXT_LIB_SETUP([POPT], [popt], [popt])
@@ -2340,6 +2341,7 @@ if test "$USE_PJPROJECT" != "no" ; then
       CPPFLAGS="${CPPFLAGS} ${PJPROJECT_CFLAGS}"
       LIBS="${LIBS} ${PJPROJECT_LIB}"
       AST_C_COMPILE_CHECK([PJSIP_TLS_TRANSPORT_PROTO], [struct pjsip_tls_setting setting; int proto; proto = setting.proto;], [pjsip.h])
+      AST_C_COMPILE_CHECK([PJSIP_INV_ACCEPT_MULTIPLE_SDP_ANSWERS], [pjsip_cfg()->endpt.accept_multiple_sdp_answers = 0;], [pjsip.h])
       LIBS="${saved_libs}"
       CPPFLAGS="${saved_cppflags}"
 
diff --git a/contrib/ast-db-manage/config/versions/0be05c3a8225_add_early_media_options.py b/contrib/ast-db-manage/config/versions/0be05c3a8225_add_early_media_options.py
new file mode 100644
index 0000000000000000000000000000000000000000..d82b1d2346870e86ea3748377f02396fa958bda6
--- /dev/null
+++ b/contrib/ast-db-manage/config/versions/0be05c3a8225_add_early_media_options.py
@@ -0,0 +1,37 @@
+"""Add early media options
+
+Revision ID: 0be05c3a8225
+Revises: d3e4284f8707
+Create Date: 2018-06-18 17:26:16.737692
+
+"""
+
+# revision identifiers, used by Alembic.
+revision = '0be05c3a8225'
+down_revision = 'd3e4284f8707'
+
+from alembic import op
+import sqlalchemy as sa
+from sqlalchemy.dialects.postgresql import ENUM
+
+YESNO_NAME = 'yesno_values'
+YESNO_VALUES = ['yes', 'no']
+
+def upgrade():
+    yesno_values = ENUM(*YESNO_VALUES, name=YESNO_NAME, create_type=False)
+
+    op.add_column('ps_systems', sa.Column('follow_early_media_fork', yesno_values))
+    op.add_column('ps_systems', sa.Column('accept_multiple_sdp_answers', yesno_values))
+    op.add_column('ps_endpoints', sa.Column('follow_early_media_fork', yesno_values))
+    op.add_column('ps_endpoints', sa.Column('accept_multiple_sdp_answers', yesno_values))
+
+def downgrade():
+    if op.get_context().bind.dialect.name == 'mssql':
+        op.drop_constraint('ck_ps_systems_follow_early_media_fork_yesno_values','ps_systems')
+        op.drop_constraint('ck_ps_systems_accept_multiple_sdp_answers_yesno_values','ps_systems')
+        op.drop_constraint('ck_ps_endpoints_follow_early_media_fork_yesno_values','ps_endpoints')
+        op.drop_constraint('ck_ps_endpoints_accept_multiple_sdp_answers_yesno_values','ps_endpoints')
+    op.drop_column('ps_systems', 'follow_early_media_fork')
+    op.drop_column('ps_systems', 'accept_multiple_sdp_answers')
+    op.drop_column('ps_endpoints', 'follow_early_media_fork')
+    op.drop_column('ps_endpoints', 'accept_multiple_sdp_answers')
diff --git a/include/asterisk/autoconfig.h.in b/include/asterisk/autoconfig.h.in
index 39d2e8088ce0fcdb5fddc6c868401267e231357a..def4efd52a9e20fbab3677baad8adf060ec2ed2a 100644
--- a/include/asterisk/autoconfig.h.in
+++ b/include/asterisk/autoconfig.h.in
@@ -623,6 +623,10 @@
 /* Define to 1 if PJPROJECT has the pjsip_get_dest_info support feature. */
 #undef HAVE_PJSIP_GET_DEST_INFO
 
+/* Define if your system has the PJSIP_INV_ACCEPT_MULTIPLE_SDP_ANSWERS
+   headers. */
+#undef HAVE_PJSIP_INV_ACCEPT_MULTIPLE_SDP_ANSWERS
+
 /* Define to 1 if PJPROJECT has the PJSIP INVITE Session Reference Count
    support feature. */
 #undef HAVE_PJSIP_INV_SESSION_REF
diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h
index 028051a2ba8b00b18e1e0e801b811d1b01bf29af..b94269a32673e24194c5880922eba4882fd7fd0c 100644
--- a/include/asterisk/res_pjsip.h
+++ b/include/asterisk/res_pjsip.h
@@ -643,6 +643,10 @@ struct ast_sip_media_rtp_configuration {
 	unsigned int timeout;
 	/*! Number of seconds before terminating channel due to lack of RTP (when on hold) */
 	unsigned int timeout_hold;
+	/*! Follow forked media with a different To tag */
+	unsigned int follow_early_media_fork;
+	/*! Accept updated SDPs on non-100rel 18X and 2XX responses with the same To tag */
+	unsigned int accept_multiple_sdp_answers;
 };
 
 /*!
diff --git a/res/res_pjsip.c b/res/res_pjsip.c
index b6a736b2021795cd688c660e3a57f2e669f26135..9a6b310715a2dd4bf3053374d73c44881d121457 100644
--- a/res/res_pjsip.c
+++ b/res/res_pjsip.c
@@ -1080,6 +1080,36 @@
 						changes.  If not set, incoming MWI NOTIFYs are ignored.
 					</para></description>
 				</configOption>
+				<configOption name="follow_early_media_fork">
+					<synopsis>Follow SDP forked media when To tag is different</synopsis>
+					<description><para>
+						On outgoing calls, if the UAS responds with different SDP attributes
+						on subsequent 18X or 2XX responses (such as a port update) AND the
+						To tag on the subsequent response is different than that on the previous
+						one, follow it. This usually happens when the INVITE is forked to multiple
+						UASs and more than one sends an SDP answer.
+						</para>
+						<note><para>
+							This option must also be enabled in the <literal>system</literal>
+							section for it to take effect here.
+						</para></note>
+					</description>
+				</configOption>
+				<configOption name="accept_multiple_sdp_answers" default="no">
+					<synopsis>Accept multiple SDP answers on non-100rel responses</synopsis>
+					<description><para>
+						On outgoing calls, if the UAS responds with different SDP attributes
+						on non-100rel 18X or 2XX responses (such as a port update) AND the
+						To tag on the subsequent response is the same as that on the previous one,
+						process the updated SDP.  This can happen when the UAS needs to change ports
+						for some reason such as using a separate port for custom ringback.
+						</para>
+						<note><para>
+							This option must also be enabled in the <literal>system</literal>
+							section for it to take effect here.
+						</para></note>
+					</description>
+				</configOption>
 			</configObject>
 			<configObject name="auth">
 				<synopsis>Authentication type</synopsis>
@@ -1647,6 +1677,34 @@
 						request is too large.  See RFC 3261 section 18.1.1.
 					</para></description>
 				</configOption>
+				<configOption name="follow_early_media_fork">
+					<synopsis>Follow SDP forked media when To tag is different</synopsis>
+					<description><para>
+						On outgoing calls, if the UAS responds with different SDP attributes
+						on subsequent 18X or 2XX responses (such as a port update) AND the
+						To tag on the subsequent response is different than that on the previous
+						one, follow it.
+						</para>
+						<note><para>
+							This option must also be enabled on endpoints that require
+							this functionality.
+						</para></note>
+					</description>
+				</configOption>
+				<configOption name="accept_multiple_sdp_answers">
+					<synopsis>Follow SDP forked media when To tag is the same</synopsis>
+					<description><para>
+						On outgoing calls, if the UAS responds with different SDP attributes
+						on non-100rel 18X or 2XX responses (such as a port update) AND the
+						To tag on the subsequent response is the same as that on the previous one,
+						process the updated SDP.
+						</para>
+						<note><para>
+							This option must also be enabled on endpoints that require
+							this functionality.
+						</para></note>
+					</description>
+				</configOption>
 				<configOption name="type">
 					<synopsis>Must be of type 'system'.</synopsis>
 				</configOption>
diff --git a/res/res_pjsip/config_system.c b/res/res_pjsip/config_system.c
index ed2b5d232b27f6f431c77a9873ad97df19a80a85..65e4e2c05ec7f7101aaddc87071a8e828bcaf4c8 100644
--- a/res/res_pjsip/config_system.c
+++ b/res/res_pjsip/config_system.c
@@ -52,6 +52,13 @@ struct system_config {
 	} threadpool;
 	/*! Nonzero to disable switching from UDP to TCP transport */
 	unsigned int disable_tcp_switch;
+	/*!
+	 * Although early media is enabled in pjproject by default, it's only
+	 * enabled when the To tags are different. These options allow turning
+	 * on or off the feature for different tags and same tags.
+	 */
+	unsigned int follow_early_media_fork;
+	unsigned int accept_multiple_sdp_answers;
 };
 
 static struct ast_threadpool_options sip_threadpool_options = {
@@ -96,6 +103,16 @@ static int system_apply(const struct ast_sorcery *system_sorcery, void *obj)
 	pjsip_cfg()->tsx.t1 = system->timert1;
 	pjsip_cfg()->tsx.td = system->timerb;
 
+	pjsip_cfg()->endpt.follow_early_media_fork = system->follow_early_media_fork;
+#ifdef HAVE_PJSIP_INV_ACCEPT_MULTIPLE_SDP_ANSWERS
+	pjsip_cfg()->endpt.accept_multiple_sdp_answers = system->accept_multiple_sdp_answers;
+#else
+	if (system->accept_multiple_sdp_answers) {
+		ast_log(LOG_WARNING,
+			"The accept_multiple_sdp_answers flag is not supported in this version of pjproject. Ignoring\n");
+	}
+#endif
+
 	if (system->compactheaders) {
 		extern pj_bool_t pjsip_use_compact_form;
 
@@ -184,6 +201,10 @@ int ast_sip_initialize_system(void)
 			OPT_UINT_T, 0, FLDSET(struct system_config, threadpool.max_size));
 	ast_sorcery_object_field_register(system_sorcery, "system", "disable_tcp_switch", "yes",
 			OPT_BOOL_T, 1, FLDSET(struct system_config, disable_tcp_switch));
+	ast_sorcery_object_field_register(system_sorcery, "system", "follow_early_media_fork", "yes",
+			OPT_BOOL_T, 1, FLDSET(struct system_config, follow_early_media_fork));
+	ast_sorcery_object_field_register(system_sorcery, "system", "accept_multiple_sdp_answers", "no",
+			OPT_BOOL_T, 1, FLDSET(struct system_config, accept_multiple_sdp_answers));
 
 	ast_sorcery_load(system_sorcery);
 
diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c
index 80983af634cf1c28d2242cd6e4ef450acfacf692..f44ceb0c325b86adee4afd8670b3058c5bde1949 100644
--- a/res/res_pjsip/pjsip_configuration.c
+++ b/res/res_pjsip/pjsip_configuration.c
@@ -1902,6 +1902,8 @@ int ast_res_pjsip_initialize_configuration(void)
 	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "bundle", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, media.bundle));
 	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "webrtc", "no", OPT_YESNO_T, 1, FLDSET(struct ast_sip_endpoint, media.webrtc));
 	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "incoming_mwi_mailbox", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, incoming_mwi_mailbox));
+	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "follow_early_media_fork", "yes", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, media.rtp.follow_early_media_fork));
+	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "accept_multiple_sdp_answers", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, media.rtp.accept_multiple_sdp_answers));
 
 	if (ast_sip_initialize_sorcery_transport()) {
 		ast_log(LOG_ERROR, "Failed to register SIP transport support with sorcery\n");
diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c
index 8b1012e5e005e7c0c638cc34656380c04a498423..1ec6901fc502e9f098eab4f9cdf19acd206dd20a 100644
--- a/res/res_pjsip_session.c
+++ b/res/res_pjsip_session.c
@@ -4053,6 +4053,42 @@ static void session_inv_on_media_update(pjsip_inv_session *inv, pj_status_t stat
 		return;
 	}
 
+	if (session->endpoint) {
+		int bail = 0;
+
+		/*
+		 * If following_fork is set, then this is probably the result of a
+		 * forked INVITE and SDP asnwers coming from the different fork UAS
+		 * destinations.  In this case updated_sdp_answer will also be set.
+		 *
+		 * If only updated_sdp_answer is set, then this is the non-forking
+		 * scenario where the same UAS just needs to change something like
+		 * the media port.
+		 */
+
+		if (inv->following_fork) {
+			if (session->endpoint->media.rtp.follow_early_media_fork) {
+				ast_debug(3, "Following early media fork with different To tags\n");
+			} else {
+				ast_debug(3, "Not following early media fork with different To tags\n");
+				bail = 1;
+			}
+		}
+#ifdef HAVE_PJSIP_INV_ACCEPT_MULTIPLE_SDP_ANSWERS
+		else if (inv->updated_sdp_answer) {
+			if (session->endpoint->media.rtp.accept_multiple_sdp_answers) {
+				ast_debug(3, "Accepting updated SDP with same To tag\n");
+			} else {
+				ast_debug(3, "Ignoring updated SDP answer with same To tag\n");
+				bail = 1;
+			}
+		}
+#endif
+		if (bail) {
+			return;
+		}
+	}
+
 	if ((status != PJ_SUCCESS) || (pjmedia_sdp_neg_get_active_local(inv->neg, &local) != PJ_SUCCESS) ||
 		(pjmedia_sdp_neg_get_active_remote(inv->neg, &remote) != PJ_SUCCESS)) {
 		ast_channel_hangupcause_set(session->channel, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
diff --git a/third-party/pjproject/configure.m4 b/third-party/pjproject/configure.m4
index 42482b2e5e6ba758a382f3c8375098df500ddcc4..9b70e09ff6d248bbfe903c13429c745f3c6f730d 100644
--- a/third-party/pjproject/configure.m4
+++ b/third-party/pjproject/configure.m4
@@ -87,6 +87,7 @@ AC_DEFUN([_PJPROJECT_CONFIGURE],
 	AC_DEFINE([HAVE_PJSIP_INV_SESSION_REF], 1, [Define if your system has PJSIP_INV_SESSION_REF])
 	AC_DEFINE([HAVE_PJSIP_AUTH_CLT_DEINIT], 1, [Define if your system has pjsip_auth_clt_deinit declared.])
 	AC_DEFINE([HAVE_PJSIP_TSX_LAYER_FIND_TSX2], 1, [Define if your system has pjsip_tsx_layer_find_tsx2 declared.])
+	AC_DEFINE([HAVE_PJSIP_INV_ACCEPT_MULTIPLE_SDP_ANSWERS], 1, [Define if your system has HAVE_PJSIP_INV_ACCEPT_MULTIPLE_SDP_ANSWERS declared.])
 
 	AC_SUBST([PJPROJECT_BUNDLED])
 	AC_SUBST([PJPROJECT_DIR])
diff --git a/third-party/pjproject/patches/0100-sip_inv-Add-option-to-accept-updated-SDP-on-same-To-.patch b/third-party/pjproject/patches/0100-sip_inv-Add-option-to-accept-updated-SDP-on-same-To-.patch
new file mode 100644
index 0000000000000000000000000000000000000000..cfcc9e8826e2584288af24c46f2a36840eda28b3
--- /dev/null
+++ b/third-party/pjproject/patches/0100-sip_inv-Add-option-to-accept-updated-SDP-on-same-To-.patch
@@ -0,0 +1,215 @@
+From 13e20772cd3c8735a6b78e30391a33f3eba4c023 Mon Sep 17 00:00:00 2001
+From: George Joseph <gjoseph@digium.com>
+Date: Fri, 22 Jun 2018 09:33:34 -0600
+Subject: [PATCH] sip_inv:  Add option to accept updated SDP on same To tag
+
+Currently, setting pjsip_cfg()->endpt.follow_early_media_fork allows
+sip_inv to process media updates when the To tag is different.  There
+are some cases where media updates need to be processed when the tags
+are the same.  Since removing the requirement for different tags would
+change default behavior, a new option "accept_multiple_sdp_answers"
+has been added along with a new pjsip_inv_session flag
+"updated_sdp_answer" to indicate under which condition we're
+updating.
+
+The logic was also updated to more closely follow RFC6337 in that
+if 100rel is efffect, do not accept updated SDPs.
+
+See
+https://tools.ietf.org/html/rfc6337#section-3.1.1
+for more information.
+---
+ pjsip/include/pjsip-ua/sip_inv.h |  2 ++
+ pjsip/include/pjsip/sip_config.h | 25 ++++++++++++++++
+ pjsip/src/pjsip-ua/sip_inv.c     | 62 +++++++++++++++++++++++++---------------
+ pjsip/src/pjsip/sip_config.c     |  3 +-
+ 4 files changed, 68 insertions(+), 24 deletions(-)
+
+diff --git a/pjsip/include/pjsip-ua/sip_inv.h b/pjsip/include/pjsip-ua/sip_inv.h
+index 1bb7b8adc..77ef070c3 100644
+--- a/pjsip/include/pjsip-ua/sip_inv.h
++++ b/pjsip/include/pjsip-ua/sip_inv.h
+@@ -442,6 +442,8 @@ struct pjsip_inv_session
+     pj_bool_t		 following_fork;	    /**< Internal, following
+ 							 forked media?	    */
+     pj_atomic_t		*ref_cnt;		    /**< Reference counter. */
++    pj_bool_t            updated_sdp_answer;        /**< SDP answer just been
++							 updated?	    */
+ };
+ 
+ 
+diff --git a/pjsip/include/pjsip/sip_config.h b/pjsip/include/pjsip/sip_config.h
+index b3a9468e2..b7cf6feed 100644
+--- a/pjsip/include/pjsip/sip_config.h
++++ b/pjsip/include/pjsip/sip_config.h
+@@ -157,6 +157,17 @@ typedef struct pjsip_cfg_t
+ 	 */
+ 	pj_bool_t disable_secure_dlg_check;
+ 
++        /**
++         * Accept multiple SDP answers on non-reliable 18X responses and the 2XX
++         * response when they are all received from the same source (same To tag).
++         *
++         * See also:
++         * https://tools.ietf.org/html/rfc6337#section-3.1.1
++         *
++         * Default is PJSIP_ACCEPT_MULTIPLE_SDP_ANSWERS.
++         */
++        pj_bool_t accept_multiple_sdp_answers;
++
+     } endpt;
+ 
+     /** Transaction layer settings. */
+@@ -402,6 +413,20 @@ PJ_INLINE(pjsip_cfg_t*) pjsip_cfg(void)
+ #endif
+ 
+ 
++/**
++ * Accept multiple SDP answers on non-reliable 18X responses and the 2XX
++ * response when they are all received from the same source (same To tag).
++ *
++ * This option can also be controlled at run-time by the
++ * \a accept_multiple_sdp_answers setting in pjsip_cfg_t.
++ *
++ * Default is PJ_FALSE.
++ */
++#ifndef PJSIP_ACCEPT_MULTIPLE_SDP_ANSWERS
++#   define PJSIP_ACCEPT_MULTIPLE_SDP_ANSWERS        PJ_TRUE
++#endif
++
++
+ /**
+  * Specify whether "alias" param should be added to the Via header
+  * in any outgoing request with connection oriented transport.
+diff --git a/pjsip/src/pjsip-ua/sip_inv.c b/pjsip/src/pjsip-ua/sip_inv.c
+index c9686a088..c22726bad 100644
+--- a/pjsip/src/pjsip-ua/sip_inv.c
++++ b/pjsip/src/pjsip-ua/sip_inv.c
+@@ -162,6 +162,7 @@ struct tsx_inv_data
+     pj_bool_t		 retrying;  /* Resend (e.g. due to 401/407)         */
+     pj_str_t		 done_tag;  /* To tag in RX response with answer    */
+     pj_bool_t		 done_early;/* Negotiation was done for early med?  */
++    pj_bool_t		 done_early_rel;/* Early med was realiable?	    */
+     pj_bool_t		 has_sdp;   /* Message with SDP?		    */
+ };
+ 
+@@ -2000,18 +2001,20 @@ static pj_status_t inv_check_sdp_in_incoming_msg( pjsip_inv_session *inv,
+ 
+     /* Initialize info that we are following forked media */
+     inv->following_fork = PJ_FALSE;
++    inv->updated_sdp_answer = PJ_FALSE;
+ 
+     /* MUST NOT do multiple SDP offer/answer in a single transaction,
+-     * EXCEPT if:
+-     *	- this is an initial UAC INVITE transaction (i.e. not re-INVITE), and
+-     *	- the previous negotiation was done on an early media (18x) and
+-     *    this response is a final/2xx response, and
+-     *  - the 2xx response has different To tag than the 18x response
+-     *    (i.e. the request has forked).
++     * EXCEPT previous nego was in 18x (early media) and any of the following
++     * condition is met:
++     *  - Non-forking scenario:
++     *	  - 'accept_multiple_sdp_answers' is set, and
++     *    - previous early response was not reliable (rfc6337 section 3.1.1).
++     *  - Forking scenario:
++     *    - This response has different To tag than the previous response, and
++     *    - This response is 18x/2xx (early or final). If this is 18x,
++     *      only do multiple SDP nego if 'follow_early_media_fork' is set.
+      *
+-     * The exception above is to add a rudimentary support for early media
+-     * forking (sample case: custom ringback). See this ticket for more
+-     * info: http://trac.pjsip.org/repos/ticket/657
++     * See also ticket #657, #1644, #1764 for more info.
+      */
+     if (tsx_inv_data->sdp_done) {
+ 	pj_str_t res_tag;
+@@ -2020,21 +2023,29 @@ static pj_status_t inv_check_sdp_in_incoming_msg( pjsip_inv_session *inv,
+ 	res_tag = rdata->msg_info.to->tag;
+ 	st_code = rdata->msg_info.msg->line.status.code;
+ 
+-	/* Allow final/early response after SDP has been negotiated in early
+-	 * media, IF this response is a final/early response with different
+-	 * tag.
+-         * See ticket #1644 and #1764 for forked early media case.
+-	 */
+-	if (tsx->role == PJSIP_ROLE_UAC &&
+-	    (st_code/100 == 2 ||
+-	     (st_code/10 == 18 /* st_code == 18x */
+-              && pjsip_cfg()->endpt.follow_early_media_fork)) &&
+-	    tsx_inv_data->done_early &&
+-	    pj_stricmp(&tsx_inv_data->done_tag, &res_tag))
++	if (tsx->role == PJSIP_ROLE_UAC && tsx_inv_data->done_early &&
++	       (
++	           /* Non-forking scenario */
++	           (
++	               !tsx_inv_data->done_early_rel &&
++	               (st_code/100 == 2 || st_code/10 == 18) &&
++                       pjsip_cfg()->endpt.accept_multiple_sdp_answers &&
++	               !pj_stricmp(&tsx_inv_data->done_tag, &res_tag)
++	           )
++	           ||
++	           /* Forking scenario */
++	           (
++	               (st_code/100 == 2 ||
++	                   (st_code/10 == 18 &&
++	                       pjsip_cfg()->endpt.follow_early_media_fork)) &&
++	               pj_stricmp(&tsx_inv_data->done_tag, &res_tag)
++	           )
++	       )
++	   )
+ 	{
+ 	    const pjmedia_sdp_session *reoffer_sdp = NULL;
+ 
+-	    PJ_LOG(4,(inv->obj_name, "Received forked %s response "
++	    PJ_LOG(4,(inv->obj_name, "Received %s response "
+ 		      "after SDP negotiation has been done in early "
+ 		      "media. Renegotiating SDP..",
+ 		      (st_code/10==18? "early" : "final" )));
+@@ -2054,7 +2065,9 @@ static pj_status_t inv_check_sdp_in_incoming_msg( pjsip_inv_session *inv,
+ 		return status;
+ 	    }
+ 
+-	    inv->following_fork = PJ_TRUE;
++	    inv->following_fork = !!pj_stricmp(&tsx_inv_data->done_tag,
++					       &res_tag);
++	    inv->updated_sdp_answer = PJ_TRUE;
+ 
+ 	} else {
+ 
+@@ -2135,6 +2148,7 @@ static pj_status_t inv_check_sdp_in_incoming_msg( pjsip_inv_session *inv,
+ 		PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER) 
+     {
+ 	int status_code;
++	pjsip_msg *msg = rdata->msg_info.msg;
+ 
+ 	/* This is an answer. 
+ 	 * Process and negotiate remote answer.
+@@ -2161,8 +2175,10 @@ static pj_status_t inv_check_sdp_in_incoming_msg( pjsip_inv_session *inv,
+ 	 */
+ 
+ 	tsx_inv_data->sdp_done = 1;
+-	status_code = rdata->msg_info.msg->line.status.code;
++	status_code = msg->line.status.code;
+ 	tsx_inv_data->done_early = (status_code/100==1);
++	tsx_inv_data->done_early_rel = tsx_inv_data->done_early &&
++				       pjsip_100rel_is_reliable(rdata);
+ 	pj_strdup(tsx->pool, &tsx_inv_data->done_tag, 
+ 		  &rdata->msg_info.to->tag);
+ 
+diff --git a/pjsip/src/pjsip/sip_config.c b/pjsip/src/pjsip/sip_config.c
+index 3576f351e..316824a00 100644
+--- a/pjsip/src/pjsip/sip_config.c
++++ b/pjsip/src/pjsip/sip_config.c
+@@ -34,7 +34,8 @@ pjsip_cfg_t pjsip_sip_cfg_var =
+        PJSIP_FOLLOW_EARLY_MEDIA_FORK,
+        PJSIP_REQ_HAS_VIA_ALIAS,
+        PJSIP_RESOLVE_HOSTNAME_TO_GET_INTERFACE,
+-       0
++       0,
++       PJSIP_ACCEPT_MULTIPLE_SDP_ANSWERS
+     },
+ 
+     /* Transaction settings */
+-- 
+2.14.4
+