diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 1ac7c6e709acd458da8feb49c72ecb7974d6d2d1..f87697f46a270972a656ad5946c59f0800f9a46f 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -378,6 +378,7 @@ enum check_auth_result {
 	AUTH_UNKNOWN_DOMAIN = -5,
 	AUTH_PEER_NOT_DYNAMIC = -6,
 	AUTH_ACL_FAILED = -7,
+	AUTH_BAD_TRANSPORT = -8,
 };
 
 /*! \brief States for outbound registrations (with register= lines in sip.conf */
@@ -1461,6 +1462,7 @@ struct sip_mailbox {
 struct sip_peer {
 	char name[80];			/*!< peer->name is the unique name of this object */
 	struct sip_socket socket;	/*!< Socket used for this peer */
+	unsigned int transports:3; /*!< Transports (enum sip_transport) that are acceptable for this peer */
 	char secret[80];		/*!< Password */
 	char md5secret[80];		/*!< Password in MD5 */
 	struct sip_auth *auth;		/*!< Realm authentication list */
@@ -2714,6 +2716,27 @@ static inline int sip_debug_test_pvt(struct sip_pvt *p)
 	return sip_debug_test_addr(sip_real_dst(p));
 }
 
+static inline const char *get_transport_list(struct sip_peer *peer) {
+	switch (peer->transports) {
+		case SIP_TRANSPORT_UDP:
+			return "UDP";
+		case SIP_TRANSPORT_TCP:
+			return "TCP";
+		case SIP_TRANSPORT_TLS:
+			return "TLS";
+	}
+
+	if (peer->transports & (SIP_TRANSPORT_TLS | SIP_TRANSPORT_TCP))
+		return "TLS,TCP";
+	if (peer->transports & (SIP_TRANSPORT_TLS | SIP_TRANSPORT_UDP))
+		return "TLS,UDP";
+	if (peer->transports & (SIP_TRANSPORT_UDP | SIP_TRANSPORT_TCP))
+		return "TCP,UDP";
+
+	return peer->transports ? 
+		"TLS,TCP,UDP" : "UNKNOWN";
+}
+
 static inline const char *get_transport(enum sip_transport t)
 {
 	switch (t) {
@@ -10321,8 +10344,9 @@ static enum parse_register_result parse_register_contact(struct sip_pvt *pvt, st
 		}
 	}
 
-	copy_socket_data(&peer->socket, &req->socket);
-	copy_socket_data(&pvt->socket, &peer->socket);
+	if (peer->socket.type == req->socket.type)
+		copy_socket_data(&peer->socket, &req->socket);
+	copy_socket_data(&pvt->socket, &req->socket);
 
 	/* Look for brackets */
 	curi = contact;
@@ -10941,6 +10965,29 @@ static enum check_auth_result register_verify(struct sip_pvt *p, struct sockaddr
 					res = 0;
 					break;
 				}
+
+				if (peer->socket.type != req->socket.type ) {
+					if (!(peer->transports & req->socket.type)) {
+						ast_log(LOG_ERROR,
+							"peer '%s' has contacted us over %s, but we only accept '%s' for this peer! ending call.\n",
+							peer->name, get_transport(req->socket.type), get_transport_list(peer)
+						);
+
+						ast_set_flag(&p->flags[0], SIP_PENDINGBYE);
+						transmit_response_with_date(p, "403 Forbidden", req);
+						res = AUTH_BAD_TRANSPORT;
+					} else if (peer->socket.type & SIP_TRANSPORT_TLS) {
+						ast_log(LOG_WARNING,
+							"peer '%s' HAS STOPPED USING TLS in favor of '%s' (but this was allowed in sip.conf)!\n",
+							peer->name, get_transport(req->socket.type)
+						);
+					} else {
+						ast_log(LOG_DEBUG,
+							"peer '%s' has contacted us over %s even though we prefer %s.\n", 
+							peer->name, get_transport(req->socket.type), get_transport(peer->socket.type)
+						);
+					}
+				}
 			} 
 		}
 	}
@@ -11019,6 +11066,7 @@ static enum check_auth_result register_verify(struct sip_pvt *p, struct sockaddr
 							name, ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
 			}
 			break;
