[asterisk-commits] oej: branch oej/pgtips-srv-and-outbound-stuff-1.8 r397702 - in /team/oej/pgti...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Aug 27 07:25:42 CDT 2013


Author: oej
Date: Tue Aug 27 07:25:39 2013
New Revision: 397702

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=397702
Log:
Add a DNS SRV context to the sip_pvt in order to prepare for failover.

Modified:
    team/oej/pgtips-srv-and-outbound-stuff-1.8/README.pgtips-srv-records
    team/oej/pgtips-srv-and-outbound-stuff-1.8/channels/chan_sip.c
    team/oej/pgtips-srv-and-outbound-stuff-1.8/channels/sip/include/sip.h
    team/oej/pgtips-srv-and-outbound-stuff-1.8/main/srv.c

Modified: team/oej/pgtips-srv-and-outbound-stuff-1.8/README.pgtips-srv-records
URL: http://svnview.digium.com/svn/asterisk/team/oej/pgtips-srv-and-outbound-stuff-1.8/README.pgtips-srv-records?view=diff&rev=397702&r1=397701&r2=397702
==============================================================================
--- team/oej/pgtips-srv-and-outbound-stuff-1.8/README.pgtips-srv-records (original)
+++ team/oej/pgtips-srv-and-outbound-stuff-1.8/README.pgtips-srv-records Tue Aug 27 07:25:39 2013
@@ -2,7 +2,7 @@
 Olle E. Johansson
 
 Project start: 2013-04-18
-Update:        2013-08-26
+Update:        2013-08-27
 
 
 
@@ -72,6 +72,21 @@
 of incoming calls, possibly deny calls from servers that does not match.
 This is NOT the expected solution.
 
+Failover
+========
+I see two situation for failover to the next host/ip in the SRV list:
+- sip_xmit fails (no destination, icmp unreachable etc)
+- timeout on Timer B
+
+The Timeout case is handled by the retransmit engine. We need to
+restart the timers and retransmissions with the same request.
+
+The SIP_xmit can be handled in send_request(). This function doesn't
+bother with failures at this time, strangely enough. What fails, fails,
+and currently there's nothing to do about it.
+
+We do need a function in main/srv.c to switch to the next entry and
+move the "current" pointer.
 
 Development Notes
 =================
@@ -82,12 +97,15 @@
 DNSmanager can still maintain A/AAAA records if enabled, but not SRV
 lists.
 
+Not fixed here
+==============
 At IETF 87 in Berlin I had a meeting with two members of the IETF DNS directorate
 to discuss SRV records. We discovered that SRV requires you to test ALL ip addresses
 found (in families you support) for a host before moving to the next host. 
 This means that if a host has multiple A or AAAA records, all of them should be
 tested. This is not supported in Asterisk currently and this patch will not
 fix that.
+
 
 Todo:
 =====
@@ -99,17 +117,19 @@
 3. Provide hooks for happy earballs if server is dual stack and we're dual stack
 4. Implement failover to next server in list if transaction fails.
 5. Make sure we use the DNS TTL properly
-6. Add multiple IPs to the peer in an ACL list
-	- Have added some code that fails to work. Is it me or the code?
-7. Add the same IPs to the AO2object for IP matching
-8. Make sure the ACL list is updated by DNS manager
-9. Change peer match by ip/port to use ACL list if available
-10. Fix outbound proxy SRV support (proxy_update)
-11. Avoid testing. Real developers don't test.
-12. Don't open a bug tracker issue on this project.
-13. De-install GDB. GDB is for weak developers.
-14. Do not write any documentation, regardless of what people say. It's a SEP.
-15. Stay calm and carry on.
+6. Use SRV for outbound proxys too, with failover
+7. Add multiple IPs to the peer in an ACL list
+	- Added a linked list
+	- Needs to be added to peers by ip list for matching. Not done yet.
+8. Add the same IPs to the AO2object for IP matching
+9. Make sure the ACL list is updated by DNS manager
+10. Change peer match by ip/port to use ACL list if available
+11. Fix outbound proxy SRV support (proxy_update)
+12. Avoid testing. Real developers don't test.
+13. Don't open a bug tracker issue on this project.
+14. De-install GDB. GDB is for weak developers.
+15. Do not write any documentation, regardless of what people say. It's a SEP.
+16. Stay calm and carry on.
 
 
 Query on AO2 object stuff:

