# HG changeset patch # User Mychaela Falconia # Date 1662533836 28800 # Node ID dec31b1a8b965ec4c54feb35b4b2f6e3866238cc # Parent 8117d8ee44a5261372b82b7ac476fdd57e02d51f sip-in: check Require and Supported diff -r 8117d8ee44a5 -r dec31b1a8b96 libsip/Makefile --- a/libsip/Makefile Tue Sep 06 22:07:51 2022 -0800 +++ b/libsip/Makefile Tue Sep 06 22:57:16 2022 -0800 @@ -1,6 +1,7 @@ CC= gcc CFLAGS= -O2 -OBJS= get_header.o out_msg.o primary_parse.o uas_basic.o uri_utils.o +OBJS= get_header.o out_msg.o primary_parse.o req_supp.o uas_basic.o \ + uri_utils.o LIB= libsip.a all: ${LIB} diff -r 8117d8ee44a5 -r dec31b1a8b96 libsip/req_supp.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libsip/req_supp.c Tue Sep 06 22:57:16 2022 -0800 @@ -0,0 +1,77 @@ +/* + * Here we parse Require and Supported headers in a SIP request, + * checking whether our supported extensions are also supported + * or required by the client, and catching any client requirements + * which we don't support. + */ + +#include +#include +#include +#include "parse.h" +#include "req_supp.h" + +parse_require_supported(msg, lsupp, nlsupp, unsupp) + struct sip_pkt_rx *msg; + struct supported_ext *lsupp; + unsigned nlsupp; + char **unsupp; +{ + struct sip_parse_hdr *hdr, *endhdr; + char *cp, *np; + unsigned n; + + endhdr = msg->hdr_fields + msg->num_hdr_fields; + /* check Require first */ + for (hdr = msg->hdr_fields; hdr < endhdr; hdr++) { + if (strcasecmp(hdr->field_name, "Require")) + continue; + cp = hdr->field_value; + for (;;) { + while (isspace(*cp) || *cp == ',') + cp++; + if (!*cp) + break; + np = cp; + while (*cp && !isspace(*cp) && *cp != ',') + cp++; + if (*cp) + *cp++ = '\0'; + for (n = 0; n < nlsupp; n++) { + if (!strcasecmp(np, lsupp[n].name)) { + *lsupp[n].req_flag = 1; + break; + } else { + if (unsupp) + *unsupp = np; + return(-1); + } + } + } + } + /* now check Supported */ + for (hdr = msg->hdr_fields; hdr < endhdr; hdr++) { + if (strcasecmp(hdr->field_name, "Supported") && + strcasecmp(hdr->field_name, "k")) + continue; + cp = hdr->field_value; + for (;;) { + while (isspace(*cp) || *cp == ',') + cp++; + if (!*cp) + break; + np = cp; + while (*cp && !isspace(*cp) && *cp != ',') + cp++; + if (*cp) + *cp++ = '\0'; + for (n = 0; n < nlsupp; n++) { + if (!strcasecmp(np, lsupp[n].name)) { + *lsupp[n].sup_flag = 1; + break; + } + } + } + } + return(0); +} diff -r 8117d8ee44a5 -r dec31b1a8b96 libsip/req_supp.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libsip/req_supp.h Tue Sep 06 22:57:16 2022 -0800 @@ -0,0 +1,9 @@ +/* + * Data structure for parsing Require and Supported header fields + */ + +struct supported_ext { + char *name; + int *req_flag; + int *sup_flag; +}; diff -r 8117d8ee44a5 -r dec31b1a8b96 sip-in/invite.c --- a/sip-in/invite.c Tue Sep 06 22:07:51 2022 -0800 +++ b/sip-in/invite.c Tue Sep 06 22:57:16 2022 -0800 @@ -13,8 +13,11 @@ #include #include "../libsip/parse.h" #include "../libsip/uas_basic.h" +#include "../libsip/req_supp.h" #include "../libsip/out_msg.h" +extern int cfg_use_100rel; + void handle_sip_invite(req, ess, sin) struct sip_pkt_rx *req; @@ -23,6 +26,9 @@ { char uri_user[13], *called_nanp; struct sip_msg_out resp; + struct supported_ext supp_ext; + char *unsup_ext; + int ext_100rel_req, ext_100rel_sup, use_100rel; int rc; /* check for existing Call-ID will go here */ @@ -33,7 +39,7 @@ "416 Request-URI is not a NANP number"); error_resp: rc = add_resp_basic_headers(&resp, ess, req->req_method); if (rc < 0) { - syslog(LOG_ERR, +error_resp_toolong: syslog(LOG_ERR, "INVITE error response length exceeded"); return; } @@ -67,9 +73,27 @@ "404 Called number does not belong here"); goto error_resp; } + /* check 100rel and catch any unsupported requirements */ + supp_ext.name = "100rel"; + supp_ext.req_flag = &ext_100rel_req; + supp_ext.sup_flag = &ext_100rel_sup; + ext_100rel_req = ext_100rel_sup = 0; + rc = parse_require_supported(req, &supp_ext, 1, &unsup_ext); + if (rc < 0) { + start_response_out_msg(&resp, "420 Extension not supported"); + rc = out_msg_add_header(&resp, "Unsupported", unsup_ext); + if (rc < 0) + goto error_resp_toolong; + goto error_resp; + } + if (ext_100rel_req) + use_100rel = 1; + else if (ext_100rel_sup) + use_100rel = cfg_use_100rel; + else + use_100rel = 0; /* * Remaining checks to be implemented: - * Require and Supported headers * SDP message body */ }