Răsfoiți Sursa

lib/kcore: abstracted the option-tag parsing code out of parse_supported.[ch]

- This is to make it easier to add parsers for other similar headers
  (for example, Require:)
Peter Dunkley 12 ani în urmă
părinte
comite
af75f69a58
4 a modificat fișierele cu 213 adăugiri și 168 ștergeri
  1. 38 0
      lib/kcore/option-tags.c
  2. 164 0
      lib/kcore/option-tags.h
  3. 8 125
      lib/kcore/parse_supported.c
  4. 3 43
      lib/kcore/parse_supported.h

+ 38 - 0
lib/kcore/option-tags.c

@@ -0,0 +1,38 @@
+/*
+ * $Id$
+ *
+ * This file is part of Kamailio, a free SIP server.
+ *
+ * Kamailio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * Kamailio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include "../../mem/mem.h"
+#include "option-tags.h"
+
+static inline void free_option_tag(struct option_tag_body **otb)
+{
+	if (otb && *otb) {
+		pkg_free(*otb);
+		*otb = 0;
+	}
+}
+
+void hf_free_option_tag(void *parsed)
+{
+	struct option_tag_body *otb;
+	otb = (struct option_tag_body *) parsed;
+	free_option_tag(&otb);
+}

+ 164 - 0
lib/kcore/option-tags.h

@@ -0,0 +1,164 @@
+/*
+ * $Id$
+ *
+ * This file is part of Kamailio, a free SIP server.
+ *
+ * Kamailio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * Kamailio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef OPTION_TAGS_H
+#define OPTION_TAGS_H
+
+#include <strings.h>
+#include "../../parser/hf.h"
+#include "../../parser/keys.h"
+
+#define F_OPTION_TAG_PATH	(1 << 0)
+#define F_OPTION_TAG_100REL	(1 << 1)
+#define F_OPTION_TAG_TIMER	(1 << 2)
+#define F_OPTION_TAG_EVENTLIST	(1 << 3)
+#define F_OPTION_TAG_GRUU	(1 << 4)
+#define F_OPTION_TAG_OUTBOUND	(1 << 5)
+
+#define OPTION_TAG_PATH_STR		"path"
+#define OPTION_TAG_PATH_LEN		(sizeof(OPTION_TAG_PATH_STR)-1)
+
+/* RFC 3262 (PRACK) */
+#define OPTION_TAG_100REL_STR		"100rel"
+#define OPTION_TAG_100REL_LEN		(sizeof(OPTION_TAG_100REL_STR)-1)
+
+/* RFC 4028 */
+#define OPTION_TAG_TIMER_STR		"timer"
+#define OPTION_TAG_TIMER_LEN		(sizeof(OPTION_TAG_TIMER_STR)-1)
+
+/* RFC 4662 (RLS) */
+#define OPTION_TAG_EVENTLIST_STR	"eventlist"
+#define OPTION_TAG_EVENTLIST_LEN	(sizeof(OPTION_TAG_EVENTLIST_STR)-1)
+
+/* RFC 5627 */
+#define OPTION_TAG_GRUU_STR		"gruu"
+#define OPTION_TAG_GRUU_LEN		(sizeof(OPTION_TAG_GRUU_STR)-1)
+
+/* RFC 5626 */
+#define OPTION_TAG_OUTBOUND_STR		"outbound"
+#define OPTION_TAG_OUTBOUND_LEN		(sizeof(OPTION_TAG_OUTBOUND_STR)-1)
+
+
+struct option_tag_body {
+	hf_parsed_free_f hfree;        /* function to free the content */
+	unsigned int option_tags;      /* option-tag mask for the current hdr */
+	unsigned int option_tags_all;  /* option-tag mask for the all hdr
+	                                *  - it's set only for the first hdr in 
+	                                *  sibling list*/
+};
+
+
+#define IS_DELIM(c) (*(c) == ' ' || *(c) == '\t' || *(c) == '\r' || *(c) == '\n' || *(c) == ',')
+
+/* from parser/parse_hname2.c: */
+#define LOWER_BYTE(b) ((b) | 0x20)
+#define LOWER_DWORD(d) ((d) | 0x20202020)
+#define READ(val) \
+	(*(val + 0) + (*(val + 1) << 8) + (*(val + 2) << 16) + (*(val + 3) << 24))
+
+/*!
+ * Parse HF body containing option-tags.
+ */
+static inline int parse_option_tag_body(str *body, unsigned int *tags)
+{
+	register char* p;
+	register unsigned int val;
+	int len, pos = 0;
+
+	*tags = 0;
+
+	p = body->s;
+	len = body->len;
+
+	while (pos < len) {
+		/* skip spaces and commas */
+		for (; pos < len && IS_DELIM(p); ++pos, ++p);
+
+		val = LOWER_DWORD(READ(p));
+		switch (val) {
+
+			/* "path" */
+			case _path_:
+				if(pos + 4 <= len && IS_DELIM(p+4)) {
+					*tags |= F_OPTION_TAG_PATH;
+					pos += 5; p += 5;
+				}
+				break;
+
+			/* "100rel" */
+			case _100r_:
+				if ( pos+6 <= len
+					 && LOWER_BYTE(*(p+4))=='e' && LOWER_BYTE(*(p+5))=='l'
+					 && IS_DELIM(p+6)) {
+					*tags |= F_OPTION_TAG_100REL;
+					pos += OPTION_TAG_100REL_LEN + 1;
+					p   += OPTION_TAG_100REL_LEN + 1;
+				}
+				break;
+
+			/* "timer" */
+			case _time_:
+				if ( pos+5 <= len && LOWER_BYTE(*(p+4))=='r'
+					 && IS_DELIM(p+5) ) {
+					*tags |= F_OPTION_TAG_TIMER;
+					pos += OPTION_TAG_TIMER_LEN + 1;
+					p   += OPTION_TAG_TIMER_LEN + 1;
+				}
+				break;
+
+			/* extra require or unknown */
+			default:
+				if(pos+OPTION_TAG_EVENTLIST_LEN<=len
+						&& strncasecmp(p, OPTION_TAG_EVENTLIST_STR,
+							OPTION_TAG_EVENTLIST_LEN)==0
+						&& IS_DELIM(p+OPTION_TAG_EVENTLIST_LEN) ) {
+					*tags |= F_OPTION_TAG_EVENTLIST;
+					pos += OPTION_TAG_EVENTLIST_LEN + 1;
+					p   += OPTION_TAG_EVENTLIST_LEN + 1;
+				} else if(pos+OPTION_TAG_GRUU_LEN<=len
+						&& strncasecmp(p, OPTION_TAG_GRUU_STR,
+							OPTION_TAG_GRUU_LEN)==0
+						&& IS_DELIM(p+OPTION_TAG_GRUU_LEN)) {
+					*tags |= F_OPTION_TAG_GRUU;
+					pos += OPTION_TAG_GRUU_LEN + 1;
+					p   += OPTION_TAG_GRUU_LEN + 1;
+				} else if(pos+OPTION_TAG_OUTBOUND_LEN<=len
+						&& strncasecmp(p, OPTION_TAG_OUTBOUND_STR,
+							OPTION_TAG_OUTBOUND_LEN)==0
+						&& IS_DELIM(p+OPTION_TAG_OUTBOUND_LEN)) {
+					*tags |= F_OPTION_TAG_OUTBOUND;
+					pos += OPTION_TAG_OUTBOUND_LEN + 1;
+					p   += OPTION_TAG_OUTBOUND_LEN + 1;
+				} else {
+					/* skip element */
+					for (; pos < len && !IS_DELIM(p); ++pos, ++p);
+				}
+				break;
+		}
+	}
+	
+	return 0;
+}
+
+
+void hf_free_option_tag(void *parsed);
+
+#endif /* OPTION_TAGS_H */

