Main Page | Modules | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

t_fwd.c

Go to the documentation of this file.
00001 /*
00002  * $Id: t_fwd.c,v 1.108 2009/03/13 13:59:29 tirpi Exp $
00003  *
00004  *
00005  * Copyright (C) 2001-2003 FhG Fokus
00006  *
00007  * This file is part of ser, a free SIP server.
00008  *
00009  * ser is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version
00013  *
00014  * For a license to use the ser software under conditions
00015  * other than those described here, or to purchase support for this
00016  * software, please contact iptel.org by e-mail at the following addresses:
00017  *    info@iptel.org
00018  *
00019  * ser is distributed in the hope that it will be useful,
00020  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022  * GNU General Public License for more details.
00023  *
00024  * You should have received a copy of the GNU General Public License 
00025  * along with this program; if not, write to the Free Software 
00026  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00027  */
00028 /*
00029  * History:
00030  * -------
00031  *  2003-02-13  proto support added (andrei)
00032  *  2003-02-24  s/T_NULL/T_NULL_CELL/ to avoid redefinition conflict w/
00033  *              nameser_compat.h (andrei)
00034  *  2003-03-01  kr set through a function now (jiri)
00035  *  2003-03-06  callbacks renamed; "blind UAC" introduced, which makes
00036  *              transaction behave as if it was forwarded even if it was
00037  *              not -- good for local UAS, like VM (jiri)
00038  *  2003-03-19  replaced all the mallocs/frees w/ pkg_malloc/pkg_free (andrei)
00039  *  2003-03-30  we now watch downstream delivery and if it fails, send an
00040  *              error message upstream (jiri)
00041  *  2003-04-14  use protocol from uri (jiri)
00042  *  2003-12-04  global TM callbacks switched to per transaction callbacks
00043  *              (bogdan)
00044  *  2004-02-13: t->is_invite and t->local replaced with flags (bogdan)
00045  *  2005-08-04  msg->parsed_uri and parsed_uri_ok are no saved & restored
00046  *               before & after handling the branches (andrei)
00047  *  2005-12-11  onsend_route support added for forwarding (andrei)
00048  *  2006-01-27  t_forward_no_ack will return error if a forward on an 
00049  *              already canceled transaction is attempted (andrei)
00050  *  2006-02-07  named routes support (andrei)
00051  *  2006-04-18  add_uac simplified + switched to struct dest_info (andrei)
00052  *  2006-04-20  pint_uac_request uses now struct dest_info (andrei)
00053  *  2006-08-11  dns failover support (andrei)
00054  *              t_forward_non_ack won't start retransmission on send errors
00055  *               anymore (WARNING: callers should release/kill the transaction
00056  *               if error is returned) (andrei)
00057  *  2006-09-15  e2e_cancel uses t_reply_unsafe when called from the 
00058  *               failure_route and replying to a cancel (andrei)
00059  *  2006-10-10  e2e_cancel update for the new/modified 
00060  *               which_cancel()/should_cancel() (andrei)
00061  *  2006-10-11  don't fork a new branch if the transaction or branch was
00062  *               canceled, or a 6xx was received
00063  *              stop retr. timers fix on cancel for non-invites     (andrei)
00064  *  2006-11-20  new_uri is no longer saved/restore across add_uac calls, since
00065  *              print_uac_request is now uri safe (andrei)
00066  *  2007-03-15  TMCB_ONSEND hooks added (andrei)
00067  *  2007-05-02  added t_forward_cancel(unmatched_cancel) (andrei)
00068  *  2007-05-24  added TMCB_E2ECANCEL_IN hook support (andrei)
00069  *  2007-05-28: e2e_cancel_branch() constructs the CANCEL from the
00070  *              outgoing INVITE instead of applying the lumps to the
00071  *              incomming one. (it can be disabled with reparse_invite=0) (Miklos)
00072  *              t_relay_cancel() introduced -- can be used to relay CANCELs
00073  *              at the beginning of the script. (Miklos)
00074  * 2007-06-04  running transaction are canceled hop by hop (andrei)
00075  * 2007-08-37  In case of DNS failover the new SIP message is constructed
00076  *              from the message buffer of the failed branch instead of
00077  *              applying the lumps again, because the per-branch lumps are no
00078  *              t saved, thus, are not available. Set reparse_on_dns_failover
00079  *              to 0 to revert the change. (Miklos)
00080  * 2008-06-04  T_CANCELED is now set each time a CANCEL is received (andrei)
00081  */
00082 
00083 #include "defs.h"
00084 
00085 
00086 #include "../../dprint.h"
00087 #include "../../config.h"
00088 #include "../../parser/parser_f.h"
00089 #include "../../ut.h"
00090 #include "../../timer.h"
00091 #include "../../hash_func.h"
00092 #include "../../globals.h"
00093 #include "../../cfg_core.h"
00094 #include "../../mem/mem.h"
00095 #include "../../dset.h"
00096 #include "../../action.h"
00097 #include "../../data_lump.h"
00098 #include "../../onsend.h"
00099 #include "../../compiler_opt.h"
00100 #include "t_funcs.h"
00101 #include "t_hooks.h"
00102 #include "t_msgbuilder.h"
00103 #include "ut.h"
00104 #include "t_cancel.h"
00105 #include "t_lookup.h"
00106 #include "t_fwd.h"
00107 #include "fix_lumps.h"
00108 #include "config.h"
00109 #ifdef USE_DNS_FAILOVER
00110 #include "../../dns_cache.h"
00111 #include "../../cfg_core.h" /* cfg_get(core, core_cfg, use_dns_failover) */
00112 #include "../../msg_translator.h"
00113 #include "lw_parser.h"
00114 #endif
00115 #ifdef USE_DST_BLACKLIST
00116 #include "../../dst_blacklist.h"
00117 #endif
00118 #include "../../select_buf.h" /* reset_static_buffer() */
00119 #ifdef POSTPONE_MSG_CLONING
00120 #include "../../atomic_ops.h" /* membar_depends() */
00121 #endif
00122 
00123 static int goto_on_branch = 0, branch_route = 0;
00124 
00125 void t_on_branch( unsigned int go_to )
00126 {
00127         struct cell *t = get_t();
00128 
00129        /* in MODE_REPLY and MODE_ONFAILURE T will be set to current transaction;
00130         * in MODE_REQUEST T will be set only if the transaction was already
00131         * created; if not -> use the static variable */
00132         if (!t || t==T_UNDEFINED ) {
00133                 goto_on_branch=go_to;
00134         } else {
00135                 get_t()->on_branch = go_to;
00136         }
00137 }
00138 
00139 unsigned int get_on_branch(void)
00140 {
00141         return goto_on_branch;
00142 }
00143 
00144 
00145 static char *print_uac_request( struct cell *t, struct sip_msg *i_req,
00146         int branch, str *uri, unsigned int *len, struct dest_info* dst)
00147 {
00148         char *buf, *shbuf;
00149         str* msg_uri;
00150         struct lump* add_rm_backup, *body_lumps_backup;
00151         struct sip_uri parsed_uri_bak;
00152         int parsed_uri_ok_bak, uri_backed_up;
00153         str msg_uri_bak;
00154         struct run_act_ctx ra_ctx;
00155 
00156         shbuf=0;
00157         msg_uri_bak.s=0; /* kill warnings */
00158         msg_uri_bak.len=0;
00159         parsed_uri_ok_bak=0;
00160         uri_backed_up=0;
00161 
00162         /* ... we calculate branch ... */       
00163         if (!t_calc_branch(t, branch, i_req->add_to_branch_s,
00164                         &i_req->add_to_branch_len ))
00165         {
00166                 LOG(L_ERR, "ERROR: print_uac_request: branch computation failed\n");
00167                 goto error00;
00168         }
00169 
00170         /* ... update uri ... */
00171         msg_uri=GET_RURI(i_req);
00172         if ((msg_uri->s!=uri->s) || (msg_uri->len!=uri->len)){
00173                 msg_uri_bak=i_req->new_uri;
00174                 parsed_uri_ok_bak=i_req->parsed_uri_ok;
00175                 parsed_uri_bak=i_req->parsed_uri;
00176                 i_req->new_uri=*uri;
00177                 i_req->parsed_uri_ok=0;
00178                 uri_backed_up=1;
00179         }
00180 
00181 #ifdef POSTPONE_MSG_CLONING
00182         /* lumps can be set outside of the lock, make sure that we read
00183          * the up-to-date values */
00184         membar_depends();
00185 #endif
00186         add_rm_backup = i_req->add_rm;
00187         body_lumps_backup = i_req->body_lumps;
00188         i_req->add_rm = dup_lump_list(i_req->add_rm);
00189         i_req->body_lumps = dup_lump_list(i_req->body_lumps);
00190 
00191         if (unlikely(branch_route)) {
00192                 reset_static_buffer();
00193                      /* run branch_route actions if provided */
00194                 init_run_actions_ctx(&ra_ctx);
00195                 if (run_actions(&ra_ctx, branch_rt.rlist[branch_route], i_req) < 0) {
00196                         LOG(L_ERR, "ERROR: print_uac_request: Error in run_actions\n");
00197                }
00198         }
00199 
00200         /* run the specific callbacks for this transaction */
00201         if (unlikely(has_tran_tmcbs(t, TMCB_REQUEST_FWDED)))
00202                 run_trans_callbacks( TMCB_REQUEST_FWDED , t, i_req, 0,
00203                                                                 -i_req->REQ_METHOD);
00204 
00205         /* ... and build it now */
00206         buf=build_req_buf_from_sip_req( i_req, len, dst);
00207 #ifdef DBG_MSG_QA
00208         if (buf[*len-1]==0) {
00209                 LOG(L_ERR, "ERROR: print_uac_request: sanity check failed\n");
00210                 abort();
00211         }
00212 #endif
00213         if (!buf) {
00214                 LOG(L_ERR, "ERROR: print_uac_request: no pkg_mem\n"); 
00215                 ser_error=E_OUT_OF_MEM;
00216                 goto error01;
00217         }
00218 
00219         shbuf=(char *)shm_malloc(*len);
00220         if (!shbuf) {
00221                 ser_error=E_OUT_OF_MEM;
00222                 LOG(L_ERR, "ERROR: print_uac_request: no shmem\n");
00223                 goto error02;
00224         }
00225         memcpy( shbuf, buf, *len );
00226 
00227 error02:
00228         pkg_free( buf );
00229 error01:
00230              /* Delete the duplicated lump lists, this will also delete
00231               * all lumps created here, such as lumps created in per-branch
00232               * routing sections, Via, and Content-Length headers created in
00233               * build_req_buf_from_sip_req
00234               */
00235         free_duped_lump_list(i_req->add_rm);
00236         free_duped_lump_list(i_req->body_lumps);
00237              /* Restore the lists from backups */
00238         i_req->add_rm = add_rm_backup;
00239         i_req->body_lumps = body_lumps_backup;
00240         /* restore the new_uri from the backup */
00241         if (uri_backed_up){
00242                 i_req->new_uri=msg_uri_bak;
00243                 i_req->parsed_uri=parsed_uri_bak;
00244                 i_req->parsed_uri_ok=parsed_uri_ok_bak;
00245         }
00246 
00247  error00:
00248         return shbuf;
00249 }
00250 
00251 #ifdef USE_DNS_FAILOVER
00252 /* Similar to print_uac_request(), but this function uses the outgoing message buffer of
00253    the failed branch to construt the new message in case of DNS failover.
00254 
00255    WARNING: only the first VIA header is replaced in the buffer, the rest
00256    of the message is untuched, thus, the send socket is corrected only in the VIA HF.
00257 */
00258 static char *print_uac_request_from_buf( struct cell *t, struct sip_msg *i_req,
00259         int branch, str *uri, unsigned int *len, struct dest_info* dst,
00260         char *buf, short buf_len)
00261 {
00262         char *shbuf;
00263         str branch_str;
00264         char *via, *old_via_begin, *old_via_end;
00265         unsigned int via_len;
00266 
00267         shbuf=0;
00268 
00269         /* ... we calculate branch ... */       
00270         if (!t_calc_branch(t, branch, i_req->add_to_branch_s,
00271                         &i_req->add_to_branch_len ))
00272         {
00273                 LOG(L_ERR, "ERROR: print_uac_request_from_buf: branch computation failed\n");
00274                 goto error00;
00275         }
00276         branch_str.s = i_req->add_to_branch_s;
00277         branch_str.len = i_req->add_to_branch_len;
00278 
00279         /* find the beginning of the first via header in the buffer */
00280         old_via_begin = lw_find_via(buf, buf+buf_len);
00281         if (!old_via_begin) {
00282                 LOG(L_ERR, "ERROR: print_uac_request_from_buf: beginning of via header not found\n");
00283                 goto error00;
00284         }
00285         /* find the end of the first via header in the buffer */
00286         old_via_end = lw_next_line(old_via_begin, buf+buf_len);
00287         if (!old_via_end) {
00288                 LOG(L_ERR, "ERROR: print_uac_request_from_buf: end of via header not found\n");
00289                 goto error00;
00290         }
00291 
00292         /* create the new VIA HF */
00293         via = create_via_hf(&via_len, i_req, dst, &branch_str);
00294         if (!via) {
00295                 LOG(L_ERR, "ERROR: print_uac_request_from_buf: via building failed\n");
00296                 goto error00;
00297         }
00298 
00299         /* allocate memory for the new buffer */
00300         *len = buf_len + via_len - (old_via_end - old_via_begin);
00301         shbuf=(char *)shm_malloc(*len);
00302         if (!shbuf) {
00303                 ser_error=E_OUT_OF_MEM;
00304                 LOG(L_ERR, "ERROR: print_uac_request_from_buf: no shmem\n");
00305                 goto error01;
00306         }
00307 
00308         /* construct the new buffer */
00309         memcpy(shbuf, buf, old_via_begin-buf);
00310         memcpy(shbuf+(old_via_begin-buf), via, via_len);
00311         memcpy(shbuf+(old_via_begin-buf)+via_len, old_via_end, (buf+buf_len)-old_via_end);
00312 
00313 #ifdef DBG_MSG_QA
00314         if (shbuf[*len-1]==0) {
00315                 LOG(L_ERR, "ERROR: print_uac_request_from_buf: sanity check failed\n");
00316                 abort();
00317         }
00318 #endif
00319 
00320 error01:
00321         pkg_free(via);
00322 error00:
00323         return shbuf;
00324 }
00325 #endif
00326 
00327 /* introduce a new uac, which is blind -- it only creates the
00328    data structures and starts FR timer, but that's it; it does
00329    not print messages and send anything anywhere; that is good
00330    for FIFO apps -- the transaction must look operationally
00331    and FR must be ticking, whereas the request is "forwarded"
00332    using a non-SIP way and will be replied the same way
00333 */
00334 int add_blind_uac( /*struct cell *t*/ )
00335 {
00336         unsigned short branch;
00337         struct cell *t;
00338 
00339         t=get_t();
00340         if (t==T_UNDEFINED || !t ) {
00341                 LOG(L_ERR, "ERROR: add_blind_uac: no transaction context\n");
00342                 return -1;
00343         }
00344 
00345         branch=t->nr_of_outgoings;      
00346         if (branch==MAX_BRANCHES) {
00347                 LOG(L_ERR, "ERROR: add_blind_uac: "
00348                         "maximum number of branches exceeded\n");
00349                 return -1;
00350         }
00351         /* make sure it will be replied */
00352         t->flags |= T_NOISY_CTIMER_FLAG;
00353         membar_write(); /* to allow lockless which_cancel() we want to be sure 
00354                                            all the writes finished before updating branch number*/
00355         t->nr_of_outgoings=(branch+1);
00356         /* start FR timer -- protocol set by default to PROTO_NONE,
00357        which means retransmission timer will not be started
00358     */
00359         if (start_retr(&t->uac[branch].request)!=0)
00360                 LOG(L_CRIT, "BUG: add_blind_uac: start retr failed for %p\n",
00361                                 &t->uac[branch].request);
00362         /* we are on a timer -- don't need to put on wait on script
00363            clean-up     
00364         */
00365         set_kr(REQ_FWDED); 
00366 
00367         return 1; /* success */
00368 }
00369 
00370 /* introduce a new uac to transaction; returns its branch id (>=0)
00371    or error (<0); it doesn't send a message yet -- a reply to it
00372    might interfere with the processes of adding multiple branches;
00373    On error returns <0 & sets ser_error to the same value
00374 */
00375 int add_uac( struct cell *t, struct sip_msg *request, str *uri, str* next_hop,
00376         struct proxy_l *proxy, int proto )
00377 {
00378 
00379         int ret;
00380         unsigned short branch;
00381         char *shbuf;
00382         unsigned int len;
00383 
00384         branch=t->nr_of_outgoings;
00385         if (branch==MAX_BRANCHES) {
00386                 LOG(L_ERR, "ERROR: add_uac: maximum number of branches exceeded\n");
00387                 ret=ser_error=E_TOO_MANY_BRANCHES;
00388                 goto error;
00389         }
00390 
00391         /* check existing buffer -- rewriting should never occur */
00392         if (t->uac[branch].request.buffer) {
00393                 LOG(L_CRIT, "ERROR: add_uac: buffer rewrite attempt\n");
00394                 ret=ser_error=E_BUG;
00395                 goto error;
00396         }
00397 
00398         /* check DNS resolution */
00399         if (proxy){
00400                 /* dst filled from the proxy */
00401                 init_dest_info(&t->uac[branch].request.dst);
00402                 t->uac[branch].request.dst.proto=get_proto(proto, proxy->proto);
00403                 proxy2su(&t->uac[branch].request.dst.to, proxy);
00404                 /* fill dst send_sock */
00405                 t->uac[branch].request.dst.send_sock =
00406                 get_send_socket( request, &t->uac[branch].request.dst.to,
00407                                                                 t->uac[branch].request.dst.proto);
00408         }else {
00409 #ifdef USE_DNS_FAILOVER
00410                 if (uri2dst(&t->uac[branch].dns_h, &t->uac[branch].request.dst,
00411                                         request, next_hop?next_hop:uri, proto) == 0)
00412 #else
00413                 /* dst filled from the uri & request (send_socket) */
00414                 if (uri2dst(&t->uac[branch].request.dst, request,
00415                                                 next_hop ? next_hop: uri, proto)==0)
00416 #endif
00417                 {
00418                         ret=ser_error=E_BAD_ADDRESS;
00419                         goto error;
00420                 }
00421         }
00422         
00423         /* check if send_sock is ok */
00424         if (t->uac[branch].request.dst.send_sock==0) {
00425                 LOG(L_ERR, "ERROR: add_uac: can't fwd to af %d, proto %d "
00426                         " (no corresponding listening socket)\n",
00427                         t->uac[branch].request.dst.to.s.sa_family, 
00428                         t->uac[branch].request.dst.proto );
00429                 ret=ser_error=E_NO_SOCKET;
00430                 goto error01;
00431         }
00432 
00433         /* now message printing starts ... */
00434         shbuf=print_uac_request( t, request, branch, uri, 
00435                                                         &len, &t->uac[branch].request.dst);
00436         if (!shbuf) {
00437                 ret=ser_error=E_OUT_OF_MEM;
00438                 goto error01;
00439         }
00440 
00441         /* things went well, move ahead and install new buffer! */
00442         t->uac[branch].request.buffer=shbuf;
00443         t->uac[branch].request.buffer_len=len;
00444         t->uac[branch].uri.s=t->uac[branch].request.buffer+
00445                 request->first_line.u.request.method.len+1;
00446         t->uac[branch].uri.len=uri->len;
00447         membar_write(); /* to allow lockless ops (e.g. which_cancel()) we want
00448                                            to be sure everything above is fully written before
00449                                            updating branches no. */
00450         t->nr_of_outgoings=(branch+1);
00451 
00452         /* update stats */
00453         if (proxy){
00454                 proxy_mark(proxy, 1);
00455         }
00456         /* done! */
00457         ret=branch;
00458                 
00459 error01:
00460 error:
00461         return ret;
00462 }
00463 
00464 
00465 
00466 #ifdef USE_DNS_FAILOVER
00467 /* Similar to add_uac(), but this function uses the outgoing message buffer of
00468    the failed branch to construt the new message in case of DNS failover.
00469 */
00470 static int add_uac_from_buf( struct cell *t, struct sip_msg *request, str *uri, int proto,
00471                         char *buf, short buf_len)
00472 {
00473 
00474         int ret;
00475         unsigned short branch;
00476         char *shbuf;
00477         unsigned int len;
00478 
00479         branch=t->nr_of_outgoings;
00480         if (branch==MAX_BRANCHES) {
00481                 LOG(L_ERR, "ERROR: add_uac_from_buf: maximum number of branches exceeded\n");
00482                 ret=ser_error=E_TOO_MANY_BRANCHES;
00483                 goto error;
00484         }
00485 
00486         /* check existing buffer -- rewriting should never occur */
00487         if (t->uac[branch].request.buffer) {
00488                 LOG(L_CRIT, "ERROR: add_uac_from_buf: buffer rewrite attempt\n");
00489                 ret=ser_error=E_BUG;
00490                 goto error;
00491         }
00492 
00493         if (uri2dst(&t->uac[branch].dns_h, &t->uac[branch].request.dst,
00494                                 request, uri, proto) == 0)
00495         {
00496                 ret=ser_error=E_BAD_ADDRESS;
00497                 goto error;
00498         }
00499         
00500         /* check if send_sock is ok */
00501         if (t->uac[branch].request.dst.send_sock==0) {
00502                 LOG(L_ERR, "ERROR: add_uac_from_buf: can't fwd to af %d, proto %d "
00503                         " (no corresponding listening socket)\n",
00504                         t->uac[branch].request.dst.to.s.sa_family, 
00505                         t->uac[branch].request.dst.proto );
00506                 ret=ser_error=E_NO_SOCKET;
00507                 goto error;
00508         }
00509 
00510         /* now message printing starts ... */
00511         shbuf=print_uac_request_from_buf( t, request, branch, uri, 
00512                                                         &len, &t->uac[branch].request.dst,
00513                                                         buf, buf_len);
00514         if (!shbuf) {
00515                 ret=ser_error=E_OUT_OF_MEM;
00516                 goto error;
00517         }
00518 
00519         /* things went well, move ahead and install new buffer! */
00520         t->uac[branch].request.buffer=shbuf;
00521         t->uac[branch].request.buffer_len=len;
00522         t->uac[branch].uri.s=t->uac[branch].request.buffer+
00523                 request->first_line.u.request.method.len+1;
00524         t->uac[branch].uri.len=uri->len;
00525         membar_write(); /* to allow lockless ops (e.g. which_cancel()) we want
00526                                            to be sure everything above is fully written before
00527                                            updating branches no. */
00528         t->nr_of_outgoings=(branch+1);
00529 
00530         /* done! */
00531         ret=branch;
00532                 
00533 error:
00534         return ret;
00535 }
00536 
00537 /* introduce a new uac to transaction, based on old_uac and a possible
00538  *  new ip address (if the dns name resolves to more ips). If no more
00539  *   ips are found => returns -1.
00540  *  returns its branch id (>=0)
00541    or error (<0) and sets ser_error if needed; it doesn't send a message 
00542    yet -- a reply to it
00543    might interfere with the processes of adding multiple branches
00544    if lock_replies is 1 replies will be locked for t until the new branch
00545    is added (to prevent add branches races). Use 0 if the reply lock is
00546    already held, e.g. in failure route/handlers (WARNING: using 1 in a 
00547    failure route will cause a deadlock).
00548 */
00549 int add_uac_dns_fallback( struct cell *t, struct sip_msg* msg, 
00550                                                                         struct ua_client* old_uac,
00551                                                                         int lock_replies)
00552 {
00553         int ret;
00554         
00555         ret=-1;
00556         if (cfg_get(core, core_cfg, use_dns_failover) && 
00557                         !((t->flags & T_DONT_FORK) || uac_dont_fork(old_uac)) &&
00558                         dns_srv_handle_next(&old_uac->dns_h, 0)){
00559                         if (lock_replies){
00560                                 /* use reply lock to guarantee nobody is adding a branch
00561                                  * in the same time */
00562                                 LOCK_REPLIES(t);
00563                                 /* check again that we can fork */
00564                                 if ((t->flags & T_DONT_FORK) || uac_dont_fork(old_uac)){
00565                                         UNLOCK_REPLIES(t);
00566                                         DBG("add_uac_dns_fallback: no forking on => no new"
00567                                                         " branches\n");
00568                                         return ret;
00569                                 }
00570                         }
00571                         if (t->nr_of_outgoings >= MAX_BRANCHES){
00572                                 LOG(L_ERR, "ERROR: add_uac_dns_fallback: maximum number of "
00573                                                         "branches exceeded\n");
00574                                 if (lock_replies)
00575                                         UNLOCK_REPLIES(t);
00576                                         ret=ser_error=E_TOO_MANY_BRANCHES;
00577                                 return ret;
00578                         }
00579                         /* copy the dns handle into the new uac */
00580                         dns_srv_handle_cpy(&t->uac[t->nr_of_outgoings].dns_h,
00581                                                                 &old_uac->dns_h);
00582 
00583                         if (cfg_get(tm, tm_cfg, reparse_on_dns_failover))
00584                                 /* Reuse the old buffer and only replace the via header.
00585                                  * The drowback is that the send_socket is not corrected
00586                                  * in the rest of the message, only in the VIA HF (Miklos) */
00587                                 ret=add_uac_from_buf(t,  msg, &old_uac->uri, 
00588                                                         old_uac->request.dst.proto,
00589                                                         old_uac->request.buffer,
00590                                                         old_uac->request.buffer_len);
00591                         else
00592                                 /* add_uac will use dns_h => next_hop will be ignored.
00593                                  * Unfortunately we can't reuse the old buffer, the branch id
00594                                  *  must be changed and the send_socket might be different =>
00595                                  *  re-create the whole uac */
00596                                 ret=add_uac(t,  msg, &old_uac->uri, 0, 0, 
00597                                                         old_uac->request.dst.proto);
00598 
00599                         if (ret<0){
00600                                 /* failed, delete the copied dns_h */
00601                                 dns_srv_handle_put(&t->uac[t->nr_of_outgoings].dns_h);
00602                         }
00603                         if (lock_replies){
00604                                 UNLOCK_REPLIES(t);
00605                         }
00606         }
00607         return ret;
00608 }
00609 
00610 #endif
00611 
00612 int e2e_cancel_branch( struct sip_msg *cancel_msg, struct cell *t_cancel, 
00613         struct cell *t_invite, int branch )
00614 {
00615         int ret;
00616         char *shbuf;
00617         unsigned int len;
00618 
00619         ret=-1;
00620         if (t_cancel->uac[branch].request.buffer) {
00621                 LOG(L_CRIT, "ERROR: e2e_cancel_branch: buffer rewrite attempt\n");
00622                 ret=ser_error=E_BUG;
00623                 goto error;
00624         }
00625         if (t_invite->uac[branch].request.buffer==0){
00626                 /* inactive / deleted  branch */
00627                 goto error;
00628         }
00629         t_invite->uac[branch].request.flags|=F_RB_CANCELED;
00630 
00631         /* note -- there is a gap in proxy stats -- we don't update 
00632            proxy stats with CANCEL (proxy->ok, proxy->tx, etc.)
00633         */
00634 
00635         /* print */
00636         if (cfg_get(tm, tm_cfg, reparse_invite)) {
00637                 /* buffer is built localy from the INVITE which was sent out */
00638 #ifdef POSTPONE_MSG_CLONING
00639                 /* lumps can be set outside of the lock, make sure that we read
00640                  * the up-to-date values */
00641                 membar_depends();
00642 #endif
00643                 if (cancel_msg->add_rm || cancel_msg->body_lumps) {
00644                         LOG(L_WARN, "WARNING: e2e_cancel_branch: CANCEL is built locally, "
00645                         "thus lumps are not applied to the message!\n");
00646                 }
00647                 shbuf=build_local_reparse( t_invite, branch, &len, CANCEL, CANCEL_LEN, &t_invite->to);
00648 
00649         } else {
00650                 /* buffer is constructed from the received CANCEL with applying lumps */
00651                 shbuf=print_uac_request( t_cancel, cancel_msg, branch, 
00652                                                         &t_invite->uac[branch].uri, &len, 
00653                                                         &t_invite->uac[branch].request.dst);
00654         }
00655 
00656         if (!shbuf) {
00657                 LOG(L_ERR, "ERROR: e2e_cancel_branch: printing e2e cancel failed\n");
00658                 ret=ser_error=E_OUT_OF_MEM;
00659                 goto error;
00660         }
00661         
00662         /* install buffer */
00663         t_cancel->uac[branch].request.dst=t_invite->uac[branch].request.dst;
00664         t_cancel->uac[branch].request.buffer=shbuf;
00665         t_cancel->uac[branch].request.buffer_len=len;
00666         t_cancel->uac[branch].uri.s=t_cancel->uac[branch].request.buffer+
00667                 cancel_msg->first_line.u.request.method.len+1;
00668         t_cancel->uac[branch].uri.len=t_invite->uac[branch].uri.len;
00669         
00670 
00671         /* success */
00672         ret=1;
00673 
00674 
00675 error:
00676         return ret;
00677 }
00678 
00679 void e2e_cancel( struct sip_msg *cancel_msg, 
00680         struct cell *t_cancel, struct cell *t_invite )
00681 {
00682         branch_bm_t cancel_bm;
00683 #ifndef E2E_CANCEL_HOP_BY_HOP
00684         branch_bm_t tmp_bm;
00685 #endif
00686         int i;
00687         int lowest_error;
00688         int ret;
00689         struct tmcb_params tmcb;
00690 
00691         cancel_bm=0;
00692         lowest_error=0;
00693 
00694         if (unlikely(has_tran_tmcbs(t_invite, TMCB_E2ECANCEL_IN))){
00695                 INIT_TMCB_PARAMS(tmcb, cancel_msg, 0, cancel_msg->REQ_METHOD);
00696                 run_trans_callbacks_internal(&t_invite->tmcb_hl, TMCB_E2ECANCEL_IN, 
00697                                                                                 t_invite, &tmcb);
00698         }
00699         /* mark transaction as canceled, so that no new message are forwarded
00700          * on it and t_is_canceled() returns true 
00701          * WARNING: it's safe to do it without locks, at least for now (in a race
00702          * event even if a flag is unwillingly reset nothing bad will happen),
00703          * however this should be rechecked for any future new flags use.
00704          */
00705         t_invite->flags|=T_CANCELED;
00706         /* first check if there are any branches */
00707         if (t_invite->nr_of_outgoings==0){
00708                 /* no branches yet => force a reply to the invite */
00709                 t_reply( t_invite, t_invite->uas.request, 487, CANCELED );
00710                 DBG("DEBUG: e2e_cancel: e2e cancel -- no more pending branches\n");
00711                 t_reply( t_cancel, cancel_msg, 200, CANCEL_DONE );
00712                 return;
00713         }
00714         
00715         /* determine which branches to cancel ... */
00716         which_cancel( t_invite, &cancel_bm );
00717 #ifdef E2E_CANCEL_HOP_BY_HOP
00718         /* we don't need to set t_cancel label to be the same as t_invite if
00719          * we do hop by hop cancel. The cancel transaction will have a different 
00720          * label, but this is not a problem since this transaction is only used to
00721          * send a reply back. The cancels sent upstream will be part of the invite
00722          * transaction (local_cancel retr. bufs) and they will be generated with
00723          * the same via as the invite.
00724          * Note however that setting t_cancel label the same as t_invite will work
00725          * too (the upstream cancel replies will properly match the t_invite
00726          * transaction and will not match the t_cancel because t_cancel will always
00727          * have 0 branches and we check for the branch number in 
00728          * t_reply_matching() ).
00729          */
00730         for (i=0; i<t_invite->nr_of_outgoings; i++)
00731                 if (cancel_bm & (1<<i)) {
00732                         /* it's safe to get the reply lock since e2e_cancel is
00733                          * called with the cancel as the "current" transaction so
00734                          * at most t_cancel REPLY_LOCK is held in this process =>
00735                          * no deadlock possibility */
00736                         ret=cancel_branch(
00737                                 t_invite,
00738                                 i,
00739                                 cfg_get(tm,tm_cfg, cancel_b_flags)
00740                                         | ((t_invite->uac[i].request.buffer==NULL)?
00741                                                 F_CANCEL_B_FAKE_REPLY:0) /* blind UAC? */
00742                         );
00743                         if (ret<0) cancel_bm &= ~(1<<i);
00744                         if (ret<lowest_error) lowest_error=ret;
00745                 }
00746 #else /* ! E2E_CANCEL_HOP_BY_HOP */
00747         /* fix label -- it must be same for reply matching (the label is part of
00748          * the generated via branch for the cancels sent upstream and if it
00749          * would be different form the one in the INVITE the transactions would not
00750          * match */
00751         t_cancel->label=t_invite->label;
00752         t_cancel->nr_of_outgoings=t_invite->nr_of_outgoings;
00753         /* ... and install CANCEL UACs */
00754         for (i=0; i<t_invite->nr_of_outgoings; i++)
00755                 if ((cancel_bm & (1<<i)) && (t_invite->uac[i].last_received>=100)) {
00756                         ret=e2e_cancel_branch(cancel_msg, t_cancel, t_invite, i);
00757                         if (ret<0) cancel_bm &= ~(1<<i);
00758                         if (ret<lowest_error) lowest_error=ret;
00759                 }
00760 
00761         /* send them out */
00762         for (i = 0; i < t_cancel->nr_of_outgoings; i++) {
00763                 if (cancel_bm & (1 << i)) {
00764                         if (t_invite->uac[i].last_received>=100){
00765                                 /* Provisional reply received on this branch, send CANCEL */
00766                                 /* we do need to stop the retr. timers if the request is not 
00767                                  * an invite and since the stop_rb_retr() cost is lower then
00768                                  * the invite check we do it always --andrei */
00769                                 stop_rb_retr(&t_invite->uac[i].request);
00770                                 if (SEND_BUFFER(&t_cancel->uac[i].request) == -1) {
00771                                         LOG(L_ERR, "ERROR: e2e_cancel: send failed\n");
00772                                 }
00773 #ifdef TMCB_ONSEND
00774                                 else{
00775                                         if (unlikely(has_tran_tmcbs(t_cancel, TMCB_REQUEST_SENT)))
00776                                                 run_onsend_callbacks(TMCB_REQUEST_SENT, 
00777                                                                                                 &t_cancel->uac[i].request,
00778                                                                                                 cancel_msg, 0, TMCB_LOCAL_F);
00779                                 }
00780 #endif
00781                                 if (start_retr( &t_cancel->uac[i].request )!=0)
00782                                         LOG(L_CRIT, "BUG: e2e_cancel: failed to start retr."
00783                                                         " for %p\n", &t_cancel->uac[i].request);
00784                         } else {
00785                                 /* No provisional response received, stop
00786                                  * retransmission timers */
00787                                 if (!(cfg_get(tm, tm_cfg, cancel_b_flags) & 
00788                                                         F_CANCEL_B_FORCE_RETR))
00789                                         stop_rb_retr(&t_invite->uac[i].request);
00790                                 /* no need to stop fr, it will be stopped by relay_reply
00791                                  * put_on_wait -- andrei */
00792                                 /* Generate faked reply */
00793                                 if (cfg_get(tm, tm_cfg, cancel_b_flags) &
00794                                                 F_CANCEL_B_FAKE_REPLY){
00795                                         LOCK_REPLIES(t_invite);
00796                                         if (relay_reply(t_invite, FAKED_REPLY, i,
00797                                                                         487, &tmp_bm, 1) == RPS_ERROR) {
00798                                                 lowest_error = -1;
00799                                         }
00800                                 }
00801                         }
00802                 }
00803         }
00804 #endif /*E2E_CANCEL_HOP_BY_HOP */
00805 
00806         /* if error occurred, let it know upstream (final reply
00807            will also move the transaction on wait state
00808         */
00809         if (lowest_error<0) {
00810                 LOG(L_ERR, "ERROR: cancel error\n");
00811                 /* if called from failure_route, make sure that the unsafe version
00812                  * is called (we are already holding the reply mutex for the cancel
00813                  * transaction).
00814                  */
00815                 if ((rmode==MODE_ONFAILURE) && (t_cancel==get_t()))
00816                         t_reply_unsafe( t_cancel, cancel_msg, 500, "cancel error");
00817                 else
00818                         t_reply( t_cancel, cancel_msg, 500, "cancel error");
00819         } else if (cancel_bm) {
00820                 /* if there are pending branches, let upstream know we
00821                    are working on it
00822                 */
00823                 DBG("DEBUG: e2e_cancel: e2e cancel proceeding\n");
00824                 /* if called from failure_route, make sure that the unsafe version
00825                  * is called (we are already hold the reply mutex for the cancel
00826                  * transaction).
00827                  */
00828                 if ((rmode==MODE_ONFAILURE) && (t_cancel==get_t()))
00829                         t_reply_unsafe( t_cancel, cancel_msg, 200, CANCELING );
00830                 else
00831                         t_reply( t_cancel, cancel_msg, 200, CANCELING );
00832         } else {
00833                 /* if the transaction exists, but there are no more pending
00834                    branches, tell upstream we're done
00835                 */
00836                 DBG("DEBUG: e2e_cancel: e2e cancel -- no more pending branches\n");
00837                 /* if called from failure_route, make sure that the unsafe version
00838                  * is called (we are already hold the reply mutex for the cancel
00839                  * transaction).
00840                  */
00841                 if ((rmode==MODE_ONFAILURE) && (t_cancel==get_t()))
00842                         t_reply_unsafe( t_cancel, cancel_msg, 200, CANCEL_DONE );
00843                 else
00844                         t_reply( t_cancel, cancel_msg, 200, CANCEL_DONE );
00845         }
00846 }
00847 
00848 
00849 
00850 /* sends one uac/branch buffer and fallbacks to other ips if
00851  *  the destination resolves to several addresses
00852  *  Takes care of starting timers a.s.o. (on send success)
00853  *  returns: -2 on error, -1 on drop,  current branch id on success,
00854  *   new branch id on send error/blacklist, when failover is possible
00855  *    (ret>=0 && ret!=branch)
00856  *    if lock_replies is 1, the replies for t will be locked when adding
00857  *     new branches (to prevent races). Use 0 from failure routes or other
00858  *     places where the reply lock is already held, to avoid deadlocks. */
00859 int t_send_branch( struct cell *t, int branch, struct sip_msg* p_msg ,
00860                                         struct proxy_l * proxy, int lock_replies)
00861 {
00862         struct ip_addr ip; /* debugging */
00863         int ret;
00864         struct ua_client* uac;
00865         
00866         uac=&t->uac[branch];
00867         ret=branch;
00868         if (run_onsend(p_msg,   &uac->request.dst, uac->request.buffer,
00869                                         uac->request.buffer_len)==0){
00870                 /* disable the current branch: set a "fake" timeout
00871                  *  reply code but don't set uac->reply, to avoid overriding 
00872                  *  a higly unlikely, perfectly timed fake reply (to a message
00873                  *   we never sent).
00874                  * (code=final reply && reply==0 => t_pick_branch won't ever pick it)*/
00875                         uac->last_received=408;
00876                         su2ip_addr(&ip, &uac->request.dst.to);
00877                         DBG("t_send_branch: onsend_route dropped msg. to %s:%d (%d)\n",
00878                                                         ip_addr2a(&ip), su_getport(&uac->request.dst.to),
00879                                                         uac->request.dst.proto);
00880 #ifdef USE_DNS_FAILOVER
00881                         /* if the destination resolves to more ips, add another
00882                          *  branch/uac */
00883                         if (cfg_get(core, core_cfg, use_dns_failover)){
00884                                 ret=add_uac_dns_fallback(t, p_msg, uac, lock_replies);
00885                                 if (ret>=0){
00886                                         su2ip_addr(&ip, &uac->request.dst.to);
00887                                         DBG("t_send_branch: send on branch %d failed "
00888                                                         "(onsend_route), trying another ip %s:%d (%d)\n",
00889                                                         branch, ip_addr2a(&ip),
00890                                                         su_getport(&uac->request.dst.to),
00891                                                         uac->request.dst.proto);
00892                                         /* success, return new branch */
00893                                         return ret;
00894                                 }
00895                         }
00896 #endif /* USE_DNS_FAILOVER*/
00897                 return -1; /* drop, try next branch */
00898         }
00899 #ifdef USE_DST_BLACKLIST
00900         if (cfg_get(core, core_cfg, use_dst_blacklist)
00901                 && p_msg
00902                 && (p_msg->REQ_METHOD & cfg_get(tm, tm_cfg, tm_blst_methods_lookup))
00903         ){
00904                 if (dst_is_blacklisted(&uac->request.dst, p_msg)){
00905                         su2ip_addr(&ip, &uac->request.dst.to);
00906                         DBG("t_send_branch: blacklisted destination: %s:%d (%d)\n",
00907                                                         ip_addr2a(&ip), su_getport(&uac->request.dst.to),
00908                                                         uac->request.dst.proto);
00909                         /* disable the current branch: set a "fake" timeout
00910                          *  reply code but don't set uac->reply, to avoid overriding 
00911                          *  a higly unlikely, perfectly timed fake reply (to a message
00912                          *   we never sent).  (code=final reply && reply==0 => 
00913                          *   t_pick_branch won't ever pick it)*/
00914                         uac->last_received=408;
00915 #ifdef USE_DNS_FAILOVER
00916                         /* if the destination resolves to more ips, add another
00917                          *  branch/uac */
00918                         if (cfg_get(core, core_cfg, use_dns_failover)){
00919                                 ret=add_uac_dns_fallback(t, p_msg, uac, lock_replies);
00920                                 if (ret>=0){
00921                                         su2ip_addr(&ip, &uac->request.dst.to);
00922                                         DBG("t_send_branch: send on branch %d failed (blacklist),"
00923                                                         " trying another ip %s:%d (%d)\n", branch,
00924                                                         ip_addr2a(&ip), su_getport(&uac->request.dst.to),
00925                                                         uac->request.dst.proto);
00926                                         /* success, return new branch */
00927                                         return ret;
00928                                 }
00929                         }
00930 #endif /* USE_DNS_FAILOVER*/
00931                         return -1; /* don't send */
00932                 }
00933         }
00934 #endif /* USE_DST_BLACKLIST */
00935         if (SEND_BUFFER( &uac->request)==-1) {
00936                 /* disable the current branch: set a "fake" timeout
00937                  *  reply code but don't set uac->reply, to avoid overriding 
00938                  *  a highly unlikely, perfectly timed fake reply (to a message
00939                  *  we never sent).
00940                  * (code=final reply && reply==0 => t_pick_branch won't ever pick it)*/
00941                 uac->last_received=408;
00942                 su2ip_addr(&ip, &uac->request.dst.to);
00943                 DBG("t_send_branch: send to %s:%d (%d) failed\n",
00944                                                         ip_addr2a(&ip), su_getport(&uac->request.dst.to),
00945                                                         uac->request.dst.proto);
00946 #ifdef USE_DST_BLACKLIST
00947                 if (cfg_get(core, core_cfg, use_dst_blacklist))
00948                         dst_blacklist_add(BLST_ERR_SEND, &uac->request.dst, p_msg);
00949 #endif
00950 #ifdef USE_DNS_FAILOVER
00951                 /* if the destination resolves to more ips, add another
00952                  *  branch/uac */
00953                 if (cfg_get(core, core_cfg, use_dns_failover)){
00954                         ret=add_uac_dns_fallback(t, p_msg, uac, lock_replies);
00955                         if (ret>=0){
00956                                 /* success, return new branch */
00957                                 DBG("t_send_branch: send on branch %d failed, adding another"
00958                                                 " branch with another ip\n", branch);
00959                                 return ret;
00960                         }
00961                 }
00962 #endif
00963                 LOG(L_ERR, "ERROR: t_send_branch: sending request on branch %d "
00964                                 "failed\n", branch);
00965                 if (proxy) { proxy->errors++; proxy->ok=0; }
00966                 return -2;
00967         } else {
00968 #ifdef TMCB_ONSEND
00969                 if (unlikely(has_tran_tmcbs(t, TMCB_REQUEST_SENT)))
00970                         run_onsend_callbacks(TMCB_REQUEST_SENT, &uac->request, p_msg, 0,0);
00971 #endif
00972                 /* start retr. only if the send succeeded */
00973                 if (start_retr( &uac->request )!=0){
00974                         LOG(L_CRIT, "BUG: t_send_branch: retr. already started for %p\n",
00975                                         &uac->request);
00976                         return -2;
00977                 }
00978         }
00979         return ret;
00980 }
00981 
00982 
00983 
00984 /* function returns:
00985  *       1 - forward successful
00986  *      -1 - error during forward
00987  */
00988 int t_forward_nonack( struct cell *t, struct sip_msg* p_msg , 
00989         struct proxy_l * proxy, int proto)
00990 {
00991         int branch_ret, lowest_ret;
00992         str current_uri;
00993         branch_bm_t     added_branches;
00994         int first_branch;
00995         int i, q;
00996         struct cell *t_invite;
00997         int success_branch;
00998         int try_new;
00999         int lock_replies;
01000         str dst_uri;
01001         struct socket_info* si, *backup_si;
01002         
01003 
01004         /* make -Wall happy */
01005         current_uri.s=0;
01006 
01007         if (t->flags & T_CANCELED){
01008                 DBG("t_forward_non_ack: no forwarding on a canceled transaction\n");
01009                 ser_error=E_CANCELED;
01010                 return -1;
01011         }
01012         if (p_msg->REQ_METHOD==METHOD_CANCEL) { 
01013                 t_invite=t_lookupOriginalT(  p_msg );
01014                 if (t_invite!=T_NULL_CELL) {
01015                         e2e_cancel( p_msg, t, t_invite );
01016                         UNREF(t_invite);
01017                         /* it should be set to REQ_RPLD by e2e_cancel, which should
01018                          * send a final reply */
01019                         set_kr(REQ_FWDED);
01020                         return 1;
01021                 }
01022         }
01023 
01024         backup_si = p_msg->force_send_socket;
01025         /* if no more specific error code is known, use this */
01026         lowest_ret=E_UNSPEC;
01027         /* branches added */
01028         added_branches=0;
01029         /* branch to begin with */
01030         first_branch=t->nr_of_outgoings;
01031 
01032         if (t->on_branch) {
01033                 /* tell add_uac that it should run branch route actions */
01034                 branch_route = t->on_branch;
01035                 /* reset the flag before running the actions (so that it
01036                  * could be set again in branch_route if needed
01037                  */
01038                 t_on_branch(0);
01039         } else {
01040                 branch_route = 0;
01041         }
01042         
01043         /* on first-time forwarding, use current uri, later only what
01044            is in additional branches (which may be continuously refilled
01045         */
01046         if (first_branch==0) {
01047 #ifdef POSTPONE_MSG_CLONING
01048                 /* update the shmem-ized msg with the lumps */
01049                 if ((rmode == MODE_REQUEST) &&
01050                         save_msg_lumps(t->uas.request, p_msg)) {
01051                                 LOG(L_ERR, "ERROR: t_forward_nonack: "
01052                                         "failed to save the message lumps\n");
01053                                 return -1;
01054                         }
01055 #endif
01056                 try_new=1;
01057                 branch_ret=add_uac( t, p_msg, GET_RURI(p_msg), GET_NEXT_HOP(p_msg),
01058                                                         proxy, proto );
01059                 if (branch_ret>=0) 
01060                         added_branches |= 1<<branch_ret;
01061                 else
01062                         lowest_ret=MIN_int(lowest_ret, branch_ret);
01063         } else try_new=0;
01064 
01065         init_branch_iterator();
01066         while((current_uri.s=next_branch( &current_uri.len, &q, &dst_uri.s, &dst_uri.len, &si))) {
01067                 try_new++;
01068                 p_msg->force_send_socket = si;
01069                 branch_ret=add_uac( t, p_msg, &current_uri, 
01070                                     (dst_uri.len) ? (&dst_uri) : &current_uri, 
01071                                     proxy, proto);
01072                 /* pick some of the errors in case things go wrong;
01073                    note that picking lowest error is just as good as
01074                    any other algorithm which picks any other negative
01075                    branch result */
01076                 if (branch_ret>=0) 
01077                         added_branches |= 1<<branch_ret;
01078                 else
01079                         lowest_ret=MIN_int(lowest_ret, branch_ret);
01080         }
01081         /* consume processed branches */
01082         clear_branches();
01083 
01084         p_msg->force_send_socket = backup_si;
01085 
01086         /* don't forget to clear all branches processed so far */
01087 
01088         /* things went wrong ... no new branch has been fwd-ed at all */
01089         if (added_branches==0) {
01090                 if (try_new==0) {
01091                         LOG(L_ERR, "ERROR: t_forward_nonack: no branches for"
01092                                                 " forwarding\n");
01093                         /* either failed to add branches, or there were no more branches
01094                         */
01095                         ser_error=MIN_int(lowest_ret, E_CFG);
01096                         return -1;
01097                 }
01098                 LOG(L_ERR, "ERROR: t_forward_nonack: failure to add branches\n");
01099                 ser_error=lowest_ret;
01100                 return lowest_ret;
01101         }
01102         ser_error=0; /* clear branch adding errors */
01103         /* send them out now */
01104         success_branch=0;
01105         lock_replies= ! ((rmode==MODE_ONFAILURE) && (t==get_t()));
01106         for (i=first_branch; i<t->nr_of_outgoings; i++) {
01107                 if (added_branches & (1<<i)) {
01108                         
01109                         branch_ret=t_send_branch(t, i, p_msg , proxy, lock_replies);
01110                         if (branch_ret>=0){ /* some kind of success */
01111                                 if (branch_ret==i) /* success */
01112                                         success_branch++;
01113                                 else /* new branch added */
01114                                         added_branches |= 1<<branch_ret;
01115                         }
01116                 }
01117         }
01118         if (success_branch<=0) {
01119                 /* return always E_SEND for now
01120                  * (the real reason could be: denied by onsend routes, blacklisted,
01121                  *  send failed or any of the errors listed before + dns failed
01122                  *  when attempting dns failover) */
01123                 ser_error=E_SEND;
01124                 /* else return the last error (?) */
01125                 /* the caller should take care and delete the transaction */
01126                 return -1;
01127         }
01128         ser_error=0; /* clear branch send errors, we have overall success */
01129         set_kr(REQ_FWDED);
01130         return 1;
01131 }
01132 
01133 
01134 
01135 /* cancel handling/forwarding function
01136  * CANCELs with no matching transaction are handled in function of
01137  * the unmatched_cancel config var: they are either forwarded statefully,
01138  * statelessly or dropped.
01139  * function returns:
01140  *       1 - forward successful
01141  *       0 - error, but do not reply 
01142  *      <0 - error during forward
01143  * it also sets *tran if a transaction was created
01144  */
01145 int t_forward_cancel(struct sip_msg* p_msg , struct proxy_l * proxy, int proto,
01146                                                 struct cell** tran)
01147 {
01148         struct cell* t_invite;
01149         struct cell* t;
01150         int ret;
01151         int new_tran;
01152         struct dest_info dst;
01153         str host;
01154         unsigned short port;
01155         short comp;
01156         
01157         t=0;
01158         /* handle cancels for which no transaction was created yet */
01159         if (cfg_get(tm, tm_cfg, unmatched_cancel)==UM_CANCEL_STATEFULL){
01160                 /* create cancel transaction */
01161                 new_tran=t_newtran(p_msg);
01162                 if (new_tran<=0 && new_tran!=E_SCRIPT){
01163                         if (new_tran==0)
01164                                  /* retransmission => do nothing */
01165                                 ret=1;
01166                         else
01167                                 /* some error => return it or DROP */
01168                                 ret=(ser_error==E_BAD_VIA && reply_to_via) ? 0: new_tran;
01169                         goto end;
01170                 }
01171                 t=get_t();
01172                 ret=t_forward_nonack(t, p_msg, proxy, proto);
01173                 goto end;
01174         }
01175         
01176         t_invite=t_lookupOriginalT(  p_msg );
01177         if (t_invite!=T_NULL_CELL) {
01178                 /* create cancel transaction */
01179                 new_tran=t_newtran(p_msg);
01180                 if (new_tran<=0 && new_tran!=E_SCRIPT){
01181                         if (new_tran==0)
01182                                  /* retransmission => do nothing */
01183                                 ret=1;
01184                         else
01185                                 /* some error => return it or DROP */
01186                                 ret=(ser_error==E_BAD_VIA && reply_to_via) ? 0: new_tran;
01187                         UNREF(t_invite);
01188                         goto end;
01189                 }
01190                 t=get_t();
01191                 e2e_cancel( p_msg, t, t_invite );
01192                 UNREF(t_invite);
01193                 ret=1;
01194                 goto end;
01195         }else /* no coresponding INVITE transaction */
01196              if (cfg_get(tm, tm_cfg, unmatched_cancel)==UM_CANCEL_DROP){
01197                                 DBG("t_forward_nonack: non matching cancel dropped\n");
01198                                 ret=1; /* do nothing -> drop */
01199                                 goto end;
01200                  }else{
01201                         /* UM_CANCEL_STATELESS -> stateless forward */
01202                                 DBG( "SER: forwarding CANCEL statelessly \n");
01203                                 if (proxy==0) {
01204                                         init_dest_info(&dst);
01205                                         dst.proto=proto;
01206                                         if (get_uri_send_info(GET_NEXT_HOP(p_msg), &host,
01207                                                                 &port, &dst.proto, &comp)!=0){
01208                                                 ret=E_BAD_ADDRESS;
01209                                                 goto end;
01210                                         }
01211 #ifdef USE_COMP
01212                                         dst.comp=comp;
01213 #endif
01214                                         /* dst->send_sock not set, but forward_request 
01215                                          * will take care of it */
01216                                         ret=forward_request(p_msg, &host, port, &dst);
01217                                         goto end;
01218                                 } else {
01219                                         init_dest_info(&dst);
01220                                         dst.proto=get_proto(proto, proxy->proto);
01221                                         proxy2su(&dst.to, proxy);
01222                                         /* dst->send_sock not set, but forward_request 
01223                                          * will take care of it */
01224                                         ret=forward_request( p_msg , 0, 0, &dst) ;
01225                                         goto end;
01226                                 }
01227                 }
01228 end:
01229         if (tran)
01230                 *tran=t;
01231         return ret;
01232 }
01233 
01234 /* Relays a CANCEL request if a corresponding INVITE transaction
01235  * can be found. The function is supposed to be used at the very
01236  * beginning of the script with reparse_invite=1 module parameter.
01237  *
01238  * return value:
01239  *    0: the CANCEL was successfully relayed
01240  *       (or error occured but reply cannot be sent) => DROP
01241  *    1: no corresponding INVITE transaction exisis
01242  *   <0: corresponding INVITE transaction exisis but error occured
01243  */
01244 int t_relay_cancel(struct sip_msg* p_msg)
01245 {
01246         struct cell* t_invite;
01247         struct cell* t;
01248         int ret;
01249         int new_tran;
01250 
01251         t_invite=t_lookupOriginalT(  p_msg );
01252         if (t_invite!=T_NULL_CELL) {
01253                 /* create cancel transaction */
01254                 new_tran=t_newtran(p_msg);
01255                 if (new_tran<=0 && new_tran!=E_SCRIPT){
01256                         if (new_tran==0)
01257                                 /* retransmission => DROP,
01258                                 t_newtran() takes care about it */
01259                                 ret=0;
01260                         else
01261                                 /* some error => return it or DROP */
01262                                 ret=(ser_error==E_BAD_VIA && reply_to_via) ? 0: new_tran;
01263                         UNREF(t_invite);
01264                         goto end;
01265                 }
01266                 t=get_t();
01267                 e2e_cancel( p_msg, t, t_invite );
01268                 UNREF(t_invite);
01269                 /* return 0 to stop the script processing */
01270                 ret=0;
01271                 goto end;
01272 
01273         } else {
01274                 /* no corresponding INVITE trasaction found */
01275                 ret=1;
01276         }
01277 end:
01278         return ret;
01279 }
01280 
01281 /* WARNING: doesn't work from failure route (deadlock, uses t_relay_to which
01282  *  is failure route unsafe) */
01283 int t_replicate(struct sip_msg *p_msg,  struct proxy_l *proxy, int proto )
01284 {
01285         /* this is a quite horrible hack -- we just take the message
01286            as is, including Route-s, Record-route-s, and Vias ,
01287            forward it downstream and prevent replies received
01288            from relaying by setting the replication/local_trans bit;
01289 
01290                 nevertheless, it should be good enough for the primary
01291                 customer of this function, REGISTER replication
01292 
01293                 if we want later to make it thoroughly, we need to
01294                 introduce delete lumps for all the header fields above
01295         */
01296         return t_relay_to(p_msg, proxy, proto, 1 /* replicate */);
01297 }
01298 
01299 /* fixup function for reparse_on_dns_failover modparam */
01300 int reparse_on_dns_failover_fixup(void *handle, str *gname, str *name, void **val)
01301 {
01302 #ifdef USE_DNS_FAILOVER
01303         if ((int)(long)(*val) && mhomed) {
01304                 LOG(L_WARN, "WARNING: reparse_on_dns_failover_fixup:"
01305                 "reparse_on_dns_failover is enabled on a "
01306                 "multihomed host -- check the readme of tm module!\n");
01307         }
01308 #endif
01309         return 0;
01310 }

Generated on Tue Sep 7 04:16:09 2010 for SIPExpressRouter by  doxygen 1.3.9.1