- changed sip_msg (new rcv member containing all the ips, ports, protocol)
[sip-router] / action.c
1 /*
2  * $Id$
3  *
4  * Copyright (C) 2001-2003 Fhg Fokus
5  *
6  * This file is part of ser, a free SIP server.
7  *
8  * ser 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  * For a license to use the ser software under conditions
14  * other than those described here, or to purchase support for this
15  * software, please contact iptel.org by e-mail at the following addresses:
16  *    info@iptel.org
17  *
18  * ser is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License 
24  * along with this program; if not, write to the Free Software 
25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26  */
27
28
29
30
31 #include "action.h"
32 #include "config.h"
33 #include "error.h"
34 #include "dprint.h"
35 #include "proxy.h"
36 #include "forward.h"
37 #include "udp_server.h"
38 #include "route.h"
39 #include "parser/msg_parser.h"
40 #include "parser/parse_uri.h"
41 #include "ut.h"
42 #include "sr_module.h"
43 #include "mem/mem.h"
44 #include "globals.h"
45 #include "dset.h"
46 #ifdef USE_TCP
47 #include "tcp_server.h"
48 #endif
49
50 #include <sys/types.h>
51 #include <sys/socket.h>
52 #include <netdb.h>
53 #include <stdlib.h>
54 #include <netinet/in.h>
55 #include <arpa/inet.h>
56 #include <string.h>
57
58 #ifdef DEBUG_DMALLOC
59 #include <dmalloc.h>
60 #endif
61
62
63 /* ret= 0! if action -> end of list(e.g DROP), 
64       > 0 to continue processing next actions
65    and <0 on error */
66 int do_action(struct action* a, struct sip_msg* msg)
67 {
68         int ret;
69         int v;
70         union sockaddr_union* to;
71         struct socket_info* send_sock;
72         struct proxy_l* p;
73         char* tmp;
74         char *new_uri, *end, *crt;
75         int len;
76         int user;
77         struct sip_uri uri;
78         struct sip_uri* u;
79         unsigned short port;
80         int proto;
81
82         /* reset the value of error to E_UNSPEC so avoid unknowledgable
83            functions to return with errror (status<0) and not setting it
84            leaving there previous error; cache the previous value though
85            for functions which want to process it */
86         prev_ser_error=ser_error;
87         ser_error=E_UNSPEC;
88
89         ret=E_BUG;
90         switch ((unsigned char)a->type){
91                 case DROP_T:
92                                 ret=0;
93                         break;
94                 case FORWARD_T:
95 #ifdef USE_TCP
96                 case FORWARD_TCP_T:
97 #endif
98                 case FORWARD_UDP_T:
99
100                         if (a->type==FORWARD_UDP_T) proto=PROTO_UDP;
101 #ifdef USE_TCP
102                         else if (a->type==FORWARD_TCP_T) proto= PROTO_TCP;
103 #endif
104                         else proto=msg->rcv.proto;
105                         if (a->p1_type==URIHOST_ST){
106                                 /*parse uri*/
107                                 ret=parse_sip_msg_uri(msg);
108                                 if (ret<0) {
109                                         LOG(L_ERR, "ERROR: do_action: forward: bad_uri "
110                                                                 " dropping packet\n");
111                                         break;
112                                 }
113                                 u=&msg->parsed_uri;
114                                 switch (a->p2_type){
115                                         case URIPORT_ST:
116                                                                         port=u->port_no;
117                                                                         break;
118                                         case NUMBER_ST:
119                                                                         port=a->p2.number;
120                                                                         break;
121                                         default:
122                                                         LOG(L_CRIT, "BUG: do_action bad forward 2nd"
123                                                                                 " param type (%d)\n", a->p2_type);
124                                                         ret=E_UNSPEC;
125                                                         goto error_fwd_uri;
126                                 }
127                                 /* create a temporary proxy*/
128                                 p=mk_proxy(u->host.s, port);
129                                 if (p==0){
130                                         LOG(L_ERR, "ERROR:  bad host name in uri,"
131                                                         " dropping packet\n");
132                                         ret=E_BAD_ADDRESS;
133                                         goto error_fwd_uri;
134                                 }
135                                 ret=forward_request(msg, p, proto);
136                                 /*free_uri(&uri); -- no longer needed, in sip_msg*/
137                                 free_proxy(p); /* frees only p content, not p itself */
138                                 free(p);
139                                 if (ret>=0) ret=1;
140                         }else if ((a->p1_type==PROXY_ST) && (a->p2_type==NUMBER_ST)){
141                                 ret=forward_request(msg,(struct proxy_l*)a->p1.data, proto);
142                                 if (ret>=0) ret=1;
143                         }else{
144                                 LOG(L_CRIT, "BUG: do_action: bad forward() types %d, %d\n",
145                                                 a->p1_type, a->p2_type);
146                                 ret=E_BUG;
147                         }
148                         break;
149                 case SEND_T:
150                 case SEND_TCP_T:
151                         if ((a->p1_type!= PROXY_ST)|(a->p2_type!=NUMBER_ST)){
152                                 LOG(L_CRIT, "BUG: do_action: bad send() types %d, %d\n",
153                                                 a->p1_type, a->p2_type);
154                                 ret=E_BUG;
155                                 break;
156                         }
157                         to=(union sockaddr_union*) malloc(sizeof(union sockaddr_union));
158                         if (to==0){
159                                 LOG(L_ERR, "ERROR: do_action: "
160                                                         "memory allocation failure\n");
161                                 ret=E_OUT_OF_MEM;
162                                 break;
163                         }
164                         
165                         p=(struct proxy_l*)a->p1.data;
166                         
167                         if (p->ok==0){
168                                 if (p->host.h_addr_list[p->addr_idx+1])
169                                         p->addr_idx++;
170                                 else 
171                                         p->addr_idx=0;
172                                 p->ok=1;
173                         }
174                         ret=hostent2su( to, &p->host, p->addr_idx,
175                                                 (p->port)?htons(p->port):htons(SIP_PORT) );
176                         if (ret==0){
177                                 p->tx++;
178                                 p->tx_bytes+=msg->len;
179                                 if (a->type==SEND_T){
180                                         /*udp*/
181                                         send_sock=get_send_socket(to, PROTO_UDP);
182                                         if (send_sock!=0){
183                                                 ret=udp_send(send_sock, msg->orig, msg->len, to);
184                                         }else{
185                                                 ret=-1;
186                                         }
187                                 }
188 #ifdef USE_TCP
189                                         else{
190                                         /*tcp*/
191                                         ret=tcp_send(msg->orig, msg->len, to, 0);
192                                 }
193 #endif
194                         }
195                         free(to);
196                         if (ret<0){
197                                 p->errors++;
198                                 p->ok=0;
199                         }else ret=1;
200                         
201                         break;
202                 case LOG_T:
203                         if ((a->p1_type!=NUMBER_ST)|(a->p2_type!=STRING_ST)){
204                                 LOG(L_CRIT, "BUG: do_action: bad log() types %d, %d\n",
205                                                 a->p1_type, a->p2_type);
206                                 ret=E_BUG;
207                                 break;
208                         }
209                         LOG(a->p1.number, a->p2.string);
210                         ret=1;
211                         break;
212
213                 /* jku -- introduce a new branch */
214                 case APPEND_BRANCH_T:
215                         if ((a->p1_type!=STRING_ST)) {
216                                 LOG(L_CRIT, "BUG: do_action: bad append_branch_t %d\n",
217                                         a->p1_type );
218                                 ret=E_BUG;
219                                 break;
220                         }
221                         ret=append_branch( msg, a->p1.string, 
222                                 a->p1.string ? strlen(a->p1.string):0 );
223                         break;
224
225                 /* jku begin: is_length_greater_than */
226                 case LEN_GT_T:
227                         if (a->p1_type!=NUMBER_ST) {
228                                 LOG(L_CRIT, "BUG: do_action: bad len_gt type %d\n",
229                                         a->p1_type );
230                                 ret=E_BUG;
231                                 break;
232                         }
233                         /* DBG("XXX: message length %d, max %d\n", 
234                                 msg->len, a->p1.number ); */
235                         ret = msg->len >= a->p1.number ? 1 : -1;
236                         break;
237                 /* jku end: is_length_greater_than */
238                         
239                 /* jku - begin : flag processing */
240
241                 case SETFLAG_T:
242                         if (a->p1_type!=NUMBER_ST) {
243                                 LOG(L_CRIT, "BUG: do_action: bad setflag() type %d\n",
244                                         a->p1_type );
245                                 ret=E_BUG;
246                                 break;
247                         }
248                         if (!flag_in_range( a->p1.number )) {
249                                 ret=E_CFG;
250                                 break;
251                         }
252                         setflag( msg, a->p1.number );
253                         ret=1;
254                         break;
255
256                 case RESETFLAG_T:
257                         if (a->p1_type!=NUMBER_ST) {
258                                 LOG(L_CRIT, "BUG: do_action: bad resetflag() type %d\n",
259                                         a->p1_type );
260                                 ret=E_BUG;
261                                 break;
262                         }
263                         if (!flag_in_range( a->p1.number )) {
264                                 ret=E_CFG;
265                                 break;
266                         }
267                         resetflag( msg, a->p1.number );
268                         ret=1;
269                         break;
270                         
271                 case ISFLAGSET_T:
272                         if (a->p1_type!=NUMBER_ST) {
273                                 LOG(L_CRIT, "BUG: do_action: bad isflagset() type %d\n",
274                                         a->p1_type );
275                                 ret=E_BUG;
276                                 break;
277                         }
278                         if (!flag_in_range( a->p1.number )) {
279                                 ret=E_CFG;
280                                 break;
281                         }
282                         ret=isflagset( msg, a->p1.number );
283                         break;
284                 /* jku - end : flag processing */
285
286                 case ERROR_T:
287                         if ((a->p1_type!=STRING_ST)|(a->p2_type!=STRING_ST)){
288                                 LOG(L_CRIT, "BUG: do_action: bad error() types %d, %d\n",
289                                                 a->p1_type, a->p2_type);
290                                 ret=E_BUG;
291                                 break;
292                         }
293                         LOG(L_NOTICE, "WARNING: do_action: error(\"%s\", \"%s\") "
294                                         "not implemented yet\n", a->p1.string, a->p2.string);
295                         ret=1;
296                         break;
297                 case ROUTE_T:
298                         if (a->p1_type!=NUMBER_ST){
299                                 LOG(L_CRIT, "BUG: do_action: bad route() type %d\n",
300                                                 a->p1_type);
301                                 ret=E_BUG;
302                                 break;
303                         }
304                         if ((a->p1.number>RT_NO)||(a->p1.number<0)){
305                                 LOG(L_ERR, "ERROR: invalid routing table number in"
306                                                         "route(%d)\n", a->p1.number);
307                                 ret=E_CFG;
308                                 break;
309                         }
310                         ret=((ret=run_actions(rlist[a->p1.number], msg))<0)?ret:1;
311                         break;
312                 case EXEC_T:
313                         if (a->p1_type!=STRING_ST){
314                                 LOG(L_CRIT, "BUG: do_action: bad exec() type %d\n",
315                                                 a->p1_type);
316                                 ret=E_BUG;
317                                 break;
318                         }
319                         LOG(L_NOTICE, "WARNING: exec(\"%s\") not fully implemented,"
320                                                 " using dumb version...\n", a->p1.string);
321                         ret=system(a->p1.string);
322                         if (ret!=0){
323                                 LOG(L_NOTICE, "WARNING: exec() returned %d\n", ret);
324                         }
325                         ret=1;
326                         break;
327                 case REVERT_URI_T:
328                         if (msg->new_uri.s) {
329                                 pkg_free(msg->new_uri.s);
330                                 msg->new_uri.len=0;
331                                 msg->new_uri.s=0;
332                                 if (msg->parsed_uri_ok){
333                                         msg->parsed_uri_ok=0; /* invalidate current parsed uri*/
334                                         free_uri(&msg->parsed_uri);
335                                 }
336                         };
337                         ret=1;
338                         break;
339                 case SET_HOST_T:
340                 case SET_HOSTPORT_T:
341                 case SET_USER_T:
342                 case SET_USERPASS_T:
343                 case SET_PORT_T:
344                 case SET_URI_T:
345                 case PREFIX_T:
346                 case STRIP_T:
347                                 user=0;
348                                 if (a->type==STRIP_T) {
349                                         if (a->p1_type!=NUMBER_ST) {
350                                                 LOG(L_CRIT, "BUG: do_action: bad set*() type %d\n",
351                                                         a->p1_type);
352                                                 break;
353                                         }
354                                 } else if (a->p1_type!=STRING_ST){
355                                         LOG(L_CRIT, "BUG: do_action: bad set*() type %d\n",
356                                                         a->p1_type);
357                                         ret=E_BUG;
358                                         break;
359                                 }
360                                 if (a->type==SET_URI_T){
361                                         if (msg->new_uri.s) {
362                                                         pkg_free(msg->new_uri.s);
363                                                         msg->new_uri.len=0;
364                                         }
365                                         if (msg->parsed_uri_ok){
366                                                         msg->parsed_uri_ok=0;
367                                                         free_uri(&msg->parsed_uri);
368                                         }
369                                         len=strlen(a->p1.string);
370                                         msg->new_uri.s=pkg_malloc(len+1);
371                                         if (msg->new_uri.s==0){
372                                                 LOG(L_ERR, "ERROR: do_action: memory allocation"
373                                                                 " failure\n");
374                                                 ret=E_OUT_OF_MEM;
375                                                 break;
376                                         }
377                                         memcpy(msg->new_uri.s, a->p1.string, len);
378                                         msg->new_uri.s[len]=0;
379                                         msg->new_uri.len=len;
380                                         
381                                         ret=1;
382                                         break;
383                                 }
384                                 if (msg->new_uri.s) {
385                                         tmp=msg->new_uri.s;
386                                         len=msg->new_uri.len;
387                                 }else{
388                                         tmp=msg->first_line.u.request.uri.s;
389                                         len=msg->first_line.u.request.uri.len;
390                                 }
391                                 if (parse_uri(tmp, len, &uri)<0){
392                                         LOG(L_ERR, "ERROR: do_action: bad uri <%s>, dropping"
393                                                                 " packet\n", tmp);
394                                         ret=E_UNSPEC;
395                                         break;
396                                 }
397                                 
398                                 new_uri=pkg_malloc(MAX_URI_SIZE);
399                                 if (new_uri==0){
400                                         LOG(L_ERR, "ERROR: do_action: memory allocation "
401                                                                 " failure\n");
402                                         ret=E_OUT_OF_MEM;
403                                         free_uri(&uri);
404                                         break;
405                                 }
406                                 end=new_uri+MAX_URI_SIZE;
407                                 crt=new_uri;
408                                 /* begin copying */
409                                 len=strlen("sip:"); if(crt+len>end) goto error_uri;
410                                 memcpy(crt,"sip:",len);crt+=len;
411
412                                 /* user */
413
414                                 /* prefix (-jiri) */
415                                 if (a->type==PREFIX_T) {
416                                         tmp=a->p1.string;
417                                         len=strlen(tmp); if(crt+len>end) goto error_uri;
418                                         memcpy(crt,tmp,len);crt+=len;
419                                         /* whateever we had before, with prefix we have username now */
420                                         user=1;
421                                 }
422
423                                 if ((a->type==SET_USER_T)||(a->type==SET_USERPASS_T)) {
424                                         tmp=a->p1.string;
425                                         len=strlen(tmp);
426                                 } else if (a->type==STRIP_T) {
427                                         if (a->p1.number>uri.user.len) {
428                                                 LOG(L_WARN, "Error: too long strip asked; deleting username: "
429                                                         "%d of %s\n", a->p1.number, uri.user.s );
430                                                 len=0;
431                                         } else if (a->p1.number==uri.user.len) {
432                                                 len=0;
433                                         } else {
434                                                 tmp=uri.user.s + a->p1.number;
435                                                 len=uri.user.len - a->p1.number;
436                                         }
437                                 } else {
438                                         tmp=uri.user.s;
439                                         len=uri.user.len;
440                                 }
441
442                                 if (len){
443                                         if(crt+len>end) goto error_uri;
444                                         memcpy(crt,tmp,len);crt+=len;
445                                         user=1; /* we have an user field so mark it */
446                                 }
447
448                                 if (a->type==SET_USERPASS_T) tmp=0;
449                                 else tmp=uri.passwd.s;
450                                 /* passwd */
451                                 if (tmp){
452                                         len=strlen(":"); if(crt+len>end) goto error_uri;
453                                         memcpy(crt,":",len);crt+=len;
454                                         len=strlen(tmp); if(crt+len>end) goto error_uri;
455                                         memcpy(crt,tmp,len);crt+=len;
456                                 }
457                                 /* host */
458                                 if (user || tmp){ /* add @ */
459                                         len=strlen("@"); if(crt+len>end) goto error_uri;
460                                         memcpy(crt,"@",len);crt+=len;
461                                 }
462                                 if ((a->type==SET_HOST_T) ||(a->type==SET_HOSTPORT_T))
463                                         tmp=a->p1.string;
464                                 else
465                                         tmp=uri.host.s;
466                                 if (tmp){
467                                         len=strlen(tmp); if(crt+len>end) goto error_uri;
468                                         memcpy(crt,tmp,len);crt+=len;
469                                 }
470                                 /* port */
471                                 if (a->type==SET_HOSTPORT_T) tmp=0;
472                                 else if (a->type==SET_PORT_T) tmp=a->p1.string;
473                                 else tmp=uri.port.s;
474                                 if (tmp){
475                                         len=strlen(":"); if(crt+len>end) goto error_uri;
476                                         memcpy(crt,":",len);crt+=len;
477                                         len=strlen(tmp); if(crt+len>end) goto error_uri;
478                                         memcpy(crt,tmp,len);crt+=len;
479                                 }
480                                 /* params */
481                                 tmp=uri.params.s;
482                                 if (tmp){
483                                         len=strlen(";"); if(crt+len>end) goto error_uri;
484                                         memcpy(crt,";",len);crt+=len;
485                                         len=strlen(tmp); if(crt+len>end) goto error_uri;
486                                         memcpy(crt,tmp,len);crt+=len;
487                                 }
488                                 /* headers */
489                                 tmp=uri.headers.s;
490                                 if (tmp){
491                                         len=strlen("?"); if(crt+len>end) goto error_uri;
492                                         memcpy(crt,"?",len);crt+=len;
493                                         len=strlen(tmp); if(crt+len>end) goto error_uri;
494                                         memcpy(crt,tmp,len);crt+=len;
495                                 }
496                                 *crt=0; /* null terminate the thing */
497                                 /* copy it to the msg */
498                                 if (msg->new_uri.s) pkg_free(msg->new_uri.s);
499                                 msg->new_uri.s=new_uri;
500                                 msg->new_uri.len=crt-new_uri;
501                                 if (msg->parsed_uri_ok){
502                                         msg->parsed_uri_ok=0;
503                                         free_uri(&msg->parsed_uri);
504                                 }
505                                 free_uri(&uri);
506                                 ret=1;
507                                 break;
508                 case IF_T:
509                                 /* if null expr => ignore if? */
510                                 if ((a->p1_type==EXPR_ST)&&a->p1.data){
511                                         v=eval_expr((struct expr*)a->p1.data, msg);
512                                         if (v<0){
513                                                 if (v==EXPR_DROP){ /* hack to quit on DROP*/
514                                                         ret=0;
515                                                         break;
516                                                 }else{
517                                                         LOG(L_WARN,"WARNING: do_action:"
518                                                                                 "error in expression\n");
519                                                 }
520                                         }
521                                         
522                                         ret=1;  /*default is continue */
523                                         if (v>0) {
524                                                 if ((a->p2_type==ACTIONS_ST)&&a->p2.data){
525                                                         ret=run_actions((struct action*)a->p2.data, msg);
526                                                 }
527                                         }else if ((a->p3_type==ACTIONS_ST)&&a->p3.data){
528                                                         ret=run_actions((struct action*)a->p3.data, msg);
529                                         }
530                                 }
531                         break;
532                 case MODULE_T:
533                         if ( ((a->p1_type==CMDF_ST)&&a->p1.data)/*&&
534                                         ((a->p2_type==STRING_ST)&&a->p2.data)*/ ){
535                                 ret=((cmd_function)(a->p1.data))(msg, (char*)a->p2.data,
536                                                                                                           (char*)a->p3.data);
537                         }else{
538                                 LOG(L_CRIT,"BUG: do_action: bad module call\n");
539                         }
540                         break;
541                 default:
542                         LOG(L_CRIT, "BUG: do_action: unknown type %d\n", a->type);
543         }
544 /*skip:*/
545         return ret;
546         
547 error_uri:
548         LOG(L_ERR, "ERROR: do_action: set*: uri too long\n");
549         free_uri(&uri);
550         if (new_uri) free(new_uri);
551         return E_UNSPEC;
552 error_fwd_uri:
553         /*free_uri(&uri); -- not needed anymore, using msg->parsed_uri*/
554         return ret;
555 }
556
557
558
559 /* returns: 0, or 1 on success, <0 on error */
560 /* (0 if drop or break encountered, 1 if not ) */
561 int run_actions(struct action* a, struct sip_msg* msg)
562 {
563         struct action* t;
564         int ret=E_UNSPEC;
565         static int rec_lev=0;
566         struct sr_module *mod;
567
568         rec_lev++;
569         if (rec_lev>ROUTE_MAX_REC_LEV){
570                 LOG(L_ERR, "WARNING: too many recursive routing table lookups (%d)"
571                                         " giving up!\n", rec_lev);
572                 ret=E_UNSPEC;
573                 goto error;
574         }
575                 
576         if (a==0){
577                 LOG(L_ERR, "WARNING: run_actions: null action list (rec_level=%d)\n", 
578                         rec_lev);
579                 ret=0;
580         }
581
582         for (t=a; t!=0; t=t->next){
583                 ret=do_action(t, msg);
584                 if(ret==0) break;
585                 /* ignore errors */
586                 /*else if (ret<0){ ret=-1; goto error; }*/
587         }
588         
589         rec_lev--;
590         /* process module onbreak handlers if present */
591         if (rec_lev==0 && ret==0) 
592                 for (mod=modules;mod;mod=mod->next) 
593                         if (mod->exports && mod->exports->onbreak_f) {
594                                 mod->exports->onbreak_f( msg );
595                                 DBG("DEBUG: %s onbreak handler called\n", mod->exports->name);
596                         }
597         return ret;
598         
599
600 error:
601         rec_lev--;
602         return ret;
603 }
604
605
606