Browse code

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 authored on 27/02/2013 13:59:56
Showing 4 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,38 @@
0
+/*
1
+ * $Id$
2
+ *
3
+ * This file is part of Kamailio, a free SIP server.
4
+ *
5
+ * Kamailio is free software; you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation; either version 2 of the License, or
8
+ * (at your option) any later version
9
+ *
10
+ * Kamailio is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with this program; if not, write to the Free Software
17
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
+ *
19
+ */
20
+
21
+#include "../../mem/mem.h"
22
+#include "option-tags.h"
23
+
24
+static inline void free_option_tag(struct option_tag_body **otb)
25
+{
26
+	if (otb && *otb) {
27
+		pkg_free(*otb);
28
+		*otb = 0;
29
+	}
30
+}
31
+
32
+void hf_free_option_tag(void *parsed)
33
+{
34
+	struct option_tag_body *otb;
35
+	otb = (struct option_tag_body *) parsed;
36
+	free_option_tag(&otb);
37
+}
0 38
new file mode 100644
... ...
@@ -0,0 +1,164 @@
0
+/*
1
+ * $Id$
2
+ *
3
+ * This file is part of Kamailio, a free SIP server.
4
+ *
5
+ * Kamailio is free software; you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation; either version 2 of the License, or
8
+ * (at your option) any later version
9
+ *
10
+ * Kamailio is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with this program; if not, write to the Free Software
17
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
+ *
19
+ */
20
+
21
+#ifndef OPTION_TAGS_H
22
+#define OPTION_TAGS_H
23
+
24
+#include <strings.h>
25
+#include "../../parser/hf.h"
26
+#include "../../parser/keys.h"
27
+
28
+#define F_OPTION_TAG_PATH	(1 << 0)
29
+#define F_OPTION_TAG_100REL	(1 << 1)
30
+#define F_OPTION_TAG_TIMER	(1 << 2)
31
+#define F_OPTION_TAG_EVENTLIST	(1 << 3)
32
+#define F_OPTION_TAG_GRUU	(1 << 4)
33
+#define F_OPTION_TAG_OUTBOUND	(1 << 5)
34
+
35
+#define OPTION_TAG_PATH_STR		"path"
36
+#define OPTION_TAG_PATH_LEN		(sizeof(OPTION_TAG_PATH_STR)-1)
37
+
38
+/* RFC 3262 (PRACK) */
39
+#define OPTION_TAG_100REL_STR		"100rel"
40
+#define OPTION_TAG_100REL_LEN		(sizeof(OPTION_TAG_100REL_STR)-1)
41
+
42
+/* RFC 4028 */
43
+#define OPTION_TAG_TIMER_STR		"timer"
44
+#define OPTION_TAG_TIMER_LEN		(sizeof(OPTION_TAG_TIMER_STR)-1)
45
+
46
+/* RFC 4662 (RLS) */
47
+#define OPTION_TAG_EVENTLIST_STR	"eventlist"
48
+#define OPTION_TAG_EVENTLIST_LEN	(sizeof(OPTION_TAG_EVENTLIST_STR)-1)
49
+
50
+/* RFC 5627 */
51
+#define OPTION_TAG_GRUU_STR		"gruu"
52
+#define OPTION_TAG_GRUU_LEN		(sizeof(OPTION_TAG_GRUU_STR)-1)
53
+
54
+/* RFC 5626 */
55
+#define OPTION_TAG_OUTBOUND_STR		"outbound"
56
+#define OPTION_TAG_OUTBOUND_LEN		(sizeof(OPTION_TAG_OUTBOUND_STR)-1)
57
+
58
+
59
+struct option_tag_body {
60
+	hf_parsed_free_f hfree;        /* function to free the content */
61
+	unsigned int option_tags;      /* option-tag mask for the current hdr */
62
+	unsigned int option_tags_all;  /* option-tag mask for the all hdr
63
+	                                *  - it's set only for the first hdr in 
64
+	                                *  sibling list*/
65
+};
66
+
67
+
68
+#define IS_DELIM(c) (*(c) == ' ' || *(c) == '\t' || *(c) == '\r' || *(c) == '\n' || *(c) == ',')
69
+
70
+/* from parser/parse_hname2.c: */
71
+#define LOWER_BYTE(b) ((b) | 0x20)
72
+#define LOWER_DWORD(d) ((d) | 0x20202020)
73
+#define READ(val) \
74
+	(*(val + 0) + (*(val + 1) << 8) + (*(val + 2) << 16) + (*(val + 3) << 24))
75
+
76
+/*!
77
+ * Parse HF body containing option-tags.
78
+ */
79
+static inline int parse_option_tag_body(str *body, unsigned int *tags)
80
+{
81
+	register char* p;
82
+	register unsigned int val;
83
+	int len, pos = 0;
84
+
85
+	*tags = 0;
86
+
87
+	p = body->s;
88
+	len = body->len;
89
+
90
+	while (pos < len) {
91
+		/* skip spaces and commas */
92
+		for (; pos < len && IS_DELIM(p); ++pos, ++p);
93
+
94
+		val = LOWER_DWORD(READ(p));
95
+		switch (val) {
96
+
97
+			/* "path" */
98
+			case _path_:
99
+				if(pos + 4 <= len && IS_DELIM(p+4)) {
100
+					*tags |= F_OPTION_TAG_PATH;
101
+					pos += 5; p += 5;
102
+				}
103
+				break;
104
+
105
+			/* "100rel" */
106
+			case _100r_:
107
+				if ( pos+6 <= len
108
+					 && LOWER_BYTE(*(p+4))=='e' && LOWER_BYTE(*(p+5))=='l'
109
+					 && IS_DELIM(p+6)) {
110
+					*tags |= F_OPTION_TAG_100REL;
111
+					pos += OPTION_TAG_100REL_LEN + 1;
112
+					p   += OPTION_TAG_100REL_LEN + 1;
113
+				}
114
+				break;
115
+
116
+			/* "timer" */
117
+			case _time_:
118
+				if ( pos+5 <= len && LOWER_BYTE(*(p+4))=='r'
119
+					 && IS_DELIM(p+5) ) {
120
+					*tags |= F_OPTION_TAG_TIMER;
121
+					pos += OPTION_TAG_TIMER_LEN + 1;
122
+					p   += OPTION_TAG_TIMER_LEN + 1;
123
+				}
124
+				break;
125
+
126
+			/* extra require or unknown */
127
+			default:
128
+				if(pos+OPTION_TAG_EVENTLIST_LEN<=len
129
+						&& strncasecmp(p, OPTION_TAG_EVENTLIST_STR,
130
+							OPTION_TAG_EVENTLIST_LEN)==0
131
+						&& IS_DELIM(p+OPTION_TAG_EVENTLIST_LEN) ) {
132
+					*tags |= F_OPTION_TAG_EVENTLIST;
133
+					pos += OPTION_TAG_EVENTLIST_LEN + 1;
134
+					p   += OPTION_TAG_EVENTLIST_LEN + 1;
135
+				} else if(pos+OPTION_TAG_GRUU_LEN<=len
136
+						&& strncasecmp(p, OPTION_TAG_GRUU_STR,
137
+							OPTION_TAG_GRUU_LEN)==0
138
+						&& IS_DELIM(p+OPTION_TAG_GRUU_LEN)) {
139
+					*tags |= F_OPTION_TAG_GRUU;
140
+					pos += OPTION_TAG_GRUU_LEN + 1;
141
+					p   += OPTION_TAG_GRUU_LEN + 1;
142
+				} else if(pos+OPTION_TAG_OUTBOUND_LEN<=len
143
+						&& strncasecmp(p, OPTION_TAG_OUTBOUND_STR,
144
+							OPTION_TAG_OUTBOUND_LEN)==0
145
+						&& IS_DELIM(p+OPTION_TAG_OUTBOUND_LEN)) {
146
+					*tags |= F_OPTION_TAG_OUTBOUND;
147
+					pos += OPTION_TAG_OUTBOUND_LEN + 1;
148
+					p   += OPTION_TAG_OUTBOUND_LEN + 1;
149
+				} else {
150
+					/* skip element */
151
+					for (; pos < len && !IS_DELIM(p); ++pos, ++p);
152
+				}
153
+				break;
154
+		}
155
+	}
156
+	
157
+	return 0;
158
+}
159
+
160
+
161
+void hf_free_option_tag(void *parsed);
162
+
163
+#endif /* OPTION_TAGS_H */
... ...
@@ -27,116 +27,8 @@
27 27
  */
