# HG changeset patch # User Samuel Tardieu # Date 1149150674 -7200 # Node ID 71da8d2818c655bc850291d865aa0f7baa5440eb # Parent 1f53c5431c87d1bb474819abd9c2203d3c91d9ed Honor "423 Interval too brief" errors at registration time. diff -r 1f53c5431c87 -r 71da8d2818c6 channels/chan_sip.c --- a/channels/chan_sip.c Thu Jun 01 08:59:27 2006 +0200 +++ b/channels/chan_sip.c Thu Jun 01 10:31:14 2006 +0200 @@ -994,6 +994,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 */ @@ -3817,6 +3818,7 @@ static int sip_register(char *value, int 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 = porta ? atoi(porta) : 0; @@ -6045,7 +6047,7 @@ static int transmit_register(struct sip_ } - 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"); @@ -10376,6 +10378,25 @@ static int handle_response_register(stru ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries); 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); @@ -10640,6 +10661,10 @@ static void handle_response(struct sip_p } else /* We can't handle this, giving up in a bad way */ 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, ignore, seqno); break; case 481: /* Call leg does not exist */ if (sipmethod == SIP_INVITE) {