diff options
author | Matthew Jordan <mjordan@digium.com> | 2014-10-30 01:47:25 +0000 |
---|---|---|
committer | Matthew Jordan <mjordan@digium.com> | 2014-10-30 01:47:25 +0000 |
commit | ab07cf71f8b7317c4d1309c00c0890ba14f87da5 (patch) | |
tree | d436815a12dee01a4ef54a320a044c88d06354d2 /channels | |
parent | b1acfd36fdebe734a2d7e5de2a5a62566f712ce1 (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
git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/13@426597 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels')
-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 a0440cd67..a776f232f 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -25071,7 +25071,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]; @@ -25083,31 +25085,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; |