t_cancel.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "t_funcs.h"
00038 #include "../../dprint.h"
00039 #include "../../ut.h"
00040 #include "t_reply.h"
00041 #include "t_fwd.h"
00042 #include "t_cancel.h"
00043 #include "t_msgbuilder.h"
00044 #include "t_lookup.h"
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 void which_cancel( struct cell *t, branch_bm_t *cancel_bm )
00057 {
00058 int i;
00059
00060 for( i=t->first_branch ; i<t->nr_of_outgoings ; i++ ) {
00061 if (should_cancel_branch(t, i))
00062 *cancel_bm |= 1<<i ;
00063
00064 }
00065 }
00066
00067
00068
00069 void cancel_uacs( struct cell *t, branch_bm_t cancel_bm )
00070 {
00071 int i;
00072
00073
00074 for( i=0 ; i<t->nr_of_outgoings ; i++ )
00075 if (cancel_bm & (1<<i))
00076 cancel_branch(t, i);
00077 }
00078
00079
00080 void cancel_branch( struct cell *t, int branch )
00081 {
00082 char *cancel;
00083 unsigned int len;
00084 struct retr_buf *crb, *irb;
00085
00086 crb=&t->uac[branch].local_cancel;
00087 irb=&t->uac[branch].request;
00088
00089 # ifdef EXTRA_DEBUG
00090 if (crb->buffer.s!=0 && crb->buffer.s!=BUSY_BUFFER) {
00091 LM_CRIT("attempt to rewrite cancel buffer failed\n");
00092 abort();
00093 }
00094 # endif
00095
00096 cancel=build_cancel(t, branch, &len);
00097 if (!cancel) {
00098 LM_ERR("attempt to build a CANCEL failed\n");
00099 return;
00100 }
00101
00102 crb->buffer.s=cancel;
00103 crb->buffer.len=len;
00104 crb->dst=irb->dst;
00105 crb->branch=branch;
00106
00107
00108 crb->activ_type=TYPE_LOCAL_CANCEL;
00109
00110 if ( has_tran_tmcbs( t, TMCB_REQUEST_BUILT) ) {
00111 set_extra_tmcb_params( &crb->buffer, &crb->dst);
00112 run_trans_callbacks( TMCB_REQUEST_BUILT, t, t->uas.request,0,
00113 -t->uas.request->REQ_METHOD);
00114 }
00115
00116 LM_DBG("sending cancel...\n");
00117 SEND_BUFFER( crb );
00118
00119
00120 start_retr( crb );
00121 }
00122
00123
00124 char *build_cancel(struct cell *Trans,unsigned int branch,
00125 unsigned int *len )
00126 {
00127 return build_local( Trans, branch, len,
00128 CANCEL, CANCEL_LEN, &Trans->to );
00129 }
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140 unsigned int t_uac_cancel( str *headers, str *body,
00141 unsigned int cancelled_hashIdx, unsigned int cancelled_label,
00142 transaction_cb cb, void* cbp)
00143 {
00144 struct cell *t_invite,*cancel_cell;
00145 struct retr_buf *cancel,*invite;
00146 unsigned int len,ret;
00147 char *buf;
00148
00149 ret=0;
00150
00151 if(t_lookup_ident(&t_invite,cancelled_hashIdx,cancelled_label)<0){
00152 LM_ERR("failed to t_lookup_ident hash_idx=%d,"
00153 "label=%d\n", cancelled_hashIdx,cancelled_label);
00154 return 0;
00155 }
00156
00157 if(! is_local(t_invite)){
00158 LM_ERR("tried to cancel a non-local transaction\n");
00159 goto error3;
00160 }
00161 if(t_invite->uac[0].last_received < 100){
00162 LM_WARN("trying to cancel a transaction not in "
00163 "Proceeding state !\n");
00164 goto error3;
00165 }
00166 if(t_invite->uac[0].last_received > 200){
00167 LM_WARN("trying to cancel a completed transaction !\n");
00168 goto error3;
00169 }
00170
00171
00172
00173
00174 if(!(cancel_cell = build_cell(0))){
00175 ret=0;
00176 LM_ERR("no more shm memory!\n");
00177 goto error3;
00178 }
00179 reset_avps();
00180 if(cb && insert_tmcb(&(cancel_cell->tmcb_hl),
00181 TMCB_RESPONSE_IN|TMCB_LOCAL_COMPLETED,cb,cbp,0)!=1){
00182 ret=0;
00183 LM_ERR("short of tmcb shmem !\n");
00184 goto error2;
00185 }
00186
00187
00188
00189 cancel_cell->flags |= T_IS_LOCAL_FLAG;
00190 cancel_cell->hash_index=t_invite->hash_index;
00191
00192 LOCK_HASH(cancel_cell->hash_index);
00193 insert_into_hash_table_unsafe(cancel_cell,cancel_cell->hash_index);
00194 ret=cancel_cell->label;
00195 cancel_cell->label=t_invite->label;
00196 UNLOCK_HASH(cancel_cell->hash_index);
00197
00198
00199
00200
00201 cancel=&cancel_cell->uac[0].request;
00202 invite=&t_invite->uac[0].request;
00203
00204 cancel->dst.to = invite->dst.to;
00205 cancel->dst.send_sock = invite->dst.send_sock;
00206 cancel->dst.proto = invite->dst.proto;
00207 cancel->dst.proto_reserved1 = invite->dst.proto_reserved1;
00208
00209 if(!(buf = build_uac_cancel(headers,body,t_invite,0,&len))){
00210 ret=0;
00211 LM_ERR("attempt to build a CANCEL failed\n");
00212 goto error1;
00213 }
00214 cancel->buffer.s=buf;
00215 cancel->buffer.len=len;
00216 cancel_cell->method.s = buf;
00217 cancel_cell->method.len = 6 ;
00218
00219
00220
00221
00222 cancel_cell->nr_of_outgoings++;
00223 if (SEND_BUFFER(cancel)==-1) {
00224 ret=0;
00225 LM_ERR("send failed\n");
00226 goto error1;
00227 }
00228 start_retr(cancel);
00229
00230
00231 return ret;
00232
00233 error1:
00234 LOCK_HASH(cancel_cell->hash_index);
00235 remove_from_hash_table_unsafe(cancel_cell);
00236 UNLOCK_HASH(cancel_cell->hash_index);
00237 error2:
00238 free_cell(cancel_cell);
00239 error3:
00240 return ret;
00241 }
00242