Browse code

Merge remote branch 'origin/sr_3.0'

* origin/sr_3.0:
core: new param to give outbut buffer size
core: use one buffer for int2str
core: use dlflags to load modules
uac(k): use header types for detection
uac(k): proper test for send failure
uac(k): set type for tm callback
modules/mediaproxy: take boundary string from Content-Type header.
core: stats events cbs are called only if USE_CORE_STATS is defined
update drp_reqs statistics
update drp_rpls statistics
update fwd_rpls statistics
update err_reqs statistics
update err_rpls statistics
update bad_URIs statistics
update bad_msg_hdr statistics
core: update fwd_reqs stat
kex: support to update core stats via core events
core: added new event SREV_CORE_STATS

Andrei Pelinescu-Onciul authored on 03/02/2010 22:32:55
Showing 11 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,99 @@
0
+/* 
1
+ * $Id$
2
+ * 
3
+ * Copyright (C) 2010 iptelorg GmbH
4
+ *
5
+ * Permission to use, copy, modify, and distribute this software for any
6
+ * purpose with or without fee is hereby granted, provided that the above
7
+ * copyright notice and this permission notice appear in all copies.
8
+ *
9
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
+ */
17
+/**  macros used for various core statistics.
18
+ *  (if USE_CORE_STATS is not defined they won't do anything)
19
+ * @file core_stats.h
20
+ * @ingroup core
21
+ */
22
+/*
23
+ * History:
24
+ * --------
25
+ *  2010-02-01  initial version (andrei)
26
+*/
27
+
28
+#ifndef __core_stats_h
29
+#define __core_stats_h
30
+
31
+/* define USE_CORE_STATS to enable statistics events 
32
+   (SREV_CORE_STATS callbacks) */
33
+/*#define USE_CORE_STATS */
34
+
35
+#ifndef USE_CORE_STATS
36
+
37
+#define STATS_REQ_FWD_DROP()
38
+#define STATS_REQ_FWD_OK()
39
+#define STATS_RPL_FWD_DROP()
40
+#define STATS_RPL_FWD_OK()
41
+#define STATS_BAD_MSG()
42
+#define STATS_BAD_RPL()
43
+#define STATS_BAD_URI()
44
+#define STATS_BAD_MSG_HDR()
45
+
46
+#else /* USE_CORE_STATS */
47
+
48
+#include "events.h"
49
+
50
+/** called each time a received request is dropped.
51
+ * The request might be dropped explicitly (e.g. pre script callback)
52
+ * or there might be an error while trying to forward it (e.g. send).
53
+ */
54
+#define STATS_REQ_FWD_DROP() sr_event_exec(SREV_CORE_STATS, (void*)3)
55
+
56
+
57
+/** called each time forwarding a request succeeds (send).*/
58
+#define STATS_REQ_FWD_OK() sr_event_exec(SREV_CORE_STATS, (void*)1)
59
+
60
+
61
+/** called each time forwarding a reply fails.
62
+ * The reply forwarding might fail due to send errors,
63
+ * pre script callbacks (module denying forwarding) or explicit script
64
+ * drop (drop or module function returning 0).
65
+ */
66
+#define STATS_RPL_FWD_DROP() sr_event_exec(SREV_CORE_STATS, (void*)4)
67
+
68
+
69
+/* called each time forwarding a reply succeeds. */
70
+#define STATS_RPL_FWD_OK() sr_event_exec(SREV_CORE_STATS, (void*)2)
71
+
72
+
73
+/** called each time a received request is too bad to process.
74
+  * For now it's called in case the message does not have any via.
75
+  */
76
+#define STATS_BAD_MSG() sr_event_exec(SREV_CORE_STATS, (void*)5)
77
+
78
+
79
+/** called each time a received reply is too bad to process.
80
+  * For now it's called in case the message does not have any via.
81
+  */
82
+#define STATS_BAD_RPL() sr_event_exec(SREV_CORE_STATS, (void*)6)
83
+
84
+
85
+/** called each time uri parsing fails. */
86
+#define STATS_BAD_URI() sr_event_exec(SREV_CORE_STATS, (void*)7)
87
+
88
+
89
+/** called each time parsing some header fails. */
90
+#define STATS_BAD_MSG_HDR() sr_event_exec(SREV_CORE_STATS, (void*)8)
91
+
92
+
93
+
94
+#endif /* USE_CORE_STATS */
95
+
96
+#endif /*__core_stats_h*/
97
+
98
+/* vi: set ts=4 sw=4 tw=79:ai:cindent: */
... ...
@@ -55,6 +55,11 @@ int sr_event_register_cb(int type, sr_event_cb_f f)
55 55
 					_sr_events_list.net_data_out = f;
