diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 092064a23987aa684548015a884967eee0181fda..9fc2340e4479e2b05636c03bf23f75566b64facd 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -2429,10 +2429,11 @@ static char *get_in_brackets(char *tmp)
 	return tmp;
 }
 
-/*!
- * parses a URI in its components.
- * If scheme is specified, drop it from the top.
- * If a component is not requested, do not split around it.
+/*! \brief * parses a URI in its components.
+ *
+ * \note 
+ *- If scheme is specified, drop it from the top.
+ * - If a component is not requested, do not split around it.
  * This means that if we don't have domain, we cannot split
  * name:pass and domain:port.
  * It is safe to call with ret_name, pass, domain, port
@@ -2440,6 +2441,7 @@ static char *get_in_brackets(char *tmp)
  * Init pointers to empty string so we never get NULL dereferencing.
  * Overwrites the string.
  * return 0 on success, other values on error.
+ * general form we are expecting is sip[s]:username[:password][;parameter]@host[:port][;...] 
  */
 static int parse_uri(char *uri, char *scheme,
 	char **ret_name, char **pass, char **domain, char **port, char **options)
@@ -2452,13 +2454,12 @@ static int parse_uri(char *uri, char *scheme,
 		*pass = "";
 	if (port)
 		*port = "";
-	name = strsep(&uri, ";");	/* remove options */
 	if (scheme) {
 		int l = strlen(scheme);
-		if (!strncmp(name, scheme, l))
-			name += l;
+		if (!strncmp(uri, scheme, l))
+			uri += l;
 		else {
-			ast_log(LOG_NOTICE, "Missing scheme '%s' in '%s'\n", scheme, name);
+			ast_log(LOG_NOTICE, "Missing scheme '%s' in '%s'\n", scheme, uri);
 			error = -1;
 		}
 	}
@@ -2472,14 +2473,20 @@ static int parse_uri(char *uri, char *scheme,
 		 */
 		char *c, *dom = "";
 
-		if ((c = strchr(name, '@')) == NULL) {
+		if ((c = strchr(uri, '@')) == NULL) {
 			/* domain-only URI, according to the SIP RFC. */
-			dom = name;
+			dom = uri;
 			name = "";
 		} else {
 			*c++ = '\0';
 			dom = c;
+			name = uri;
 		}
+
+		/* Remove options in domain and name */
+		dom = strsep(&dom, ";");
+		name = strsep(&name, ";");
+
 		if (port && (c = strchr(dom, ':'))) { /* Remove :port */
 			*c++ = '\0';
 			*port = c;
@@ -5922,7 +5929,7 @@ static void set_destination(struct sip_pvt *p, char *uri)
 	int debug=sip_debug_test_pvt(p);
 
 	/* Parse uri to h (host) and port - uri is already just the part inside the <> */
-	/* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */
+	/* general form we are expecting is sip[s]:username[:password][;parameter]@host[:port][;...] */
 
 	if (debug)
 		ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri);
@@ -7077,12 +7084,20 @@ static void extract_uri(struct sip_pvt *p, struct sip_request *req)
 {
 	char stripped[BUFSIZ];
 	char *c;
+	char *atsign;
 
 	ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped));
 	c = get_in_brackets(stripped);
-	c = strsep(&c, ";");	/* trim ; and beyond */
+	/* Cut the URI at the at sign after the @, not in the username part */
+	atsign = strchr(c, '@');	/* First, locate the at sign */
+	if (!atsign)
+		atsign = c;	/* Ok hostname only, let's stick with the rest */
+	atsign = strchr(atsign, ';');	/* Locate semi colon */
+	if (atsign)
+		*atsign = '\0';	/* Kill at the semi colon */
 	if (!ast_strlen_zero(c))
 		ast_string_field_set(p, uri, c);
+
 }
 
 /*! \brief Build contact header - the contact header we send out */