mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-19 22:28:45 +05:00
Skel of RadiusAgent with sample config
This commit is contained in:
76
agents/radagent.go
Normal file
76
agents/radagent.go
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments
|
||||
Copyright (C) ITsysCOM GmbH
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
package agents
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"github.com/cgrates/radigo"
|
||||
"github.com/cgrates/rpcclient"
|
||||
)
|
||||
|
||||
func NewRadiusAgent(cgrCfg *config.CGRConfig, smg rpcclient.RpcClientConnection) (ra *RadiusAgent, err error) {
|
||||
dicts := make(map[string]*radigo.Dictionary, len(cgrCfg.RadiusAgentCfg().ClientDictionaries))
|
||||
for clntID, dictPath := range cgrCfg.RadiusAgentCfg().ClientDictionaries {
|
||||
if dicts[clntID], err = radigo.NewDictionaryFromFolderWithRFC2865(dictPath); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
ra = &RadiusAgent{cgrCfg: cgrCfg, smg: smg}
|
||||
ra.rsAuth = radigo.NewServer(cgrCfg.RadiusAgentCfg().ListenNet, cgrCfg.RadiusAgentCfg().ListenAuth, cgrCfg.RadiusAgentCfg().ClientSecrets, dicts,
|
||||
map[radigo.PacketCode]func(*radigo.Packet) (*radigo.Packet, error){radigo.AccessRequest: ra.handleAuth})
|
||||
ra.rsAcct = radigo.NewServer(cgrCfg.RadiusAgentCfg().ListenNet, cgrCfg.RadiusAgentCfg().ListenAcct, cgrCfg.RadiusAgentCfg().ClientSecrets, dicts,
|
||||
map[radigo.PacketCode]func(*radigo.Packet) (*radigo.Packet, error){radigo.AccountingRequest: ra.handleAcct})
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
type RadiusAgent struct {
|
||||
cgrCfg *config.CGRConfig // reference for future config reloads
|
||||
smg rpcclient.RpcClientConnection // Connection towards CGR-SMG component
|
||||
rsAuth *radigo.Server
|
||||
rsAcct *radigo.Server
|
||||
}
|
||||
|
||||
func (ra *RadiusAgent) handleAuth(req *radigo.Packet) (rpl *radigo.Packet, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (ra *RadiusAgent) handleAcct(req *radigo.Packet) (rpl *radigo.Packet, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (ra *RadiusAgent) ListenAndServe() (err error) {
|
||||
var errListen chan error
|
||||
go func() {
|
||||
utils.Logger.Info(fmt.Sprintf("<RadiusAgent> Start listening for auth requests on <%s>", ra.cgrCfg.RadiusAgentCfg().ListenAuth))
|
||||
if err := ra.rsAuth.ListenAndServe(); err != nil {
|
||||
errListen <- err
|
||||
}
|
||||
}()
|
||||
go func() {
|
||||
utils.Logger.Info(fmt.Sprintf("<RadiusAgent> Start listening for acct requests on <%s>", ra.cgrCfg.RadiusAgentCfg().ListenAcct))
|
||||
if err := ra.rsAcct.ListenAndServe(); err != nil {
|
||||
errListen <- err
|
||||
}
|
||||
}()
|
||||
err = <-errListen
|
||||
return
|
||||
}
|
||||
@@ -210,7 +210,7 @@ func startSMAsterisk(internalSMGChan chan *sessionmanager.SMGeneric, exitChan ch
|
||||
}
|
||||
|
||||
func startDiameterAgent(internalSMGChan chan *sessionmanager.SMGeneric, internalPubSubSChan chan rpcclient.RpcClientConnection, exitChan chan bool) {
|
||||
utils.Logger.Info("Starting CGRateS DiameterAgent service.")
|
||||
utils.Logger.Info("Starting CGRateS DiameterAgent service")
|
||||
smgChan := make(chan rpcclient.RpcClientConnection, 1) // Use it to pass smg
|
||||
go func(internalSMGChan chan *sessionmanager.SMGeneric, smgChan chan rpcclient.RpcClientConnection) {
|
||||
// Need this to pass from *sessionmanager.SMGeneric to rpcclient.RpcClientConnection
|
||||
@@ -250,8 +250,39 @@ func startDiameterAgent(internalSMGChan chan *sessionmanager.SMGeneric, internal
|
||||
exitChan <- true
|
||||
}
|
||||
|
||||
func startRadiusAgent(internalSMGChan chan *sessionmanager.SMGeneric, exitChan chan bool) {
|
||||
utils.Logger.Info("Starting CGRateS RadiusAgent service")
|
||||
smgChan := make(chan rpcclient.RpcClientConnection, 1) // Use it to pass smg
|
||||
go func(internalSMGChan chan *sessionmanager.SMGeneric, smgChan chan rpcclient.RpcClientConnection) {
|
||||
// Need this to pass from *sessionmanager.SMGeneric to rpcclient.RpcClientConnection
|
||||
smg := <-internalSMGChan
|
||||
internalSMGChan <- smg
|
||||
smgChan <- smg
|
||||
}(internalSMGChan, smgChan)
|
||||
var smgConn *rpcclient.RpcClientPool
|
||||
if len(cfg.RadiusAgentCfg().SMGenericConns) != 0 {
|
||||
smgConn, err = engine.NewRPCPool(rpcclient.POOL_FIRST, cfg.ConnectAttempts, cfg.Reconnects, cfg.ConnectTimeout, cfg.ReplyTimeout,
|
||||
cfg.RadiusAgentCfg().SMGenericConns, smgChan, cfg.InternalTtl)
|
||||
if err != nil {
|
||||
utils.Logger.Crit(fmt.Sprintf("<RadiusAgent> Could not connect to SMG: %s", err.Error()))
|
||||
exitChan <- true
|
||||
return
|
||||
}
|
||||
}
|
||||
ra, err := agents.NewRadiusAgent(cfg, smgConn)
|
||||
if err != nil {
|
||||
utils.Logger.Err(fmt.Sprintf("<RadiusAgent> error: <%s>", err.Error()))
|
||||
exitChan <- true
|
||||
return
|
||||
}
|
||||
if err = ra.ListenAndServe(); err != nil {
|
||||
utils.Logger.Err(fmt.Sprintf("<RadiusAgent> error: <%s>", err.Error()))
|
||||
}
|
||||
exitChan <- true
|
||||
}
|
||||
|
||||
func startSmFreeSWITCH(internalRaterChan, internalCDRSChan, rlsChan chan rpcclient.RpcClientConnection, cdrDb engine.CdrStorage, exitChan chan bool) {
|
||||
utils.Logger.Info("Starting CGRateS SMFreeSWITCH service.")
|
||||
utils.Logger.Info("Starting CGRateS SMFreeSWITCH service")
|
||||
var ralsConn, cdrsConn, rlsConn *rpcclient.RpcClientPool
|
||||
if len(cfg.SmFsConfig.RALsConns) != 0 {
|
||||
ralsConn, err = engine.NewRPCPool(rpcclient.POOL_FIRST, cfg.ConnectAttempts, cfg.Reconnects, cfg.ConnectTimeout, cfg.ReplyTimeout,
|
||||
@@ -730,6 +761,10 @@ func main() {
|
||||
go startDiameterAgent(internalSMGChan, internalPubSubSChan, exitChan)
|
||||
}
|
||||
|
||||
if cfg.RadiusAgentCfg().Enabled {
|
||||
go startRadiusAgent(internalSMGChan, exitChan)
|
||||
}
|
||||
|
||||
// Start HistoryS service
|
||||
if cfg.HistoryServerEnabled {
|
||||
go startHistoryServer(internalHistorySChan, server, exitChan)
|
||||
|
||||
@@ -359,7 +359,9 @@ const CGRATES_CFG_JSON = `
|
||||
"listen_net": "udp", // network to listen on <udp|tcp>
|
||||
"listen_auth": "127.0.0.1:1812", // address where to listen for radius authentication requests <x.y.z.y:1234>
|
||||
"listen_acct": "127.0.0.1:1813", // address where to listen for radius accounting requests <x.y.z.y:1234>
|
||||
"client_secrets": {"*default": "CGRateS.org"}, // hash containing secrets for clients connecting here <*default|$client_ip>
|
||||
"client_secrets": { // hash containing secrets for clients connecting here <*default|$client_ip>
|
||||
"*default": "CGRateS.org"
|
||||
},
|
||||
"client_dictionaries": { // per client path towards directory holding additional dictionaries to load (extra to RFC)
|
||||
"*default": "/usr/share/cgrates/radius/dict/", // key represents the client IP or catch-all <*default|$client_ip>
|
||||
},
|
||||
|
||||
79
data/conf/samples/radagent/cgrates.json
Normal file
79
data/conf/samples/radagent/cgrates.json
Normal file
@@ -0,0 +1,79 @@
|
||||
{
|
||||
// CGRateS Configuration file
|
||||
//
|
||||
// Used for cgradmin
|
||||
// Starts rater, scheduler
|
||||
|
||||
"listen": {
|
||||
"rpc_json": ":2012", // RPC JSON listening address
|
||||
"rpc_gob": ":2013", // RPC GOB listening address
|
||||
"http": ":2080", // HTTP listening address
|
||||
},
|
||||
|
||||
"data_db": { // database used to store runtime data (eg: accounts, cdr stats)
|
||||
"db_type": "mongo", // stor database type to use: <mysql|postgres>
|
||||
"db_port": 27017, // the port to reach the stordb
|
||||
"db_name": "datadb",
|
||||
"db_password": "",
|
||||
},
|
||||
|
||||
"stor_db": {
|
||||
"db_type": "mongo", // stor database type to use: <mysql|postgres>
|
||||
"db_port": 27017, // the port to reach the stordb
|
||||
"db_name": "stordb",
|
||||
"db_password": "",
|
||||
},
|
||||
|
||||
"rals": {
|
||||
"enabled": true,
|
||||
"cdrstats_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
"pubsubs_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
"users_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
"aliases_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
},
|
||||
|
||||
"scheduler": {
|
||||
"enabled": true,
|
||||
},
|
||||
|
||||
"cdrs": {
|
||||
"enabled": true,
|
||||
"cdrstats_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
},
|
||||
|
||||
"cdrstats": {
|
||||
"enabled": true,
|
||||
},
|
||||
|
||||
"pubsubs": {
|
||||
"enabled": true, // starts PubSub service: <true|false>.
|
||||
},
|
||||
|
||||
"aliases": {
|
||||
"enabled": true, // starts Aliases service: <true|false>.
|
||||
},
|
||||
|
||||
"users": {
|
||||
"enabled": true,
|
||||
"indexes": ["SubscriberId"],
|
||||
},
|
||||
|
||||
"sm_generic": {
|
||||
"enabled": true,
|
||||
},
|
||||
|
||||
"radius_agent": {
|
||||
"enabled": true,
|
||||
},
|
||||
|
||||
}
|
||||
2
glide.lock
generated
2
glide.lock
generated
@@ -18,7 +18,7 @@ imports:
|
||||
- name: github.com/cgrates/osipsdagram
|
||||
version: 3d6beed663452471dec3ca194137a30d379d9e8f
|
||||
- name: github.com/cgrates/radigo
|
||||
version: 8ee4c8409a0f8b8084d427dfb81010fd2add788c
|
||||
version: b0690a5c829349f3c1bb0973f422788b870a9acc
|
||||
- name: github.com/cgrates/rpcclient
|
||||
version: dddae42e9344e877627cd4b7aba075d63b452c0b
|
||||
- name: github.com/ChrisTrenkamp/goxpath
|
||||
|
||||
Reference in New Issue
Block a user