28 28
 
29 29
 #include "../../mem/mem.h"
30
-#include "../../parser/keys.h"
31 30
 #include "parse_supported.h"
32 31
 
33
-#define _100r_ 0x72303031   /* "100r" for "100rel" */
34
-#define _time_ 0x656d6974   /*!< "time" */
35
-
36
-#define IS_DELIM(c) (*(c) == ' ' || *(c) == '\t' || *(c) == '\r' || *(c) == '\n' || *(c) == ',')
37
-
38
-/* from parser/parse_hname2.c: */
39
-#define LOWER_BYTE(b) ((b) | 0x20)
40
-#define LOWER_DWORD(d) ((d) | 0x20202020)
41
-#define READ(val) \
42
-	(*(val + 0) + (*(val + 1) << 8) + (*(val + 2) << 16) + (*(val + 3) << 24))
43
-
44
-
45
-/*!
46
- * Parse Supported HF body.
47
- */
48
-static inline int parse_supported_body(str *body, unsigned int *sup)
49
-{
50
-	register char* p;
51
-	register unsigned int val;
52
-	int len, pos = 0;
53
-
54
-	*sup = 0;
55
-
56
-	p = body->s;
57
-	len = body->len;
58
-
59
-	while (pos < len) {
60
-		/* skip spaces and commas */
61
-		for (; pos < len && IS_DELIM(p); ++pos, ++p);
62
-
63
-		val = LOWER_DWORD(READ(p));
64
-		switch (val) {
65
-
66
-			/* "path" */
67
-			case _path_:
68
-				if(pos + 4 <= len && IS_DELIM(p+4)) {
69
-					*sup |= F_SUPPORTED_PATH;
70
-					pos += 5; p += 5;
71
-				}
72
-				break;
73
-
74
-			/* "100rel" */
75
-			case _100r_:
76
-				if ( pos+6 <= len
77
-					 && LOWER_BYTE(*(p+4))=='e' && LOWER_BYTE(*(p+5))=='l'
78
-					 && IS_DELIM(p+6)) {
79
-					*sup |= F_SUPPORTED_100REL;
80
-					pos += SUPPORTED_100REL_LEN + 1;
81
-					p   += SUPPORTED_100REL_LEN + 1;
82
-				}
83
-				break;
84
-
85
-			/* "timer" */
86
-			case _time_:
87
-				if ( pos+5 <= len && LOWER_BYTE(*(p+4))=='r'
88
-					 && IS_DELIM(p+5) ) {
89
-					*sup |= F_SUPPORTED_TIMER;
90
-					pos += SUPPORTED_TIMER_LEN + 1;
91
-					p   += SUPPORTED_TIMER_LEN + 1;
92
-				}
93
-				break;
94
-
95
-			/* extra supported or unknown */
96
-			default:
97
-				if(pos+SUPPORTED_EVENTLIST_LEN<=len
98
-						&& strncasecmp(p, SUPPORTED_EVENTLIST_STR,
99
-							SUPPORTED_EVENTLIST_LEN)==0
100
-						&& IS_DELIM(p+SUPPORTED_EVENTLIST_LEN) ) {
101
-					*sup |= F_SUPPORTED_EVENTLIST;
102
-					pos += SUPPORTED_EVENTLIST_LEN + 1;
103
-					p   += SUPPORTED_EVENTLIST_LEN + 1;
104
-				} else if(pos+SUPPORTED_GRUU_LEN<=len
105
-						&& strncasecmp(p, SUPPORTED_GRUU_STR,
106
-							SUPPORTED_GRUU_LEN)==0
107
-						&& IS_DELIM(p+SUPPORTED_GRUU_LEN)) {
108
-					*sup |= F_SUPPORTED_GRUU;
109
-					pos += SUPPORTED_GRUU_LEN + 1;
110
-					p   += SUPPORTED_GRUU_LEN + 1;
111
-				} else if(pos+SUPPORTED_OUTBOUND_LEN<=len
112
-						&& strncasecmp(p, SUPPORTED_OUTBOUND_STR,
113
-							SUPPORTED_OUTBOUND_LEN)==0
114
-						&& IS_DELIM(p+SUPPORTED_OUTBOUND_LEN)) {
115
-					*sup |= F_SUPPORTED_OUTBOUND;
116
-					pos += SUPPORTED_OUTBOUND_LEN + 1;
117
-					p   += SUPPORTED_OUTBOUND_LEN + 1;
118
-				} else {
119
-					/* skip element */
120
-					for (; pos < len && !IS_DELIM(p); ++pos, ++p);
121
-				}
122
-				break;
123
-		}
124
-	}
125
-	
126
-	return 0;
127
-}
128
-
129
-
130
-/**
131
- * wrapper to free the content of parsed supported header
132
- */
133
-void hf_free_supported(void *parsed)
134
-{
135
-	struct supported_body *sb;
136
-	sb = (struct supported_body*)parsed;
137
-	free_supported(&sb);
138
-}
139
-
140 32
 /*!
141 33
  * Parse all Supported headers
142 34
  */
