Browse code

- fixed a memroy leak (rewritehost/uri/etc.) - added forward to uri support (forward(uri:host, uri:port) ). - improved free_lump_list speed (could be dangerous)

Andrei Pelinescu-Onciul authored on 26/10/2001 20:28:55
Showing 15 changed files
... ...
@@ -24,6 +24,7 @@ Configuration files:
24 24
 		- fork
25 25
 		- children_no
26 26
 		- log_stderror
27
+		- loadmodule "path/modulename"
27 28
 		...
28 29
 
29 30
 	Logical expressions [missing]
... ...
@@ -51,6 +52,10 @@ Configuration files:
51 51
 		- log
52 52
 		- exec
53 53
 		- route/goto
54
-		- drop
54
+		- drop/break
55
+		- if {} else{}
56
+	Modules:
57
+		- loadmodule "..."
58
+		- commands registered by modules
55 59
 
56 60
 
... ...
@@ -41,6 +41,7 @@ int do_action(struct action* a, struct sip_msg* msg)
41 41
 	int len;
42 42
 	int user;
43 43
 	struct sip_uri uri;
44
+	unsigned short port;
44 45
 
45 46
 	ret=E_BUG;
46 47
 	switch (a->type){
... ...
@@ -48,14 +49,54 @@ int do_action(struct action* a, struct sip_msg* msg)
48 48
 				ret=0;
49 49
 			break;
50 50
 		case FORWARD_T:
51
-			if ((a->p1_type!= PROXY_ST)|(a->p2_type!=NUMBER_ST)){
51
+			if (a->p1_type==URIHOST_ST){
52
+				/*parse uri*/
53
+				tmp=(msg->new_uri)?msg->new_uri:
54
+						msg->first_line.u.request.uri;
55
+				if (parse_uri(tmp, strlen(tmp), &uri)<0){
56
+					LOG(L_ERR, "ERROR: do_action: forward: bad_uri <%s>,"
57
+								" dropping packet\n",tmp);
58
+					ret=E_UNSPEC;
59
+					break;
60
+				}
61
+				switch (a->p2_type){
62
+					case URIPORT_ST:
63
+									if (uri.port){
64
+										port=strtol(uri.port,&end,10);
65
+										if ((end)&&(*end)){
66
+											LOG(L_ERR, "ERROR: do_action: "
67
+													"forward: bad port in "
68
+													"uri: <%s>\n", uri.port);
69
+											ret=E_UNSPEC;
70
+											free_uri(&uri);
71
+											goto skip;
72
+										}
73
+									}else port=SIP_PORT;
74
+									break;
75
+					case NUMBER_ST:
76
+									port=a->p2.number;
77
+									break;
78
+					default:
79
+							LOG(L_CRIT, "BUG: do_action bad forward 2nd"
80
+										" param type (%d)\n", a->p2_type);
81
+							free_uri(&uri);
82
+							goto skip;
83
+				}
84
+				/* create a temporary proxy*/
85
+				p=mk_proxy(uri.host, port);
86
+				ret=forward_request(msg, p);
87
+				free_uri(&uri);
88
+				free_proxy(p); /* frees only p content, not p itself */
89
+				free(p);
90
+				if (ret>=0) ret=1;
91
+			}else if ((a->p1_type==PROXY_ST) && (a->p2_type==NUMBER_ST)){
92
+				ret=forward_request(msg,(struct proxy_l*)a->p1.data);
93
+				if (ret>=0) ret=1;
94
+			}else{
52 95
 				LOG(L_CRIT, "BUG: do_action: bad forward() types %d, %d\n",
53 96
 						a->p1_type, a->p2_type);
54 97
 				ret=E_BUG;
55
-				break;
56 98
 			}
57
-			ret=forward_request(msg, (struct proxy_l*)a->p1.data);
58
-			if (ret>=0) ret=1;
59 99
 			break;
60 100
 		case SEND_T:
61 101
 			to=(struct sockaddr_in*) malloc(sizeof(struct sockaddr_in));
... ...
@@ -79,6 +120,8 @@ int do_action(struct action* a, struct sip_msg* msg)
79 79
 			if (p->ok==0){
80 80
 				if (p->host.h_addr_list[p->addr_idx+1])
81 81
 					p->addr_idx++;
82
+				else 
83
+					p->addr_idx=0;
82 84
 				p->ok=1;
83 85
 			}
84 86
 			to->sin_addr.s_addr=*((long*)p->host.h_addr_list[p->addr_idx]);
... ...
@@ -186,6 +229,7 @@ int do_action(struct action* a, struct sip_msg* msg)
186 186
 					LOG(L_ERR, "ERROR: do_action: memory allocation "
187 187
 								" failure\n");
188 188
 					ret=E_OUT_OF_MEM;
189
+					free_uri(&uri);
189 190
 					break;
190 191
 				}
191 192
 				end=new_uri+MAX_URI_SIZE;
... ...
@@ -255,6 +299,7 @@ int do_action(struct action* a, struct sip_msg* msg)
255 255
 				/* copy it to the msg */
256 256
 				if (msg->new_uri) free(msg->new_uri);
257 257
 				msg->new_uri=new_uri;
258
+				free_uri(&uri);
258 259
 				ret=1;
259 260
 				break;
260 261
 		case IF_T:
... ...
@@ -287,10 +332,12 @@ int do_action(struct action* a, struct sip_msg* msg)
287 287
 		default:
288 288
 			LOG(L_CRIT, "BUG: do_action: unknown type %d\n", a->type);
289 289
 	}
