Index: channels/chan_sip.c
===================================================================
--- channels/chan_sip.c	(revision 398195)
+++ channels/chan_sip.c	(working copy)
@@ -813,6 +813,7 @@
 static int global_match_auth_username;    /*!< Match auth username if available instead of From: Default off. */
 
 static int global_relaxdtmf;        /*!< Relax DTMF */
+static int global_enable_session_id;      /*!< Copy incoming Session-ID header to outbound calls. */
 static int global_prematuremediafilter;   /*!< Enable/disable premature frames in a call (causing 183 early media) */
 static int global_rtptimeout;       /*!< Time out call if no RTP */
 static int global_rtpholdtimeout;   /*!< Time out call if no RTP during hold */
@@ -1309,6 +1310,8 @@
 static struct ast_variable *copy_vars(struct ast_variable *src);
 static int dialog_find_multiple(void *obj, void *arg, int flags);
 static struct ast_channel *sip_pvt_lock_full(struct sip_pvt *pvt);
+static void add_sid(struct sip_pvt *p, struct sip_request *req);
+
 /* static int sip_addrcmp(char *name, struct sockaddr_in *sin);	Support for peer matching */
 static int sip_refer_alloc(struct sip_pvt *p);
 static int sip_notify_alloc(struct sip_pvt *p);
@@ -8979,6 +8982,25 @@
 	return 0;
 }
 
+/*! \brief Add Session-ID header to SIP message. The SESSIONID variable is set in handle_request_invite(). */
+static void add_sid(struct sip_pvt *p, struct sip_request *req)
+{
+	const char *sid;
+
+	if (!global_enable_session_id)
+		/* Feature not enabled. */
+		return;
+
+	if (p->owner && (sid = pbx_builtin_getvar_helper(p->owner, "SESSIONID")) != NULL && *sid != '\0') {
+		ast_debug(5, "Adding session id %s\n", sid);
+		add_header(req, "Session-ID", sid);
+	} else if (p->owner) {
+		ast_debug(5, "Channel %s does not have session id\n", ast_channel_name(p->owner));
+	} else {
+		ast_debug(5, "Channel not set\n");
+	}
+}
+
 /* \brief arguments used for Request/Response to matching */
 struct match_req_args {
 	int method;
@@ -14230,6 +14252,8 @@
 		add_header(&req, "Require", "replaces");
 	}
 
+	add_sid(p, &req);
+
 	/* Add Session-Timers related headers */
 	if (st_get_mode(p, 0) == SESSION_TIMER_MODE_ORIGINATE
 		|| (st_get_mode(p, 0) == SESSION_TIMER_MODE_ACCEPT
@@ -15712,6 +15736,9 @@
 	struct sip_request resp;
 
 	reqprep(&resp, p, sipmethod, seqno, newbranch);
+
+	add_sid(p, &resp);
+
 	if (sipmethod == SIP_CANCEL && p->answered_elsewhere) {
 		add_header(&resp, "Reason", "SIP;cause=200;text=\"Call completed elsewhere\"");
 	}
@@ -15744,6 +15771,9 @@
 	struct sip_request resp;
 
 	reqprep(&resp, p, sipmethod, seqno, newbranch);
+
+	add_sid(p, &resp);
+
 	if (!ast_strlen_zero(p->realm)) {
 		char digest[1024];
 
@@ -21071,6 +21101,7 @@
 	ast_cli(a->fd, "  Qualify Freq :          %d ms\n", global_qualifyfreq);
 	ast_cli(a->fd, "  Q.850 Reason header:    %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_Q850_REASON)));
 	ast_cli(a->fd, "  Store SIP_CAUSE:        %s\n", AST_CLI_YESNO(global_store_sip_cause));
+	ast_cli(a->fd, "  Enable Session-ID hdr:  %s\n", AST_CLI_YESNO(global_enable_session_id));
 	ast_cli(a->fd, "\nNetwork QoS Settings:\n");
 	ast_cli(a->fd, "---------------------------\n");
 	ast_cli(a->fd, "  IP ToS SIP:             %s\n", ast_tos2str(global_tos_sip));
@@ -25111,6 +25142,7 @@
 	int rtn;
 	struct ast_party_redirecting redirecting;
 	struct ast_set_party_redirecting update_redirecting;
+	const char *sid;
 
 	const char *p_uac_se_hdr;       /* UAC's Session-Expires header string                      */
 	const char *p_uac_min_se;       /* UAC's requested Min-SE interval (char string)            */
@@ -25162,6 +25194,10 @@
 	p->sipoptions |= required_profile;
 	p->reqsipoptions = required_profile;
 
+	/* If the Session-ID is present then store in SESSIONID variable. */
+	if (global_enable_session_id && (sid = sip_get_header(req, "Session-ID")))
+		pbx_builtin_setvar_helper(c, "SESSIONID", sid);
+
 	/* Check if this is a loop */
 	if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->invitestate != INV_TERMINATED && p->invitestate != INV_CONFIRMED) && ast_channel_state(p->owner) != AST_STATE_UP) {
 		/* This is a call to ourself.  Send ourselves an error code and stop
@@ -31416,6 +31452,7 @@
 	/* Misc settings for the channel */
 	global_relaxdtmf = FALSE;
 	global_authfailureevents = FALSE;
+	global_enable_session_id = FALSE;
 	global_t1 = DEFAULT_TIMER_T1;
 	global_timer_b = 64 * DEFAULT_TIMER_T1;
 	global_t1min = DEFAULT_T1MIN;
@@ -31986,6 +32023,8 @@
 			ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot));
 		} else if (!strcasecmp(v->name, "refer_addheaders")) {
 			global_refer_addheaders = ast_true(v->value);
+		} else if (!strcasecmp(v->name, "enable_session_id")) {
+			global_enable_session_id = ast_true(v->value);
 		}
 	}
 