+		case AUTH_BAD_TRANSPORT:
 		default:
 			break;
 		}
@@ -19165,6 +19213,9 @@ static int handle_request_register(struct sip_pvt *p, struct sip_request *req, s
 		case AUTH_ACL_FAILED:
 			reason = "Device does not match ACL";
 			break;
+		case AUTH_BAD_TRANSPORT:
+			reason = "Device not configured to use this transport type";
+			break;
 		default:
 			reason = "Unknown failure";
 			break;
@@ -21198,17 +21249,21 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
 	/* If we have realm authentication information, remove them (reload) */
 	clear_realm_authentication(peer->auth);
 	peer->auth = NULL;
+	peer->transports = 0;
+	peer->socket.type = 0;
 
 	for (; v || ((v = alt) && !(alt=NULL)); v = v->next) {
 		if (handle_common_options(&peerflags[0], &mask[0], v))
 			continue;
 		if (!strcasecmp(v->name, "transport")) {
 			if (!strcasecmp(v->value, "udp")) 
-				peer->socket.type = SIP_TRANSPORT_UDP;
+				peer->transports &= SIP_TRANSPORT_UDP;
 			else if (!strcasecmp(v->value, "tcp"))
-				peer->socket.type = SIP_TRANSPORT_TCP;
+				peer->transports &= SIP_TRANSPORT_TCP;
 			else if (!strcasecmp(v->value, "tls"))
-				peer->socket.type = SIP_TRANSPORT_TLS;
+				peer->transports &= SIP_TRANSPORT_TLS;
+			if (!peer->socket.type) /*!< The first transport listed should be used for outgoing */
+				peer->socket.type = peer->transports;
 		} else if (realtime && !strcasecmp(v->name, "regseconds")) {
 			ast_get_time_t(v->value, &regseconds, 0, NULL);
 		} else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) {
@@ -21450,6 +21505,11 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
 		}
 	}
 
+	if (!peer->socket.type) {
+		peer->transports  = SIP_TRANSPORT_UDP;
+		peer->socket.type = SIP_TRANSPORT_UDP;
+	}
+
 	if (fullcontact->used > 0) {
 		ast_copy_string(peer->fullcontact, fullcontact->str, sizeof(peer->fullcontact));
 		peer->rt_fromcontact = TRUE;
diff --git a/configs/sip.conf.sample b/configs/sip.conf.sample
index 3879c062d58f2bf921137f042e8ee585d472c919..3f10a4ce497f8aa9c1816af2d4766e720deb1736 100644
--- a/configs/sip.conf.sample
+++ b/configs/sip.conf.sample
@@ -685,6 +685,7 @@ srvlookup=yes			; Enable DNS SRV lookups on outbound calls
 ; deny                        deny
 ; secret                      secret
 ; md5secret                   md5secret
+; transport                   transport
 ; dtmfmode                    dtmfmode
 ; canreinvite                 canreinvite
 ; nat                         nat
@@ -753,6 +754,9 @@ srvlookup=yes			; Enable DNS SRV lookups on outbound calls
 ;fromuser=yourusername			; Many SIP providers require this!
 ;fromdomain=provider.sip.domain	
 ;host=box.provider.com
+;transport=udp,tcp		    ; This sets the transport type to udp for outgoing, and will
+;                           ;   accept both tcp and udp. Default is udp. The first transport
+;                           ;   listed will always be used for outgoing connections.
 ;usereqphone=yes			; This provider requires ";user=phone" on URI
 ;callcounter=yes			; Enable call counter
 ;busylevel=2				; Signal busy at 2 or more calls
@@ -767,6 +771,9 @@ srvlookup=yes			; Enable DNS SRV lookups on outbound calls
 ;fromuser=4015552299		; how your provider knows you
 ;secret=youwillneverguessit
 ;callbackextension=123		; Register with this server and require calls coming back to this extension
+;transport=udp,tcp		    ; This sets the transport type to udp for outgoing, and will
+;                           ;   accept both tcp and udp. Default is udp. The first transport
+;                           ;   listed will always be used for outgoing connections.
 
 ;------------------------------------------------------------------------------
 ; Definitions of locally connected SIP devices