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 @@
1
+/* 
2
+ * $Id$
3
+ * 
4
+ * Copyright (C) 2010 iptelorg GmbH
5
+ *
6
+ * Permission to use, copy, modify, and distribute this software for any
7
+ * purpose with or without fee is hereby granted, provided that the above
8
+ * copyright notice and this permission notice appear in all copies.
9
+ *
10
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
+ */
18
+/**  macros used for various core statistics.
19
+ *  (if USE_CORE_STATS is not defined they won't do anything)
20
+ * @file core_stats.h
21
+ * @ingroup core
22
+ */
23
+/*
24
+ * History:
25
+ * --------
26
+ *  2010-02-01  initial version (andrei)
27
+*/
28
+
29
+#ifndef __core_stats_h
30
+#define __core_stats_h
31
+
32
+/* define USE_CORE_STATS to enable statistics events 
33
+   (SREV_CORE_STATS callbacks) */
34
+/*#define USE_CORE_STATS */
35
+
36
+#ifndef USE_CORE_STATS
37
+
38
+#define STATS_REQ_FWD_DROP()
39
+#define STATS_REQ_FWD_OK()
40
+#define STATS_RPL_FWD_DROP()
41
+#define STATS_RPL_FWD_OK()
42
+#define STATS_BAD_MSG()
43
+#define STATS_BAD_RPL()
44
+#define STATS_BAD_URI()
45
+#define STATS_BAD_MSG_HDR()
46
+
47
+#else /* USE_CORE_STATS */
48
+
49
+#include "events.h"
50
+
51
+/** called each time a received request is dropped.
52
+ * The request might be dropped explicitly (e.g. pre script callback)
53
+ * or there might be an error while trying to forward it (e.g. send).
54
+ */
55
+#define STATS_REQ_FWD_DROP() sr_event_exec(SREV_CORE_STATS, (void*)3)
56
+
57
+
58
+/** called each time forwarding a request succeeds (send).*/
59
+#define STATS_REQ_FWD_OK() sr_event_exec(SREV_CORE_STATS, (void*)1)
60
+
61
+
62
+/** called each time forwarding a reply fails.
63
+ * The reply forwarding might fail due to send errors,
64
+ * pre script callbacks (module denying forwarding) or explicit script
65
+ * drop (drop or module function returning 0).
66
+ */
67
+#define STATS_RPL_FWD_DROP() sr_event_exec(SREV_CORE_STATS, (void*)4)
68
+
69
+
70
+/* called each time forwarding a reply succeeds. */
71
+#define STATS_RPL_FWD_OK() sr_event_exec(SREV_CORE_STATS, (void*)2)
72
+
73
+
74
+/** called each time a received request is too bad to process.
75
+  * For now it's called in case the message does not have any via.
76
+  */
77
+#define STATS_BAD_MSG() sr_event_exec(SREV_CORE_STATS, (void*)5)
78
+
79
+
80
+/** called each time a received reply is too bad to process.
81
+  * For now it's called in case the message does not have any via.
82
+  */
83
+#define STATS_BAD_RPL() sr_event_exec(SREV_CORE_STATS, (void*)6)
84
+
85
+
86
+/** called each time uri parsing fails. */
87
+#define STATS_BAD_URI() sr_event_exec(SREV_CORE_STATS, (void*)7)
88
+
89
+
90
+/** called each time parsing some header fails. */
91
+#define STATS_BAD_MSG_HDR() sr_event_exec(SREV_CORE_STATS, (void*)8)
92
+
93
+
94
+
95
+#endif /* USE_CORE_STATS */
96
+
97
+#endif /*__core_stats_h*/
98
+
99
+/* 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 103
 					return ret;
99 104
 				} else return 1;
100 105
 			break;
106
+		case SREV_CORE_STATS:
107
+				if(unlikely(_sr_events_list.core_stats!=0))
108
+				{
109
+					ret = _sr_events_list.core_stats(data);
110
+					return ret;
111
+				} else return 1;
112
+			break;
101 113
 		default:
102 114
 			return -1;
103 115
 	}
... ...
@@ -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 101
 #include "dst_blacklist.h"
101 102
 #endif
102 103
 #include "compiler_opt.h"
104
+#include "core_stats.h"
103 105
 
104 106
 #ifdef DEBUG_DMALLOC
105 107
 #include <dmalloc.h>
... ...
@@ -640,6 +642,12 @@ end:
640 642
 #endif
641 643
 	if (buf) pkg_free(buf);
642 644
 	/* received_buf & line_buf will be freed in receive_msg by free_lump_list*/
645
+#if defined STATS_REQ_FWD_OK || defined STATS_REQ_FWD_DROP
646
+	if(ret==0)
647
+		STATS_REQ_FWD_OK();
648
+	else
649
+		STATS_REQ_FWD_DROP();
650
+#endif /* STATS_REQ_FWD_* */
643 651
 	return ret;
644 652
 }
645 653
 
... ...
@@ -792,7 +800,11 @@ int forward_reply(struct sip_msg* msg)
792 800
 				
793 801
 	} 
794 802
 #endif
795
-	if (msg_send(&dst, new_buf, new_len)<0) goto error;
803
+	if (msg_send(&dst, new_buf, new_len)<0)
804
+	{
805
+		STATS_RPL_FWD_DROP();
806
+		goto error;
807
+	}
796 808
 #ifdef STATS
797 809
 	STATS_TX_RESPONSE(  (msg->first_line.u.reply.statuscode/100) );
798 810
 #endif