... ...
@@ -144,7 +36,7 @@ int parse_supported( struct sip_msg *msg)
144 144
 {
145 145
 	unsigned int supported;
146 146
 	struct hdr_field  *hdr;
147
-	struct supported_body *sb;
147
+	struct option_tag_body *sb;
148 148
 
149 149
 	/* maybe the header is already parsed! */
150 150
 	if (msg->supported && msg->supported->parsed)
... ...
@@ -158,33 +50,24 @@ int parse_supported( struct sip_msg *msg)
158 158
 	supported = 0;
159 159
 	for( hdr=msg->supported ; hdr ; hdr=next_sibling_hdr(hdr)) {
160 160
 		if (hdr->parsed) {
161
-			supported |= ((struct supported_body*)hdr->parsed)->supported;
161
+			supported |= ((struct option_tag_body*)hdr->parsed)->option_tags;
162 162
 			continue;
163 163
 		}
164 164
 
165
-		sb = (struct supported_body*)pkg_malloc(sizeof(struct supported_body));
165
+		sb = (struct option_tag_body*)pkg_malloc(sizeof(struct option_tag_body));
166 166
 		if (sb == 0) {
167 167
 			LM_ERR("out of pkg_memory\n");
168 168
 			return -1;
169 169
 		}
170 170
 
171
-		parse_supported_body(&(hdr->body), &(sb->supported));
172
-		sb->hfree = hf_free_supported;
173
-		sb->supported_all = 0;
171
+		parse_option_tag_body(&(hdr->body), &(sb->option_tags));
172
+		sb->hfree = hf_free_option_tag;
173
+		sb->option_tags_all = 0;
174 174
 		hdr->parsed = (void*)sb;
175
-		supported |= sb->supported;
175
+		supported |= sb->option_tags;
176 176
 	}
177 177
 
178
-	((struct supported_body*)msg->supported->parsed)->supported_all = 
178
+	((struct option_tag_body*)msg->supported->parsed)->option_tags_all = 
179 179
 		supported;
180 180
 	return 0;
181 181
 }
