mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Updated DNSAgent
This commit is contained in:
committed by
Dan Christian Bogos
parent
dce8636c30
commit
ec539b5994
@@ -221,6 +221,18 @@ func testDiamItResetAllDB(t *testing.T) {
|
||||
if err := engine.InitStorDb(allCfg); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
cfgPath2 := path.Join(*dataDir, "conf", "samples", "dispatchers", "all2")
|
||||
allCfg2, err := config.NewCGRConfigFromPath(cfgPath2)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := engine.InitDataDb(allCfg2); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := engine.InitStorDb(allCfg2); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Remove data in both rating and accounting db
|
||||
|
||||
@@ -267,14 +267,17 @@ func (da *DiameterAgent) handleMessage(c diam.Conn, m *diam.Message) {
|
||||
var processed bool
|
||||
for _, reqProcessor := range da.cgrCfg.DiameterAgentCfg().RequestProcessors {
|
||||
var lclProcessed bool
|
||||
lclProcessed, err = da.processRequest(
|
||||
lclProcessed, err = processRequest(
|
||||
reqProcessor,
|
||||
NewAgentRequest(
|
||||
diamDP, reqVars, cgrRplyNM, rply, opts,
|
||||
reqProcessor.Tenant, da.cgrCfg.GeneralCfg().DefaultTenant,
|
||||
utils.FirstNonEmpty(reqProcessor.Timezone,
|
||||
da.cgrCfg.GeneralCfg().DefaultTimezone),
|
||||
da.filterS, nil))
|
||||
da.filterS, nil),
|
||||
utils.DiameterAgent, da.connMgr,
|
||||
da.cgrCfg.DiameterAgentCfg().SessionSConns,
|
||||
da, da.filterS)
|
||||
if lclProcessed {
|
||||
processed = lclProcessed
|
||||
}
|
||||
@@ -309,180 +312,6 @@ func (da *DiameterAgent) handleMessage(c diam.Conn, m *diam.Message) {
|
||||
writeOnConn(c, a)
|
||||
}
|
||||
|
||||
func (da *DiameterAgent) processRequest(reqProcessor *config.RequestProcessor,
|
||||
agReq *AgentRequest) (processed bool, err error) {
|
||||
if pass, err := da.filterS.Pass(agReq.Tenant,
|
||||
reqProcessor.Filters, agReq); err != nil || !pass {
|
||||
return pass, err
|
||||
}
|
||||
if err = agReq.SetFields(reqProcessor.RequestFields); err != nil {
|
||||
return
|
||||
}
|
||||
cgrEv := utils.NMAsCGREvent(agReq.CGRRequest, agReq.Tenant, utils.NestingSep, agReq.Opts)
|
||||
var reqType string
|
||||
for _, typ := range []string{
|
||||
utils.MetaDryRun, utils.MetaAuthorize,
|
||||
utils.MetaInitiate, utils.MetaUpdate,
|
||||
utils.MetaTerminate, utils.MetaMessage,
|
||||
utils.MetaCDRs, utils.MetaEvent, utils.MetaNone} {
|
||||
if reqProcessor.Flags.Has(typ) { // request type is identified through flags
|
||||
reqType = typ
|
||||
break
|
||||
}
|
||||
}
|
||||
var cgrArgs utils.Paginator
|
||||
if reqType == utils.MetaAuthorize || reqType == utils.MetaMessage || reqType == utils.MetaEvent {
|
||||
if cgrArgs, err = utils.GetRoutePaginatorFromOpts(cgrEv.APIOpts); err != nil {
|
||||
utils.Logger.Warning(fmt.Sprintf("<%s> args extraction failed because <%s>",
|
||||
utils.DiameterAgent, err.Error()))
|
||||
err = nil // reset the error and continue the processing
|
||||
}
|
||||
}
|
||||
|
||||
if reqProcessor.Flags.Has(utils.MetaLog) {
|
||||
utils.Logger.Info(
|
||||
fmt.Sprintf("<%s> LOG, processorID: %s, diameter message: %s",
|
||||
utils.DiameterAgent, reqProcessor.ID, agReq.Request.String()))
|
||||
}
|
||||
switch reqType {
|
||||
default:
|
||||
return false, fmt.Errorf("unknown request type: <%s>", reqType)
|
||||
case utils.MetaNone: // do nothing on CGRateS side
|
||||
case utils.MetaDryRun:
|
||||
utils.Logger.Info(
|
||||
fmt.Sprintf("<%s> DRY_RUN, processorID: %s, DiameterMessage: %s",
|
||||
utils.DiameterAgent, reqProcessor.ID, agReq.Request.String()))
|
||||
case utils.MetaAuthorize:
|
||||
authArgs := sessions.NewV1AuthorizeArgs(
|
||||
reqProcessor.Flags.GetBool(utils.MetaAttributes),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaAttributes, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaThresholds),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaThresholds, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaStats),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaStats, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaResources),
|
||||
reqProcessor.Flags.Has(utils.MetaAccounts),
|
||||
reqProcessor.Flags.GetBool(utils.MetaRoutes),
|
||||
reqProcessor.Flags.Has(utils.MetaRoutesIgnoreErrors),
|
||||
reqProcessor.Flags.Has(utils.MetaRoutesEventCost),
|
||||
cgrEv, cgrArgs,
|
||||
reqProcessor.Flags.Has(utils.MetaFD),
|
||||
reqProcessor.Flags.ParamValue(utils.MetaRoutesMaxCost),
|
||||
)
|
||||
rply := new(sessions.V1AuthorizeReply)
|
||||
err = da.connMgr.Call(da.cgrCfg.DiameterAgentCfg().SessionSConns, da, utils.SessionSv1AuthorizeEvent,
|
||||
authArgs, rply)
|
||||
rply.SetMaxUsageNeeded(authArgs.GetMaxUsage)
|
||||
agReq.setCGRReply(rply, err)
|
||||
case utils.MetaInitiate:
|
||||
initArgs := sessions.NewV1InitSessionArgs(
|
||||
reqProcessor.Flags.GetBool(utils.MetaAttributes),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaAttributes, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaThresholds),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaThresholds, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaStats),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaStats, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaResources),
|
||||
reqProcessor.Flags.Has(utils.MetaAccounts),
|
||||
cgrEv, reqProcessor.Flags.Has(utils.MetaFD))
|
||||
rply := new(sessions.V1InitSessionReply)
|
||||
err = da.connMgr.Call(da.cgrCfg.DiameterAgentCfg().SessionSConns, da, utils.SessionSv1InitiateSession,
|
||||
initArgs, rply)
|
||||
rply.SetMaxUsageNeeded(initArgs.InitSession)
|
||||
agReq.setCGRReply(rply, err)
|
||||
case utils.MetaUpdate:
|
||||
updateArgs := sessions.NewV1UpdateSessionArgs(
|
||||
reqProcessor.Flags.GetBool(utils.MetaAttributes),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaAttributes, utils.MetaIDs),
|
||||
reqProcessor.Flags.Has(utils.MetaAccounts),
|
||||
cgrEv, reqProcessor.Flags.Has(utils.MetaFD))
|
||||
rply := new(sessions.V1UpdateSessionReply)
|
||||
rply.SetMaxUsageNeeded(updateArgs.UpdateSession)
|
||||
err = da.connMgr.Call(da.cgrCfg.DiameterAgentCfg().SessionSConns, da, utils.SessionSv1UpdateSession,
|
||||
updateArgs, rply)
|
||||
agReq.setCGRReply(rply, err)
|
||||
case utils.MetaTerminate:
|
||||
terminateArgs := sessions.NewV1TerminateSessionArgs(
|
||||
reqProcessor.Flags.Has(utils.MetaAccounts),
|
||||
reqProcessor.Flags.GetBool(utils.MetaResources),
|
||||
reqProcessor.Flags.GetBool(utils.MetaThresholds),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaThresholds, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaStats),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaStats, utils.MetaIDs),
|
||||
cgrEv, reqProcessor.Flags.Has(utils.MetaFD))
|
||||
var rply string
|
||||
err = da.connMgr.Call(da.cgrCfg.DiameterAgentCfg().SessionSConns, da, utils.SessionSv1TerminateSession,
|
||||
terminateArgs, &rply)
|
||||
agReq.setCGRReply(nil, err)
|
||||
case utils.MetaMessage:
|
||||
msgArgs := sessions.NewV1ProcessMessageArgs(
|
||||
reqProcessor.Flags.GetBool(utils.MetaAttributes),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaAttributes, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaThresholds),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaThresholds, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaStats),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaStats, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaResources),
|
||||
reqProcessor.Flags.Has(utils.MetaAccounts),
|
||||
reqProcessor.Flags.GetBool(utils.MetaRoutes),
|
||||
reqProcessor.Flags.Has(utils.MetaRoutesIgnoreErrors),
|
||||
reqProcessor.Flags.Has(utils.MetaRoutesEventCost),
|
||||
cgrEv, cgrArgs,
|
||||
reqProcessor.Flags.Has(utils.MetaFD),
|
||||
reqProcessor.Flags.ParamValue(utils.MetaRoutesMaxCost),
|
||||
)
|
||||
rply := new(sessions.V1ProcessMessageReply)
|
||||
err = da.connMgr.Call(da.cgrCfg.DiameterAgentCfg().SessionSConns, da, utils.SessionSv1ProcessMessage,
|
||||
msgArgs, rply)
|
||||
if utils.ErrHasPrefix(err, utils.RalsErrorPrfx) {
|
||||
cgrEv.Event[utils.Usage] = 0 // avoid further debits
|
||||
} else if msgArgs.Debit {
|
||||
cgrEv.Event[utils.Usage] = rply.MaxUsage // make sure the CDR reflects the debit
|
||||
}
|
||||
rply.SetMaxUsageNeeded(msgArgs.Debit)
|
||||
agReq.setCGRReply(rply, err)
|
||||
case utils.MetaEvent:
|
||||
evArgs := &sessions.V1ProcessEventArgs{
|
||||
Flags: reqProcessor.Flags.SliceFlags(),
|
||||
Paginator: cgrArgs,
|
||||
CGREvent: cgrEv,
|
||||
}
|
||||
rply := new(sessions.V1ProcessEventReply)
|
||||
err = da.connMgr.Call(da.cgrCfg.DiameterAgentCfg().SessionSConns, da, utils.SessionSv1ProcessEvent,
|
||||
evArgs, rply)
|
||||
if utils.ErrHasPrefix(err, utils.RalsErrorPrfx) {
|
||||
cgrEv.Event[utils.Usage] = 0 // avoid further debits
|
||||
} else if needsMaxUsage(reqProcessor.Flags[utils.MetaRALs]) {
|
||||
cgrEv.Event[utils.Usage] = rply.MaxUsage // make sure the CDR reflects the debit
|
||||
}
|
||||
agReq.setCGRReply(rply, err)
|
||||
case utils.MetaCDRs: // allow CDR processing
|
||||
}
|
||||
// separate request so we can capture the Terminate/Event also here
|
||||
if reqProcessor.Flags.GetBool(utils.MetaCDRs) &&
|
||||
!reqProcessor.Flags.Has(utils.MetaDryRun) {
|
||||
var rplyCDRs string
|
||||
if err = da.connMgr.Call(da.cgrCfg.DiameterAgentCfg().SessionSConns, da, utils.SessionSv1ProcessCDR,
|
||||
cgrEv, &rplyCDRs); err != nil {
|
||||
agReq.CGRReply.Map[utils.Error] = utils.NewLeafNode(err.Error())
|
||||
}
|
||||
}
|
||||
if err = agReq.SetFields(reqProcessor.ReplyFields); err != nil {
|
||||
return
|
||||
}
|
||||
if reqProcessor.Flags.Has(utils.MetaLog) {
|
||||
utils.Logger.Info(
|
||||
fmt.Sprintf("<%s> LOG, Diameter reply: %s",
|
||||
utils.DiameterAgent, agReq.Reply))
|
||||
}
|
||||
if reqType == utils.MetaDryRun {
|
||||
utils.Logger.Info(
|
||||
fmt.Sprintf("<%s> DRY_RUN, Diameter reply: %s",
|
||||
utils.DiameterAgent, agReq.Reply))
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// Call implements rpcclient.ClientConnector interface
|
||||
func (da *DiameterAgent) Call(serviceMethod string, args interface{}, reply interface{}) error {
|
||||
return utils.RPCCall(da, serviceMethod, args, reply)
|
||||
|
||||
@@ -458,7 +458,7 @@ func TestProcessRequest(t *testing.T) {
|
||||
filterS: filters,
|
||||
connMgr: connMgr,
|
||||
}
|
||||
pr, err := da.processRequest(reqProcessor, agReq)
|
||||
pr, err := processRequest(reqProcessor, agReq, utils.DiameterAgent, connMgr, da.cgrCfg.DiameterAgentCfg().SessionSConns, da, da.filterS)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
} else if !pr {
|
||||
@@ -475,7 +475,7 @@ func TestProcessRequest(t *testing.T) {
|
||||
reqProcessor.Tenant, config.CgrConfig().GeneralCfg().DefaultTenant,
|
||||
config.CgrConfig().GeneralCfg().DefaultTimezone, filters, nil)
|
||||
|
||||
pr, err = da.processRequest(reqProcessor, agReq)
|
||||
pr, err = processRequest(reqProcessor, agReq, utils.DiameterAgent, connMgr, da.cgrCfg.DiameterAgentCfg().SessionSConns, da, da.filterS)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
} else if !pr {
|
||||
@@ -492,7 +492,7 @@ func TestProcessRequest(t *testing.T) {
|
||||
reqProcessor.Tenant, config.CgrConfig().GeneralCfg().DefaultTenant,
|
||||
config.CgrConfig().GeneralCfg().DefaultTimezone, filters, nil)
|
||||
|
||||
pr, err = da.processRequest(reqProcessor, agReq)
|
||||
pr, err = processRequest(reqProcessor, agReq, utils.DiameterAgent, connMgr, da.cgrCfg.DiameterAgentCfg().SessionSConns, da, da.filterS)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
} else if !pr {
|
||||
@@ -515,7 +515,7 @@ func TestProcessRequest(t *testing.T) {
|
||||
reqProcessor.Tenant, config.CgrConfig().GeneralCfg().DefaultTenant,
|
||||
config.CgrConfig().GeneralCfg().DefaultTimezone, filters, nil)
|
||||
|
||||
pr, err = da.processRequest(reqProcessor, agReq)
|
||||
pr, err = processRequest(reqProcessor, agReq, utils.DiameterAgent, connMgr, da.cgrCfg.DiameterAgentCfg().SessionSConns, da, da.filterS)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
} else if !pr {
|
||||
@@ -532,7 +532,7 @@ func TestProcessRequest(t *testing.T) {
|
||||
reqProcessor.Tenant, config.CgrConfig().GeneralCfg().DefaultTenant,
|
||||
config.CgrConfig().GeneralCfg().DefaultTimezone, filters, nil)
|
||||
|
||||
pr, err = da.processRequest(reqProcessor, agReq)
|
||||
pr, err = processRequest(reqProcessor, agReq, utils.DiameterAgent, connMgr, da.cgrCfg.DiameterAgentCfg().SessionSConns, da, da.filterS)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
} else if !pr {
|
||||
|
||||
@@ -25,7 +25,6 @@ import (
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/sessions"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
@@ -47,27 +46,23 @@ type DNSAgent struct {
|
||||
}
|
||||
|
||||
// initDNSServer instantiates the DNS server
|
||||
func (da *DNSAgent) initDNSServer() (err error) {
|
||||
handler := dns.HandlerFunc(func(w dns.ResponseWriter, m *dns.Msg) {
|
||||
go da.handleMessage(w, m)
|
||||
})
|
||||
func (da *DNSAgent) initDNSServer() (_ error) {
|
||||
da.server = &dns.Server{
|
||||
Addr: da.cgrCfg.DNSAgentCfg().Listen,
|
||||
Net: da.cgrCfg.DNSAgentCfg().ListenNet,
|
||||
Handler: dns.HandlerFunc(func(w dns.ResponseWriter, m *dns.Msg) {
|
||||
go da.handleMessage(w, m)
|
||||
}),
|
||||
}
|
||||
if strings.HasSuffix(da.cgrCfg.DNSAgentCfg().ListenNet, utils.TLSNoCaps) {
|
||||
cert, err := tls.LoadX509KeyPair(da.cgrCfg.TLSCfg().ServerCerificate, da.cgrCfg.TLSCfg().ServerKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
config := tls.Config{
|
||||
da.server.Net = "tcp-tls"
|
||||
da.server.TLSConfig = &tls.Config{
|
||||
Certificates: []tls.Certificate{cert},
|
||||
}
|
||||
|
||||
da.server = &dns.Server{
|
||||
Addr: da.cgrCfg.DNSAgentCfg().Listen,
|
||||
Net: "tcp-tls",
|
||||
TLSConfig: &config,
|
||||
Handler: handler,
|
||||
}
|
||||
} else {
|
||||
da.server = &dns.Server{Addr: da.cgrCfg.DNSAgentCfg().Listen, Net: da.cgrCfg.DNSAgentCfg().ListenNet, Handler: handler}
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -88,7 +83,7 @@ func (da *DNSAgent) Reload() (err error) {
|
||||
// handleMessage is the entry point of all DNS requests
|
||||
// requests are reaching here asynchronously
|
||||
func (da *DNSAgent) handleMessage(w dns.ResponseWriter, req *dns.Msg) {
|
||||
dnsDP := newDNSDataProvider(req, w)
|
||||
dnsDP := newDnsDP(req)
|
||||
reqVars := &utils.DataNode{
|
||||
Type: utils.NMMapType,
|
||||
Map: map[string]*utils.DataNode{
|
||||
@@ -99,20 +94,8 @@ func (da *DNSAgent) handleMessage(w dns.ResponseWriter, req *dns.Msg) {
|
||||
rply := new(dns.Msg)
|
||||
rply.SetReply(req)
|
||||
// message preprocesing
|
||||
switch req.Question[0].Qtype {
|
||||
case dns.TypeNAPTR:
|
||||
if req.Question[0].Qtype == dns.TypeNAPTR {
|
||||
reqVars.Map[QueryName] = utils.NewLeafNode(req.Question[0].Name)
|
||||
e164, err := e164FromNAPTR(req.Question[0].Name)
|
||||
if err != nil {
|
||||
utils.Logger.Warning(
|
||||
fmt.Sprintf("<%s> decoding NAPTR query: <%s>, err: %s",
|
||||
utils.DNSAgent, req.Question[0].Name, err.Error()))
|
||||
rply.Rcode = dns.RcodeServerFailure
|
||||
dnsWriteMsg(w, rply)
|
||||
return
|
||||
}
|
||||
reqVars.Map[E164Address] = utils.NewLeafNode(e164)
|
||||
reqVars.Map[DomainName] = utils.NewLeafNode(domainNameFromNAPTR(req.Question[0].Name))
|
||||
}
|
||||
cgrRplyNM := &utils.DataNode{Type: utils.NMMapType, Map: make(map[string]*utils.DataNode)}
|
||||
rplyNM := utils.NewOrderedNavigableMap() // share it among different processors
|
||||
@@ -121,7 +104,7 @@ func (da *DNSAgent) handleMessage(w dns.ResponseWriter, req *dns.Msg) {
|
||||
var err error
|
||||
for _, reqProcessor := range da.cgrCfg.DNSAgentCfg().RequestProcessors {
|
||||
var lclProcessed bool
|
||||
lclProcessed, err = da.processRequest(
|
||||
lclProcessed, err = processRequest(
|
||||
reqProcessor,
|
||||
NewAgentRequest(
|
||||
dnsDP, reqVars, cgrRplyNM, rplyNM,
|
||||
@@ -129,7 +112,10 @@ func (da *DNSAgent) handleMessage(w dns.ResponseWriter, req *dns.Msg) {
|
||||
da.cgrCfg.GeneralCfg().DefaultTenant,
|
||||
utils.FirstNonEmpty(da.cgrCfg.DNSAgentCfg().Timezone,
|
||||
da.cgrCfg.GeneralCfg().DefaultTimezone),
|
||||
da.fltrS, nil))
|
||||
da.fltrS, nil),
|
||||
utils.DNSAgent, da.connMgr,
|
||||
da.cgrCfg.DNSAgentCfg().SessionSConns,
|
||||
nil, da.fltrS)
|
||||
if lclProcessed {
|
||||
processed = lclProcessed
|
||||
}
|
||||
@@ -169,186 +155,6 @@ func (da *DNSAgent) handleMessage(w dns.ResponseWriter, req *dns.Msg) {
|
||||
}
|
||||
}
|
||||
|
||||
func (da *DNSAgent) processRequest(reqProcessor *config.RequestProcessor,
|
||||
agReq *AgentRequest) (processed bool, err error) {
|
||||
if pass, err := da.fltrS.Pass(agReq.Tenant,
|
||||
reqProcessor.Filters, agReq); err != nil || !pass {
|
||||
return pass, err
|
||||
}
|
||||
if err = agReq.SetFields(reqProcessor.RequestFields); err != nil {
|
||||
return
|
||||
}
|
||||
cgrEv := utils.NMAsCGREvent(agReq.CGRRequest, agReq.Tenant, utils.NestingSep, agReq.Opts)
|
||||
var reqType string
|
||||
for _, typ := range []string{
|
||||
utils.MetaDryRun, utils.MetaAuthorize,
|
||||
utils.MetaInitiate, utils.MetaUpdate,
|
||||
utils.MetaTerminate, utils.MetaMessage,
|
||||
utils.MetaCDRs, utils.MetaEvent, utils.MetaNone} {
|
||||
if reqProcessor.Flags.Has(typ) { // request type is identified through flags
|
||||
reqType = typ
|
||||
break
|
||||
}
|
||||
}
|
||||
var cgrArgs utils.Paginator
|
||||
if reqType == utils.MetaAuthorize ||
|
||||
reqType == utils.MetaMessage ||
|
||||
reqType == utils.MetaEvent {
|
||||
if cgrArgs, err = utils.GetRoutePaginatorFromOpts(cgrEv.APIOpts); err != nil {
|
||||
utils.Logger.Warning(fmt.Sprintf("<%s> args extraction failed because <%s>",
|
||||
utils.DNSAgent, err.Error()))
|
||||
err = nil // reset the error and continue the processing
|
||||
}
|
||||
}
|
||||
if reqProcessor.Flags.Has(utils.MetaLog) {
|
||||
utils.Logger.Info(
|
||||
fmt.Sprintf("<%s> LOG, processorID: <%s>, message: %s",
|
||||
utils.DNSAgent, reqProcessor.ID, agReq.Request.String()))
|
||||
}
|
||||
switch reqType {
|
||||
default:
|
||||
return false, fmt.Errorf("unknown request type: <%s>", reqType)
|
||||
case utils.MetaNone: // do nothing on CGRateS side
|
||||
case utils.MetaDryRun:
|
||||
utils.Logger.Info(
|
||||
fmt.Sprintf("<%s> DRY_RUN, processorID: %s, CGREvent: %s",
|
||||
utils.DNSAgent, reqProcessor.ID, utils.ToJSON(cgrEv)))
|
||||
case utils.MetaAuthorize:
|
||||
authArgs := sessions.NewV1AuthorizeArgs(
|
||||
reqProcessor.Flags.GetBool(utils.MetaAttributes),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaAttributes, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaThresholds),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaThresholds, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaStats),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaStats, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaResources),
|
||||
reqProcessor.Flags.Has(utils.MetaAccounts),
|
||||
reqProcessor.Flags.GetBool(utils.MetaRoutes),
|
||||
reqProcessor.Flags.Has(utils.MetaRoutesIgnoreErrors),
|
||||
reqProcessor.Flags.Has(utils.MetaRoutesEventCost),
|
||||
cgrEv, cgrArgs, reqProcessor.Flags.Has(utils.MetaFD),
|
||||
reqProcessor.Flags.ParamValue(utils.MetaRoutesMaxCost),
|
||||
)
|
||||
rply := new(sessions.V1AuthorizeReply)
|
||||
err = da.connMgr.Call(da.cgrCfg.DNSAgentCfg().SessionSConns, nil,
|
||||
utils.SessionSv1AuthorizeEvent,
|
||||
authArgs, rply)
|
||||
rply.SetMaxUsageNeeded(authArgs.GetMaxUsage)
|
||||
agReq.setCGRReply(rply, err)
|
||||
case utils.MetaInitiate:
|
||||
initArgs := sessions.NewV1InitSessionArgs(
|
||||
reqProcessor.Flags.GetBool(utils.MetaAttributes),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaAttributes, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaThresholds),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaThresholds, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaStats),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaStats, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaResources),
|
||||
reqProcessor.Flags.Has(utils.MetaAccounts),
|
||||
cgrEv, reqProcessor.Flags.Has(utils.MetaFD))
|
||||
rply := new(sessions.V1InitSessionReply)
|
||||
err = da.connMgr.Call(da.cgrCfg.DNSAgentCfg().SessionSConns, nil,
|
||||
utils.SessionSv1InitiateSession,
|
||||
initArgs, rply)
|
||||
rply.SetMaxUsageNeeded(initArgs.InitSession)
|
||||
agReq.setCGRReply(rply, err)
|
||||
case utils.MetaUpdate:
|
||||
updateArgs := sessions.NewV1UpdateSessionArgs(
|
||||
reqProcessor.Flags.GetBool(utils.MetaAttributes),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaAttributes, utils.MetaIDs),
|
||||
reqProcessor.Flags.Has(utils.MetaAccounts),
|
||||
cgrEv, reqProcessor.Flags.Has(utils.MetaFD))
|
||||
rply := new(sessions.V1UpdateSessionReply)
|
||||
err = da.connMgr.Call(da.cgrCfg.DNSAgentCfg().SessionSConns, nil,
|
||||
utils.SessionSv1UpdateSession,
|
||||
updateArgs, rply)
|
||||
rply.SetMaxUsageNeeded(updateArgs.UpdateSession)
|
||||
agReq.setCGRReply(rply, err)
|
||||
case utils.MetaTerminate:
|
||||
terminateArgs := sessions.NewV1TerminateSessionArgs(
|
||||
reqProcessor.Flags.Has(utils.MetaAccounts),
|
||||
reqProcessor.Flags.GetBool(utils.MetaResources),
|
||||
reqProcessor.Flags.GetBool(utils.MetaThresholds),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaThresholds, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaStats),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaStats, utils.MetaIDs),
|
||||
cgrEv, reqProcessor.Flags.Has(utils.MetaFD))
|
||||
var rply string
|
||||
err = da.connMgr.Call(da.cgrCfg.DNSAgentCfg().SessionSConns, nil,
|
||||
utils.SessionSv1TerminateSession,
|
||||
terminateArgs, &rply)
|
||||
agReq.setCGRReply(nil, err)
|
||||
case utils.MetaMessage:
|
||||
evArgs := sessions.NewV1ProcessMessageArgs(
|
||||
reqProcessor.Flags.GetBool(utils.MetaAttributes),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaAttributes, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaThresholds),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaThresholds, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaStats),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaStats, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaResources),
|
||||
reqProcessor.Flags.Has(utils.MetaAccounts),
|
||||
reqProcessor.Flags.GetBool(utils.MetaRoutes),
|
||||
reqProcessor.Flags.Has(utils.MetaRoutesIgnoreErrors),
|
||||
reqProcessor.Flags.Has(utils.MetaRoutesEventCost),
|
||||
cgrEv, cgrArgs, reqProcessor.Flags.Has(utils.MetaFD),
|
||||
reqProcessor.Flags.ParamValue(utils.MetaRoutesMaxCost),
|
||||
)
|
||||
rply := new(sessions.V1ProcessMessageReply) // need it so rpcclient can clone
|
||||
err = da.connMgr.Call(da.cgrCfg.DNSAgentCfg().SessionSConns, nil,
|
||||
utils.SessionSv1ProcessMessage,
|
||||
evArgs, rply)
|
||||
if utils.ErrHasPrefix(err, utils.RalsErrorPrfx) {
|
||||
cgrEv.Event[utils.Usage] = 0 // avoid further debits
|
||||
} else if evArgs.Debit {
|
||||
cgrEv.Event[utils.Usage] = rply.MaxUsage // make sure the CDR reflects the debit
|
||||
}
|
||||
rply.SetMaxUsageNeeded(evArgs.Debit)
|
||||
agReq.setCGRReply(rply, err)
|
||||
case utils.MetaEvent:
|
||||
evArgs := &sessions.V1ProcessEventArgs{
|
||||
Flags: reqProcessor.Flags.SliceFlags(),
|
||||
CGREvent: cgrEv,
|
||||
Paginator: cgrArgs,
|
||||
}
|
||||
rply := new(sessions.V1ProcessEventReply)
|
||||
err = da.connMgr.Call(da.cgrCfg.DNSAgentCfg().SessionSConns, nil,
|
||||
utils.SessionSv1ProcessEvent,
|
||||
evArgs, rply)
|
||||
if utils.ErrHasPrefix(err, utils.RalsErrorPrfx) {
|
||||
cgrEv.Event[utils.Usage] = 0 // avoid further debits
|
||||
} else if needsMaxUsage(reqProcessor.Flags[utils.MetaRALs]) {
|
||||
cgrEv.Event[utils.Usage] = rply.MaxUsage // make sure the CDR reflects the debit
|
||||
}
|
||||
agReq.setCGRReply(rply, err)
|
||||
case utils.MetaCDRs: // allow CDR processing
|
||||
}
|
||||
// separate request so we can capture the Terminate/Event also here
|
||||
if reqProcessor.Flags.GetBool(utils.MetaCDRs) &&
|
||||
!reqProcessor.Flags.Has(utils.MetaDryRun) {
|
||||
var rplyCDRs string
|
||||
if err = da.connMgr.Call(da.cgrCfg.DNSAgentCfg().SessionSConns, nil,
|
||||
utils.SessionSv1ProcessCDR,
|
||||
cgrEv, &rplyCDRs); err != nil {
|
||||
agReq.CGRReply.Map[utils.Error] = utils.NewLeafNode(err.Error())
|
||||
}
|
||||
}
|
||||
if err := agReq.SetFields(reqProcessor.ReplyFields); err != nil {
|
||||
return false, err
|
||||
}
|
||||
if reqProcessor.Flags.Has(utils.MetaLog) {
|
||||
utils.Logger.Info(
|
||||
fmt.Sprintf("<%s> LOG, reply: %s",
|
||||
utils.DNSAgent, agReq.Reply))
|
||||
}
|
||||
if reqType == utils.MetaDryRun {
|
||||
utils.Logger.Info(
|
||||
fmt.Sprintf("<%s> DRY_RUN, reply: %s",
|
||||
utils.DNSAgent, agReq.Reply))
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// Shutdown stops the DNS server
|
||||
func (da *DNSAgent) Shutdown() error {
|
||||
return da.server.Shutdown()
|
||||
|
||||
@@ -24,7 +24,6 @@ import (
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/sessions"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
@@ -73,7 +72,9 @@ func (ha *HTTPAgent) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
utils.FirstNonEmpty(reqProcessor.Timezone,
|
||||
config.CgrConfig().GeneralCfg().DefaultTimezone),
|
||||
ha.filterS, nil)
|
||||
lclProcessed, err := ha.processRequest(reqProcessor, agReq)
|
||||
lclProcessed, err := processRequest(reqProcessor, agReq,
|
||||
utils.HTTPAgent, ha.connMgr, ha.sessionConns,
|
||||
nil, agReq.filterS)
|
||||
if err != nil {
|
||||
utils.Logger.Warning(
|
||||
fmt.Sprintf("<%s> error: %s processing request: %s",
|
||||
@@ -101,177 +102,3 @@ func (ha *HTTPAgent) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// processRequest represents one processor processing the request
|
||||
func (ha *HTTPAgent) processRequest(reqProcessor *config.RequestProcessor,
|
||||
agReq *AgentRequest) (processed bool, err error) {
|
||||
if pass, err := ha.filterS.Pass(agReq.Tenant,
|
||||
reqProcessor.Filters, agReq); err != nil || !pass {
|
||||
return pass, err
|
||||
}
|
||||
if err = agReq.SetFields(reqProcessor.RequestFields); err != nil {
|
||||
return
|
||||
}
|
||||
cgrEv := utils.NMAsCGREvent(agReq.CGRRequest, agReq.Tenant, utils.NestingSep, agReq.Opts)
|
||||
var reqType string
|
||||
for _, typ := range []string{
|
||||
utils.MetaDryRun, utils.MetaAuthorize,
|
||||
utils.MetaInitiate, utils.MetaUpdate,
|
||||
utils.MetaTerminate, utils.MetaMessage,
|
||||
utils.MetaCDRs, utils.MetaEvent, utils.MetaEmpty} {
|
||||
if reqProcessor.Flags.Has(typ) { // request type is identified through flags
|
||||
reqType = typ
|
||||
break
|
||||
}
|
||||
}
|
||||
var cgrArgs utils.Paginator
|
||||
if reqType == utils.MetaAuthorize ||
|
||||
reqType == utils.MetaMessage ||
|
||||
reqType == utils.MetaEvent {
|
||||
if cgrArgs, err = utils.GetRoutePaginatorFromOpts(cgrEv.APIOpts); err != nil {
|
||||
utils.Logger.Warning(fmt.Sprintf("<%s> args extraction failed because <%s>",
|
||||
utils.HTTPAgent, err.Error()))
|
||||
err = nil // reset the error and continue the processing
|
||||
}
|
||||
}
|
||||
if reqProcessor.Flags.Has(utils.MetaLog) {
|
||||
utils.Logger.Info(
|
||||
fmt.Sprintf("<%s> LOG, processorID: %s, http message: %s",
|
||||
utils.HTTPAgent, reqProcessor.ID, agReq.Request.String()))
|
||||
}
|
||||
switch reqType {
|
||||
default:
|
||||
return false, fmt.Errorf("unknown request type: <%s>", reqType)
|
||||
case utils.MetaNone: // do nothing on CGRateS side
|
||||
case utils.MetaDryRun:
|
||||
utils.Logger.Info(
|
||||
fmt.Sprintf("<%s> DRY_RUN, processorID: %s, CGREvent: %s",
|
||||
utils.HTTPAgent, reqProcessor.ID, utils.ToJSON(cgrEv)))
|
||||
case utils.MetaAuthorize:
|
||||
authArgs := sessions.NewV1AuthorizeArgs(
|
||||
reqProcessor.Flags.GetBool(utils.MetaAttributes),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaAttributes, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaThresholds),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaThresholds, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaStats),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaStats, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaResources),
|
||||
reqProcessor.Flags.Has(utils.MetaAccounts),
|
||||
reqProcessor.Flags.GetBool(utils.MetaRoutes),
|
||||
reqProcessor.Flags.Has(utils.MetaRoutesIgnoreErrors),
|
||||
reqProcessor.Flags.Has(utils.MetaRoutesEventCost),
|
||||
cgrEv, cgrArgs, reqProcessor.Flags.Has(utils.MetaFD),
|
||||
reqProcessor.Flags.ParamValue(utils.MetaRoutesMaxCost),
|
||||
)
|
||||
rply := new(sessions.V1AuthorizeReply)
|
||||
err = ha.connMgr.Call(ha.sessionConns, nil, utils.SessionSv1AuthorizeEvent,
|
||||
authArgs, rply)
|
||||
rply.SetMaxUsageNeeded(authArgs.GetMaxUsage)
|
||||
agReq.setCGRReply(rply, err)
|
||||
case utils.MetaInitiate:
|
||||
initArgs := sessions.NewV1InitSessionArgs(
|
||||
reqProcessor.Flags.GetBool(utils.MetaAttributes),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaAttributes, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaThresholds),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaThresholds, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaStats),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaStats, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaResources),
|
||||
reqProcessor.Flags.Has(utils.MetaAccounts),
|
||||
cgrEv, reqProcessor.Flags.Has(utils.MetaFD))
|
||||
rply := new(sessions.V1InitSessionReply)
|
||||
err = ha.connMgr.Call(ha.sessionConns, nil, utils.SessionSv1InitiateSession,
|
||||
initArgs, rply)
|
||||
rply.SetMaxUsageNeeded(initArgs.InitSession)
|
||||
agReq.setCGRReply(rply, err)
|
||||
case utils.MetaUpdate:
|
||||
updateArgs := sessions.NewV1UpdateSessionArgs(
|
||||
reqProcessor.Flags.GetBool(utils.MetaAttributes),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaAttributes, utils.MetaIDs),
|
||||
reqProcessor.Flags.Has(utils.MetaAccounts),
|
||||
cgrEv, reqProcessor.Flags.Has(utils.MetaFD))
|
||||
rply := new(sessions.V1UpdateSessionReply)
|
||||
err = ha.connMgr.Call(ha.sessionConns, nil, utils.SessionSv1UpdateSession,
|
||||
updateArgs, rply)
|
||||
rply.SetMaxUsageNeeded(updateArgs.UpdateSession)
|
||||
agReq.setCGRReply(rply, err)
|
||||
case utils.MetaTerminate:
|
||||
terminateArgs := sessions.NewV1TerminateSessionArgs(
|
||||
reqProcessor.Flags.Has(utils.MetaAccounts),
|
||||
reqProcessor.Flags.GetBool(utils.MetaResources),
|
||||
reqProcessor.Flags.GetBool(utils.MetaThresholds),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaThresholds, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaStats),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaStats, utils.MetaIDs),
|
||||
cgrEv, reqProcessor.Flags.Has(utils.MetaFD))
|
||||
var rply string
|
||||
err = ha.connMgr.Call(ha.sessionConns, nil, utils.SessionSv1TerminateSession,
|
||||
terminateArgs, &rply)
|
||||
agReq.setCGRReply(nil, err)
|
||||
case utils.MetaMessage:
|
||||
evArgs := sessions.NewV1ProcessMessageArgs(
|
||||
reqProcessor.Flags.GetBool(utils.MetaAttributes),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaAttributes, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaThresholds),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaThresholds, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaStats),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaStats, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaResources),
|
||||
reqProcessor.Flags.Has(utils.MetaAccounts),
|
||||
reqProcessor.Flags.GetBool(utils.MetaRoutes),
|
||||
reqProcessor.Flags.Has(utils.MetaRoutesIgnoreErrors),
|
||||
reqProcessor.Flags.Has(utils.MetaRoutesEventCost),
|
||||
cgrEv, cgrArgs, reqProcessor.Flags.Has(utils.MetaFD),
|
||||
reqProcessor.Flags.ParamValue(utils.MetaRoutesMaxCost),
|
||||
)
|
||||
rply := new(sessions.V1ProcessMessageReply)
|
||||
err = ha.connMgr.Call(ha.sessionConns, nil, utils.SessionSv1ProcessMessage,
|
||||
evArgs, rply)
|
||||
if utils.ErrHasPrefix(err, utils.RalsErrorPrfx) {
|
||||
cgrEv.Event[utils.Usage] = 0 // avoid further debits
|
||||
} else if evArgs.Debit {
|
||||
cgrEv.Event[utils.Usage] = rply.MaxUsage // make sure the CDR reflects the debit
|
||||
}
|
||||
rply.SetMaxUsageNeeded(evArgs.Debit)
|
||||
agReq.setCGRReply(nil, err)
|
||||
case utils.MetaEvent:
|
||||
evArgs := &sessions.V1ProcessEventArgs{
|
||||
Flags: reqProcessor.Flags.SliceFlags(),
|
||||
CGREvent: cgrEv,
|
||||
Paginator: cgrArgs,
|
||||
}
|
||||
rply := new(sessions.V1ProcessEventReply)
|
||||
err = ha.connMgr.Call(ha.sessionConns, nil, utils.SessionSv1ProcessEvent,
|
||||
evArgs, rply)
|
||||
if utils.ErrHasPrefix(err, utils.RalsErrorPrfx) {
|
||||
cgrEv.Event[utils.Usage] = 0 // avoid further debits
|
||||
} else if needsMaxUsage(reqProcessor.Flags[utils.MetaRALs]) {
|
||||
cgrEv.Event[utils.Usage] = rply.MaxUsage // make sure the CDR reflects the debit
|
||||
}
|
||||
agReq.setCGRReply(rply, err)
|
||||
case utils.MetaCDRs: // allow CDR processing
|
||||
}
|
||||
// separate request so we can capture the Terminate/Event also here
|
||||
if reqProcessor.Flags.GetBool(utils.MetaCDRs) &&
|
||||
!reqProcessor.Flags.Has(utils.MetaDryRun) {
|
||||
var rplyCDRs string
|
||||
if err = ha.connMgr.Call(ha.sessionConns, nil, utils.SessionSv1ProcessCDR,
|
||||
cgrEv, &rplyCDRs); err != nil {
|
||||
agReq.CGRReply.Map[utils.Error] = utils.NewLeafNode(err.Error())
|
||||
}
|
||||
}
|
||||
if err := agReq.SetFields(reqProcessor.ReplyFields); err != nil {
|
||||
return false, err
|
||||
}
|
||||
if reqProcessor.Flags.Has(utils.MetaLog) {
|
||||
utils.Logger.Info(
|
||||
fmt.Sprintf("<%s> LOG, HTTP reply: %s",
|
||||
utils.HTTPAgent, agReq.Reply))
|
||||
}
|
||||
if reqType == utils.MetaDryRun {
|
||||
utils.Logger.Info(
|
||||
fmt.Sprintf("<%s> DRY_RUN, HTTP reply: %s",
|
||||
utils.HTTPAgent, agReq.Reply))
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
204
agents/libagents.go
Normal file
204
agents/libagents.go
Normal file
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
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/engine"
|
||||
"github.com/cgrates/cgrates/sessions"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"github.com/cgrates/rpcclient"
|
||||
)
|
||||
|
||||
func processRequest(reqProcessor *config.RequestProcessor, agReq *AgentRequest,
|
||||
agentName string, connMgr *engine.ConnManager, sessionsConns []string,
|
||||
aConn rpcclient.BiRPCConector, filterS *engine.FilterS) (processed bool, err error) {
|
||||
if pass, err := filterS.Pass(agReq.Tenant,
|
||||
reqProcessor.Filters, agReq); err != nil || !pass {
|
||||
return pass, err
|
||||
}
|
||||
if err = agReq.SetFields(reqProcessor.RequestFields); err != nil {
|
||||
return
|
||||
}
|
||||
cgrEv := utils.NMAsCGREvent(agReq.CGRRequest, agReq.Tenant, utils.NestingSep, agReq.Opts)
|
||||
var reqType string
|
||||
for _, typ := range []string{
|
||||
utils.MetaDryRun, utils.MetaAuthorize,
|
||||
utils.MetaInitiate, utils.MetaUpdate,
|
||||
utils.MetaTerminate, utils.MetaMessage,
|
||||
utils.MetaCDRs, utils.MetaEvent, utils.MetaNone} {
|
||||
if reqProcessor.Flags.Has(typ) { // request type is identified through flags
|
||||
reqType = typ
|
||||
break
|
||||
}
|
||||
}
|
||||
var cgrArgs utils.Paginator
|
||||
if reqType == utils.MetaAuthorize || reqType == utils.MetaMessage || reqType == utils.MetaEvent {
|
||||
if cgrArgs, err = utils.GetRoutePaginatorFromOpts(cgrEv.APIOpts); err != nil {
|
||||
utils.Logger.Warning(fmt.Sprintf("<%s> args extraction failed because <%s>",
|
||||
agentName, err.Error()))
|
||||
err = nil // reset the error and continue the processing
|
||||
}
|
||||
}
|
||||
|
||||
if reqProcessor.Flags.Has(utils.MetaLog) {
|
||||
utils.Logger.Info(
|
||||
fmt.Sprintf("<%s> LOG, processorID: %s, diameter message: %s",
|
||||
agentName, reqProcessor.ID, agReq.Request.String()))
|
||||
}
|
||||
switch reqType {
|
||||
default:
|
||||
return false, fmt.Errorf("unknown request type: <%s>", reqType)
|
||||
case utils.MetaNone: // do nothing on CGRateS side
|
||||
case utils.MetaDryRun:
|
||||
utils.Logger.Info(
|
||||
fmt.Sprintf("<%s> DRY_RUN, processorID: %s, DiameterMessage: %s",
|
||||
agentName, reqProcessor.ID, agReq.Request.String()))
|
||||
case utils.MetaAuthorize:
|
||||
authArgs := sessions.NewV1AuthorizeArgs(
|
||||
reqProcessor.Flags.GetBool(utils.MetaAttributes),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaAttributes, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaThresholds),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaThresholds, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaStats),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaStats, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaResources),
|
||||
reqProcessor.Flags.Has(utils.MetaAccounts),
|
||||
reqProcessor.Flags.GetBool(utils.MetaRoutes),
|
||||
reqProcessor.Flags.Has(utils.MetaRoutesIgnoreErrors),
|
||||
reqProcessor.Flags.Has(utils.MetaRoutesEventCost),
|
||||
cgrEv, cgrArgs,
|
||||
reqProcessor.Flags.Has(utils.MetaFD),
|
||||
reqProcessor.Flags.ParamValue(utils.MetaRoutesMaxCost),
|
||||
)
|
||||
rply := new(sessions.V1AuthorizeReply)
|
||||
err = connMgr.Call(sessionsConns, aConn, utils.SessionSv1AuthorizeEvent,
|
||||
authArgs, rply)
|
||||
rply.SetMaxUsageNeeded(authArgs.GetMaxUsage)
|
||||
agReq.setCGRReply(rply, err)
|
||||
case utils.MetaInitiate:
|
||||
initArgs := sessions.NewV1InitSessionArgs(
|
||||
reqProcessor.Flags.GetBool(utils.MetaAttributes),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaAttributes, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaThresholds),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaThresholds, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaStats),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaStats, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaResources),
|
||||
reqProcessor.Flags.Has(utils.MetaAccounts),
|
||||
cgrEv, reqProcessor.Flags.Has(utils.MetaFD))
|
||||
rply := new(sessions.V1InitSessionReply)
|
||||
err = connMgr.Call(sessionsConns, aConn, utils.SessionSv1InitiateSession,
|
||||
initArgs, rply)
|
||||
rply.SetMaxUsageNeeded(initArgs.InitSession)
|
||||
agReq.setCGRReply(rply, err)
|
||||
case utils.MetaUpdate:
|
||||
updateArgs := sessions.NewV1UpdateSessionArgs(
|
||||
reqProcessor.Flags.GetBool(utils.MetaAttributes),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaAttributes, utils.MetaIDs),
|
||||
reqProcessor.Flags.Has(utils.MetaAccounts),
|
||||
cgrEv, reqProcessor.Flags.Has(utils.MetaFD))
|
||||
rply := new(sessions.V1UpdateSessionReply)
|
||||
rply.SetMaxUsageNeeded(updateArgs.UpdateSession)
|
||||
err = connMgr.Call(sessionsConns, aConn, utils.SessionSv1UpdateSession,
|
||||
updateArgs, rply)
|
||||
agReq.setCGRReply(rply, err)
|
||||
case utils.MetaTerminate:
|
||||
terminateArgs := sessions.NewV1TerminateSessionArgs(
|
||||
reqProcessor.Flags.Has(utils.MetaAccounts),
|
||||
reqProcessor.Flags.GetBool(utils.MetaResources),
|
||||
reqProcessor.Flags.GetBool(utils.MetaThresholds),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaThresholds, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaStats),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaStats, utils.MetaIDs),
|
||||
cgrEv, reqProcessor.Flags.Has(utils.MetaFD))
|
||||
var rply string
|
||||
err = connMgr.Call(sessionsConns, aConn, utils.SessionSv1TerminateSession,
|
||||
terminateArgs, &rply)
|
||||
agReq.setCGRReply(nil, err)
|
||||
case utils.MetaMessage:
|
||||
msgArgs := sessions.NewV1ProcessMessageArgs(
|
||||
reqProcessor.Flags.GetBool(utils.MetaAttributes),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaAttributes, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaThresholds),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaThresholds, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaStats),
|
||||
reqProcessor.Flags.ParamsSlice(utils.MetaStats, utils.MetaIDs),
|
||||
reqProcessor.Flags.GetBool(utils.MetaResources),
|
||||
reqProcessor.Flags.Has(utils.MetaAccounts),
|
||||
reqProcessor.Flags.GetBool(utils.MetaRoutes),
|
||||
reqProcessor.Flags.Has(utils.MetaRoutesIgnoreErrors),
|
||||
reqProcessor.Flags.Has(utils.MetaRoutesEventCost),
|
||||
cgrEv, cgrArgs,
|
||||
reqProcessor.Flags.Has(utils.MetaFD),
|
||||
reqProcessor.Flags.ParamValue(utils.MetaRoutesMaxCost),
|
||||
)
|
||||
rply := new(sessions.V1ProcessMessageReply)
|
||||
err = connMgr.Call(sessionsConns, aConn, utils.SessionSv1ProcessMessage,
|
||||
msgArgs, rply)
|
||||
if utils.ErrHasPrefix(err, utils.RalsErrorPrfx) {
|
||||
cgrEv.Event[utils.Usage] = 0 // avoid further debits
|
||||
} else if msgArgs.Debit {
|
||||
cgrEv.Event[utils.Usage] = rply.MaxUsage // make sure the CDR reflects the debit
|
||||
}
|
||||
rply.SetMaxUsageNeeded(msgArgs.Debit)
|
||||
agReq.setCGRReply(rply, err)
|
||||
case utils.MetaEvent:
|
||||
evArgs := &sessions.V1ProcessEventArgs{
|
||||
Flags: reqProcessor.Flags.SliceFlags(),
|
||||
Paginator: cgrArgs,
|
||||
CGREvent: cgrEv,
|
||||
}
|
||||
rply := new(sessions.V1ProcessEventReply)
|
||||
err = connMgr.Call(sessionsConns, aConn, utils.SessionSv1ProcessEvent,
|
||||
evArgs, rply)
|
||||
if utils.ErrHasPrefix(err, utils.RalsErrorPrfx) {
|
||||
cgrEv.Event[utils.Usage] = 0 // avoid further debits
|
||||
} else if needsMaxUsage(reqProcessor.Flags[utils.MetaRALs]) {
|
||||
cgrEv.Event[utils.Usage] = rply.MaxUsage // make sure the CDR reflects the debit
|
||||
}
|
||||
agReq.setCGRReply(rply, err)
|
||||
case utils.MetaCDRs: // allow CDR processing
|
||||
}
|
||||
// separate request so we can capture the Terminate/Event also here
|
||||
if reqProcessor.Flags.GetBool(utils.MetaCDRs) &&
|
||||
!reqProcessor.Flags.Has(utils.MetaDryRun) {
|
||||
var rplyCDRs string
|
||||
if err = connMgr.Call(sessionsConns, aConn, utils.SessionSv1ProcessCDR,
|
||||
cgrEv, &rplyCDRs); err != nil {
|
||||
agReq.CGRReply.Map[utils.Error] = utils.NewLeafNode(err.Error())
|
||||
}
|
||||
}
|
||||
if err = agReq.SetFields(reqProcessor.ReplyFields); err != nil {
|
||||
return
|
||||
}
|
||||
if reqProcessor.Flags.Has(utils.MetaLog) {
|
||||
utils.Logger.Info(
|
||||
fmt.Sprintf("<%s> LOG, Diameter reply: %s",
|
||||
agentName, agReq.Reply))
|
||||
}
|
||||
if reqType == utils.MetaDryRun {
|
||||
utils.Logger.Info(
|
||||
fmt.Sprintf("<%s> DRY_RUN, Diameter reply: %s",
|
||||
agentName, agReq.Reply))
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
757
agents/libdns.go
757
agents/libdns.go
@@ -19,93 +19,22 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package agents
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
const (
|
||||
QueryType = "QueryType"
|
||||
E164Address = "E164Address"
|
||||
QueryName = "QueryName"
|
||||
DomainName = "DomainName"
|
||||
QueryType = "QueryType"
|
||||
QueryName = "QueryName"
|
||||
dnsOption = "Option"
|
||||
)
|
||||
|
||||
// e164FromNAPTR extracts the E164 address out of a NAPTR name record
|
||||
func e164FromNAPTR(name string) (e164 string, err error) {
|
||||
i := strings.Index(name, ".e164.")
|
||||
if i == -1 {
|
||||
return "", errors.New("unknown format")
|
||||
}
|
||||
e164 = utils.ReverseString(
|
||||
strings.Replace(name[:i], ".", "", -1))
|
||||
return
|
||||
}
|
||||
|
||||
// domainNameFromNAPTR extracts the domain part out of a NAPTR name record
|
||||
func domainNameFromNAPTR(name string) (dName string) {
|
||||
i := strings.Index(name, ".e164.")
|
||||
if i == -1 {
|
||||
dName = name
|
||||
} else {
|
||||
dName = name[i:]
|
||||
}
|
||||
return strings.Trim(dName, ".")
|
||||
}
|
||||
|
||||
// newDADataProvider constructs a DataProvider for a diameter message
|
||||
func newDNSDataProvider(req *dns.Msg,
|
||||
w dns.ResponseWriter) utils.DataProvider {
|
||||
return &dnsDP{req: req, w: w,
|
||||
cache: utils.MapStorage{}}
|
||||
}
|
||||
|
||||
// dnsDP implements engien.DataProvider, serving as dns.Msg decoder
|
||||
// cache is used to cache queries within the message
|
||||
type dnsDP struct {
|
||||
req *dns.Msg
|
||||
w dns.ResponseWriter
|
||||
cache utils.MapStorage
|
||||
}
|
||||
|
||||
// String is part of utils.DataProvider interface
|
||||
// when called, it will display the already parsed values out of cache
|
||||
func (dP *dnsDP) String() string {
|
||||
return utils.ToJSON(dP.req)
|
||||
}
|
||||
|
||||
// FieldAsString is part of utils.DataProvider interface
|
||||
func (dP *dnsDP) FieldAsString(fldPath []string) (data string, err error) {
|
||||
var valIface interface{}
|
||||
valIface, err = dP.FieldAsInterface(fldPath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return utils.IfaceAsString(valIface), nil
|
||||
}
|
||||
|
||||
// FieldAsInterface is part of utils.DataProvider interface
|
||||
func (dP *dnsDP) FieldAsInterface(fldPath []string) (data interface{}, err error) {
|
||||
if data, err = dP.cache.FieldAsInterface(fldPath); err != nil {
|
||||
if err != utils.ErrNotFound { // item found in cache
|
||||
return nil, err
|
||||
}
|
||||
err = nil // cancel previous err
|
||||
} else {
|
||||
return // data was found in cache
|
||||
}
|
||||
data = ""
|
||||
// Return Question[0] by default
|
||||
if len(dP.req.Question) != 0 {
|
||||
data = dP.req.Question[0]
|
||||
}
|
||||
dP.cache.Set(fldPath, data)
|
||||
return
|
||||
}
|
||||
|
||||
// dnsWriteErr writes the error with code back to the client
|
||||
func dnsWriteMsg(w dns.ResponseWriter, msg *dns.Msg) (err error) {
|
||||
if err = w.WriteMsg(msg); err != nil {
|
||||
@@ -145,73 +74,643 @@ func appendDNSAnswer(msg *dns.Msg) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// updateDNSMsgFromNM will update DNS message with values from NavigableMap
|
||||
func newDnsDP(req *dns.Msg) utils.DataProvider {
|
||||
var opts interface{}
|
||||
if o := req.IsEdns0(); o != nil {
|
||||
opts = o
|
||||
}
|
||||
return &dnsDP{
|
||||
req: config.NewObjectDP(req),
|
||||
opts: config.NewObjectDP(opts),
|
||||
}
|
||||
}
|
||||
|
||||
type dnsDP struct {
|
||||
req utils.DataProvider
|
||||
opts utils.DataProvider
|
||||
}
|
||||
|
||||
func (dp dnsDP) String() string { return dp.req.String() }
|
||||
func (dp dnsDP) FieldAsInterface(fldPath []string) (interface{}, error) {
|
||||
if len(fldPath) != 0 && fldPath[0] == dnsOption {
|
||||
return dp.opts.FieldAsInterface(fldPath[1:])
|
||||
}
|
||||
return dp.req.FieldAsInterface(fldPath)
|
||||
}
|
||||
func (dp dnsDP) FieldAsString(fldPath []string) (string, error) {
|
||||
valIface, err := dp.FieldAsInterface(fldPath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return utils.IfaceAsString(valIface), nil
|
||||
}
|
||||
|
||||
func updateDNSMsgFromNM(msg *dns.Msg, nm *utils.OrderedNavigableMap) (err error) {
|
||||
msgFields := make(utils.StringSet) // work around to NMap issue
|
||||
for el := nm.GetFirstElement(); el != nil; el = el.Next() {
|
||||
path := el.Value
|
||||
cfgItm, _ := nm.Field(path)
|
||||
// path = path[:len(path)-1] // no need to remove the last index here as this uses only the first level
|
||||
apnd := len(msg.Answer) == 0
|
||||
if msgFields.Has(path[0]) { // force append if the same path was already used
|
||||
apnd = true
|
||||
}
|
||||
if apnd {
|
||||
if err = appendDNSAnswer(msg); err != nil {
|
||||
return
|
||||
itm, _ := nm.Field(path)
|
||||
switch path[0] { // go for each posible field
|
||||
case utils.Id:
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(itm.Data); err != nil {
|
||||
return fmt.Errorf("item: <%s>, err: %s", path[0], err.Error())
|
||||
}
|
||||
msgFields = make(utils.StringSet) // reset the fields inside since we have a new message
|
||||
}
|
||||
itmData := cfgItm.Data
|
||||
switch path[0] {
|
||||
msg.Id = uint16(vItm)
|
||||
case utils.Response:
|
||||
var vItm bool
|
||||
if vItm, err = utils.IfaceAsBool(itm.Data); err != nil {
|
||||
return fmt.Errorf("item: <%s>, err: %s", path[0], err.Error())
|
||||
}
|
||||
msg.Response = vItm
|
||||
case utils.Opcode:
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(itm.Data); err != nil {
|
||||
return fmt.Errorf("item: <%s>, err: %s", path[0], err.Error())
|
||||
}
|
||||
msg.Opcode = int(vItm)
|
||||
case utils.Authoritative:
|
||||
var vItm bool
|
||||
if vItm, err = utils.IfaceAsBool(itm.Data); err != nil {
|
||||
return fmt.Errorf("item: <%s>, err: %s", path[0], err.Error())
|
||||
}
|
||||
msg.Authoritative = vItm
|
||||
case utils.Truncated:
|
||||
var vItm bool
|
||||
if vItm, err = utils.IfaceAsBool(itm.Data); err != nil {
|
||||
return fmt.Errorf("item: <%s>, err: %s", path[0], err.Error())
|
||||
}
|
||||
msg.Truncated = vItm
|
||||
case utils.RecursionDesired:
|
||||
var vItm bool
|
||||
if vItm, err = utils.IfaceAsBool(itm.Data); err != nil {
|
||||
return fmt.Errorf("item: <%s>, err: %s", path[0], err.Error())
|
||||
}
|
||||
msg.RecursionDesired = vItm
|
||||
case utils.RecursionAvailable:
|
||||
var vItm bool
|
||||
if vItm, err = utils.IfaceAsBool(itm.Data); err != nil {
|
||||
return fmt.Errorf("item: <%s>, err: %s", path[0], err.Error())
|
||||
}
|
||||
msg.RecursionAvailable = vItm
|
||||
case utils.Zero:
|
||||
var vItm bool
|
||||
if vItm, err = utils.IfaceAsBool(itm.Data); err != nil {
|
||||
return fmt.Errorf("item: <%s>, err: %s", path[0], err.Error())
|
||||
}
|
||||
msg.Zero = vItm
|
||||
case utils.AuthenticatedData:
|
||||
var vItm bool
|
||||
if vItm, err = utils.IfaceAsBool(itm.Data); err != nil {
|
||||
return fmt.Errorf("item: <%s>, err: %s", path[0], err.Error())
|
||||
}
|
||||
msg.AuthenticatedData = vItm
|
||||
case utils.CheckingDisabled:
|
||||
var vItm bool
|
||||
if vItm, err = utils.IfaceAsBool(itm.Data); err != nil {
|
||||
return fmt.Errorf("item: <%s>, err: %s", path[0], err.Error())
|
||||
}
|
||||
msg.CheckingDisabled = vItm
|
||||
case utils.Rcode:
|
||||
var itm int64
|
||||
if itm, err = utils.IfaceAsInt64(itmData); err != nil {
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(itm.Data); err != nil {
|
||||
return fmt.Errorf("item: <%s>, err: %s", path[0], err.Error())
|
||||
}
|
||||
msg.Rcode = int(itm)
|
||||
case utils.Order:
|
||||
if msg.Question[0].Qtype != dns.TypeNAPTR {
|
||||
return fmt.Errorf("field <%s> only works with NAPTR", utils.Order)
|
||||
msg.Rcode = int(vItm)
|
||||
case utils.Question:
|
||||
if msg.Question, err = updateDnsQuestions(msg.Question, path[1:len(path)-1], itm.Data, itm.NewBranch); err != nil {
|
||||
return fmt.Errorf("item: <%s>, err: %s", path[:len(path)-1], err.Error())
|
||||
}
|
||||
var itm int64
|
||||
if itm, err = utils.IfaceAsInt64(itmData); err != nil {
|
||||
return fmt.Errorf("item: <%s>, err: %s", path[0], err.Error())
|
||||
case utils.Answer:
|
||||
newBranch := itm.NewBranch ||
|
||||
len(msg.Answer) == 0 ||
|
||||
msgFields.Has(path[0])
|
||||
if newBranch { // force append if the same path was already used
|
||||
msgFields = make(utils.StringSet) // reset the fields inside since we have a new message
|
||||
msgFields.Add(strings.Join(path, ".")) // detect new branch
|
||||
}
|
||||
msg.Answer[len(msg.Answer)-1].(*dns.NAPTR).Order = uint16(itm)
|
||||
case utils.Preference:
|
||||
if msg.Question[0].Qtype != dns.TypeNAPTR {
|
||||
return fmt.Errorf("field <%s> only works with NAPTR", utils.Preference)
|
||||
if msg.Answer, err = updateDnsAnswer(msg.Answer, msg.Question[0].Qtype, msg.Question[0].Name, path[1:len(path)-1], itm.Data, newBranch); err != nil {
|
||||
return fmt.Errorf("item: <%s>, err: %s", path[:len(path)-1], err.Error())
|
||||
}
|
||||
var itm int64
|
||||
if itm, err = utils.IfaceAsInt64(itmData); err != nil {
|
||||
return fmt.Errorf("item: <%s>, err: %s", path[0], err.Error())
|
||||
case utils.Ns: //ToDO
|
||||
case utils.Extra: //ToDO
|
||||
case dnsOption:
|
||||
opts := msg.IsEdns0()
|
||||
if opts == nil {
|
||||
opts = msg.SetEdns0(4096, false).IsEdns0()
|
||||
}
|
||||
msg.Answer[len(msg.Answer)-1].(*dns.NAPTR).Preference = uint16(itm)
|
||||
case utils.Flags:
|
||||
if msg.Question[0].Qtype != dns.TypeNAPTR {
|
||||
return fmt.Errorf("field <%s> only works with NAPTR", utils.Flags)
|
||||
if opts.Option, err = updateDnsOption(opts.Option, path[1:len(path)-1], itm.Data, itm.NewBranch); err != nil {
|
||||
return fmt.Errorf("item: <%s>, err: %s", path[:len(path)-1], err.Error())
|
||||
}
|
||||
msg.Answer[len(msg.Answer)-1].(*dns.NAPTR).Flags = utils.IfaceAsString(itmData)
|
||||
case utils.Service:
|
||||
if msg.Question[0].Qtype != dns.TypeNAPTR {
|
||||
return fmt.Errorf("field <%s> only works with NAPTR", utils.Service)
|
||||
}
|
||||
msg.Answer[len(msg.Answer)-1].(*dns.NAPTR).Service = utils.IfaceAsString(itmData)
|
||||
case utils.Regexp:
|
||||
if msg.Question[0].Qtype != dns.TypeNAPTR {
|
||||
return fmt.Errorf("field <%s> only works with NAPTR", utils.Regexp)
|
||||
}
|
||||
msg.Answer[len(msg.Answer)-1].(*dns.NAPTR).Regexp = utils.IfaceAsString(itmData)
|
||||
case utils.Replacement:
|
||||
if msg.Question[0].Qtype != dns.TypeNAPTR {
|
||||
return fmt.Errorf("field <%s> only works with NAPTR", utils.Replacement)
|
||||
}
|
||||
msg.Answer[len(msg.Answer)-1].(*dns.NAPTR).Replacement = utils.IfaceAsString(itmData)
|
||||
default:
|
||||
}
|
||||
|
||||
msgFields.Add(path[0]) // detect new branch
|
||||
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// updateDnsQuestion
|
||||
func updateDnsQuestions(q []dns.Question, path []string, value interface{}, newBranch bool) (_ []dns.Question, err error) {
|
||||
var idx int
|
||||
var field string
|
||||
switch len(path) {
|
||||
case 1: // only the field so update the last one
|
||||
if newBranch || len(q) == 0 {
|
||||
q = append(q, dns.Question{})
|
||||
}
|
||||
idx = len(q) - 1
|
||||
field = path[0]
|
||||
case 2: // the index is specified
|
||||
if idx, err = strconv.Atoi(path[0]); err != nil {
|
||||
return
|
||||
}
|
||||
if lq := len(q); idx > lq {
|
||||
err = utils.ErrWrongPath
|
||||
return
|
||||
} else if lq == idx {
|
||||
q = append(q, dns.Question{})
|
||||
}
|
||||
field = path[1]
|
||||
default:
|
||||
err = utils.ErrWrongPath
|
||||
return
|
||||
}
|
||||
switch field {
|
||||
case utils.Name:
|
||||
q[idx].Name = utils.IfaceAsString(value)
|
||||
case utils.Qtype:
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(value); err != nil {
|
||||
return
|
||||
}
|
||||
q[idx].Qtype = uint16(vItm)
|
||||
case utils.Qclass:
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(value); err != nil {
|
||||
return
|
||||
}
|
||||
q[idx].Qclass = uint16(vItm)
|
||||
default:
|
||||
err = utils.ErrWrongPath
|
||||
return
|
||||
}
|
||||
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func updateDnsOption(q []dns.EDNS0, path []string, value interface{}, newBranch bool) (_ []dns.EDNS0, err error) {
|
||||
var idx int
|
||||
var field string
|
||||
switch len(path) {
|
||||
case 1: // only the field so update the last one
|
||||
field = path[0]
|
||||
if newBranch ||
|
||||
len(q) == 0 {
|
||||
var o dns.EDNS0
|
||||
if o, err = createDnsOption(field, value); err != nil {
|
||||
return
|
||||
}
|
||||
return append(q, o), nil
|
||||
}
|
||||
idx = len(q) - 1
|
||||
case 2: // the index is specified
|
||||
field = path[1]
|
||||
if idx, err = strconv.Atoi(path[0]); err != nil {
|
||||
return
|
||||
}
|
||||
if lq := len(q); idx > lq {
|
||||
err = utils.ErrWrongPath
|
||||
return
|
||||
} else if lq == idx {
|
||||
var o dns.EDNS0
|
||||
if o, err = createDnsOption(field, value); err != nil {
|
||||
return
|
||||
}
|
||||
return append(q, o), nil
|
||||
}
|
||||
default:
|
||||
err = utils.ErrWrongPath
|
||||
return
|
||||
}
|
||||
switch v := q[idx].(type) {
|
||||
case *dns.EDNS0_NSID:
|
||||
if field != "Nsid" {
|
||||
err = utils.ErrWrongPath
|
||||
return
|
||||
}
|
||||
v.Nsid = utils.IfaceAsString(value)
|
||||
case *dns.EDNS0_SUBNET:
|
||||
switch field {
|
||||
case "Family":
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(value); err != nil {
|
||||
return
|
||||
}
|
||||
v.Family = uint16(vItm)
|
||||
case "SourceNetmask":
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(value); err != nil {
|
||||
return
|
||||
}
|
||||
v.SourceNetmask = uint8(vItm)
|
||||
case "SourceScope":
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(value); err != nil {
|
||||
return
|
||||
}
|
||||
v.SourceScope = uint8(vItm)
|
||||
case "Address":
|
||||
v.Address = net.ParseIP(utils.IfaceAsString(value))
|
||||
default:
|
||||
err = utils.ErrWrongPath
|
||||
return
|
||||
}
|
||||
case *dns.EDNS0_COOKIE:
|
||||
if field != "Cookie" {
|
||||
err = utils.ErrWrongPath
|
||||
return
|
||||
}
|
||||
v.Cookie = utils.IfaceAsString(value)
|
||||
case *dns.EDNS0_UL:
|
||||
switch field {
|
||||
case "Lease":
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(value); err != nil {
|
||||
return
|
||||
}
|
||||
v.Lease = uint32(vItm)
|
||||
case "KeyLease":
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(value); err != nil {
|
||||
return
|
||||
}
|
||||
v.KeyLease = uint32(vItm)
|
||||
default:
|
||||
err = utils.ErrWrongPath
|
||||
return
|
||||
}
|
||||
case *dns.EDNS0_LLQ:
|
||||
switch field {
|
||||
case "Version":
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(value); err != nil {
|
||||
return
|
||||
}
|
||||
v.Version = uint16(vItm)
|
||||
case "Opcode":
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(value); err != nil {
|
||||
return
|
||||
}
|
||||
v.Opcode = uint16(vItm)
|
||||
case "Error":
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(value); err != nil {
|
||||
return
|
||||
}
|
||||
v.Error = uint16(vItm)
|
||||
case "Id":
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(value); err != nil {
|
||||
return
|
||||
}
|
||||
v.Id = uint64(vItm)
|
||||
case "LeaseLife":
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(value); err != nil {
|
||||
return
|
||||
}
|
||||
v.LeaseLife = uint32(vItm)
|
||||
default:
|
||||
err = utils.ErrWrongPath
|
||||
return
|
||||
}
|
||||
case *dns.EDNS0_DAU:
|
||||
if field != "DAU" {
|
||||
err = utils.ErrWrongPath
|
||||
return
|
||||
}
|
||||
v.AlgCode = []uint8(utils.IfaceAsString(value))
|
||||
case *dns.EDNS0_DHU:
|
||||
if field != "DHU" {
|
||||
err = utils.ErrWrongPath
|
||||
return
|
||||
}
|
||||
v.AlgCode = []uint8(utils.IfaceAsString(value))
|
||||
case *dns.EDNS0_N3U:
|
||||
if field != "N3U" {
|
||||
err = utils.ErrWrongPath
|
||||
return
|
||||
}
|
||||
v.AlgCode = []uint8(utils.IfaceAsString(value))
|
||||
case *dns.EDNS0_EXPIRE:
|
||||
if field != "Expire" {
|
||||
err = utils.ErrWrongPath
|
||||
return
|
||||
}
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(value); err != nil {
|
||||
return
|
||||
}
|
||||
v.Expire = uint32(vItm)
|
||||
case *dns.EDNS0_TCP_KEEPALIVE:
|
||||
switch field {
|
||||
case "Length": //
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(value); err != nil {
|
||||
return
|
||||
}
|
||||
v.Length = uint16(vItm)
|
||||
case "Timeout": //
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(value); err != nil {
|
||||
return
|
||||
}
|
||||
v.Timeout = uint16(vItm)
|
||||
default:
|
||||
err = utils.ErrWrongPath
|
||||
return
|
||||
}
|
||||
case *dns.EDNS0_PADDING:
|
||||
if field != "Padding" {
|
||||
err = utils.ErrWrongPath
|
||||
return
|
||||
}
|
||||
v.Padding = []byte(utils.IfaceAsString(value))
|
||||
case *dns.EDNS0_EDE:
|
||||
switch field {
|
||||
case "InfoCode":
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(value); err != nil {
|
||||
return
|
||||
}
|
||||
v.InfoCode = uint16(vItm)
|
||||
case "ExtraText":
|
||||
v.ExtraText = utils.IfaceAsString(value)
|
||||
default:
|
||||
err = utils.ErrWrongPath
|
||||
return
|
||||
}
|
||||
case *dns.EDNS0_ESU:
|
||||
if field != "Uri" {
|
||||
err = utils.ErrWrongPath
|
||||
return
|
||||
}
|
||||
v.Uri = utils.IfaceAsString(value)
|
||||
case *dns.EDNS0_LOCAL: // if already there you can change data
|
||||
if field != "Data" {
|
||||
err = utils.ErrWrongPath
|
||||
return
|
||||
}
|
||||
v.Data = []byte(utils.IfaceAsString(value))
|
||||
case nil:
|
||||
err = fmt.Errorf("unsuported dns option type <%T>", v)
|
||||
default:
|
||||
err = fmt.Errorf("unsuported dns option type <%T>", v)
|
||||
}
|
||||
return q, err
|
||||
}
|
||||
|
||||
func createDnsOption(field string, value interface{}) (o dns.EDNS0, err error) {
|
||||
switch field {
|
||||
case "Nsid": // EDNS0_NSID
|
||||
o = &dns.EDNS0_NSID{Nsid: utils.IfaceAsString(value)}
|
||||
case "Family": // EDNS0_SUBNET
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(value); err != nil {
|
||||
return
|
||||
}
|
||||
o = &dns.EDNS0_SUBNET{Family: uint16(vItm)}
|
||||
case "SourceNetmask": // EDNS0_SUBNET
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(value); err != nil {
|
||||
return
|
||||
}
|
||||
o = &dns.EDNS0_SUBNET{SourceNetmask: uint8(vItm)}
|
||||
case "SourceScope": // EDNS0_SUBNET
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(value); err != nil {
|
||||
return
|
||||
}
|
||||
o = &dns.EDNS0_SUBNET{SourceScope: uint8(vItm)}
|
||||
case "Address": // EDNS0_SUBNET
|
||||
o = &dns.EDNS0_SUBNET{Address: net.ParseIP(utils.IfaceAsString(value))}
|
||||
case "Cookie": // EDNS0_COOKIE
|
||||
o = &dns.EDNS0_COOKIE{Cookie: utils.IfaceAsString(value)}
|
||||
case "Lease": // EDNS0_UL
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(value); err != nil {
|
||||
return
|
||||
}
|
||||
o = &dns.EDNS0_UL{Lease: uint32(vItm)}
|
||||
case "KeyLease": // EDNS0_UL
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(value); err != nil {
|
||||
return
|
||||
}
|
||||
o = &dns.EDNS0_UL{KeyLease: uint32(vItm)}
|
||||
case "Version": // EDNS0_LLQ
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(value); err != nil {
|
||||
return
|
||||
}
|
||||
o = &dns.EDNS0_LLQ{Version: uint16(vItm)}
|
||||
case "Opcode": // EDNS0_LLQ
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(value); err != nil {
|
||||
return
|
||||
}
|
||||
o = &dns.EDNS0_LLQ{Opcode: uint16(vItm)}
|
||||
case "Error": // EDNS0_LLQ
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(value); err != nil {
|
||||
return
|
||||
}
|
||||
o = &dns.EDNS0_LLQ{Error: uint16(vItm)}
|
||||
case "Id": // EDNS0_LLQ
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(value); err != nil {
|
||||
return
|
||||
}
|
||||
o = &dns.EDNS0_LLQ{Id: uint64(vItm)}
|
||||
case "LeaseLife": // EDNS0_LLQ
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(value); err != nil {
|
||||
return
|
||||
}
|
||||
o = &dns.EDNS0_LLQ{LeaseLife: uint32(vItm)}
|
||||
case "DAU": // EDNS0_DAU
|
||||
o = &dns.EDNS0_DAU{AlgCode: []uint8(utils.IfaceAsString(value))}
|
||||
case "DHU": // EDNS0_DHU
|
||||
o = &dns.EDNS0_DHU{AlgCode: []uint8(utils.IfaceAsString(value))}
|
||||
case "N3U": // EDNS0_N3U
|
||||
o = &dns.EDNS0_N3U{AlgCode: []uint8(utils.IfaceAsString(value))}
|
||||
case "Expire": // EDNS0_EXPIRE
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(value); err != nil {
|
||||
return
|
||||
}
|
||||
o = &dns.EDNS0_EXPIRE{Expire: uint32(vItm)}
|
||||
case "Length": // EDNS0_TCP_KEEPALIVE
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(value); err != nil {
|
||||
return
|
||||
}
|
||||
o = &dns.EDNS0_TCP_KEEPALIVE{Length: uint16(vItm)}
|
||||
case "Timeout": // EDNS0_TCP_KEEPALIVE
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(value); err != nil {
|
||||
return
|
||||
}
|
||||
o = &dns.EDNS0_TCP_KEEPALIVE{Timeout: uint16(vItm)}
|
||||
case "Padding": // EDNS0_PADDING
|
||||
o = &dns.EDNS0_PADDING{Padding: []byte(utils.IfaceAsString(value))}
|
||||
case "InfoCode": // EDNS0_EDE
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(value); err != nil {
|
||||
return
|
||||
}
|
||||
o = &dns.EDNS0_EDE{InfoCode: uint16(vItm)}
|
||||
case "ExtraText": // EDNS0_EDE
|
||||
o = &dns.EDNS0_EDE{ExtraText: utils.IfaceAsString(value)}
|
||||
case "Uri": // EDNS0_ESU
|
||||
o = &dns.EDNS0_ESU{Uri: utils.IfaceAsString(value)}
|
||||
default:
|
||||
err = fmt.Errorf("can not create option from field <%q>", field)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func updateDnsAnswer(q []dns.RR, qType uint16, qName string, path []string, value interface{}, newBranch bool) (_ []dns.RR, err error) {
|
||||
var idx int
|
||||
switch len(path) {
|
||||
case 1: // only the field so update the last one
|
||||
if newBranch || len(q) == 0 {
|
||||
var a dns.RR
|
||||
if a, err = newDNSAnswer(qType, qName); err != nil {
|
||||
return
|
||||
}
|
||||
q = append(q, a)
|
||||
}
|
||||
idx = len(q) - 1
|
||||
case 2: // the index is specified
|
||||
if idx, err = strconv.Atoi(path[0]); err != nil {
|
||||
return
|
||||
}
|
||||
if lq := len(q); idx > lq {
|
||||
err = utils.ErrWrongPath
|
||||
return
|
||||
} else if lq == idx {
|
||||
var a dns.RR
|
||||
if a, err = newDNSAnswer(qType, qName); err != nil {
|
||||
return
|
||||
}
|
||||
q = append(q, a)
|
||||
}
|
||||
path = path[1:]
|
||||
default:
|
||||
err = utils.ErrWrongPath
|
||||
return
|
||||
}
|
||||
switch v := q[idx].(type) {
|
||||
case *dns.NAPTR:
|
||||
err = updateDnsNAPTRAnswer(v, path, value)
|
||||
case nil:
|
||||
err = fmt.Errorf("unsuported dns option type <%T>", v)
|
||||
default:
|
||||
err = fmt.Errorf("unsuported dns option type <%T>", v)
|
||||
}
|
||||
|
||||
return q, err
|
||||
}
|
||||
|
||||
// appendDNSAnswer will append the right answer payload to the message
|
||||
func newDNSAnswer(qType uint16, qName string) (a dns.RR, err error) {
|
||||
hdr := dns.RR_Header{
|
||||
Name: qName,
|
||||
Rrtype: qType,
|
||||
Class: dns.ClassINET,
|
||||
Ttl: 60,
|
||||
}
|
||||
switch qType {
|
||||
case dns.TypeA:
|
||||
a = &dns.A{Hdr: hdr}
|
||||
case dns.TypeNAPTR:
|
||||
a = &dns.NAPTR{Hdr: hdr}
|
||||
default:
|
||||
err = fmt.Errorf("unsupported DNS type: <%v>", qType)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func updateDnsNAPTRAnswer(v *dns.NAPTR, path []string, value interface{}) (err error) {
|
||||
if len(path) < 1 ||
|
||||
(path[0] != "Hdr" && len(path) != 1) ||
|
||||
(path[0] == "Hdr" && len(path) != 2) {
|
||||
return utils.ErrWrongPath
|
||||
}
|
||||
switch path[0] {
|
||||
case "Hdr":
|
||||
return updateDnsRRHeader(&v.Hdr, path[1:], value)
|
||||
case "Order":
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(value); err != nil {
|
||||
return
|
||||
}
|
||||
v.Order = uint16(vItm)
|
||||
case "Preference":
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(value); err != nil {
|
||||
return
|
||||
}
|
||||
v.Preference = uint16(vItm)
|
||||
case "Flags":
|
||||
v.Flags = utils.IfaceAsString(value)
|
||||
case "Service":
|
||||
v.Service = utils.IfaceAsString(value)
|
||||
case "Regexp":
|
||||
v.Regexp = utils.IfaceAsString(value)
|
||||
case "Replacement":
|
||||
v.Replacement = utils.IfaceAsString(value)
|
||||
default:
|
||||
return utils.ErrWrongPath
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func updateDnsRRHeader(v *dns.RR_Header, path []string, value interface{}) (err error) {
|
||||
if len(path) != 1 {
|
||||
return utils.ErrWrongPath
|
||||
}
|
||||
switch path[0] {
|
||||
case "Name":
|
||||
v.Name = utils.IfaceAsString(value)
|
||||
case "Rrtype":
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(value); err != nil {
|
||||
return
|
||||
}
|
||||
v.Rrtype = uint16(vItm)
|
||||
case "Class":
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(value); err != nil {
|
||||
return
|
||||
}
|
||||
v.Class = uint16(vItm)
|
||||
case "Ttl":
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(value); err != nil {
|
||||
return
|
||||
}
|
||||
v.Ttl = uint32(vItm)
|
||||
case "Rdlength":
|
||||
var vItm int64
|
||||
if vItm, err = utils.IfaceAsTInt64(value); err != nil {
|
||||
return
|
||||
}
|
||||
v.Rdlength = uint16(vItm)
|
||||
default:
|
||||
return utils.ErrWrongPath
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package agents
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@@ -27,26 +26,6 @@ import (
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
func TestE164FromNAPTR(t *testing.T) {
|
||||
if e164, err := e164FromNAPTR("8.7.6.5.4.3.2.1.0.1.6.e164.arpa."); err != nil {
|
||||
t.Error(err)
|
||||
} else if e164 != "61012345678" {
|
||||
t.Errorf("received: <%s>", e164)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDomainNameFromNAPTR(t *testing.T) {
|
||||
if dName := domainNameFromNAPTR("8.7.6.5.4.3.2.1.0.1.6.e164.arpa."); dName != "e164.arpa" {
|
||||
t.Errorf("received: <%s>", dName)
|
||||
}
|
||||
if dName := domainNameFromNAPTR("8.7.6.5.4.3.2.1.0.1.6.e164.itsyscom.com."); dName != "e164.itsyscom.com" {
|
||||
t.Errorf("received: <%s>", dName)
|
||||
}
|
||||
if dName := domainNameFromNAPTR("8.7.6.5.4.3.2.1.0.1.6.itsyscom.com."); dName != "8.7.6.5.4.3.2.1.0.1.6.itsyscom.com" {
|
||||
t.Errorf("received: <%s>", dName)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendDNSAnswerTypeNAPTR(t *testing.T) {
|
||||
m := new(dns.Msg)
|
||||
m.SetQuestion("3.6.9.4.7.1.7.1.5.6.8.9.4.e164.arpa.", dns.TypeNAPTR)
|
||||
@@ -93,84 +72,6 @@ func TestAppendDNSAnswerUnexpectedType(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDNSDPFieldAsInterface(t *testing.T) {
|
||||
m := new(dns.Msg)
|
||||
m.SetQuestion("3.6.9.4.7.1.7.1.5.6.8.9.4.e164.arpa.", dns.TypeNAPTR)
|
||||
dp := newDNSDataProvider(m, nil)
|
||||
expected := m.Question[0]
|
||||
if data, err := dp.FieldAsInterface([]string{"test"}); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(data, expected) {
|
||||
t.Errorf("expecting: <%+v>, received: <%+v>", expected, data)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDNSDPFieldAsInterfaceEmptyPath(t *testing.T) {
|
||||
m := new(dns.Msg)
|
||||
m.SetQuestion("3.6.9.4.7.1.7.1.5.6.8.9.4.e164.arpa.", dns.TypeNAPTR)
|
||||
dp := newDNSDataProvider(m, nil)
|
||||
if _, err := dp.FieldAsInterface([]string{}); err == nil ||
|
||||
err.Error() != "empty field path" {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDNSDPFieldAsInterfaceFromCache(t *testing.T) {
|
||||
m := new(dns.Msg)
|
||||
m.SetQuestion("3.6.9.4.7.1.7.1.5.6.8.9.4.e164.arpa.", dns.TypeNAPTR)
|
||||
dp := newDNSDataProvider(m, nil)
|
||||
expected := m.Question[0]
|
||||
if data, err := dp.FieldAsInterface([]string{"test"}); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(data, expected) {
|
||||
t.Errorf("expecting: <%+v>, received: <%+v>", expected, data)
|
||||
}
|
||||
if data, err := dp.FieldAsInterface([]string{"test"}); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(data, expected) {
|
||||
t.Errorf("expecting: <%+v>, received: <%+v>", expected, data)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDNSDPFieldAsString(t *testing.T) {
|
||||
m := new(dns.Msg)
|
||||
m.SetQuestion("3.6.9.4.7.1.7.1.5.6.8.9.4.e164.arpa.", dns.TypeNAPTR)
|
||||
dp := newDNSDataProvider(m, nil)
|
||||
expected := utils.ToJSON(m.Question[0])
|
||||
if data, err := dp.FieldAsString([]string{"test"}); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(data, expected) {
|
||||
t.Errorf("expecting: <%+v>, received: <%+v>", expected, data)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDNSDPFieldAsStringEmptyPath(t *testing.T) {
|
||||
m := new(dns.Msg)
|
||||
m.SetQuestion("3.6.9.4.7.1.7.1.5.6.8.9.4.e164.arpa.", dns.TypeNAPTR)
|
||||
dp := newDNSDataProvider(m, nil)
|
||||
if _, err := dp.FieldAsString([]string{}); err == nil ||
|
||||
err.Error() != "empty field path" {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDNSDPFieldAsStringFromCache(t *testing.T) {
|
||||
m := new(dns.Msg)
|
||||
m.SetQuestion("3.6.9.4.7.1.7.1.5.6.8.9.4.e164.arpa.", dns.TypeNAPTR)
|
||||
dp := newDNSDataProvider(m, nil)
|
||||
expected := utils.ToJSON(m.Question[0])
|
||||
if data, err := dp.FieldAsString([]string{"test"}); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(data, expected) {
|
||||
t.Errorf("expecting: <%+v>, received: <%+v>", expected, data)
|
||||
}
|
||||
if data, err := dp.FieldAsString([]string{"test"}); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(data, expected) {
|
||||
t.Errorf("expecting: <%+v>, received: <%+v>", expected, data)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateDNSMsgFromNM(t *testing.T) {
|
||||
m := new(dns.Msg)
|
||||
m.SetQuestion("3.6.9.4.7.1.7.1.5.6.8.9.4.e164.arpa.", dns.TypeNAPTR)
|
||||
@@ -206,7 +107,7 @@ func TestUpdateDNSMsgFromNM(t *testing.T) {
|
||||
}
|
||||
|
||||
nM = utils.NewOrderedNavigableMap()
|
||||
path = []string{utils.Order}
|
||||
path = []string{utils.Answer, utils.Order}
|
||||
itm = &utils.DataNode{Type: utils.NMDataType, Value: &utils.DataLeaf{
|
||||
Data: "RandomValue",
|
||||
}}
|
||||
@@ -215,12 +116,12 @@ func TestUpdateDNSMsgFromNM(t *testing.T) {
|
||||
PathSlice: path,
|
||||
}, []*utils.DataNode{itm})
|
||||
if err := updateDNSMsgFromNM(m, nM); err == nil ||
|
||||
err.Error() != `item: <Order>, err: strconv.ParseInt: parsing "RandomValue": invalid syntax` {
|
||||
err.Error() != `item: <[Answer Order]>, err: strconv.ParseInt: parsing "RandomValue": invalid syntax` {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
nM = utils.NewOrderedNavigableMap()
|
||||
path = []string{utils.Preference}
|
||||
path = []string{utils.Answer, utils.Preference}
|
||||
itm = &utils.DataNode{Type: utils.NMDataType, Value: &utils.DataLeaf{
|
||||
Data: "RandomValue",
|
||||
}}
|
||||
@@ -229,14 +130,14 @@ func TestUpdateDNSMsgFromNM(t *testing.T) {
|
||||
PathSlice: path,
|
||||
}, []*utils.DataNode{itm})
|
||||
if err := updateDNSMsgFromNM(m, nM); err == nil ||
|
||||
err.Error() != `item: <Preference>, err: strconv.ParseInt: parsing "RandomValue": invalid syntax` {
|
||||
err.Error() != `item: <[Answer Preference]>, err: strconv.ParseInt: parsing "RandomValue": invalid syntax` {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
m = new(dns.Msg)
|
||||
m.SetQuestion("3.6.9.4.7.1.7.1.5.6.8.9.4.e164.arpa.", dns.TypeA)
|
||||
nM = utils.NewOrderedNavigableMap()
|
||||
path = []string{utils.Order}
|
||||
path = []string{utils.Answer, utils.Order}
|
||||
itm = &utils.DataNode{Type: utils.NMDataType, Value: &utils.DataLeaf{
|
||||
Data: 10,
|
||||
}}
|
||||
@@ -245,12 +146,12 @@ func TestUpdateDNSMsgFromNM(t *testing.T) {
|
||||
PathSlice: path,
|
||||
}, []*utils.DataNode{itm})
|
||||
if err := updateDNSMsgFromNM(m, nM); err == nil ||
|
||||
err.Error() != `field <Order> only works with NAPTR` {
|
||||
err.Error() != `item: <[Answer Order]>, err: unsuported dns option type <*dns.A>` {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
nM = utils.NewOrderedNavigableMap()
|
||||
path = []string{utils.Preference}
|
||||
path = []string{utils.Answer, utils.Preference}
|
||||
itm = &utils.DataNode{Type: utils.NMDataType, Value: &utils.DataLeaf{
|
||||
Data: 10,
|
||||
}}
|
||||
@@ -259,12 +160,12 @@ func TestUpdateDNSMsgFromNM(t *testing.T) {
|
||||
PathSlice: path,
|
||||
}, []*utils.DataNode{itm})
|
||||
if err := updateDNSMsgFromNM(m, nM); err == nil ||
|
||||
err.Error() != `field <Preference> only works with NAPTR` {
|
||||
err.Error() != `item: <[Answer Preference]>, err: unsuported dns option type <*dns.A>` {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
nM = utils.NewOrderedNavigableMap()
|
||||
path = []string{utils.Flags}
|
||||
path = []string{utils.Answer, utils.Flags}
|
||||
itm = &utils.DataNode{Type: utils.NMDataType, Value: &utils.DataLeaf{
|
||||
Data: 10,
|
||||
}}
|
||||
@@ -273,12 +174,12 @@ func TestUpdateDNSMsgFromNM(t *testing.T) {
|
||||
PathSlice: path,
|
||||
}, []*utils.DataNode{itm})
|
||||
if err := updateDNSMsgFromNM(m, nM); err == nil ||
|
||||
err.Error() != `field <Flags> only works with NAPTR` {
|
||||
err.Error() != `item: <[Answer Flags]>, err: unsuported dns option type <*dns.A>` {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
nM = utils.NewOrderedNavigableMap()
|
||||
path = []string{utils.Service}
|
||||
path = []string{utils.Answer, utils.Service}
|
||||
itm = &utils.DataNode{Type: utils.NMDataType, Value: &utils.DataLeaf{
|
||||
Data: 10,
|
||||
}}
|
||||
@@ -287,12 +188,12 @@ func TestUpdateDNSMsgFromNM(t *testing.T) {
|
||||
PathSlice: path,
|
||||
}, []*utils.DataNode{itm})
|
||||
if err := updateDNSMsgFromNM(m, nM); err == nil ||
|
||||
err.Error() != `field <Service> only works with NAPTR` {
|
||||
err.Error() != `item: <[Answer Service]>, err: unsuported dns option type <*dns.A>` {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
nM = utils.NewOrderedNavigableMap()
|
||||
path = []string{utils.Regexp}
|
||||
path = []string{utils.Answer, utils.Regexp}
|
||||
itm = &utils.DataNode{Type: utils.NMDataType, Value: &utils.DataLeaf{
|
||||
Data: 10,
|
||||
}}
|
||||
@@ -301,12 +202,12 @@ func TestUpdateDNSMsgFromNM(t *testing.T) {
|
||||
PathSlice: path,
|
||||
}, []*utils.DataNode{itm})
|
||||
if err := updateDNSMsgFromNM(m, nM); err == nil ||
|
||||
err.Error() != `field <Regexp> only works with NAPTR` {
|
||||
err.Error() != `item: <[Answer Regexp]>, err: unsuported dns option type <*dns.A>` {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
nM = utils.NewOrderedNavigableMap()
|
||||
path = []string{utils.Replacement}
|
||||
path = []string{utils.Answer, utils.Replacement}
|
||||
itm = &utils.DataNode{Type: utils.NMDataType, Value: &utils.DataLeaf{
|
||||
Data: 10,
|
||||
}}
|
||||
@@ -315,7 +216,7 @@ func TestUpdateDNSMsgFromNM(t *testing.T) {
|
||||
PathSlice: path,
|
||||
}, []*utils.DataNode{itm})
|
||||
if err := updateDNSMsgFromNM(m, nM); err == nil ||
|
||||
err.Error() != `field <Replacement> only works with NAPTR` {
|
||||
err.Error() != `item: <[Answer Replacement]>, err: unsuported dns option type <*dns.A>` {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package agents
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"github.com/cgrates/radigo"
|
||||
)
|
||||
@@ -112,9 +114,7 @@ func radauthReq(flags utils.FlagsWithParams, req *radigo.Packet, aReq *AgentRequ
|
||||
if len(userPassAvps) == 0 {
|
||||
return false, utils.NewErrMandatoryIeMissing(UserPasswordAVP)
|
||||
}
|
||||
if userPassAvps[0].StringValue != pass {
|
||||
return false, nil
|
||||
}
|
||||
return userPassAvps[0].StringValue == pass, nil
|
||||
case flags.Has(utils.MetaCHAP):
|
||||
chapAVPs := req.AttributesWithName(CHAPPasswordAVP, utils.EmptyString)
|
||||
if len(chapAVPs) == 0 {
|
||||
@@ -131,34 +131,25 @@ func radauthReq(flags utils.FlagsWithParams, req *radigo.Packet, aReq *AgentRequ
|
||||
if len(msResponse) == 0 {
|
||||
return false, utils.NewErrMandatoryIeMissing(MSCHAPResponseAVP)
|
||||
}
|
||||
vsaMSResponde := msResponse[0].Value.(*radigo.VSA)
|
||||
vsaMSChallange := msChallenge[0].Value.(*radigo.VSA)
|
||||
vsaMSResponde := msResponse[0].Value.(*radigo.VSA).RawValue
|
||||
vsaMSChallange := msChallenge[0].Value.(*radigo.VSA).RawValue
|
||||
|
||||
userName := req.AttributesWithName("User-Name", utils.EmptyString)[0].StringValue
|
||||
passwordFromAttributes := pass
|
||||
|
||||
if len(vsaMSChallange.RawValue) != 16 || len(vsaMSResponde.RawValue) != 50 {
|
||||
if len(vsaMSChallange) != 16 || len(vsaMSResponde) != 50 {
|
||||
return false, nil
|
||||
}
|
||||
ident := vsaMSResponde.RawValue[0]
|
||||
peerChallenge := vsaMSResponde.RawValue[2:18]
|
||||
peerResponse := vsaMSResponde.RawValue[26:50]
|
||||
ntResponse, err := radigo.GenerateNTResponse(vsaMSChallange.RawValue,
|
||||
peerChallenge, userName, passwordFromAttributes)
|
||||
if err != nil {
|
||||
ident := vsaMSResponde[0]
|
||||
peerChallenge := vsaMSResponde[2:18]
|
||||
peerResponse := vsaMSResponde[26:50]
|
||||
ntResponse, err := radigo.GenerateNTResponse(vsaMSChallange,
|
||||
peerChallenge, userName, pass)
|
||||
if err != nil || !bytes.Equal(ntResponse, peerResponse) {
|
||||
return false, err
|
||||
}
|
||||
if len(ntResponse) != len(peerResponse) {
|
||||
return false, nil
|
||||
}
|
||||
for i := range ntResponse {
|
||||
if ntResponse[i] != peerResponse[i] {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
authenticatorResponse, err := radigo.GenerateAuthenticatorResponse(vsaMSChallange.RawValue, peerChallenge,
|
||||
ntResponse, userName, passwordFromAttributes)
|
||||
authenticatorResponse, err := radigo.GenerateAuthenticatorResponse(vsaMSChallange, peerChallenge,
|
||||
ntResponse, userName, pass)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -167,9 +158,9 @@ func radauthReq(flags utils.FlagsWithParams, req *radigo.Packet, aReq *AgentRequ
|
||||
copy(success[1:], authenticatorResponse)
|
||||
// this AVP need to be added to be verified on the client side
|
||||
rpl.AddAVPWithName(MSCHAP2SuccessAVP, string(success), MicrosoftVendor)
|
||||
return true, nil
|
||||
default:
|
||||
return false, utils.NewErrMandatoryIeMissing(utils.Flags)
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
@@ -26,12 +26,11 @@ import (
|
||||
)
|
||||
|
||||
// NewObjectDP constructs a utils.DataProvider
|
||||
func NewObjectDP(obj interface{}) (dP utils.DataProvider) {
|
||||
dP = &ObjectDP{
|
||||
func NewObjectDP(obj interface{}) utils.DataProvider {
|
||||
return &ObjectDP{
|
||||
obj: obj,
|
||||
cache: make(map[string]interface{}),
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ObjectDP implements the DataProvider for any interface{}
|
||||
@@ -119,8 +118,7 @@ func (objDP *ObjectDP) FieldAsInterface(fldPath []string) (data interface{}, err
|
||||
// FieldAsString is part of engine.utils.DataProvider interface
|
||||
func (objDP *ObjectDP) FieldAsString(fldPath []string) (data string, err error) {
|
||||
var valIface interface{}
|
||||
valIface, err = objDP.FieldAsInterface(fldPath)
|
||||
if err != nil {
|
||||
if valIface, err = objDP.FieldAsInterface(fldPath); err != nil {
|
||||
return
|
||||
}
|
||||
return utils.IfaceAsString(valIface), nil
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"request_processors": [
|
||||
{
|
||||
"id": "NAPTRAttributes",
|
||||
"filters": ["*string:~*vars.QueryType:NAPTR", "*string:~*vars.E164Address:4986517174964"],
|
||||
"filters": ["*string:~*vars.QueryType:NAPTR", "*string:~*req.Question[0].Name{*e164}:4986517174964"],
|
||||
"flags": ["*authorize", "*attributes","*log"],
|
||||
"request_fields":[
|
||||
{"tag": "E164Address", "path": "*cgreq.E164Address",
|
||||
@@ -13,15 +13,15 @@
|
||||
"type": "*constant", "value": "*attributes"}
|
||||
],
|
||||
"reply_fields":[
|
||||
{"tag": "NAPTROrder", "path": "*rep.Order",
|
||||
{"tag": "NAPTROrder", "path": "*rep.Answer.Order",
|
||||
"type": "*constant", "value": "100"},
|
||||
{"tag": "NAPTRPreference", "path": "*rep.Preference",
|
||||
{"tag": "NAPTRPreference", "path": "*rep.Answer.Preference",
|
||||
"type": "*constant", "value": "10"},
|
||||
{"tag": "NAPTRFlags", "path": "*rep.Flags",
|
||||
{"tag": "NAPTRFlags", "path": "*rep.Answer.Flags",
|
||||
"type": "*constant", "value": "U"},
|
||||
{"tag": "NAPTRService", "path": "*rep.Service",
|
||||
{"tag": "NAPTRService", "path": "*rep.Answer.Service",
|
||||
"type": "*constant", "value": "E2U+SIP"},
|
||||
{"tag": "NAPTRRegex", "path": "*rep.Regexp",
|
||||
{"tag": "NAPTRRegex", "path": "*rep.Answer.Regexp",
|
||||
"type": "*variable", "value": "~*cgrep.Attributes.NAPTRAddress"},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -4,18 +4,18 @@
|
||||
"request_processors": [
|
||||
{
|
||||
"id": "DryRunNAPTR",
|
||||
"filters": ["*string:~*vars.QueryType:NAPTR", "*string:~*vars.E164Address:4986517174963"],
|
||||
"filters": ["*string:~*vars.QueryType:NAPTR", "*string:~*req.Question[0].Name{*e164}:4986517174963"],
|
||||
"flags": ["*dryrun","*log"],
|
||||
"request_fields":[
|
||||
{"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*sms"},
|
||||
],
|
||||
"reply_fields":[
|
||||
{"tag": "NAPTROrder", "path": "*rep.Order", "type": "*constant", "value": "100"},
|
||||
{"tag": "NAPTRPreference", "path": "*rep.Preference", "type": "*constant", "value": "10"},
|
||||
{"tag": "NAPTRFlags", "path": "*rep.Flags", "type": "*constant", "value": "U"},
|
||||
{"tag": "NAPTRService", "path": "*rep.Service", "type": "*constant", "value": "E2U+SIP"},
|
||||
{"tag": "NAPTRRegexp", "path": "*rep.Regexp", "type": "*constant", "value": "!^(.*)$!sip:\\1@172.16.1.10.!"},
|
||||
{"tag": "NAPTRReplacement", "path": "*rep.Replacement", "type": "*constant", "value": "."},
|
||||
{"tag": "NAPTROrder", "path": "*rep.Answer.Order", "type": "*constant", "value": "100"},
|
||||
{"tag": "NAPTRPreference", "path": "*rep.Answer.Preference", "type": "*constant", "value": "10"},
|
||||
{"tag": "NAPTRFlags", "path": "*rep.Answer.Flags", "type": "*constant", "value": "U"},
|
||||
{"tag": "NAPTRService", "path": "*rep.Answer.Service", "type": "*constant", "value": "E2U+SIP"},
|
||||
{"tag": "NAPTRRegexp", "path": "*rep.Answer.Regexp", "type": "*constant", "value": "!^(.*)$!sip:\\1@172.16.1.10.!"},
|
||||
{"tag": "NAPTRReplacement", "path": "*rep.Answer.Replacement", "type": "*constant", "value": "."},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
{
|
||||
"id": "NAPTRRoutesQuery",
|
||||
"filters": ["*string:~*vars.QueryType:NAPTR",
|
||||
"*string:~*vars.E164Address:4986517174965"],
|
||||
"*string:~*req.Question[0].Name{*e164}:4986517174965"],
|
||||
"flags": ["*message", "*routes","*continue"],
|
||||
"request_fields":[
|
||||
{"tag": "ToR", "path": "*cgreq.Account", "type": "*constant", "value": "1001"}, // so we can match the supplier profile
|
||||
@@ -18,44 +18,44 @@
|
||||
{
|
||||
"id": "NAPTRSuppliersOneSupplier",
|
||||
"filters": ["*string:~*vars.QueryType:NAPTR",
|
||||
"*string:~*vars.E164Address:4986517174965",
|
||||
"*string:~*req.Question[0].Name{*e164}:4986517174965",
|
||||
"*gte:~*cgrep.RouteProfiles.Length:1",
|
||||
"*gte:~*cgrep.RouteProfiles[0].Routes.Length:1"],
|
||||
"flags": ["*none","*continue"], // do not send request to CGRateS
|
||||
"reply_fields":[
|
||||
{"tag": "NAPTROrder", "path": "*rep.Order",
|
||||
{"tag": "NAPTROrder", "path": "*rep.Answer.Order",
|
||||
"type": "*group", "value": "100"},
|
||||
{"tag": "NAPTRPreference", "path": "*rep.Preference",
|
||||
{"tag": "NAPTRPreference", "path": "*rep.Answer.Preference",
|
||||
"type": "*group", "value": "10"},
|
||||
{"tag": "NAPTRFlags", "path": "*rep.Flags",
|
||||
{"tag": "NAPTRFlags", "path": "*rep.Answer.Flags",
|
||||
"type": "*group", "value": "U"},
|
||||
{"tag": "NAPTRService", "path": "*rep.Service",
|
||||
{"tag": "NAPTRService", "path": "*rep.Answer.Service",
|
||||
"type": "*group", "value": "E2U+SIP"},
|
||||
{"tag": "NAPTRRegexp", "path": "*rep.Regexp", "type": "*group",
|
||||
{"tag": "NAPTRRegexp", "path": "*rep.Answer.Regexp", "type": "*group",
|
||||
"value": "~*cgrep.RouteProfiles[0].Routes[0].RouteParameters"},
|
||||
{"tag": "NAPTRReplacement", "path": "*rep.Replacement",
|
||||
{"tag": "NAPTRReplacement", "path": "*rep.Answer.Replacement",
|
||||
"type": "*group", "value": "."},
|
||||
],
|
||||
},
|
||||
{
|
||||
"id": "NAPTRSuppliersTwoSuppliers",
|
||||
"filters": ["*string:~*vars.QueryType:NAPTR",
|
||||
"*string:~*vars.E164Address:4986517174965",
|
||||
"*string:~*req.Question[0].Name{*e164}:4986517174965",
|
||||
"*gte:~*cgrep.RouteProfiles.Length:1",
|
||||
"*gte:~*cgrep.RouteProfiles[0].Routes.Length:2"],
|
||||
"flags": ["*none","*continue"],
|
||||
"reply_fields":[
|
||||
{"tag": "NAPTROrder", "type": "*group", "new_branch": true,
|
||||
"path": "*rep.Order", "value": "100"},
|
||||
{"tag": "NAPTRPreference", "path": "*rep.Preference",
|
||||
"path": "*rep.Answer.Order", "value": "100"},
|
||||
{"tag": "NAPTRPreference", "path": "*rep.Answer.Preference",
|
||||
"type": "*group", "value": "10"},
|
||||
{"tag": "NAPTRFlags", "path": "*rep.Flags",
|
||||
{"tag": "NAPTRFlags", "path": "*rep.Answer.Flags",
|
||||
"type": "*group", "value": "U"},
|
||||
{"tag": "NAPTRService", "path": "*rep.Service",
|
||||
{"tag": "NAPTRService", "path": "*rep.Answer.Service",
|
||||
"type": "*group", "value": "E2U+SIP"},
|
||||
{"tag": "NAPTRRegexp", "path": "*rep.Regexp", "type": "*group",
|
||||
{"tag": "NAPTRRegexp", "path": "*rep.Answer.Regexp", "type": "*group",
|
||||
"value": "~*cgrep.RouteProfiles[0].Routes[1].RouteParameters"},
|
||||
{"tag": "NAPTRReplacement", "path": "*rep.Replacement",
|
||||
{"tag": "NAPTRReplacement", "path": "*rep.Answer.Replacement",
|
||||
"type": "*group", "value": "."},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"request_processors": [
|
||||
{
|
||||
"id": "NAPTRAttributes",
|
||||
"filters": ["*string:~*vars.QueryType:NAPTR", "*string:~*vars.E164Address:4986517174964"],
|
||||
"filters": ["*string:~*vars.QueryType:NAPTR", "*string:~*req.Question[0].Name{*e164}:4986517174964"],
|
||||
"flags": ["*authorize", "*attributes","*log"],
|
||||
"request_fields":[
|
||||
{"tag": "E164Address", "path": "*cgreq.E164Address",
|
||||
@@ -13,15 +13,15 @@
|
||||
"type": "*constant", "value": "*attributes"}
|
||||
],
|
||||
"reply_fields":[
|
||||
{"tag": "NAPTROrder", "path": "*rep.Order",
|
||||
{"tag": "NAPTROrder", "path": "*rep.Answer.Order",
|
||||
"type": "*constant", "value": "100"},
|
||||
{"tag": "NAPTRPreference", "path": "*rep.Preference",
|
||||
{"tag": "NAPTRPreference", "path": "*rep.Answer.Preference",
|
||||
"type": "*constant", "value": "10"},
|
||||
{"tag": "NAPTRFlags", "path": "*rep.Flags",
|
||||
{"tag": "NAPTRFlags", "path": "*rep.Answer.Flags",
|
||||
"type": "*constant", "value": "U"},
|
||||
{"tag": "NAPTRService", "path": "*rep.Service",
|
||||
{"tag": "NAPTRService", "path": "*rep.Answer.Service",
|
||||
"type": "*constant", "value": "E2U+SIP"},
|
||||
{"tag": "NAPTRRegex", "path": "*rep.Regexp",
|
||||
{"tag": "NAPTRRegex", "path": "*rep.Answer.Regexp",
|
||||
"type": "*variable", "value": "~*cgrep.Attributes.NAPTRAddress"},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -4,18 +4,18 @@
|
||||
"request_processors": [
|
||||
{
|
||||
"id": "DryRunNAPTR",
|
||||
"filters": ["*string:~*vars.QueryType:NAPTR", "*string:~*vars.E164Address:4986517174963"],
|
||||
"filters": ["*string:~*vars.QueryType:NAPTR", "*string:~*req.Question[0].Name{*e164}:4986517174963"],
|
||||
"flags": ["*dryrun","*log"],
|
||||
"request_fields":[
|
||||
{"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*sms"},
|
||||
],
|
||||
"reply_fields":[
|
||||
{"tag": "NAPTROrder", "path": "*rep.Order", "type": "*constant", "value": "100"},
|
||||
{"tag": "NAPTRPreference", "path": "*rep.Preference", "type": "*constant", "value": "10"},
|
||||
{"tag": "NAPTRFlags", "path": "*rep.Flags", "type": "*constant", "value": "U"},
|
||||
{"tag": "NAPTRService", "path": "*rep.Service", "type": "*constant", "value": "E2U+SIP"},
|
||||
{"tag": "NAPTRRegexp", "path": "*rep.Regexp", "type": "*constant", "value": "!^(.*)$!sip:\\1@172.16.1.10.!"},
|
||||
{"tag": "NAPTRReplacement", "path": "*rep.Replacement", "type": "*constant", "value": "."},
|
||||
{"tag": "NAPTROrder", "path": "*rep.Answer.Order", "type": "*constant", "value": "100"},
|
||||
{"tag": "NAPTRPreference", "path": "*rep.Answer.Preference", "type": "*constant", "value": "10"},
|
||||
{"tag": "NAPTRFlags", "path": "*rep.Answer.Flags", "type": "*constant", "value": "U"},
|
||||
{"tag": "NAPTRService", "path": "*rep.Answer.Service", "type": "*constant", "value": "E2U+SIP"},
|
||||
{"tag": "NAPTRRegexp", "path": "*rep.Answer.Regexp", "type": "*constant", "value": "!^(.*)$!sip:\\1@172.16.1.10.!"},
|
||||
{"tag": "NAPTRReplacement", "path": "*rep.Answer.Replacement", "type": "*constant", "value": "."},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
{
|
||||
"id": "NAPTRRoutesQuery",
|
||||
"filters": ["*string:~*vars.QueryType:NAPTR",
|
||||
"*string:~*vars.E164Address:4986517174965"],
|
||||
"*string:~*req.Question[0].Name{*e164}:4986517174965"],
|
||||
"flags": ["*message", "*routes","*continue"],
|
||||
"request_fields":[
|
||||
{"tag": "ToR", "path": "*cgreq.Account", "type": "*constant", "value": "1001"}, // so we can match the supplier profile
|
||||
@@ -18,44 +18,44 @@
|
||||
{
|
||||
"id": "NAPTRSuppliersOneSupplier",
|
||||
"filters": ["*string:~*vars.QueryType:NAPTR",
|
||||
"*string:~*vars.E164Address:4986517174965",
|
||||
"*string:~*req.Question[0].Name{*e164}:4986517174965",
|
||||
"*gte:~*cgrep.RouteProfiles.Length:1",
|
||||
"*gte:~*cgrep.RouteProfiles[0].Routes.Length:1"],
|
||||
"flags": ["*none","*continue"], // do not send request to CGRateS
|
||||
"reply_fields":[
|
||||
{"tag": "NAPTROrder", "path": "*rep.Order",
|
||||
{"tag": "NAPTROrder", "path": "*rep.Answer.Order",
|
||||
"type": "*group", "value": "100"},
|
||||
{"tag": "NAPTRPreference", "path": "*rep.Preference",
|
||||
{"tag": "NAPTRPreference", "path": "*rep.Answer.Preference",
|
||||
"type": "*group", "value": "10"},
|
||||
{"tag": "NAPTRFlags", "path": "*rep.Flags",
|
||||
{"tag": "NAPTRFlags", "path": "*rep.Answer.Flags",
|
||||
"type": "*group", "value": "U"},
|
||||
{"tag": "NAPTRService", "path": "*rep.Service",
|
||||
{"tag": "NAPTRService", "path": "*rep.Answer.Service",
|
||||
"type": "*group", "value": "E2U+SIP"},
|
||||
{"tag": "NAPTRRegexp", "path": "*rep.Regexp", "type": "*group",
|
||||
{"tag": "NAPTRRegexp", "path": "*rep.Answer.Regexp", "type": "*group",
|
||||
"value": "~*cgrep.RouteProfiles[0].Routes[0].RouteParameters"},
|
||||
{"tag": "NAPTRReplacement", "path": "*rep.Replacement",
|
||||
{"tag": "NAPTRReplacement", "path": "*rep.Answer.Replacement",
|
||||
"type": "*group", "value": "."},
|
||||
],
|
||||
},
|
||||
{
|
||||
"id": "NAPTRSuppliersTwoSuppliers",
|
||||
"filters": ["*string:~*vars.QueryType:NAPTR",
|
||||
"*string:~*vars.E164Address:4986517174965",
|
||||
"*string:~*req.Question[0].Name{*e164}:4986517174965",
|
||||
"*gte:~*cgrep.RouteProfiles.Length:1",
|
||||
"*gte:~*cgrep.RouteProfiles[0].Routes.Length:1"],
|
||||
"flags": ["*none","*continue"],
|
||||
"reply_fields":[
|
||||
{"tag": "NAPTROrder", "type": "*group", "new_branch": true,
|
||||
"path": "*rep.Order", "value": "100"},
|
||||
{"tag": "NAPTRPreference", "path": "*rep.Preference",
|
||||
"path": "*rep.Answer.Order", "value": "100"},
|
||||
{"tag": "NAPTRPreference", "path": "*rep.Answer.Preference",
|
||||
"type": "*group", "value": "10"},
|
||||
{"tag": "NAPTRFlags", "path": "*rep.Flags",
|
||||
{"tag": "NAPTRFlags", "path": "*rep.Answer.Flags",
|
||||
"type": "*group", "value": "U"},
|
||||
{"tag": "NAPTRService", "path": "*rep.Service",
|
||||
{"tag": "NAPTRService", "path": "*rep.Answer.Service",
|
||||
"type": "*group", "value": "E2U+SIP"},
|
||||
{"tag": "NAPTRRegexp", "path": "*rep.Regexp", "type": "*group",
|
||||
{"tag": "NAPTRRegexp", "path": "*rep.Answer.Regexp", "type": "*group",
|
||||
"value": "~*cgrep.RouteProfiles[0].Routes[1].RouteParameters"},
|
||||
{"tag": "NAPTRReplacement", "path": "*rep.Replacement",
|
||||
{"tag": "NAPTRReplacement", "path": "*rep.Answer.Replacement",
|
||||
"type": "*group", "value": "."},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"request_processors": [
|
||||
{
|
||||
"id": "NAPTRAttributes",
|
||||
"filters": ["*string:~*vars.QueryType:NAPTR", "*string:~*vars.E164Address:4986517174964"],
|
||||
"filters": ["*string:~*vars.QueryType:NAPTR", "*string:~*req.Question[0].Name{*e164}:4986517174964"],
|
||||
"flags": ["*authorize", "*attributes","*log"],
|
||||
"request_fields":[
|
||||
{"tag": "E164Address", "path": "*cgreq.E164Address",
|
||||
@@ -13,15 +13,15 @@
|
||||
"type": "*constant", "value": "*attributes"}
|
||||
],
|
||||
"reply_fields":[
|
||||
{"tag": "NAPTROrder", "path": "*rep.Order",
|
||||
{"tag": "NAPTROrder", "path": "*rep.Answer.Order",
|
||||
"type": "*constant", "value": "100"},
|
||||
{"tag": "NAPTRPreference", "path": "*rep.Preference",
|
||||
{"tag": "NAPTRPreference", "path": "*rep.Answer.Preference",
|
||||
"type": "*constant", "value": "10"},
|
||||
{"tag": "NAPTRFlags", "path": "*rep.Flags",
|
||||
{"tag": "NAPTRFlags", "path": "*rep.Answer.Flags",
|
||||
"type": "*constant", "value": "U"},
|
||||
{"tag": "NAPTRService", "path": "*rep.Service",
|
||||
{"tag": "NAPTRService", "path": "*rep.Answer.Service",
|
||||
"type": "*constant", "value": "E2U+SIP"},
|
||||
{"tag": "NAPTRRegex", "path": "*rep.Regexp",
|
||||
{"tag": "NAPTRRegex", "path": "*rep.Answer.Regexp",
|
||||
"type": "*variable", "value": "~*cgrep.Attributes.NAPTRAddress"},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -4,18 +4,18 @@
|
||||
"request_processors": [
|
||||
{
|
||||
"id": "DryRunNAPTR",
|
||||
"filters": ["*string:~*vars.QueryType:NAPTR", "*string:~*vars.E164Address:4986517174963"],
|
||||
"filters": ["*string:~*vars.QueryType:NAPTR", "*string:~*req.Question[0].Name{*e164}:4986517174963"],
|
||||
"flags": ["*dryrun","*log"],
|
||||
"request_fields":[
|
||||
{"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*sms"},
|
||||
{"tag": "ToR", "path": "*cgreq.Order", "type": "*variable", "value": "~*req.Question[0].Name"},
|
||||
],
|
||||
"reply_fields":[
|
||||
{"tag": "NAPTROrder", "path": "*rep.Order", "type": "*constant", "value": "100"},
|
||||
{"tag": "NAPTRPreference", "path": "*rep.Preference", "type": "*constant", "value": "10"},
|
||||
{"tag": "NAPTRFlags", "path": "*rep.Flags", "type": "*constant", "value": "U"},
|
||||
{"tag": "NAPTRService", "path": "*rep.Service", "type": "*constant", "value": "E2U+SIP"},
|
||||
{"tag": "NAPTRRegexp", "path": "*rep.Regexp", "type": "*constant", "value": "!^(.*)$!sip:\\1@172.16.1.10.!"},
|
||||
{"tag": "NAPTRReplacement", "path": "*rep.Replacement", "type": "*constant", "value": "."},
|
||||
{"tag": "NAPTROrder", "path": "*rep.Answer.Order", "type": "*constant", "value": "100"},
|
||||
{"tag": "NAPTRPreference", "path": "*rep.Answer.Preference", "type": "*constant", "value": "10"},
|
||||
{"tag": "NAPTRFlags", "path": "*rep.Answer.Flags", "type": "*constant", "value": "U"},
|
||||
{"tag": "NAPTRService", "path": "*rep.Answer.Service", "type": "*constant", "value": "E2U+SIP"},
|
||||
{"tag": "NAPTRRegexp", "path": "*rep.Answer.Regexp", "type": "*constant", "value": "!^(.*)$!sip:\\1@172.16.1.10.!"},
|
||||
{"tag": "NAPTRReplacement", "path": "*rep.Answer.Replacement", "type": "*constant", "value": "."},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
{
|
||||
"id": "NAPTRRoutesQuery",
|
||||
"filters": ["*string:~*vars.QueryType:NAPTR",
|
||||
"*string:~*vars.E164Address:4986517174965"],
|
||||
"*string:~*req.Question[0].Name{*e164}:4986517174965"],
|
||||
"flags": ["*message", "*routes","*continue"],
|
||||
"request_fields":[
|
||||
{"tag": "ToR", "path": "*cgreq.Account", "type": "*constant", "value": "1001"}, // so we can match the supplier profile
|
||||
@@ -18,44 +18,44 @@
|
||||
{
|
||||
"id": "NAPTRSuppliersOneSupplier",
|
||||
"filters": ["*string:~*vars.QueryType:NAPTR",
|
||||
"*string:~*vars.E164Address:4986517174965",
|
||||
"*string:~*req.Question[0].Name{*e164}:4986517174965",
|
||||
"*gte:~*cgrep.RouteProfiles.Length:1",
|
||||
"*gte:~*cgrep.RouteProfiles[0].Routes.Length:1"],
|
||||
"flags": ["*none","*continue"], // do not send request to CGRateS
|
||||
"reply_fields":[
|
||||
{"tag": "NAPTROrder", "path": "*rep.Order",
|
||||
{"tag": "NAPTROrder", "path": "*rep.Answer.Order",
|
||||
"type": "*group", "value": "100"},
|
||||
{"tag": "NAPTRPreference", "path": "*rep.Preference",
|
||||
{"tag": "NAPTRPreference", "path": "*rep.Answer.Preference",
|
||||
"type": "*group", "value": "10"},
|
||||
{"tag": "NAPTRFlags", "path": "*rep.Flags",
|
||||
{"tag": "NAPTRFlags", "path": "*rep.Answer.Flags",
|
||||
"type": "*group", "value": "U"},
|
||||
{"tag": "NAPTRService", "path": "*rep.Service",
|
||||
{"tag": "NAPTRService", "path": "*rep.Answer.Service",
|
||||
"type": "*group", "value": "E2U+SIP"},
|
||||
{"tag": "NAPTRRegexp", "path": "*rep.Regexp", "type": "*group",
|
||||
{"tag": "NAPTRRegexp", "path": "*rep.Answer.Regexp", "type": "*group",
|
||||
"value": "~*cgrep.RouteProfiles[0].Routes[0].RouteParameters"},
|
||||
{"tag": "NAPTRReplacement", "path": "*rep.Replacement",
|
||||
{"tag": "NAPTRReplacement", "path": "*rep.Answer.Replacement",
|
||||
"type": "*group", "value": "."},
|
||||
],
|
||||
},
|
||||
{
|
||||
"id": "NAPTRSuppliersTwoSuppliers",
|
||||
"filters": ["*string:~*vars.QueryType:NAPTR",
|
||||
"*string:~*vars.E164Address:4986517174965",
|
||||
"*string:~*req.Question[0].Name{*e164}:4986517174965",
|
||||
"*gte:~*cgrep.RouteProfiles.Length:1",
|
||||
"*gte:~*cgrep.RouteProfiles[0].Routes.Length:2"],
|
||||
"flags": ["*none","*continue"],
|
||||
"reply_fields":[
|
||||
{"tag": "NAPTROrder", "type": "*group", "new_branch": true,
|
||||
"path": "*rep.Order", "value": "100"},
|
||||
{"tag": "NAPTRPreference", "path": "*rep.Preference",
|
||||
"path": "*rep.Answer.Order", "value": "100"},
|
||||
{"tag": "NAPTRPreference", "path": "*rep.Answer.Preference",
|
||||
"type": "*group", "value": "10"},
|
||||
{"tag": "NAPTRFlags", "path": "*rep.Flags",
|
||||
{"tag": "NAPTRFlags", "path": "*rep.Answer.Flags",
|
||||
"type": "*group", "value": "U"},
|
||||
{"tag": "NAPTRService", "path": "*rep.Service",
|
||||
{"tag": "NAPTRService", "path": "*rep.Answer.Service",
|
||||
"type": "*group", "value": "E2U+SIP"},
|
||||
{"tag": "NAPTRRegexp", "path": "*rep.Regexp", "type": "*group",
|
||||
{"tag": "NAPTRRegexp", "path": "*rep.Answer.Regexp", "type": "*group",
|
||||
"value": "~*cgrep.RouteProfiles[0].Routes[1].RouteParameters"},
|
||||
{"tag": "NAPTRReplacement", "path": "*rep.Replacement",
|
||||
{"tag": "NAPTRReplacement", "path": "*rep.Answer.Replacement",
|
||||
"type": "*group", "value": "."},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -430,7 +430,7 @@ func (acc *Account) debitCreditBalance(cd *CallDescriptor, count bool, dryRun bo
|
||||
moneyBalanceChecker = false
|
||||
for _, balance := range usefulMoneyBalances {
|
||||
partCC, debitErr := balance.debit(cd, balance.account,
|
||||
usefulMoneyBalances, count, dryRun, len(cc.Timespans) == 0,false)
|
||||
usefulMoneyBalances, count, dryRun, len(cc.Timespans) == 0, false)
|
||||
if debitErr != nil {
|
||||
return nil, debitErr
|
||||
}
|
||||
|
||||
12
go.mod
12
go.mod
@@ -8,7 +8,7 @@ go 1.16
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.75.0 // indirect
|
||||
github.com/Azure/go-amqp v0.13.1
|
||||
github.com/Azure/go-amqp v0.15.0
|
||||
github.com/RoaringBitmap/roaring v0.5.5 // indirect
|
||||
github.com/antchfx/xmlquery v1.3.3
|
||||
github.com/antchfx/xpath v1.1.11 // indirect
|
||||
@@ -41,7 +41,7 @@ require (
|
||||
github.com/lib/pq v1.8.0 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.10 // indirect
|
||||
github.com/mediocregopher/radix/v3 v3.7.0
|
||||
github.com/miekg/dns v1.1.35
|
||||
github.com/miekg/dns v1.1.44-0.20210927135021-1630ffe2ca11
|
||||
github.com/mitchellh/mapstructure v1.4.0
|
||||
github.com/nats-io/nats-server/v2 v2.2.6 // indirect
|
||||
github.com/nats-io/nats.go v1.11.0
|
||||
@@ -56,11 +56,11 @@ require (
|
||||
github.com/xdg/stringprep v1.0.1-0.20180714160509-73f8eece6fdc // indirect
|
||||
go.mongodb.org/mongo-driver v1.4.4
|
||||
golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110
|
||||
golang.org/x/mod v0.5.1 // indirect
|
||||
golang.org/x/net v0.0.0-20210924151903-3ad01bbaa167
|
||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a // indirect
|
||||
golang.org/x/sys v0.0.0-20210112091331-59c308dcf3cc // indirect
|
||||
golang.org/x/text v0.3.5 // indirect
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 // indirect
|
||||
golang.org/x/tools v0.1.6 // indirect
|
||||
google.golang.org/api v0.36.0
|
||||
google.golang.org/genproto v0.0.0-20210111234610-22ae2b108f89 // indirect
|
||||
google.golang.org/grpc v1.34.1 // indirect
|
||||
|
||||
48
go.sum
48
go.sum
@@ -36,6 +36,8 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/Azure/go-amqp v0.13.1 h1:dXnEJ89Hf7wMkcBbLqvocZlM4a3uiX9uCxJIvU77+Oo=
|
||||
github.com/Azure/go-amqp v0.13.1/go.mod h1:qj+o8xPCz9tMSbQ83Vp8boHahuRDl5mkNHyt1xlxUTs=
|
||||
github.com/Azure/go-amqp v0.15.0 h1:YcB++F5msgyl8htdsjjlhK132YFca31FBPB7lObE/p0=
|
||||
github.com/Azure/go-amqp v0.15.0/go.mod h1:9YJ3RhxRT1gquYnzpZO1vcYMMpAdJT+QEg6fwmw9Zlg=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/RoaringBitmap/roaring v0.4.23/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06Mq5mKs52e1TwOo=
|
||||
@@ -218,7 +220,6 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
@@ -237,8 +238,8 @@ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
@@ -384,8 +385,8 @@ github.com/mattn/go-runewidth v0.0.10 h1:CoZ3S2P7pvtP45xOtBw+/mDL2z0RKI576gSkzRR
|
||||
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
||||
github.com/mediocregopher/radix/v3 v3.7.0 h1:SM9zJdme5pYGEVvh1HttjBjDmIaNBDKy+oDCv5w81Wo=
|
||||
github.com/mediocregopher/radix/v3 v3.7.0/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8=
|
||||
github.com/miekg/dns v1.1.35 h1:oTfOaDH+mZkdcgdIjH6yBajRGtIwcwcaR+rt23ZSrJs=
|
||||
github.com/miekg/dns v1.1.35/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||
github.com/miekg/dns v1.1.44-0.20210927135021-1630ffe2ca11 h1:x/LgmprhSZSR5CV8wFas/6sMT2U70LGgKog/P0Oe+jA=
|
||||
github.com/miekg/dns v1.1.44-0.20210927135021-1630ffe2ca11/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
|
||||
github.com/minio/highwayhash v1.0.1 h1:dZ6IIu8Z14VlC0VpfKofAhCy74wu/Qb5gcn52yWoz/0=
|
||||
github.com/minio/highwayhash v1.0.1/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
@@ -409,10 +410,6 @@ github.com/nats-io/nkeys v0.3.0 h1:cgM5tL53EvYRU+2YLXIK0G2mJtK12Ft9oeooSZMA2G8=
|
||||
github.com/nats-io/nkeys v0.3.0/go.mod h1:gvUNGjVcM2IPr5rCsRsC6Wb3Hr2CQAm08dsxtV6A5y4=
|
||||
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
|
||||
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||
github.com/nyaruka/phonenumbers v1.0.60 h1:nnAcNwmZflhegiImm6MkvjlRRyoaSw1ox/jGPAewWTg=
|
||||
github.com/nyaruka/phonenumbers v1.0.60/go.mod h1:sDaTZ/KPX5f8qyV9qN+hIm+4ZBARJrupC6LuhshJq1U=
|
||||
github.com/nyaruka/phonenumbers v1.0.70 h1:AecpfeQ8/qWKzkZM2NZZEoq5B+qAuH9MUmHK397U7CQ=
|
||||
github.com/nyaruka/phonenumbers v1.0.70/go.mod h1:sDaTZ/KPX5f8qyV9qN+hIm+4ZBARJrupC6LuhshJq1U=
|
||||
github.com/nyaruka/phonenumbers v1.0.71 h1:itkCGhxkQkHrJ6OyZSApdjQVlPmrWs88MF283pPvbFU=
|
||||
github.com/nyaruka/phonenumbers v1.0.71/go.mod h1:sDaTZ/KPX5f8qyV9qN+hIm+4ZBARJrupC6LuhshJq1U=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
@@ -508,6 +505,8 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
||||
go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0=
|
||||
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
||||
@@ -577,6 +576,9 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
|
||||
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -591,7 +593,6 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191119073136-fc4aabc6c914/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
@@ -613,8 +614,12 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
|
||||
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210924151903-3ad01bbaa167 h1:eDd+TJqbgfXruGQ5sJRU7tEtp/58OAx4+Ayjxg4SM+4=
|
||||
golang.org/x/net v0.0.0-20210924151903-3ad01bbaa167/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@@ -634,8 +639,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -657,7 +662,6 @@ golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -680,8 +684,13 @@ golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210112091331-59c308dcf3cc h1:y0Og6AYdwus7SIAnKnDxjc4gJetRiYEWOx4AKbOeyEI=
|
||||
golang.org/x/sys v0.0.0-20210112091331-59c308dcf3cc/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 h1:foEbQz/B0Oz6YIqu/69kfXPYeFQAuuMYFkjaqXzl5Wo=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@@ -689,8 +698,8 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@@ -724,7 +733,6 @@ golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtn
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
@@ -751,6 +759,9 @@ golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4f
|
||||
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.6 h1:SIasE1FVIQOWz2GEAHFOmoW7xchJcqlucjSULTL0Ag4=
|
||||
golang.org/x/tools v0.1.6/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
||||
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@@ -847,7 +858,6 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
|
||||
@@ -172,6 +172,7 @@ cgrates (0.11.0~dev) UNRELEASED; urgency=medium
|
||||
* [CacheS] Updated LoadCache and ReloadCache APIs
|
||||
* [EEs] Added *log exporter
|
||||
* [AttributeS] Added profile_runs to control how many times a profile is proccessed for an event
|
||||
* [DNSAgent] Updated Msg handling from templates
|
||||
|
||||
-- DanB <danb@cgrates.org> Wed, 19 Feb 2020 13:25:52 +0200
|
||||
|
||||
|
||||
@@ -696,6 +696,8 @@ const (
|
||||
MetaSIPURIMethod = "*sipuri_method"
|
||||
MetaSIPURIHost = "*sipuri_host"
|
||||
MetaSIPURIUser = "*sipuri_user"
|
||||
E164DomainConverter = "*e164Domain"
|
||||
E164Converter = "*e164"
|
||||
MetaReload = "*reload"
|
||||
MetaLoad = "*load"
|
||||
MetaFloat64 = "*float64"
|
||||
@@ -713,7 +715,6 @@ const (
|
||||
DNSAgent = "DNSAgent"
|
||||
TLSNoCaps = "tls"
|
||||
UsageID = "UsageID"
|
||||
Rcode = "Rcode"
|
||||
Replacement = "Replacement"
|
||||
Regexp = "Regexp"
|
||||
Order = "Order"
|
||||
@@ -853,6 +854,26 @@ const (
|
||||
BalanceIDs = "BalanceIDs"
|
||||
MetaCostIncrement = "*costIncrement"
|
||||
Length = "Length"
|
||||
|
||||
// dns
|
||||
Rcode = "Rcode"
|
||||
Id = "Id"
|
||||
Response = "Response"
|
||||
Opcode = "Opcode"
|
||||
Authoritative = "Authoritative"
|
||||
Truncated = "Truncated"
|
||||
RecursionDesired = "RecursionDesired"
|
||||
RecursionAvailable = "RecursionAvailable"
|
||||
Zero = "Zero"
|
||||
AuthenticatedData = "AuthenticatedData"
|
||||
CheckingDisabled = "CheckingDisabled"
|
||||
Question = "Question"
|
||||
Answer = "Answer"
|
||||
Ns = "Ns"
|
||||
Extra = "Extra"
|
||||
Name = "Name"
|
||||
Qtype = "Qtype"
|
||||
Qclass = "Qclass"
|
||||
)
|
||||
|
||||
// Migrator Action
|
||||
|
||||
@@ -21,6 +21,7 @@ package utils
|
||||
import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net"
|
||||
@@ -94,6 +95,10 @@ func NewDataConverter(params string) (conv DataConverter, err error) {
|
||||
return new(SliceConverter), nil
|
||||
case params == MetaFloat64:
|
||||
return new(Float64Converter), nil
|
||||
case params == E164DomainConverter:
|
||||
return new(e164DomainConverter), nil
|
||||
case params == E164Converter:
|
||||
return new(e164Converter), nil
|
||||
case strings.HasPrefix(params, MetaLibPhoneNumber):
|
||||
if len(params) == len(MetaLibPhoneNumber) {
|
||||
return NewPhoneNumberConverter(EmptyString)
|
||||
@@ -547,3 +552,27 @@ type Float64Converter struct{}
|
||||
func (Float64Converter) Convert(in interface{}) (interface{}, error) {
|
||||
return IfaceAsFloat64(in)
|
||||
}
|
||||
|
||||
// e164DomainConverter extracts the domain part out of a NAPTR name record
|
||||
type e164DomainConverter struct{}
|
||||
|
||||
func (e164DomainConverter) Convert(in interface{}) (interface{}, error) {
|
||||
name := IfaceAsString(in)
|
||||
if i := strings.Index(name, ".e164."); i != -1 {
|
||||
name = name[i:]
|
||||
}
|
||||
return strings.Trim(name, "."), nil
|
||||
}
|
||||
|
||||
// e164Converter extracts the E164 address out of a NAPTR name record
|
||||
type e164Converter struct{}
|
||||
|
||||
func (e164Converter) Convert(in interface{}) (interface{}, error) {
|
||||
name := IfaceAsString(in)
|
||||
i := strings.Index(name, ".e164.")
|
||||
if i == -1 {
|
||||
return nil, errors.New("unknown format")
|
||||
}
|
||||
return ReverseString(
|
||||
strings.Replace(name[:i], ".", "", -1)), nil
|
||||
}
|
||||
|
||||
@@ -1181,3 +1181,45 @@ func TestSliceConverter(t *testing.T) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", expected, rcv)
|
||||
}
|
||||
}
|
||||
|
||||
func TestE164FromNAPTRConverter(t *testing.T) {
|
||||
exp := new(e164Converter)
|
||||
cnv, err := NewDataConverter(E164Converter)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !reflect.DeepEqual(exp, cnv) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", exp, cnv)
|
||||
}
|
||||
if e164, err := cnv.Convert("8.7.6.5.4.3.2.1.0.1.6.e164.arpa."); err != nil {
|
||||
t.Error(err)
|
||||
} else if e164 != "61012345678" {
|
||||
t.Errorf("received: <%s>", e164)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDomainNameFromNAPTRConverter(t *testing.T) {
|
||||
exp := new(e164DomainConverter)
|
||||
cnv, err := NewDataConverter(E164DomainConverter)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !reflect.DeepEqual(exp, cnv) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", exp, cnv)
|
||||
}
|
||||
if dName, err := cnv.Convert("8.7.6.5.4.3.2.1.0.1.6.e164.arpa."); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if dName != "e164.arpa" {
|
||||
t.Errorf("received: <%s>", dName)
|
||||
}
|
||||
if dName, err := cnv.Convert("8.7.6.5.4.3.2.1.0.1.6.e164.itsyscom.com."); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if dName != "e164.itsyscom.com" {
|
||||
t.Errorf("received: <%s>", dName)
|
||||
}
|
||||
if dName, err := cnv.Convert("8.7.6.5.4.3.2.1.0.1.6.itsyscom.com."); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if dName != "8.7.6.5.4.3.2.1.0.1.6.itsyscom.com" {
|
||||
t.Errorf("received: <%s>", dName)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user