summaryrefslogtreecommitdiff
path: root/channels
diff options
context:
space:
mode:
authorMatthew Jordan <mjordan@digium.com>2014-10-30 01:47:25 +0000
committerMatthew Jordan <mjordan@digium.com>2014-10-30 01:47:25 +0000
commitab07cf71f8b7317c4d1309c00c0890ba14f87da5 (patch)
treed436815a12dee01a4ef54a320a044c88d06354d2 /channels
parentb1acfd36fdebe734a2d7e5de2a5a62566f712ce1 (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.c48
-rw-r--r--channels/sip/reqresp_parser.c4
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;