t_cancel.h

00001 /*
00002  * $Id$
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  * History:
00029  * ---------
00030  *  2004-02-11  FIFO/CANCEL + alignments (hash=f(callid,cseq)) (uli+jiri)
00031  *  2006-10-10  should_cancel_branch() returns true even for branches with
00032  *               no response or with response <100 (andrei)
00033  *  2007-06-04  should_cancel_branch() takes another parameter and it is safe
00034  *               to be called w/o REPLY_LOCK held (andrei)
00035  *  2009-07-14  should_cancel_branch() renamed to prepare_cancel_branch() to
00036  *               better reflect its purpose
00037  *              which_cancel() renamed to prepare_to_cancel() (andrei)
00038  * 2010-02-26  cancel reason (rfc3326) basic support (andrei)
00039  */
00040 
00041 
00042 #ifndef _CANCEL_H
00043 #define _CANCEL_H
00044 
00045 #include <stdio.h> /* just for FILE* for fifo_uac_cancel */
00046 #include "../../rpc.h"
00047 #include "../../atomic_ops.h"
00048 #include "defs.h"
00049 #include "h_table.h"
00050 #include "t_reply.h"
00051 
00052 
00053 /* a buffer is empty but cannot be used by anyone else;
00054    particularly, we use this value in the buffer pointer
00055    in local_buffer to tell "a process is already scheduled
00056    to generate a CANCEL, other processes are not supposed to"
00057    (which might happen if for example in a three-branch forking,
00058    two 200 would enter separate processes and compete for
00059    canceling the third branch); note that to really avoid
00060    race conditions, the value must be set in REPLY_LOCK
00061 */
00062 
00063 #define BUSY_BUFFER ((char *)-1)
00064 
00065 /* flags for cancel_uacs(), cancel_branch() */
00066 #define F_CANCEL_B_KILL 1  /*  will completely stop the  branch (stops the
00067                                                            timers), use only before a put_on_wait()
00068                                                            or set_final_timer()*/
00069 #define F_CANCEL_B_FAKE_REPLY 2 /* will send a fake 487 to all branches that
00070                                                                  haven't received any response (>=100). It
00071                                                                  assumes the REPLY_LOCK is not held (if it is
00072                                                                  => deadlock) */
00073 #define F_CANCEL_B_FORCE_C 4 /* will send a cancel even if no reply was 
00074                                                                 received; F_CANCEL_B_FAKE_REPLY will be 
00075                                                                 ignored */
00076 #define F_CANCEL_B_FORCE_RETR 8  /* will not stop request retr. on a branch
00077                                                                         if no provisional response was received;
00078                                                                         F_CANCEL_B_FORCE_C, F_CANCEL_B_FAKE_REPLY
00079                                                                         and F_CANCE_B_KILL take precedence */
00080 #define F_CANCEL_UNREF 16 /* unref the trans after canceling */
00081 
00082 
00083 void prepare_to_cancel(struct cell *t, branch_bm_t *cancel_bm, branch_bm_t s);
00084 int cancel_uacs( struct cell *t, struct cancel_info* cancel_data, int flags );
00085 int cancel_all_uacs(struct cell *trans, int how);
00086 int cancel_branch( struct cell *t, int branch,
00087 #ifdef CANCEL_REASON_SUPPORT
00088                                         struct cancel_reason* reason,
00089 #endif /* CANCEL_REASON_SUPPORT */
00090                                         int flags );
00091 
00092 typedef int(*cancel_uacs_f)(struct cell *t, struct cancel_info* cancel_data,
00093                 int flags);
00094 typedef int (*cancel_all_uacs_f)(struct cell *trans, int how);
00095 
00096 typedef void (*prepare_to_cancel_f)(struct cell *t, branch_bm_t *cancel_bm,
00097                                                                         branch_bm_t skip_branches);
00098 
00099 
00120 inline short static prepare_cancel_branch( struct cell *t, int b, int noreply )
00121 {
00122         int last_received;
00123         unsigned long old;
00124 
00125         last_received=t->uac[b].last_received;
00126         /* if noreply=1 cancel even if no reply received (in this case 
00127          * cancel_branch()  won't actually send the cancel but it will do the 
00128          * cleanup) */
00129         if (last_received<200 && (noreply || last_received>=100)){
00130                 old=atomic_cmpxchg_long((void*)&t->uac[b].local_cancel.buffer, 0,
00131                                                                         (long)(BUSY_BUFFER));
00132                 return old==0;
00133         }
00134         return 0;
00135 }
00136 
00137 void rpc_cancel(rpc_t* rpc, void* c);
00138 int cancel_b_flags_fixup(void* handle, str* gname, str* name, void** val);
00139 int cancel_b_flags_get(unsigned int* f, int m);
00140 
00141 typedef unsigned int (*tuaccancel_f)( str *headers,str *body,
00142                 unsigned int cancelledIdx,unsigned int cancelledLabel,
00143                 transaction_cb cb, void* cbp);
00144 
00145 unsigned int t_uac_cancel(str *headers,str *body,
00146                 unsigned int cancelledIdx,unsigned int cancelledLabel,
00147                 transaction_cb cb, void* cbp);
00148 
00149 #endif