Modified: team/oej/pgtips-srv-and-outbound-stuff-1.8/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pgtips-srv-and-outbound-stuff-1.8/channels/chan_sip.c?view=diff&rev=397702&r1=397701&r2=397702
==============================================================================
--- team/oej/pgtips-srv-and-outbound-stuff-1.8/channels/chan_sip.c (original)
+++ team/oej/pgtips-srv-and-outbound-stuff-1.8/channels/chan_sip.c Tue Aug 27 07:25:39 2013
@@ -4571,6 +4571,7 @@
 /*!
  * \internal
  * \brief Send SIP Request to the other part of the dialogue
+ * 	If the xmit returns a network error (XMIT_ERROR or -1) then try with another SRV record if it exists. 
  * \return see \ref __sip_xmit
  */
 static int send_request(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, uint32_t seqno)
@@ -4599,9 +4600,20 @@
 		append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", ast_str_buffer(tmp.data), get_header(&tmp, "CSeq"), sip_methods[tmp.method].text);
 		deinit_req(&tmp);
 	}
-	res = (reliable) ?
-		__sip_reliable_xmit(p, seqno, 0, req->data, (reliable == XMIT_CRITICAL), req->method) :
-		__sip_xmit(p, req->data);
+	if (p->srvcon) {
+		/* We have an SRV record set. If we get transmit errors, retry on the next directly. */
+		res = (reliable) ?
+			__sip_reliable_xmit(p, seqno, 0, req->data, (reliable == XMIT_CRITICAL), req->method) :
+			__sip_xmit(p, req->data);
+		if (res == -1 || res == XMIT_ERROR) {
+			ast_debug(3, "====>> SRV failover. Changing to next SRV record in the list\n");
+			XXX SRV FAILOVER HERE XXX
+		}
+	} else {
+		res = (reliable) ?
+			__sip_reliable_xmit(p, seqno, 0, req->data, (reliable == XMIT_CRITICAL), req->method) :
+			__sip_xmit(p, req->data);
+	}
 	deinit_req(req);
 	return res;
 }
@@ -5677,6 +5689,7 @@
  *
  * \return -1 on error, 0 on success.
  *