... ...
@@ -801,6 +813,7 @@ int forward_reply(struct sip_msg* msg)
801 813
 			msg->via2->host.len, msg->via2->host.s,
802 814
 			(unsigned short) msg->via2->port);
803 815
 
816
+	STATS_RPL_FWD_OK();
804 817
 	pkg_free(new_buf);
805 818
 skip:
806 819
 	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 128
 	return 1;
128 129
 }
129 130
 
131
+
132
+static int sts_update_core_stats(void *data)
133
+{
134
+	int type;
135
+
136
+	type = (int)data;
137
+	switch(type) {
138
+		case 1:
139
+			/* fwd_requests */
140
+			update_stat(fwd_reqs, 1);
141
+		break;
142
+		case 2:
143
+			/* fwd_replies */
144
+			update_stat(fwd_rpls, 1);
145
+		break;
146
+		case 3:
147
+			/* drop_requests */
148
+			update_stat(drp_reqs, 1);
149
+		break;
150
+		case 4:
151
+			/* drop_replies */
152
+			update_stat(drp_rpls, 1);
153
+		break;
154
+		case 5:
155
+			/* err_requests */
156
+			update_stat(err_reqs, 1);
157
+		break;
158
+		case 6:
159
+			/* err_replies */
160
+			update_stat(err_rpls, 1);
161
+		break;
162
+		case 7:
163
+			/* bad_URIs_rcvd */
164
+			update_stat(bad_URIs, 1);
165
+		break;
166
+		case 8:
167
+			/* bad_msg_hdr */
168
+			update_stat(bad_msg_hdr, 1);
169
+		break;
170
+	}
171
+	return 0;
172
+}
173
+
130 174
 int register_core_stats(void)
131 175
 {
132 176
 	/* register core statistics */
... ...
@@ -147,6 +191,7 @@ int register_core_stats(void)
147 191
 		LM_ERR("failed to register PRE request callback\n");
148 192
 		return -1;
149 193
 	}
194
+	sr_event_register_cb(SREV_CORE_STATS, sts_update_core_stats);
150 195
 
151 196
 	return 0;
152 197
 }
... ...
@@ -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 291
 	return tmp;
291 292
 error:
292 293
 	DBG("get_hdr_field: error exit\n");
294
+	STATS_BAD_MSG_HDR();
293 295
 	hdr->type=HDR_ERROR_T;
294 296
 	hdr->len=tmp-hdr->name.s;
295 297
 	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 1230
 error_exit:
1230 1231
 	ser_error=E_BAD_URI;
1231 1232
 	uri->type=ERROR_URI_T;
1233
+	STATS_BAD_URI();
1232 1234
 	return E_BAD_URI;
1233 1235
 }
1234 1236
 
... ...
@@ -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 157
 		if ((msg->via1==0) || (msg->via1->error!=PARSE_OK)){
157 158
 			/* no via, send back error ? */
158 159
 			LOG(L_ERR, "ERROR: receive_msg: no via found in request\n");
160
+			STATS_BAD_MSG();
159 161
 			goto error02;
160 162
 		}
161 163
 		/* 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 191
 		   on via1 being parsed in a pre-script callback --andrei
190 192
 		*/
191 193
 		if (exec_pre_script_cb(msg, REQUEST_CB_TYPE)==0 )
194
+		{
195
+			STATS_REQ_FWD_DROP();
192 196
 			goto end; /* drop the request */
197
+		}
193 198
 
194 199
 		set_route_type(REQUEST_ROUTE);
195 200
 		/* exec the routing script */
... ...
@@ -215,6 +220,7 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
215 220
 		if ((msg->via1==0) || (msg->via1->error!=PARSE_OK)){
216 221
 			/* no via, send back error ? */
217 222
 			LOG(L_ERR, "ERROR: receive_msg: no via found in reply\n");
223
+			STATS_BAD_RPL();
218 224
 			goto error02;
219 225
 		}
220 226
 
... ...
@@ -231,7 +237,10 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
231 237
 		   on via1 being parsed in a pre-script callback --andrei
232 238
 		*/
233 239
 		if (exec_pre_script_cb(msg, ONREPLY_CB_TYPE)==0 )
234
-			goto end; /* drop the request */
240
+		{
241
+			STATS_RPL_FWD_DROP();
242
+			goto end; /* drop the reply */
243
+		}
235 244
 
236 245
 		/* exec the onreply routing script */
237 246
 		if (onreply_rt.rlist[DEFAULT_RT]){
... ...
@@ -245,6 +254,7 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
245 254
 			}else
246 255
 #endif /* NO_ONREPLY_ROUTE_ERROR */
247 256
 			if (unlikely(ret==0 || (ctx.run_flags&DROP_R_F))){
257
+				STATS_RPL_FWD_DROP();
248 258
 				goto skip_send_reply; /* drop the message, no error */
249 259
 			}
250 260
 		}
... ...
@@ -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 317
 	return &r[i+1];
313 318
 }
314 319
 
320
+extern char ut_buf_int2str[INT2STR_MAX_LEN];
321
+/* returns a pointer to a static buffer containing l in asciiz & sets len */
322
+static inline char* int2str(unsigned long l, int* len)
323
+{
324
+	return int2strbuf(l, ut_buf_int2str, INT2STR_MAX_LEN, len);
325
+}
326
+
315 327
 /* Signed INTeger-TO-STRing: convers a long to a string
316 328
  * returns a pointer to a static buffer containing l in asciiz & sets len */
317 329
 static inline char* sint2str(long l, int* len)