Browse code

- ipv6 reference parsing support

Andrei Pelinescu-Onciul authored on 10/04/2003 17:44:48
Showing 2 changed files
... ...
@@ -90,6 +90,8 @@ optimizations:
90 90
 tcp stuff:
91 91
 x tcp disable nagle 
92 92
 - tcp locking/atomic ops review
93
+- tcp fix simultaneous connects (ser process is blocked until connect timeouts
94
+ => possible DOS)
93 95
 
94 96
 tm optimizations:
95 97
 
... ...
@@ -20,7 +20,8 @@ struct sip_uri {
20 20
 
21 21
 int parse_uri(char* buf, int len, struct sip_uri* uri)
22 22
 {
23
-	enum states  {	URI_INIT, URI_USER, URI_PASSWORD, URI_HOST, URI_PORT,
23
+	enum states  {	URI_INIT, URI_USER, URI_PASSWORD, URI_HOST, URI_HOST_P,
24
+					URI_HOST6_P, URI_HOST6_END, URI_PORT,
24 25
 					URI_PARAM, URI_HEADERS };
25 26
 	enum states state;
26 27
 	char* s;
... ...
@@ -54,8 +55,31 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
54 55
 							found_user=1;\
55 56
 							error_headers=0; \
56 57
 							state=URI_HOST; \
57
-						}else goto error_bad_char; 
58
-	 
58
+						}else goto error_bad_char 
59
+#define check_host_end \
60
+					case ':': \
61
+						/* found the host */ \
62
+						uri->host.s=s; \
63
+						uri->host.len=p-s; \
64
+						state=URI_PORT; \
65
+						s=p+1; \
66
+						break; \
67
+					case ';': \
68
+						uri->host.s=s; \
69
+						uri->host.len=p-s; \
70
+						state=URI_PARAM; \
71
+						s=p+1; \
72
+						break; \
73
+					case '?': \
74
+						uri->host.s=s; \
75
+						uri->host.len=p-s; \
76
+						state=URI_HEADERS; \
77
+						s=p+1; \
78
+						break; \
79
+					case '&': \
80
+					case '@': \
81
+						goto error_bad_char 
82
+	
59 83
 	end=buf+len;
60 84
 	p=buf+4;
61 85
 	found_user=0;
... ...
@@ -69,9 +93,26 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
69 93
 		     (buf[3]==':') ) ) goto error_bad_uri;
70 94
 	
71 95
 	s=p;
72
-	state=URI_USER;
73 96
 	for(;p<end; p++){
74 97
 		switch(state){
98
+			case URI_INIT:
99
+				switch(*p){
100
+					case '[':
101
+						/* uri =  [ipv6address]... */
102
+						state=URI_HOST6_P;
103
+						s=p;
104
+						break;
105
+					case ']':
106
+						/* invalid, no uri can start with ']' */
107
+					case ':':
108
+						/* the same as above for ':' */
109
+						goto error_bad_char;
110
+					case '@': /* error no user part, or
111
+								 be forgiving and accept it ? */
112
+					default:
113
+						state=URI_USER;
114
+				}
115
+				break; 
75 116
 			case URI_USER:
76 117
 				switch(*p){
77 118
 					case '@':
... ...
@@ -104,6 +145,9 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
104 145
 						s=p+1;
105 146
 						break;
106 147
 						/* almost anything permitted in the user part */
148
+					case '[':
149
+					case ']': /* the user part cannot contain "[]" */
150
+						goto error_bad_char;
107 151
 				}
108 152
 				break;
109 153
 			case URI_PASSWORD: /* this can also be the port (missing user)*/
... ...
@@ -142,34 +186,50 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
142 186
 						found_user=1; /*  there is no user part */
143 187
 						s=p+1;
144 188
 						break;
189
+					case '[':
190
+					case ']':
145 191
 					case ':':
146 192
 						goto error_bad_char;
147 193
 				}
148 194
 				break;
149 195
 			case URI_HOST:
150 196
 				switch(*p){
151
-					case ':':
152
-						/* found the host */
153
-						uri->host.s=s;
154
-						uri->host.len=p-s;
155
-						state=URI_PORT;
156
-						s=p+1;
197
+					case '[':
198
+						state=URI_HOST6_P;
157 199
 						break;
200
+					case ':': 
158 201
 					case ';':
159
-						uri->host.s=s;
160
-						uri->host.len=p-s;
161
-						state=URI_PARAM;
162
-						s=p+1;
163
-						break;
164
-					case '?':
165
-						uri->host.s=s;
166
-						uri->host.len=p-s;
167
-						state=URI_HEADERS;
168
-						s=p+1;
202
+					case '?': /* null host name ->invalid */
203
+					case '&':
204
+					case '@': /*chars not allowed in hosts names */
205
+						goto error_bad_host;
206
+					default:
207
+						state=URI_HOST_P;
208
+				}
209
+				break;
210
+			case URI_HOST_P:
211
+				switch(*p){
212
+					check_host_end;
213
+				}
214
+				break;
215
+			case URI_HOST6_END:
216
+				switch(*p){
217
+					check_host_end;
218
+					default: /*no chars allowed after [ipv6] */
219
+						goto error_bad_host;
220
+				}
221
+				break;
222
+			case URI_HOST6_P:
223
+				switch(*p){
224
+					case ']':
225
+						state=URI_HOST6_END;
169 226
 						break;
227
+					case '[':
170 228
 					case '&':
171 229
 					case '@':
172
-						goto error_bad_char;
230
+					case ';':
231
+					case '?':
232
+						goto error_bad_host;
173 233
 				}
174 234
 				break;
175 235
 			case URI_PORT:
... ...
@@ -271,6 +331,8 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
271 331
 	}
272 332
 	/*end of uri */
273 333
 	switch (state){
334
+		case URI_INIT: /* error empy uri */
335
+			goto error_too_short;
274 336
 		case URI_USER:
275 337
 			/* this is the host, it can't be the user */
276 338
 			if (found_user) goto error_bad_uri;
... ...
@@ -287,10 +349,14 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
287 349
 			uri->user.s=0;
288 350
 			uri->user.len=0;
289 351
 			break;
290
-		case URI_HOST:
352
+		case URI_HOST_P:
353
+		case URI_HOST6_END:
291 354
 			uri->host.s=s;
292 355
 			uri->host.len=p-s;
293 356
 			break;
357
+		case URI_HOST: /* error: null host */
358
+		case URI_HOST6_P: /* error: unterminated ipv6 reference*/
359
+			goto error_bad_host;
294 360
 		case URI_PORT:
295 361
 			uri->port.s=s;
296 362
 			uri->port.len=p-s;
... ...
@@ -329,6 +395,11 @@ error_bad_char:
329 395
 			" parsed: <%.*s> (%d) / <%.*s> (%d)\n",
330 396
 			*p, state, (p-buf), buf, (p-buf), len, buf, len);
331 397
 	return -1;
398
+error_bad_host:
399
+	LOG(L_ERR, "ERROR: parse_uri: bad host in uri (error at char %c in"
400
+			" state %d) parsed: <%.*s>(%d) /<%.*s> (%d)\n",
401
+			*p, state, (p-buf), buf, (p-buf), len, buf, len);
402
+	return -1;
332 403
 error_bad_uri:
333 404
 	LOG(L_ERR, "ERROR: parse_uri: bad uri,  state %d"
334 405
 			" parsed: <%.*s> (%d) / <%.*s> (%d)\n",