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
1.7.1