Browse code

- tm on_send callbacks support: if such a callback is registered it will be called after tm sends a message. The callback can "see" what exactly was sent on the wire and to whom. These callbacks are intended to be read-only (no changes to the message are allowed). Their man purpose is extra-accounting or logging. For more info see the comments in tm/t_hooks.h.

Andrei Pelinescu-Onciul authored on 15/03/2007 16:30:16
Showing 9 changed files
... ...
@@ -3,7 +3,15 @@ Release notes for SIP Express Router (ser)
3 3
 
4 4
 $Id$
5 5
 
6
-0.10.99-dev changes
6
+
7
+2.1.0 changes
8
+
9
+modules:
10
+ - tm        - new onsend callbacks support (require defining TMCB_ONSEND prior
11
+               to compiling tm)
12
+
13
+
14
+2.0.0 changes
7 15
 
8 16
 
9 17
 new archs:
... ...
@@ -45,8 +45,10 @@
45 45
 #ifndef _H_TABLE_H
46 46
 #define _H_TABLE_H
47 47
 
48
-#include <stdio.h>
49
-#include <stdlib.h>
48
+/*
49
+ #include <stdio.h>
50
+ #include <stdlib.h>
51
+*/
50 52
 
51 53
 #include "../../parser/msg_parser.h"
52 54
 #include "../../types.h"
... ...
@@ -80,6 +82,7 @@ void unlock_hash(int i);
80 80
 #define NO_CANCEL       ( (char*) 0 )
81 81
 #define EXTERNAL_CANCEL ( (char*) -1)
82 82
 
83
+#define TYPE_LOCAL_ACK    -2
83 84
 #define TYPE_LOCAL_CANCEL -1
84 85
 #define TYPE_REQUEST       0
85 86
 
... ...
@@ -32,6 +32,7 @@
32 32
  * 2004-02-11  FIFO/CANCEL + alignments (hash=f(callid,cseq)) (uli+jiri)
33 33
  * 2004-02-13  timer_link.payload removed (bogdan)
34 34
  * 2006-10-10  cancel_uacs  & cancel_branch take more options now (andrei)
35
+ * 2007-03-15  TMCB_ONSEND hooks added (andrei)
35 36
  */
36 37
 
37 38
 #include <stdio.h> /* for FILE* in fifo_uac_cancel */
... ...
@@ -46,6 +47,7 @@
46 46
 #include "t_cancel.h"
47 47
 #include "t_msgbuilder.h"
48 48
 #include "t_lookup.h" /* for t_lookup_callid in fifo_uac_cancel */
49
+#include "t_hooks.h"
49 50
 
50 51
 
51 52
 /* determine which branches should be canceled; do it
... ...
@@ -114,9 +116,9 @@ int cancel_uacs( struct cell *t, branch_bm_t cancel_bm, int flags)
114 114
  *         -1 - error
115 115
  * WARNING:
116 116
  *          - F_CANCEL_KILL_B should be used only if the transaction is killed
117
- *            explicitely afterwards (since it might kill all the timers
117
+ *            explicitly afterwards (since it might kill all the timers
118 118
  *            the transaction won't be able to "kill" itself => if not
119
- *            explicitely "put_on_wait" it migh leave forever)
119
+ *            explicitly "put_on_wait" it might live forever)
120 120
  *          - F_CANCEL_B_FAKE_REPLY must be used only if the REPLY_LOCK is not
121 121
  *            held
122 122
  */
... ...
@@ -189,7 +191,12 @@ int cancel_branch( struct cell *t, int branch, int flags )
189 189
 	crb->activ_type = TYPE_LOCAL_CANCEL;
190 190
 
191 191
 	DBG("DEBUG: cancel_branch: sending cancel...\n");
192
+#ifdef TMCB_ONSEND
193
+	if (SEND_BUFFER( crb )>=0)
194
+		run_onsend_callbacks(TMCB_REQUEST_SENT, crb, 0);
195
+#else
192 196
 	SEND_BUFFER( crb );
