Browse code

core: parser/parse_hname2 - option to skip printing logs on parse failure

Daniel-Constantin Mierla authored on 02/06/2021 16:00:35
Showing 1 changed files
... ...
@@ -219,21 +219,25 @@ int ksr_hname_init_config(void)
219 219
  * - fills hdr structure (must not be null)
220 220
  * - set hdr->type=HDR_ERROR_T in case of parsing error
221 221
  * - if emode==1, then parsing does not expect : after header name
222
+ * - if logmode==1, then print error log messages on parsing failure
222 223
  * - returns pointer after : if emode==0 or after header name if emode==1
224
+ *   in case of parsing error, returns begin and sets hdr->type to HDR_ERROR_T
223 225
  */
224 226
 char *parse_sip_header_name(char* const begin, const char* const end,
225
-		hdr_field_t* const hdr, int emode)
227
+		hdr_field_t* const hdr, int emode, int logmode)
226 228
 {
227 229
 	char *p;
228 230
 	int i;
229 231
 
230
-	if (end <= begin) {
232
+	if (begin == NULL || end == NULL || end <= begin) {
231 233
 		hdr->type = HDR_ERROR_T;
232 234
 		return begin;
233 235
 	}
234 236
 	if(_ksr_hname_chars_idx[(unsigned char)(*begin)] == 0) {
235
-		LM_ERR("invalid start of header name for [%.*s]\n",
236
-				(int)(end-begin), begin);
237
+		if(likely(logmode)) {
238
+			LM_ERR("invalid start of header name for [%.*s]\n",
239
+					(int)(end-begin), begin);
240
+		}
237 241
 		hdr->type = HDR_ERROR_T;
238 242
 		return begin;
239 243
 	}
... ...
@@ -262,8 +266,10 @@ char *parse_sip_header_name(char* const begin, const char* const end,
262 266
 		}
263 267
 		if(*p != ' ' && *p != '\t') {
264 268
 			/* no white space - bad header name format */
265
-			LM_ERR("invalid header name for [%.*s]\n",
266
-					(int)(end-begin), begin);
269
+			if(likely(logmode)) {
270
+				LM_ERR("invalid header name for [%.*s]\n",
271
+						(int)(end-begin), begin);
272
+			}
267 273
 			hdr->type = HDR_ERROR_T;
268 274
 			return begin;
269 275
 		}
... ...
@@ -271,8 +277,10 @@ char *parse_sip_header_name(char* const begin, const char* const end,
271 277
 
272 278
 	if(p == end) {
273 279
 		/* no : found - emode==0 */
274
-		LM_ERR("invalid end of header name for [%.*s]\n",
275
-				(int)(end-begin), begin);
280
+		if(likely(logmode)) {
281
+			LM_ERR("invalid end of header name for [%.*s]\n",
282
+					(int)(end-begin), begin);
283
+		}
276 284
 		hdr->type = HDR_ERROR_T;
277 285
 		return begin;
278 286
 	}
... ...
@@ -298,7 +306,7 @@ done:
298 306
 
299 307
 char* parse_hname2(char* const begin, const char* const end, struct hdr_field* const hdr)
300 308
 {
301
-	return parse_sip_header_name(begin, end, hdr, 0);
309
+	return parse_sip_header_name(begin, end, hdr, 0, 1);
302 310
 }
303 311
 
304 312
 /**
... ...
@@ -307,11 +315,11 @@ char* parse_hname2(char* const begin, const char* const end, struct hdr_field* c
307 315
  */
308 316
 char* parse_hname2_short(char* const begin, const char* const end, struct hdr_field* const hdr)
309 317
 {
310
-	return parse_sip_header_name(begin, end, hdr, 0);
318
+	return parse_sip_header_name(begin, end, hdr, 0, 1);
311 319
 }
312 320
 
313 321
 char* parse_hname2_str (str* const hbuf, hdr_field_t* const hdr)
314 322
 {
315
-	return parse_sip_header_name(hbuf->s, hbuf->s + hbuf->len, hdr, 1);
323
+	return parse_sip_header_name(hbuf->s, hbuf->s + hbuf->len, hdr, 1, 1);
316 324
 }
317 325
 
Browse code

core: parser - wrapper function to parse str header name

Daniel-Constantin Mierla authored on 06/10/2020 10:18:26
Showing 1 changed files
... ...
@@ -309,3 +309,9 @@ char* parse_hname2_short(char* const begin, const char* const end, struct hdr_fi
309 309
 {
310 310
 	return parse_sip_header_name(begin, end, hdr, 0);
311 311
 }
312
+
313
+char* parse_hname2_str (str* const hbuf, hdr_field_t* const hdr)
314
+{
315
+	return parse_sip_header_name(hbuf->s, hbuf->s + hbuf->len, hdr, 1);
316
+}
317
+
Browse code

core: cast to unsigned to make analyzers happy on index type

Daniel-Constantin Mierla authored on 03/09/2020 12:03:02
Showing 1 changed files
... ...
@@ -154,17 +154,17 @@ static ksr_hdr_map_idx_t _ksr_hdr_map_idx[KSR_HDR_MAP_IDX_SIZE];
154 154
 /**
155 155
  * valid chars in header names
156 156
  */
157
-static char *_ksr_hname_chars_list = "0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz-._+~";
157
+static unsigned char *_ksr_hname_chars_list = (unsigned char*)"0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz-._+~";
158 158
 
159 159
 /**
160 160
  * additional valid chars in header names (core param)
161 161
  */
162
-char *_ksr_hname_extra_chars = "";
162
+unsigned char *_ksr_hname_extra_chars = (unsigned char*)"";
163 163
 
164 164
 /**
165 165
  * indexed valid chars in 256-array for 1-byte-index access check
166 166
  */
167
-static char _ksr_hname_chars_idx[KSR_HDR_MAP_IDX_SIZE];
167
+static unsigned char _ksr_hname_chars_idx[KSR_HDR_MAP_IDX_SIZE];
168 168
 
169 169
 
170 170
 /**
... ...
@@ -172,7 +172,7 @@ static char _ksr_hname_chars_idx[KSR_HDR_MAP_IDX_SIZE];
172 172
  */
173 173
 int ksr_hname_init_index(void)
174 174
 {
175
-	char c;
175
+	unsigned char c;
176 176
 	int i;
177 177
 
178 178
 	for(i=0; i<KSR_HDR_MAP_IDX_SIZE; i++) {
... ...
@@ -231,7 +231,7 @@ char *parse_sip_header_name(char* const begin, const char* const end,
231 231
 		hdr->type = HDR_ERROR_T;
232 232
 		return begin;
233 233
 	}
234
-	if(_ksr_hname_chars_idx[*begin] == 0) {
234
+	if(_ksr_hname_chars_idx[(unsigned char)(*begin)] == 0) {
235 235
 		LM_ERR("invalid start of header name for [%.*s]\n",
236 236
 				(int)(end-begin), begin);
237 237
 		hdr->type = HDR_ERROR_T;
... ...
@@ -241,7 +241,7 @@ char *parse_sip_header_name(char* const begin, const char* const end,
241 241
 	hdr->name.s = begin;
242 242
 
243 243
 	for(p=begin+1; p<end; p++) {
244
-		if(_ksr_hname_chars_idx[*p] == 0) {
244
+		if(_ksr_hname_chars_idx[(unsigned char)(*p)] == 0) {
245 245
 			/* char not allowed in header name */
246 246
 			break;
247 247
 		}
... ...
@@ -279,9 +279,9 @@ char *parse_sip_header_name(char* const begin, const char* const end,
279 279
 
280 280
 done:
281 281
 	/* lookup header type */
282
-	if(_ksr_hdr_map_idx[hdr->name.s[0]].idxs >= 0) {
283
-		for(i = _ksr_hdr_map_idx[hdr->name.s[0]].idxs;
284
-					i <= _ksr_hdr_map_idx[hdr->name.s[0]].idxe; i++) {
282
+	if(_ksr_hdr_map_idx[(unsigned char)(hdr->name.s[0])].idxs >= 0) {
283
+		for(i = _ksr_hdr_map_idx[(unsigned char)(hdr->name.s[0])].idxs;
284
+					i <= _ksr_hdr_map_idx[(unsigned char)(hdr->name.s[0])].idxe; i++) {
285 285
 			if(hdr->name.len == _ksr_hdr_map[i].hname.len
286 286
 					&& strncasecmp(hdr->name.s, _ksr_hdr_map[i].hname.s,
287 287
 							hdr->name.len) == 0) {
... ...
@@ -308,4 +308,4 @@ char* parse_hname2(char* const begin, const char* const end, struct hdr_field* c
308 308
 char* parse_hname2_short(char* const begin, const char* const end, struct hdr_field* const hdr)
309 309
 {
310 310
 	return parse_sip_header_name(begin, end, hdr, 0);
311
-}
312 311
\ No newline at end of file
312
+}
Browse code

core: added global parameter hdr_name_extra_chars

- allow specifying additional chars to be allowed in header names

Daniel-Constantin Mierla authored on 23/07/2020 06:51:30
Showing 1 changed files
... ...
@@ -156,6 +156,11 @@ static ksr_hdr_map_idx_t _ksr_hdr_map_idx[KSR_HDR_MAP_IDX_SIZE];
156 156
  */
157 157
 static char *_ksr_hname_chars_list = "0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz-._+~";
158 158
 
159
+/**
160
+ * additional valid chars in header names (core param)
161
+ */
162
+char *_ksr_hname_extra_chars = "";
163
+
159 164
 /**
160 165
  * indexed valid chars in 256-array for 1-byte-index access check
161 166
  */
... ...
@@ -163,7 +168,7 @@ static char _ksr_hname_chars_idx[KSR_HDR_MAP_IDX_SIZE];
163 168
 
164 169
 
165 170
 /**
166
- * init header name parsing structures and indexes
171
+ * init header name parsing structures and indexes at very beginning of start up
167 172
  */
168 173
 int ksr_hname_init_index(void)
169 174
 {
... ...
@@ -195,6 +200,20 @@ int ksr_hname_init_index(void)
195 200
 	return 0;
196 201
 }
197 202
 
203
+/**
204
+ * init header name parsing structures and indexes after config parsing
205
+ */
206
+int ksr_hname_init_config(void)
207
+{
208
+	int i;
209
+
210
+	for(i=0; _ksr_hname_extra_chars[i] != 0; i++) {
211
+		_ksr_hname_chars_idx[_ksr_hname_extra_chars[i]] = 1;
212
+	}
213
+
214
+	return 0;
215
+}
216
+
198 217
 /**
199 218
  * parse the sip header name in the buffer starting at 'begin' till before 'end'
200 219
  * - fills hdr structure (must not be null)
Browse code

core: parse hdr name - removed unused defines

- comments to describe indexing arrays

Daniel-Constantin Mierla authored on 22/07/2020 06:09:02
Showing 1 changed files
... ...
@@ -145,12 +145,26 @@ typedef struct ksr_hdr_map_idx {
145 145
 } ksr_hdr_map_idx_t;
146 146
 
147 147
 #define KSR_HDR_MAP_IDX_SIZE 256
148
+
149
+/**
150
+ * array to keep start and end indexes of header names groupped by first char
151
+ */
148 152
 static ksr_hdr_map_idx_t _ksr_hdr_map_idx[KSR_HDR_MAP_IDX_SIZE];
149 153
 
154
+/**
155
+ * valid chars in header names
156
+ */
150 157
 static char *_ksr_hname_chars_list = "0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz-._+~";
151 158
 
159
+/**
160
+ * indexed valid chars in 256-array for 1-byte-index access check
161
+ */
152 162
 static char _ksr_hname_chars_idx[KSR_HDR_MAP_IDX_SIZE];
153 163
 
164
+
165
+/**
166
+ * init header name parsing structures and indexes
167
+ */
154 168
 int ksr_hname_init_index(void)
155 169
 {
156 170
 	char c;
... ...
@@ -181,10 +195,6 @@ int ksr_hname_init_index(void)
181 195
 	return 0;
182 196
 }
183 197
 
184
-#define LOWER_BYTE(b) ((b) | 0x20)
185
-#define LOWER_DWORD(d) ((d) | 0x20202020)
186
-
187
-
188 198
 /**
189 199
  * parse the sip header name in the buffer starting at 'begin' till before 'end'
190 200
  * - fills hdr structure (must not be null)
Browse code

core: parse hdr name - added missing compact names in static map

- https://www.iana.org/assignments/sip-parameters/sip-parameters.xhtml#sip-parameters-2

Daniel-Constantin Mierla authored on 20/07/2020 14:15:33
Showing 1 changed files
... ...
@@ -62,6 +62,7 @@ static ksr_hdr_map_t _ksr_hdr_map[] = {
62 62
 	{ str_init("Content-Type"), HDR_CONTENTTYPE_T, HDR_CONTENTTYPE_F },
63 63
 	{ str_init("CSeq"), HDR_CSEQ_T, HDR_CSEQ_F },
64 64
 
65
+	{ str_init("d"), HDR_REQUESTDISPOSITION_T, HDR_REQUESTDISPOSITION_F },
65 66
 	{ str_init("Date"), HDR_DATE_T, HDR_DATE_F },
66 67
 	{ str_init("Diversion"), HDR_DIVERSION_T, HDR_DIVERSION_F },
67 68
 
... ...
@@ -76,6 +77,8 @@ static ksr_hdr_map_t _ksr_hdr_map[] = {
76 77
 	{ str_init("Identity"), HDR_IDENTITY_T, HDR_IDENTITY_F },
77 78
 	{ str_init("Identity-Info"), HDR_IDENTITY_INFO_T, HDR_IDENTITY_INFO_F },
78 79
 
80
+	{ str_init("j"), HDR_REJECTCONTACT_T, HDR_REJECTCONTACT_F },
81
+
79 82
 	{ str_init("k"), HDR_SUPPORTED_T, HDR_SUPPORTED_F },
80 83
 
81 84
 	{ str_init("l"), HDR_CONTENTLENGTH_T, HDR_CONTENTLENGTH_F },
... ...
@@ -127,6 +130,10 @@ static ksr_hdr_map_t _ksr_hdr_map[] = {
127 130
 	{ str_init("v"), HDR_VIA_T, HDR_VIA_F },
128 131
 	{ str_init("Via"), HDR_VIA_T, HDR_VIA_F },
129 132
 
133
+	{ str_init("x"), HDR_SESSIONEXPIRES_T, HDR_SESSIONEXPIRES_F },
134
+
135
+	{ str_init("y"), HDR_IDENTITY_T, HDR_IDENTITY_F },
136
+
130 137
 	{ str_init("WWW-Authenticate"), HDR_WWW_AUTHENTICATE_T, HDR_WWW_AUTHENTICATE_F },
131 138
 
132 139
 	{ str_init(""), 0, 0 }
Browse code

core: parser - use str cmp function directly for hdr name parsing

Daniel-Constantin Mierla authored on 16/07/2020 12:15:01
Showing 1 changed files
... ...
@@ -29,7 +29,6 @@
29 29
 #include <stdio.h>
30 30
 #include <ctype.h>
31 31
 
32
-#include "../strutils.h"
33 32
 #include "../dprint.h"
34 33
 
35 34
 #include "parse_hname2.h"
... ...
@@ -247,7 +246,9 @@ done:
247 246
 	if(_ksr_hdr_map_idx[hdr->name.s[0]].idxs >= 0) {
248 247
 		for(i = _ksr_hdr_map_idx[hdr->name.s[0]].idxs;
249 248
 					i <= _ksr_hdr_map_idx[hdr->name.s[0]].idxe; i++) {
250
-			if(cmp_hdrname_str(&hdr->name, &_ksr_hdr_map[i].hname) == 0) {
249
+			if(hdr->name.len == _ksr_hdr_map[i].hname.len
250
+					&& strncasecmp(hdr->name.s, _ksr_hdr_map[i].hname.s,
251
+							hdr->name.len) == 0) {
251 252
 				hdr->type = _ksr_hdr_map[i].htype;
252 253
 			}
253 254
 		}
Browse code

core: use static map for header name and type for parsing

- simplified header name parsing by using indexed (at startup) mapping
of header name and type in a static array

Daniel-Constantin Mierla authored on 16/07/2020 11:27:00
Showing 1 changed files
... ...
@@ -26,271 +26,249 @@
26 26
  * @ingroup parser
27 27
  */
28 28
 
29
-#include "../comp_defs.h"
30
-#include "../trim.h"
31
-#include "../ut.h"  /* q_memchr */
29
+#include <stdio.h>
30
+#include <ctype.h>
31
+
32
+#include "../strutils.h"
33
+#include "../dprint.h"
34
+
32 35
 #include "parse_hname2.h"
33
-#include "keys.h"
34 36
 
35
-#define LOWER_BYTE(b) ((b) | 0x20)
36
-#define LOWER_DWORD(d) ((d) | 0x20202020)
37
+typedef struct ksr_hdr_map {
38
+	str hname;
39
+	hdr_types_t htype;
40
+	hdr_flags_t hflag;
41
+} ksr_hdr_map_t;
37 42
 
38
-/** Skip all white-chars and return position of the first non-white char.
39
- */
40
-static inline char* skip_ws(char* p, unsigned int size)
43
+/* map with SIP header name
44
+ * - must be groupped by first letter - indexed for faster search */
45
+static ksr_hdr_map_t _ksr_hdr_map[] = {
46
+	{ str_init("a"), HDR_ACCEPTCONTACT_T, HDR_ACCEPTCONTACT_F },
47
+	{ str_init("Accept"), HDR_ACCEPT_T, HDR_ACCEPT_F },
48
+	{ str_init("Accept-Contact"), HDR_ACCEPTCONTACT_T, HDR_ACCEPTCONTACT_F },
49
+	{ str_init("Accept-Language"), HDR_ACCEPTLANGUAGE_T, HDR_ACCEPTLANGUAGE_F },
50
+	{ str_init("Allow"), HDR_ALLOW_T, HDR_ALLOW_F },
51
+	{ str_init("Allow-Events"), HDR_ALLOWEVENTS_T, HDR_ALLOWEVENTS_F },
52
+	{ str_init("Authorization"), HDR_AUTHORIZATION_T, HDR_AUTHORIZATION_F },
53
+
54
+	{ str_init("b"), HDR_REFERREDBY_T, HDR_REFERREDBY_F },
55
+
56
+	{ str_init("c"), HDR_CONTENTTYPE_T, HDR_CONTENTTYPE_F },
57
+	{ str_init("Call-Id"), HDR_CALLID_T, HDR_CALLID_F },
58
+	{ str_init("Call-Info"), HDR_CALLINFO_T, HDR_CALLINFO_F },
59
+	{ str_init("Contact"), HDR_CONTACT_T, HDR_CONTACT_F },
60
+	{ str_init("Content-Disposition"), HDR_CONTENTDISPOSITION_T, HDR_CONTENTDISPOSITION_F },
61
+	{ str_init("Content-Encoding"), HDR_CONTENTENCODING_T, HDR_CONTENTENCODING_F },
62
+	{ str_init("Content-Length"), HDR_CONTENTLENGTH_T, HDR_CONTENTLENGTH_F },
63
+	{ str_init("Content-Type"), HDR_CONTENTTYPE_T, HDR_CONTENTTYPE_F },
64
+	{ str_init("CSeq"), HDR_CSEQ_T, HDR_CSEQ_F },
65
+
66
+	{ str_init("Date"), HDR_DATE_T, HDR_DATE_F },
67
+	{ str_init("Diversion"), HDR_DIVERSION_T, HDR_DIVERSION_F },
68
+
69
+	{ str_init("e"), HDR_CONTENTENCODING_T, HDR_CONTENTENCODING_F },
70
+	{ str_init("Event"), HDR_EVENT_T, HDR_EVENT_F },
71
+	{ str_init("Expires"), HDR_EXPIRES_T, HDR_EXPIRES_F },
72
+
73
+	{ str_init("f"), HDR_FROM_T, HDR_FROM_F },
74
+	{ str_init("From"), HDR_FROM_T, HDR_FROM_F },
75
+
76
+	{ str_init("i"), HDR_CALLID_T, HDR_CALLID_F },
77
+	{ str_init("Identity"), HDR_IDENTITY_T, HDR_IDENTITY_F },
78
+	{ str_init("Identity-Info"), HDR_IDENTITY_INFO_T, HDR_IDENTITY_INFO_F },
79
+
80
+	{ str_init("k"), HDR_SUPPORTED_T, HDR_SUPPORTED_F },
81
+
82
+	{ str_init("l"), HDR_CONTENTLENGTH_T, HDR_CONTENTLENGTH_F },
83
+
84
+	{ str_init("m"), HDR_CONTACT_T, HDR_CONTACT_F },
85
+	{ str_init("Max-Forwards"), HDR_MAXFORWARDS_T, HDR_MAXFORWARDS_F },
86
+	{ str_init("Min-Expires"), HDR_MIN_EXPIRES_T, HDR_MIN_EXPIRES_F },
87
+	{ str_init("Min-SE"), HDR_MIN_SE_T, HDR_MIN_SE_F },
88
+
89
+	{ str_init("o"), HDR_EVENT_T, HDR_EVENT_F },
90
+	{ str_init("Organization"), HDR_ORGANIZATION_T, HDR_ORGANIZATION_F },
91
+
92
+	{ str_init("Path"), HDR_PATH_T, HDR_PATH_F },
93
+	{ str_init("Priority"), HDR_PRIORITY_T, HDR_PRIORITY_F },
94
+	{ str_init("Privacy"), HDR_PRIVACY_T, HDR_PRIVACY_F },
95
+	{ str_init("Proxy-Authenticate"), HDR_PROXY_AUTHENTICATE_T, HDR_PROXY_AUTHENTICATE_F },
96
+	{ str_init("Proxy-Authorization"), HDR_PROXYAUTH_T, HDR_PROXYAUTH_F },
97
+	{ str_init("Proxy-Require"), HDR_PROXYREQUIRE_T, HDR_PROXYREQUIRE_F },
98
+	{ str_init("P-Preferred-Identity"), HDR_PPI_T, HDR_PPI_F },
99
+	{ str_init("P-Asserted-Identity"), HDR_PAI_T, HDR_PAI_F },
100
+
101
+	{ str_init("r"), HDR_REFER_TO_T, HDR_REFER_TO_F },
102
+	{ str_init("Reason"), HDR_REASON_T, HDR_REASON_F },
103
+	{ str_init("Record-Route"), HDR_RECORDROUTE_T, HDR_RECORDROUTE_F },
104
+	{ str_init("Refer-To"), HDR_REFER_TO_T, HDR_REFER_TO_F },
105
+	{ str_init("Referred-By"), HDR_REFERREDBY_T, HDR_REFERREDBY_F },
106
+	{ str_init("Reject-Contact"), HDR_REJECTCONTACT_T, HDR_REJECTCONTACT_F },
107
+	{ str_init("Remote-Party-ID"), HDR_RPID_T, HDR_RPID_F },
108
+	{ str_init("Request-Disposition"), HDR_REQUESTDISPOSITION_T, HDR_REQUESTDISPOSITION_F },
109
+	{ str_init("Require"), HDR_REQUIRE_T, HDR_REQUIRE_F },
110
+	{ str_init("Retry-After"), HDR_RETRY_AFTER_T, HDR_RETRY_AFTER_F },
111
+	{ str_init("Route"), HDR_ROUTE_T, HDR_ROUTE_F },
112
+
113
+	{ str_init("s"), HDR_SUBJECT_T, HDR_SUBJECT_F },
114
+	{ str_init("Server"), HDR_SERVER_T, HDR_SERVER_F },
115
+	{ str_init("Session-Expires"), HDR_SESSIONEXPIRES_T, HDR_SESSIONEXPIRES_F },
116
+	{ str_init("SIP-If-Match"), HDR_SIPIFMATCH_T, HDR_SIPIFMATCH_F },
117
+	{ str_init("Subject"), HDR_SUBJECT_T, HDR_SUBJECT_F },
118
+	{ str_init("Subscription-State"), HDR_SUBSCRIPTION_STATE_T, HDR_SUBSCRIPTION_STATE_F },
119
+	{ str_init("Supported"), HDR_SUPPORTED_T, HDR_SUPPORTED_F },
120
+
121
+	{ str_init("t"), HDR_TO_T, HDR_TO_F },
122
+	{ str_init("To"), HDR_TO_T, HDR_TO_F },
123
+
124
+	{ str_init("u"), HDR_ALLOWEVENTS_T, HDR_ALLOWEVENTS_F },
125
+	{ str_init("Unsupported"), HDR_UNSUPPORTED_T, HDR_UNSUPPORTED_F },
126
+	{ str_init("User-Agent"), HDR_USERAGENT_T, HDR_USERAGENT_F },
127
+
128
+	{ str_init("v"), HDR_VIA_T, HDR_VIA_F },
129
+	{ str_init("Via"), HDR_VIA_T, HDR_VIA_F },
130
+
131
+	{ str_init("WWW-Authenticate"), HDR_WWW_AUTHENTICATE_T, HDR_WWW_AUTHENTICATE_F },
132
+
133
+	{ str_init(""), 0, 0 }
134
+};
135
+
136
+typedef struct ksr_hdr_map_idx {
137
+	int idxs;
138
+	int idxe;
139
+} ksr_hdr_map_idx_t;
140
+
141
+#define KSR_HDR_MAP_IDX_SIZE 256
142
+static ksr_hdr_map_idx_t _ksr_hdr_map_idx[KSR_HDR_MAP_IDX_SIZE];
143
+
144
+static char *_ksr_hname_chars_list = "0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz-._+~";
145
+
146
+static char _ksr_hname_chars_idx[KSR_HDR_MAP_IDX_SIZE];
147
+
148
+int ksr_hname_init_index(void)
41 149
 {
42
-	char* end;
150
+	char c;
151
+	int i;
152
+
153
+	for(i=0; i<KSR_HDR_MAP_IDX_SIZE; i++) {
154
+		_ksr_hdr_map_idx[i].idxs = -1;
155
+		_ksr_hdr_map_idx[i].idxe = -1;
156
+		_ksr_hname_chars_idx[i] = 0;
157
+	}
43 158
 
44
-	end = p + size;
45
-	for(; p < end; p++) {
46
-		if ((*p != ' ') && (*p != '\t')) return p;
159
+	for(i=0; _ksr_hdr_map[i].hname.len > 0; i++) {
160
+		c = _ksr_hdr_map[i].hname.s[0];
161
+		if(_ksr_hdr_map_idx[c].idxs == -1) {
162
+			_ksr_hdr_map_idx[tolower(c)].idxs = i;
163
+			_ksr_hdr_map_idx[toupper(c)].idxs = i;
164
+		}
165
+		if(c != _ksr_hdr_map[i+1].hname.s[0]) {
166
+			_ksr_hdr_map_idx[tolower(c)].idxe = i;
167
+			_ksr_hdr_map_idx[toupper(c)].idxe = i;
168
+		}
47 169
 	}
48
-	return p;
170
+
171
+	for(i=0; _ksr_hname_chars_list[i] != 0; i++) {
172
+		_ksr_hname_chars_idx[_ksr_hname_chars_list[i]] = 1;
173
+	}
174
+
175
+	return 0;
49 176
 }
50 177
 
51
-/*! \name 
52
- * Parser macros
53
- */
54
-/*@{ */
55
-#include "case_via.h"      /* Via */
56
-#include "case_from.h"     /* From */
57
-#include "case_to.h"       /* To */
58
-#include "case_cseq.h"     /* CSeq */
59
-#include "case_call.h"     /* Call-ID */
60
-#include "case_cont.h"     /* Contact, Content-Type, Content-Length, Content-Purpose,
61
-			    * Content-Action, Content-Disposition */
62
-#include "case_rout.h"     /* Route */
63
-#include "case_max.h"      /* Max-Forwards */
64
-#include "case_reco.h"     /* Record-Route */
65
-#include "case_auth.h"     /* Authorization */
66
-#include "case_expi.h"     /* Expires */
67
-#include "case_prox.h"     /* Proxy-Authorization, Proxy-Require */
68
-#include "case_allo.h"     /* Allow */
69
-#include "case_unsu.h"     /* Unsupported */
70
-#include "case_even.h"     /* Event */
71
-#include "case_sip.h"      /* Sip-If-Match */
72
-#include "case_acce.h"     /* Accept, Accept-Language */
73
-#include "case_orga.h"     /* Organization */
74
-#include "case_prio.h"     /* Priority */
75
-#include "case_subj.h"     /* Subject */
76
-#include "case_user.h"     /* User-Agent */
77
-#include "case_serv.h"     /* Server */
78
-#include "case_supp.h"     /* Supported */
79
-#include "case_dive.h"     /* Diversion */
80
-#include "case_remo.h"     /* Remote-Party-ID */
81
-#include "case_refe.h"     /* Refer-To */
82
-#include "case_sess.h"     /* Session-Expires */
83
-#include "case_reje.h"     /* Reject-Contact */
84
-#include "case_min.h"      /* Min-SE */
85
-#include "case_subs.h"     /* Subscription-State */
86
-#include "case_requ.h"     /* Require */
87
-#include "case_www.h"      /* WWW-Authenticate */
88
-#include "case_date.h"     /* Date */
89
-#include "case_iden.h"     /* Identity, Identity-info */
90
-#include "case_retr.h"     /* Retry-After */
91
-#include "case_path.h"     /* Path */
92
-#include "case_priv.h"
93
-#include "case_reas.h"     /* Reason */
94
-#include "case_p_as.h"     /* P-Asserted-Identity */
95
-#include "case_p_pr.h"     /* P-Preferred-Identity */
96
-
97
-/*@} */
98
-
99
-#define SAFE_READ(val, len) \
100
-((len) == 1 ? READ1(val) : ((len) == 2 ? READ2(val) : ((len) == 3 ? READ3(val) : ((len) > 3 ? READ4(val) : READ0(val)))))
101
-
102
-#define READ(val) \
103
-READ4(val)
104
-
105
-#define READ4(val) \
106
-(*((val) + 0) + (*((val) + 1) << 8) + (*((val) + 2) << 16) + (*((val) + 3) << 24))
107
-
108
-#define READ3(val) \
109
-(*((val) + 0) + (*((val) + 1) << 8) + (*((val) + 2) << 16))
110
-
111
-#define READ2(val) \
112
-(*((val) + 0) + (*((val) + 1) << 8))
113
-
114
-#define READ1(val) \
115
-(*((val) + 0))
116
-
117
-#define READ0(val) \
118
-(0)
119
-
120
-#define FIRST_QUATERNIONS       \
121
-        case _via1_: via1_CASE; \
122
-	case _from_: from_CASE; \
123
-	case _to12_: to12_CASE; \
124
-	case _cseq_: cseq_CASE; \
125
-	case _call_: call_CASE; \
126
-	case _cont_: cont_CASE; \
127
-	case _rout_: rout_CASE; \
128
-	case _max__: max_CASE;  \
129
-	case _reco_: reco_CASE; \
130
-	case _via2_: via2_CASE; \
131
-	case _auth_: auth_CASE; \
132
-	case _supp_: supp_CASE; \
133
-	case _expi_: expi_CASE; \
134
-	case _prox_: prox_CASE; \
135
-	case _allo_: allo_CASE; \
136
-	case _unsu_: unsu_CASE; \
137
-        case _even_: even_CASE; \
138
-        case _sip_ : sip_CASE;  \
139
-        case _acce_: acce_CASE; \
140
-        case _orga_: orga_CASE; \
141
-        case _prio_: prio_CASE; \
142
-        case _subj_: subj_CASE; \
143
-        case _subs_: subs_CASE; \
144
-        case _user_: user_CASE; \
145
-        case _serv_: serv_CASE; \
146
-        case _dive_: dive_CASE; \
147
-        case _remo_: remo_CASE; \
148
-        case _refe_: refe_CASE; \
149
-	case _sess_: sess_CASE; \
150
-	case _reje_: reje_CASE; \
151
-	case _min__: min_CASE;  \
152
-	case _requ_: requ_CASE;  \
153
-	case _www__: www_CASE; \
154
-	case _date_: date_CASE; \
155
-	case _iden_: iden_CASE; \
156
-	case _retr_: retr_CASE; \
157
-	case _path_: path_CASE; \
158
-	case _priv_: priv_CASE; \
159
-	case _reas_: reas_CASE; \
160
-	case _p_as_: p_as_CASE; \
161
-	case _p_pr_: p_pr_CASE;
162
-
163
-
164
-#define PARSE_COMPACT(id)          \
165
-        switch(*(p + 1)) {         \
166
-        case ' ':                  \
167
-	        hdr->type = id;    \
168
-	        p += 2;            \
169
-	        goto dc_end;       \
170
-	                           \
171
-        case ':':                  \
172
-	        hdr->type = id;    \
173
-	        hdr->name.len = 1; \
174
-	        return (p + 2);    \
175
-        }
178
+#define LOWER_BYTE(b) ((b) | 0x20)
179
+#define LOWER_DWORD(d) ((d) | 0x20202020)
176 180
 
177
-char* parse_hname2(char* const begin, const char* const end, struct hdr_field* const hdr)
181
+
182
+/**
183
+ * parse the sip header name in the buffer starting at 'begin' till before 'end'
184
+ * - fills hdr structure (must not be null)
185
+ * - set hdr->type=HDR_ERROR_T in case of parsing error
186
+ * - if emode==1, then parsing does not expect : after header name
187
+ * - returns pointer after : if emode==0 or after header name if emode==1
188
+ */
189
+char *parse_sip_header_name(char* const begin, const char* const end,
190
+		hdr_field_t* const hdr, int emode)
178 191
 {
179
-	register char* p;
180
-	register unsigned int val;
192
+	char *p;
193
+	int i;
181 194
 
182
-	if ((end - begin) < 4) {
195
+	if (end <= begin) {
183 196
 		hdr->type = HDR_ERROR_T;
184 197
 		return begin;
185 198
 	}
186
-
187
-	p = begin;
188
-
189
-	val = LOWER_DWORD(READ(p));
199
+	if(_ksr_hname_chars_idx[*begin] == 0) {
200
+		LM_ERR("invalid start of header name for [%.*s]\n",
201
+				(int)(end-begin), begin);
202
+		hdr->type = HDR_ERROR_T;
203
+		return begin;
204
+	}
205
+	hdr->type = HDR_OTHER_T;
190 206
 	hdr->name.s = begin;
191 207
 
192
-	switch(val) {
193
-	FIRST_QUATERNIONS;
194
-
195
-	default:
196
-		switch(LOWER_BYTE(*p)) {
197
-		case 't':
198
-			switch(LOWER_BYTE(*(p + 1))) {
199
-			case 'o':
200
-			case ' ':
201
-				hdr->type = HDR_TO_T;
202
-				p += 2;
203
-				goto dc_end;
204
-
205
-			case ':':
206
-				hdr->type = HDR_TO_T;
207
-				hdr->name.len = 1;
208
-				return (p + 2);
209
-			}
208
+	for(p=begin+1; p<end; p++) {
209
+		if(_ksr_hname_chars_idx[*p] == 0) {
210
+			/* char not allowed in header name */
210 211
 			break;
212
+		}
213
+	}
214
+	hdr->name.len = p - hdr->name.s;
215
+
216
+	if(emode == 1) {
217
+		/* allowed end of header name without finding : */
218
+		p = p - 1; /* function returns (p+1) */
219
+		goto done;
220
+	}
211 221
 
212
-		case 'v': PARSE_COMPACT(HDR_VIA_T);           break;
213
-		case 'f': PARSE_COMPACT(HDR_FROM_T);          break;
214
-		case 'i': PARSE_COMPACT(HDR_CALLID_T);        break;
215
-		case 'm': PARSE_COMPACT(HDR_CONTACT_T);       break;
216
-		case 'l': PARSE_COMPACT(HDR_CONTENTLENGTH_T); break;
217
-		case 'k': PARSE_COMPACT(HDR_SUPPORTED_T);     break;
218
-		case 'c': PARSE_COMPACT(HDR_CONTENTTYPE_T);   break;
219
-		case 'o': PARSE_COMPACT(HDR_EVENT_T);         break;
220
-		case 'x': PARSE_COMPACT(HDR_SESSIONEXPIRES_T);break;
221
-		case 'a': PARSE_COMPACT(HDR_ACCEPTCONTACT_T); break;
222
-		case 'u': PARSE_COMPACT(HDR_ALLOWEVENTS_T);   break;
223
-		case 'e': PARSE_COMPACT(HDR_CONTENTENCODING_T); break;
224
-		case 'b': PARSE_COMPACT(HDR_REFERREDBY_T);    break;
225
-		case 'j': PARSE_COMPACT(HDR_REJECTCONTACT_T); break;
226
-		case 'd': PARSE_COMPACT(HDR_REQUESTDISPOSITION_T); break;
227
-		case 's': PARSE_COMPACT(HDR_SUBJECT_T);       break;
228
-		case 'r': PARSE_COMPACT(HDR_REFER_TO_T);      break;
229
-		case 'y': PARSE_COMPACT(HDR_IDENTITY_T);      break;
230
-		case 'n': PARSE_COMPACT(HDR_IDENTITY_INFO_T); break;
222
+	/* ensure no character or only white spaces till : */
223
+	for(; p<end; p++) {
224
+		if(*p == ':') {
225
+			/* end of header name */
226
+			break;
227
+		}
228
+		if(*p != ' ' && *p != '\t') {
229
+			/* no white space - bad header name format */
230
+			LM_ERR("invalid header name for [%.*s]\n",
231
+					(int)(end-begin), begin);
232
+			hdr->type = HDR_ERROR_T;
233
+			return begin;
231 234
 		}
232
-		goto other;
233
-        }
234
-
235
-	     /* Double colon hasn't been found yet */
236
- dc_end:
237
-       	p = skip_ws(p, end - p);
238
-	if (*p != ':') {
239
-	        goto other;
240
-	} else {
241
-		hdr->name.len = p - hdr->name.s;
242
-		trim_trailing(&hdr->name);
243
-		return (p + 1);
244 235
 	}
245 236
 
246
-	     /* Unknown header type */
247
- other:
248
-	p = q_memchr(p, ':', end - p);
249
-	if (!p) {        /* No double colon found, error.. */
237
+	if(p == end) {
238
+		/* no : found - emode==0 */
239
+		LM_ERR("invalid end of header name for [%.*s]\n",
240
+				(int)(end-begin), begin);
250 241
 		hdr->type = HDR_ERROR_T;
251
-		hdr->name.s = 0;
252
-		hdr->name.len = 0;
253
-		return 0;
254
-	} else {
255
-		hdr->type = HDR_OTHER_T;
256
-		hdr->name.len = p - hdr->name.s;
257
-		trim_trailing(&hdr->name);
258
-		/*hdr_update_type(hdr);*/
259
-		return (p + 1);
242
+		return begin;
260 243
 	}
244
+
245
+done:
246
+	/* lookup header type */
247
+	if(_ksr_hdr_map_idx[hdr->name.s[0]].idxs >= 0) {
248
+		for(i = _ksr_hdr_map_idx[hdr->name.s[0]].idxs;
249
+					i <= _ksr_hdr_map_idx[hdr->name.s[0]].idxe; i++) {
250
+			if(cmp_hdrname_str(&hdr->name, &_ksr_hdr_map[i].hname) == 0) {
251
+				hdr->type = _ksr_hdr_map[i].htype;
252
+			}
253
+		}
254
+	}
255
+
256
+	LM_DBG("parsed header name [%.*s] type %d\n", hdr->name.len, hdr->name.s,
257
+				hdr->type);
258
+
259
+	return (p+1);
260
+}
261
+
262
+char* parse_hname2(char* const begin, const char* const end, struct hdr_field* const hdr)
263
+{
264
+	return parse_sip_header_name(begin, end, hdr, 0);
261 265
 }
262 266
 
263 267
 /**
264
- * parse_hname2_short() - safer version to parse header name stored in short buffers
265
- *   - parse_hanem2() reads 4 bytes at once, expecting to walk through a buffer
266
- *   that contains more than the header name (e.g., sip msg buf, full header buf
267
- *   with name and body)
268
+ * kept for compatibility of code developed in the past
269
+ * - to be replace with parse_hname2() across the code
268 270
  */
269 271
 char* parse_hname2_short(char* const begin, const char* const end, struct hdr_field* const hdr)
270 272
 {
271
-#define HBUF_MAX_SIZE 256
272
-	char hbuf[HBUF_MAX_SIZE];
273
-	char *p;
274
-
275
-	if(end-begin>=HBUF_MAX_SIZE-4) {
276
-		p = q_memchr(begin, ':', end - begin);
277
-		if(p && p-4> begin) {
278
-			/* header name termination char found and enough space in buffer after it */
279
-			return parse_hname2(begin, end, hdr);
280
-		}
281
-		/* not enough space */
282
-		LM_ERR("not enough space to parse the header name in [%.*s] (%d)\n",
283
-				(int)(end-begin), begin, (int)(end-begin));
284
-		return NULL;
285
-	}
286
-	/* pad with whitespace - tipycal char after the ':' of the header name */
287
-	memset(hbuf, ' ', HBUF_MAX_SIZE);
288
-	memcpy(hbuf, begin, end-begin);
289
-	p = parse_hname2(hbuf, hbuf + 4 + (end-begin), hdr);
290
-	if(!p) {
291
-		LM_ERR("failed to parse the header name in [%.*s] (%d)\n",
292
-				(int)(end-begin), begin, (int)(end-begin));
293
-		return NULL;
294
-	}
295
-	return begin + (p-hbuf);
296
-}
273
+	return parse_sip_header_name(begin, end, hdr, 0);
274
+}
297 275
\ No newline at end of file
Browse code

core: parser - trim trailing whitespaces in header name

Daniel-Constantin Mierla authored on 16/07/2020 07:09:48
Showing 1 changed files
... ...
@@ -27,9 +27,10 @@
27 27
  */
28 28
 
29 29
 #include "../comp_defs.h"
30
+#include "../trim.h"
31
+#include "../ut.h"  /* q_memchr */
30 32
 #include "parse_hname2.h"
31 33
 #include "keys.h"
32
-#include "../ut.h"  /* q_memchr */
33 34
 
34 35
 #define LOWER_BYTE(b) ((b) | 0x20)
35 36
 #define LOWER_DWORD(d) ((d) | 0x20202020)
... ...
@@ -238,6 +239,7 @@ char* parse_hname2(char* const begin, const char* const end, struct hdr_field* c
238 239
 	        goto other;
239 240
 	} else {
240 241
 		hdr->name.len = p - hdr->name.s;
242
+		trim_trailing(&hdr->name);
241 243
 		return (p + 1);
242 244
 	}
243 245
 
... ...
@@ -252,6 +254,7 @@ char* parse_hname2(char* const begin, const char* const end, struct hdr_field* c
252 254
 	} else {
253 255
 		hdr->type = HDR_OTHER_T;
254 256
 		hdr->name.len = p - hdr->name.s;
257
+		trim_trailing(&hdr->name);
255 258
 		/*hdr_update_type(hdr);*/
256 259
 		return (p + 1);
257 260
 	}
Browse code

core, lib, modules: restructured source code tree

- new folder src/ to hold the source code for main project applications
- main.c is in src/
- all core files are subfolder are in src/core/
- modules are in src/modules/
- libs are in src/lib/
- application Makefiles are in src/
- application binary is built in src/ (src/kamailio)

Daniel-Constantin Mierla authored on 07/12/2016 11:03:51
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,293 @@
1
+/*
2
+ * Fast 32-bit Header Field Name Parser
3
+ *
4
+ * Copyright (C) 2001-2003 FhG Fokus
5
+ *
6
+ * This file is part of Kamailio, a free SIP server.
7
+ *
8
+ * Kamailio is free software; you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation; either version 2 of the License, or
11
+ * (at your option) any later version
12
+ *
13
+ * Kamailio is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program; if not, write to the Free Software
20
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21
+ *
22
+ */
23
+
24
+/** Parser :: Fast 32-bit Header Field Name Parser.
25
+ * @file
26
+ * @ingroup parser
27
+ */
28
+
29
+#include "../comp_defs.h"
30
+#include "parse_hname2.h"
31
+#include "keys.h"
32
+#include "../ut.h"  /* q_memchr */
33
+
34
+#define LOWER_BYTE(b) ((b) | 0x20)
35
+#define LOWER_DWORD(d) ((d) | 0x20202020)
36
+
37
+/** Skip all white-chars and return position of the first non-white char.
38
+ */
39
+static inline char* skip_ws(char* p, unsigned int size)
40
+{
41
+	char* end;
42
+
43
+	end = p + size;
44
+	for(; p < end; p++) {
45
+		if ((*p != ' ') && (*p != '\t')) return p;
46
+	}
47
+	return p;
48
+}
49
+
50
+/*! \name 
51
+ * Parser macros
52
+ */
53
+/*@{ */
54
+#include "case_via.h"      /* Via */
55
+#include "case_from.h"     /* From */
56
+#include "case_to.h"       /* To */
57
+#include "case_cseq.h"     /* CSeq */
58
+#include "case_call.h"     /* Call-ID */
59
+#include "case_cont.h"     /* Contact, Content-Type, Content-Length, Content-Purpose,
60
+			    * Content-Action, Content-Disposition */
61
+#include "case_rout.h"     /* Route */
62
+#include "case_max.h"      /* Max-Forwards */
63
+#include "case_reco.h"     /* Record-Route */
64
+#include "case_auth.h"     /* Authorization */
65
+#include "case_expi.h"     /* Expires */
66
+#include "case_prox.h"     /* Proxy-Authorization, Proxy-Require */
67
+#include "case_allo.h"     /* Allow */
68
+#include "case_unsu.h"     /* Unsupported */
69
+#include "case_even.h"     /* Event */
70
+#include "case_sip.h"      /* Sip-If-Match */
71
+#include "case_acce.h"     /* Accept, Accept-Language */
72
+#include "case_orga.h"     /* Organization */
73
+#include "case_prio.h"     /* Priority */
74
+#include "case_subj.h"     /* Subject */
75
+#include "case_user.h"     /* User-Agent */
76
+#include "case_serv.h"     /* Server */
77
+#include "case_supp.h"     /* Supported */
78
+#include "case_dive.h"     /* Diversion */
79
+#include "case_remo.h"     /* Remote-Party-ID */
80
+#include "case_refe.h"     /* Refer-To */
81
+#include "case_sess.h"     /* Session-Expires */
82
+#include "case_reje.h"     /* Reject-Contact */
83
+#include "case_min.h"      /* Min-SE */
84
+#include "case_subs.h"     /* Subscription-State */
85
+#include "case_requ.h"     /* Require */
86
+#include "case_www.h"      /* WWW-Authenticate */
87
+#include "case_date.h"     /* Date */
88
+#include "case_iden.h"     /* Identity, Identity-info */
89
+#include "case_retr.h"     /* Retry-After */
90
+#include "case_path.h"     /* Path */
91
+#include "case_priv.h"
92
+#include "case_reas.h"     /* Reason */
93
+#include "case_p_as.h"     /* P-Asserted-Identity */
94
+#include "case_p_pr.h"     /* P-Preferred-Identity */
95
+