290
+skip:
290 291
 	return ret;
291 292
 	
292 293
 error_uri:
293 294
 	LOG(L_ERR, "ERROR: do_action: set*: uri too long\n");
295
+	free_uri(&uri);
294 296
 	if (new_uri) free(new_uri);
295 297
 	return E_UNSPEC;
296 298
 }
... ...
@@ -321,7 +368,8 @@ int run_actions(struct action* a, struct sip_msg* msg)
321 321
 	for (t=a; t!=0; t=t->next){
322 322
 		ret=do_action(t, msg);
323 323
 		if(ret==0) break;
324
-		else if (ret<0){ ret=-1; goto error; }
324
+		/* ignore errors */
325
+		/*else if (ret<0){ ret=-1; goto error; }*/
325 326
 	}
326 327
 	
327 328
 	rec_lev--;
... ...
@@ -55,6 +55,10 @@ SET_URI			"rewriteuri"|"seturi"
55 55
 IF				"if"
56 56
 ELSE			"else"
57 57
 
58
+/*ACTION LVALUES*/
59
+URIHOST			"uri:host"
60
+URIPORT			"uri:port"
61
+
58 62
 
59 63
 /* condition keywords */
60 64
 METHOD	method
... ...
@@ -134,6 +138,9 @@ EAT_ABLE	[\ \t\b\r]
134 134
 <INITIAL>{IF}	{ count(); yylval.strval=yytext; return IF; }
135 135
 <INITIAL>{ELSE}	{ count(); yylval.strval=yytext; return ELSE; }
136 136
 
137
+<INITIAL>{URIHOST}	{ count(); yylval.strval=yytext; return URIHOST; }
138
+<INITIAL>{URIPORT}	{ count(); yylval.strval=yytext; return URIPORT; }
139
+
137 140
 <INITIAL>{METHOD}	{ count(); yylval.strval=yytext; return METHOD; }
138 141
 <INITIAL>{URI}	{ count(); yylval.strval=yytext; return URI; }
139 142
 <INITIAL>{SRCIP}	{ count(); yylval.strval=yytext; return SRCIP; }
... ...
@@ -199,7 +206,7 @@ EAT_ABLE	[\ \t\b\r]
199 199
 						yyleng--; addstr(yytext, &str); }
200 200
 <STRING1>\\r		{ count(); yytext[yyleng-2]='\r';yytext[yyleng-1]=0; 
201 201
 						yyleng--; addstr(yytext, &str); }