182
-
183
-/* free supported header structure */
184
-void free_supported(struct supported_body **sb)
185
-{
186
-	if (sb && *sb) {
187
-		pkg_free(*sb);
188
-		*sb = 0;
189
-	}
190
-}
... ...
@@ -36,51 +36,11 @@
36 36
 #define PARSE_SUPPORTED_H
37 37
 
38 38
 #include "../../parser/msg_parser.h"
39
-#include "../../parser/hf.h"
40 39
 #include "../../mem/mem.h"
41
-
42
-
43
-#define F_SUPPORTED_PATH		(1 << 0)
44
-#define F_SUPPORTED_100REL		(1 << 1)
45
-#define F_SUPPORTED_TIMER		(1 << 2)
46
-#define F_SUPPORTED_EVENTLIST   (1 << 3)
47
-#define F_SUPPORTED_GRUU        (1 << 4)
48
-#define F_SUPPORTED_OUTBOUND    (1 << 5)
49
-
50
-#define SUPPORTED_PATH_STR		"path"
51
-#define SUPPORTED_PATH_LEN		(sizeof(SUPPORTED_PATH_STR)-1)
52
-
53
-/* RFC 3262 (PRACK) */
54
-#define SUPPORTED_100REL_STR	"100rel"
55
-#define SUPPORTED_100REL_LEN	(sizeof(SUPPORTED_100REL_STR)-1)
56
-
57
-/* RFC 4028 */
58
-#define SUPPORTED_TIMER_STR		"timer"
59
-#define SUPPORTED_TIMER_LEN		(sizeof(SUPPORTED_TIMER_STR)-1)
60
-
61
-/* RFC 4662 (RLS) */
62
-#define SUPPORTED_EVENTLIST_STR  "eventlist"
63
-#define SUPPORTED_EVENTLIST_LEN  (sizeof(SUPPORTED_EVENTLIST_STR)-1)
64
-
65
-/* RFC 5627 */
66
-#define SUPPORTED_GRUU_STR		"gruu"
67
-#define SUPPORTED_GRUU_LEN		(sizeof(SUPPORTED_GRUU_STR)-1)
68
-
69
-/* RFC 5626 */
70
-#define SUPPORTED_OUTBOUND_STR	"outbound"
71
-#define SUPPORTED_OUTBOUND_LEN	(sizeof(SUPPORTED_OUTBOUND_STR)-1)
40
+#include "option-tags.h"
72 41
 
73 42
 #define get_supported(p_msg) \
74
-	((p_msg)->supported ? ((struct supported_body*)(p_msg)->supported->parsed)->supported_all : 0)
75
-
76
-
77
-struct supported_body {
78
-	hf_parsed_free_f hfree;        /* function to free the content */
79
-	unsigned int supported;        /* supported mask for the current hdr */
80
-	unsigned int supported_all;    /* suppoted mask for the all "supported" hdr
81
-	                                *  - it's set only for the first hdr in 
82
-	                                *  sibling list*/
83
-};
43
+	((p_msg)->supported ? ((struct option_tag_body*)(p_msg)->supported->parsed)->option_tags_all : 0)
84 44
 
85 45
 
86 46
 /*!
... ...
@@ -89,6 +49,6 @@ struct supported_body {
89 89
 int parse_supported( struct sip_msg *msg);
90 90
 
91 91
 
92
-void free_supported(struct supported_body **sb);
92
+void free_supported(struct option_tag_body **sb);
93 93
 
94 94
 #endif /* PARSE_SUPPORTED_H */