diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index e60bd4bf23e3adb5789a79105c373f3e30124e97..d69ae80ace093e9e0df535c6d893f058fc3c7df9 100755
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -442,6 +442,7 @@ struct sip_invite_param {
 	char *distinctive_ring;
 	char *osptoken;
 	int addsipheaders;
+       char *uri_options;
 	char *vxml_url;
 	char *auth;
 	char *authheader;
@@ -1941,6 +1942,8 @@ static int sip_call(struct ast_channel *ast, char *dest, int timeout)
 		/* Check whether there is a VXML_URL variable */
 		if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) {
 			p->options->vxml_url = ast_var_value(current);
+               } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) {
+                       p->options->uri_options = ast_var_value(current);
 		} else if (!p->options->distinctive_ring && !strcasecmp(ast_var_name(current), "ALERT_INFO")) {
 			/* Check whether there is a ALERT_INFO variable */
 			p->options->distinctive_ring = ast_var_value(current);
@@ -4388,9 +4391,11 @@ static void build_contact(struct sip_pvt *p)
 }
 
 /*--- initreqprep: Initiate new SIP request to peer/user ---*/
-static void initreqprep(struct sip_request *req, struct sip_pvt *p, int sipmethod, char *vxml_url)
+static void initreqprep(struct sip_request *req, struct sip_pvt *p, int sipmethod)
 {
-	char invite[256] = "";
+	char invite_buf[256] = "";
+	char *invite = invite_buf;
+	size_t invite_max = sizeof(invite_buf);
 	char from[256];
 	char to[256];
 	char tmp[BUFSIZ/2];
@@ -4460,41 +4465,45 @@ static void initreqprep(struct sip_request *req, struct sip_pvt *p, int sipmetho
 	}
 
 	if ((ourport != 5060) && ast_strlen_zero(p->fromdomain))	/* Needs to be 5060 */
-		snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=as%08x", tmp, l, ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain, ourport, p->tag);
+		snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=as%08x", n, l, ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain, ourport, p->tag);
 	else
 		snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=as%08x", n, l, ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain, p->tag);
 
-	/* If we're calling a registred SIP peer, use the fullcontact to dial to the peer */
+	/* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */
 	if (!ast_strlen_zero(p->fullcontact)) {
 		/* If we have full contact, trust it */
-		ast_copy_string(invite, p->fullcontact, sizeof(invite));
-	/* Otherwise, use the username while waiting for registration */
-	} else if (!ast_strlen_zero(p->username)) {
-		n = p->username;
-		if (pedanticsipchecking) {
-			ast_uri_encode(n, tmp, sizeof(tmp), 0);
-			n = tmp;
-		}
-		if (ntohs(p->sa.sin_port) != 5060) {		/* Needs to be 5060 */
-			snprintf(invite, sizeof(invite), "sip:%s@%s:%d%s", n, p->tohost, ntohs(p->sa.sin_port), urioptions);
-		} else {
-			snprintf(invite, sizeof(invite), "sip:%s@%s%s", n, p->tohost, urioptions);
-		}
-	} else if (ntohs(p->sa.sin_port) != 5060) {		/* Needs to be 5060 */
-		snprintf(invite, sizeof(invite), "sip:%s:%d%s", p->tohost, ntohs(p->sa.sin_port), urioptions);
+		ast_build_string(&invite, &invite_max, "%s", p->fullcontact);
 	} else {
-		snprintf(invite, sizeof(invite), "sip:%s%s", p->tohost, urioptions);
+		/* Otherwise, use the username while waiting for registration */
+		ast_build_string(&invite, &invite_max, "sip:");
+		if (!ast_strlen_zero(p->username)) {
+			n = p->username;
+			if (pedanticsipchecking) {
+				ast_uri_encode(n, tmp, sizeof(tmp), 0);
+				n = tmp;
+			}
+			ast_build_string(&invite, &invite_max, "%s@", n);
+		}
+		ast_build_string(&invite, &invite_max, "%s", p->tohost);
+		if (ntohs(p->sa.sin_port) != 5060)		/* Needs to be 5060 */
+			ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port));
+		ast_build_string(&invite, &invite_max, "%s", urioptions);
 	}
-	ast_copy_string(p->uri, invite, sizeof(p->uri));
 
-	/* If there is a VXML URL append it to the SIP URL */
-	if (vxml_url) {
-		snprintf(to, sizeof(to), "<%s>;%s", invite, vxml_url);
-	} else {
-		snprintf(to, sizeof(to), "<%s>", invite);
+       /* If custom URI options have been provided, append them */
+       if (p->options && p->options->uri_options)
+	       ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options);
+
+       ast_copy_string(p->uri, invite_buf, sizeof(p->uri));
+
+       /* If there is a VXML URL append it to the SIP URL */
+       if (p->options && p->options->vxml_url) {
+               snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url);
+       } else {
+	       snprintf(to, sizeof(to), "<%s>", p->uri);
 	}
 	memset(req, 0, sizeof(struct sip_request));
-	init_req(req, sipmethod, invite);
+	init_req(req, sipmethod, p->uri);
 	snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text);
 
 	add_header(req, "Via", p->via);
@@ -4520,7 +4529,7 @@ static int transmit_invite(struct sip_pvt *p, int sipmethod, int sdp, int init)
 		/* Bump branch even on initial requests */
 		p->branch ^= rand();
 		build_via(p, p->via, sizeof(p->via));
-		initreqprep(&req, p, sipmethod, p->options ? p->options->vxml_url : (char *) NULL);
+               initreqprep(&req, p, sipmethod);
 	} else
 		reqprep(&req, p, sipmethod, 0, 1);
 		
@@ -4783,7 +4792,7 @@ static int transmit_notify_with_mwi(struct sip_pvt *p, int newmsgs, int oldmsgs,
 	char *t = tmp;
 	size_t maxbytes = sizeof(tmp);
 
-	initreqprep(&req, p, SIP_NOTIFY, NULL);
+       initreqprep(&req, p, SIP_NOTIFY);
 	add_header(&req, "Event", "message-summary");
 	add_header(&req, "Content-Type", default_notifymime);
 
@@ -8272,7 +8281,7 @@ static int sip_notify(int fd, int argc, char *argv[])
 			continue;
 		}
 
-		initreqprep(&req, p, SIP_NOTIFY, NULL);
+               initreqprep(&req, p, SIP_NOTIFY);
 
 		for (var = varlist; var; var = var->next)
 			add_header(&req, var->name, var->value);
diff --git a/doc/README.variables b/doc/README.variables
index fc96bd4462bca4288c72f8f1b8edb6c243e60ef4..90e74ffcdb988c6985079745928237f3cc0b6e06 100755
--- a/doc/README.variables
+++ b/doc/README.variables
@@ -628,13 +628,14 @@ ${CALLINGSUBADDR}	* Called PRI Subaddress
 ${FAXEXTEN}	 	* The extension called before being redirected to "fax"	
 ${PRIREDIRECTREASON}	* Reason for redirect, if a call was directed
 
-The SIP channel sets the following variables:
+The SIP channel uses the following variables:
 ---------------------------------------------------------
 ${SIPCALLID} 		* SIP Call-ID: header verbatim (for logging or CDR matching)
 ${SIPDOMAIN}    	* SIP destination domain of an inbound call (if appropriate)
 ${SIPUSERAGENT} 	* SIP user agent 
 ${SIPURI}		* SIP uri
 ${SIP_CODEC} 		Set the SIP codec for a call	
+${SIP_URI_OPTIONS}	* additional options to add to the URI for an outgoing call
 
 The Agent channel uses the following variables:
 ---------------------------------------------------------