Implement DisconnectSession API for RADIUS Agent

Updated radigo library to latest version.

Updated RadiusAgent to satisfy the birpc client interface.

Added *radDAdiscMsg OrderedNavigableMap type field within AgentRequest.
This one is similar to *diamreq, as it is used for building RADIUS
server-initiated Disconnect Requests.

radReplyAppendAttributes: refactored to reflect that it can now be
used to also append attributes to request packets, not only reply.

Added bidirectional support for session related RadiusAgent methods.

For Dynamic Authorization to be possible, a new field was added within RadiusAgent
that holds dicts and secrets only for the clients that support it. They are used
to create the DA Client sending Disconnect Requests.

Added a new cache partition to store Access-Request packets with the purpose
of using them to build the Disconnect Requests. They are identified by sessionID.
It defaults to the value of 'Acct-Session-id'.

Added a predefined '*dmr' template as well as a 'dmr_template' config option within
the 'radius_agent' config section. This will map to a custom or to the predefined
template and will be used to build the Disconnect Request. By default, it doesn't
point to any template (this also means that the Access-Request packets will not be
cached).

Another option added to 'radius_agent' is 'client_da_addresses', which lists the
RADIUS clients supporting Dynamic Authorization. The key represents the host of
the client, while the value represents the address to which we will send the
Disconnect Request.

Added integration test.
This commit is contained in:
ionutboangiu
2024-01-23 17:11:12 -05:00
committed by Dan Christian Bogos
parent d182d6f601
commit 9991b29cae
20 changed files with 864 additions and 115 deletions

View File

@@ -0,0 +1,35 @@
{
"radius_agent": {
"request_processors": [
{
"id": "Accounting",
"filters": ["*string:~*req.Acct-Status-Type:Start"],
"flags": ["*initiate", "*attributes", "*resources", "*accounts"],
"request_fields":[
{"tag": "Category", "path": "*cgreq.Category", "type": "*constant", "value": "call"},
{"tag": "RequestType", "path": "*cgreq.RequestType", "type": "*constant",
"value": "*prepaid", "mandatory": true},
{"tag": "OriginID", "path": "*cgreq.OriginID", "type": "*composed",
"value": "~*req.Acct-Session-Id;-;modified", "mandatory": true},
{"tag": "OriginHost", "path": "*cgreq.OriginHost", "type": "*composed",
"value": "~*req.NAS-IP-Address", "mandatory": true},
{"tag": "Account", "path": "*cgreq.Account", "type": "*composed",
"value": "~*req.User-Name", "mandatory": true},
{"tag": "Subject", "path": "*cgreq.Subject", "type": "*composed",
"value": "~*req.User-Name", "mandatory": true},
{"tag": "Destination", "path": "*cgreq.Destination", "type": "*composed",
"value": "~*req.Called-Station-Id", "mandatory": true},
{"tag": "SetupTime", "path": "*cgreq.SetupTime", "type": "*composed",
"value": "~*req.Event-Timestamp", "mandatory": true},
{"tag": "AnswerTime", "path": "*cgreq.AnswerTime", "type": "*composed",
"value": "~*req.Event-Timestamp", "mandatory": true},
{"tag": "RemoteAddr" , "path": "*cgreq.RemoteAddr", "type": "*variable",
"value": "~*vars.RemoteHost:s/(.*):\\d+/${1}/"}
],
"reply_fields":[]
}
]
}
}

View File

@@ -0,0 +1,39 @@
{
"radius_agent": {
"request_processors": [
{
"id": "Authorization",
"filters": ["*string:~*vars.*radReqType:*radAuth"],
"flags": ["*authorize", "*attributes", "*accounts", "*continue"],
"request_fields":[
{"tag": "Category", "path": "*cgreq.Category", "type": "*constant",
"value": "call"},
{"tag": "RequestType", "path": "*cgreq.RequestType", "type": "*constant",
"value": "*prepaid", "mandatory": true},
{"tag": "OriginID", "path": "*cgreq.OriginID", "type": "*composed",
"value": "~*req.Acct-Session-Id", "mandatory": true},
{"tag": "Account", "path": "*cgreq.Account", "type": "*composed",
"value": "~*req.User-Name", "mandatory": true},
{"tag": "Subject", "path": "*cgreq.Subject", "type": "*composed",
"value": "~*req.User-Name", "mandatory": true},
{"tag": "Destination", "path": "*cgreq.Destination", "type": "*composed",
"value": "~*req.Called-Station-Id", "mandatory": true},
{"tag": "SetupTime", "path": "*cgreq.SetupTime", "type": "*composed",
"value": "~*req.Event-Timestamp", "mandatory": true},
{"tag": "AnswerTime", "path": "*cgreq.AnswerTime", "type": "*composed",
"value": "~*req.Event-Timestamp", "mandatory": true},
{"tag": "PasswordFromAttributes", "path": "*cgreq.PasswordFromAttributes", "type": "*constant",
"value": "*attributes"},
{"tag": "SessionID", "path": "*vars.*sessionID", "type": "*variable",
"value": "~*req.Acct-Session-Id;-;modified"}
],
"reply_fields":[
{"tag": "MaxUsage", "path": "*rep.SIP-AVP", "type": "*composed",
"value": "session_max_time#;~*cgrep.MaxUsage{*duration_seconds}", "mandatory": true}
]
}
]
}
}

View File

@@ -0,0 +1,72 @@
{
"general": {
"log_level": 7
},
"data_db": {
"db_type": "*internal"
},
"stor_db": {
"db_type": "*internal"
},
"rals": {
"enabled": true
},
"schedulers": {
"enabled": true
},
"cdrs": {
"enabled": true,
"rals_conns": ["*internal"]
},
"resources": {
"enabled": true,
"store_interval": "-1"
},
"attributes": {
"enabled": true
},
"chargers": {
"enabled": true
},
"sessions": {
"enabled": true,
"attributes_conns": ["*localhost"],
"cdrs_conns": ["*localhost"],
"rals_conns": ["*localhost"],
"resources_conns": ["*localhost"],
"chargers_conns": ["*localhost"],
"debit_interval": "10s"
},
"radius_agent": {
"enabled": true,
"sessions_conns": ["*bijson_localhost"],
"client_da_addresses": {
"127.0.0.1": ":3799"
},
"listeners":[
{
"network": "udp",
"auth_address": "127.0.0.1:1812",
"acct_address": "127.0.0.1:1813"
}
],
"dmr_template": "*dmr"
},
"apiers": {
"enabled": true,
"scheduler_conns": ["*localhost"]
}
}