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 82
 #define NO_CANCEL       ( (char*) 0 )
81 83
 #define EXTERNAL_CANCEL ( (char*) -1)
82 84
 
85
+#define TYPE_LOCAL_ACK    -2
83 86
 #define TYPE_LOCAL_CANCEL -1
84 87
 #define TYPE_REQUEST       0
85 88
 
... ...
@@ -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 47
 #include "t_cancel.h"
47 48
 #include "t_msgbuilder.h"
48 49
 #include "t_lookup.h" /* for t_lookup_callid in fifo_uac_cancel */
50
+#include "t_hooks.h"
49 51
 
50 52
 
51 53
 /* 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 116
  *         -1 - error
115 117
  * WARNING:
116 118
  *          - F_CANCEL_KILL_B should be used only if the transaction is killed
117
- *            explicitely afterwards (since it might kill all the timers
119
+ *            explicitly afterwards (since it might kill all the timers
118 120
  *            the transaction won't be able to "kill" itself => if not
119
- *            explicitely "put_on_wait" it migh leave forever)
121
+ *            explicitly "put_on_wait" it might live forever)
120 122
  *          - F_CANCEL_B_FAKE_REPLY must be used only if the REPLY_LOCK is not
121 123
  *            held
122 124
  */
... ...
@@ -189,7 +191,12 @@ int cancel_branch( struct cell *t, int branch, int flags )
189 191
 	crb->activ_type = TYPE_LOCAL_CANCEL;
190 192
 
191 193
 	DBG("DEBUG: cancel_branch: sending cancel...\n");
194
+#ifdef TMCB_ONSEND
195
+	if (SEND_BUFFER( crb )>=0)
196
+		run_onsend_callbacks(TMCB_REQUEST_SENT, crb, 0);
197
+#else
192 198
 	SEND_BUFFER( crb );
199
+#endif
193 200
 	/*sets and starts the FINAL RESPONSE timer */
194 201
 	if (start_retr( crb )!=0)
195 202
 		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 508
 				if (SEND_BUFFER(&t_cancel->uac[i].request) == -1) {
508 509
 					LOG(L_ERR, "ERROR: e2e_cancel: send failed\n");
509 510
 				}
511
+#ifdef TMCB_ONSEND
512
+				else{
513
+					run_onsend_callbacks(TMCB_REQUEST_SENT, 
514
+											&t_cancel->uac[i].request, 0);
515
+				}
516
+#endif
510 517
 				if (start_retr( &t_cancel->uac[i].request )!=0)
