[svn-commits] bbryant: trunk r125891 - in /trunk: channels/chan_sip.c configs/sip.conf.sample

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri Jun 27 11:28:06 CDT 2008


Author: bbryant
Date: Fri Jun 27 11:28:06 2008
New Revision: 125891

URL: http://svn.digium.com/view/asterisk?view=rev&rev=125891
Log:
Change the way that the transport option works for sip users. transport will now take multiple arguments, the first one listed will be the one used 
for new dialogs, and the rest listed will be acceptable ways for that peer to contact us. This fixes a minor bug where, because SIP TCP/UDP run on 
the same port, could cause a TCP peer to be saved in the ast_db. There will also be warnings when a transport is changed for an unexpected reason.

(issue #12799)

Modified:
    trunk/channels/chan_sip.c
    trunk/configs/sip.conf.sample

Modified: trunk/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/chan_sip.c?view=diff&rev=125891&r1=125890&r2=125891
==============================================================================
--- trunk/channels/chan_sip.c (original)
+++ trunk/channels/chan_sip.c Fri Jun 27 11:28:06 2008
@@ -378,6 +378,7 @@
 	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_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 */
@@ -2712,6 +2714,27 @@
 	if (!sipdebug)
 		return 0;
 	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)
@@ -10321,8 +10344,9 @@
 		}
 	}
 
-	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 @@
 					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 @@
 							name, ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
 			}
 			break;
+		case AUTH_BAD_TRANSPORT:
 		default:
 			break;
 		}
@@ -19165,6 +19213,9 @@
 		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 @@
 	/* 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 @@
 		}
 	}
 
+	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;

Modified: trunk/configs/sip.conf.sample
URL: http://svn.digium.com/view/asterisk/trunk/configs/sip.conf.sample?view=diff&rev=125891&r1=125890&r2=125891
==============================================================================
--- trunk/configs/sip.conf.sample (original)
+++ trunk/configs/sip.conf.sample Fri Jun 27 11:28:06 2008
@@ -685,6 +685,7 @@
 ; deny                        deny
 ; secret                      secret
 ; md5secret                   md5secret
+; transport                   transport
 ; dtmfmode                    dtmfmode
 ; canreinvite                 canreinvite
 ; nat                         nat
@@ -753,6 +754,9 @@
 ;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 @@
 ;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




More information about the svn-commits mailing list