+ 8 - 125
lib/kcore/parse_supported.c

@@ -27,116 +27,8 @@
  */
 
 #include "../../mem/mem.h"
-#include "../../parser/keys.h"
 #include "parse_supported.h"
 
-#define _100r_ 0x72303031   /* "100r" for "100rel" */
-#define _time_ 0x656d6974   /*!< "time" */
-
-#define IS_DELIM(c) (*(c) == ' ' || *(c) == '\t' || *(c) == '\r' || *(c) == '\n' || *(c) == ',')
-
-/* from parser/parse_hname2.c: */
-#define LOWER_BYTE(b) ((b) | 0x20)
-#define LOWER_DWORD(d) ((d) | 0x20202020)
-#define READ(val) \
-	(*(val + 0) + (*(val + 1) << 8) + (*(val + 2) << 16) + (*(val + 3) << 24))
-
-
-/*!
- * Parse Supported HF body.
- */
-static inline int parse_supported_body(str *body, unsigned int *sup)
-{
-	register char* p;
-	register unsigned int val;
-	int len, pos = 0;
-
-	*sup = 0;
-
-	p = body->s;
-	len = body->len;
-
-	while (pos < len) {
-		/* skip spaces and commas */
-		for (; pos < len && IS_DELIM(p); ++pos, ++p);
-
-		val = LOWER_DWORD(READ(p));
-		switch (val) {
-
-			/* "path" */
-			case _path_:
-				if(pos + 4 <= len && IS_DELIM(p+4)) {
-					*sup |= F_SUPPORTED_PATH;
-					pos += 5; p += 5;
-				}
-				break;
-
-			/* "100rel" */
-			case _100r_:
-				if ( pos+6 <= len
-					 && LOWER_BYTE(*(p+4))=='e' && LOWER_BYTE(*(p+5))=='l'
-					 && IS_DELIM(p+6)) {
-					*sup |= F_SUPPORTED_100REL;
-					pos += SUPPORTED_100REL_LEN + 1;
-					p   += SUPPORTED_100REL_LEN + 1;
-				}
-				break;
-
-			/* "timer" */
-			case _time_:
-				if ( pos+5 <= len && LOWER_BYTE(*(p+4))=='r'
-					 && IS_DELIM(p+5) ) {
-					*sup |= F_SUPPORTED_TIMER;
-					pos += SUPPORTED_TIMER_LEN + 1;
-					p   += SUPPORTED_TIMER_LEN + 1;
-				}
-				break;
-
-			/* extra supported or unknown */
-			default:
-				if(pos+SUPPORTED_EVENTLIST_LEN<=len
-						&& strncasecmp(p, SUPPORTED_EVENTLIST_STR,
-							SUPPORTED_EVENTLIST_LEN)==0
-						&& IS_DELIM(p+SUPPORTED_EVENTLIST_LEN) ) {
-					*sup |= F_SUPPORTED_EVENTLIST;
-					pos += SUPPORTED_EVENTLIST_LEN + 1;
-					p   += SUPPORTED_EVENTLIST_LEN + 1;
-				} else if(pos+SUPPORTED_GRUU_LEN<=len
-						&& strncasecmp(p, SUPPORTED_GRUU_STR,
-							SUPPORTED_GRUU_LEN)==0
-						&& IS_DELIM(p+SUPPORTED_GRUU_LEN)) {
-					*sup |= F_SUPPORTED_GRUU;
-					pos += SUPPORTED_GRUU_LEN + 1;
-					p   += SUPPORTED_GRUU_LEN + 1;
-				} else if(pos+SUPPORTED_OUTBOUND_LEN<=len
-						&& strncasecmp(p, SUPPORTED_OUTBOUND_STR,
-							SUPPORTED_OUTBOUND_LEN)==0
-						&& IS_DELIM(p+SUPPORTED_OUTBOUND_LEN)) {
-					*sup |= F_SUPPORTED_OUTBOUND;
-					pos += SUPPORTED_OUTBOUND_LEN + 1;
-					p   += SUPPORTED_OUTBOUND_LEN + 1;
-				} else {
-					/* skip element */
-					for (; pos < len && !IS_DELIM(p); ++pos, ++p);
-				}
-				break;
-		}
-	}
-	
-	return 0;
-}
-
-
-/**
- * wrapper to free the content of parsed supported header
- */
-void hf_free_supported(void *parsed)
-{
-	struct supported_body *sb;
-	sb = (struct supported_body*)parsed;
-	free_supported(&sb);
-}
-
 /*!
  * Parse all Supported headers
  */
