Browse code

acc: Fix reason code for locally generated replies. (#3137)

* acc: Fix reason code for locally generated replies.

- Use heap memory for the reason code instead of the stack memory.
- See issue #2981

* acc: Remove code which was commented out.

- Code was commented out in the previous pull request. (#3137).
- This has now been corrected.

Frits Wiersma authored on 22/06/2022 19:50:44 • GitHub committed on 22/06/2022 19:50:44
Showing 1 changed files
... ...
@@ -93,25 +93,20 @@ void env_set_totag(struct cell *t, struct sip_msg *reply)
93 93
 		tmb.t_get_reply_totag(t->uas.request, &acc_env.to_tag);
94 94
 }
95 95
 
96
-int env_set_reason(struct sip_msg *reply, str *buff) {
97
-	int i;
98
-	char *p;
96
+int env_set_reason(struct sip_msg *reply, str *buff, int code) {
97
+
99 98
 	if (reply!=FAKED_REPLY || !buff || !buff->s || buff->len < 20)
100 99
 		return 0;
101 100
 	if (strncmp(buff->s, "SIP/2.0 ", 8) != 0) {
102 101
 		LM_ERR("not a SIP reply\n");
103 102
 		return 0;
104 103
 	}
105
-	p = buff->s + 12;
106
-	for (i=12;i<buff->len;i++) {
107
-		if (*p == '\r' || *p == '\n') {
108
-			acc_env.reason.s = buff->s+12;
109
-			acc_env.reason.len = i-12;
110
-			LM_DBG("reason[%.*s]\n", acc_env.reason.len, acc_env.reason.s);
111
-			return 1;
112
-		}
113
-		p++;
114
-	}
104
+
105
+	/* Set the reason to a pointer in heap memory. It will contain the last seen FAKED_REPLY */
106
+	acc_env.reason.s = error_text(code);
107
+	acc_env.reason.len = strlen(acc_env.reason.s);
108
+	LM_DBG("reason[%.*s]\n", acc_env.reason.len, acc_env.reason.s);
109
+
115 110
 	return 0;
116 111
 }
117 112
 
... ...
@@ -139,7 +134,8 @@ static inline void env_set_code_status( int code, struct sip_msg *reply)
139 134
 		acc_env.code_s.s =
140 135
 			int2bstr((unsigned long)code, code_buf, &acc_env.code_s.len);
141 136
 		/* reason */
142
-		if (acc_env.reason.len == 0) { /* already extracted in case of locally generated replies */
137
+		/* In case of an ACK the reply == NULL, but the reason must be set when report_ack is 1 */
138
+		if (acc_env.reason.len == 0 || reply==NULL) { /* already extracted in case of locally generated replies */
143 139
 			acc_env.reason.s = error_text(code);
144 140
 			acc_env.reason.len = strlen(acc_env.reason.s);
145 141
 		}
... ...
@@ -719,7 +715,7 @@ static void tmcb_func( struct cell* t, int type, struct tmcb_params *ps )
719 715
 	LM_DBG("acc callback called for t(%p) event type %d, reply code %d\n",
720 716
 			t, type, ps->code);
721 717
 	if (type&TMCB_RESPONSE_OUT) {
722
-		env_set_reason(ps->rpl, &ps->send_buf);
718
+		env_set_reason(ps->rpl, &ps->send_buf, ps->code);
723 719
 		acc_onreply( t, ps->req, ps->rpl, ps->code);
724 720
 	} else if (type&TMCB_E2EACK_IN) {
725 721
 		acc_onack( t, t->uas.request, ps->req, ps->code);
Browse code

acc: use sent reason phrase for locally generated

replies

Julien Chavanton authored on 12/08/2020 21:40:42
Showing 1 changed files
... ...
@@ -93,6 +93,28 @@ void env_set_totag(struct cell *t, struct sip_msg *reply)
93 93
 		tmb.t_get_reply_totag(t->uas.request, &acc_env.to_tag);
94 94
 }
95 95
 
96
+int env_set_reason(struct sip_msg *reply, str *buff) {
97
+	int i;
98
+	char *p;
99
+	if (reply!=FAKED_REPLY || !buff || !buff->s || buff->len < 20)
100
+		return 0;
101
+	if (strncmp(buff->s, "SIP/2.0 ", 8) != 0) {
102
+		LM_ERR("not a SIP reply\n");
103
+		return 0;
104
+	}
105
+	p = buff->s + 12;
106
+	for (i=12;i<buff->len;i++) {
107
+		if (*p == '\r' || *p == '\n') {
108
+			acc_env.reason.s = buff->s+12;
109
+			acc_env.reason.len = i-12;
110
+			LM_DBG("reason[%.*s]\n", acc_env.reason.len, acc_env.reason.s);
111
+			return 1;
112
+		}
113
+		p++;
114
+	}
115
+	return 0;
116
+}
117
+
96 118
 static inline void env_set_to(struct hdr_field *to)
97 119
 {
98 120
 	acc_env.to = to;
... ...
@@ -117,8 +139,10 @@ static inline void env_set_code_status( int code, struct sip_msg *reply)
117 139
 		acc_env.code_s.s =
118 140
 			int2bstr((unsigned long)code, code_buf, &acc_env.code_s.len);
119 141
 		/* reason */
120
-		acc_env.reason.s = error_text(code);
121
-		acc_env.reason.len = strlen(acc_env.reason.s);
142
+		if (acc_env.reason.len == 0) { /* already extracted in case of locally generated replies */
143
+			acc_env.reason.s = error_text(code);
144
+			acc_env.reason.len = strlen(acc_env.reason.s);
145
+		}
122 146
 	} else {
123 147
 		acc_env.code_s = reply->first_line.u.reply.status;
124 148
 		hf = NULL;
... ...
@@ -695,6 +719,7 @@ static void tmcb_func( struct cell* t, int type, struct tmcb_params *ps )
695 719
 	LM_DBG("acc callback called for t(%p) event type %d, reply code %d\n",
696 720
 			t, type, ps->code);
697 721
 	if (type&TMCB_RESPONSE_OUT) {
722
+		env_set_reason(ps->rpl, &ps->send_buf);
698 723
 		acc_onreply( t, ps->req, ps->rpl, ps->code);
699 724
 	} else if (type&TMCB_E2EACK_IN) {
700 725
 		acc_onack( t, t->uas.request, ps->req, ps->code);
Browse code

acc: add to-tag for locally generated replies

Julien Chavanton authored on 28/07/2020 23:22:42
Showing 1 changed files
... ...
@@ -79,8 +79,7 @@ struct acc_enviroment acc_env;
79 79
 static void tmcb_func( struct cell* t, int type, struct tmcb_params *ps );
80 80
 
81 81
 
82
-static inline struct hdr_field* get_rpl_to( struct cell *t,
83
-														struct sip_msg *reply)
82
+static inline struct hdr_field* get_rpl_to( struct cell *t, struct sip_msg *reply)
84 83
 {
85 84
 	if (reply==FAKED_REPLY || !reply || !reply->to)
86 85
 		return t->uas.request->to;
... ...
@@ -88,13 +87,17 @@ static inline struct hdr_field* get_rpl_to( struct cell *t,
88 87
 		return reply->to;
89 88
 }
90 89
 
90
+void env_set_totag(struct cell *t, struct sip_msg *reply)
91
+{
92
+	if (reply==FAKED_REPLY || !reply || !reply->to)
93
+		tmb.t_get_reply_totag(t->uas.request, &acc_env.to_tag);
94
+}
91 95
 
92 96
 static inline void env_set_to(struct hdr_field *to)
93 97
 {
94 98
 	acc_env.to = to;
95 99
 }
96 100
 
97
-
98 101
 static inline void env_set_text(char *p, int len)
99 102
 {
100 103
 	acc_env.text.s = p;
... ...
@@ -493,7 +496,9 @@ static inline void on_missed(struct cell *t, struct sip_msg *req,
493 496
 
494 497
 	/* set env variables */
495 498
 	env_set_to( get_rpl_to(t,reply) );
496
-	env_set_code_status( code, reply);
499
+	env_set_code_status(code, reply);
500
+	/* for missed calls, we make sure to include the totag if it is locally generated */
501
+	env_set_totag(t, reply);
497 502
 
498 503
 	/* we report on missed calls when the first
499 504
 	 * forwarding attempt fails; we do not wish to
... ...
@@ -512,7 +517,6 @@ static inline void on_missed(struct cell *t, struct sip_msg *req,
512 517
 		acc_db_request( req );
513 518
 		flags_to_reset |= 1 << db_missed_flag;
514 519
 	}
515
-
516 520
 	/* run extra acc engines */
517 521
 	acc_run_engines(req, 1, &flags_to_reset);
518 522
 
Browse code

Merge pull request #2107 from lbalaceanu/cdr_json

Adding CDR as JSON functionality

Lucian Balaceanu authored on 18/11/2019 10:13:47 • GitHub committed on 18/11/2019 10:13:47
Showing 0 changed files
Browse code

acc: adding CDR engine functionality

- the engine allows the extension of the acc module
for anyone wanting to add another format (e.g. JSON)
or another backend for CDRs

Lucian Balaceanu authored on 07/11/2019 13:46:13
Showing 1 changed files
... ...
@@ -675,6 +675,16 @@ int acc_api_exec(struct sip_msg *rq, acc_engine_t *eng,
675 675
 	return eng->acc_req(rq, &inf);
676 676
 }
677 677
 
678
+/**
679
+ * @brief execute an acc event via a specific engine
680
+ */
681
+int cdr_api_exec(struct dlg_cell *dlg, struct sip_msg *rq, cdr_engine_t *eng, acc_param_t* comment)
682
+{
683
+	cdr_info_t inf;
684
+	memset(&inf, 0, sizeof(cdr_info_t));
685
+	cdr_api_set_arrays(&inf);
686
+	return eng->cdr_write(dlg, rq, &inf);
687
+}
678 688
 
679 689
 static void tmcb_func( struct cell* t, int type, struct tmcb_params *ps )
680 690
 {
Browse code

acc: better evaluation of error return for pv_printf_s()

Daniel-Constantin Mierla authored on 30/10/2019 17:27:40
Showing 1 changed files
... ...
@@ -178,7 +178,7 @@ int acc_parse_code(char *p, struct acc_param *param)
178 178
 int acc_get_param_value(struct sip_msg *rq, struct acc_param *param)
179 179
 {
180 180
 	if(param->elem!=NULL) {
181
-		if(pv_printf_s(rq, param->elem, &param->reason)==-1) {
181
+		if(pv_printf_s(rq, param->elem, &param->reason)<0) {
182 182
 			LM_ERR("Can't get value for %.*s\n", param->reason.len, param->reason.s);
183 183
 			return -1;
184 184
 		}
Browse code

acc: fix generating duplicates for missed calls

- fix generating duplicates for missed calls (#GH1674)
- patch from Julien Chavanton jchavanton at gmail dot com

Henning Westerholt authored on 01/11/2018 20:21:28
Showing 1 changed files
... ...
@@ -55,7 +55,6 @@ struct acc_enviroment acc_env;
55 55
 
56 56
 
57 57
 #define is_acc_flag_set(_rq,_flag)  (((_flag) != -1) && (isflagset((_rq), (_flag)) == 1))
58
-#define reset_acc_flag(_rq,_flag)   (resetflag((_rq), (_flag)))
59 58
 
60 59
 #define is_failed_acc_on(_rq)  is_acc_flag_set(_rq,failed_transaction_flag)
61 60
 
... ...
@@ -465,7 +464,6 @@ static inline void acc_onreply_in(struct cell *t, struct sip_msg *req,
465 464
 }
466 465
 
467 466
 
468
-
469 467
 /* initiate a report if we previously enabled MC accounting for this t */
470 468
 static inline void on_missed(struct cell *t, struct sip_msg *req,
471 469
 											struct sip_msg *reply, int code)
... ...
@@ -501,11 +499,10 @@ static inline void on_missed(struct cell *t, struct sip_msg *req,
501 499
 	 * forwarding attempt fails; we do not wish to
502 500
 	 * report on every attempt; so we clear the flags;
503 501
 	 */
504
-
505 502
 	if (is_log_mc_on(req)) {
506 503
 		env_set_text( ACC_MISSED, ACC_MISSED_LEN);
507 504
 		acc_log_request( req );
508
-		flags_to_reset |= log_missed_flag;
505
+		flags_to_reset |= 1 << log_missed_flag;
509 506
 	}
510 507
 	if (is_db_mc_on(req)) {
511 508
 		if(acc_db_set_table_name(req, db_table_mc_data, &db_table_mc)<0) {
... ...
@@ -513,7 +510,7 @@ static inline void on_missed(struct cell *t, struct sip_msg *req,
513 510
 			return;
514 511
 		}
515 512
 		acc_db_request( req );
516
-		flags_to_reset |= db_missed_flag;
513
+		flags_to_reset |= 1 << db_missed_flag;
517 514
 	}
518 515
 
519 516
 	/* run extra acc engines */
... ...
@@ -523,7 +520,7 @@ static inline void on_missed(struct cell *t, struct sip_msg *req,
523 520
 	 * These can't be reset in the blocks above, because
524 521
 	 * it would skip accounting if the flags are identical
525 522
 	 */
526
-	reset_acc_flag( req, flags_to_reset );
523
+	resetflags(req, flags_to_reset);
527 524
 
528 525
 	if (new_uri_bk.len>=0) {
529 526
 		req->new_uri = new_uri_bk;
Browse code

acc: more debug message when checking if acc should be done

Daniel-Constantin Mierla authored on 10/09/2018 07:18:27
Showing 1 changed files
... ...
@@ -411,27 +411,40 @@ static inline int should_acc_reply(struct sip_msg *req, struct sip_msg *rpl,
411 411
 {
412 412
 	unsigned int i;
413 413
 
414
+	LM_DBG("probing acc state - code: %d flags: 0x%x\n", code,
415
+			(req)?req->flags:0);
414 416
 	/* negative transactions reported otherwise only if explicitly
415 417
 	 * demanded */
416
-
417 418
 	if (code >= 300) {
418
-		if (!is_failed_acc_on(req)) return 0;
419
+		if (!is_failed_acc_on(req)) {
420
+			LM_DBG("failed acc is off\n");
421
+			return 0;
422
+		}
419 423
 		i = 0;
420 424
 		while (failed_filter[i] != 0) {
421
-			if (failed_filter[i] == code) return 0;
425
+			if (failed_filter[i] == code) {
426
+				LM_DBG("acc code in filter: %d\n", code);
427
+				return 0;
428
+			}
422 429
 			i++;
423 430
 		}
431
+		LM_DBG("failed acc is on\n");
424 432
 		return 1;
425 433
 	}
426 434
 
427
-	if ( !is_acc_on(req) )
435
+	if ( !is_acc_on(req) ) {
436
+		LM_DBG("acc is off\n");
428 437
 		return 0;
438
+	}
429 439
 
430 440
 	if ( code<200 && !(early_media &&
431 441
 				parse_headers(rpl,HDR_CONTENTLENGTH_F, 0) == 0 &&
432
-				rpl->content_length && get_content_length(rpl) > 0))
442
+				rpl->content_length && get_content_length(rpl) > 0)) {
443
+		LM_DBG("early media acc is off\n");
433 444
 		return 0;
445
+	}
434 446
 
447
+	LM_DBG("acc is on\n");
435 448
 	return 1; /* seed is through, we will account this reply */
436 449
 }
437 450
 
... ...
@@ -461,6 +474,7 @@ static inline void on_missed(struct cell *t, struct sip_msg *req,
461 474
 	int flags_to_reset = 0;
462 475
 	int br = -1;
463 476
 
477
+	LM_DBG("preparing to report the record\n");
464 478
 	/* get winning branch index, if set */
465 479
 	if (t->relayed_reply_branch>=0) {
466 480
 		br = t->relayed_reply_branch;
Browse code

acc: allow accounting only for external accounting engine

- have accounting via external engines without a need to have log flag set

Daniel-Constantin Mierla authored on 31/10/2017 11:31:26
Showing 1 changed files
... ...
@@ -66,10 +66,10 @@ struct acc_enviroment acc_env;
66 66
 #define is_db_mc_on(_rq)      is_acc_flag_set(_rq,db_missed_flag)
67 67
 
68 68
 #define is_acc_on(_rq) \
69
-	( (is_log_acc_on(_rq)) || (is_db_acc_on(_rq)) )
69
+	( (is_log_acc_on(_rq)) || (is_db_acc_on(_rq)) || (is_eng_acc_on(_rq)) )
70 70
 
71 71
 #define is_mc_on(_rq) \
72
-	( (is_log_mc_on(_rq)) || (is_db_mc_on(_rq)) )
72
+	( (is_log_mc_on(_rq)) || (is_db_mc_on(_rq)) || (is_eng_mc_on(_rq)) )
73 73
 
74 74
 #define skip_cancel(_rq) \
75 75
 	(((_rq)->REQ_METHOD==METHOD_CANCEL) && report_cancels==0)
Browse code

acc: relocated the code related to diameter accounting to acc_diameter

Daniel-Constantin Mierla authored on 09/08/2017 13:28:25
Showing 1 changed files
... ...
@@ -65,21 +65,11 @@ struct acc_enviroment acc_env;
65 65
 #define is_db_acc_on(_rq)     is_acc_flag_set(_rq,db_flag)
66 66
 #define is_db_mc_on(_rq)      is_acc_flag_set(_rq,db_missed_flag)
67 67
 
68
-#ifdef DIAM_ACC
69
-	#define is_diam_acc_on(_rq)     is_acc_flag_set(_rq,diameter_flag)
70
-	#define is_diam_mc_on(_rq)      is_acc_flag_set(_rq,diameter_missed_flag)
71
-#else
72
-	#define is_diam_acc_on(_rq)     (0)
73
-	#define is_diam_mc_on(_rq)      (0)
74
-#endif
75
-
76 68
 #define is_acc_on(_rq) \
77
-	( (is_log_acc_on(_rq)) || (is_db_acc_on(_rq)) \
78
-	|| (is_diam_acc_on(_rq)) )
69
+	( (is_log_acc_on(_rq)) || (is_db_acc_on(_rq)) )
79 70
 
80 71
 #define is_mc_on(_rq) \
81
-	( (is_log_mc_on(_rq)) || (is_db_mc_on(_rq)) \
82
-	|| (is_diam_mc_on(_rq)) )
72
+	( (is_log_mc_on(_rq)) || (is_db_mc_on(_rq)) )
83 73
 
84 74
 #define skip_cancel(_rq) \
85 75
 	(((_rq)->REQ_METHOD==METHOD_CANCEL) && report_cancels==0)
... ...
@@ -377,22 +367,6 @@ int w_acc_request(sip_msg_t *rq, char *comment, char *table)
377 367
 }
378 368
 
379 369
 
380
-#ifdef DIAM_ACC
381
-int w_acc_diam_request(struct sip_msg *rq, char *comment, char *foo)
382
-{
383
-	struct acc_param *param = (struct acc_param*)comment;
384
-	if (acc_preparse_req(rq)<0)
385
-		return -1;
386
-	if(acc_get_param_value(rq, param)<0)
387
-		return -1;
388
-	env_set_to( rq->to );
389
-	env_set_comment(param);
390
-	return acc_diam_request(rq);
391
-}
392
-#endif
393
-
394
-
395
-
396 370
 /* prepare message and transaction context for later accounting */
397 371
 void acc_onreq( struct cell* t, int type, struct tmcb_params *ps )
398 372
 {
... ...
@@ -528,14 +502,6 @@ static inline void on_missed(struct cell *t, struct sip_msg *req,
528 502
 		flags_to_reset |= db_missed_flag;
529 503
 	}
530 504
 
531
-/* DIAMETER */
532
-#ifdef DIAM_ACC
533
-	if (is_diam_mc_on(req)) {
534
-		acc_diam_request( req );
535
-		flags_to_reset |= diameter_missed_flag;
536
-	}
537
-#endif
538
-
539 505
 	/* run extra acc engines */
540 506
 	acc_run_engines(req, 1, &flags_to_reset);
541 507
 
... ...
@@ -628,12 +594,6 @@ static void acc_onreply(tm_cell_t *t, sip_msg_t *req, sip_msg_t *reply, int code
628 594
 		}
629 595
 	}
630 596
 
631
-/* DIAMETER */
632
-#ifdef DIAM_ACC
633
-	if (is_diam_acc_on(preq))
634
-		acc_diam_request(preq);
635
-#endif
636
-
637 597
 	/* run extra acc engines */
638 598
 	acc_run_engines(preq, 0, NULL);
639 599
 
... ...
@@ -682,13 +642,6 @@ static inline void acc_onack( struct cell* t, struct sip_msg *req,
682 642
 		acc_db_request( ack );
683 643
 	}
684 644
 
685
-/* DIAMETER */
686
-#ifdef DIAM_ACC
687
-	if (is_diam_acc_on(req)) {
688
-		acc_diam_request(ack);
689
-	}
690
-#endif
691
-
692 645
 	/* run extra acc engines */
693 646
 	acc_run_engines(ack, 0, NULL);
694 647
 }
Browse code

acc: removed define for SQL_ACC

- it was enabled for more than 10 years and the module links to
lib/srdb1 anyhow

Daniel-Constantin Mierla authored on 09/08/2017 11:37:20
Showing 1 changed files
... ...
@@ -62,14 +62,8 @@ struct acc_enviroment acc_env;
62 62
 #define is_log_acc_on(_rq)     is_acc_flag_set(_rq,log_flag)
63 63
 #define is_log_mc_on(_rq)      is_acc_flag_set(_rq,log_missed_flag)
64 64
 
65
-#ifdef SQL_ACC
66
-	#define is_db_acc_on(_rq)     is_acc_flag_set(_rq,db_flag)
67
-	#define is_db_mc_on(_rq)      is_acc_flag_set(_rq,db_missed_flag)
68
-#else
69
-	#define is_db_acc_on(_rq)     (0)
70
-	#define is_db_mc_on(_rq)      (0)
71
-#endif
72
-
65
+#define is_db_acc_on(_rq)     is_acc_flag_set(_rq,db_flag)
66
+#define is_db_mc_on(_rq)      is_acc_flag_set(_rq,db_missed_flag)
73 67
 
74 68
 #ifdef DIAM_ACC
75 69
 	#define is_diam_acc_on(_rq)     is_acc_flag_set(_rq,diameter_flag)
... ...
@@ -262,7 +256,6 @@ int ki_acc_log_request(sip_msg_t *rq, str *comment)
262 256
 }
263 257
 
264 258
 
265
-#ifdef SQL_ACC
266 259
 int acc_db_set_table_name(struct sip_msg *msg, void *param, str *table)
267 260
 {
268 261
 #define DB_TABLE_NAME_SIZE	64
... ...
@@ -331,7 +324,6 @@ int ki_acc_db_request(sip_msg_t *rq, str *comment, str *dbtable)
331 324
 	env_set_comment(&accp);
332 325
 	return acc_db_request(rq);
333 326
 }
334
-#endif
335 327
 
336 328
 int ki_acc_request(sip_msg_t *rq, str *comment, str *dbtable)
337 329
 {
... ...
@@ -345,12 +337,10 @@ int ki_acc_request(sip_msg_t *rq, str *comment, str *dbtable)
345 337
 	if (acc_preparse_req(rq)<0)
346 338
 		return -1;
347 339
 
348
-#ifdef SQL_ACC
349 340
 	if(acc_db_set_table_name(rq, NULL, dbtable)<0) {
350 341
 		LM_ERR("cannot set table name\n");
351 342
 		return -1;
352 343
 	}
353
-#endif
354 344
 
355 345
 	env_set_to(rq->to);
356 346
 	env_set_comment(&accp);
... ...
@@ -359,14 +349,12 @@ int ki_acc_request(sip_msg_t *rq, str *comment, str *dbtable)
359 349
 	if(ret<0) {
360 350
 		LM_ERR("acc log request failed\n");
361 351
 	}
362
-#ifdef SQL_ACC
363 352
 	if(acc_is_db_ready()) {
364 353
 		ret = acc_db_request(rq);
365 354
 		if(ret<0) {
366 355
 			LM_ERR("acc db request failed\n");
367 356
 		}
368 357
 	}
369
-#endif
370 358
 
371 359
 	return ret;
372 360
 }
... ...
@@ -531,7 +519,6 @@ static inline void on_missed(struct cell *t, struct sip_msg *req,
531 519
 		acc_log_request( req );
532 520
 		flags_to_reset |= log_missed_flag;
533 521
 	}
534
-#ifdef SQL_ACC
535 522
 	if (is_db_mc_on(req)) {
536 523
 		if(acc_db_set_table_name(req, db_table_mc_data, &db_table_mc)<0) {
537 524
 			LM_ERR("cannot set missed call db table name\n");
... ...
@@ -540,7 +527,6 @@ static inline void on_missed(struct cell *t, struct sip_msg *req,
540 527
 		acc_db_request( req );
541 528
 		flags_to_reset |= db_missed_flag;
542 529
 	}
543
-#endif
544 530
 
545 531
 /* DIAMETER */
546 532
 #ifdef DIAM_ACC
... ...
@@ -634,7 +620,6 @@ static void acc_onreply(tm_cell_t *t, sip_msg_t *req, sip_msg_t *reply, int code
634 620
 		env_set_text( ACC_ANSWERED, ACC_ANSWERED_LEN);
635 621
 		acc_log_request(preq);
636 622
 	}
637
-#ifdef SQL_ACC
638 623
 	if (is_db_acc_on(preq)) {
639 624
 		if(acc_db_set_table_name(preq, db_table_acc_data, &db_table_acc)<0) {
640 625
 			LM_ERR("cannot set acc db table name\n");
... ...
@@ -642,7 +627,6 @@ static void acc_onreply(tm_cell_t *t, sip_msg_t *req, sip_msg_t *reply, int code
642 627
 			acc_db_request(preq);
643 628
 		}
644 629
 	}
645
-#endif
646 630
 
647 631
 /* DIAMETER */
648 632
 #ifdef DIAM_ACC
... ...
@@ -690,7 +674,6 @@ static inline void acc_onack( struct cell* t, struct sip_msg *req,
690 674
 		env_set_text( ACC_ACKED, ACC_ACKED_LEN);
691 675
 		acc_log_request( ack );
692 676
 	}
693
-#ifdef SQL_ACC
694 677
 	if (is_db_acc_on(req)) {
695 678
 		if(acc_db_set_table_name(ack, db_table_acc_data, &db_table_acc)<0) {
696 679
 			LM_ERR("cannot set acc db table name\n");
... ...
@@ -698,7 +681,6 @@ static inline void acc_onack( struct cell* t, struct sip_msg *req,
698 681
 		}
699 682
 		acc_db_request( ack );
700 683
 	}
701
-#endif
702 684
 
703 685
 /* DIAMETER */
704 686
 #ifdef DIAM_ACC
Browse code

acc: added acc_request(reason, table)

- wrapper around acc_log_request() and acc_db_request(), writting acc
record to log and db backend (if db_url is set)

Daniel-Constantin Mierla authored on 09/08/2017 06:59:00
Showing 1 changed files
... ...
@@ -41,6 +41,7 @@
41 41
 #include "../../modules/tm/tm_load.h"
42 42
 #include "../rr/api.h"
43 43
 #include "../../core/flags.h"
44
+#include "../../core/mod_fix.h"
44 45
 #include "../../core/kemi.h"
45 46
 #include "acc.h"
46 47
 #include "acc_api.h"
... ...
@@ -135,7 +136,7 @@ static inline void env_set_code_status( int code, struct sip_msg *reply)
135 136
 	} else {
136 137
 		acc_env.code_s = reply->first_line.u.reply.status;
137 138
 		hf = NULL;
138
-	        if (reason_from_hf) {
139
+		if (reason_from_hf) {
139 140
 			/* TODO: take reason from all Reason headers */
140 141
 			if(parse_headers(reply, HDR_EOH_F, 0) < 0) {
141 142
 				LM_ERR("error parsing headers\n");
... ...
@@ -260,6 +261,7 @@ int ki_acc_log_request(sip_msg_t *rq, str *comment)
260 261
 	return acc_log_request(rq);
261 262
 }
262 263
 
264
+
263 265
 #ifdef SQL_ACC
264 266
 int acc_db_set_table_name(struct sip_msg *msg, void *param, str *table)
265 267
 {
... ...
@@ -331,6 +333,62 @@ int ki_acc_db_request(sip_msg_t *rq, str *comment, str *dbtable)
331 333
 }
332 334
 #endif
333 335
 
336
+int ki_acc_request(sip_msg_t *rq, str *comment, str *dbtable)
337
+{
338
+	acc_param_t accp;
339
+	int ret;
340
+
341
+	if(acc_param_parse(comment, &accp)<0) {
342
+		LM_ERR("failed execution\n");
343
+		return -1;
344
+	}
345
+	if (acc_preparse_req(rq)<0)
346
+		return -1;
347
+
348
+#ifdef SQL_ACC
349
+	if(acc_db_set_table_name(rq, NULL, dbtable)<0) {
350
+		LM_ERR("cannot set table name\n");
351
+		return -1;
352
+	}
353
+#endif
354
+
355
+	env_set_to(rq->to);
356
+	env_set_comment(&accp);
357
+	env_set_text(ACC_REQUEST, ACC_REQUEST_LEN);
358
+	ret = acc_log_request(rq);
359
+	if(ret<0) {
360
+		LM_ERR("acc log request failed\n");
361
+	}
362
+#ifdef SQL_ACC
363
+	if(acc_is_db_ready()) {
364
+		ret = acc_db_request(rq);
365
+		if(ret<0) {
366
+			LM_ERR("acc db request failed\n");
367
+		}
368
+	}
369
+#endif
370
+
371
+	return ret;
372
+}
373
+
374
+int w_acc_request(sip_msg_t *rq, char *comment, char *table)
375
+{
376
+	str scomment;
377
+	str stable;
378
+
379
+	if(fixup_get_svalue(rq, (gparam_t *)comment, &scomment)<0) {
380
+		LM_ERR("failed to get comment parameter\n");
381
+		return -1;
382
+	}
383
+	if(fixup_get_svalue(rq, (gparam_t *)table, &stable)<0) {
384
+		LM_ERR("failed to get table parameter\n");
385
+		return -1;
386
+	}
387
+
388
+	return ki_acc_request(rq, &scomment, &stable);
389
+}
390
+
391
+
334 392
 #ifdef DIAM_ACC
335 393
 int w_acc_diam_request(struct sip_msg *rq, char *comment, char *foo)
336 394
 {
... ...
@@ -387,32 +445,32 @@ void acc_onreq( struct cell* t, int type, struct tmcb_params *ps )
387 445
 
388 446
 /* is this reply of interest for accounting ? */
389 447
 static inline int should_acc_reply(struct sip_msg *req, struct sip_msg *rpl,
390
-				   int code)
448
+			int code)
391 449
 {
392
-    unsigned int i;
450
+	unsigned int i;
393 451
 
394 452
 	/* negative transactions reported otherwise only if explicitly
395 453
 	 * demanded */
396 454
 
397
-    if (code >= 300) {
455
+	if (code >= 300) {
398 456
 		if (!is_failed_acc_on(req)) return 0;
399 457
 		i = 0;
400 458
 		while (failed_filter[i] != 0) {
401
-		    if (failed_filter[i] == code) return 0;
402
-		    i++;
459
+			if (failed_filter[i] == code) return 0;
460
+			i++;
403 461
 		}
404 462
 		return 1;
405
-    }
463
+	}
406 464
 
407
-    if ( !is_acc_on(req) )
465
+	if ( !is_acc_on(req) )
408 466
 		return 0;
409 467
 
410
-    if ( code<200 && !(early_media &&
411
-		       parse_headers(rpl,HDR_CONTENTLENGTH_F, 0) == 0 &&
412
-		       rpl->content_length && get_content_length(rpl) > 0))
468
+	if ( code<200 && !(early_media &&
469
+				parse_headers(rpl,HDR_CONTENTLENGTH_F, 0) == 0 &&
470
+				rpl->content_length && get_content_length(rpl) > 0))
413 471
 		return 0;
414 472
 
415
-    return 1; /* seed is through, we will account this reply */
473
+	return 1; /* seed is through, we will account this reply */
416 474
 }
417 475
 
418 476
 
... ...
@@ -524,8 +582,8 @@ static void acc_onreply(tm_cell_t *t, sip_msg_t *req, sip_msg_t *reply, int code
524 582
 	void *mend;
525 583
 
526 584
 	/* acc_onreply is bound to TMCB_REPLY which may be called
527
-	   from _reply, like when FR hits; we should not miss this
528
-	   event for missed calls either */
585
+	 * from _reply, like when FR hits; we should not miss this
586
+	 * event for missed calls either */
529 587
 	if (is_invite(t) && code>=300 && is_mc_on(req) )
530 588
 		on_missed(t, req, reply, code);
531 589
 
... ...
@@ -651,7 +709,6 @@ static inline void acc_onack( struct cell* t, struct sip_msg *req,
651 709
 
652 710
 	/* run extra acc engines */
653 711
 	acc_run_engines(ack, 0, NULL);
654
-	
655 712
 }
656 713
 
657 714
 
Browse code

acc: free parameter in acc fixup in case of error

Daniel-Constantin Mierla authored on 08/07/2017 07:35:13
Showing 1 changed files
... ...
@@ -391,26 +391,26 @@ static inline int should_acc_reply(struct sip_msg *req, struct sip_msg *rpl,
391 391
 {
392 392
     unsigned int i;
393 393
 
394
-	/* negative transactions reported otherwise only if explicitly 
394
+	/* negative transactions reported otherwise only if explicitly
395 395
 	 * demanded */
396 396
 
397 397
     if (code >= 300) {
398
-	if (!is_failed_acc_on(req)) return 0;
399
-	i = 0;
400
-	while (failed_filter[i] != 0) {
401
-	    if (failed_filter[i] == code) return 0;
402
-	    i++;
403
-	}
404
-	return 1;
398
+		if (!is_failed_acc_on(req)) return 0;
399
+		i = 0;
400
+		while (failed_filter[i] != 0) {
401
+		    if (failed_filter[i] == code) return 0;
402
+		    i++;
403
+		}
404
+		return 1;
405 405
     }
406 406
 
407 407
     if ( !is_acc_on(req) )
408
-	return 0;
409
-	
408
+		return 0;
409
+
410 410
     if ( code<200 && !(early_media &&
411 411
 		       parse_headers(rpl,HDR_CONTENTLENGTH_F, 0) == 0 &&
412 412
 		       rpl->content_length && get_content_length(rpl) > 0))
413
-	return 0;
413
+		return 0;
414 414
 
415 415
     return 1; /* seed is through, we will account this reply */
416 416
 }
... ...
@@ -424,8 +424,10 @@ static inline void acc_onreply_in(struct cell *t, struct sip_msg *req,
424 424
 	/* don't parse replies in which we are not interested */
425 425
 	/* missed calls enabled ? */
426 426
 	if ( (reply && reply!=FAKED_REPLY) && (should_acc_reply(req,reply,code)
427
-	|| (is_invite(t) && code>=300 && is_mc_on(req))) ) {
428
-		parse_headers(reply, HDR_TO_F, 0 );
427
+			|| (is_invite(t) && code>=300 && is_mc_on(req))) ) {
428
+		if(parse_headers(reply, HDR_TO_F, 0)<0) {
429
+			LM_ERR("failed to parse headers\n");
430
+		}
429 431
 	}
430 432
 }
431 433
 
... ...
@@ -463,7 +465,7 @@ static inline void on_missed(struct cell *t, struct sip_msg *req,
463 465
 
464 466
 	/* we report on missed calls when the first
465 467
 	 * forwarding attempt fails; we do not wish to
466
-	 * report on every attempt; so we clear the flags; 
468
+	 * report on every attempt; so we clear the flags;
467 469
 	 */
468 470
 
469 471
 	if (is_log_mc_on(req)) {
... ...
@@ -684,4 +686,4 @@ static void tmcb_func( struct cell* t, int type, struct tmcb_params *ps )
684 686
 	} else if (type&TMCB_RESPONSE_IN) {
685 687
 		acc_onreply_in( t, ps->req, ps->rpl, ps->code);
686 688
 	}
687
-}
688 689
\ No newline at end of file
690
+}
Browse code

acc: exported functions to kemi framework

Daniel-Constantin Mierla authored on 24/04/2017 13:37:58
Showing 1 changed files
... ...
@@ -41,6 +41,7 @@
41 41
 #include "../../modules/tm/tm_load.h"
42 42
 #include "../rr/api.h"
43 43
 #include "../../core/flags.h"
44
+#include "../../core/kemi.h"
44 45
 #include "acc.h"
45 46
 #include "acc_api.h"
46 47
 #include "acc_mod.h"
... ...
@@ -219,6 +220,45 @@ int w_acc_log_request(struct sip_msg *rq, char *comment, char *foo)
219 220
 	return acc_log_request(rq);
220 221
 }
221 222
 
223
+static int acc_param_parse(str *s, acc_param_t *accp)
224
+{
225
+	if(s==NULL || s->s==NULL || s->len<=0 || accp==NULL) {
226
+		LM_ERR("invalid parameters\n");
227
+		return -1;
228
+	}
229
+	memset(accp, 0, sizeof(acc_param_t));
230
+	accp->reason.s = s->s;
231
+	accp->reason.len = s->len;
232
+	if (strchr(s->s, PV_MARKER)!=NULL) {
233
+		/* there is a cfg variable - not through kemi */
234
+		LM_ERR("cfg variable detected - not supported\n");
235
+		return -1;
236
+	} else {
237
+		if(acc_parse_code(s->s, accp)<0) {
238
+			LM_ERR("failed to parse: [%.*s] (expected [code text])\n",
239
+					s->len, s->s);
240
+			return -1;
241
+		}
242
+	}
243
+	return 0;
244
+}
245
+
246
+int ki_acc_log_request(sip_msg_t *rq, str *comment)
247
+{
248
+	acc_param_t accp;
249
+
250
+	if(acc_param_parse(comment, &accp)<0) {
251
+		LM_ERR("failed execution\n");
252
+		return -1;
253
+	}
254
+	if (acc_preparse_req(rq)<0)
255
+		return -1;
256
+
257
+	env_set_to(rq->to);
258
+	env_set_comment(&accp);
259
+	env_set_text(ACC_REQUEST, ACC_REQUEST_LEN);
260
+	return acc_log_request(rq);
261
+}
222 262
 
223 263
 #ifdef SQL_ACC
224 264
 int acc_db_set_table_name(struct sip_msg *msg, void *param, str *table)
... ...
@@ -270,6 +310,25 @@ int w_acc_db_request(struct sip_msg *rq, char *comment, char *table)
270 310
 	env_set_comment(param);
271 311
 	return acc_db_request(rq);
272 312
 }
313
+
314
+int ki_acc_db_request(sip_msg_t *rq, str *comment, str *dbtable)
315
+{
316
+	acc_param_t accp;
317
+
318
+	if(acc_param_parse(comment, &accp)<0) {
319
+		LM_ERR("failed execution\n");
320
+		return -1;
321
+	}
322
+	if (acc_preparse_req(rq)<0)
323
+		return -1;
324
+	if(acc_db_set_table_name(rq, NULL, dbtable)<0) {
325
+		LM_ERR("cannot set table name\n");
326
+		return -1;
327
+	}
328
+	env_set_to(rq->to);
329
+	env_set_comment(&accp);
330
+	return acc_db_request(rq);
331
+}
273 332
 #endif
274 333
 
275 334
 #ifdef DIAM_ACC
... ...
@@ -625,5 +684,4 @@ static void tmcb_func( struct cell* t, int type, struct tmcb_params *ps )
625 684
 	} else if (type&TMCB_RESPONSE_IN) {
626 685
 		acc_onreply_in( t, ps->req, ps->rpl, ps->code);
627 686
 	}
628
-}
629
-
687
+}
630 688
\ No newline at end of file
Browse code

acc: deep cloning of the request for acc onreply event

- parsing additional headers were linked in tm request and could have
been accessed by other processes, resulting in a segfault
- reported by Joshua Colp

Daniel-Constantin Mierla authored on 16/01/2017 14:17:22
Showing 1 changed files
... ...
@@ -37,6 +37,7 @@
37 37
 #include "../../core/parser/parse_from.h"
38 38
 #include "../../core/parser/parse_content.h"
39 39
 #include "../../core/strutils.h"
40
+#include "../../core/sip_msg_clone.h"
40 41
 #include "../../modules/tm/tm_load.h"
41 42
 #include "../rr/api.h"
42 43
 #include "../../core/flags.h"
... ...
@@ -450,14 +451,16 @@ static inline void on_missed(struct cell *t, struct sip_msg *req,
450 451
 extern int _acc_clone_msg;
451 452
 
452 453
 /* initiate a report if we previously enabled accounting for this t */
453
-static inline void acc_onreply( struct cell* t, struct sip_msg *req,
454
-											struct sip_msg *reply, int code)
454
+static void acc_onreply(tm_cell_t *t, sip_msg_t *req, sip_msg_t *reply, int code)
455 455
 {
456 456
 	str new_uri_bk;
457 457
 	int br = -1;
458 458
 	hdr_field_t *hdr;
459
-	sip_msg_t tmsg;
460
-	sip_msg_t *preq;
459
+	sip_msg_t *cmsg = 0;
460
+	int cmsg_len = 0;
461
+	sip_msg_t *preq = 0;
462
+	void *mstart;
463
+	void *mend;
461 464
 
462 465
 	/* acc_onreply is bound to TMCB_REPLY which may be called
463 466
 	   from _reply, like when FR hits; we should not miss this
... ...
@@ -469,9 +472,20 @@ static inline void acc_onreply( struct cell* t, struct sip_msg *req,
469 472
 		return;
470 473
 
471 474
 	if(_acc_clone_msg==1) {
472
-		memcpy(&tmsg, req, sizeof(sip_msg_t));
473
-		preq = &tmsg;
475
+		/* make a clone so eventual new parsed headers in pkg are not visible
476
+		 * to other processes -- other attributes should be already parsed,
477
+		 * available in the req structure and propagated by cloning */
478
+		cmsg = sip_msg_shm_clone(req, &cmsg_len, 1);
479
+		if(cmsg==NULL) {
480
+			LM_ERR("failed to clone the request - acc aborted\n");
481
+			return;
482
+		}
483
+		mstart = cmsg;
484
+		mend = ((char*)cmsg) + cmsg_len;
485
+		preq = cmsg;
474 486
 	} else {
487
+		mstart = t->uas.request;
488
+		mend = t->uas.end_request;
475 489
 		preq = req;
476 490
 	}
477 491
 
... ...
@@ -521,22 +535,24 @@ static inline void acc_onreply( struct cell* t, struct sip_msg *req,
521 535
 	acc_run_engines(preq, 0, NULL);
522 536
 
523 537
 	if (new_uri_bk.len>=0) {
524
-		req->new_uri = new_uri_bk;
525
-		req->parsed_uri_ok = 0;
538
+		preq->new_uri = new_uri_bk;
539
+		preq->parsed_uri_ok = 0;
526 540
 	}
527 541
 
528 542
 	/* free header's parsed structures that were added by resolving acc attributes */
529
-	for( hdr=req->headers ; hdr ; hdr=hdr->next ) {
530
-		if ( hdr->parsed && hdr_allocs_parse(hdr) &&
531
-					(hdr->parsed<(void*)t->uas.request ||
532
-					hdr->parsed>=(void*)t->uas.end_request)) {
533
-			/* header parsed filed doesn't point inside uas.request memory
543
+	for( hdr=preq->headers ; hdr ; hdr=hdr->next ) {
544
+		if (hdr->parsed && hdr_allocs_parse(hdr) &&
545
+					(hdr->parsed<mstart || hdr->parsed>=mend)) {
546
+			/* header parsed filed doesn't point inside cloned request memory
534 547
 			 * chunck -> it was added by resolving acc attributes -> free it as pkg */
535 548
 			DBG("removing hdr->parsed %d\n", hdr->type);
536 549
 			clean_hdr_field(hdr);
537 550
 			hdr->parsed = 0;
538 551
 		}
539 552
 	}
553
+	if(cmsg!=NULL) {
554
+		shm_free(cmsg);
555
+	}
540 556
 }
541 557
 
542 558
 
Browse code

acc Remove radius support code (now in separate module - acc_radius.so)

Olle E. Johansson authored on 02/01/2017 20:07:38
Showing 1 changed files
... ...
@@ -67,14 +67,6 @@ struct acc_enviroment acc_env;
67 67
 	#define is_db_mc_on(_rq)      (0)
68 68
 #endif
69 69
 
70
-#ifdef RAD_ACC
71
-	#define is_rad_acc_on(_rq)     is_acc_flag_set(_rq,radius_flag)
72
-	#define is_rad_mc_on(_rq)      is_acc_flag_set(_rq,radius_missed_flag)
73
-#else
74
-	#define is_rad_acc_on(_rq)     (0)
75
-	#define is_rad_mc_on(_rq)      (0)
76
-#endif
77
-
78 70
 
79 71
 #ifdef DIAM_ACC
80 72
 	#define is_diam_acc_on(_rq)     is_acc_flag_set(_rq,diameter_flag)
... ...
@@ -86,11 +78,11 @@ struct acc_enviroment acc_env;
86 78
 
87 79
 #define is_acc_on(_rq) \
88 80
 	( (is_log_acc_on(_rq)) || (is_db_acc_on(_rq)) \
89
-	|| (is_rad_acc_on(_rq)) || (is_diam_acc_on(_rq)) )
81
+	|| (is_diam_acc_on(_rq)) )
90 82
 
91 83
 #define is_mc_on(_rq) \
92 84
 	( (is_log_mc_on(_rq)) || (is_db_mc_on(_rq)) \
93
-	|| (is_rad_mc_on(_rq)) || (is_diam_mc_on(_rq)) )
85
+	|| (is_diam_mc_on(_rq)) )
94 86
 
95 87
 #define skip_cancel(_rq) \
96