56 56
 				else return -1;
57 57
 			break;
58
+		case SREV_CORE_STATS:
59
+				if(_sr_events_list.core_stats==0)
60
+					_sr_events_list.core_stats = f;
61
+				else return -1;
62
+			break;
58 63
 		default:
59 64
 			return -1;
60 65
 	}
... ...
@@ -98,6 +103,13 @@ int sr_event_exec(int type, void *data)
98 98
 					return ret;
99 99
 				} else return 1;
100 100
 			break;
101
+		case SREV_CORE_STATS:
102
+				if(unlikely(_sr_events_list.core_stats!=0))
103
+				{
104
+					ret = _sr_events_list.core_stats(data);
105
+					return ret;
106
+				} else return 1;
107
+			break;
101 108
 		default:
102 109
 			return -1;
103 110
 	}
... ...
@@ -25,12 +25,14 @@
25 25
 
26 26
 #define SREV_NET_DATA_IN	1
27 27
 #define SREV_NET_DATA_OUT	2
28
+#define SREV_CORE_STATS		3
28 29
 
29 30
 typedef int (*sr_event_cb_f)(void *data);
30 31
 
31 32
 typedef struct sr_event_cb {
32 33
 	sr_event_cb_f net_data_in;
33 34
 	sr_event_cb_f net_data_out;
35
+	sr_event_cb_f core_stats;
34 36
 } sr_event_cb_t;
35 37
 
36 38
 void sr_event_cb_init(void);
... ...
@@ -79,6 +79,7 @@
79 79
 #include "config.h"
80 80
 #include "parser/msg_parser.h"
81 81
 #include "route.h"
82
+#include "events.h"
82 83
 #include "dprint.h"
83 84
 #include "globals.h"
84 85
 #include "cfg_core.h"
... ...
@@ -100,6 +101,7 @@
100 100
 #include "dst_blacklist.h"
101 101
 #endif
102 102
 #include "compiler_opt.h"
103
+#include "core_stats.h"
103 104
 
104 105
 #ifdef DEBUG_DMALLOC
105 106
 #include <dmalloc.h>
... ...
@@ -640,6 +642,12 @@ end:
640 640
 #endif
641 641
 	if (buf) pkg_free(buf);
642 642
 	/* received_buf & line_buf will be freed in receive_msg by free_lump_list*/
643
+#if defined STATS_REQ_FWD_OK || defined STATS_REQ_FWD_DROP
644
+	if(ret==0)
645
+		STATS_REQ_FWD_OK();
646
+	else
647
+		STATS_REQ_FWD_DROP();
648
+#endif /* STATS_REQ_FWD_* */
643 649
 	return ret;
644 650
 }
645 651
 
... ...
@@ -792,7 +800,11 @@ int forward_reply(struct sip_msg* msg)
792 792
 				
793 793
 	} 
794 794
 #endif
795
-	if (msg_send(&dst, new_buf, new_len)<0) goto error;
795
+	if (msg_send(&dst, new_buf, new_len)<0)
796
+	{
797
+		STATS_RPL_FWD_DROP();
798
+		goto error;
799
+	}
796 800
 #ifdef STATS
797 801
 	STATS_TX_RESPONSE(  (msg->first_line.u.reply.statuscode/100) );
798 802
 #endif
... ...
@@ -801,6 +813,7 @@ int forward_reply(struct sip_msg* msg)
801 801
 			msg->via2->host.len, msg->via2->host.s,
802 802
 			(unsigned short) msg->via2->port);
803 803
 
804
+	STATS_RPL_FWD_OK();
804 805
 	pkg_free(new_buf);
805 806
 skip:
806 807
 	return 0;
... ...
@@ -36,6 +36,7 @@
36 36
 
37 37
 #include "../../lib/kcore/statistics.h"
38 38
 #include "../../lib/kmi/mi.h"
39
+#include "../../events.h"
39 40
 #include "../../dprint.h"
40 41
 #include "../../timer.h"
41 42
 #include "../../parser/msg_parser.h"
... ...
@@ -127,6 +128,49 @@ static int km_cb_rpl_stats(struct sip_msg *msg,
127 127
 	return 1;
128 128
 }
129 129
 
