245f9f30f0a6a7a5dfd422626f8bdce3d5275404
[sip-router] / modules / tm / t_fwd.c
1 /*
2  * $Id$
3  *
4  */
5
6 #include "../../dprint.h"
7 #include "../../config.h"
8 #include "../../parser/parser_f.h"
9 #include "../../ut.h"
10 #include "../../timer.h"
11 #include "../../hash_func.h"
12 #include "../../globals.h"
13 #include "../../dset.h"
14 #include "t_funcs.h"
15 #include "t_hooks.h"
16 #include "t_msgbuilder.h"
17 #include "ut.h"
18 #include "t_cancel.h"
19 #include "t_lookup.h"
20 #include "t_fwd.h"
21 #include "fix_lumps.h"
22 #include "config.h"
23
24
25 #ifdef _OBSOLETED
26 #define shm_free_lump( _lmp) \
27         do{\
28                 if ((_lmp)) {\
29                         if ((_lmp)->op==LUMP_ADD && (_lmp)->u.value )\
30                                 shm_free((_lmp)->u.value);\
31                         shm_free((_lmp));\
32                 }\
33         }while(0);
34 #endif
35
36 char *print_uac_request( struct cell *t, struct sip_msg *i_req,
37         int branch, str *uri, int *len, struct socket_info *send_sock )
38 {
39         char *buf, *shbuf;
40
41         shbuf=0;
42
43         /* ... we calculate branch ... */       
44         if (!t_setbranch( t, i_req, branch )) {
45                 LOG(L_ERR, "ERROR: print_uac_request: branch computation failed\n");
46                 goto error01;
47         }
48
49         /* ... update uri ... */
50         i_req->new_uri=*uri;
51
52         /* ... give apps a chance to change things ... */
53         callback_event( TMCB_REQUEST_OUT, t, i_req, -i_req->REQ_METHOD);
54
55         /* ... and build it now */
56         buf=build_req_buf_from_sip_req( i_req, len, send_sock );
57 #ifdef DBG_MSG_QA
58         if (buf[*len-1]==0) {
59                 LOG(L_ERR, "ERROR: print_uac_request: sanity check failed\n");
60                 abort();
61         }
62 #endif
63         if (!buf) {
64                 LOG(L_ERR, "ERROR: print_uac_request: no pkg_mem\n"); 
65                 ser_error=E_OUT_OF_MEM;
66                 goto error01;
67         }
68         /*      clean Via's we created now -- they would accumulate for
69                 other branches  and for  shmem i_req they would mix up
70                 shmem with pkg_mem
71         */
72 #ifdef OBSOLETED
73         if (branch) for(b=i_req->add_rm,b1=0;b;b1=b,b=b->next)
74                 if (b->type==HDR_VIA) {
75                         for(a=b->before;a;)
76                                 {c=a->before;free_lump(a);pkg_free(a);a=c;}
77                         for(a=b->after;a;)
78                                 {c=a->after;free_lump(a);pkg_free(a);a=c;}
79                         if (b1) b1->next = b->next;
80                         else i_req->add_rm = b->next;
81                         free_lump(b);pkg_free(b);
82                 }
83 #endif
84         free_via_lump(&i_req->add_rm);
85
86         shbuf=(char *)shm_malloc(*len);
87         if (!shbuf) {
88                 ser_error=E_OUT_OF_MEM;
89                 LOG(L_ERR, "ERROR: print_uac_request: no shmem\n");
90                 goto error02;
91         }
92         memcpy( shbuf, buf, *len );
93
94 error02:
95         pkg_free( buf );
96 error01:
97         return shbuf;
98 }
99
100 /* introduce a new uac to transaction; returns its branch id (>=0)
101    or error (<0); it doesn't send a message yet -- a reply to it
102    might itnerfere with the processes of adding multiple branches
103 */
104 int add_uac( struct cell *t, struct sip_msg *request, str *uri, 
105         struct proxy_l *proxy )
106 {
107
108         int ret;
109         short temp_proxy;
110         union sockaddr_union to;
111         unsigned short branch;
112         struct socket_info* send_sock;
113         char *shbuf;
114         unsigned int len;
115
116         branch=t->nr_of_outgoings;
117         if (branch==MAX_BRANCHES) {
118                 LOG(L_ERR, "ERROR: add_uac: maximum number of branches exceeded\n");
119                 ret=E_CFG;
120                 goto error;
121         }
122
123         /* check existing buffer -- rewriting should never occur */
124         if (t->uac[branch].request.buffer) {
125                 LOG(L_CRIT, "ERROR: add_uac: buffer rewrite attempt\n");
126                 ret=ser_error=E_BUG;
127                 goto error;
128         }
129
130         /* check DNS resolution */
131         if (proxy) temp_proxy=0; else {
132                 proxy=uri2proxy( uri );
133                 if (proxy==0)  {
134                         ret=E_BAD_ADDRESS;
135                         goto error;
136                 }
137                 temp_proxy=1;
138         }
139
140         if (proxy->ok==0) {
141                 if (proxy->host.h_addr_list[proxy->addr_idx+1])
142                         proxy->addr_idx++;
143                 else proxy->addr_idx=0;
144                 proxy->ok=1;
145         }
146
147         hostent2su( &to, &proxy->host, proxy->addr_idx, 
148                 proxy->port ? htons(proxy->port):htons(SIP_PORT));
149
150         send_sock=get_send_socket( &to );
151         if (send_sock==0) {
152                 LOG(L_ERR, "ERROR: add_uac: can't fwd to af %d "
153                         " (no corresponding listening socket)\n",
154                         to.s.sa_family );
155                 ret=ser_error=E_NO_SOCKET;
156                 goto error01;
157         }
158
159         /* now message printing starts ... */
160         shbuf=print_uac_request( t, request, branch, uri, 
161                 &len, send_sock );
162         if (!shbuf) {
163                 ret=ser_error=E_OUT_OF_MEM;
164                 goto error01;
165         }
166
167         /* things went well, move ahead and install new buffer! */
168         t->uac[branch].request.to=to;
169         t->uac[branch].request.send_sock=send_sock;
170         t->uac[branch].request.buffer=shbuf;
171         t->uac[branch].request.buffer_len=len;
172         t->uac[branch].uri.s=t->uac[branch].request.buffer+
173                 request->first_line.u.request.method.len+1;
174         t->uac[branch].uri.len=uri->len;
175         t->nr_of_outgoings++;
176
177         /* update stats */
178         proxy->tx++;
179         proxy->tx_bytes+=len;
180
181         /* done! */     
182         ret=branch;
183                 
184 error01:
185         if (temp_proxy) {
186                 free_proxy( proxy );
187                 free( proxy );
188         }
189 error:
190         return ret;
191 }
192
193 int e2e_cancel_branch( struct sip_msg *cancel_msg, struct cell *t_cancel, 
194         struct cell *t_invite, int branch )
195 {
196         int ret;
197         char *shbuf;
198         int len;
199
200         if (t_cancel->uac[branch].request.buffer) {
201                 LOG(L_CRIT, "ERROR: e2e_cancel_branch: buffer rewrite attempt\n");
202                 ret=ser_error=E_BUG;
203                 goto error;
204         }       
205
206         /* note -- there is a gap in proxy stats -- we don't update 
207            proxy stats with CANCEL (proxy->ok, proxy->tx, etc.)
208         */
209
210         /* print */
211         shbuf=print_uac_request( t_cancel, cancel_msg, branch, 
212                 &t_invite->uac[branch].uri, &len, 
213                 t_invite->uac[branch].request.send_sock);
214         if (!shbuf) {
215                 LOG(L_ERR, "ERROR: e2e_cancel_branch: printing e2e cancel failed\n");
216                 ret=ser_error=E_OUT_OF_MEM;
217                 goto error;
218         }
219         
220         /* install buffer */
221         t_cancel->uac[branch].request.to=t_invite->uac[branch].request.to;
222         t_cancel->uac[branch].request.send_sock=t_invite->uac[branch].request.send_sock;
223         t_cancel->uac[branch].request.buffer=shbuf;
224         t_cancel->uac[branch].request.buffer_len=len;
225         t_cancel->uac[branch].uri.s=t_cancel->uac[branch].request.buffer+
226                 cancel_msg->first_line.u.request.method.len+1;
227         t_cancel->uac[branch].uri.len=t_invite->uac[branch].uri.len;
228         
229
230         /* success */
231         ret=1;
232
233
234 error:
235         return ret;
236 }
237
238 void e2e_cancel( struct sip_msg *cancel_msg, 
239         struct cell *t_cancel, struct cell *t_invite )
240 {
241         branch_bm_t cancel_bm;
242         int i;
243         int lowest_error;
244         str backup_uri;
245         int ret;
246
247         cancel_bm=0;
248         lowest_error=0;
249
250         backup_uri=cancel_msg->new_uri;
251         /* determine which branches to cancel ... */
252         which_cancel( t_invite, &cancel_bm );
253         t_cancel->nr_of_outgoings=t_invite->nr_of_outgoings;
254         /* fix label -- it must be same for reply matching */
255         t_cancel->label=t_invite->label;
256         /* ... and install CANCEL UACs */
257         for (i=0; i<t_invite->nr_of_outgoings; i++)
258                 if (cancel_bm & (1<<i)) {
259                         ret=e2e_cancel_branch(cancel_msg, t_cancel, t_invite, i);
260                         if (ret<0) cancel_bm &= ~(1<<i);
261                         if (ret<lowest_error) lowest_error=ret;
262                 }
263         cancel_msg->new_uri=backup_uri;
264
265         /* send them out */
266         for (i=0; i<t_cancel->nr_of_outgoings; i++) {
267                 if (cancel_bm & (1<<i)) {
268                         if (SEND_BUFFER( &t_cancel->uac[i].request)==-1) {
269                                 LOG(L_ERR, "ERROR: e2e_cancel: send failed\n");
270                         }
271                         start_retr( &t_cancel->uac[i].request );
272                 }
273         }
274
275
276         /* if error occured, let it know upstream (final reply
277            will also move the transaction on wait state
278         */
279         if (lowest_error<0) {
280                 LOG(L_ERR, "ERROR: cancel error\n");
281                 t_reply( t_cancel, cancel_msg, 500, "cancel error");
282         /* if there are pending branches, let upstream know we
283            are working on it
284         */
285         } else if (cancel_bm) {
286                 DBG("DEBUG: e2e_cancel: e2e cancel proceeding\n");
287                 t_reply( t_cancel, cancel_msg, 200, CANCELLING );
288         /* if the transaction exists, but there is no more pending
289            branch, tell usptream we're done
290         */
291         } else {
292                 DBG("DEBUG: e2e_cancel: e2e cancel -- no more pending branches\n");
293                 t_reply( t_cancel, cancel_msg, 200, CANCEL_DONE );
294         }
295         /* we could await downstream UAS's 487 replies; however,
296            if some of the branches does not do that, we could wait
297            long time and annoy upstream UAC which wants to see 
298            a result of CANCEL quickly
299         */
300         DBG("DEBUG: e2e_cancel: sending 487\n");
301         t_reply(t_invite, t_invite->uas.request, 487, CANCELLED );
302 }
303
304
305 /* function returns:
306  *       1 - forward successfull
307  *      -1 - error during forward
308  */
309 int t_forward_nonack( struct cell *t, struct sip_msg* p_msg , 
310         struct proxy_l * proxy )
311 {
312         str          backup_uri;
313         int branch_ret, lowest_ret;
314         str current_uri;
315         branch_bm_t     added_branches;
316         int first_branch;
317         int i;
318         struct cell *t_invite;
319
320         /* make -Wall happy */
321         current_uri.s=0;
322
323         t->kr|=REQ_FWDED;
324
325         if (p_msg->REQ_METHOD==METHOD_CANCEL) {
326                 t_invite=t_lookupOriginalT(  p_msg );
327                 if (t_invite!=T_NULL) {
328                         e2e_cancel( p_msg, t, t_invite );
329                         UNREF(t_invite);
330                         return 1;
331                 }
332         }
333
334         /* backup current uri ... add_uac changes it */
335         backup_uri = p_msg->new_uri;
336         /* if no more specific error code is known, use this */
337         lowest_ret=E_BUG;
338         /* branches added */
339         added_branches=0;
340         /* branch to begin with */
341         first_branch=t->nr_of_outgoings;
342
343         /* on first-time forwarding, use current uri, later only what
344            is in additional branches (which may be continuously refilled
345         */
346         if (first_branch==0) {
347                 branch_ret=add_uac( t, p_msg, 
348                         p_msg->new_uri.s ? &p_msg->new_uri :  
349                                 &p_msg->first_line.u.request.uri,
350                         proxy );
351                 if (branch_ret>=0) 
352                         added_branches |= 1<<branch_ret;
353                 else
354                         lowest_ret=branch_ret;
355         }
356
357         init_branch_iterator();
358         while((current_uri.s=next_branch( &current_uri.len))) {
359                 branch_ret=add_uac( t, p_msg, &current_uri, proxy );
360                 /* pick some of the errors in case things go wrong;
361                    note that picking lowest error is just as good as
362                    any other algorithm which picks any other negative
363                    branch result */
364                 if (branch_ret>=0) 
365                         added_branches |= 1<<branch_ret;
366                 else
367                         lowest_ret=branch_ret;
368         }
369         /* consume processed branches */
370         clear_branches();
371
372         /* restore original URI */
373         p_msg->new_uri=backup_uri;
374
375         /* don't forget to clear all branches processed so far */
376
377         /* things went wrong ... no new branch has been fwd-ed at all */
378         if (added_branches==0)
379                 return lowest_ret;
380
381         /* if someone set on_negative, store in in T-context */
382         t->on_negative=get_on_negative();
383
384         /* send them out now */
385         for (i=first_branch; i<t->nr_of_outgoings; i++) {
386                 if (added_branches & (1<<i)) {
387                         if (SEND_BUFFER( &t->uac[i].request)==-1) {
388                                 LOG(L_ERR, "ERROR: add_uac: sending request failed\n");
389                                 if (proxy) { proxy->errors++; proxy->ok=0; }
390                         }
391                         start_retr( &t->uac[i].request );
392                 }
393         }
394         return 1;
395 }       
396
397 int t_replicate(struct sip_msg *p_msg,  struct proxy_l *proxy )
398 {
399         /* this is a quite horrible hack -- we just take the message
400            as is, including Route-s, Record-route-s, and Vias ,
401            forward it downstream and prevent replies received
402            from relaying by setting the replication/local_trans bit;
403
404                 nevertheless, it should be good enough for the primary
405                 customer of this function, REGISTER replication
406
407                 if we want later to make it thoroughly, we need to
408                 introduce delete lumps for all the header fields above
409         */
410         return t_relay_to(p_msg, proxy, 1 /* replicate */);
411 }