@@ -144,7 +36,7 @@ int parse_supported( struct sip_msg *msg)
 {
 	unsigned int supported;
 	struct hdr_field  *hdr;
-	struct supported_body *sb;
+	struct option_tag_body *sb;
 
 	/* maybe the header is already parsed! */
 	if (msg->supported && msg->supported->parsed)
@@ -158,33 +50,24 @@ int parse_supported( struct sip_msg *msg)
 	supported = 0;
 	for( hdr=msg->supported ; hdr ; hdr=next_sibling_hdr(hdr)) {
 		if (hdr->parsed) {
-			supported |= ((struct supported_body*)hdr->parsed)->supported;
+			supported |= ((struct option_tag_body*)hdr->parsed)->option_tags;
 			continue;
 		}
 
-		sb = (struct supported_body*)pkg_malloc(sizeof(struct supported_body));
+		sb = (struct option_tag_body*)pkg_malloc(sizeof(struct option_tag_body));
 		if (sb == 0) {
 			LM_ERR("out of pkg_memory\n");
 			return -1;
 		}
 
-		parse_supported_body(&(hdr->body), &(sb->supported));
-		sb->hfree = hf_free_supported;
-		sb->supported_all = 0;
+		parse_option_tag_body(&(hdr->body), &(sb->option_tags));
+		sb->hfree = hf_free_option_tag;
+		sb->option_tags_all = 0;
 		hdr->parsed = (void*)sb;
-		supported |= sb->supported;
+		supported |= sb->option_tags;
 	}
 
-	((struct supported_body*)msg->supported->parsed)->supported_all = 
+	((struct option_tag_body*)msg->supported->parsed)->option_tags_all = 
 		supported;
 	return 0;
 }
