[Devel] Inaccurate Radius Accounting
Klaus Darilion
klaus.mailinglists at pernau.at
Wed Jan 4 10:06:29 CET 2006
I'm on it - just testing at the moment.
regards
klaus
Lenir wrote:
> Can you guys implement this patch (written by Jan Janak) for acc radius to
> CVS?
> It's been implemented to SER CVS.
>
> Thanks,
>
> Lenir
>
> -----Original Message-----
> From: 'Jan Janak' [mailto:jan at iptel.org]
> Sent: Sunday, December 25, 2005 12:56 PM
> To: Lenir
> Cc: 'Klaus Darilion'; serdev at iptel.org; serusers at iptel.org;
> devel at openser.org; users at openser.org
> Subject: Re: [Users] RE: [Serusers] Re: [Serdev] Inaccurate Radius
> Accounting
>
> Hello,
>
> Attached is a patch that implements "swap_direction" parameter of acc
> module. If you turn the parameter on in the configuration file:
>
> modparam("acc", "swap_direction", 1)
>
> then the acc module will swap Calling-Station-ID and Called-Station-ID
> values when necessary (in this case BYE comming from the callee).
>
> Put the patch in top level source directory (ser-0.9.x) and type:
> patch -p0 < swap.patch
>
> The patch should work with any 0.9.x release.
>
> Note that Alan DeKok is wrong in thinking that this is a bug in SER.
> This particular problem is a result of incomplete specification of
> RADIUS use with SIP. I will commit the patch in CVS so it will be
> included in future SER releases.
>
> Jan.
>
> On 23-12-2005 17:10, Lenir wrote:
>
>>Please read the reply below from one of the maintainers of freeradius:
>>
>>"Lenir" <lenirsantiago at yahoo.com> wrote:
>>
>>>But if UserB hangs up on UserA: SER generates a stop-record where the
>>>Calling-Station-Id is UserB and the Called-Station-Id is UserA, this
>>>is the undesired and incorrect behavior.
>>
>> It would appear to be a bug in SER.
>>
>>
>>>To me the Calling-Station-Id and the Called-Station-Id should be the
>>>same for both start and stop records, am I right by thinking that?
>>
>> Yes.
>>
>>
>>>According to the developers of SER/OpenSER, this is the correct
>>>behavior, whoever sends the hangup signal (BYE or CANCEL) is
>>>considered the Calling-Station-Id, and they are unwilling to modify or
>>>create a patch to "fix" this.
>>
>> What they do for something inside of SER is their business. When they
>>generate RADIUS packets, they should follow RADIUS standards and
>>interoperability. The expectation, as you said, is that the
>>Calling/Called-Station-Id doesn't change during a session. If it does,
>
> it's
>
>>a bug and they should fix it.
>>
>> Alan DeKok.
>>-
>>List info/subscribe/unsubscribe? See
>>http://www.freeradius.org/list/users.html
>>
>>
>>
>>-----Original Message-----
>>From: 'Jan Janak' [mailto:jan at iptel.org]
>>Sent: Thursday, November 17, 2005 10:33 AM
>>To: Lenir
>>Cc: 'Klaus Darilion'; serdev at iptel.org; serusers at iptel.org;
>>devel at openser.org; users at openser.org
>>Subject: Re: [Users] RE: [Serusers] Re: [Serdev] Inaccurate Radius
>>Accounting
>>
>>On 17-11-2005 10:21, Lenir wrote:
>>
>>>In this case the radius proxy wont work, because you never can
>
> anticipate
>
>>>who hangs up the call, thus radius wont know who hung up the
>>
>>call...Besides
>>
>>>all other voice applications/hardware (SIP and H323) that use radius do
>>
>>not
>>
>>>behave like that, the Called-Station-ID ALWAYS remains the same, as with
>>
>>the
>>
>>>Calling-Station-ID.
>>
>> Could you name those SIP applications that behave the way you describe ?
>>
>> Jan.
>>
>>
>>
>>------------------------------------------------------------------------
>>
>>RCS file: /cvsroot/ser/sip_router/modules/acc/Attic/acc.c,v
>>retrieving revision 1.26.2.1
>>diff -u -r1.26.2.1 acc.c
>>--- modules/acc/acc.c 14 Jun 2005 20:25:19 -0000 1.26.2.1
>>+++ modules/acc/acc.c 25 Dec 2005 17:35:19 -0000
>>@@ -49,6 +49,9 @@
>> #include "acc_mod.h"
>> #include "acc.h"
>> #include "dict.h"
>>+#include "../../parser/parse_rr.h"
>>+#include "../../trim.h"
>>+#include "../../parser/parse_uri.h"
>> #ifdef RAD_ACC
>> # ifdef RADIUSCLIENT_NG_4
>> # include <radiusclient.h>
>>@@ -71,6 +74,8 @@
>> #define M_NAME "acc"
>> #endif
>>
>>+extern int swap_dir;
>>+
>> #define ATR(atr) atr_arr[cnt].s=A_##atr;\
>> atr_arr[cnt].len=A_##atr##_LEN;
>>
>>@@ -101,6 +106,94 @@
>> #endif
>>
>>
>>+static int check_ftag(struct sip_msg* msg, str* uri)
>>+{
>>+ param_hooks_t hooks;
>>+ param_t* params;
>>+ char* semi;
>>+ struct to_body* from;
>>+ str t;
>>+
>>+ t = *uri;
>>+ params = 0;
>>+ semi = q_memchr(t.s, ';', t.len);
>>+ if (!semi) {
>>+ DBG("No ftag parameter found\n");
>>+ return -1;
>>+ }
>>+
>>+ t.len -= semi - uri->s + 1;
>>+ t.s = semi + 1;
>>+ trim_leading(&t);
>>+
>>+ if (parse_params(&t, CLASS_URI, &hooks, ¶ms) < 0) {
>>+ LOG(L_ERR, "Error while parsing parameters\n");
>>+ return -1;
>>+ }
>>+
>>+ if (!hooks.uri.ftag) {
>>+ DBG("No ftag parameter found\n");
>>+ goto err;
>>+ }
>>+
>>+ from = get_from(msg);
>>+
>>+ if (!from || !from->tag_value.len || !from->tag_value.s) {
>>+ DBG("No from tag parameter found\n");
>>+ goto err;
>>+ }
>>+
>>+ if (from->tag_value.len == hooks.uri.ftag->body.len &&
>>+ !strncmp(from->tag_value.s, hooks.uri.ftag->body.s, hooks.uri.ftag->body.len)) {
>>+ DBG("Route ftag and From tag are same\n");
>>+ free_params(params);
>>+ return 0;
>>+ } else {
>>+ DBG("Route ftag and From tag are NOT same\n");
>>+ free_params(params);
>>+ return 1;
>>+ }
>>+
>>+ err:
>>+ if (params) free_params(params);
>>+ return -1;
>>+}
>>+
>>+static int get_direction(struct sip_msg* msg)
>>+{
>>+ int ret;
>>+ if (parse_orig_ruri(msg) < 0) {
>>+ return -1;
>>+ }
>>+
>>+ if (!msg->parsed_orig_ruri_ok) {
>>+ LOG(L_ERR, "Error while parsing original Request-URI\n");
>>+ return -1;
>>+ }
>>+
>>+ ret = check_self(&msg->parsed_orig_ruri.host,
>>+ msg->parsed_orig_ruri.port_no ? msg->parsed_orig_ruri.port_no : SIP_PORT, 0);/* match all protos*/
>>+ if (ret < 0) return -1;
>>+ if (ret > 0) {
>>+ /* Route is in ruri */
>>+ return check_ftag(msg, &msg->first_line.u.request.uri);
>>+ } else {
>>+ if (msg->route) {
>>+ if (parse_rr(msg->route) < 0) {
>>+ LOG(L_ERR, "Error while parsing Route HF\n");
>>+ return -1;
>>+ }
>>+ ret = check_ftag(msg, &((rr_t*)msg->route->parsed)->nameaddr.uri);
>>+ if (msg->route->parsed) free_rr((rr_t**)&msg->route->parsed);
>>+ return ret;
>>+ } else {
>>+ DBG("No Route headers found\n");
>>+ return -1;
>>+ }
>>+ }
>>+}
>>+
>>+
>> static inline struct hdr_field *valid_to( struct cell *t,
>> struct sip_msg *reply)
>> {
>>@@ -156,9 +249,10 @@
>> static str mycode;
>> str *cr;
>> struct cseq_body *cseq;
>>+ int dir;
>>
>> cnt=tl=al=0;
>>-
>>+ dir = -2;
>> /* we don't care about parsing here; either the function
>> * was called from script, in which case the wrapping function
>> * is supposed to parse, or from reply processing in which case
>>@@ -218,10 +312,19 @@
>> }
>> /* fallback to from-uri if digest unavailable ... */
>> case 'F': /* from-uri */
>>- if (rq->from && (from=get_from(rq))
>>- && from->uri.len) {
>>+
>>+ if (swap_dir && dir == -2) dir = get_direction(rq);
>>+ if (dir <= 0) {
>>+ if (rq->from && (from=get_from(rq))
>>+ && from->uri.len) {
>> val_arr[cnt]=&from->uri;
>>- } else val_arr[cnt]=&na;
>>+ } else val_arr[cnt]=&na;
>>+ } else {
>>+ if (rq->to && (pto=get_to(rq))
>>+ && pto->uri.len) {
>>+ val_arr[cnt]=&pto->uri;
>>+ } else val_arr[cnt]=&na;
>>+ }
>> ATR(FROMURI);
>> break;
>> case '0': /* from user */
>>@@ -255,10 +358,19 @@
>> ATR(TOTAG);
>> break;
>> case 'T': /* to-uri */
>>- if (rq->to && (pto=get_to(rq))
>>- && pto->uri.len) {
>>+
>>+ if (swap_dir && dir == -2) dir = get_direction(rq);
>>+ if (dir <= 0) {
>>+ if (rq->to && (pto=get_to(rq))
>>+ && pto->uri.len) {
>> val_arr[cnt]=&pto->uri;
>>- } else val_arr[cnt]=&na;
>>+ } else val_arr[cnt]=&na;
>>+ } else {
>>+ if (rq->from && (from=get_from(rq))
>>+ && from->uri.len) {
>>+ val_arr[cnt]=&from->uri;
>>+ } else val_arr[cnt]=&na;
>>+ }
>> ATR(TOURI);
>> break;
>> case '1': /* to user */
>>Index: modules/acc/acc_mod.c
>>===================================================================
>>RCS file: /cvsroot/ser/sip_router/modules/acc/Attic/acc_mod.c,v
>>retrieving revision 1.39.2.3
>>diff -u -r1.39.2.3 acc_mod.c
>>--- modules/acc/acc_mod.c 20 Sep 2005 16:03:14 -0000 1.39.2.3
>>+++ modules/acc/acc_mod.c 25 Dec 2005 17:35:20 -0000
>>@@ -115,6 +115,7 @@
>> int radius_flag = 0;
>> int radius_missed_flag = 0;
>> static int service_type = -1;
>>+int swap_dir = 0;
>> void *rh;
>> struct attr attrs[A_MAX];
>> struct val vals[V_MAX];
>>@@ -206,6 +207,7 @@
>> {"radius_flag", INT_PARAM, &radius_flag },
>> {"radius_missed_flag", INT_PARAM, &radius_missed_flag },
>> {"service_type", INT_PARAM, &service_type },
>>+ {"swap_direction", INT_PARAM, &swap_dir},
>> #endif
>> /* DIAMETER */
>> #ifdef DIAM_ACC
>>@@ -414,7 +416,7 @@
>> * don't be worried about parsing outcome -- if it failed,
>> * we will report N/A
>> */
>>- parse_headers(rq, HDR_CALLID| HDR_FROM| HDR_TO, 0 );
>>+ parse_headers(rq, HDR_CALLID| HDR_FROM| HDR_TO| HDR_ROUTE, 0 );
>> parse_from_header(rq);
>>
>> if (strchr(log_fmt, 'p') || strchr(log_fmt, 'D')) {
>>Index: modules/acc/acc_mod.h
>>===================================================================
>>RCS file: /cvsroot/ser/sip_router/modules/acc/Attic/acc_mod.h,v
>>retrieving revision 1.14
>>diff -u -r1.14 acc_mod.h
>>--- modules/acc/acc_mod.h 24 Aug 2004 08:58:23 -0000 1.14
>>+++ modules/acc/acc_mod.h 25 Dec 2005 17:35:21 -0000
>>@@ -87,6 +87,7 @@
>> extern char* acc_totag_col;
>> extern char* acc_fromtag_col;
>>
>>+extern int swap_dir;
>>
>> #endif /* SQL_ACC */
>>
>>Index: parser/parse_param.c
>>===================================================================
>>RCS file: /cvsroot/ser/sip_router/parser/parse_param.c,v
>>retrieving revision 1.21
>>diff -u -r1.21 parse_param.c
>>--- parser/parse_param.c 1 Sep 2004 12:50:40 -0000 1.21
>>+++ parser/parse_param.c 25 Dec 2005 17:35:26 -0000
>>@@ -144,6 +144,15 @@
>> _h->uri.maddr = _p;
>> }
>> break;
>>+
>>+ case 'f':
>>+ case 'F':
>>+ if ((_p->name.len == 4) &&
>>+ (!strncasecmp(_p->name.s + 1, "tag", 3))) {
>>+ _p->type = P_FTAG;
>>+ _h->uri.ftag = _p;
>>+ }
>>+ break;
>> }
>> }
>>
>>@@ -475,6 +484,7 @@
>> case P_MADDR: type = "P_MADDR"; break;
>> case P_TTL: type = "P_TTL"; break;
>> case P_RECEIVED: type = "P_RECEIVED"; break;
>>+ case P_FTAG: type = "P_FTAG"; break;
>> default: type = "UNKNOWN"; break;
>> }
>>
>>Index: parser/parse_param.h
>>===================================================================
>>RCS file: /cvsroot/ser/sip_router/parser/parse_param.h,v
>>retrieving revision 1.11
>>diff -u -r1.11 parse_param.h
>>--- parser/parse_param.h 1 Sep 2004 11:56:59 -0000 1.11
>>+++ parser/parse_param.h 25 Dec 2005 17:35:26 -0000
>>@@ -53,6 +53,7 @@
>> P_R2, /* URI: r2 parameter (ser specific) */
>> P_MADDR, /* URI: maddr parameter */
>> P_TTL, /* URI: ttl parameter */
>>+ P_FTAG /* URI: ftag parameter */
>> } ptype_t;
>>
>>
>>@@ -98,6 +99,7 @@
>> struct param* r2; /* r2 parameter */
>> struct param* maddr; /* maddr parameter */
>> struct param* ttl; /* ttl parameter */
>>+ struct param* ftag; /* ftag parameter */
>> };
>>
>>
>>
>>
>>------------------------------------------------------------------------
>>
>>_______________________________________________
>>Devel mailing list
>>Devel at openser.org
>>http://openser.org/cgi-bin/mailman/listinfo/devel
More information about the Devel
mailing list