202
-<STRING1>\\g		{ count(); yytext[yyleng-2]='\g';yytext[yyleng-1]=0; 
202
+<STRING1>\\a		{ count(); yytext[yyleng-2]='\a';yytext[yyleng-1]=0; 
203 203
 						yyleng--; addstr(yytext, &str); }
204 204
 <STRING1>\\t		{ count(); yytext[yyleng-2]='\t';yytext[yyleng-1]=0; 
205 205
 						yyleng--; addstr(yytext, &str); }
... ...
@@ -57,6 +57,8 @@ void* f_tmp;
57 57
 %token SET_URI
58 58
 %token IF
59 59
 %token ELSE
60
+%token URIHOST
61
+%token URIPORT
60 62
 
61 63
 %token METHOD
62 64
 %token URI
... ...
@@ -449,6 +451,29 @@ cmd:		FORWARD LPAREN host RPAREN	{ $$=mk_action(	FORWARD_T,
449 449
 																 (void*)$3,
450 450
 																(void*)$5);
451 451
 												  }
452
+		| FORWARD LPAREN URIHOST COMMA URIPORT RPAREN {
453
+													$$=mk_action(FORWARD_T,
454
+																 URIHOST_ST,
455
+																 URIPORT_ST,
456
+																0,
457
+																0);
458
+													}
459
+													
460
+									
461
+		| FORWARD LPAREN URIHOST COMMA NUMBER RPAREN {
462
+													$$=mk_action(FORWARD_T,
463
+																 URIHOST_ST,
464
+																 NUMBER_ST,
465
+																0,
466
+																(void*)$5);
467
+													}
468
+		| FORWARD LPAREN URIHOST RPAREN {
469
+													$$=mk_action(FORWARD_T,
470
+																 URIHOST_ST,
471
+																 NUMBER_ST,
472
+																0,
473
+																0);
474
+										}
452 475
 		| FORWARD error { $$=0; yyerror("missing '(' or ')' ?"); }
453 476
 		| FORWARD LPAREN error RPAREN { $$=0; yyerror("bad forward"
454 477
 										"argument"); }
... ...
@@ -186,14 +186,30 @@ void free_lump(struct lump* lmp)
186 186
 
187 187
 void free_lump_list(struct lump* l)
188 188
 {
189
-	struct lump* t, *crt;
189
+	struct lump* t, *r, *foo,*crt;
190 190
 	t=l;
191 191
 	while(t){
192 192
 		crt=t;
193 193
 		t=t->next;
194
-		/* dangerous recursive clean*/
194
+	/*
195
+		 dangerous recursive clean
195 196
 		if (crt->before) free_lump_list(crt->before);
196 197
 		if (crt->after)  free_lump_list(crt->after);
198
+	*/
199
+		/* no more recursion, clean after and before and that's it */
200
+		r=crt->before;
201
+		while(r){
202
+			foo=r; r=r->before;
203
+			free_lump(foo);
204
+			free(foo);
205
+		}
206
+		r=crt->after;
207
+		while(r){
208
+			foo=r; r=r->after;
209
+			free_lump(foo);
210
+			free(foo);
211
+		}
212
+		
197 213
 		/*clean current elem*/
198 214
 		free_lump(crt);
199 215
 		free(crt);
... ...
@@ -142,8 +142,6 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p)
142 142
 	new_len=len;
143 143
 	s_offset=0;
144 144
 	for(t=msg->add_rm;t;t=t->next){
145
-		DBG("t=%x, op=%d, offset=%x, len=%d, s_offset=%x\n",
146
-				t, t->op, t->u.offset, t->len, s_offset);
147 145
 		for(r=t->before;r;r=r->before){
148 146
 			switch(r->op){
149 147
 				case LUMP_ADD:
... ...
@@ -162,14 +160,11 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p)
162 162
 			case LUMP_DEL:
163 163
 				/* fix overlapping deleted zones */
164 164
 				if (t->u.offset < s_offset){
165
-					DBG( "overlapping DEL offsets (%d,%d(%d)), fixing...\n",
166
-						 s_offset, t->u.offset, t->len);
167 165
 					/* change len */
168 166
 					if (t->len>s_offset-t->u.offset) 
169 167
 							t->len-=s_offset-t->u.offset;
170 168
 					else t->len=0;
171 169
 					t->u.offset=s_offset;
172
-					DBG("fixed to %d(%d)\n", t->u.offset, t->len);
173 170
 				}
174 171
 				s_offset=t->u.offset+t->len;
175 172
 				new_len-=t->len;
... ...
@@ -177,9 +172,7 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p)
177 177
 			case LUMP_NOP:
178 178
 				/* fix offset if overlapping on a deleted zone */
179 179
 				if (t->u.offset < s_offset){
180
-					DBG("overlapping zones (%d,%d)\n", s_offset, t->u.offset);
181 180
 					t->u.offset=s_offset;
182
-					DBG("fixed to %d\n", t->u.offset);
183 181
 				}else
184 182
 					s_offset=t->u.offset;
185 183
 				/* do nothing */
... ...
@@ -226,8 +219,6 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p)
226 226
 	}
227 227
 /* copy msg adding/removing lumps */
228 228
 	for (t=msg->add_rm;t;t=t->next){
229
-		DBG(" t=%x, op=%d, offset=%x, len=%d, s_offset=%x\n",
230
-				t, t->op, t->u.offset, t->len, s_offset);
231 229
 		switch(t->op){
232 230
 			case LUMP_ADD:
233 231
 				/* just add it here! */
... ...
@@ -30,7 +30,7 @@
30 30
 
31 31
 
32 32
 static char id[]="@(#) $Id$";
33
-static char version[]="ser 0.8.2";
33
+static char version[]="ser 0.8.3";
34 34
 static char flags[]="NOCR:"
35 35
 #ifdef NOCR
36 36
 "On"
... ...
@@ -382,16 +382,6 @@ error:
382 382
 }
383 383
 
384 384
 
385
-			
386
-
387
-			
388
-			
389
-	
390
-		
391
-	
392
-	
393
-
394
-
395 385
 
396 386
 /* parses a via body, returns next via (for compact vias) & fills vb,
397 387
  * the buffer should be null terminated! */
... ...
@@ -686,3 +676,16 @@ error:
686 686
 	return -1;
687 687
 }
688 688
 
689
+
690
+
691
+void free_uri(struct sip_uri* u)
692
+{
693
+	if (u){
694
+		if (u->user) free(u->user);
695
+		if (u->passwd) free(u->passwd);
696
+		if (u->host) free(u->host);
697
+		if (u->port) free(u->port);
698
+		if (u->params) free(u->params);
699
+		if (u->headers) free(u->headers);
700
+	}
701
+}
... ...
@@ -102,6 +102,7 @@ char* parse_hostport(char* buf, char** host, short int* port);
102 102
 char* parse_via_body(char* buffer,unsigned int len, struct via_body * vb);
103 103
 int parse_msg(char* buf, unsigned int len, struct sip_msg* msg);
104 104
 int parse_uri(char *buf, int len, struct sip_uri* uri);
105
+void free_uri(struct sip_uri* u);
105 106
 
106 107
 
107 108
 
... ...
@@ -112,15 +112,52 @@ error:
112 112
 
113 113
 
114 114
 
115
+void free_hostent(struct hostent *dst)
116
+{
117
+	int r;
118
+	if (dst->h_name) free(dst->h_name);
119
+	if (dst->h_aliases){
120
+		for(r=0; dst->h_aliases[r]; r++)	free(dst->h_aliases[r]);
121
+		free(dst->h_aliases[r]);
122
+		free(dst->h_aliases);
123
+	}
124
+	if (dst->h_addr_list){
125
+		for (r=0; dst->h_addr_list[r];r++) free(dst->h_addr_list[r]);
126
+		free(dst->h_addr_list[r]);
127
+		free(dst->h_addr_list);
128
+	}
129
+}
130
+
131
+
132
+
133
+
115 134
 struct proxy_l* add_proxy(char* name, unsigned short port)
116 135
 {
117 136
 	struct proxy_l* p;
118 137
 	struct hostent* he;
119 138
 	
120 139
 	if ((p=find_proxy(name, port))!=0) return p;
140
+	if ((p=mk_proxy(name, port))==0) goto error;
141
+	/* add p to the proxy list */
142
+	p->next=proxies;
143
+	proxies=p;
144
+	return p;
145
+
146
+error:
147
+	return 0;
148
+}
149
+
150
+
151
+
152
+/* same as add_proxy, but it doesn't add the proxy to the list*/
153
+struct proxy_l* mk_proxy(char* name, unsigned short port)
154
+{
155
+	struct proxy_l* p;
156
+	struct hostent* he;
157
+	
121 158
 	p=(struct proxy_l*) malloc(sizeof(struct proxy_l));
122 159
 	if (p==0){
123
-		LOG(L_CRIT, "ERROR: add_proxy: memory allocation failure\n");
160
+		LOG(L_CRIT, "ERROR: mk_proxy: memory allocation failure\n");
124 161
 		goto error;
125 162
 	}
126 163
 	memset(p,0,sizeof(struct proxy_l));
... ...
@@ -128,7 +165,7 @@ struct proxy_l* add_proxy(char* name, unsigned short port)
128 128
 	p->port=port;
129 129
 	he=gethostbyname(name);
130 130
 	if (he==0){
131
-		LOG(L_CRIT, "ERROR: add_proxy: could not resolve hostname:"
131
+		LOG(L_CRIT, "ERROR: mk_proxy: could not resolve hostname:"
132 132
 					" \"%s\"\n", name);
133 133
 		free(p);
134 134
 		goto error;
... ...
@@ -138,12 +175,14 @@ struct proxy_l* add_proxy(char* name, unsigned short port)
138 138
 		goto error;
139 139
 	}
140 140
 	p->ok=1;
141
-	/* add p to the proxy list */
142
-	p->next=proxies;
143
-	proxies=p;
144 141
 	return p;
145
-
146 142
 error:
147 143
 	return 0;
148 144
 }
149 145
 
146
+
147
+
148
+void free_proxy(struct proxy_l* p)
149
+{
150
+	if (p) free_hostent(&p->host);
151
+}
... ...
@@ -28,6 +28,8 @@ struct proxy_l{
28 28
 extern struct proxy_l* proxies;
29 29
 
30 30
 struct proxy_l* add_proxy(char* name, unsigned short port);
31
+struct proxy_l* mk_proxy(char* name, unsigned short port);
32
+void free_proxy(struct proxy_l* p);
31 33
 
32 34
 
33 35
 #endif
... ...
@@ -135,6 +135,8 @@ static int fix_actions(struct action* a)
135 135
 							t->p1.data=p;
136 136
 							t->p1_type=PROXY_ST;
137 137
 							break;
138
+						case URIHOST_ST:
139
+							break;
138 140
 						default:
139 141
 							LOG(L_CRIT, "BUG: fix_actions: invalid type"
140 142
 									"%d (should be string or number)\n",
... ...
@@ -178,11 +180,15 @@ static int fix_actions(struct action* a)
178 178
 							mod->exports->cmd_names[r]);
179 179
 					if (mod->exports->fixup_pointers[r]){
180 180
 						if (mod->exports->param_no[r]>0){
181
-							ret=mod->exports->fixup_pointers[r](&t->p2.data,1);
181
+							ret=mod->exports->fixup_pointers[r](&t->p2.data,
182
+																1);
183
+							t->p2_type=MODFIXUP_ST;
182 184
 							if (ret<0) return ret;
183 185
 						}
184 186
 						if (mod->exports->param_no[r]>1){
185
-							ret=mod->exports->fixup_pointers[r](&t->p3.data,2);
187
+							ret=mod->exports->fixup_pointers[r](&t->p3.data,
188
+																2);
189
+							t->p3_type=MODFIXUP_ST;
186 190
 							if (ret<0) return ret;
187 191
 						}
188 192
 					}
... ...
@@ -15,7 +15,7 @@ enum { FORWARD_T=1, SEND_T, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T,
15 15
 		SET_HOST_T, SET_HOSTPORT_T, SET_USER_T, SET_USERPASS_T, 
16 16
 		SET_PORT_T, SET_URI_T, IF_T, MODULE_T };
17 17
 enum { NOSUBTYPE=0, STRING_ST, NET_ST, NUMBER_ST, IP_ST, RE_ST, PROXY_ST,
18
-		EXPR_ST, ACTIONS_ST, CMDF_ST };
18
+		EXPR_ST, ACTIONS_ST, CMDF_ST, MODFIXUP_ST, URIHOST_ST, URIPORT_ST };
19 19
 
20 20
 	
21 21
 struct expr{
22 22
new file mode 100644
... ...
@@ -0,0 +1,5 @@
0
+INVITE sip:andrei@localhost:5061;a=b?c=d SIP/2.0
1
+Via: SIP/2.0/UDP localhost
2
+
3
+
4
+
0 5
new file mode 100644
... ...
@@ -0,0 +1,17 @@
0
+debug=9          # debug level (cmd line: -dddddddddd)
1
+check_via=yes     # (cmd. line: -v)
2
+dns=on           # (cmd. line: -r)
3
+rev_dns=yes      # (cmd. line: -R)
4
+fork=no          # (cmd. line: -D)
5
+log_stderror=yes # (cmd line: -E)
6
+# for more info: sip_router -h
7
+
8
+#modules
9
+loadmodule "modules/print/print.so"
10
+
11
+route{
12
+	#rewritehost("127.0.0.1");
13
+	print("trying forward to uri");
14
+	forward(uri:host,uri:port);
15
+	print("after forward");
16
+}