From 3376c8e97670fdace8bf65afeddc90411f29cf5a Mon Sep 17 00:00:00 2001
From: Olle Johansson <oej@edvina.net>
Date: Tue, 17 Oct 2006 17:54:59 +0000
Subject: [PATCH] Issue #7254 - Add support of "423 Interval too brief" to
 outbound SIP registrations. 	Thanks, tardieu!

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@45335 65c4cc65-6c06-0410-ace0-fbb531ad65f3
---
 channels/chan_sip.c | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 783d1e776f..22d752c883 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -1108,6 +1108,7 @@ struct sip_registry {
 	);
 	int portno;			/*!<  Optional port override */
 	int expire;			/*!< Sched ID of expiration */
+	int expiry;			/*!< Value to use for the Expires header */
 	int regattempts;		/*!< Number of attempts (since the last success) */
 	int timeout; 			/*!< sched id of sip_reg_timeout */
 	int refresh;			/*!< How often to refresh */
@@ -4339,6 +4340,7 @@ static int sip_register(char *value, int lineno)
 	if (secret)
 		ast_string_field_set(reg, secret, secret);
 	reg->expire = -1;
+	reg->expiry = default_expiry;
 	reg->timeout =  -1;
 	reg->refresh = default_expiry;
 	reg->portno = portnum;
@@ -7083,7 +7085,7 @@ static int transmit_register(struct sip_registry *r, int sipmethod, const char *
 	
 	}
 
-	snprintf(tmp, sizeof(tmp), "%d", default_expiry);
+	snprintf(tmp, sizeof(tmp), "%d", r->expiry);
 	add_header(&req, "Expires", tmp);
 	add_header(&req, "Contact", p->our_contact);
 	add_header(&req, "Event", "registration");
@@ -11604,6 +11606,25 @@ static int handle_response_register(struct sip_pvt *p, int resp, char *rest, str
 			ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);	
 		}
 		break;
+	case 423:	/* Interval too brief */
+		r->expiry = atoi(get_header(req, "Min-Expires"));
+		ast_log(LOG_WARNING, "Got 423 Interval too brief for service %s@%s, minimum is %d seconds\n", p->registry->username, p->registry->hostname, r->expiry);
+		ast_sched_del(sched, r->timeout);
+		r->timeout = -1;
+		if (r->call) {
+			r->call = NULL;
+			ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);	
+		}
+		if (r->expiry > max_expiry) {
+			ast_log(LOG_WARNING, "Required expiration time from %s@%s is too high, giving up\n", p->registry->username, p->registry->hostname);
+			r->expiry = default_expiry;
+			r->regstate = REG_STATE_REJECTED;
+		} else {
+			r->regstate = REG_STATE_UNREGISTERED;
+			transmit_register(r, SIP_REGISTER, NULL, NULL);
+		}
+		manager_event(EVENT_FLAG_SYSTEM, "Registry", "Channel: SIP\r\nUsername: %s\r\nDomain: %s\r\nStatus: %s\r\n", r->username, r->hostname, regstate2str(r->regstate));
+		break;
 	case 479:	/* SER: Not able to process the URI - address is wrong in register*/
 		ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname);
 		if (global_regattempts_max)
@@ -11878,6 +11899,10 @@ static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_
 				ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);	
 
 			break;
+		case 423: /* Interval too brief */
+			if (sipmethod == SIP_REGISTER)
+				res = handle_response_register(p, resp, rest, req, seqno);
+			break;
 		case 481: /* Call leg does not exist */
 			if (sipmethod == SIP_INVITE) {
 				/* First we ACK */
-- 
GitLab