-
-/* free supported header structure */
-void free_supported(struct supported_body **sb)
-{
-	if (sb && *sb) {
-		pkg_free(*sb);
-		*sb = 0;
-	}
-}

+ 3 - 43
lib/kcore/parse_supported.h

@@ -36,51 +36,11 @@
 #define PARSE_SUPPORTED_H
 
 #include "../../parser/msg_parser.h"
-#include "../../parser/hf.h"
 #include "../../mem/mem.h"
-
-
-#define F_SUPPORTED_PATH		(1 << 0)
-#define F_SUPPORTED_100REL		(1 << 1)
-#define F_SUPPORTED_TIMER		(1 << 2)
-#define F_SUPPORTED_EVENTLIST   (1 << 3)
-#define F_SUPPORTED_GRUU        (1 << 4)
-#define F_SUPPORTED_OUTBOUND    (1 << 5)
-
-#define SUPPORTED_PATH_STR		"path"
-#define SUPPORTED_PATH_LEN		(sizeof(SUPPORTED_PATH_STR)-1)
-
-/* RFC 3262 (PRACK) */
-#define SUPPORTED_100REL_STR	"100rel"
-#define SUPPORTED_100REL_LEN	(sizeof(SUPPORTED_100REL_STR)-1)
-
-/* RFC 4028 */
-#define SUPPORTED_TIMER_STR		"timer"
-#define SUPPORTED_TIMER_LEN		(sizeof(SUPPORTED_TIMER_STR)-1)
-
-/* RFC 4662 (RLS) */
-#define SUPPORTED_EVENTLIST_STR  "eventlist"
-#define SUPPORTED_EVENTLIST_LEN  (sizeof(SUPPORTED_EVENTLIST_STR)-1)
-
-/* RFC 5627 */
-#define SUPPORTED_GRUU_STR		"gruu"
-#define SUPPORTED_GRUU_LEN		(sizeof(SUPPORTED_GRUU_STR)-1)
-
-/* RFC 5626 */
-#define SUPPORTED_OUTBOUND_STR	"outbound"
-#define SUPPORTED_OUTBOUND_LEN	(sizeof(SUPPORTED_OUTBOUND_STR)-1)
+#include "option-tags.h"
 
 #define get_supported(p_msg) \
-	((p_msg)->supported ? ((struct supported_body*)(p_msg)->supported->parsed)->supported_all : 0)
-
-
-struct supported_body {
-	hf_parsed_free_f hfree;        /* function to free the content */
-	unsigned int supported;        /* supported mask for the current hdr */
-	unsigned int supported_all;    /* suppoted mask for the all "supported" hdr
-	                                *  - it's set only for the first hdr in 
-	                                *  sibling list*/
-};
+	((p_msg)->supported ? ((struct option_tag_body*)(p_msg)->supported->parsed)->option_tags_all : 0)
 
 
 /*!
@@ -89,6 +49,6 @@ struct supported_body {
 int parse_supported( struct sip_msg *msg);
 
 
-void free_supported(struct supported_body **sb);
+void free_supported(struct option_tag_body **sb);
 
 #endif /* PARSE_SUPPORTED_H */