511 518
 					LOG(L_CRIT, "BUG: e2e_cancel: failed to start retr."
512 519
 							" 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 662
 	if (SEND_BUFFER( &uac->request)==-1) {
656 663
 		/* disable the current branch: set a "fake" timeout
657 664
 		 *  reply code but don't set uac->reply, to avoid overriding 
658
-		 *  a higly unlikely, perfectly timed fake reply (to a message
665
+		 *  a highly unlikely, perfectly timed fake reply (to a message
659 666
 		 *  we never sent).
660 667
 		 * (code=final reply && reply==0 => t_pick_branch won't ever pick it)*/
661 668
 		uac->last_received=408;
... ...
@@ -685,6 +692,9 @@ int t_send_branch( struct cell *t, int branch, struct sip_msg* p_msg ,
685 692
 		if (proxy) { proxy->errors++; proxy->ok=0; }
686 693
 		return -2;
687 694
 	} else {
695
+#ifdef TMCB_ONSEND
696
+		run_onsend_callbacks(TMCB_REQUEST_SENT, &uac->request, 0);
697
+#endif
688 698
 		/* start retr. only if the send succeeded */
689 699
 		if (start_retr( &uac->request )!=0){
690 700
 			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 183
 }
183 184
 
184 185
 
185
-void run_trans_callbacks( int type , struct cell *trans,
186
-						struct sip_msg *req, struct sip_msg *rpl, int code )
186
+static void run_trans_callbacks_internal(int type, struct cell *trans, 
187
+											struct tmcb_params *params)
187 188
 {
188
-	static struct tmcb_params params = {0,0,0,0};
189 189
 	struct tm_callback    *cbp;
190 190
 	avp_list_t* backup_from, *backup_to, *backup_dom_from, *backup_dom_to, *backup_uri_from, *backup_uri_to;
191 191
 
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 192
 	backup_uri_from = set_avp_list(AVP_CLASS_URI | AVP_TRACK_FROM, &trans->uri_avps_from );
200 193
 	backup_uri_to = set_avp_list(AVP_CLASS_URI | AVP_TRACK_TO, &trans->uri_avps_to );
201 194
 	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 199
 		if ( (cbp->types)&type ) {
207 200
 			DBG("DBG: trans=%p, callback type %d, id %d entered\n",
208 201
 				trans, type, cbp->id );
209
-			params.param = &(cbp->param);
210
-			cbp->callback( trans, type, &params );
202
+			params->param = &(cbp->param);
203
+			cbp->callback( trans, type, params );
211 204
 		}
212 205
 	}
213 206
 	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 213
 
221 214
 
222 215
 
216
+void run_trans_callbacks( int type , struct cell *trans,
217
+						struct sip_msg *req, struct sip_msg *rpl, int code )
218
+{
219
+	struct tmcb_params params;
220
+	if (trans->tmcb_hl.first==0 || ((trans->tmcb_hl.reg_types)&type)==0 )
221
+		return;
222
+	memset (&params, 0, sizeof(params));
223
+	params.req = req;
224
+	params.rpl = rpl;
225
+	params.code = code;
226
+	run_trans_callbacks_internal(type, trans, &params);
227
+}
228
+
229
+
230
+
231
+#ifdef TMCB_ONSEND
232
+void run_onsend_callbacks(int type, struct retr_buf* rbuf, int retr)
233
+{
234
+	struct tmcb_params params;
235
+	struct cell * trans;
236
+
237
+	trans=rbuf->my_T;
238
+	if ( trans==0 || trans->tmcb_hl.first==0 || 
239
+			((trans->tmcb_hl.reg_types)&type)==0 )
240
+		return;
241
+	memset (&params, 0, sizeof(params));
242
+	params.send_buf.s=rbuf->buffer;
243
+	params.send_buf.len=rbuf->buffer_len;
244
+	params.dst=&rbuf->dst;
245
+	params.is_retr=retr;
246
+	params.branch=rbuf->branch;
247
+	params.t_rbuf=rbuf;
248
+	params.code=rbuf->activ_type;
249
+	/* req, rpl */
250
+	run_trans_callbacks_internal(type, trans, &params);
251
+}
252
+
253
+
254
+void run_onsend_callbacks2(int type , struct retr_buf* rbuf, char* buf,
255
+							int buf_len, struct dest_info* dst, int code)
256
+{
257
+	struct tmcb_params params;
258
+	struct cell * trans;
259
+
260
+	trans=rbuf->my_T;
261
+	if ( trans==0 || trans->tmcb_hl.first==0 || 
262
+			((trans->tmcb_hl.reg_types)&type)==0 )
263
+		return;
264
+	memset (&params, 0, sizeof(params));
265
+	params.send_buf.s=buf;
266
+	params.send_buf.len=buf_len;
267
+	params.dst=dst;
268
+	params.is_retr=0;
269
+	params.branch=rbuf->branch;
270
+	params.t_rbuf=rbuf;
271
+	params.code=code;
272
+	/* req, rpl */
273
+	run_trans_callbacks_internal(type, trans, &params);
274
+}
275
+
276
+#endif
277
+
223 278
 void run_reqin_callbacks( struct cell *trans, struct sip_msg *req, int code )
224 279
 {
225
-	static struct tmcb_params params = {0,0,0,0};
280
+	static struct tmcb_params params;
226 281
 	struct tm_callback    *cbp;
227 282
 	avp_list_t* backup_from, *backup_to, *backup_dom_from, *backup_dom_to, *backup_uri_from, *backup_uri_to;
228 283
 
284
+	if (req_in_tmcb_hl->first==0)
285
+		return;
286
+	memset (&params, 0, sizeof(params));
229 287
 	params.req = req;
230 288
 	params.code = code;
231 289
 
232
-	if (req_in_tmcb_hl->first==0)
233
-		return;
234 290
 
235 291
 	backup_uri_from = set_avp_list(AVP_CLASS_URI | AVP_TRACK_FROM, &trans->uri_avps_from );
236 292
 	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 40
 
40 41
 #include "defs.h"
41 42
 
43
+/* if defined support for ONSEND callbacks will be added and
44
+ * the tmcb_params structure will get some additional members */
45
+/*
46
+#define TMCB_ONSEND
47
+*/
48
+#ifdef TMCB_ONSEND
49
+#include "../../ip_addr.h" /* dest_info */
50
+#endif
51
+
42 52
 struct sip_msg;
43 53
 struct cell;
44 54
 
... ...
@@ -52,7 +62,13 @@ struct cell;
52 62
 #define TMCB_RESPONSE_OUT_N     7
53 63
 #define TMCB_LOCAL_COMPLETED_N  8
54 64
 #define TMCB_LOCAL_RESPONSE_OUT_N 9
65
+#ifdef TMCB_ONSEND
66
+#define TMCB_REQUEST_SENT_N     10
67
+#define TMCB_RESPONSE_SENT_N    11
68
+#define TMCB_MAX_N              11
69
+#else
55 70
 #define TMCB_MAX_N              9
71
+#endif
56 72
 
57 73
 #define TMCB_REQUEST_IN       (1<<TMCB_REQUEST_IN_N)
58 74
 #define TMCB_RESPONSE_IN      (1<<TMCB_RESPONSE_IN_N)
... ...
@@ -64,6 +80,10 @@ struct cell;
64 80
 #define TMCB_RESPONSE_OUT     (1<<TMCB_RESPONSE_OUT_N)
65 81
 #define TMCB_LOCAL_COMPLETED  (1<<TMCB_LOCAL_COMPLETED_N)
66 82
 #define TMCB_LOCAL_RESPONSE_OUT (1<<TMCB_LOCAL_RESPONSE_OUT_N)
83
+#ifdef TMCB_ONSEND
84
+#define TMCB_REQUEST_SENT      (1<<TMCB_REQUEST_SENT_N)
85
+#define TMCB_RESPONSE_SENT     (1<<TMCB_RESPONSE_SENT_N)
86
+#endif
67 87
 #define TMCB_MAX              ((1<<(TMCB_MAX_N+1))-1)
68 88
 
69 89
 
... ...
@@ -199,11 +219,49 @@ struct cell;
199 219
  *  called multiple time quasi-simultaneously. No lock is held.
200 220
  *  It's unsafe to register other TMCB callbacks.
201 221
  *
222
+ *  TMCB_ONSEND callbacks
223
+ *
224
+ *  All of the following callbacks are called immediately after or before 
225
+ *  sending a message. All of them are read-only (no change can be made to
226
+ * the message). These callbacks use the t_rbuf, send_buf, dst, is_retr
227
+ *  and the code members of the tmcb_params structure.
228
+ *  For a request code is <=0. code values can be TYPE_LOCAL_ACK for an ACK 
229
+ *  generated by ser, TYPE_LOCAL_CANCEL for a CANCEL generated by ser 
230
+ *  and TYPE_REQUEST for all the other requests or requests generated via 
231
+ *  t_uac.
232
+ *   For a reply the code is the response status (which is always >0, e.g. 200,
233
+ *   408, a.s.o).
234
+ *  Note: - these callbacks can be used only if TMCB_ONSEND is defined.
235
+ *        - the callbacks will be called sometimes with the REPLY lock held
236
+ *          and sometimes without it, so trying to acquire the REPLY lock
237
+ *          from these callbacks could lead to deadlocks (avoid it unless
238
+ *           you really know what you're doing).
239
+ *
240
+ *  TMCB_REQUEST_SENT (present only if TMCB_ONSEND is defined) -- called 
241
+ *  each time a request was sent (even for retransmissions), it includes 
242
+ *  local and forwarded request, ser generated CANCELs and ACKs. The 
243
+ *  tmcb_params structure will have the t_rbuf, dst, send_buf and is_retr
244
+ *  members  filled.
245
+ *  This callback is "read-only", the message was already sent and no changes
246
+ *  are allowed.
247
+ *  Note: send_buf can be different from t_rbuf->buffer for ACKs (in this
248
+ *   case t_rbuf->buf will contain the last request sent on the branch and
249
+ *   its destination). The same goes for t_rbuf->dst and tmcb->dst for local 
250
+ *   transactions ACKs to 2xxs.
251
+ *
252
+ *  TMCB_RESPONSE_SENT  (present only if TMCB_ONSEND is defined) -- called 
253
+ *  each time a response was sent (even for retransmissions). The tmcb_params
254
+ *   structure will have t_rbuf set to the reply retransmission buffer and
255
+ *   send_buf set to the data sent (in this case it will always be the same 
256
+ *   with t_rbuf->buf). is_retr will also be set if the reply is retransmitted
257
+ *   by ser.
258
+ *  This callback is "read-only", the message was already sent and no changes
259
+ *  are allowed.
202 260
  *
203 261
 
204 262
 	the callback's param MUST be in shared memory and will
205 263
 	NOT be freed by TM; you must do it yourself from the
206
-	callback function id necessary.
264
+	callback function if necessary.
207 265
 */
208 266
 
209 267
 
... ...
@@ -211,8 +269,22 @@ struct cell;
211 269
 struct tmcb_params {
212 270
 	struct sip_msg* req;
213 271
 	struct sip_msg* rpl;
214
-	int code;
215 272
 	void **param;
273
+#ifdef TMCB_ONSEND
274
+	struct retr_buf* t_rbuf; /* transaction retr. buf., all the information
275
+								 regarding destination, data that is/was
276
+								 actually sent on the net, branch a.s.o is
277
+								 inside */
278
+	struct dest_info* dst; /* destination */
279
+	str send_buf; /* what was/will be sent on the net, used for ACKs
280
+					(which don't have a retr_buf). */
281
+	short is_retr; /* set if this is a _ser_ retransmission (but not if
282
+					 if it's a "forwarded" retr., like a retr. 200 Ok for 
283
+					 example) */
284
+	unsigned short branch;
285
+	/* could also be: send_buf, dst, branch */
286
+#endif
287
+	int code;
216 288
 };
217 289
 
218 290
 /* callback function prototype */
... ...
@@ -267,4 +339,10 @@ void run_trans_callbacks( int type , struct cell *trans,
267 339
 /* run all REQUEST_IN callbacks */
268 340
 void run_reqin_callbacks( struct cell *trans, struct sip_msg *req, int code );
269 341
 
342
+#ifdef TMCB_ONSEND
343
+void run_onsend_callbacks(int type, struct retr_buf* rbuf, int retr);
344
+void run_onsend_callbacks2(int type , struct retr_buf* rbuf, char* buf,
345
+							int buf_len, struct dest_info* dst, int code);
346
+#endif
347
+
270 348
 #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 492
 	if (!trans->uas.response.dst.send_sock) {
492 493
 		LOG(L_ERR, "ERROR: _reply_light: no resolved dst to send reply to\n");
493 494
 	} else {
495
+#ifdef TMCB_ONSEND
496
+		if (SEND_PR_BUFFER( rb, buf, len )>=0)
497
+			run_onsend_callbacks2(TMCB_RESPONSE_SENT, rb, buf, len, &rb->dst,
498
+									code);
499
+#else
494 500
 		SEND_PR_BUFFER( rb, buf, len );
501
+#endif
495 502
 		DBG("DEBUG: reply sent out. buf=%p: %.9s..., shmem=%p: %.9s\n",
496 503
 			buf, buf, rb->buffer, rb->buffer );
497 504
 	}
... ...
@@ -1069,6 +1076,9 @@ int t_retransmit_reply( struct cell *t )
1069 1076
 	memcpy( b, t->uas.response.buffer, len );
1070 1077
 	UNLOCK_REPLIES( t );
1071 1078
 	SEND_PR_BUFFER( & t->uas.response, b, len );
1079
+#ifdef TMCB_ONSEND
1080
+	run_onsend_callbacks(TMCB_RESPONSE_SENT, &t->uas.response, 1);
1081
+#endif
1072 1082
 	DBG("DEBUG: reply retransmitted. buf=%p: %.9s..., shmem=%p: %.9s\n",
1073 1083
 		b, b, t->uas.response.buffer, t->uas.response.buffer );
1074 1084
 	return 1;
... ...
@@ -1431,12 +1441,15 @@ enum rps relay_reply( struct cell *t, struct sip_msg *p_msg, int branch,
1431 1441
 
1432 1442
 	/* send it now (from the private buffer) */
1433 1443
 	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);
1444
+		if (SEND_PR_BUFFER( uas_rb, buf, res_len )>=0){
1445
+			if (!totag_retr && has_tran_tmcbs(t, TMCB_RESPONSE_OUT) ) {
1446
+				run_trans_callbacks( TMCB_RESPONSE_OUT, t, t->uas.request,
1447
+					relayed_msg, relayed_code);
1448
+			}
1449
+#ifdef TMCB_ONSEND
1450
+			run_onsend_callbacks2(TMCB_RESPONSE_SENT, uas_rb, buf, res_len,
1451
+									&uas_rb->dst, relayed_code);
1452
+#endif
1440 1453
 		}
1441 1454
 		pkg_free( buf );
1442 1455
 	}
... ...
@@ -1615,15 +1628,28 @@ int reply_received( struct sip_msg  *p_msg )
1615 1628
 			if (msg_status >= 300) {
1616 1629
 				ack = build_ack(p_msg, t, branch, &ack_len);
1617 1630
 				if (ack) {
1631
+#ifdef	TMCB_ONSEND
1632
+					if (SEND_PR_BUFFER(&uac->request, ack, ack_len)>=0)
1633
+						run_onsend_callbacks2(TMCB_REQUEST_SENT,
1634
+									&uac->request, ack, ack_len, 
1635
+									&uac->request.dst,
1636
+									TYPE_LOCAL_ACK);
1637
+#else
1618 1638
 					SEND_PR_BUFFER(&uac->request, ack, ack_len);
1639
+#endif
1619 1640
 					shm_free(ack);
1620 1641
 				}
1621 1642
 			} else if (is_local(t) /*&& 200 <= msg_status < 300*/) {
1622 1643
 				ack = build_local_ack(p_msg, t, branch, &ack_len, &lack_dst);
1623 1644
 				if (ack) {
1624
-					if (msg_send(&lack_dst, ack, ack_len)<0){
1645
+					if (msg_send(&lack_dst, ack, ack_len)<0)
1625 1646
 						LOG(L_ERR, "Error while sending local ACK\n");
1626
-					}
1647
+#ifdef	TMCB_ONSEND
1648
+					else
1649
+						run_onsend_callbacks2(TMCB_REQUEST_SENT,
1650
+									&uac->request, ack, ack_len, &lack_dst,
1651
+									TYPE_LOCAL_ACK);
1652
+#endif
1627 1653
 					shm_free(ack);
1628 1654
 				}
1629 1655
 			}
... ...
@@ -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 130
 #include "t_funcs.h"
130 131
 #include "t_reply.h"
131 132
 #include "t_cancel.h"
133
+#include "t_hooks.h"
132 134
 #ifdef USE_DNS_FAILOVER
133 135
 #include "t_fwd.h" /* t_send_branch */
134 136
 #endif
... ...
@@ -305,6 +307,9 @@ inline static ticks_t retransmission_handler( struct retr_buf *r_buf )
305 307
 				fake_reply(r_buf->my_T, r_buf->branch, 503 );
306 308
 				return (ticks_t)-1;
307 309
 			}
310
+#ifdef TMCB_ONSEND
311
+			run_onsend_callbacks(TMCB_REQUEST_SENT, r_buf, 1);
312
+#endif
308 313
 	} else {
309 314
 #ifdef EXTRA_DEBUG
310 315
 			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 345
 	if (SEND_BUFFER(request) == -1) {
345 346
 		LOG(L_ERR, "t_uac: Attempt to send to precreated request failed\n");
346 347
 	}
348
+#ifdef TMCB_ONSEND
349
+	else
350
+		/* we don't know the method here */
351
+		run_onsend_callbacks(TMCB_REQUEST_SENT, request, 0);
352
+#endif
347 353
 	
348 354
 	if (retransmit && (start_retr(request)!=0))
349 355
 		LOG(L_CRIT, "BUG: t_uac: failed to start retr. for %p\n", request);