all: updated FSF address in GPL text
[sip-router] / modules / cpl-c / cpl_sig.c
1 /*
2  * $Id$
3  *
4  * Copyright (C) 2001-2003 FhG Fokus
5  *
6  * This file is part of Kamailio, a free SIP server.
7  *
8  * Kamailio 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  * Kamailio is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21  */
22
23
24 #include "../../action.h"
25 #include "../../dset.h"
26 #include "../../modules/tm/tm_load.h"
27 #include "loc_set.h"
28 #include "cpl_sig.h"
29 #include "cpl_env.h"
30
31
32 /* forwards the msg to the given location set; if flags has set the
33  * CPL_PROXY_DONE, all locations will be added as branches, otherwise, the 
34  * first one will set as RURI (this is ha case when this is the first proxy 
35  * of the message)
36  * The given list of location will be freed, returning 0 instead.
37  * Returns:  0 - OK
38  *          -1 - error */
39 int cpl_proxy_to_loc_set( struct sip_msg *msg, struct location **locs,
40                                                                                                         unsigned char flag)
41 {
42         struct location *foo;
43         struct action act;
44         struct run_act_ctx ra_ctx;
45         int bflags;
46
47         if (!*locs) {
48                 LM_ERR("empty loc set!!\n");
49                 goto error;
50         }
51
52         /* if it's the first time when this sip_msg is proxied, use the first addr
53          * in loc_set to rewrite the RURI */
54         if (!(flag&CPL_PROXY_DONE)) {
55                 LM_DBG("rewriting Request-URI with <%s>\n",(*locs)->addr.uri.s);
56                 /* build a new action for setting the URI */
57                 memset(&act, '\0', sizeof(act));
58                 act.type = SET_URI_T;
59                 act.val[0].type = STRING_ST;
60                 act.val[0].u.string = (*locs)->addr.uri.s;
61                 init_run_actions_ctx(&ra_ctx);
62                 /* push the action */
63                 if (do_action(&ra_ctx, &act, msg) < 0) {
64                         LM_ERR("do_action failed\n");
65                         goto error;
66                 }
67                 /* build a new action for setting the DSTURI */
68                 if((*locs)->addr.received.s && (*locs)->addr.received.len) {
69                         LM_DBG("rewriting Destination URI "
70                                 "with <%s>\n",(*locs)->addr.received.s);
71                         if (set_dst_uri(msg, &(*locs)->addr.received) < 0) {
72                                 LM_ERR("Error while setting the dst uri\n");
73                                 goto error;
74                         }
75                         /* dst_uri changes, so it makes sense to re-use the current uri for
76                                 forking */
77                         ruri_mark_new(); /* re-use uri for serial forking */
78                 }
79                 /* is the location NATED? */
80                 if ((*locs)->flags&CPL_LOC_NATED)
81                         setbflag( 0, cpl_fct.ulb.nat_flag );
82                 /* free the location and point to the next one */
83                 foo = (*locs)->next;
84                 free_location( *locs );
85                 *locs = foo;
86         }
87
88         /* add the rest of the locations as branches */
89         while(*locs) {
90                 bflags = ((*locs)->flags&CPL_LOC_NATED) ? cpl_fct.ulb.nat_flag : 0 ;
91                 LM_DBG("appending branch <%.*s>, flags %d\n",
92                         (*locs)->addr.uri.len, (*locs)->addr.uri.s, bflags);
93                 if(append_branch(msg, &(*locs)->addr.uri,
94                                  &(*locs)->addr.received, 0,
95                                  Q_UNSPECIFIED, bflags, 0, 0, 0, 0, 0)==-1){
96                         LM_ERR("failed when appending branch <%s>\n",
97                                (*locs)->addr.uri.s);
98                         goto error;
99                 }
100                 /* free the location and point to the next one */
101                 foo = (*locs)->next;
102                 free_location( *locs );
103                 *locs = foo;
104         }
105
106         /* run what proxy route is set */
107         if (cpl_env.proxy_route) {
108                 /* do not alter route type - it might be REQUEST or FAILURE */
109                 run_top_route( main_rt.rlist[cpl_env.proxy_route], msg, 0);
110         }
111
112         /* do t_forward */
113         if (cpl_fct.tmb.t_relay(msg, 0, 0)==-1) {
114                 LM_ERR("t_relay failed !\n");
115                 goto error;
116         }
117
118         return 0;
119 error:
120         return -1;
121 }
122
123