197
+#endif
193 198
 	/*sets and starts the FINAL RESPONSE timer */
194 199
 	if (start_retr( crb )!=0)
195 200
 		LOG(L_CRIT, "BUG: cancel_branch: failed to start retransmission"
... ...
@@ -63,6 +63,7 @@
63 63
  *              stop retr. timers fix on cancel for non-invites     (andrei)
64 64
  *  2006-11-20  new_uri is no longer saved/restore across add_uac calls, since
65 65
  *              print_uac_request is now uri safe (andrei)
66
+ * 2007-03-15  TMCB_ONSEND hooks added (andrei)
66 67
  */
67 68
 
68 69
 #include "defs.h"
... ...
@@ -507,6 +508,12 @@ void e2e_cancel( struct sip_msg *cancel_msg,
507 507
 				if (SEND_BUFFER(&t_cancel->uac[i].request) == -1) {
508 508
 					LOG(L_ERR, "ERROR: e2e_cancel: send failed\n");
509 509
 				}
510
+#ifdef TMCB_ONSEND
511
+				else{
512
+					run_onsend_callbacks(TMCB_REQUEST_SENT, 
513
+											&t_cancel->uac[i].request, 0);
514
+				}
515
+#endif
510 516
 				if (start_retr( &t_cancel->uac[i].request )!=0)
511 517
 					LOG(L_CRIT, "BUG: e2e_cancel: failed to start retr."
512 518
 							" for %p\n", &t_cancel->uac[i].request);
... ...
@@ -655,7 +662,7 @@ int t_send_branch( struct cell *t, int branch, struct sip_msg* p_msg ,
655 655
 	if (SEND_BUFFER( &uac->request)==-1) {
656 656
 		/* disable the current branch: set a "fake" timeout
657 657
 		 *  reply code but don't set uac->reply, to avoid overriding 
658
-		 *  a higly unlikely, perfectly timed fake reply (to a message
658
+		 *  a highly unlikely, perfectly timed fake reply (to a message
659 659
 		 *  we never sent).
660 660
 		 * (code=final reply && reply==0 => t_pick_branch won't ever pick it)*/
661 661
 		uac->last_received=408;
... ...
@@ -685,6 +692,9 @@ int t_send_branch( struct cell *t, int branch, struct sip_msg* p_msg ,
685 685
 		if (proxy) { proxy->errors++; proxy->ok=0; }
686 686
 		return -2;
687 687
 	} else {
688
+#ifdef TMCB_ONSEND
689
+		run_onsend_callbacks(TMCB_REQUEST_SENT, &uac->request, 0);
690
+#endif
688 691
 		/* start retr. only if the send succeeded */
689 692
 		if (start_retr( &uac->request )!=0){
690 693
 			LOG(L_CRIT, "BUG: t_send_branch: retr. already started for %p\n",
... ...
@@ -34,6 +34,7 @@
34 34
  *  2004-08-23  user avp(attribute value pair) added -> making avp list
35 35
  *              available in callbacks (bogdan)
36 36
  * 2007-03-08  membar_write() used in insert_tmcb(...) (andrei)
37
+ * 2007-03-14  added *_SENT callbacks (andrei)
37 38
  */
38 39
 
39 40
 #include "defs.h"
... ...
@@ -182,20 +183,12 @@ int register_tmcb( struct sip_msg* p_msg, struct cell *t, int types,
182 182
 }
183 183
 
184 184
 
185
-void run_trans_callbacks( int type , struct cell *trans,
186
-						struct sip_msg *req, struct sip_msg *rpl, int code )
185
+static void run_trans_callbacks_internal(int type, struct cell *trans, 
186
+											struct tmcb_params *params)
187 187
 {
188
-	static struct tmcb_params params = {0,0,0,0};
189 188
 	struct tm_callback    *cbp;
190 189
 	avp_list_t* backup_from, *backup_to, *backup_dom_from, *backup_dom_to, *backup_uri_from, *backup_uri_to;
191 190
 
192
-	params.req = req;
193
-	params.rpl = rpl;
194
-	params.code = code;
195
-
196
-	if (trans->tmcb_hl.first==0 || ((trans->tmcb_hl.reg_types)&type)==0 )
197
-		return;
198
-
199 191
 	backup_uri_from = set_avp_list(AVP_CLASS_URI | AVP_TRACK_FROM, &trans->uri_avps_from );
200 192
 	backup_uri_to = set_avp_list(AVP_CLASS_URI | AVP_TRACK_TO, &trans->uri_avps_to );
201 193
 	backup_from = set_avp_list(AVP_CLASS_USER | AVP_TRACK_FROM, &trans->user_avps_from );
... ...
@@ -206,8 +199,8 @@ void run_trans_callbacks( int type , struct cell *trans,
206 206
 		if ( (cbp->types)&type ) {
207 207
 			DBG("DBG: trans=%p, callback type %d, id %d entered\n",
208 208
 				trans, type, cbp->id );
209
-			params.param = &(cbp->param);
210
-			cbp->callback( trans, type, &params );
209
+			params->param = &(cbp->param);
210
+			cbp->callback( trans, type, params );
211 211
 		}
212 212
 	}
213 213
 	set_avp_list(AVP_CLASS_DOMAIN | AVP_TRACK_TO, backup_dom_to );
... ...
@@ -220,17 +213,80 @@ void run_trans_callbacks( int type , struct cell *trans,
220 220
 
221 221
 
222 222
 
223
+void run_trans_callbacks( int type , struct cell *trans,
224
+						struct sip_msg *req, struct sip_msg *rpl, int code )
225
+{
226
+	struct tmcb_params params;
227
+	if (trans->tmcb_hl.first==0 || ((trans->tmcb_hl.reg_types)&type)==0 )
228
+		return;
229
+	memset (&params, 0, sizeof(params));
230
+	params.req = req;
231
+	params.rpl = rpl;
232
+	params.code = code;
233
+	run_trans_callbacks_internal(type, trans, &params);
234
+}
235
+
236
+
237
+
238
+#ifdef TMCB_ONSEND
239
+void run_onsend_callbacks(int type, struct retr_buf* rbuf, int retr)
240
+{
241
+	struct tmcb_params params;
242
+	struct cell * trans;
243
+
244
+	trans=rbuf->my_T;
245
+	if ( trans==0 || trans->tmcb_hl.first==0 || 
246
+			((trans->tmcb_hl.reg_types)&type)==0 )
247
+		return;
248
+	memset (&params, 0, sizeof(params));
249
+	params.send_buf.s=rbuf->buffer;
250
+	params.send_buf.len=rbuf->buffer_len;
251
+	params.dst=&rbuf->dst;
252
+	params.is_retr=retr;
253
+	params.branch=rbuf->branch;
254
+	params.t_rbuf=rbuf;
255
+	params.code=rbuf->activ_type;
256
+	/* req, rpl */
257
+	run_trans_callbacks_internal(type, trans, &params);
258
+}
259
+
260
+
261
+void run_onsend_callbacks2(int type , struct retr_buf* rbuf, char* buf,
262
+							int buf_len, struct dest_info* dst, int code)
263
+{
264
+	struct tmcb_params params;
265
+	struct cell * trans;
266
+
267
+	trans=rbuf->my_T;
268
+	if ( trans==0 || trans->tmcb_hl.first==0 || 
269
+			((trans->tmcb_hl.reg_types)&type)==0 )
270
+		return;
271
+	memset (&params, 0, sizeof(params));
272
+	params.send_buf.s=buf;
273
+	params.send_buf.len=buf_len;
274
+	params.dst=dst;
275
+	params.is_retr=0;
276
+	params.branch=rbuf->branch;
277
+	params.t_rbuf=rbuf;
278
+	params.code=code;
279
+	/* req, rpl */
280
+	run_trans_callbacks_internal(type, trans, &params);
281
+}
282
+
283
+#endif
284
+
223 285
 void run_reqin_callbacks( struct cell *trans, struct sip_msg *req, int code )
224 286
 {
225
-	static struct tmcb_params params = {0,0,0,0};
287
+	static struct tmcb_params params;
226 288
 	struct tm_callback    *cbp;
227 289
 	avp_list_t* backup_from, *backup_to, *backup_dom_from, *backup_dom_to, *backup_uri_from, *backup_uri_to;
228 290
 
291
+	if (req_in_tmcb_hl->first==0)
292
+		return;
293
+	memset (&params, 0, sizeof(params));
229 294
 	params.req = req;
230 295
 	params.code = code;
231 296
 
232
-	if (req_in_tmcb_hl->first==0)
233
-		return;
234 297
 
235 298
 	backup_uri_from = set_avp_list(AVP_CLASS_URI | AVP_TRACK_FROM, &trans->uri_avps_from );
236 299
 	backup_uri_to = set_avp_list(AVP_CLASS_URI | AVP_TRACK_TO, &trans->uri_avps_to );
... ...
@@ -31,6 +31,7 @@
31 31
  * 2003-12-04 : global callbacks moved into transaction callbacks;
32 32
  *              multiple events per callback added; single list per
33 33
  *              transaction for all its callbacks (bogdan)
34
+ * 2007-03-14   added *_SENT callbacks (andrei)
34 35
  */
35 36
 
36 37
 
... ...
@@ -39,6 +40,15 @@
39 39
 
40 40
 #include "defs.h"
41 41
 
42
+/* if defined support for ONSEND callbacks will be added and
43
+ * the tmcb_params structure will get some additional members */
44
+/*
45
+#define TMCB_ONSEND
46
+*/
47
+#ifdef TMCB_ONSEND
48
+#include "../../ip_addr.h" /* dest_info */
49
+#endif
50
+
42 51
 struct sip_msg;
43 52
 struct cell;
44 53
 
... ...
@@ -52,7 +62,13 @@ struct cell;
52 52
 #define TMCB_RESPONSE_OUT_N     7
53 53
 #define TMCB_LOCAL_COMPLETED_N  8
54 54
 #define TMCB_LOCAL_RESPONSE_OUT_N 9
55
+#ifdef TMCB_ONSEND
56
+#define TMCB_REQUEST_SENT_N     10
57
+#define TMCB_RESPONSE_SENT_N    11
58
+#define TMCB_MAX_N              11
59
+#else
55 60
 #define TMCB_MAX_N              9
61
+#endif
56 62
 
57 63
 #define TMCB_REQUEST_IN       (1<<TMCB_REQUEST_IN_N)
58 64
 #define TMCB_RESPONSE_IN      (1<<TMCB_RESPONSE_IN_N)
... ...
@@ -64,6 +80,10 @@ struct cell;
64 64
 #define TMCB_RESPONSE_OUT     (1<<TMCB_RESPONSE_OUT_N)
65 65
 #define TMCB_LOCAL_COMPLETED  (1<<TMCB_LOCAL_COMPLETED_N)
66 66
 #define TMCB_LOCAL_RESPONSE_OUT (1<<TMCB_LOCAL_RESPONSE_OUT_N)
67
+#ifdef TMCB_ONSEND
68
+#define TMCB_REQUEST_SENT      (1<<TMCB_REQUEST_SENT_N)
69
+#define TMCB_RESPONSE_SENT     (1<<TMCB_RESPONSE_SENT_N)
70
+#endif
67 71
 #define TMCB_MAX              ((1<<(TMCB_MAX_N+1))-1)
68 72
 
69 73
 
... ...
@@ -199,11 +219,49 @@ struct cell;
199 199
  *  called multiple time quasi-simultaneously. No lock is held.
200 200
  *  It's unsafe to register other TMCB callbacks.
201 201
  *
202
+ *  TMCB_ONSEND callbacks
203
+ *
204
+ *  All of the following callbacks are called immediately after or before 
205
+ *  sending a message. All of them are read-only (no change can be made to
206
+ * the message). These callbacks use the t_rbuf, send_buf, dst, is_retr
207
+ *  and the code members of the tmcb_params structure.
208
+ *  For a request code is <=0. code values can be TYPE_LOCAL_ACK for an ACK 
209
+ *  generated by ser, TYPE_LOCAL_CANCEL for a CANCEL generated by ser 
210
+ *  and TYPE_REQUEST for all the other requests or requests generated via 
211
+ *  t_uac.
212
+ *   For a reply the code is the response status (which is always >0, e.g. 200,
213
+ *   408, a.s.o).
214
+ *  Note: - these callbacks can be used only if TMCB_ONSEND is defined.
215
+ *        - the callbacks will be called sometimes with the REPLY lock held
216
+ *          and sometimes without it, so trying to acquire the REPLY lock
217
+ *          from these callbacks could lead to deadlocks (avoid it unless
218
+ *           you really know what you're doing).
219
+ *
220
+ *  TMCB_REQUEST_SENT (present only if TMCB_ONSEND is defined) -- called 
221
+ *  each time a request was sent (even for retransmissions), it includes 
222
+ *  local and forwarded request, ser generated CANCELs and ACKs. The 
223
+ *  tmcb_params structure will have the t_rbuf, dst, send_buf and is_retr
224
+ *  members  filled.
225
+ *  This callback is "read-only", the message was already sent and no changes
226
+ *  are allowed.
227
+ *  Note: send_buf can be different from t_rbuf->buffer for ACKs (in this
228
+ *   case t_rbuf->buf will contain the last request sent on the branch and
229
+ *   its destination). The same goes for t_rbuf->dst and tmcb->dst for local 
230
+ *   transactions ACKs to 2xxs.
231
+ *
232
+ *  TMCB_RESPONSE_SENT  (present only if TMCB_ONSEND is defined) -- called 
233
+ *  each time a response was sent (even for retransmissions). The tmcb_params
234
+ *   structure will have t_rbuf set to the reply retransmission buffer and
235
+ *   send_buf set to the data sent (in this case it will always be the same 
236
+ *   with t_rbuf->buf). is_retr will also be set if the reply is retransmitted
237
+ *   by ser.
238
+ *  This callback is "read-only", the message was already sent and no changes
239
+ *  are allowed.
202 240
  *
203 241
 
204 242
 	the callback's param MUST be in shared memory and will
205 243
 	NOT be freed by TM; you must do it yourself from the
206
-	callback function id necessary.
244
+	callback function if necessary.
207 245
 */
208 246
 
209 247
 
... ...
@@ -211,8 +269,22 @@ struct cell;
211 211
 struct tmcb_params {
212 212
 	struct sip_msg* req;
213 213
 	struct sip_msg* rpl;
214
-	int code;
215 214
 	void **param;
215
+#ifdef TMCB_ONSEND
216
+	struct retr_buf* t_rbuf; /* transaction retr. buf., all the information
217
+								 regarding destination, data that is/was
218
+								 actually sent on the net, branch a.s.o is
219
+								 inside */
220
+	struct dest_info* dst; /* destination */
221
+	str send_buf; /* what was/will be sent on the net, used for ACKs
222
+					(which don't have a retr_buf). */
223
+	short is_retr; /* set if this is a _ser_ retransmission (but not if
224
+					 if it's a "forwarded" retr., like a retr. 200 Ok for 
225
+					 example) */
226
+	unsigned short branch;
227
+	/* could also be: send_buf, dst, branch */
228
+#endif
229
+	int code;
216 230
 };
217 231
 
218 232
 /* callback function prototype */
... ...
@@ -267,4 +339,10 @@ void run_trans_callbacks( int type , struct cell *trans,
267 267
 /* run all REQUEST_IN callbacks */
268 268
 void run_reqin_callbacks( struct cell *trans, struct sip_msg *req, int code );
269 269
 
270
+#ifdef TMCB_ONSEND
271
+void run_onsend_callbacks(int type, struct retr_buf* rbuf, int retr);
272
+void run_onsend_callbacks2(int type , struct retr_buf* rbuf, char* buf,
273
+							int buf_len, struct dest_info* dst, int code);
274
+#endif
275
+
270 276
 #endif
... ...
@@ -80,7 +80,8 @@
80 80
  *               the final response is 401 or 407 (andrei)
81 81
  * 2007-03-08  membar_write() used in update_totag_set(...)(andrei)
82 82
  * 2007-03-15  build_local_ack: removed next_hop and replaced with dst to 
83
- *              avoid resolving next_hop twice (andrei)
83
+ *              avoid resolving next_hop twice
84
+*              added TMCB_ONSEND callbacks support for replies & ACKs (andrei)
84 85
  *
85 86
  */
86 87
 
... ...
@@ -491,7 +492,13 @@ static int _reply_light( struct cell *trans, char* buf, unsigned int len,
491 491
 	if (!trans->uas.response.dst.send_sock) {
492 492
 		LOG(L_ERR, "ERROR: _reply_light: no resolved dst to send reply to\n");
493 493
 	} else {
494
+#ifdef TMCB_ONSEND
495
+		if (SEND_PR_BUFFER( rb, buf, len )>=0)
496
+			run_onsend_callbacks2(TMCB_RESPONSE_SENT, rb, buf, len, &rb->dst,
497
+									code);
498
+#else
494 499
 		SEND_PR_BUFFER( rb, buf, len );
500
+#endif
495 501
 		DBG("DEBUG: reply sent out. buf=%p: %.9s..., shmem=%p: %.9s\n",
496 502
 			buf, buf, rb->buffer, rb->buffer );
497 503
 	}
... ...
@@ -1069,6 +1076,9 @@ int t_retransmit_reply( struct cell *t )
1069 1069
 	memcpy( b, t->uas.response.buffer, len );
1070 1070
 	UNLOCK_REPLIES( t );
1071 1071
 	SEND_PR_BUFFER( & t->uas.response, b, len );
1072
+#ifdef TMCB_ONSEND
1073
+	run_onsend_callbacks(TMCB_RESPONSE_SENT, &t->uas.response, 1);
1074
+#endif
1072 1075
 	DBG("DEBUG: reply retransmitted. buf=%p: %.9s..., shmem=%p: %.9s\n",
1073 1076
 		b, b, t->uas.response.buffer, t->uas.response.buffer );
1074 1077
 	return 1;
... ...
@@ -1431,12 +1441,15 @@ enum rps relay_reply( struct cell *t, struct sip_msg *p_msg, int branch,
1431 1431
 
1432 1432
 	/* send it now (from the private buffer) */
1433 1433
 	if (relay >= 0) {
1434
-		SEND_PR_BUFFER( uas_rb, buf, res_len );
1435
-		DBG("DEBUG: reply relayed. buf=%p: %.15s..., shmem=%p: %.9s totag_retr=%d\n",
1436
-			buf, buf, uas_rb->buffer, uas_rb->buffer, totag_retr );
1437
-		if (!totag_retr && has_tran_tmcbs(t, TMCB_RESPONSE_OUT) ) {
1438
-			run_trans_callbacks( TMCB_RESPONSE_OUT, t, t->uas.request,
1439
-				relayed_msg, relayed_code);
1434
+		if (SEND_PR_BUFFER( uas_rb, buf, res_len )>=0){
1435
+			if (!totag_retr && has_tran_tmcbs(t, TMCB_RESPONSE_OUT) ) {
1436
+				run_trans_callbacks( TMCB_RESPONSE_OUT, t, t->uas.request,
1437
+					relayed_msg, relayed_code);
1438
+			}
1439
+#ifdef TMCB_ONSEND
1440
+			run_onsend_callbacks2(TMCB_RESPONSE_SENT, uas_rb, buf, res_len,
1441
+									&uas_rb->dst, relayed_code);
1442
+#endif
1440 1443
 		}
1441 1444
 		pkg_free( buf );
1442 1445
 	}
... ...
@@ -1615,15 +1628,28 @@ int reply_received( struct sip_msg  *p_msg )
1615 1615
 			if (msg_status >= 300) {
1616 1616
 				ack = build_ack(p_msg, t, branch, &ack_len);
1617 1617
 				if (ack) {
1618
+#ifdef	TMCB_ONSEND
1619
+					if (SEND_PR_BUFFER(&uac->request, ack, ack_len)>=0)
1620
+						run_onsend_callbacks2(TMCB_REQUEST_SENT,
1621
+									&uac->request, ack, ack_len, 
1622
+									&uac->request.dst,
1623
+									TYPE_LOCAL_ACK);
1624
+#else
1618 1625
 					SEND_PR_BUFFER(&uac->request, ack, ack_len);
1626
+#endif
1619 1627
 					shm_free(ack);
1620 1628
 				}
1621 1629
 			} else if (is_local(t) /*&& 200 <= msg_status < 300*/) {
1622 1630
 				ack = build_local_ack(p_msg, t, branch, &ack_len, &lack_dst);
1623 1631
 				if (ack) {
1624
-					if (msg_send(&lack_dst, ack, ack_len)<0){
1632
+					if (msg_send(&lack_dst, ack, ack_len)<0)
1625 1633
 						LOG(L_ERR, "Error while sending local ACK\n");
1626
-					}
1634
+#ifdef	TMCB_ONSEND
1635
+					else
1636
+						run_onsend_callbacks2(TMCB_REQUEST_SENT,
1637
+									&uac->request, ack, ack_len, &lack_dst,
1638
+									TYPE_LOCAL_ACK);
1639
+#endif
1627 1640
 					shm_free(ack);
1628 1641
 				}
1629 1642
 			}
... ...
@@ -107,6 +107,7 @@
107 107
  *               return a 408
108 108
  *              set the corresponding "faked" failure route sip_msg->msg_flags 
109 109
  *               on timeout or if the branch received a reply (andrei)
110
+ *  2007-03-15  TMCB_ONSEND callbacks support (andrei)
110 111
  */
111 112
 
112 113
 #include "defs.h"
... ...
@@ -129,6 +130,7 @@
129 129
 #include "t_funcs.h"
130 130
 #include "t_reply.h"
131 131
 #include "t_cancel.h"
132
+#include "t_hooks.h"
132 133
 #ifdef USE_DNS_FAILOVER
133 134
 #include "t_fwd.h" /* t_send_branch */
134 135
 #endif
... ...
@@ -305,6 +307,9 @@ inline static ticks_t retransmission_handler( struct retr_buf *r_buf )
305 305
 				fake_reply(r_buf->my_T, r_buf->branch, 503 );
306 306
 				return (ticks_t)-1;
307 307
 			}
308
+#ifdef TMCB_ONSEND
309
+			run_onsend_callbacks(TMCB_REQUEST_SENT, r_buf, 1);
310
+#endif
308 311
 	} else {
309 312
 #ifdef EXTRA_DEBUG
310 313
 			DBG("DEBUG: retransmission_handler : "
... ...
@@ -53,6 +53,7 @@
53 53
  *  2005-12-16  t_uac will set the new_cell timers to the default values,
54 54
  *               fixes 0 fr_timer bug (andrei)
55 55
  *  2006-08-11  t_uac uses dns failover until it finds a send socket (andrei)
56
+ *  2007-03-15  TMCB_ONSEND callbacks support added (andrei)
56 57
  */
57 58
 
58 59
 #include <string.h>
... ...
@@ -344,6 +345,11 @@ static inline void send_prepared_request_impl(struct retr_buf *request, int retr
344 344
 	if (SEND_BUFFER(request) == -1) {
345 345
 		LOG(L_ERR, "t_uac: Attempt to send to precreated request failed\n");
346 346
 	}
347
+#ifdef TMCB_ONSEND
348
+	else
349
+		/* we don't know the method here */
350
+		run_onsend_callbacks(TMCB_REQUEST_SENT, request, 0);
351
+#endif
347 352
 	
348 353
 	if (retransmit && (start_retr(request)!=0))
349 354
 		LOG(L_CRIT, "BUG: t_uac: failed to start retr. for %p\n", request);