diff options
author | Matthew Jordan <mjordan@digium.com> | 2014-10-30 01:48:00 +0000 |
---|---|---|
committer | Matthew Jordan <mjordan@digium.com> | 2014-10-30 01:48:00 +0000 |
commit | ff83ff564c1f54fb7ed82a8efc41107acd882071 (patch) | |
tree | 1f8577a746a88095f19dcc1abf4739d0090a62da | |
parent | 8a69aedd17b7b0c3e9e5b0b88483b6a2536cabc1 (diff) |
channels/chan_sip: Support mutltiple Supported and Required headers
A SIP request may contain multiple Supported: and Required: headers. Currently,
chan_sip only parses the first Supported/Required header it finds. This patch
adds support for multiple Supported/Required headers for INVITE requests.
Review: https://reviewboard.asterisk.org/r/2478
ASTERISK-21721 #close
Reported by: Olle Johansson
patches:
rb2478.patch uploaded by oej (License 5267)
........
Merged revisions 426594 from http://svn.asterisk.org/svn/asterisk/branches/1.8
........
Merged revisions 426595 from http://svn.asterisk.org/svn/asterisk/branches/11
........
Merged revisions 426596 from http://svn.asterisk.org/svn/asterisk/branches/12
........
Merged revisions 426597 from http://svn.asterisk.org/svn/asterisk/branches/13
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@426598 65c4cc65-6c06-0410-ace0-fbb531ad65f3
-rw-r--r-- | channels/chan_sip.c | 48 | ||||
-rw-r--r-- | channels/sip/reqresp_parser.c | 4 |
2 files changed, 28 insertions, 24 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 8d44b34ec..43cb2e9af 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -25081,7 +25081,9 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, str int reinvite = 0; struct ast_party_redirecting redirecting; struct ast_set_party_redirecting update_redirecting; - + int supported_start = 0; + int require_start = 0; + char unsupported[256] = { 0, }; struct { char exten[AST_MAX_EXTENSION]; char context[AST_MAX_CONTEXT]; @@ -25093,31 +25095,37 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, str /* Find out what they support */ if (!p->sipoptions) { - const char *supported = sip_get_header(req, "Supported"); - if (!ast_strlen_zero(supported)) { - p->sipoptions = parse_sip_options(supported, NULL, 0); - } + const char *supported = NULL; + do { + supported = __get_header(req, "Supported", &supported_start); + if (!ast_strlen_zero(supported)) { + p->sipoptions |= parse_sip_options(supported, NULL, 0); + } + } while (!ast_strlen_zero(supported)); } /* Find out what they require */ - required = sip_get_header(req, "Require"); - if (!ast_strlen_zero(required)) { - char unsupported[256] = { 0, }; - required_profile = parse_sip_options(required, unsupported, ARRAY_LEN(unsupported)); - - /* If there are any options required that we do not support, - * then send a 420 with only those unsupported options listed */ - if (!ast_strlen_zero(unsupported)) { - transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, unsupported); - ast_log(LOG_WARNING, "Received SIP INVITE with unsupported required extension: required:%s unsupported:%s\n", required, unsupported); - p->invitestate = INV_COMPLETED; - if (!p->lastinvite) - sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); - res = INV_REQ_ERROR; - goto request_invite_cleanup; + do { + required = __get_header(req, "Require", &require_start); + if (!ast_strlen_zero(required)) { + required_profile |= parse_sip_options(required, unsupported, ARRAY_LEN(unsupported)); + } + } while (!ast_strlen_zero(required)); + + /* If there are any options required that we do not support, + * then send a 420 with only those unsupported options listed */ + if (!ast_strlen_zero(unsupported)) { + transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, unsupported); + ast_log(LOG_WARNING, "Received SIP INVITE with unsupported required extension: required:%s unsupported:%s\n", required, unsupported); + p->invitestate = INV_COMPLETED; + if (!p->lastinvite) { + sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); } + res = -1; + goto request_invite_cleanup; } + /* The option tags may be present in Supported: or Require: headers. Include the Require: option tags for further processing as well */ p->sipoptions |= required_profile; diff --git a/channels/sip/reqresp_parser.c b/channels/sip/reqresp_parser.c index f914595f3..aa568a0e9 100644 --- a/channels/sip/reqresp_parser.c +++ b/channels/sip/reqresp_parser.c @@ -1692,10 +1692,6 @@ unsigned int parse_sip_options(const char *options, char *unsupported, size_t un size_t outlen = unsupported_len; char *cur_out = out; - if (out && (outlen > 0)) { - memset(out, 0, outlen); - } - if (ast_strlen_zero(options) ) return 0; |