... | ... |
@@ -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 | 52 |
- log |
52 | 53 |
- exec |
53 | 54 |
- route/goto |
54 |
- - drop |
|
55 |
+ - drop/break |
|
56 |
+ - if {} else{} |
|
57 |
+ Modules: |
|
58 |
+ - loadmodule "..." |
|
59 |
+ - commands registered by modules |
|
55 | 60 |
|
56 | 61 |
|
... | ... |
@@ -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 | 49 |
ret=0; |
49 | 50 |
break; |
50 | 51 |
case FORWARD_T: |
51 |
- if ((a->p1_type!= PROXY_ST)|(a->p2_type!=NUMBER_ST)){ |
|
52 |
+ if (a->p1_type==URIHOST_ST){ |
|
53 |
+ /*parse uri*/ |
|
54 |
+ tmp=(msg->new_uri)?msg->new_uri: |
|
55 |
+ msg->first_line.u.request.uri; |
|
56 |
+ if (parse_uri(tmp, strlen(tmp), &uri)<0){ |
|
57 |
+ LOG(L_ERR, "ERROR: do_action: forward: bad_uri <%s>," |
|
58 |
+ " dropping packet\n",tmp); |
|
59 |
+ ret=E_UNSPEC; |
|
60 |
+ break; |
|
61 |
+ } |
|
62 |
+ switch (a->p2_type){ |
|
63 |
+ case URIPORT_ST: |
|
64 |
+ if (uri.port){ |
|
65 |
+ port=strtol(uri.port,&end,10); |
|
66 |
+ if ((end)&&(*end)){ |
|
67 |
+ LOG(L_ERR, "ERROR: do_action: " |
|
68 |
+ "forward: bad port in " |
|
69 |
+ "uri: <%s>\n", uri.port); |
|
70 |
+ ret=E_UNSPEC; |
|
71 |
+ free_uri(&uri); |
|
72 |
+ goto skip; |
|
73 |
+ } |
|
74 |
+ }else port=SIP_PORT; |
|
75 |
+ break; |
|
76 |
+ case NUMBER_ST: |
|
77 |
+ port=a->p2.number; |
|
78 |
+ break; |
|
79 |
+ default: |
|
80 |
+ LOG(L_CRIT, "BUG: do_action bad forward 2nd" |
|
81 |
+ " param type (%d)\n", a->p2_type); |
|
82 |
+ free_uri(&uri); |
|
83 |
+ goto skip; |
|
84 |
+ } |
|
85 |
+ /* create a temporary proxy*/ |
|
86 |
+ p=mk_proxy(uri.host, port); |
|
87 |
+ ret=forward_request(msg, p); |
|
88 |
+ free_uri(&uri); |
|
89 |
+ free_proxy(p); /* frees only p content, not p itself */ |
|
90 |
+ free(p); |
|
91 |
+ if (ret>=0) ret=1; |
|
92 |
+ }else if ((a->p1_type==PROXY_ST) && (a->p2_type==NUMBER_ST)){ |
|
93 |
+ ret=forward_request(msg,(struct proxy_l*)a->p1.data); |
|
94 |
+ if (ret>=0) ret=1; |
|
95 |
+ }else{ |
|
52 | 96 |
LOG(L_CRIT, "BUG: do_action: bad forward() types %d, %d\n", |
53 | 97 |
a->p1_type, a->p2_type); |
54 | 98 |
ret=E_BUG; |
55 |
- break; |
|
56 | 99 |
} |
57 |
- ret=forward_request(msg, (struct proxy_l*)a->p1.data); |
|
58 |
- if (ret>=0) ret=1; |
|
59 | 100 |
break; |
60 | 101 |
case SEND_T: |
61 | 102 |
to=(struct sockaddr_in*) malloc(sizeof(struct sockaddr_in)); |
... | ... |
@@ -79,6 +120,8 @@ int do_action(struct action* a, struct sip_msg* msg) |
79 | 120 |
if (p->ok==0){ |
80 | 121 |
if (p->host.h_addr_list[p->addr_idx+1]) |
81 | 122 |
p->addr_idx++; |
123 |
+ else |
|
124 |
+ p->addr_idx=0; |
|
82 | 125 |
p->ok=1; |
83 | 126 |
} |
84 | 127 |
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 | 229 |
LOG(L_ERR, "ERROR: do_action: memory allocation " |
187 | 230 |
" failure\n"); |
188 | 231 |
ret=E_OUT_OF_MEM; |
232 |
+ free_uri(&uri); |
|
189 | 233 |
break; |
190 | 234 |
} |
191 | 235 |
end=new_uri+MAX_URI_SIZE; |
... | ... |
@@ -255,6 +299,7 @@ int do_action(struct action* a, struct sip_msg* msg) |
255 | 299 |
/* copy it to the msg */ |
256 | 300 |
if (msg->new_uri) free(msg->new_uri); |
257 | 301 |
msg->new_uri=new_uri; |
302 |
+ free_uri(&uri); |
|
258 | 303 |
ret=1; |
259 | 304 |
break; |
260 | 305 |
case IF_T: |
... | ... |
@@ -287,10 +332,12 @@ int do_action(struct action* a, struct sip_msg* msg) |
287 | 332 |
default: |
288 | 333 |
LOG(L_CRIT, "BUG: do_action: unknown type %d\n", a->type); |
289 | 334 |
} |
335 |
+skip: |
|
290 | 336 |
return ret; |
291 | 337 |
|
292 | 338 |
error_uri: |
293 | 339 |
LOG(L_ERR, "ERROR: do_action: set*: uri too long\n"); |
340 |
+ free_uri(&uri); |
|
294 | 341 |
if (new_uri) free(new_uri); |
295 | 342 |
return E_UNSPEC; |
296 | 343 |
} |
... | ... |
@@ -321,7 +368,8 @@ int run_actions(struct action* a, struct sip_msg* msg) |
321 | 368 |
for (t=a; t!=0; t=t->next){ |
322 | 369 |
ret=do_action(t, msg); |
323 | 370 |
if(ret==0) break; |
324 |
- else if (ret<0){ ret=-1; goto error; } |
|
371 |
+ /* ignore errors */ |
|
372 |
+ /*else if (ret<0){ ret=-1; goto error; }*/ |
|
325 | 373 |
} |
326 | 374 |
|
327 | 375 |
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 | 138 |
<INITIAL>{IF} { count(); yylval.strval=yytext; return IF; } |
135 | 139 |
<INITIAL>{ELSE} { count(); yylval.strval=yytext; return ELSE; } |
136 | 140 |
|
141 |
+<INITIAL>{URIHOST} { count(); yylval.strval=yytext; return URIHOST; } |
|
142 |
+<INITIAL>{URIPORT} { count(); yylval.strval=yytext; return URIPORT; } |
|
143 |
+ |
|
137 | 144 |
<INITIAL>{METHOD} { count(); yylval.strval=yytext; return METHOD; } |
138 | 145 |
<INITIAL>{URI} { count(); yylval.strval=yytext; return URI; } |
139 | 146 |
<INITIAL>{SRCIP} { count(); yylval.strval=yytext; return SRCIP; } |
... | ... |
@@ -199,7 +206,7 @@ EAT_ABLE [\ \t\b\r] |
199 | 206 |
yyleng--; addstr(yytext, &str); } |
200 | 207 |
<STRING1>\\r { count(); yytext[yyleng-2]='\r';yytext[yyleng-1]=0; |
201 | 208 |
yyleng--; addstr(yytext, &str); } |
202 |
-<STRING1>\\g { count(); yytext[yyleng-2]='\g';yytext[yyleng-1]=0; |
|
209 |
+<STRING1>\\a { count(); yytext[yyleng-2]='\a';yytext[yyleng-1]=0; |
|
203 | 210 |
yyleng--; addstr(yytext, &str); } |
204 | 211 |
<STRING1>\\t { count(); yytext[yyleng-2]='\t';yytext[yyleng-1]=0; |
205 | 212 |
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 | 451 |
(void*)$3, |
450 | 452 |
(void*)$5); |
451 | 453 |
} |
454 |
+ | FORWARD LPAREN URIHOST COMMA URIPORT RPAREN { |
|
455 |
+ $$=mk_action(FORWARD_T, |
|
456 |
+ URIHOST_ST, |
|
457 |
+ URIPORT_ST, |
|
458 |
+ 0, |
|
459 |
+ 0); |
|
460 |
+ } |
|
461 |
+ |
|
462 |
+ |
|
463 |
+ | FORWARD LPAREN URIHOST COMMA NUMBER RPAREN { |
|
464 |
+ $$=mk_action(FORWARD_T, |
|
465 |
+ URIHOST_ST, |
|
466 |
+ NUMBER_ST, |
|
467 |
+ 0, |
|
468 |
+ (void*)$5); |
|
469 |
+ } |
|
470 |
+ | FORWARD LPAREN URIHOST RPAREN { |
|
471 |
+ $$=mk_action(FORWARD_T, |
|
472 |
+ URIHOST_ST, |
|
473 |
+ NUMBER_ST, |
|
474 |
+ 0, |
|
475 |
+ 0); |
|
476 |
+ } |
|
452 | 477 |
| FORWARD error { $$=0; yyerror("missing '(' or ')' ?"); } |
453 | 478 |
| FORWARD LPAREN error RPAREN { $$=0; yyerror("bad forward" |
454 | 479 |
"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 | 160 |
case LUMP_DEL: |
163 | 161 |
/* fix overlapping deleted zones */ |
164 | 162 |
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 | 163 |
/* change len */ |
168 | 164 |
if (t->len>s_offset-t->u.offset) |
169 | 165 |
t->len-=s_offset-t->u.offset; |
170 | 166 |
else t->len=0; |
171 | 167 |
t->u.offset=s_offset; |
172 |
- DBG("fixed to %d(%d)\n", t->u.offset, t->len); |
|
173 | 168 |
} |
174 | 169 |
s_offset=t->u.offset+t->len; |
175 | 170 |
new_len-=t->len; |
... | ... |
@@ -177,9 +172,7 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p) |
177 | 172 |
case LUMP_NOP: |
178 | 173 |
/* fix offset if overlapping on a deleted zone */ |
179 | 174 |
if (t->u.offset < s_offset){ |
180 |
- DBG("overlapping zones (%d,%d)\n", s_offset, t->u.offset); |
|
181 | 175 |
t->u.offset=s_offset; |
182 |
- DBG("fixed to %d\n", t->u.offset); |
|
183 | 176 |
}else |
184 | 177 |
s_offset=t->u.offset; |
185 | 178 |
/* do nothing */ |
... | ... |
@@ -226,8 +219,6 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p) |
226 | 219 |
} |
227 | 220 |
/* copy msg adding/removing lumps */ |
228 | 221 |
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 | 222 |
switch(t->op){ |
232 | 223 |
case LUMP_ADD: |
233 | 224 |
/* just add it here! */ |
... | ... |
@@ -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 | 676 |
return -1; |
687 | 677 |
} |
688 | 678 |
|
679 |
+ |
|
680 |
+ |
|
681 |
+void free_uri(struct sip_uri* u) |
|
682 |
+{ |
|
683 |
+ if (u){ |
|
684 |
+ if (u->user) free(u->user); |
|
685 |
+ if (u->passwd) free(u->passwd); |
|
686 |
+ if (u->host) free(u->host); |
|
687 |
+ if (u->port) free(u->port); |
|
688 |
+ if (u->params) free(u->params); |
|
689 |
+ if (u->headers) free(u->headers); |
|
690 |
+ } |
|
691 |
+} |
... | ... |
@@ -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 | 165 |
p->port=port; |
129 | 166 |
he=gethostbyname(name); |
130 | 167 |
if (he==0){ |
131 |
- LOG(L_CRIT, "ERROR: add_proxy: could not resolve hostname:" |
|
168 |
+ LOG(L_CRIT, "ERROR: mk_proxy: could not resolve hostname:" |
|
132 | 169 |
" \"%s\"\n", name); |
133 | 170 |
free(p); |
134 | 171 |
goto error; |
... | ... |
@@ -138,12 +175,14 @@ struct proxy_l* add_proxy(char* name, unsigned short port) |
138 | 175 |
goto error; |
139 | 176 |
} |
140 | 177 |
p->ok=1; |
141 |
- /* add p to the proxy list */ |
|
142 |
- p->next=proxies; |
|
143 |
- proxies=p; |
|
144 | 178 |
return p; |
145 |
- |
|
146 | 179 |
error: |
147 | 180 |
return 0; |
148 | 181 |
} |
149 | 182 |
|
183 |
+ |
|
184 |
+ |
|
185 |
+void free_proxy(struct proxy_l* p) |
|
186 |
+{ |
|
187 |
+ if (p) free_hostent(&p->host); |
|
188 |
+} |
... | ... |
@@ -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 | 180 |
mod->exports->cmd_names[r]); |
179 | 181 |
if (mod->exports->fixup_pointers[r]){ |
180 | 182 |
if (mod->exports->param_no[r]>0){ |
181 |
- ret=mod->exports->fixup_pointers[r](&t->p2.data,1); |
|
183 |
+ ret=mod->exports->fixup_pointers[r](&t->p2.data, |
|
184 |
+ 1); |
|
185 |
+ t->p2_type=MODFIXUP_ST; |
|
182 | 186 |
if (ret<0) return ret; |
183 | 187 |
} |
184 | 188 |
if (mod->exports->param_no[r]>1){ |
185 |
- ret=mod->exports->fixup_pointers[r](&t->p3.data,2); |
|
189 |
+ ret=mod->exports->fixup_pointers[r](&t->p3.data, |
|
190 |
+ 2); |
|
191 |
+ t->p3_type=MODFIXUP_ST; |
|
186 | 192 |
if (ret<0) return ret; |
187 | 193 |
} |
188 | 194 |
} |
... | ... |
@@ -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{ |
0 | 6 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,17 @@ |
1 |
+debug=9 # debug level (cmd line: -dddddddddd) |
|
2 |
+check_via=yes # (cmd. line: -v) |
|
3 |
+dns=on # (cmd. line: -r) |
|
4 |
+rev_dns=yes # (cmd. line: -R) |
|
5 |
+fork=no # (cmd. line: -D) |
|
6 |
+log_stderror=yes # (cmd line: -E) |
|
7 |
+# for more info: sip_router -h |
|
8 |
+ |
|
9 |
+#modules |
|
10 |
+loadmodule "modules/print/print.so" |
|
11 |
+ |
|
12 |
+route{ |
|
13 |
+ #rewritehost("127.0.0.1"); |
|
14 |
+ print("trying forward to uri"); |
|
15 |
+ forward(uri:host,uri:port); |
|
16 |
+ print("after forward"); |
|
17 |
+} |