diff --git a/agents/diam_it_test.go b/agents/diam_it_test.go index c1f73a71a..bbe90e0f9 100644 --- a/agents/diam_it_test.go +++ b/agents/diam_it_test.go @@ -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 diff --git a/agents/diamagent.go b/agents/diamagent.go index 203547717..95244f30e 100644 --- a/agents/diamagent.go +++ b/agents/diamagent.go @@ -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) diff --git a/agents/diamagent_test.go b/agents/diamagent_test.go index b86255607..648a6254a 100644 --- a/agents/diamagent_test.go +++ b/agents/diamagent_test.go @@ -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 { diff --git a/agents/dnsagent.go b/agents/dnsagent.go index ef7a20e66..b21aec6a1 100644 --- a/agents/dnsagent.go +++ b/agents/dnsagent.go @@ -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() diff --git a/agents/httpagent.go b/agents/httpagent.go index 353217d1d..0d4809b5a 100644 --- a/agents/httpagent.go +++ b/agents/httpagent.go @@ -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 -} diff --git a/agents/libagents.go b/agents/libagents.go new file mode 100644 index 000000000..22e18a58e --- /dev/null +++ b/agents/libagents.go @@ -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 +*/ + +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 +} diff --git a/agents/libdns.go b/agents/libdns.go index 4c73b95a0..785c4d3f5 100644 --- a/agents/libdns.go +++ b/agents/libdns.go @@ -19,93 +19,22 @@ along with this program. If not, see 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 } diff --git a/agents/libdns_test.go b/agents/libdns_test.go index d4056fd85..fb710bf0e 100644 --- a/agents/libdns_test.go +++ b/agents/libdns_test.go @@ -19,7 +19,6 @@ along with this program. If not, see 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: , 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: , 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 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 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 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 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 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 only works with NAPTR` { + err.Error() != `item: <[Answer Replacement]>, err: unsuported dns option type <*dns.A>` { t.Error(err) } diff --git a/agents/librad.go b/agents/librad.go index 564e8409c..1ba66d5bb 100644 --- a/agents/librad.go +++ b/agents/librad.go @@ -19,6 +19,8 @@ along with this program. If not, see 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 } diff --git a/config/objdp.go b/config/objdp.go index fa8aefc67..f9e8adda6 100644 --- a/config/objdp.go +++ b/config/objdp.go @@ -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 diff --git a/data/conf/samples/dnsagent_internal/attributes.json b/data/conf/samples/dnsagent_internal/attributes.json index e0739ee48..839d9cdac 100644 --- a/data/conf/samples/dnsagent_internal/attributes.json +++ b/data/conf/samples/dnsagent_internal/attributes.json @@ -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"}, ], }, diff --git a/data/conf/samples/dnsagent_internal/dryrun.json b/data/conf/samples/dnsagent_internal/dryrun.json index a8fce8adb..ee6627732 100644 --- a/data/conf/samples/dnsagent_internal/dryrun.json +++ b/data/conf/samples/dnsagent_internal/dryrun.json @@ -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": "."}, ], }, ], diff --git a/data/conf/samples/dnsagent_internal/suppliers.json b/data/conf/samples/dnsagent_internal/suppliers.json index c3a0d8c18..d5171f15a 100644 --- a/data/conf/samples/dnsagent_internal/suppliers.json +++ b/data/conf/samples/dnsagent_internal/suppliers.json @@ -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": "."}, ], }, diff --git a/data/conf/samples/dnsagent_mongo/attributes.json b/data/conf/samples/dnsagent_mongo/attributes.json index e0739ee48..839d9cdac 100644 --- a/data/conf/samples/dnsagent_mongo/attributes.json +++ b/data/conf/samples/dnsagent_mongo/attributes.json @@ -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"}, ], }, diff --git a/data/conf/samples/dnsagent_mongo/dryrun.json b/data/conf/samples/dnsagent_mongo/dryrun.json index a8fce8adb..ee6627732 100644 --- a/data/conf/samples/dnsagent_mongo/dryrun.json +++ b/data/conf/samples/dnsagent_mongo/dryrun.json @@ -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": "."}, ], }, ], diff --git a/data/conf/samples/dnsagent_mongo/suppliers.json b/data/conf/samples/dnsagent_mongo/suppliers.json index 72204f004..4d6abb0bf 100644 --- a/data/conf/samples/dnsagent_mongo/suppliers.json +++ b/data/conf/samples/dnsagent_mongo/suppliers.json @@ -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": "."}, ], }, diff --git a/data/conf/samples/dnsagent_mysql/attributes.json b/data/conf/samples/dnsagent_mysql/attributes.json index e0739ee48..839d9cdac 100644 --- a/data/conf/samples/dnsagent_mysql/attributes.json +++ b/data/conf/samples/dnsagent_mysql/attributes.json @@ -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"}, ], }, diff --git a/data/conf/samples/dnsagent_mysql/dryrun.json b/data/conf/samples/dnsagent_mysql/dryrun.json index a8fce8adb..a8815704e 100644 --- a/data/conf/samples/dnsagent_mysql/dryrun.json +++ b/data/conf/samples/dnsagent_mysql/dryrun.json @@ -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": "."}, ], }, ], diff --git a/data/conf/samples/dnsagent_mysql/suppliers.json b/data/conf/samples/dnsagent_mysql/suppliers.json index 9441d4dd8..ed7038143 100644 --- a/data/conf/samples/dnsagent_mysql/suppliers.json +++ b/data/conf/samples/dnsagent_mysql/suppliers.json @@ -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": "."}, ], }, diff --git a/engine/account.go b/engine/account.go index 737fa1295..47990ae72 100644 --- a/engine/account.go +++ b/engine/account.go @@ -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 } diff --git a/go.mod b/go.mod index 6430d6570..ea67ad606 100644 --- a/go.mod +++ b/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 diff --git a/go.sum b/go.sum index 71262275d..497b5f6ec 100644 --- a/go.sum +++ b/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= diff --git a/packages/debian/changelog b/packages/debian/changelog index d974d667f..63e318a5a 100644 --- a/packages/debian/changelog +++ b/packages/debian/changelog @@ -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 Wed, 19 Feb 2020 13:25:52 +0200 diff --git a/utils/consts.go b/utils/consts.go index b38b0688c..dd324c580 100644 --- a/utils/consts.go +++ b/utils/consts.go @@ -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 diff --git a/utils/dataconverter.go b/utils/dataconverter.go index 874d62925..5af5f80d8 100644 --- a/utils/dataconverter.go +++ b/utils/dataconverter.go @@ -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 +} diff --git a/utils/dataconverter_test.go b/utils/dataconverter_test.go index 0ac9c55ca..483a6448b 100644 --- a/utils/dataconverter_test.go +++ b/utils/dataconverter_test.go @@ -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) + } +}