+ *    XXX SHould copy or create new SRV list (depending on the TTL) in the dialog structure.
  */
 static int create_addr_from_peer(struct sip_pvt *dialog, struct sip_peer *peer)
 {
@@ -5902,22 +5915,25 @@
 		 * an A record lookup should be used instead of SRV.
 		 */
 		if (!hostport.port && sip_cfg.srvlookup) {
-			struct srv_context *srvcon = ast_srv_context_new();
+			if (dialog->srvcon) {
+				ast_srv_context_free_list(dialog->srvcon);
+				dialog->srvcon = ast_srv_context_new();
+			}
 
 			snprintf(service, sizeof(service), "_%s._%s.%s", 
 				 get_srv_service(dialog->socket.type),
 				 get_srv_protocol(dialog->socket.type), peername);
 
 			/* Get the srv list */
-			if ((srv_ret = ast_get_srv_list(srvcon, NULL, service)) > 0) {
+			if ((srv_ret = ast_get_srv_list(dialog->srvcon, NULL, service)) > 0) {
 				int rec = 1;
 				unsigned short port, prio, weight;
 				const char *srvhost;
 
 				ast_debug(3, "   ==> DNS lookup of %s returned %d entries. First %s \n", service, ast_srv_get_record_count(srvcon), hostn);
 				hostn = host;
-				for (rec = 0; rec < ast_srv_get_record_count(srvcon); rec++) {
-					if(ast_srv_get_nth_record(srvcon, rec, &srvhost, &port, &prio, &weight)) {
+				for (rec = 0; rec < ast_srv_get_record_count(dialog->srvcon); rec++) {
+					if(ast_srv_get_nth_record(dialog->srvcon, rec, &srvhost, &port, &prio, &weight)) {
 						ast_log(LOG_WARNING, "No more SRV records for: %s\n", peername);
 						return -1;
 					}
@@ -5925,7 +5941,7 @@
 					hostn = host;
 					tportno = (int) port;
 					ast_debug(3, "   ==> Trying SRV entry %d (prio %d weight %d): %s\n", rec, prio, weight, hostn);
-					/* We need to try all IP addresses if there are multiple A / AAAA records*/
+					/* XXX We need to try all IP addresses if there are multiple A / AAAA records*/
 					if (!ast_sockaddr_resolve_first_transport(&dialog->sa, hostn, 0, dialog->socket.type ? dialog->socket.type : SIP_TRANSPORT_UDP)) {
 						/* We found a host to try on */
 						break;
@@ -5934,10 +5950,7 @@
 				}
 
 				ast_debug(3, "   ==> Settling with SRV entry %d:   %s\n", rec, hostn);
-
-			}
-			ast_srv_context_free_list(srvcon);
-			ast_free(srvcon);
+			}
 		} else {
 
 			if (ast_sockaddr_resolve_first_transport(&dialog->sa, hostn, 0, dialog->socket.type ? dialog->socket.type : SIP_TRANSPORT_UDP)) {
@@ -6248,6 +6261,10 @@
 	if (p->mwi) {
 		p->mwi->call = NULL;
 		p->mwi = NULL;
+	}
+	if (p->srvcon) {		/* Free the list of SRV entries used by this dialog */
+		ast_srv_context_free_list(p->srvcon);
+		ast_free(p->srvcon);
 	}
 
 	if (dumphistory)
@@ -28096,6 +28113,7 @@
 	struct sip_peer *peer = NULL;
 	struct ast_ha *oldha = NULL;
 	struct ast_ha *olddirectmediaha = NULL;
+	struct sip_host_ip *old_host_ip = NULL;
 	int found = 0;
 	int firstpass = 1;
 	uint16_t port = 0;
@@ -28718,7 +28736,7 @@
 
 			/* Now loop again and fill the ACL */
 			if (peer->srventries) {
-				free_sip_host_ip(peer->srventries);
+				old_sip_host_ip = peer->srventries;
 				peer->srventries = NULL;
 			}
 			for (rec = 1; rec <= ast_srv_get_record_count(peer->srvcontext); rec++) {
@@ -28862,6 +28880,7 @@
 
 	ast_free_ha(oldha);
 	ast_free_ha(olddirectmediaha);
+	free_sip_host_ip(old_sip_host_ip);
 	if (!ast_strlen_zero(callback)) { /* build string from peer info */
 		char *reg_string;
 		if (ast_asprintf(&reg_string, "%s?%s:%s@%s/%s", peer->name, peer->username, !ast_strlen_zero(peer->remotesecret) ? peer->remotesecret : peer->secret, peer->tohost, callback) >= 0) {

Modified: team/oej/pgtips-srv-and-outbound-stuff-1.8/channels/sip/include/sip.h
URL: http://svnview.digium.com/svn/asterisk/team/oej/pgtips-srv-and-outbound-stuff-1.8/channels/sip/include/sip.h?view=diff&rev=397702&r1=397701&r2=397702
==============================================================================
--- team/oej/pgtips-srv-and-outbound-stuff-1.8/channels/sip/include/sip.h (original)
+++ team/oej/pgtips-srv-and-outbound-stuff-1.8/channels/sip/include/sip.h Tue Aug 27 07:25:39 2013
@@ -1149,6 +1149,7 @@
 	struct ast_cc_config_params *cc_params;
 	struct sip_epa_entry *epa_entry;
 	int fromdomainport;                 /*!< Domain port to show in from field */
+	struct srv_context *srvcon;		/*!< SRV record list */
 };
 
 /*! \brief sip packet - raw format for outbound packets that are sent or scheduled for transmission

Modified: team/oej/pgtips-srv-and-outbound-stuff-1.8/main/srv.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pgtips-srv-and-outbound-stuff-1.8/main/srv.c?view=diff&rev=397702&r1=397701&r2=397702
==============================================================================
--- team/oej/pgtips-srv-and-outbound-stuff-1.8/main/srv.c (original)
+++ team/oej/pgtips-srv-and-outbound-stuff-1.8/main/srv.c Tue Aug 27 07:25:39 2013
@@ -439,11 +439,11 @@
 	int res = -1;
 	struct srv_entry *entry;
 
+	if (context == NULL) {
+		return res;
+	}
+
 	if (record_num < 1 || record_num > context->num_records) {
-		return res;
-	}
-
-	if (context == NULL) {
 		return res;
 	}
 




More information about the asterisk-commits mailing list