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 54
 							found_user=1;\
55 55
 							error_headers=0; \
56 56
 							state=URI_HOST; \
57
-						}else goto error_bad_char; 
58
-	 
57
+						}else goto error_bad_char 
58
+#define check_host_end \
59
+					case ':': \
60
+						/* found the host */ \
61
+						uri->host.s=s; \
62
+						uri->host.len=p-s; \
63
+						state=URI_PORT; \
64
+						s=p+1; \
65
+						break; \
66
+					case ';': \
67
+						uri->host.s=s; \
68
+						uri->host.len=p-s; \
69
+						state=URI_PARAM; \
70
+						s=p+1; \
71
+						break; \
72
+					case '?': \
73
+						uri->host.s=s; \
74
+						uri->host.len=p-s; \
75
+						state=URI_HEADERS; \
76
+						s=p+1; \
77
+						break; \
78
+					case '&': \
79
+					case '@': \
80
+						goto error_bad_char 
81
+	
59 82
 	end=buf+len;
60 83
 	p=buf+4;
61 84
 	found_user=0;
... ...
@@ -69,9 +93,26 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
69 69
 		     (buf[3]==':') ) ) goto error_bad_uri;
70 70
 	
71 71
 	s=p;
72
-	state=URI_USER;
73 72
 	for(;p<end; p++){
74 73
 		switch(state){
74
+			case URI_INIT:
75
+				switch(*p){
76
+					case '[':
77
+						/* uri =  [ipv6address]... */
78
+						state=URI_HOST6_P;
79
+						s=p;
80
+						break;
81
+					case ']':
82
+						/* invalid, no uri can start with ']' */
83
+					case ':':
84
+						/* the same as above for ':' */
85
+						goto error_bad_char;
86
+					case '@': /* error no user part, or
87
+								 be forgiving and accept it ? */
88
+					default:
89
+						state=URI_USER;
90
+				}
91
+				break; 
75 92
 			case URI_USER:
76 93
 				switch(*p){
77 94
 					case '@':
... ...
@@ -104,6 +145,9 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
104 104
 						s=p+1;
105 105
 						break;
106 106
 						/* almost anything permitted in the user part */
107
+					case '[':
108
+					case ']': /* the user part cannot contain "[]" */
109
+						goto error_bad_char;
107 110
 				}
108 111
 				break;
109 112
 			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 142
 						found_user=1; /*  there is no user part */
143 143
 						s=p+1;
144 144
 						break;
145
+					case '[':
146
+					case ']':
145 147
 					case ':':
146 148
 						goto error_bad_char;
147 149
 				}
148 150
 				break;
149 151
 			case URI_HOST:
150 152
 				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;
153
+					case '[':
154
+						state=URI_HOST6_P;
157 155
 						break;
156
+					case ':': 
158 157
 					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;
158
+					case '?': /* null host name ->invalid */
159
+					case '&':
160
+					case '@': /*chars not allowed in hosts names */
161
+						goto error_bad_host;
162
+					default:
163
+						state=URI_HOST_P;
164
+				}
165
+				break;
166
+			case URI_HOST_P:
167
+				switch(*p){
168
+					check_host_end;
169
+				}
170
+				break;
171
+			case URI_HOST6_END:
172
+				switch(*p){
173
+					check_host_end;
174
+					default: /*no chars allowed after [ipv6] */
175
+						goto error_bad_host;
176
+				}
177
+				break;
178
+			case URI_HOST6_P:
179
+				switch(*p){
180
+					case ']':
181
+						state=URI_HOST6_END;
169 182
 						break;
183
+					case '[':
170 184
 					case '&':
171 185
 					case '@':
172
-						goto error_bad_char;
186
+					case ';':
187
+					case '?':
188
+						goto error_bad_host;
173 189
 				}
174 190
 				break;
175 191
 			case URI_PORT:
... ...
@@ -271,6 +331,8 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
271 271
 	}
272 272
 	/*end of uri */
273 273
 	switch (state){
274
+		case URI_INIT: /* error empy uri */
275
+			goto error_too_short;
274 276
 		case URI_USER:
275 277
 			/* this is the host, it can't be the user */
276 278
 			if (found_user) goto error_bad_uri;
... ...
@@ -287,10 +349,14 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
287 287
 			uri->user.s=0;
288 288
 			uri->user.len=0;
289 289
 			break;
290
-		case URI_HOST:
290
+		case URI_HOST_P:
291
+		case URI_HOST6_END:
291 292
 			uri->host.s=s;
292 293
 			uri->host.len=p-s;
293 294
 			break;
295
+		case URI_HOST: /* error: null host */
296
+		case URI_HOST6_P: /* error: unterminated ipv6 reference*/
297
+			goto error_bad_host;
294 298
 		case URI_PORT:
295 299
 			uri->port.s=s;
296 300
 			uri->port.len=p-s;
... ...
@@ -329,6 +395,11 @@ error_bad_char:
329 329
 			" parsed: <%.*s> (%d) / <%.*s> (%d)\n",
330 330
 			*p, state, (p-buf), buf, (p-buf), len, buf, len);
331 331
 	return -1;
332
+error_bad_host:
333
+	LOG(L_ERR, "ERROR: parse_uri: bad host in uri (error at char %c in"
334
+			" state %d) parsed: <%.*s>(%d) /<%.*s> (%d)\n",
335
+			*p, state, (p-buf), buf, (p-buf), len, buf, len);
336
+	return -1;
332 337
 error_bad_uri:
333 338
 	LOG(L_ERR, "ERROR: parse_uri: bad uri,  state %d"
334 339
 			" parsed: <%.*s> (%d) / <%.*s> (%d)\n",