130
+
131
+static int sts_update_core_stats(void *data)
132
+{
133
+	int type;
134
+
135
+	type = (int)data;
136
+	switch(type) {
137
+		case 1:
138
+			/* fwd_requests */
139
+			update_stat(fwd_reqs, 1);
140
+		break;
141
+		case 2:
142
+			/* fwd_replies */
143
+			update_stat(fwd_rpls, 1);
144
+		break;
145
+		case 3:
146
+			/* drop_requests */
147
+			update_stat(drp_reqs, 1);
148
+		break;
149
+		case 4:
150
+			/* drop_replies */
151
+			update_stat(drp_rpls, 1);
152
+		break;
153
+		case 5:
154
+			/* err_requests */
155
+			update_stat(err_reqs, 1);
156
+		break;
157
+		case 6:
158
+			/* err_replies */
159
+			update_stat(err_rpls, 1);
160
+		break;
161
+		case 7:
162
+			/* bad_URIs_rcvd */
163
+			update_stat(bad_URIs, 1);
164
+		break;
165
+		case 8:
166
+			/* bad_msg_hdr */
167
+			update_stat(bad_msg_hdr, 1);
168
+		break;
169
+	}
170
+	return 0;
171
+}
172
+
130 173
 int register_core_stats(void)
131 174
 {
132 175
 	/* register core statistics */
... ...
@@ -147,6 +191,7 @@ int register_core_stats(void)
147 147
 		LM_ERR("failed to register PRE request callback\n");
148 148
 		return -1;
149 149
 	}
150
+	sr_event_register_cb(SREV_CORE_STATS, sts_update_core_stats);
150 151
 
151 152
 	return 0;
152 153
 }
... ...
@@ -231,9 +231,9 @@ struct hdr_field *get_autenticate_hdr(struct sip_msg *rpl, int rpl_code)
231 231
 	}
232 232
 	for( hdr=rpl->headers ; hdr ; hdr=hdr->next )
233 233
 	{
234
-		if((rpl_code==WWW_AUTH_CODE && hdr->type==HDR_WWW_AUTHENTICATE_T)
235
-				|| (rpl_code==PROXY_AUTH_CODE
236
-					&& hdr->type==HDR_PROXY_AUTHENTICATE_T))
234
+		if ( rpl_code==WWW_AUTH_CODE && hdr->type==HDR_WWW_AUTHENTICATE_T )
235
+			return hdr;
236
+		if ( rpl_code==PROXY_AUTH_CODE && hdr->type==HDR_PROXY_AUTHENTICATE_T )
237 237
 			return hdr;
238 238
 	}
239 239
 
... ...
@@ -66,6 +66,7 @@
66 66
 #include "../data_lump_rpl.h"
67 67
 #include "../mem/mem.h"
68 68
 #include "../error.h"
69
+#include "../core_stats.h"
69 70
 #include "../globals.h"
70 71
 #include "parse_hname2.h"
71 72
 #include "parse_uri.h"
... ...
@@ -290,6 +291,7 @@ char* get_hdr_field(char* buf, char* end, struct hdr_field* hdr)
290 290
 	return tmp;
291 291
 error:
292 292
 	DBG("get_hdr_field: error exit\n");
293
+	STATS_BAD_MSG_HDR();
293 294
 	hdr->type=HDR_ERROR_T;
294 295
 	hdr->len=tmp-hdr->name.s;
295 296
 	return tmp;
... ...
@@ -56,6 +56,7 @@
56 56
 #include "../ut.h"   /* q_memchr */
57 57
 /* #endif */
58 58
 #include "../error.h"
59
+#include "../core_stats.h"
59 60
 
60 61
 /* buf= pointer to begining of uri (sip:x@foo.bar:5060;a=b?h=i)
61 62
  * len= len of uri
... ...
@@ -1229,6 +1230,7 @@ error_bug:
1229 1229
 error_exit:
1230 1230
 	ser_error=E_BAD_URI;
1231 1231
 	uri->type=ERROR_URI_T;
1232
+	STATS_BAD_URI();
1232 1233
 	return E_BAD_URI;
1233 1234
 }
1234 1235
 
... ...
@@ -71,6 +71,7 @@
71 71
 #include "tcp_server.h" /* for tcpconn_add_alias */
72 72
 #include "tcp_options.h" /* for access to tcp_accept_aliases*/
73 73
 #include "cfg/cfg.h"
74
+#include "core_stats.h"
74 75
 
75 76
 #ifdef DEBUG_DMALLOC
76 77
 #include <mem/dmalloc.h>
... ...
@@ -156,6 +157,7 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
156 156
 		if ((msg->via1==0) || (msg->via1->error!=PARSE_OK)){
157 157
 			/* no via, send back error ? */
158 158
 			LOG(L_ERR, "ERROR: receive_msg: no via found in request\n");
159
+			STATS_BAD_MSG();
159 160
 			goto error02;
160 161
 		}
161 162
 		/* check if necessary to add receive?->moved to forward_req */
... ...
@@ -189,7 +191,10 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
189 189
 		   on via1 being parsed in a pre-script callback --andrei
190 190
 		*/
191 191
 		if (exec_pre_script_cb(msg, REQUEST_CB_TYPE)==0 )
192
+		{
193
+			STATS_REQ_FWD_DROP();
192 194
 			goto end; /* drop the request */
195
+		}
193 196
 
194 197
 		set_route_type(REQUEST_ROUTE);
195 198
 		/* exec the routing script */
... ...
@@ -215,6 +220,7 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
215 215
 		if ((msg->via1==0) || (msg->via1->error!=PARSE_OK)){
216 216
 			/* no via, send back error ? */
217 217
 			LOG(L_ERR, "ERROR: receive_msg: no via found in reply\n");
218
+			STATS_BAD_RPL();
218 219
 			goto error02;
219 220
 		}
220 221
 
... ...
@@ -231,7 +237,10 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
231 231
 		   on via1 being parsed in a pre-script callback --andrei
232 232
 		*/
233 233
 		if (exec_pre_script_cb(msg, ONREPLY_CB_TYPE)==0 )
234
-			goto end; /* drop the request */
234
+		{
235
+			STATS_RPL_FWD_DROP();
236
+			goto end; /* drop the reply */
237
+		}
235 238
 
236 239
 		/* exec the onreply routing script */
237 240
 		if (onreply_rt.rlist[DEFAULT_RT]){
... ...
@@ -245,6 +254,7 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
245 245
 			}else
246 246
 #endif /* NO_ONREPLY_ROUTE_ERROR */
247 247
 			if (unlikely(ret==0 || (ctx.run_flags&DROP_R_F))){
248
+				STATS_RPL_FWD_DROP();
248 249
 				goto skip_send_reply; /* drop the message, no error */
249 250
 			}
250 251
 		}
... ...
@@ -49,6 +49,9 @@
49 49
 #include "mem/mem.h"
50 50
 #include "globals.h"
51 51
 
52
+/* global buffer for ut.h int2str() */
53
+char ut_buf_int2str[INT2STR_MAX_LEN];
54
+
52 55
 
53 56
 /* converts a username into uid:gid,
54 57
  * returns -1 on error & 0 on success */
... ...
@@ -292,12 +292,17 @@ static inline char* int2str_base(unsigned int l, int* len, int base)
292 292
 
293 293
 
294 294
 
295
-/* returns a pointer to a static buffer containing l in asciiz & sets len */
296
-static inline char* int2str(unsigned int l, int* len)
295
+/* print int to asciiz in a string buffer
296
+ * - be sure result buffer is at least INT2STR_MAX_LEN in size */
297
+static inline char* int2strbuf(unsigned int l, char *r, int r_size, int* len)
297 298
 {
298
-	static char r[INT2STR_MAX_LEN];
299 299
 	int i;
300
-	
300
+
301
+	if(unlikely(r_size<INT2STR_MAX_LEN)) {
302
+		if (len)
303
+			*len = 0;
304
+		return 0; /* => if someone misuses it => crash (feature no. 1) */
305
+	}
301 306
 	i=INT2STR_MAX_LEN-2;
302 307
 	r[INT2STR_MAX_LEN-1]=0; /* null terminate */
303 308
 	do{
... ...
@@ -312,6 +317,13 @@ static inline char* int2str(unsigned int l, int* len)
312 312
 	return &r[i+1];
313 313
 }
314 314
 
315
+extern char ut_buf_int2str[INT2STR_MAX_LEN];
316
+/* returns a pointer to a static buffer containing l in asciiz & sets len */
317
+static inline char* int2str(unsigned long l, int* len)
318
+{
319
+	return int2strbuf(l, ut_buf_int2str, INT2STR_MAX_LEN, len);
320
+}
321
+
315 322
 /* Signed INTeger-TO-STRing: convers a long to a string
316 323
  * returns a pointer to a static buffer containing l in asciiz & sets len */
317 324
 static inline char* sint2str(long l, int* len)