diff --git a/agents/dnsagent_it_test.go b/agents/dnsagent_it_test.go index cc3185fd1..3cc11a844 100644 --- a/agents/dnsagent_it_test.go +++ b/agents/dnsagent_it_test.go @@ -21,311 +21,1496 @@ along with this program. If not, see package agents -// import ( -// "path" -// "testing" -// "time" +import ( + "crypto/tls" + "path" + "testing" + "time" -// "github.com/cgrates/birpc" -// "github.com/cgrates/birpc/context" -// "github.com/cgrates/cgrates/config" -// "github.com/cgrates/cgrates/engine" -// "github.com/cgrates/cgrates/loaders" -// "github.com/cgrates/cgrates/utils" -// "github.com/miekg/dns" -// ) + "github.com/cgrates/birpc" + "github.com/cgrates/birpc/context" + "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/engine" + "github.com/cgrates/cgrates/loaders" + "github.com/cgrates/cgrates/utils" + "github.com/miekg/dns" +) -// var ( -// dnsCfgPath string -// dnsCfgDIR string -// dnsCfg *config.CGRConfig -// dnsRPC *birpc.Client -// dnsClnt *dns.Conn // so we can cache the connection +type dnsConns struct { + UDP *dns.Conn + TCP *dns.Conn + TCPTLS *dns.Conn +} -// sTestsDNS = []func(t *testing.T){ -// testDNSitInitCfg, -// testDNSitResetDB, -// testDNSitStartEngine, -// testDNSitApierRpcConn, -// testDNSitTPFromFolder, -// testDNSitClntConn, -// testDNSitClntNAPTRDryRun, -// testDNSitClntNAPTRAttributes, -// testDNSitClntNAPTRSuppliers, -// testDNSitClntNAPTROpts, -// testDNSitClntNAPTROptsWithAttributes, -// testDNSitStopEngine, -// } -// ) +var ( + dnsCfgPath string + dnsCfgDIR string + dnsCfg *config.CGRConfig + dnsRPC *birpc.Client + dnsClnt *dnsConns // so we can cache the connection -// func TestDNSitSimple(t *testing.T) { -// switch *dbType { -// case utils.MetaInternal: -// dnsCfgDIR = "dnsagent_internal" -// case utils.MetaMySQL: -// dnsCfgDIR = "dnsagent_mysql" -// case utils.MetaMongo: -// dnsCfgDIR = "dnsagent_mongo" -// case utils.MetaPostgres: -// t.SkipNow() -// default: -// t.Fatal("Unknown Database type") -// } -// for _, stest := range sTestsDNS { -// t.Run(dnsCfgDIR, stest) -// } -// } + sTestsDNS = []func(t *testing.T){ + testDNSitInitCfg, + testDNSitResetDB, + testDNSitStartEngine, + testDNSitApierRpcConn, + testDNSitTPFromFolder, + testDNSitClntConn, + testDNSitClntADryRun, + testDNSitClntSRVDryRun, + testDNSitClntNAPTRDryRun, + testDNSitClntAAttributes, + testDNSitClntSRVAttributes, + testDNSitClntNAPTRAttributes, + testDNSitClntASuppliers, + testDNSitClntSRVSuppliers, + testDNSitClntNAPTRSuppliers, + testDNSitClntAOpts, + testDNSitClntSRVOpts, + testDNSitClntNAPTROpts, + testDNSitClntAOptsWithAttributes, + testDNSitClntSRVOptsWithAttributes, + testDNSitClntNAPTROptsWithAttributes, + testDNSitStopEngine, + } +) -// // Init config -// func testDNSitInitCfg(t *testing.T) { -// var err error -// dnsCfgPath = path.Join(*dataDir, "conf", "samples", dnsCfgDIR) -// dnsCfg, err = config.NewCGRConfigFromPath(context.Background(), dnsCfgPath) -// if err != nil { -// t.Error(err) -// } -// } +func TestDNSitSimple(t *testing.T) { + switch *dbType { + case utils.MetaInternal: + dnsCfgDIR = "dnsagent_internal" + case utils.MetaMySQL: + dnsCfgDIR = "dnsagent_mysql" + case utils.MetaMongo: + dnsCfgDIR = "dnsagent_mongo" + case utils.MetaPostgres: + t.SkipNow() + default: + t.Fatal("Unknown Database type") + } + for _, stest := range sTestsDNS { + t.Run(dnsCfgDIR, stest) + } +} -// // Remove data in both rating and accounting db -// func testDNSitResetDB(t *testing.T) { -// if err := engine.InitDataDB(dnsCfg); err != nil { -// t.Fatal(err) -// } +// Init config +func testDNSitInitCfg(t *testing.T) { + var err error + dnsCfgPath = path.Join(*dataDir, "conf", "samples", dnsCfgDIR) + dnsCfg, err = config.NewCGRConfigFromPath(context.Background(), dnsCfgPath) + if err != nil { + t.Error(err) + } +} -// } +// Remove data in both rating and accounting db +func testDNSitResetDB(t *testing.T) { + if err := engine.InitDataDB(dnsCfg); err != nil { + t.Fatal(err) + } -// // Start CGR Engine -// func testDNSitStartEngine(t *testing.T) { -// if _, err := engine.StopStartEngine(dnsCfgPath, *waitRater); err != nil { -// t.Fatal(err) -// } -// } +} -// // Connect rpc client to rater -// func testDNSitApierRpcConn(t *testing.T) { -// var err error -// dnsRPC, err = newRPCClient(dnsCfg.ListenCfg()) // We connect over JSON so we can also troubleshoot if needed -// if err != nil { -// t.Fatal(err) -// } -// } +// Start CGR Engine +func testDNSitStartEngine(t *testing.T) { + if _, err := engine.StopStartEngine(dnsCfgPath, *waitRater); err != nil { + t.Fatal(err) + } +} -// // Load the tariff plan, creating accounts and their balances -// func testDNSitTPFromFolder(t *testing.T) { -// caching := utils.MetaReload -// if dnsCfg.DataDbCfg().Type == utils.Internal { -// caching = utils.MetaNone -// } -// var reply string -// if err := dnsRPC.Call(context.Background(), utils.LoaderSv1Run, -// &loaders.ArgsProcessFolder{ -// APIOpts: map[string]any{ -// utils.MetaCache: caching, -// utils.MetaStopOnError: false, -// }, -// }, &reply); err != nil { -// t.Error(err) -// } else if reply != utils.OK { -// t.Error("Unexpected reply returned:", reply) -// } -// time.Sleep(time.Duration(*waitRater) * time.Millisecond) // Give time for scheduler to execute topups -// } +// Connect rpc client to rater +func testDNSitApierRpcConn(t *testing.T) { + var err error + dnsRPC, err = newRPCClient(dnsCfg.ListenCfg()) // We connect over JSON so we can also troubleshoot if needed + if err != nil { + t.Fatal(err) + } +} -// // Connect DNS client to server -// func testDNSitClntConn(t *testing.T) { -// c := new(dns.Client) -// var err error -// if dnsClnt, err = c.Dial(dnsCfg.DNSAgentCfg().Listen); err != nil { // just testing the connection, not not saving it -// t.Fatal(err) -// } else if dnsClnt == nil { -// t.Fatalf("conn is nil") -// } -// } +// Load the tariff plan, creating accounts and their balances +func testDNSitTPFromFolder(t *testing.T) { + caching := utils.MetaReload + if dnsCfg.DataDbCfg().Type == utils.MetaInternal { + caching = utils.MetaNone + } + var reply string + if err := dnsRPC.Call(context.Background(), utils.LoaderSv1Run, + &loaders.ArgsProcessFolder{ + APIOpts: map[string]any{ + utils.MetaCache: caching, + }, + }, &reply); err != nil { + t.Error(err) + } else if reply != utils.OK { + t.Error("Unexpected reply returned:", reply) + } + time.Sleep(time.Duration(*waitRater) * time.Millisecond) // Give time for scheduler to execute topups +} -// func testDNSitClntNAPTRDryRun(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) -// if err := dnsClnt.WriteMsg(m); err != nil { -// t.Error(err) -// } -// if rply, err := dnsClnt.ReadMsg(); err != nil { -// t.Error(err) -// } else { -// if rply.Rcode != dns.RcodeSuccess { -// t.Errorf("failed to get a valid answer\n%v", rply) -// } -// answr := rply.Answer[0].(*dns.NAPTR) -// if answr.Order != 100 { -// t.Errorf("received: <%q>", answr.Order) -// } -// if answr.Preference != 10 { -// t.Errorf("received: <%q>", answr.Preference) -// } -// if answr.Flags != "U" { -// t.Errorf("received: <%q>", answr.Flags) -// } -// if answr.Service != "E2U+SIP" { -// t.Errorf("received: <%q>", answr.Service) -// } -// if answr.Regexp != "!^(.*)$!sip:1@172.16.1.10.!" { -// t.Errorf("received: <%q>", answr.Regexp) -// } -// if answr.Replacement != "." { -// t.Errorf("received: <%q>", answr.Replacement) -// } -// } -// } +// Connect DNS client to server +func testDNSitClntConn(t *testing.T) { + c := new(dns.Client) + c.TLSConfig = &tls.Config{} + var err error + dnsClnt = &dnsConns{} + if dnsClnt.UDP, err = c.Dial(dnsCfg.DNSAgentCfg().Listeners[0].Address); err != nil { // just testing the connection, not saving it + t.Fatal(err) + } else if dnsClnt.UDP == nil { + t.Fatalf("conn is nil") + } -// func testDNSitClntNAPTRAttributes(t *testing.T) { -// m := new(dns.Msg) -// m.SetQuestion("4.6.9.4.7.1.7.1.5.6.8.9.4.e164.arpa.", dns.TypeNAPTR) -// if err := dnsClnt.WriteMsg(m); err != nil { -// t.Error(err) -// } -// if rply, err := dnsClnt.ReadMsg(); err != nil { -// t.Error(err) -// } else { -// if rply.Rcode != dns.RcodeSuccess { -// t.Errorf("failed to get an valid answer\n%v", rply) -// } -// answr := rply.Answer[0].(*dns.NAPTR) -// if answr.Order != 100 { -// t.Errorf("received: <%q>", answr.Order) -// } -// if answr.Regexp != "sip:1@172.16.1.1." { -// t.Errorf("Expected :<%q> , received: <%q>", "sip:1\\@172.16.1.1.", answr.Regexp) -// } -// } -// } + c.Net = dnsCfg.DNSAgentCfg().Listeners[0].Network -// func testDNSitClntNAPTRSuppliers(t *testing.T) { -// m := new(dns.Msg) -// m.SetQuestion("5.6.9.4.7.1.7.1.5.6.8.9.4.e164.arpa.", dns.TypeNAPTR) -// if err := dnsClnt.WriteMsg(m); err != nil { -// t.Error(err) -// } -// rply, err := dnsClnt.ReadMsg() -// if err != nil { -// t.Error(err) -// } else if len(rply.Answer) != 2 { -// t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) -// } -// if rply.Rcode != dns.RcodeSuccess { -// t.Errorf("failed to get an valid answer\n%v", rply) -// } -// answr := rply.Answer[0].(*dns.NAPTR) -// if answr.Order != 100 { -// t.Errorf("received: <%v>", answr.Order) -// } -// if answr.Regexp != "!^(.*)$!sip:1@172.16.1.11!" { -// t.Errorf("received: <%q>", answr.Regexp) -// } -// answr2 := rply.Answer[1].(*dns.NAPTR) -// if answr2.Regexp != "!^(.*)$!sip:1@172.16.1.12!" { -// t.Errorf("received: <%q>", answr2.Regexp) -// } -// } + if dnsClnt.TCP, err = c.Dial(dnsCfg.DNSAgentCfg().Listeners[0].Address); err != nil { // tcp has the same address as udp in this case so we can use the same here + t.Fatal(err) + } else if dnsClnt.TCP == nil { + t.Fatalf("conn is nil") + } -// func testDNSitClntNAPTROpts(t *testing.T) { -// m := new(dns.Msg) -// m.SetQuestion("5.6.9.4.7.1.7.1.5.6.8.9.5.e164.arpa.", dns.TypeNAPTR) -// m.SetEdns0(4096, false) -// m.IsEdns0().Option = append(m.IsEdns0().Option, &dns.EDNS0_ESU{Uri: "sip:cgrates@cgrates.org"}) -// if err := dnsClnt.WriteMsg(m); err != nil { -// t.Error(err) -// } -// rply, err := dnsClnt.ReadMsg() -// if err != nil { -// t.Error(err) -// } else if len(rply.Answer) != 1 { -// t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) -// } -// if rply.Rcode != dns.RcodeSuccess { -// t.Errorf("failed to get an valid answer\n%v", rply) -// } -// answr := rply.Answer[0].(*dns.NAPTR) -// if answr.Order != 100 { -// t.Errorf("received: <%q>", answr.Order) -// } -// if answr.Preference != 10 { -// t.Errorf("received: <%q>", answr.Preference) -// } -// if answr.Flags != "U" { -// t.Errorf("received: <%q>", answr.Flags) -// } -// if answr.Service != "E2U+SIP" { -// t.Errorf("received: <%q>", answr.Service) -// } -// if answr.Regexp != "!^(.*)$!sip:1@172.16.1.10.!" { -// t.Errorf("received: <%q>", answr.Regexp) -// } -// if answr.Replacement != "." { -// t.Errorf("received: <%q>", answr.Replacement) -// } -// if opts := rply.IsEdns0(); opts == nil { -// t.Error("recieved nil options") -// } else if len(opts.Option) != 2 { -// t.Errorf("recieved wrong number of options: %v", len(opts.Option)) -// } else if ov, can := opts.Option[0].(*dns.EDNS0_ESU); !can { -// t.Errorf("recieved wrong option type: %T", opts.Option[0]) -// } else if expected := "sip:cgrates@cgrates.com"; ov.Uri != expected { -// t.Errorf("Expected :<%q> , received: <%q>", expected, ov.Uri) -// } else if ov, can := opts.Option[1].(*dns.EDNS0_ESU); !can { -// t.Errorf("recieved wrong option type: %T", opts.Option[1]) -// } else if expected := "sip:cgrates@cgrates.net"; ov.Uri != expected { -// t.Errorf("Expected :<%q> , received: <%q>", expected, ov.Uri) -// } -// } + c.Net = dnsCfg.DNSAgentCfg().Listeners[1].Network + c.TLSConfig.InsecureSkipVerify = true + if dnsClnt.TCPTLS, err = c.Dial(dnsCfg.DNSAgentCfg().Listeners[1].Address); err != nil { // tcp and tcp-tls cannot be on the same address, otherwise tcp-tls and udp is allowed + t.Fatal(err) + } else if dnsClnt.TCPTLS == nil { + t.Fatalf("conn is nil") + } -// func testDNSitClntNAPTROptsWithAttributes(t *testing.T) { -// m := new(dns.Msg) -// m.SetQuestion("7.6.9.4.7.1.7.1.5.6.8.9.5.e164.arpa.", dns.TypeNAPTR) -// m.SetEdns0(4096, false) -// m.IsEdns0().Option = append(m.IsEdns0().Option, &dns.EDNS0_ESU{Uri: "sip:cgrates@cgrates.org"}) -// if err := dnsClnt.WriteMsg(m); err != nil { -// t.Error(err) -// } -// rply, err := dnsClnt.ReadMsg() -// if err != nil { -// t.Error(err) -// } else if len(rply.Answer) != 1 { -// t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) -// } -// if rply.Rcode != dns.RcodeSuccess { -// t.Errorf("failed to get an valid answer\n%v", rply) -// } -// answr := rply.Answer[0].(*dns.NAPTR) -// if answr.Order != 100 { -// t.Errorf("received: <%q>", answr.Order) -// } -// if answr.Preference != 10 { -// t.Errorf("received: <%q>", answr.Preference) -// } -// if answr.Flags != "U" { -// t.Errorf("received: <%q>", answr.Flags) -// } -// if answr.Service != "E2U+SIP" { -// t.Errorf("received: <%q>", answr.Service) -// } -// if answr.Regexp != "!^(.*)$!sip:1@172.16.1.10.!" { -// t.Errorf("received: <%q>", answr.Regexp) -// } -// if answr.Replacement != "." { -// t.Errorf("received: <%q>", answr.Replacement) -// } -// if opts := rply.IsEdns0(); opts == nil { -// t.Error("recieved nil options") -// } else if len(opts.Option) != 1 { -// t.Errorf("recieved wrong number of options: %v", len(opts.Option)) -// } else if ov, can := opts.Option[0].(*dns.EDNS0_ESU); !can { -// t.Errorf("recieved wrong option type: %T", opts.Option[0]) -// } else if expected := "sip:cgrates@e164.arpa"; ov.Uri != expected { -// t.Errorf("Expected :<%q> , received: <%q>", expected, ov.Uri) -// } -// } +} -// func testDNSitStopEngine(t *testing.T) { -// if err := engine.KillEngine(*waitRater); err != nil { -// t.Error(err) -// } -// } +func testDNSitClntADryRun(t *testing.T) { + m := new(dns.Msg) + m.SetQuestion("cgrates.org.", dns.TypeA) + if err := dnsClnt.UDP.WriteMsg(m); err != nil { + t.Error(err) + } + if rply, err := dnsClnt.UDP.ReadMsg(); err != nil { + t.Error(err) + } else if len(rply.Answer) != 1 { + t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) + } else { + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr0 := rply.Answer[0].(*dns.A) + if answr0.A.String() != "51.38.77.188" { + t.Errorf("Expected :<%q> , received: <%q>", "51.38.77.188", answr0.A) + } + } + if err := dnsClnt.TCP.WriteMsg(m); err != nil { + t.Error(err) + } + if rply, err := dnsClnt.TCP.ReadMsg(); err != nil { + t.Error(err) + } else if len(rply.Answer) != 1 { + t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) + } else { + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr0 := rply.Answer[0].(*dns.A) + if answr0.A.String() != "51.38.77.188" { + t.Errorf("Expected :<%q> , received: <%q>", "51.38.77.188", answr0.A) + } + } + if err := dnsClnt.TCPTLS.WriteMsg(m); err != nil { + t.Error(err) + } + if rply, err := dnsClnt.TCPTLS.ReadMsg(); err != nil { + t.Error(err) + } else if len(rply.Answer) != 1 { + t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) + } else { + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr0 := rply.Answer[0].(*dns.A) + if answr0.A.String() != "51.38.77.188" { + t.Errorf("Expected :<%q> , received: <%q>", "51.38.77.188", answr0.A) + } + } +} +func testDNSitClntSRVDryRun(t *testing.T) { + m := new(dns.Msg) + m.SetQuestion("_sip._tcp.opensips.org.", dns.TypeSRV) + if err := dnsClnt.UDP.WriteMsg(m); err != nil { + t.Error(err) + } + if rply, err := dnsClnt.UDP.ReadMsg(); err != nil { + t.Error(err) + } else if len(rply.Answer) != 1 { + t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) + } else { + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr := rply.Answer[0].(*dns.SRV) + if answr.Priority != uint16(0) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(0), answr.Priority) + } + if answr.Weight != uint16(50) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(50), answr.Weight) + } + if answr.Port != uint16(5060) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(5060), answr.Port) + } + if answr.Target != "opensips.org." { + t.Errorf("Expected :<%q> , received: <%q>", "opensips.org.", answr.Target) + } + } + if err := dnsClnt.TCP.WriteMsg(m); err != nil { + t.Error(err) + } + if rply, err := dnsClnt.TCP.ReadMsg(); err != nil { + t.Error(err) + } else if len(rply.Answer) != 1 { + t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) + } else { + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr := rply.Answer[0].(*dns.SRV) + if answr.Priority != uint16(0) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(0), answr.Priority) + } + if answr.Weight != uint16(50) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(50), answr.Weight) + } + if answr.Port != uint16(5060) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(5060), answr.Port) + } + if answr.Target != "opensips.org." { + t.Errorf("Expected :<%q> , received: <%q>", "opensips.org.", answr.Target) + } + } + if err := dnsClnt.TCPTLS.WriteMsg(m); err != nil { + t.Error(err) + } + if rply, err := dnsClnt.TCPTLS.ReadMsg(); err != nil { + t.Error(err) + } else if len(rply.Answer) != 1 { + t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) + } else { + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr := rply.Answer[0].(*dns.SRV) + if answr.Priority != uint16(0) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(0), answr.Priority) + } + if answr.Weight != uint16(50) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(50), answr.Weight) + } + if answr.Port != uint16(5060) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(5060), answr.Port) + } + if answr.Target != "opensips.org." { + t.Errorf("Expected :<%q> , received: <%q>", "opensips.org.", answr.Target) + } + } +} + +func testDNSitClntNAPTRDryRun(t *testing.T) { + m := new(dns.Msg) + m.SetQuestion("4.6.9.4.7.1.7.1.5.6.8.9.4.e164.arpa.", dns.TypeNAPTR) + if err := dnsClnt.UDP.WriteMsg(m); err != nil { + t.Error(err) + } + if rply, err := dnsClnt.UDP.ReadMsg(); err != nil { + t.Error(err) + } else { + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr := rply.Answer[0].(*dns.NAPTR) + if answr.Order != 100 { + t.Errorf("received: <%q>", answr.Order) + } + if answr.Regexp != "sip:1@172.16.1.1." { + t.Errorf("Expected :<%q> , received: <%q>", "sip:1\\@172.16.1.1.", answr.Regexp) + } + } + if err := dnsClnt.TCP.WriteMsg(m); err != nil { + t.Error(err) + } + if rply, err := dnsClnt.TCP.ReadMsg(); err != nil { + t.Error(err) + } else { + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr := rply.Answer[0].(*dns.NAPTR) + if answr.Order != 100 { + t.Errorf("received: <%q>", answr.Order) + } + if answr.Regexp != "sip:1@172.16.1.1." { + t.Errorf("Expected :<%q> , received: <%q>", "sip:1\\@172.16.1.1.", answr.Regexp) + } + } + if err := dnsClnt.TCPTLS.WriteMsg(m); err != nil { + t.Error(err) + } + if rply, err := dnsClnt.TCPTLS.ReadMsg(); err != nil { + t.Error(err) + } else { + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr := rply.Answer[0].(*dns.NAPTR) + if answr.Order != 100 { + t.Errorf("received: <%q>", answr.Order) + } + if answr.Regexp != "sip:1@172.16.1.1." { + t.Errorf("Expected :<%q> , received: <%q>", "sip:1\\@172.16.1.1.", answr.Regexp) + } + } +} + +func testDNSitClntAAttributes(t *testing.T) { + m := new(dns.Msg) + m.SetQuestion("dns.google.", dns.TypeA) + if err := dnsClnt.UDP.WriteMsg(m); err != nil { + t.Error(err) + } + if rply, err := dnsClnt.UDP.ReadMsg(); err != nil { + t.Error(err) + } else if len(rply.Answer) != 2 { + t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) + } else { + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr0 := rply.Answer[0].(*dns.A) + if answr0.A.String() != "8.8.8.8" { + t.Errorf("Expected :<%q> , received: <%q>", "8.8.8.8", answr0.A) + } + answr1 := rply.Answer[1].(*dns.A) + if answr1.A.String() != "8.8.4.4" { + t.Errorf("Expected :<%q> , received: <%q>", "8.8.4.4", answr1.A) + } + } + if err := dnsClnt.TCP.WriteMsg(m); err != nil { + t.Error(err) + } + if rply, err := dnsClnt.TCP.ReadMsg(); err != nil { + t.Error(err) + } else if len(rply.Answer) != 2 { + t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) + } else { + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr0 := rply.Answer[0].(*dns.A) + if answr0.A.String() != "8.8.8.8" { + t.Errorf("Expected :<%q> , received: <%q>", "8.8.8.8", answr0.A) + } + answr1 := rply.Answer[1].(*dns.A) + if answr1.A.String() != "8.8.4.4" { + t.Errorf("Expected :<%q> , received: <%q>", "8.8.4.4", answr1.A) + } + } + if err := dnsClnt.TCPTLS.WriteMsg(m); err != nil { + t.Error(err) + } + if rply, err := dnsClnt.TCPTLS.ReadMsg(); err != nil { + t.Error(err) + } else if len(rply.Answer) != 2 { + t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) + } else { + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr0 := rply.Answer[0].(*dns.A) + if answr0.A.String() != "8.8.8.8" { + t.Errorf("Expected :<%q> , received: <%q>", "8.8.8.8", answr0.A) + } + answr1 := rply.Answer[1].(*dns.A) + if answr1.A.String() != "8.8.4.4" { + t.Errorf("Expected :<%q> , received: <%q>", "8.8.4.4", answr1.A) + } + } +} + +func testDNSitClntSRVAttributes(t *testing.T) { + m := new(dns.Msg) + m.SetQuestion("_ldap._tcp.google.com.", dns.TypeSRV) + if err := dnsClnt.UDP.WriteMsg(m); err != nil { + t.Error(err) + } + if rply, err := dnsClnt.UDP.ReadMsg(); err != nil { + t.Error(err) + } else { + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr := rply.Answer[0].(*dns.SRV) + if answr.Priority != uint16(5) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(5), answr.Priority) + } + if answr.Weight != uint16(0) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(0), answr.Weight) + } + if answr.Port != uint16(389) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(389), answr.Port) + } + if answr.Target != "ldap.google.com." { + t.Errorf("Expected :<%q> , received: <%q>", "ldap.google.com.", answr.Target) + } + } + if err := dnsClnt.TCP.WriteMsg(m); err != nil { + t.Error(err) + } + if rply, err := dnsClnt.TCP.ReadMsg(); err != nil { + t.Error(err) + } else { + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr := rply.Answer[0].(*dns.SRV) + if answr.Priority != uint16(5) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(5), answr.Priority) + } + if answr.Weight != uint16(0) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(0), answr.Weight) + } + if answr.Port != uint16(389) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(389), answr.Port) + } + if answr.Target != "ldap.google.com." { + t.Errorf("Expected :<%q> , received: <%q>", "ldap.google.com.", answr.Target) + } + } + if err := dnsClnt.TCPTLS.WriteMsg(m); err != nil { + t.Error(err) + } + if rply, err := dnsClnt.TCPTLS.ReadMsg(); err != nil { + t.Error(err) + } else { + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr := rply.Answer[0].(*dns.SRV) + if answr.Priority != uint16(5) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(5), answr.Priority) + } + if answr.Weight != uint16(0) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(0), answr.Weight) + } + if answr.Port != uint16(389) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(389), answr.Port) + } + if answr.Target != "ldap.google.com." { + t.Errorf("Expected :<%q> , received: <%q>", "ldap.google.com.", answr.Target) + } + } +} + +func testDNSitClntNAPTRAttributes(t *testing.T) { + m := new(dns.Msg) + m.SetQuestion("4.6.9.4.7.1.7.1.5.6.8.9.4.e164.arpa.", dns.TypeNAPTR) + if err := dnsClnt.UDP.WriteMsg(m); err != nil { + t.Error(err) + } + if rply, err := dnsClnt.UDP.ReadMsg(); err != nil { + t.Error(err) + } else { + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr := rply.Answer[0].(*dns.NAPTR) + if answr.Order != 100 { + t.Errorf("received: <%q>", answr.Order) + } + if answr.Regexp != "sip:1@172.16.1.1." { + t.Errorf("Expected :<%q> , received: <%q>", "sip:1\\@172.16.1.1.", answr.Regexp) + } + } + if err := dnsClnt.TCP.WriteMsg(m); err != nil { + t.Error(err) + } + if rply, err := dnsClnt.TCP.ReadMsg(); err != nil { + t.Error(err) + } else { + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr := rply.Answer[0].(*dns.NAPTR) + if answr.Order != 100 { + t.Errorf("received: <%q>", answr.Order) + } + if answr.Regexp != "sip:1@172.16.1.1." { + t.Errorf("Expected :<%q> , received: <%q>", "sip:1\\@172.16.1.1.", answr.Regexp) + } + } + if err := dnsClnt.TCPTLS.WriteMsg(m); err != nil { + t.Error(err) + } + if rply, err := dnsClnt.TCPTLS.ReadMsg(); err != nil { + t.Error(err) + } else { + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr := rply.Answer[0].(*dns.NAPTR) + if answr.Order != 100 { + t.Errorf("received: <%q>", answr.Order) + } + if answr.Regexp != "sip:1@172.16.1.1." { + t.Errorf("Expected :<%q> , received: <%q>", "sip:1\\@172.16.1.1.", answr.Regexp) + } + } +} + +func testDNSitClntASuppliers(t *testing.T) { + m := new(dns.Msg) + m.SetQuestion("go.dev.", dns.TypeA) + if err := dnsClnt.UDP.WriteMsg(m); err != nil { + t.Error(err) + } + rply, err := dnsClnt.UDP.ReadMsg() + if err != nil { + t.Error(err) + } else if len(rply.Answer) != 2 { + t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) + } + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + + answr0 := rply.Answer[0].(*dns.A) + if answr0.A.String() != "216.239.32.21" { + t.Errorf("Expected :<%q> , received: <%q>", "216.239.32.21", answr0.A) + } + answr1 := rply.Answer[1].(*dns.A) + if answr1.A.String() != "216.239.34.21" { + t.Errorf("Expected :<%q> , received: <%q>", "216.239.34.21", answr1.A) + } + if err := dnsClnt.TCP.WriteMsg(m); err != nil { + t.Error(err) + } + rply, err = dnsClnt.TCP.ReadMsg() + if err != nil { + t.Error(err) + } else if len(rply.Answer) != 2 { + t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) + } + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + + answr0 = rply.Answer[0].(*dns.A) + if answr0.A.String() != "216.239.32.21" { + t.Errorf("Expected :<%q> , received: <%q>", "216.239.32.21", answr0.A) + } + answr1 = rply.Answer[1].(*dns.A) + if answr1.A.String() != "216.239.34.21" { + t.Errorf("Expected :<%q> , received: <%q>", "216.239.34.21", answr1.A) + } + if err := dnsClnt.TCPTLS.WriteMsg(m); err != nil { + t.Error(err) + } + rply, err = dnsClnt.TCPTLS.ReadMsg() + if err != nil { + t.Error(err) + } else if len(rply.Answer) != 2 { + t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) + } + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + + answr0 = rply.Answer[0].(*dns.A) + if answr0.A.String() != "216.239.32.21" { + t.Errorf("Expected :<%q> , received: <%q>", "216.239.32.21", answr0.A) + } + answr1 = rply.Answer[1].(*dns.A) + if answr1.A.String() != "216.239.34.21" { + t.Errorf("Expected :<%q> , received: <%q>", "216.239.34.21", answr1.A) + } + +} + +func testDNSitClntSRVSuppliers(t *testing.T) { + m := new(dns.Msg) + m.SetQuestion("_xmpp-client._tcp.xmpp.org.", dns.TypeSRV) + if err := dnsClnt.UDP.WriteMsg(m); err != nil { + t.Error(err) + } + rply, err := dnsClnt.UDP.ReadMsg() + if err != nil { + t.Error(err) + } else if len(rply.Answer) != 2 { + t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) + } + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr := rply.Answer[0].(*dns.SRV) + if answr.Priority != uint16(1) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(1), answr.Priority) + } + if answr.Weight != uint16(1) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(1), answr.Weight) + } + if answr.Port != uint16(9222) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(9222), answr.Port) + } + if answr.Target != "xmpp.xmpp.org." { + t.Errorf("Expected :<%q> , received: <%q>", "xmpp.xmpp.org.", answr.Target) + } + answr2 := rply.Answer[1].(*dns.SRV) + if answr2.Priority != uint16(1) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(1), answr2.Priority) + } + if answr2.Weight != uint16(1) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(1), answr2.Weight) + } + if answr2.Port != uint16(9222) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(9222), answr2.Port) + } + if answr2.Target != "xmpp.xmpp.com." { + t.Errorf("Expected :<%q> , received: <%q>", "xmpp.xmpp.com.", answr2.Target) + } + if err := dnsClnt.TCP.WriteMsg(m); err != nil { + t.Error(err) + } + rply, err = dnsClnt.TCP.ReadMsg() + if err != nil { + t.Error(err) + } else if len(rply.Answer) != 2 { + t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) + } + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr = rply.Answer[0].(*dns.SRV) + if answr.Priority != uint16(1) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(1), answr.Priority) + } + if answr.Weight != uint16(1) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(1), answr.Weight) + } + if answr.Port != uint16(9222) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(9222), answr.Port) + } + if answr.Target != "xmpp.xmpp.org." { + t.Errorf("Expected :<%q> , received: <%q>", "xmpp.xmpp.org.", answr.Target) + } + answr2 = rply.Answer[1].(*dns.SRV) + if answr2.Priority != uint16(1) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(1), answr2.Priority) + } + if answr2.Weight != uint16(1) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(1), answr2.Weight) + } + if answr2.Port != uint16(9222) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(9222), answr2.Port) + } + if answr2.Target != "xmpp.xmpp.com." { + t.Errorf("Expected :<%q> , received: <%q>", "xmpp.xmpp.com.", answr2.Target) + } + if err := dnsClnt.TCPTLS.WriteMsg(m); err != nil { + t.Error(err) + } + rply, err = dnsClnt.TCPTLS.ReadMsg() + if err != nil { + t.Error(err) + } else if len(rply.Answer) != 2 { + t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) + } + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr = rply.Answer[0].(*dns.SRV) + if answr.Priority != uint16(1) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(1), answr.Priority) + } + if answr.Weight != uint16(1) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(1), answr.Weight) + } + if answr.Port != uint16(9222) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(9222), answr.Port) + } + if answr.Target != "xmpp.xmpp.org." { + t.Errorf("Expected :<%q> , received: <%q>", "xmpp.xmpp.org.", answr.Target) + } + answr2 = rply.Answer[1].(*dns.SRV) + if answr2.Priority != uint16(1) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(1), answr2.Priority) + } + if answr2.Weight != uint16(1) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(1), answr2.Weight) + } + if answr2.Port != uint16(9222) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(9222), answr2.Port) + } + if answr2.Target != "xmpp.xmpp.com." { + t.Errorf("Expected :<%q> , received: <%q>", "xmpp.xmpp.com.", answr2.Target) + } + +} + +func testDNSitClntNAPTRSuppliers(t *testing.T) { + m := new(dns.Msg) + m.SetQuestion("5.6.9.4.7.1.7.1.5.6.8.9.4.e164.arpa.", dns.TypeNAPTR) + if err := dnsClnt.UDP.WriteMsg(m); err != nil { + t.Error(err) + } + rply, err := dnsClnt.UDP.ReadMsg() + if err != nil { + t.Error(err) + } else if len(rply.Answer) != 2 { + t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) + } + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr := rply.Answer[0].(*dns.NAPTR) + if answr.Order != 100 { + t.Errorf("received: <%v>", answr.Order) + } + if answr.Regexp != "!^(.*)$!sip:1@172.16.1.11!" { + t.Errorf("received: <%q>", answr.Regexp) + } + answr2 := rply.Answer[1].(*dns.NAPTR) + if answr2.Regexp != "!^(.*)$!sip:1@172.16.1.12!" { + t.Errorf("received: <%q>", answr2.Regexp) + } + if err := dnsClnt.TCP.WriteMsg(m); err != nil { + t.Error(err) + } + rply, err = dnsClnt.TCP.ReadMsg() + if err != nil { + t.Error(err) + } else if len(rply.Answer) != 2 { + t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) + } + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr = rply.Answer[0].(*dns.NAPTR) + if answr.Order != 100 { + t.Errorf("received: <%v>", answr.Order) + } + if answr.Regexp != "!^(.*)$!sip:1@172.16.1.11!" { + t.Errorf("received: <%q>", answr.Regexp) + } + answr2 = rply.Answer[1].(*dns.NAPTR) + if answr2.Regexp != "!^(.*)$!sip:1@172.16.1.12!" { + t.Errorf("received: <%q>", answr2.Regexp) + } + if err := dnsClnt.TCPTLS.WriteMsg(m); err != nil { + t.Error(err) + } + rply, err = dnsClnt.TCPTLS.ReadMsg() + if err != nil { + t.Error(err) + } else if len(rply.Answer) != 2 { + t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) + } + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr = rply.Answer[0].(*dns.NAPTR) + if answr.Order != 100 { + t.Errorf("received: <%v>", answr.Order) + } + if answr.Regexp != "!^(.*)$!sip:1@172.16.1.11!" { + t.Errorf("received: <%q>", answr.Regexp) + } + answr2 = rply.Answer[1].(*dns.NAPTR) + if answr2.Regexp != "!^(.*)$!sip:1@172.16.1.12!" { + t.Errorf("received: <%q>", answr2.Regexp) + } +} + +func testDNSitClntAOpts(t *testing.T) { + m := new(dns.Msg) + m.SetQuestion("example.com.", dns.TypeA) + m.SetEdns0(4096, false) + m.IsEdns0().Option = append(m.IsEdns0().Option, &dns.EDNS0_ESU{Uri: "sip:cgrates@cgrates.org"}) + if err := dnsClnt.UDP.WriteMsg(m); err != nil { + t.Error(err) + } + if rply, err := dnsClnt.UDP.ReadMsg(); err != nil { + t.Error(err) + } else if len(rply.Answer) != 1 { + t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) + } else { + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr0 := rply.Answer[0].(*dns.A) + if answr0.A.String() != "93.184.216.34" { + t.Errorf("Expected :<%q> , received: <%q>", "93.184.216.34", answr0.A) + } + if opts := rply.IsEdns0(); opts == nil { + t.Error("recieved nil options") + } else if len(opts.Option) != 2 { + t.Errorf("recieved wrong number of options: %v", len(opts.Option)) + } else if ov, can := opts.Option[0].(*dns.EDNS0_ESU); !can { + t.Errorf("recieved wrong option type: %T", opts.Option[0]) + } else if expected := "sip:cgrates@cgrates.com"; ov.Uri != expected { + t.Errorf("Expected :<%q> , received: <%q>", expected, ov.Uri) + } else if ov, can := opts.Option[1].(*dns.EDNS0_ESU); !can { + t.Errorf("recieved wrong option type: %T", opts.Option[1]) + } else if expected := "sip:cgrates@cgrates.net"; ov.Uri != expected { + t.Errorf("Expected :<%q> , received: <%q>", expected, ov.Uri) + } + } + + if err := dnsClnt.TCP.WriteMsg(m); err != nil { + t.Error(err) + } + if rply, err := dnsClnt.TCP.ReadMsg(); err != nil { + t.Error(err) + } else if len(rply.Answer) != 1 { + t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) + } else { + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr0 := rply.Answer[0].(*dns.A) + if answr0.A.String() != "93.184.216.34" { + t.Errorf("Expected :<%q> , received: <%q>", "93.184.216.34", answr0.A) + } + if opts := rply.IsEdns0(); opts == nil { + t.Error("recieved nil options") + } else if len(opts.Option) != 2 { + t.Errorf("recieved wrong number of options: %v", len(opts.Option)) + } else if ov, can := opts.Option[0].(*dns.EDNS0_ESU); !can { + t.Errorf("recieved wrong option type: %T", opts.Option[0]) + } else if expected := "sip:cgrates@cgrates.com"; ov.Uri != expected { + t.Errorf("Expected :<%q> , received: <%q>", expected, ov.Uri) + } else if ov, can := opts.Option[1].(*dns.EDNS0_ESU); !can { + t.Errorf("recieved wrong option type: %T", opts.Option[1]) + } else if expected := "sip:cgrates@cgrates.net"; ov.Uri != expected { + t.Errorf("Expected :<%q> , received: <%q>", expected, ov.Uri) + } + } + if err := dnsClnt.TCPTLS.WriteMsg(m); err != nil { + t.Error(err) + } + if rply, err := dnsClnt.TCPTLS.ReadMsg(); err != nil { + t.Error(err) + } else if len(rply.Answer) != 1 { + t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) + } else { + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr0 := rply.Answer[0].(*dns.A) + if answr0.A.String() != "93.184.216.34" { + t.Errorf("Expected :<%q> , received: <%q>", "93.184.216.34", answr0.A) + } + if opts := rply.IsEdns0(); opts == nil { + t.Error("recieved nil options") + } else if len(opts.Option) != 2 { + t.Errorf("recieved wrong number of options: %v", len(opts.Option)) + } else if ov, can := opts.Option[0].(*dns.EDNS0_ESU); !can { + t.Errorf("recieved wrong option type: %T", opts.Option[0]) + } else if expected := "sip:cgrates@cgrates.com"; ov.Uri != expected { + t.Errorf("Expected :<%q> , received: <%q>", expected, ov.Uri) + } else if ov, can := opts.Option[1].(*dns.EDNS0_ESU); !can { + t.Errorf("recieved wrong option type: %T", opts.Option[1]) + } else if expected := "sip:cgrates@cgrates.net"; ov.Uri != expected { + t.Errorf("Expected :<%q> , received: <%q>", expected, ov.Uri) + } + } +} +func testDNSitClntSRVOpts(t *testing.T) { + m := new(dns.Msg) + m.SetQuestion("_matrix._tcp.matrix.org.", dns.TypeSRV) + m.SetEdns0(4096, false) + m.IsEdns0().Option = append(m.IsEdns0().Option, + &dns.EDNS0_ESU{Uri: "sip:cgrates@cgrates.org"}) + if err := dnsClnt.UDP.WriteMsg(m); err != nil { + t.Error(err) + } + rply, err := dnsClnt.UDP.ReadMsg() + if err != nil { + t.Error(err) + } else if len(rply.Answer) != 1 { + t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) + } + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr := rply.Answer[0].(*dns.SRV) + if answr.Priority != uint16(10) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(10), answr.Priority) + } + if answr.Weight != uint16(5) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(5), answr.Weight) + } + if answr.Port != uint16(8443) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(8443), answr.Port) + } + if answr.Target != "matrix-federation.matrix.org.cdn.cloudflare.net." { + t.Errorf("Expected :<%q> , received: <%q>", + "matrix-federation.matrix.org.cdn.cloudflare.net.", answr.Target) + } + if opts := rply.IsEdns0(); opts == nil { + t.Error("recieved nil options") + } else if len(opts.Option) != 2 { + t.Errorf("recieved wrong number of options: %v", len(opts.Option)) + } else if ov, can := opts.Option[0].(*dns.EDNS0_ESU); !can { + t.Errorf("recieved wrong option type: %T", opts.Option[0]) + } else if expected := "sip:cgrates@cgrates.com"; ov.Uri != expected { + t.Errorf("Expected :<%q> , received: <%q>", expected, ov.Uri) + } else if ov, can := opts.Option[1].(*dns.EDNS0_ESU); !can { + t.Errorf("recieved wrong option type: %T", opts.Option[1]) + } else if expected := "sip:cgrates@cgrates.net"; ov.Uri != expected { + t.Errorf("Expected :<%q> , received: <%q>", expected, ov.Uri) + } + if err := dnsClnt.TCP.WriteMsg(m); err != nil { + t.Error(err) + } + rply, err = dnsClnt.TCP.ReadMsg() + if err != nil { + t.Error(err) + } else if len(rply.Answer) != 1 { + t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) + } + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr = rply.Answer[0].(*dns.SRV) + if answr.Priority != uint16(10) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(10), answr.Priority) + } + if answr.Weight != uint16(5) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(5), answr.Weight) + } + if answr.Port != uint16(8443) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(8443), answr.Port) + } + if answr.Target != "matrix-federation.matrix.org.cdn.cloudflare.net." { + t.Errorf("Expected :<%q> , received: <%q>", + "matrix-federation.matrix.org.cdn.cloudflare.net.", answr.Target) + } + if opts := rply.IsEdns0(); opts == nil { + t.Error("recieved nil options") + } else if len(opts.Option) != 2 { + t.Errorf("recieved wrong number of options: %v", len(opts.Option)) + } else if ov, can := opts.Option[0].(*dns.EDNS0_ESU); !can { + t.Errorf("recieved wrong option type: %T", opts.Option[0]) + } else if expected := "sip:cgrates@cgrates.com"; ov.Uri != expected { + t.Errorf("Expected :<%q> , received: <%q>", expected, ov.Uri) + } else if ov, can := opts.Option[1].(*dns.EDNS0_ESU); !can { + t.Errorf("recieved wrong option type: %T", opts.Option[1]) + } else if expected := "sip:cgrates@cgrates.net"; ov.Uri != expected { + t.Errorf("Expected :<%q> , received: <%q>", expected, ov.Uri) + } + if err := dnsClnt.TCPTLS.WriteMsg(m); err != nil { + t.Error(err) + } + rply, err = dnsClnt.TCPTLS.ReadMsg() + if err != nil { + t.Error(err) + } else if len(rply.Answer) != 1 { + t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) + } + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr = rply.Answer[0].(*dns.SRV) + if answr.Priority != uint16(10) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(10), answr.Priority) + } + if answr.Weight != uint16(5) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(5), answr.Weight) + } + if answr.Port != uint16(8443) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(8443), answr.Port) + } + if answr.Target != "matrix-federation.matrix.org.cdn.cloudflare.net." { + t.Errorf("Expected :<%q> , received: <%q>", + "matrix-federation.matrix.org.cdn.cloudflare.net.", answr.Target) + } + if opts := rply.IsEdns0(); opts == nil { + t.Error("recieved nil options") + } else if len(opts.Option) != 2 { + t.Errorf("recieved wrong number of options: %v", len(opts.Option)) + } else if ov, can := opts.Option[0].(*dns.EDNS0_ESU); !can { + t.Errorf("recieved wrong option type: %T", opts.Option[0]) + } else if expected := "sip:cgrates@cgrates.com"; ov.Uri != expected { + t.Errorf("Expected :<%q> , received: <%q>", expected, ov.Uri) + } else if ov, can := opts.Option[1].(*dns.EDNS0_ESU); !can { + t.Errorf("recieved wrong option type: %T", opts.Option[1]) + } else if expected := "sip:cgrates@cgrates.net"; ov.Uri != expected { + t.Errorf("Expected :<%q> , received: <%q>", expected, ov.Uri) + } +} + +func testDNSitClntNAPTROpts(t *testing.T) { + m := new(dns.Msg) + m.SetQuestion("5.6.9.4.7.1.7.1.5.6.8.9.5.e164.arpa.", dns.TypeNAPTR) + m.SetEdns0(4096, false) + m.IsEdns0().Option = append(m.IsEdns0().Option, &dns.EDNS0_ESU{Uri: "sip:cgrates@cgrates.org"}) + if err := dnsClnt.UDP.WriteMsg(m); err != nil { + t.Error(err) + } + rply, err := dnsClnt.UDP.ReadMsg() + if err != nil { + t.Error(err) + } else if len(rply.Answer) != 1 { + t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) + } + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr := rply.Answer[0].(*dns.NAPTR) + if answr.Order != 100 { + t.Errorf("received: <%q>", answr.Order) + } + if answr.Preference != 10 { + t.Errorf("received: <%q>", answr.Preference) + } + if answr.Flags != "U" { + t.Errorf("received: <%q>", answr.Flags) + } + if answr.Service != "E2U+SIP" { + t.Errorf("received: <%q>", answr.Service) + } + if answr.Regexp != "!^(.*)$!sip:1@172.16.1.10.!" { + t.Errorf("received: <%q>", answr.Regexp) + } + if answr.Replacement != "." { + t.Errorf("received: <%q>", answr.Replacement) + } + if opts := rply.IsEdns0(); opts == nil { + t.Error("recieved nil options") + } else if len(opts.Option) != 2 { + t.Errorf("recieved wrong number of options: %v", len(opts.Option)) + } else if ov, can := opts.Option[0].(*dns.EDNS0_ESU); !can { + t.Errorf("recieved wrong option type: %T", opts.Option[0]) + } else if expected := "sip:cgrates@cgrates.com"; ov.Uri != expected { + t.Errorf("Expected :<%q> , received: <%q>", expected, ov.Uri) + } else if ov, can := opts.Option[1].(*dns.EDNS0_ESU); !can { + t.Errorf("recieved wrong option type: %T", opts.Option[1]) + } else if expected := "sip:cgrates@cgrates.net"; ov.Uri != expected { + t.Errorf("Expected :<%q> , received: <%q>", expected, ov.Uri) + } + + if err := dnsClnt.TCP.WriteMsg(m); err != nil { + t.Error(err) + } + rply, err = dnsClnt.TCP.ReadMsg() + if err != nil { + t.Error(err) + } else if len(rply.Answer) != 1 { + t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) + } + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr = rply.Answer[0].(*dns.NAPTR) + if answr.Order != 100 { + t.Errorf("received: <%q>", answr.Order) + } + if answr.Preference != 10 { + t.Errorf("received: <%q>", answr.Preference) + } + if answr.Flags != "U" { + t.Errorf("received: <%q>", answr.Flags) + } + if answr.Service != "E2U+SIP" { + t.Errorf("received: <%q>", answr.Service) + } + if answr.Regexp != "!^(.*)$!sip:1@172.16.1.10.!" { + t.Errorf("received: <%q>", answr.Regexp) + } + if answr.Replacement != "." { + t.Errorf("received: <%q>", answr.Replacement) + } + if opts := rply.IsEdns0(); opts == nil { + t.Error("recieved nil options") + } else if len(opts.Option) != 2 { + t.Errorf("recieved wrong number of options: %v", len(opts.Option)) + } else if ov, can := opts.Option[0].(*dns.EDNS0_ESU); !can { + t.Errorf("recieved wrong option type: %T", opts.Option[0]) + } else if expected := "sip:cgrates@cgrates.com"; ov.Uri != expected { + t.Errorf("Expected :<%q> , received: <%q>", expected, ov.Uri) + } else if ov, can := opts.Option[1].(*dns.EDNS0_ESU); !can { + t.Errorf("recieved wrong option type: %T", opts.Option[1]) + } else if expected := "sip:cgrates@cgrates.net"; ov.Uri != expected { + t.Errorf("Expected :<%q> , received: <%q>", expected, ov.Uri) + } + + if err := dnsClnt.TCPTLS.WriteMsg(m); err != nil { + t.Error(err) + } + rply, err = dnsClnt.TCPTLS.ReadMsg() + if err != nil { + t.Error(err) + } else if len(rply.Answer) != 1 { + t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) + } + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr = rply.Answer[0].(*dns.NAPTR) + if answr.Order != 100 { + t.Errorf("received: <%q>", answr.Order) + } + if answr.Preference != 10 { + t.Errorf("received: <%q>", answr.Preference) + } + if answr.Flags != "U" { + t.Errorf("received: <%q>", answr.Flags) + } + if answr.Service != "E2U+SIP" { + t.Errorf("received: <%q>", answr.Service) + } + if answr.Regexp != "!^(.*)$!sip:1@172.16.1.10.!" { + t.Errorf("received: <%q>", answr.Regexp) + } + if answr.Replacement != "." { + t.Errorf("received: <%q>", answr.Replacement) + } + if opts := rply.IsEdns0(); opts == nil { + t.Error("recieved nil options") + } else if len(opts.Option) != 2 { + t.Errorf("recieved wrong number of options: %v", len(opts.Option)) + } else if ov, can := opts.Option[0].(*dns.EDNS0_ESU); !can { + t.Errorf("recieved wrong option type: %T", opts.Option[0]) + } else if expected := "sip:cgrates@cgrates.com"; ov.Uri != expected { + t.Errorf("Expected :<%q> , received: <%q>", expected, ov.Uri) + } else if ov, can := opts.Option[1].(*dns.EDNS0_ESU); !can { + t.Errorf("recieved wrong option type: %T", opts.Option[1]) + } else if expected := "sip:cgrates@cgrates.net"; ov.Uri != expected { + t.Errorf("Expected :<%q> , received: <%q>", expected, ov.Uri) + } +} + +func testDNSitClntAOptsWithAttributes(t *testing.T) { + m := new(dns.Msg) + m.SetQuestion("opendns.com.", dns.TypeA) + m.SetEdns0(4096, false) + m.IsEdns0().Option = append(m.IsEdns0().Option, &dns.EDNS0_ESU{Uri: "sip:cgrates@cgrates.org"}) + if err := dnsClnt.UDP.WriteMsg(m); err != nil { + t.Error(err) + } + if rply, err := dnsClnt.UDP.ReadMsg(); err != nil { + t.Error(err) + } else if len(rply.Answer) != 1 { + t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) + } else { + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr0 := rply.Answer[0].(*dns.A) + if answr0.A.String() != "146.112.62.105" { + t.Errorf("Expected :<%q> , received: <%q>", "146.112.62.105", answr0.A) + } + if opts := rply.IsEdns0(); opts == nil { + t.Error("recieved nil options") + } else if len(opts.Option) != 1 { + t.Errorf("recieved wrong number of options: %v", len(opts.Option)) + } else if ov, can := opts.Option[0].(*dns.EDNS0_ESU); !can { + t.Errorf("recieved wrong option type: %T", opts.Option[0]) + } else if expected := "sip:cgrates@opendns.com."; ov.Uri != expected { + t.Errorf("Expected :<%q> , received: <%q>", expected, ov.Uri) + } + } + + if err := dnsClnt.TCP.WriteMsg(m); err != nil { + t.Error(err) + } + if rply, err := dnsClnt.TCP.ReadMsg(); err != nil { + t.Error(err) + } else if len(rply.Answer) != 1 { + t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) + } else { + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr0 := rply.Answer[0].(*dns.A) + if answr0.A.String() != "146.112.62.105" { + t.Errorf("Expected :<%q> , received: <%q>", "146.112.62.105", answr0.A) + } + if opts := rply.IsEdns0(); opts == nil { + t.Error("recieved nil options") + } else if len(opts.Option) != 1 { + t.Errorf("recieved wrong number of options: %v", len(opts.Option)) + } else if ov, can := opts.Option[0].(*dns.EDNS0_ESU); !can { + t.Errorf("recieved wrong option type: %T", opts.Option[0]) + } else if expected := "sip:cgrates@opendns.com."; ov.Uri != expected { + t.Errorf("Expected :<%q> , received: <%q>", expected, ov.Uri) + } + } + if err := dnsClnt.TCPTLS.WriteMsg(m); err != nil { + t.Error(err) + } + if rply, err := dnsClnt.TCPTLS.ReadMsg(); err != nil { + t.Error(err) + } else if len(rply.Answer) != 1 { + t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) + } else { + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr0 := rply.Answer[0].(*dns.A) + if answr0.A.String() != "146.112.62.105" { + t.Errorf("Expected :<%q> , received: <%q>", "146.112.62.105", answr0.A) + } + if opts := rply.IsEdns0(); opts == nil { + t.Error("recieved nil options") + } else if len(opts.Option) != 1 { + t.Errorf("recieved wrong number of options: %v", len(opts.Option)) + } else if ov, can := opts.Option[0].(*dns.EDNS0_ESU); !can { + t.Errorf("recieved wrong option type: %T", opts.Option[0]) + } else if expected := "sip:cgrates@opendns.com."; ov.Uri != expected { + t.Errorf("Expected :<%q> , received: <%q>", expected, ov.Uri) + } + } +} + +func testDNSitClntSRVOptsWithAttributes(t *testing.T) { + m := new(dns.Msg) + m.SetQuestion("_sip._udp.opensips.org.", dns.TypeSRV) + m.SetEdns0(4096, false) + m.IsEdns0().Option = append(m.IsEdns0().Option, + &dns.EDNS0_ESU{Uri: "sip:cgrates@cgrates.org"}) + if err := dnsClnt.UDP.WriteMsg(m); err != nil { + t.Error(err) + } + rply, err := dnsClnt.UDP.ReadMsg() + if err != nil { + t.Error(err) + } else if len(rply.Answer) != 1 { + t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) + } + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr := rply.Answer[0].(*dns.SRV) + if answr.Priority != uint16(0) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(0), answr.Priority) + } + if answr.Weight != uint16(50) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(50), answr.Weight) + } + if answr.Port != uint16(5060) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(5060), answr.Port) + } + if answr.Target != "opensips.org." { + t.Errorf("Expected :<%q> , received: <%q>", + "opensips.org.", answr.Target) + } + if opts := rply.IsEdns0(); opts == nil { + t.Error("recieved nil options") + } else if len(opts.Option) != 1 { + t.Errorf("recieved wrong number of options: %v", len(opts.Option)) + } else if ov, can := opts.Option[0].(*dns.EDNS0_ESU); !can { + t.Errorf("recieved wrong option type: %T", opts.Option[0]) + } else if expected := "sip:cgrates@_sip._udp.opensips.org."; ov.Uri != expected { + t.Errorf("Expected :<%q> , received: <%q>", expected, ov.Uri) + } + if err := dnsClnt.TCP.WriteMsg(m); err != nil { + t.Error(err) + } + rply, err = dnsClnt.TCP.ReadMsg() + if err != nil { + t.Error(err) + } else if len(rply.Answer) != 1 { + t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) + } + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr = rply.Answer[0].(*dns.SRV) + if answr.Priority != uint16(0) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(0), answr.Priority) + } + if answr.Weight != uint16(50) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(50), answr.Weight) + } + if answr.Port != uint16(5060) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(5060), answr.Port) + } + if answr.Target != "opensips.org." { + t.Errorf("Expected :<%q> , received: <%q>", + "opensips.org.", answr.Target) + } + if opts := rply.IsEdns0(); opts == nil { + t.Error("recieved nil options") + } else if len(opts.Option) != 1 { + t.Errorf("recieved wrong number of options: %v", len(opts.Option)) + } else if ov, can := opts.Option[0].(*dns.EDNS0_ESU); !can { + t.Errorf("recieved wrong option type: %T", opts.Option[0]) + } else if expected := "sip:cgrates@_sip._udp.opensips.org."; ov.Uri != expected { + t.Errorf("Expected :<%q> , received: <%q>", expected, ov.Uri) + } + if err := dnsClnt.TCPTLS.WriteMsg(m); err != nil { + t.Error(err) + } + rply, err = dnsClnt.TCPTLS.ReadMsg() + if err != nil { + t.Error(err) + } else if len(rply.Answer) != 1 { + t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) + } + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr = rply.Answer[0].(*dns.SRV) + if answr.Priority != uint16(0) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(0), answr.Priority) + } + if answr.Weight != uint16(50) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(50), answr.Weight) + } + if answr.Port != uint16(5060) { + t.Errorf("Expected :<%q> , received: <%q>", uint16(5060), answr.Port) + } + if answr.Target != "opensips.org." { + t.Errorf("Expected :<%q> , received: <%q>", + "opensips.org.", answr.Target) + } + if opts := rply.IsEdns0(); opts == nil { + t.Error("recieved nil options") + } else if len(opts.Option) != 1 { + t.Errorf("recieved wrong number of options: %v", len(opts.Option)) + } else if ov, can := opts.Option[0].(*dns.EDNS0_ESU); !can { + t.Errorf("recieved wrong option type: %T", opts.Option[0]) + } else if expected := "sip:cgrates@_sip._udp.opensips.org."; ov.Uri != expected { + t.Errorf("Expected :<%q> , received: <%q>", expected, ov.Uri) + } + +} + +func testDNSitClntNAPTROptsWithAttributes(t *testing.T) { + m := new(dns.Msg) + m.SetQuestion("7.6.9.4.7.1.7.1.5.6.8.9.5.e164.arpa.", dns.TypeNAPTR) + m.SetEdns0(4096, false) + m.IsEdns0().Option = append(m.IsEdns0().Option, &dns.EDNS0_ESU{Uri: "sip:cgrates@cgrates.org"}) + if err := dnsClnt.UDP.WriteMsg(m); err != nil { + t.Error(err) + } + rply, err := dnsClnt.UDP.ReadMsg() + if err != nil { + t.Error(err) + } else if len(rply.Answer) != 1 { + t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) + } + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr := rply.Answer[0].(*dns.NAPTR) + if answr.Order != 100 { + t.Errorf("received: <%q>", answr.Order) + } + if answr.Preference != 10 { + t.Errorf("received: <%q>", answr.Preference) + } + if answr.Flags != "U" { + t.Errorf("received: <%q>", answr.Flags) + } + if answr.Service != "E2U+SIP" { + t.Errorf("received: <%q>", answr.Service) + } + if answr.Regexp != "!^(.*)$!sip:1@172.16.1.10.!" { + t.Errorf("received: <%q>", answr.Regexp) + } + if answr.Replacement != "." { + t.Errorf("received: <%q>", answr.Replacement) + } + if opts := rply.IsEdns0(); opts == nil { + t.Error("recieved nil options") + } else if len(opts.Option) != 1 { + t.Errorf("recieved wrong number of options: %v", len(opts.Option)) + } else if ov, can := opts.Option[0].(*dns.EDNS0_ESU); !can { + t.Errorf("recieved wrong option type: %T", opts.Option[0]) + } else if expected := "sip:cgrates@e164.arpa"; ov.Uri != expected { + t.Errorf("Expected :<%q> , received: <%q>", expected, ov.Uri) + } + + if err := dnsClnt.TCP.WriteMsg(m); err != nil { + t.Error(err) + } + rply, err = dnsClnt.TCP.ReadMsg() + if err != nil { + t.Error(err) + } else if len(rply.Answer) != 1 { + t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) + } + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr = rply.Answer[0].(*dns.NAPTR) + if answr.Order != 100 { + t.Errorf("received: <%q>", answr.Order) + } + if answr.Preference != 10 { + t.Errorf("received: <%q>", answr.Preference) + } + if answr.Flags != "U" { + t.Errorf("received: <%q>", answr.Flags) + } + if answr.Service != "E2U+SIP" { + t.Errorf("received: <%q>", answr.Service) + } + if answr.Regexp != "!^(.*)$!sip:1@172.16.1.10.!" { + t.Errorf("received: <%q>", answr.Regexp) + } + if answr.Replacement != "." { + t.Errorf("received: <%q>", answr.Replacement) + } + if opts := rply.IsEdns0(); opts == nil { + t.Error("recieved nil options") + } else if len(opts.Option) != 1 { + t.Errorf("recieved wrong number of options: %v", len(opts.Option)) + } else if ov, can := opts.Option[0].(*dns.EDNS0_ESU); !can { + t.Errorf("recieved wrong option type: %T", opts.Option[0]) + } else if expected := "sip:cgrates@e164.arpa"; ov.Uri != expected { + t.Errorf("Expected :<%q> , received: <%q>", expected, ov.Uri) + } + if err := dnsClnt.TCPTLS.WriteMsg(m); err != nil { + t.Error(err) + } + rply, err = dnsClnt.TCPTLS.ReadMsg() + if err != nil { + t.Error(err) + } else if len(rply.Answer) != 1 { + t.Fatalf("wrong number of records: %s", utils.ToIJSON(rply.Answer)) + } + if rply.Rcode != dns.RcodeSuccess { + t.Errorf("failed to get an valid answer\n%v", rply) + } + answr = rply.Answer[0].(*dns.NAPTR) + if answr.Order != 100 { + t.Errorf("received: <%q>", answr.Order) + } + if answr.Preference != 10 { + t.Errorf("received: <%q>", answr.Preference) + } + if answr.Flags != "U" { + t.Errorf("received: <%q>", answr.Flags) + } + if answr.Service != "E2U+SIP" { + t.Errorf("received: <%q>", answr.Service) + } + if answr.Regexp != "!^(.*)$!sip:1@172.16.1.10.!" { + t.Errorf("received: <%q>", answr.Regexp) + } + if answr.Replacement != "." { + t.Errorf("received: <%q>", answr.Replacement) + } + if opts := rply.IsEdns0(); opts == nil { + t.Error("recieved nil options") + } else if len(opts.Option) != 1 { + t.Errorf("recieved wrong number of options: %v", len(opts.Option)) + } else if ov, can := opts.Option[0].(*dns.EDNS0_ESU); !can { + t.Errorf("recieved wrong option type: %T", opts.Option[0]) + } else if expected := "sip:cgrates@e164.arpa"; ov.Uri != expected { + t.Errorf("Expected :<%q> , received: <%q>", expected, ov.Uri) + } + +} + +func testDNSitStopEngine(t *testing.T) { + if err := engine.KillEngine(*waitRater); err != nil { + t.Error(err) + } +} diff --git a/agents/kamagent.go b/agents/kamagent.go index 96dc1b113..bac5ba02b 100644 --- a/agents/kamagent.go +++ b/agents/kamagent.go @@ -245,11 +245,20 @@ func (ka *KamailioAgent) onDlgList(evData []byte, connIdx int) { return } var sIDs []*sessions.SessionID - // FixMe: find way to add OriginHost from event also, to be compatible with above implementation for _, dlgInfo := range kamDlgRpl.Jsonrpl_body.Result { + originHost := ka.conns[connIdx].RemoteAddr().String() + originID := dlgInfo.CallId + ";" + dlgInfo.Caller.Tag + for _, variable := range dlgInfo.Variables { + if variable.CgrOriginHost != utils.EmptyString { + originHost = variable.CgrOriginHost + } + if variable.CgrOriginID != utils.EmptyString { + originID = variable.CgrOriginID + } + } sIDs = append(sIDs, &sessions.SessionID{ - OriginHost: ka.conns[connIdx].RemoteAddr().String(), - OriginID: dlgInfo.CallId + ";" + dlgInfo.Caller.Tag, + OriginHost: originHost, + OriginID: originID, }) } ka.activeSessionIDs <- sIDs diff --git a/agents/kamevent.go b/agents/kamevent.go index 8ffa79d80..0321e0d5d 100644 --- a/agents/kamevent.go +++ b/agents/kamevent.go @@ -307,8 +307,12 @@ type kamJsonDlgBody struct { } type kamDlgInfo struct { - CallId string `json:"call-id"` - Caller *kamCallerDlg + CallId string `json:"call-id"` + Caller *kamCallerDlg + Variables []struct { + CgrOriginID string `json:"cgrOriginID,omitempty"` + CgrOriginHost string `json:"cgrOriginHost,omitempty"` + } `json:"variables"` } type kamCallerDlg struct { diff --git a/agents/libdns.go b/agents/libdns.go index 46fb5140c..66eaf1946 100644 --- a/agents/libdns.go +++ b/agents/libdns.go @@ -593,6 +593,8 @@ func updateDnsAnswer(q []dns.RR, qType uint16, qName string, path []string, valu switch v := q[idx].(type) { case *dns.NAPTR: err = updateDnsNAPTRAnswer(v, path, value) + case *dns.SRV: + err = updateDnsSRVAnswer(v, path, value) case *dns.A: if len(path) < 1 || (path[0] != utils.DNSHdr && len(path) != 1) || @@ -604,7 +606,12 @@ func updateDnsAnswer(q []dns.RR, qType uint16, qName string, path []string, valu case utils.DNSHdr: err = updateDnsRRHeader(&v.Hdr, path[1:], value) case utils.DNSA: - v.A = net.IP(utils.IfaceAsString(value)) + v.A = net.ParseIP(utils.IfaceAsString(value)) + if v.A == nil { + err = fmt.Errorf("invalid IP address <%v>", + utils.IfaceAsString(value)) + return + } default: err = utils.ErrWrongPath } @@ -630,12 +637,50 @@ func newDNSAnswer(qType uint16, qName string) (a dns.RR, err error) { a = &dns.A{Hdr: hdr} case dns.TypeNAPTR: a = &dns.NAPTR{Hdr: hdr} + case dns.TypeSRV: + a = &dns.SRV{Hdr: hdr} default: err = fmt.Errorf("unsupported DNS type: <%v>", dns.TypeToString[qType]) } return } +func updateDnsSRVAnswer(v *dns.SRV, path []string, value any) (err error) { + if len(path) < 1 || + (path[0] != utils.DNSHdr && len(path) != 1) || + (path[0] == utils.DNSHdr && len(path) != 2) { + err = utils.ErrWrongPath + return + } + switch path[0] { + case utils.DNSHdr: + err = updateDnsRRHeader(&v.Hdr, path[1:], value) + case utils.DNSPriority: + var vItm int64 + if vItm, err = utils.IfaceAsTInt64(value); err != nil { + return + } + v.Priority = uint16(vItm) + case utils.Weight: + var vItm int64 + if vItm, err = utils.IfaceAsTInt64(value); err != nil { + return + } + v.Weight = uint16(vItm) + case utils.DNSPort: + var vItm int64 + if vItm, err = utils.IfaceAsTInt64(value); err != nil { + return + } + v.Port = uint16(vItm) + case utils.DNSTarget: + v.Target = utils.IfaceAsString(value) + default: + err = utils.ErrWrongPath + } + return +} + func updateDnsNAPTRAnswer(v *dns.NAPTR, path []string, value any) (err error) { if len(path) < 1 || (path[0] != utils.DNSHdr && len(path) != 1) || diff --git a/config/config_defaults.go b/config/config_defaults.go index 3573f79dd..cb586bbf7 100644 --- a/config/config_defaults.go +++ b/config/config_defaults.go @@ -1255,7 +1255,7 @@ const CGRATES_CFG_JSON = ` "field_separator": ",", // separator used in case of csv files "tp_in_dir": "/var/spool/cgrates/loader/in", // absolute path towards the directory where the TPs are stored "tp_out_dir": "/var/spool/cgrates/loader/out", // absolute path towards the directory where processed TPs will be moved - "action": "*store", // what should the loader do<*store|*parse|*remove|*dryrun> + "action": "*store", // what should the loader do<*store|*parse|*remove|*dryRun> "opts": { // "*cache": "*reload", "*withIndex": true, diff --git a/config/config_it_test.go b/config/config_it_test.go index 02aac32bb..86ca26f5d 100644 --- a/config/config_it_test.go +++ b/config/config_it_test.go @@ -542,6 +542,10 @@ func testCGRConfigReloadDNSAgent(t *testing.T) { Address: ":2053", Network: "udp", }, + { + Address: ":2054", + Network: "tcp", + }, }, SessionSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS)}, // Timezone string diff --git a/config/dnsagentcfg_test.go b/config/dnsagentcfg_test.go index 5eaee1e88..994aa3892 100644 --- a/config/dnsagentcfg_test.go +++ b/config/dnsagentcfg_test.go @@ -426,6 +426,102 @@ func TestDiffDNSAgentJsonCfg(t *testing.T) { } } +func TestDiffDNSAgentJsonCfgExtraV1(t *testing.T) { + var d *DNSAgentJsonCfg + + v1 := &DNSAgentCfg{ + Enabled: false, + Listeners: []Listener{ + { + Address: "localhost:8080", + Network: "tcp", + }, + { + Address: "localhost:2054", + Network: "udp", + }, + }, + } + + v2 := &DNSAgentCfg{ + Enabled: true, + Listeners: []Listener{ + { + Address: "localhost:8037", + Network: "udp", + }, + }, + } + + expected := &DNSAgentJsonCfg{ + Enabled: utils.BoolPointer(true), + Listeners: &[]*ListenerJsnCfg{ + { + Address: utils.StringPointer("localhost:8037"), + Network: utils.StringPointer("udp"), + }, + { + Address: utils.StringPointer("localhost:2054"), + Network: utils.StringPointer("udp"), + }, + }, + Request_processors: &[]*ReqProcessorJsnCfg{}, + } + + rcv := diffDNSAgentJsonCfg(d, v1, v2, ";") + if !reflect.DeepEqual(rcv, expected) { + t.Errorf("Expected %v \n but received \n %v", utils.ToJSON(expected), utils.ToJSON(rcv)) + } +} + +func TestDiffDNSAgentJsonCfgExtraV2(t *testing.T) { + var d *DNSAgentJsonCfg + + v1 := &DNSAgentCfg{ + Enabled: false, + Listeners: []Listener{ + { + Address: "localhost:8080", + Network: "tcp", + }, + }, + } + + v2 := &DNSAgentCfg{ + Enabled: true, + Listeners: []Listener{ + { + Address: "localhost:8037", + Network: "udp", + }, + { + Address: "localhost:2054", + Network: "udp", + }, + }, + } + + expected := &DNSAgentJsonCfg{ + Enabled: utils.BoolPointer(true), + Listeners: &[]*ListenerJsnCfg{ + { + Address: utils.StringPointer("localhost:8037"), + Network: utils.StringPointer("udp"), + }, + { + Address: utils.StringPointer("localhost:2054"), + Network: utils.StringPointer("udp"), + }, + }, + Request_processors: &[]*ReqProcessorJsnCfg{}, + } + + rcv := diffDNSAgentJsonCfg(d, v1, v2, ";") + if !reflect.DeepEqual(rcv, expected) { + t.Errorf("Expected %v \n but received \n %v", utils.ToJSON(expected), utils.ToJSON(rcv)) + } +} + func TestDnsAgentCloneSection(t *testing.T) { dnsCfg := &DNSAgentCfg{ Enabled: false, diff --git a/data/conf/cgrates/cgrates.json b/data/conf/cgrates/cgrates.json index 548ea268a..30d2f3afa 100755 --- a/data/conf/cgrates/cgrates.json +++ b/data/conf/cgrates/cgrates.json @@ -1185,7 +1185,7 @@ // "field_separator": ",", // separator used in case of csv files // "tp_in_dir": "/var/spool/cgrates/loader/in", // absolute path towards the directory where the TPs are stored // "tp_out_dir": "/var/spool/cgrates/loader/out", // absolute path towards the directory where processed TPs will be moved -// "action": "*store", // what should the loader do<*store|*parse|*remove|*dryrun> +// "action": "*store", // what should the loader do<*store|*parse|*remove|*dryRun> // "opts": { // // "*cache": "*reload", // "*withIndex": true, diff --git a/data/conf/samples/dnsagent_internal/attributes.json b/data/conf/samples/dnsagent_internal/attributes.json index e79f73516..5a4bb44eb 100644 --- a/data/conf/samples/dnsagent_internal/attributes.json +++ b/data/conf/samples/dnsagent_internal/attributes.json @@ -1,31 +1,72 @@ { - -"dns_agent": { - "request_processors": [ - { - "id": "NAPTRAttributes", - "filters": ["*string:~*vars.QueryType:NAPTR", "*string:~*vars.QueryName{*e164}:4986517174964"], - "flags": ["*authorize", "*attributes","*log"], - "request_fields":[ - {"tag": "E164Address", "path": "*cgreq.E164Address", - "type": "*constant", "value": "4986517174964"}, - {"tag": "NAPTRAddress", "path": "*cgreq.NAPTRAddress", - "type": "*constant", "value": "*attributes"} - ], - "reply_fields":[ - {"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": "NAPTRRegex", "path": "*rep.Answer.Regexp", - "type": "*variable", "value": "~*cgrep.Attributes.NAPTRAddress"}, - ], - }, - ], -}, - -} \ No newline at end of file + "dns_agent": { + "request_processors": [ + { + "id": "NAPTRAttributes", + "filters": ["*string:~*vars.QueryType:NAPTR", "*string:~*vars.QueryName{*e164}:4986517174964"], + "flags": ["*authorize", "*attributes","*log"], + "request_fields":[ + {"tag": "E164Address", "path": "*cgreq.E164Address", + "type": "*constant", "value": "4986517174964"}, + {"tag": "NAPTRAddress", "path": "*cgreq.NAPTRAddress", + "type": "*constant", "value": "*attributes"} + ], + "reply_fields":[ + {"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": "NAPTRRegex", "path": "*rep.Answer.Regexp", + "type": "*variable", "value": "~*cgrep.Attributes.NAPTRAddress"} + ] + }, + { + "id": "AAttributes", + "filters": ["*string:~*vars.QueryType:A", "*string:~*vars.QueryName:dns.google."], + "flags": ["*authorize","*attributes","*log"], + "request_fields":[ + {"tag": "Domain", "path": "*cgreq.Domain", + "type": "*constant", "value": "dns.google."}, + {"tag": "ADomain0", "path": "*cgreq.Aip0", + "type": "*constant", "value": "*attributes"}, + {"tag": "ADomain1", "path": "*cgreq.Aip1", + "type": "*constant", "value": "*attributes"} + ], + "reply_fields":[ + {"tag": "Aname", "path": "*rep.Answer.Hdr.Name", "type": "*constant", "value": "dns.google."}, + {"tag": "Attl", "path": "*rep.Answer.Hdr.Ttl", "type": "*constant", "value": "300"}, + {"tag": "Aclass", "path": "*rep.Answer.Hdr.Class", "type": "*constant", "value": "1"}, + {"tag": "Arrtype", "path": "*rep.Answer.Hdr.Rrtype", "type": "*constant", "value": "1"}, + {"tag": "Aip0", "path": "*rep.Answer.A", "type": "*variable", "value": "~*cgrep.Attributes.Aip0"}, + {"tag": "Aname1", "path": "*rep.Answer[1].Hdr.Name", "type": "*constant", "value": "dns.google."}, + {"tag": "Attl1", "path": "*rep.Answer[1].Hdr.Ttl", "type": "*constant", "value": "300"}, + {"tag": "Aclass1", "path": "*rep.Answer[1].Hdr.Class", "type": "*constant", "value": "1"}, + {"tag": "Arrtype1", "path": "*rep.Answer[1].Hdr.Rrtype", "type": "*constant", "value": "1"}, + {"tag": "Aip1", "path": "*rep.Answer[1].A", "type": "*variable", "value": "~*cgrep.Attributes.Aip1"} + ] + }, + { + "id": "SRVAttributes", + "filters": ["*string:~*vars.QueryType:SRV", "*string:~*vars.QueryName:_ldap._tcp.google.com."], + "flags": ["*authorize", "*attributes","*log"], + "request_fields":[ + {"tag": "SRVAddress", "path": "*cgreq.SRVAddress", + "type": "*constant", "value": "_ldap._tcp.google.com."}, + {"tag": "SRVName", "path": "*cgreq.SRVName", + "type": "*constant", "value": "*attributes"} + ], + "reply_fields":[ + {"tag": "SRVHdr", "path": "*rep.Answer.Hdr.Name", "type": "*constant", "value": "_ldap._tcp.google.com."}, + {"tag": "SRVPriority", "path": "*rep.Answer.Priority", "type": "*constant", "value": "5"}, + {"tag": "SRVWeight", "path": "*rep.Answer.Weight", "type": "*constant", "value": "0"}, + {"tag": "SRVPort", "path": "*rep.Answer.Port", "type": "*constant", "value": "389"}, + {"tag": "SRVTarget", "path": "*rep.Answer.Target", "type": "*variable", "value": "~*cgrep.Attributes.SRVName"} + ] + } + ] + } + } \ No newline at end of file diff --git a/data/conf/samples/dnsagent_internal/cgrates.json b/data/conf/samples/dnsagent_internal/cgrates.json index 2365795d9..0e061d041 100644 --- a/data/conf/samples/dnsagent_internal/cgrates.json +++ b/data/conf/samples/dnsagent_internal/cgrates.json @@ -23,13 +23,50 @@ "rals_conns": ["*internal"], "cdrs_conns": ["*internal"], "chargers_conns": ["*internal"], - "routes_conns": ["*localhost"] + "routes_conns": ["*localhost"], + "opts": { + "*attributes": [ + { + "Tenant": "*any", + "FilterIDs": [], + "Value": true, + }, + ], + "*routes": [ + { + "Tenant": "*any", + "FilterIDs": ["*string:~*req.Account:1001"], + "Value": true, + }, + { + "Tenant": "*any", + "FilterIDs": ["*string:~*req.Account:1002"], + "Value": true, + }, + { + "Tenant": "*any", + "FilterIDs": ["*string:~*req.Account:1003"], + "Value": true, + }, + ], + } }, + "rates": { - "enabled": true + "enabled": true, }, +"loaders": [ + { + "enabled":true, + "id": "*default", + "tp_in_dir": "/usr/share/cgrates/tariffplans/dnsagent", + "tp_out_dir": "", + "lockfile_path": "", + }, +], + "cdrs": { "enabled": true, "rates_conns": ["*internal"] @@ -48,9 +85,30 @@ "enabled": true }, +"tls": { + "server_certificate" : "/usr/share/cgrates/tls/server.crt", + "server_key":"/usr/share/cgrates/tls/server.key", + "client_certificate" : "/usr/share/cgrates/tls/client.crt", + "client_key":"/usr/share/cgrates/tls/client.key", + "ca_certificate":"/usr/share/cgrates/tls/ca.crt" +}, + "dns_agent": { "enabled": true, - "listen": ":2053", + "listeners":[ + { + "address":":2053", + "network":"udp" + }, + { + "address":":2053", + "network":"tcp" + }, + { + "address":":2054", + "network":"tcp-tls" + } + ], "sessions_conns": ["*localhost"] }, diff --git a/data/conf/samples/dnsagent_internal/dryrun.json b/data/conf/samples/dnsagent_internal/dryrun.json index 26535baec..b9653cb4c 100644 --- a/data/conf/samples/dnsagent_internal/dryrun.json +++ b/data/conf/samples/dnsagent_internal/dryrun.json @@ -5,9 +5,9 @@ { "id": "DryRunNAPTR", "filters": ["*string:~*vars.QueryType:NAPTR", "*string:~*vars.QueryName{*e164}:4986517174963"], - "flags": ["*dryrun","*log"], + "flags": ["*dryRun","*log"], "request_fields":[ - {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*sms"}, + {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*sms"} ], "reply_fields":[ {"tag": "NAPTROrder", "path": "*rep.Answer.Order", "type": "*constant", "value": "100"}, @@ -15,10 +15,40 @@ {"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": "."}, - ], + {"tag": "NAPTRReplacement", "path": "*rep.Answer.Replacement", "type": "*constant", "value": "."} + ] }, - ], -}, + { + "id": "DryRunA", + "filters": ["*string:~*vars.QueryType:A", "*string:~*vars.QueryName:cgrates.org."], + "flags": ["*dryRun","*log"], + "request_fields":[ + {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*sms"} + ], + "reply_fields":[ + {"tag": "Aname", "path": "*rep.Answer.Hdr.Name", "type": "*constant", "value": "cgrates.org."}, + {"tag": "Attl", "path": "*rep.Answer.Hdr.Ttl", "type": "*constant", "value": "300"}, + {"tag": "Aclass", "path": "*rep.Answer.Hdr.Class", "type": "*constant", "value": "1"}, + {"tag": "Arrtype", "path": "*rep.Answer.Hdr.Rrtype", "type": "*constant", "value": "1"}, + {"tag": "Aip", "path": "*rep.Answer.A", "type": "*constant", "value": "51.38.77.188"} + ] + }, + { + "id": "DryRunSRV", + "filters": ["*string:~*vars.QueryType:SRV", "*string:~*vars.QueryName:_sip._tcp.opensips.org."], + "flags": ["*dryRun","*log"], + "request_fields":[ + {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*sms"} + ], + "reply_fields":[ + {"tag": "SRVHdr", "path": "*rep.Answer.Hdr.Name", "type": "*constant", "value": "_sip._tcp.opensips.org."}, + {"tag": "SRVPort", "path": "*rep.Answer.Port", "type": "*constant", "value": "5060"}, + {"tag": "SRVPriority", "path": "*rep.Answer.Priority", "type": "*constant", "value": "0"}, + {"tag": "SRVWeight", "path": "*rep.Answer.Weight", "type": "*constant", "value": "50"}, + {"tag": "SRVTarget", "path": "*rep.Answer.Target", "type": "*constant", "value": "opensips.org."} + ] + } + ] +} } \ No newline at end of file diff --git a/data/conf/samples/dnsagent_internal/opts.json b/data/conf/samples/dnsagent_internal/opts.json index 2da9770c6..9fd9b986e 100644 --- a/data/conf/samples/dnsagent_internal/opts.json +++ b/data/conf/samples/dnsagent_internal/opts.json @@ -4,9 +4,9 @@ { "id": "OptsNAPTR", "filters": ["*string:~*vars.QueryType:NAPTR", "*string:~*vars.QueryName{*e164}:5986517174965", "*string:~*req.Option[0].Uri:sip:cgrates@cgrates.org"], - "flags": ["*dryrun","*log"], + "flags": ["*dryRun","*log"], "request_fields":[ - {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*sms"}, + {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*sms"} ], "reply_fields":[ {"tag": "NAPTROrder", "path": "*rep.Answer.Order", "type": "*constant", "value": "100"}, @@ -17,8 +17,8 @@ {"tag": "NAPTRReplacement", "path": "*rep.Answer.Replacement", "type": "*constant", "value": "."}, {"tag": "Opts", "path": "*rep.Option.Uri", "type": "*constant", "value": "sip:cgrates@cgrates.co"}, {"tag": "Opts2", "path": "*rep.Option.Uri", "type": "*group", "value": "sip:cgrates@cgrates.net", "new_branch":true}, - {"tag": "Opts3", "path": "*rep.Option[0].Uri", "type": "*constant", "value": "sip:cgrates@cgrates.com"}, - ], + {"tag": "Opts3", "path": "*rep.Option[0].Uri", "type": "*constant", "value": "sip:cgrates@cgrates.com"} + ] }, { "id": "OptsWithAttributes", @@ -27,7 +27,7 @@ "request_fields":[ {"tag": "Origin", "path": "*cgreq.Origin", "type": "*variable", "value": "~*req.Option[0].Uri{*sipuri_user}"}, {"tag": "Domanin", "path": "*cgreq.Domanin", "type": "*variable", "value": "~*vars.QueryName{*e164Domain}"}, - {"tag": "NewSipURI", "path": "*cgreq.SipURI", "type": "*constant", "value": "*attributes"}, + {"tag": "NewSipURI", "path": "*cgreq.SipURI", "type": "*constant", "value": "*attributes"} ], "reply_fields":[ {"tag": "NAPTROrder", "path": "*rep.Answer.Order", "type": "*constant", "value": "100"}, @@ -36,10 +36,82 @@ {"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": "."}, - {"tag": "Opts", "path": "*rep.Option.Uri", "type": "*variable", "value": "~*cgrep.Attributes[*raw].SipURI", "mandatory": true}, - ], + {"tag": "Opts", "path": "*rep.Option.Uri", "type": "*variable", "value": "~*cgrep.Attributes[*raw].SipURI", "mandatory": true} + ] }, - ], - }, + { + "id": "OptsA", + "filters": ["*string:~*vars.QueryType:A", "*string:~*vars.QueryName:example.com.", "*string:~*req.Option[0].Uri:sip:cgrates@cgrates.org"], + "flags": ["*dryRun","*log"], + "request_fields":[ + {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*sms"} + ], + "reply_fields":[ + {"tag": "Aname", "path": "*rep.Answer.Hdr.Name", "type": "*constant", "value": "example.com."}, + {"tag": "Attl", "path": "*rep.Answer.Hdr.Ttl", "type": "*constant", "value": "300"}, + {"tag": "Aclass", "path": "*rep.Answer.Hdr.Class", "type": "*constant", "value": "1"}, + {"tag": "Arrtype", "path": "*rep.Answer.Hdr.Rrtype", "type": "*constant", "value": "1"}, + {"tag": "Aip", "path": "*rep.Answer.A", "type": "*constant", "value": "93.184.216.34"}, + {"tag": "Opts", "path": "*rep.Option.Uri", "type": "*constant", "value": "sip:cgrates@cgrates.co"}, + {"tag": "Opts2", "path": "*rep.Option.Uri", "type": "*group", "value": "sip:cgrates@cgrates.net", "new_branch":true}, + {"tag": "Opts3", "path": "*rep.Option[0].Uri", "type": "*constant", "value": "sip:cgrates@cgrates.com"} + ] + }, + { + "id": "AOptsWithAttributes", + "filters": ["*string:~*vars.QueryType:A", "*string:~*vars.QueryName:opendns.com."], + "flags": ["*event","*attributes"], + "request_fields":[ + {"tag": "Origin", "path": "*cgreq.AOrigin", "type": "*variable", "value": "~*req.Option[0].Uri{*sipuri_user}"}, + {"tag": "Domain", "path": "*cgreq.ASIPDomain", "type": "*variable", "value": "~*vars.QueryName"}, + {"tag": "NewSipURI", "path": "*cgreq.SipURI", "type": "*constant", "value": "*attributes"} + ], + "reply_fields":[ + {"tag": "Aname", "path": "*rep.Answer.Hdr.Name", "type": "*constant", "value": "example.com."}, + {"tag": "Attl", "path": "*rep.Answer.Hdr.Ttl", "type": "*constant", "value": "300"}, + {"tag": "Aclass", "path": "*rep.Answer.Hdr.Class", "type": "*constant", "value": "1"}, + {"tag": "Arrtype", "path": "*rep.Answer.Hdr.Rrtype", "type": "*constant", "value": "1"}, + {"tag": "Aip", "path": "*rep.Answer.A", "type": "*constant", "value": "146.112.62.105"}, + {"tag": "Opts", "path": "*rep.Option.Uri", "type": "*variable", "value": "~*cgrep.Attributes[*raw].SipURI", "mandatory": true} + ] + }, + { + "id": "OptsSRV", + "filters": ["*string:~*vars.QueryType:SRV", "*string:~*vars.QueryName:_matrix._tcp.matrix.org.", "*string:~*req.Option[0].Uri:sip:cgrates@cgrates.org"], + "flags": ["*dryRun","*log"], + "request_fields":[ + {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*sms"} + ], + "reply_fields":[ + {"tag": "SRVHdr", "path": "*rep.Answer.Hdr.Name", "type": "*constant", "value": "_xmpp-client._tcp.xmpp.org."}, + {"tag": "SRVPriority", "path": "*rep.Answer.Priority", "type": "*constant", "value": "10"}, + {"tag": "SRVWeight", "path": "*rep.Answer.Weight", "type": "*constant", "value": "5"}, + {"tag": "SRVPort", "path": "*rep.Answer.Port", "type": "*constant", "value": "8443"}, + {"tag": "SRVTarget", "path": "*rep.Answer.Target", "type": "*constant", "value": "matrix-federation.matrix.org.cdn.cloudflare.net."}, + {"tag": "Opts", "path": "*rep.Option.Uri", "type": "*constant", "value": "sip:cgrates@cgrates.co"}, + {"tag": "Opts2", "path": "*rep.Option.Uri", "type": "*group", "value": "sip:cgrates@cgrates.net", "new_branch":true}, + {"tag": "Opts3", "path": "*rep.Option[0].Uri", "type": "*constant", "value": "sip:cgrates@cgrates.com"} + ] + }, + { + "id": "SRVOptsWithAttributes", + "filters": ["*string:~*vars.QueryType:SRV", "*string:~*vars.QueryName:_sip._udp.opensips.org."], + "flags": ["*event","*attributes"], + "request_fields":[ + {"tag": "Origin", "path": "*cgreq.SRVOrigin", "type": "*variable", "value": "~*req.Option[0].Uri{*sipuri_user}"}, + {"tag": "Domain", "path": "*cgreq.SRVDomain", "type": "*variable", "value": "~*vars.QueryName"}, + {"tag": "NewSipURI", "path": "*cgreq.SipURI", "type": "*constant", "value": "*attributes"} + ], + "reply_fields":[ + {"tag": "SRVHdr", "path": "*rep.Answer.Hdr.Name", "type": "*constant", "value": "_sip._udp.opensips.org."}, + {"tag": "SRVPriority", "path": "*rep.Answer.Priority", "type": "*constant", "value": "0"}, + {"tag": "SRVWeight", "path": "*rep.Answer.Weight", "type": "*constant", "value": "50"}, + {"tag": "SRVPort", "path": "*rep.Answer.Port", "type": "*constant", "value": "5060"}, + {"tag": "SRVTarget", "path": "*rep.Answer.Target", "type": "*constant", "value": "opensips.org."}, + {"tag": "Opts", "path": "*rep.Option.Uri", "type": "*variable", "value": "~*cgrep.Attributes[*raw].SipURI", "mandatory": true} + ] + } + ] + } - } \ No newline at end of file +} \ No newline at end of file diff --git a/data/conf/samples/dnsagent_internal/suppliers.json b/data/conf/samples/dnsagent_internal/suppliers.json index 907df1b1d..629be84b2 100644 --- a/data/conf/samples/dnsagent_internal/suppliers.json +++ b/data/conf/samples/dnsagent_internal/suppliers.json @@ -1,65 +1,152 @@ { -"dns_agent": { - "request_processors": [ - { - "id": "NAPTRRoutesQuery", - "filters": ["*string:~*vars.QueryType:NAPTR", - "*string:~*vars.QueryName{*e164}:4986517174965"], - "flags": ["*message", "*routes","*continue"], - "request_fields":[ - {"tag": "ToR", "path": "*cgreq.Account", "type": "*constant", "value": "1001"}, // so we can match the supplier profile - ], - "reply_fields":[ - {"tag": "DispatchReply", "type": "*none", - "blocker": true}, // enforces continue_on_success so we can check answer with filters - ], - }, - { - "id": "NAPTRSuppliersOneSupplier", - "filters": ["*string:~*vars.QueryType:NAPTR", - "*string:~*vars.QueryName{*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.Answer.Order", - "type": "*group", "value": "100"}, - {"tag": "NAPTRPreference", "path": "*rep.Answer.Preference", - "type": "*group", "value": "10"}, - {"tag": "NAPTRFlags", "path": "*rep.Answer.Flags", - "type": "*group", "value": "U"}, - {"tag": "NAPTRService", "path": "*rep.Answer.Service", - "type": "*group", "value": "E2U+SIP"}, - {"tag": "NAPTRRegexp", "path": "*rep.Answer.Regexp", "type": "*group", - "value": "~*cgrep.RouteProfiles[0].Routes[0].RouteParameters"}, - {"tag": "NAPTRReplacement", "path": "*rep.Answer.Replacement", - "type": "*group", "value": "."}, - ], - }, - { - "id": "NAPTRSuppliersTwoSuppliers", - "filters": ["*string:~*vars.QueryType:NAPTR", - "*string:~*vars.QueryName{*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.Answer.Order", "value": "100"}, - {"tag": "NAPTRPreference", "path": "*rep.Answer.Preference", - "type": "*group", "value": "10"}, - {"tag": "NAPTRFlags", "path": "*rep.Answer.Flags", - "type": "*group", "value": "U"}, - {"tag": "NAPTRService", "path": "*rep.Answer.Service", - "type": "*group", "value": "E2U+SIP"}, - {"tag": "NAPTRRegexp", "path": "*rep.Answer.Regexp", "type": "*group", - "value": "~*cgrep.RouteProfiles[0].Routes[1].RouteParameters"}, - {"tag": "NAPTRReplacement", "path": "*rep.Answer.Replacement", - "type": "*group", "value": "."}, - ], - }, - ], -}, - -} + "dns_agent": { + "request_processors": [ + { + "id": "NAPTRRoutesQuery", + "filters": ["*string:~*vars.QueryType:NAPTR", + "*string:~*vars.QueryName{*e164}:4986517174965"], + "flags": ["*message", "*routes","*continue"], + "request_fields":[ + {"tag": "ToR", "path": "*cgreq.Account", "type": "*constant", "value": "1001"} // so we can match the supplier profile + ], + "reply_fields":[ + {"tag": "DispatchReply", "type": "*none", + "blocker": true} // enforces continue_on_success so we can check answer with filters + ] + }, + { + "id": "NAPTRSuppliersOneSupplier", + "filters": ["*string:~*vars.QueryType:NAPTR", + "*string:~*vars.QueryName{*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.Answer.Order", + "type": "*group", "value": "100"}, + {"tag": "NAPTRPreference", "path": "*rep.Answer.Preference", + "type": "*group", "value": "10"}, + {"tag": "NAPTRFlags", "path": "*rep.Answer.Flags", + "type": "*group", "value": "U"}, + {"tag": "NAPTRService", "path": "*rep.Answer.Service", + "type": "*group", "value": "E2U+SIP"}, + {"tag": "NAPTRRegexp", "path": "*rep.Answer.Regexp", "type": "*group", + "value": "~*cgrep.RouteProfiles[0].Routes[0].RouteParameters"}, + {"tag": "NAPTRReplacement", "path": "*rep.Answer.Replacement", + "type": "*group", "value": "."} + ] + }, + { + "id": "NAPTRSuppliersTwoSuppliers", + "filters": ["*string:~*vars.QueryType:NAPTR", + "*string:~*vars.QueryName{*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.Answer.Order", "value": "100"}, + {"tag": "NAPTRPreference", "path": "*rep.Answer.Preference", + "type": "*group", "value": "10"}, + {"tag": "NAPTRFlags", "path": "*rep.Answer.Flags", + "type": "*group", "value": "U"}, + {"tag": "NAPTRService", "path": "*rep.Answer.Service", + "type": "*group", "value": "E2U+SIP"}, + {"tag": "NAPTRRegexp", "path": "*rep.Answer.Regexp", "type": "*group", + "value": "~*cgrep.RouteProfiles[0].Routes[1].RouteParameters"}, + {"tag": "NAPTRReplacement", "path": "*rep.Answer.Replacement", + "type": "*group", "value": "."} + ] + }, + { + "id": "ARoutesQuery", + "filters": ["*string:~*vars.QueryType:A", + "*string:~*vars.QueryName:go.dev."], + "flags": ["*message", "*routes","*continue"], + "request_fields":[ + {"tag": "ToR", "path": "*cgreq.Account", "type": "*constant", "value": "1002"} + ], + "reply_fields":[ + {"tag": "DispatchReply", "type": "*none", + "blocker": true} + ] + }, + { + "id": "ASuppliersOneSupplier", + "filters": ["*string:~*vars.QueryType:A", + "*string:~*vars.QueryName:go.dev.", + "*gte:~*cgrep.RouteProfiles.Length:1", + "*gte:~*cgrep.RouteProfiles[0].Routes.Length:2"], + "flags": ["*none","*continue"], + "reply_fields":[ + {"tag": "Aname", "path": "*rep.Answer.Hdr.Name", "type": "*group", "value": "go.dev."}, + {"tag": "Attl", "path": "*rep.Answer.Hdr.Ttl", "type": "*group", "value": "300"}, + {"tag": "Aclass", "path": "*rep.Answer.Hdr.Class", "type": "*group", "value": "1"}, + {"tag": "Arrtype", "path": "*rep.Answer.Hdr.Rrtype", "type": "*group", "value": "1"}, + {"tag": "Aip", "path": "*rep.Answer.A", "type": "*group", "value": "~*cgrep.RouteProfiles[0].Routes[0].RouteParameters"} + ] + }, + { + "id": "ASuppliersTwoSuppliers", + "filters": ["*string:~*vars.QueryType:A", + "*string:~*vars.QueryName:go.dev.", + "*gte:~*cgrep.RouteProfiles.Length:1", + "*gte:~*cgrep.RouteProfiles[0].Routes.Length:2"], + "flags": ["*none","*continue"], + "reply_fields":[ + {"tag": "Aname", "path": "*rep.Answer[1].Hdr.Name", "type": "*group", "value": "go.dev."}, + {"tag": "Attl", "path": "*rep.Answer[1].Hdr.Ttl", "type": "*group", "value": "300"}, + {"tag": "Aclass", "path": "*rep.Answer[1].Hdr.Class", "type": "*group", "value": "1"}, + {"tag": "Arrtype", "path": "*rep.Answer[1].Hdr.Rrtype", "type": "*group", "value": "1"}, + {"tag": "Aip", "path": "*rep.Answer[1].A", "type": "*group", "value": "~*cgrep.RouteProfiles[0].Routes[1].RouteParameters"} + ] + }, + { + "id": "SRVRoutesQuery", + "filters": ["*string:~*vars.QueryType:SRV", + "*string:~*vars.QueryName:_xmpp-client._tcp.xmpp.org."], + "flags": ["*message", "*routes","*continue"], + "request_fields":[ + {"tag": "ToR", "path": "*cgreq.Account", "type": "*constant", "value": "1003"} + ], + "reply_fields":[ + {"tag": "DispatchReply", "type": "*none", + "blocker": true} + ] + }, + { + "id": "SRVSuppliersOneSupplier", + "filters": ["*string:~*vars.QueryType:SRV", + "*string:~*vars.QueryName:_xmpp-client._tcp.xmpp.org.", + "*gte:~*cgrep.RouteProfiles.Length:1", + "*gte:~*cgrep.RouteProfiles[0].Routes.Length:1"], + "flags": ["*none","*continue"], + "reply_fields":[ + {"tag": "SRVHdr", "path": "*rep.Answer.Hdr.Name", "type": "*group", "value": "_xmpp-client._tcp.xmpp.org."}, + {"tag": "SRVPriority", "path": "*rep.Answer.Priority", "type": "*group", "value": "1"}, + {"tag": "SRVWeight", "path": "*rep.Answer.Weight", "type": "*group", "value": "1"}, + {"tag": "SRVPort", "path": "*rep.Answer.Port", "type": "*group", "value": "9222"}, + {"tag": "SRVTarget", "path": "*rep.Answer.Target", "type": "*group", "value": "~*cgrep.RouteProfiles[0].Routes[0].RouteParameters"} + ] + }, + { + "id": "SRVSuppliersTwoSuppliers", + "filters": ["*string:~*vars.QueryType:SRV", + "*string:~*vars.QueryName:_xmpp-client._tcp.xmpp.org.", + "*gte:~*cgrep.RouteProfiles.Length:1", + "*gte:~*cgrep.RouteProfiles[0].Routes.Length:2"], + "flags": ["*none","*continue"], + "reply_fields":[ + {"tag": "SRVHdr", "path": "*rep.Answer[1].Hdr.Name", "type": "*group", "value": "_xmpp-client._tcp.xmpp.org."}, + {"tag": "SRVPriority", "path": "*rep.Answer[1].Priority", "type": "*group", "value": "1"}, + {"tag": "SRVWeight", "path": "*rep.Answer[1].Weight", "type": "*group", "value": "1"}, + {"tag": "SRVPort", "path": "*rep.Answer[1].Port", "type": "*group", "value": "9222"}, + {"tag": "SRVTarget", "path": "*rep.Answer[1].Target", "type": "*group", "value": "~*cgrep.RouteProfiles[0].Routes[1].RouteParameters"} + ] + } + ] + } + + } + \ No newline at end of file diff --git a/data/conf/samples/dnsagent_mongo/attributes.json b/data/conf/samples/dnsagent_mongo/attributes.json index e79f73516..5a4bb44eb 100644 --- a/data/conf/samples/dnsagent_mongo/attributes.json +++ b/data/conf/samples/dnsagent_mongo/attributes.json @@ -1,31 +1,72 @@ { - -"dns_agent": { - "request_processors": [ - { - "id": "NAPTRAttributes", - "filters": ["*string:~*vars.QueryType:NAPTR", "*string:~*vars.QueryName{*e164}:4986517174964"], - "flags": ["*authorize", "*attributes","*log"], - "request_fields":[ - {"tag": "E164Address", "path": "*cgreq.E164Address", - "type": "*constant", "value": "4986517174964"}, - {"tag": "NAPTRAddress", "path": "*cgreq.NAPTRAddress", - "type": "*constant", "value": "*attributes"} - ], - "reply_fields":[ - {"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": "NAPTRRegex", "path": "*rep.Answer.Regexp", - "type": "*variable", "value": "~*cgrep.Attributes.NAPTRAddress"}, - ], - }, - ], -}, - -} \ No newline at end of file + "dns_agent": { + "request_processors": [ + { + "id": "NAPTRAttributes", + "filters": ["*string:~*vars.QueryType:NAPTR", "*string:~*vars.QueryName{*e164}:4986517174964"], + "flags": ["*authorize", "*attributes","*log"], + "request_fields":[ + {"tag": "E164Address", "path": "*cgreq.E164Address", + "type": "*constant", "value": "4986517174964"}, + {"tag": "NAPTRAddress", "path": "*cgreq.NAPTRAddress", + "type": "*constant", "value": "*attributes"} + ], + "reply_fields":[ + {"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": "NAPTRRegex", "path": "*rep.Answer.Regexp", + "type": "*variable", "value": "~*cgrep.Attributes.NAPTRAddress"} + ] + }, + { + "id": "AAttributes", + "filters": ["*string:~*vars.QueryType:A", "*string:~*vars.QueryName:dns.google."], + "flags": ["*authorize","*attributes","*log"], + "request_fields":[ + {"tag": "Domain", "path": "*cgreq.Domain", + "type": "*constant", "value": "dns.google."}, + {"tag": "ADomain0", "path": "*cgreq.Aip0", + "type": "*constant", "value": "*attributes"}, + {"tag": "ADomain1", "path": "*cgreq.Aip1", + "type": "*constant", "value": "*attributes"} + ], + "reply_fields":[ + {"tag": "Aname", "path": "*rep.Answer.Hdr.Name", "type": "*constant", "value": "dns.google."}, + {"tag": "Attl", "path": "*rep.Answer.Hdr.Ttl", "type": "*constant", "value": "300"}, + {"tag": "Aclass", "path": "*rep.Answer.Hdr.Class", "type": "*constant", "value": "1"}, + {"tag": "Arrtype", "path": "*rep.Answer.Hdr.Rrtype", "type": "*constant", "value": "1"}, + {"tag": "Aip0", "path": "*rep.Answer.A", "type": "*variable", "value": "~*cgrep.Attributes.Aip0"}, + {"tag": "Aname1", "path": "*rep.Answer[1].Hdr.Name", "type": "*constant", "value": "dns.google."}, + {"tag": "Attl1", "path": "*rep.Answer[1].Hdr.Ttl", "type": "*constant", "value": "300"}, + {"tag": "Aclass1", "path": "*rep.Answer[1].Hdr.Class", "type": "*constant", "value": "1"}, + {"tag": "Arrtype1", "path": "*rep.Answer[1].Hdr.Rrtype", "type": "*constant", "value": "1"}, + {"tag": "Aip1", "path": "*rep.Answer[1].A", "type": "*variable", "value": "~*cgrep.Attributes.Aip1"} + ] + }, + { + "id": "SRVAttributes", + "filters": ["*string:~*vars.QueryType:SRV", "*string:~*vars.QueryName:_ldap._tcp.google.com."], + "flags": ["*authorize", "*attributes","*log"], + "request_fields":[ + {"tag": "SRVAddress", "path": "*cgreq.SRVAddress", + "type": "*constant", "value": "_ldap._tcp.google.com."}, + {"tag": "SRVName", "path": "*cgreq.SRVName", + "type": "*constant", "value": "*attributes"} + ], + "reply_fields":[ + {"tag": "SRVHdr", "path": "*rep.Answer.Hdr.Name", "type": "*constant", "value": "_ldap._tcp.google.com."}, + {"tag": "SRVPriority", "path": "*rep.Answer.Priority", "type": "*constant", "value": "5"}, + {"tag": "SRVWeight", "path": "*rep.Answer.Weight", "type": "*constant", "value": "0"}, + {"tag": "SRVPort", "path": "*rep.Answer.Port", "type": "*constant", "value": "389"}, + {"tag": "SRVTarget", "path": "*rep.Answer.Target", "type": "*variable", "value": "~*cgrep.Attributes.SRVName"} + ] + } + ] + } + } \ No newline at end of file diff --git a/data/conf/samples/dnsagent_mongo/cgrates.json b/data/conf/samples/dnsagent_mongo/cgrates.json index 3b454178b..7d03a90de 100644 --- a/data/conf/samples/dnsagent_mongo/cgrates.json +++ b/data/conf/samples/dnsagent_mongo/cgrates.json @@ -30,6 +30,32 @@ "cdrs_conns": ["*internal"], "chargers_conns": ["*internal"], "routes_conns": ["*localhost"], + "opts": { + "*attributes": [ + { + "Tenant": "*any", + "FilterIDs": [], + "Value": true, + }, + ], + "*routes": [ + { + "Tenant": "*any", + "FilterIDs": ["*string:~*req.Account:1001"], + "Value": true, + }, + { + "Tenant": "*any", + "FilterIDs": ["*string:~*req.Account:1002"], + "Value": true, + }, + { + "Tenant": "*any", + "FilterIDs": ["*string:~*req.Account:1003"], + "Value": true, + }, + ], + } }, @@ -37,6 +63,15 @@ "enabled": true, }, +"loaders": [ + { + "enabled":true, + "id": "*default", + "tp_in_dir": "/usr/share/cgrates/tariffplans/dnsagent", + "tp_out_dir": "", + "lockfile_path": "", + }, +], "cdrs": { "enabled": true, @@ -58,10 +93,30 @@ "enabled": true, }, +"tls": { + "server_certificate" : "/usr/share/cgrates/tls/server.crt", // path to server certificate(must conatin server.crt + ca.crt) + "server_key":"/usr/share/cgrates/tls/server.key", // path to server key + "client_certificate" : "/usr/share/cgrates/tls/client.crt", // path to client certificate(must conatin client.crt + ca.crt) + "client_key":"/usr/share/cgrates/tls/client.key", // path to client key + "ca_certificate":"/usr/share/cgrates/tls/ca.crt", +}, "dns_agent": { "enabled": true, - "listen": ":2053", + "listeners":[ + { + "address":":2053", + "network":"udp" + }, + { + "address":":2053", + "network":"tcp" + }, + { + "address":":2054", + "network":"tcp-tls" + } + ], "sessions_conns": ["*localhost"], }, diff --git a/data/conf/samples/dnsagent_mongo/dryrun.json b/data/conf/samples/dnsagent_mongo/dryrun.json index 26535baec..b9653cb4c 100644 --- a/data/conf/samples/dnsagent_mongo/dryrun.json +++ b/data/conf/samples/dnsagent_mongo/dryrun.json @@ -5,9 +5,9 @@ { "id": "DryRunNAPTR", "filters": ["*string:~*vars.QueryType:NAPTR", "*string:~*vars.QueryName{*e164}:4986517174963"], - "flags": ["*dryrun","*log"], + "flags": ["*dryRun","*log"], "request_fields":[ - {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*sms"}, + {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*sms"} ], "reply_fields":[ {"tag": "NAPTROrder", "path": "*rep.Answer.Order", "type": "*constant", "value": "100"}, @@ -15,10 +15,40 @@ {"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": "."}, - ], + {"tag": "NAPTRReplacement", "path": "*rep.Answer.Replacement", "type": "*constant", "value": "."} + ] }, - ], -}, + { + "id": "DryRunA", + "filters": ["*string:~*vars.QueryType:A", "*string:~*vars.QueryName:cgrates.org."], + "flags": ["*dryRun","*log"], + "request_fields":[ + {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*sms"} + ], + "reply_fields":[ + {"tag": "Aname", "path": "*rep.Answer.Hdr.Name", "type": "*constant", "value": "cgrates.org."}, + {"tag": "Attl", "path": "*rep.Answer.Hdr.Ttl", "type": "*constant", "value": "300"}, + {"tag": "Aclass", "path": "*rep.Answer.Hdr.Class", "type": "*constant", "value": "1"}, + {"tag": "Arrtype", "path": "*rep.Answer.Hdr.Rrtype", "type": "*constant", "value": "1"}, + {"tag": "Aip", "path": "*rep.Answer.A", "type": "*constant", "value": "51.38.77.188"} + ] + }, + { + "id": "DryRunSRV", + "filters": ["*string:~*vars.QueryType:SRV", "*string:~*vars.QueryName:_sip._tcp.opensips.org."], + "flags": ["*dryRun","*log"], + "request_fields":[ + {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*sms"} + ], + "reply_fields":[ + {"tag": "SRVHdr", "path": "*rep.Answer.Hdr.Name", "type": "*constant", "value": "_sip._tcp.opensips.org."}, + {"tag": "SRVPort", "path": "*rep.Answer.Port", "type": "*constant", "value": "5060"}, + {"tag": "SRVPriority", "path": "*rep.Answer.Priority", "type": "*constant", "value": "0"}, + {"tag": "SRVWeight", "path": "*rep.Answer.Weight", "type": "*constant", "value": "50"}, + {"tag": "SRVTarget", "path": "*rep.Answer.Target", "type": "*constant", "value": "opensips.org."} + ] + } + ] +} } \ No newline at end of file diff --git a/data/conf/samples/dnsagent_mongo/opts.json b/data/conf/samples/dnsagent_mongo/opts.json index 2da9770c6..9fd9b986e 100644 --- a/data/conf/samples/dnsagent_mongo/opts.json +++ b/data/conf/samples/dnsagent_mongo/opts.json @@ -4,9 +4,9 @@ { "id": "OptsNAPTR", "filters": ["*string:~*vars.QueryType:NAPTR", "*string:~*vars.QueryName{*e164}:5986517174965", "*string:~*req.Option[0].Uri:sip:cgrates@cgrates.org"], - "flags": ["*dryrun","*log"], + "flags": ["*dryRun","*log"], "request_fields":[ - {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*sms"}, + {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*sms"} ], "reply_fields":[ {"tag": "NAPTROrder", "path": "*rep.Answer.Order", "type": "*constant", "value": "100"}, @@ -17,8 +17,8 @@ {"tag": "NAPTRReplacement", "path": "*rep.Answer.Replacement", "type": "*constant", "value": "."}, {"tag": "Opts", "path": "*rep.Option.Uri", "type": "*constant", "value": "sip:cgrates@cgrates.co"}, {"tag": "Opts2", "path": "*rep.Option.Uri", "type": "*group", "value": "sip:cgrates@cgrates.net", "new_branch":true}, - {"tag": "Opts3", "path": "*rep.Option[0].Uri", "type": "*constant", "value": "sip:cgrates@cgrates.com"}, - ], + {"tag": "Opts3", "path": "*rep.Option[0].Uri", "type": "*constant", "value": "sip:cgrates@cgrates.com"} + ] }, { "id": "OptsWithAttributes", @@ -27,7 +27,7 @@ "request_fields":[ {"tag": "Origin", "path": "*cgreq.Origin", "type": "*variable", "value": "~*req.Option[0].Uri{*sipuri_user}"}, {"tag": "Domanin", "path": "*cgreq.Domanin", "type": "*variable", "value": "~*vars.QueryName{*e164Domain}"}, - {"tag": "NewSipURI", "path": "*cgreq.SipURI", "type": "*constant", "value": "*attributes"}, + {"tag": "NewSipURI", "path": "*cgreq.SipURI", "type": "*constant", "value": "*attributes"} ], "reply_fields":[ {"tag": "NAPTROrder", "path": "*rep.Answer.Order", "type": "*constant", "value": "100"}, @@ -36,10 +36,82 @@ {"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": "."}, - {"tag": "Opts", "path": "*rep.Option.Uri", "type": "*variable", "value": "~*cgrep.Attributes[*raw].SipURI", "mandatory": true}, - ], + {"tag": "Opts", "path": "*rep.Option.Uri", "type": "*variable", "value": "~*cgrep.Attributes[*raw].SipURI", "mandatory": true} + ] }, - ], - }, + { + "id": "OptsA", + "filters": ["*string:~*vars.QueryType:A", "*string:~*vars.QueryName:example.com.", "*string:~*req.Option[0].Uri:sip:cgrates@cgrates.org"], + "flags": ["*dryRun","*log"], + "request_fields":[ + {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*sms"} + ], + "reply_fields":[ + {"tag": "Aname", "path": "*rep.Answer.Hdr.Name", "type": "*constant", "value": "example.com."}, + {"tag": "Attl", "path": "*rep.Answer.Hdr.Ttl", "type": "*constant", "value": "300"}, + {"tag": "Aclass", "path": "*rep.Answer.Hdr.Class", "type": "*constant", "value": "1"}, + {"tag": "Arrtype", "path": "*rep.Answer.Hdr.Rrtype", "type": "*constant", "value": "1"}, + {"tag": "Aip", "path": "*rep.Answer.A", "type": "*constant", "value": "93.184.216.34"}, + {"tag": "Opts", "path": "*rep.Option.Uri", "type": "*constant", "value": "sip:cgrates@cgrates.co"}, + {"tag": "Opts2", "path": "*rep.Option.Uri", "type": "*group", "value": "sip:cgrates@cgrates.net", "new_branch":true}, + {"tag": "Opts3", "path": "*rep.Option[0].Uri", "type": "*constant", "value": "sip:cgrates@cgrates.com"} + ] + }, + { + "id": "AOptsWithAttributes", + "filters": ["*string:~*vars.QueryType:A", "*string:~*vars.QueryName:opendns.com."], + "flags": ["*event","*attributes"], + "request_fields":[ + {"tag": "Origin", "path": "*cgreq.AOrigin", "type": "*variable", "value": "~*req.Option[0].Uri{*sipuri_user}"}, + {"tag": "Domain", "path": "*cgreq.ASIPDomain", "type": "*variable", "value": "~*vars.QueryName"}, + {"tag": "NewSipURI", "path": "*cgreq.SipURI", "type": "*constant", "value": "*attributes"} + ], + "reply_fields":[ + {"tag": "Aname", "path": "*rep.Answer.Hdr.Name", "type": "*constant", "value": "example.com."}, + {"tag": "Attl", "path": "*rep.Answer.Hdr.Ttl", "type": "*constant", "value": "300"}, + {"tag": "Aclass", "path": "*rep.Answer.Hdr.Class", "type": "*constant", "value": "1"}, + {"tag": "Arrtype", "path": "*rep.Answer.Hdr.Rrtype", "type": "*constant", "value": "1"}, + {"tag": "Aip", "path": "*rep.Answer.A", "type": "*constant", "value": "146.112.62.105"}, + {"tag": "Opts", "path": "*rep.Option.Uri", "type": "*variable", "value": "~*cgrep.Attributes[*raw].SipURI", "mandatory": true} + ] + }, + { + "id": "OptsSRV", + "filters": ["*string:~*vars.QueryType:SRV", "*string:~*vars.QueryName:_matrix._tcp.matrix.org.", "*string:~*req.Option[0].Uri:sip:cgrates@cgrates.org"], + "flags": ["*dryRun","*log"], + "request_fields":[ + {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*sms"} + ], + "reply_fields":[ + {"tag": "SRVHdr", "path": "*rep.Answer.Hdr.Name", "type": "*constant", "value": "_xmpp-client._tcp.xmpp.org."}, + {"tag": "SRVPriority", "path": "*rep.Answer.Priority", "type": "*constant", "value": "10"}, + {"tag": "SRVWeight", "path": "*rep.Answer.Weight", "type": "*constant", "value": "5"}, + {"tag": "SRVPort", "path": "*rep.Answer.Port", "type": "*constant", "value": "8443"}, + {"tag": "SRVTarget", "path": "*rep.Answer.Target", "type": "*constant", "value": "matrix-federation.matrix.org.cdn.cloudflare.net."}, + {"tag": "Opts", "path": "*rep.Option.Uri", "type": "*constant", "value": "sip:cgrates@cgrates.co"}, + {"tag": "Opts2", "path": "*rep.Option.Uri", "type": "*group", "value": "sip:cgrates@cgrates.net", "new_branch":true}, + {"tag": "Opts3", "path": "*rep.Option[0].Uri", "type": "*constant", "value": "sip:cgrates@cgrates.com"} + ] + }, + { + "id": "SRVOptsWithAttributes", + "filters": ["*string:~*vars.QueryType:SRV", "*string:~*vars.QueryName:_sip._udp.opensips.org."], + "flags": ["*event","*attributes"], + "request_fields":[ + {"tag": "Origin", "path": "*cgreq.SRVOrigin", "type": "*variable", "value": "~*req.Option[0].Uri{*sipuri_user}"}, + {"tag": "Domain", "path": "*cgreq.SRVDomain", "type": "*variable", "value": "~*vars.QueryName"}, + {"tag": "NewSipURI", "path": "*cgreq.SipURI", "type": "*constant", "value": "*attributes"} + ], + "reply_fields":[ + {"tag": "SRVHdr", "path": "*rep.Answer.Hdr.Name", "type": "*constant", "value": "_sip._udp.opensips.org."}, + {"tag": "SRVPriority", "path": "*rep.Answer.Priority", "type": "*constant", "value": "0"}, + {"tag": "SRVWeight", "path": "*rep.Answer.Weight", "type": "*constant", "value": "50"}, + {"tag": "SRVPort", "path": "*rep.Answer.Port", "type": "*constant", "value": "5060"}, + {"tag": "SRVTarget", "path": "*rep.Answer.Target", "type": "*constant", "value": "opensips.org."}, + {"tag": "Opts", "path": "*rep.Option.Uri", "type": "*variable", "value": "~*cgrep.Attributes[*raw].SipURI", "mandatory": true} + ] + } + ] + } - } \ No newline at end of file +} \ No newline at end of file diff --git a/data/conf/samples/dnsagent_mongo/suppliers.json b/data/conf/samples/dnsagent_mongo/suppliers.json index 3e1e52ab8..f36f1e36a 100644 --- a/data/conf/samples/dnsagent_mongo/suppliers.json +++ b/data/conf/samples/dnsagent_mongo/suppliers.json @@ -59,6 +59,92 @@ "type": "*group", "value": "."}, ], }, + { + "id": "ARoutesQuery", + "filters": ["*string:~*vars.QueryType:A", + "*string:~*vars.QueryName:go.dev."], + "flags": ["*message", "*routes","*continue"], + "request_fields":[ + {"tag": "ToR", "path": "*cgreq.Account", "type": "*constant", "value": "1002"} + ], + "reply_fields":[ + {"tag": "DispatchReply", "type": "*none", + "blocker": true} + ] + }, + { + "id": "ASuppliersOneSupplier", + "filters": ["*string:~*vars.QueryType:A", + "*string:~*vars.QueryName:go.dev.", + "*gte:~*cgrep.RouteProfiles.Length:1", + "*gte:~*cgrep.RouteProfiles[0].Routes.Length:2"], + "flags": ["*none","*continue"], + "reply_fields":[ + {"tag": "Aname", "path": "*rep.Answer.Hdr.Name", "type": "*group", "value": "go.dev."}, + {"tag": "Attl", "path": "*rep.Answer.Hdr.Ttl", "type": "*group", "value": "300"}, + {"tag": "Aclass", "path": "*rep.Answer.Hdr.Class", "type": "*group", "value": "1"}, + {"tag": "Arrtype", "path": "*rep.Answer.Hdr.Rrtype", "type": "*group", "value": "1"}, + {"tag": "Aip", "path": "*rep.Answer.A", "type": "*group", "value": "~*cgrep.RouteProfiles[0].Routes[0].RouteParameters"} + ] + }, + { + "id": "ASuppliersTwoSuppliers", + "filters": ["*string:~*vars.QueryType:A", + "*string:~*vars.QueryName:go.dev.", + "*gte:~*cgrep.RouteProfiles.Length:1", + "*gte:~*cgrep.RouteProfiles[0].Routes.Length:2"], + "flags": ["*none","*continue"], + "reply_fields":[ + {"tag": "Aname", "path": "*rep.Answer[1].Hdr.Name", "type": "*group", "value": "go.dev."}, + {"tag": "Attl", "path": "*rep.Answer[1].Hdr.Ttl", "type": "*group", "value": "300"}, + {"tag": "Aclass", "path": "*rep.Answer[1].Hdr.Class", "type": "*group", "value": "1"}, + {"tag": "Arrtype", "path": "*rep.Answer[1].Hdr.Rrtype", "type": "*group", "value": "1"}, + {"tag": "Aip", "path": "*rep.Answer[1].A", "type": "*group", "value": "~*cgrep.RouteProfiles[0].Routes[1].RouteParameters"} + ] + }, + { + "id": "SRVRoutesQuery", + "filters": ["*string:~*vars.QueryType:SRV", + "*string:~*vars.QueryName:_xmpp-client._tcp.xmpp.org."], + "flags": ["*message", "*routes","*continue"], + "request_fields":[ + {"tag": "ToR", "path": "*cgreq.Account", "type": "*constant", "value": "1003"} + ], + "reply_fields":[ + {"tag": "DispatchReply", "type": "*none", + "blocker": true} + ] + }, + { + "id": "SRVSuppliersOneSupplier", + "filters": ["*string:~*vars.QueryType:SRV", + "*string:~*vars.QueryName:_xmpp-client._tcp.xmpp.org.", + "*gte:~*cgrep.RouteProfiles.Length:1", + "*gte:~*cgrep.RouteProfiles[0].Routes.Length:1"], + "flags": ["*none","*continue"], + "reply_fields":[ + {"tag": "SRVHdr", "path": "*rep.Answer.Hdr.Name", "type": "*group", "value": "_xmpp-client._tcp.xmpp.org."}, + {"tag": "SRVPriority", "path": "*rep.Answer.Priority", "type": "*group", "value": "1"}, + {"tag": "SRVWeight", "path": "*rep.Answer.Weight", "type": "*group", "value": "1"}, + {"tag": "SRVPort", "path": "*rep.Answer.Port", "type": "*group", "value": "9222"}, + {"tag": "SRVTarget", "path": "*rep.Answer.Target", "type": "*group", "value": "~*cgrep.RouteProfiles[0].Routes[0].RouteParameters"} + ] + }, + { + "id": "SRVSuppliersTwoSuppliers", + "filters": ["*string:~*vars.QueryType:SRV", + "*string:~*vars.QueryName:_xmpp-client._tcp.xmpp.org.", + "*gte:~*cgrep.RouteProfiles.Length:1", + "*gte:~*cgrep.RouteProfiles[0].Routes.Length:2"], + "flags": ["*none","*continue"], + "reply_fields":[ + {"tag": "SRVHdr", "path": "*rep.Answer[1].Hdr.Name", "type": "*group", "value": "_xmpp-client._tcp.xmpp.org."}, + {"tag": "SRVPriority", "path": "*rep.Answer[1].Priority", "type": "*group", "value": "1"}, + {"tag": "SRVWeight", "path": "*rep.Answer[1].Weight", "type": "*group", "value": "1"}, + {"tag": "SRVPort", "path": "*rep.Answer[1].Port", "type": "*group", "value": "9222"}, + {"tag": "SRVTarget", "path": "*rep.Answer[1].Target", "type": "*group", "value": "~*cgrep.RouteProfiles[0].Routes[1].RouteParameters"} + ] + } ], }, diff --git a/data/conf/samples/dnsagent_mysql/attributes.json b/data/conf/samples/dnsagent_mysql/attributes.json index 0eb837549..5a4bb44eb 100644 --- a/data/conf/samples/dnsagent_mysql/attributes.json +++ b/data/conf/samples/dnsagent_mysql/attributes.json @@ -1,29 +1,72 @@ { -"dns_agent": { - "request_processors": [ - { - "id": "NAPTRAttributes", - "filters": ["*string:~*vars.QueryType:NAPTR", "*string:~*vars.QueryName{*e164}:4986517174964"], - "flags": ["*authorize", "*attributes","*log"], - "request_fields":[ - {"tag": "E164Address", "path": "*cgreq.E164Address", - "type": "*constant", "value": "4986517174964"}, - {"tag": "NAPTRAddress", "path": "*cgreq.NAPTRAddress", - "type": "*constant", "value": "*attributes"} - ], - "reply_fields":[ - {"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": "NAPTRRegex", "path": "*rep.Answer.Regexp", - "type": "*variable", "value": "~*cgrep.Attributes.NAPTRAddress"}, - ], - }, - ], -}, -} \ No newline at end of file + "dns_agent": { + "request_processors": [ + { + "id": "NAPTRAttributes", + "filters": ["*string:~*vars.QueryType:NAPTR", "*string:~*vars.QueryName{*e164}:4986517174964"], + "flags": ["*authorize", "*attributes","*log"], + "request_fields":[ + {"tag": "E164Address", "path": "*cgreq.E164Address", + "type": "*constant", "value": "4986517174964"}, + {"tag": "NAPTRAddress", "path": "*cgreq.NAPTRAddress", + "type": "*constant", "value": "*attributes"} + ], + "reply_fields":[ + {"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": "NAPTRRegex", "path": "*rep.Answer.Regexp", + "type": "*variable", "value": "~*cgrep.Attributes.NAPTRAddress"} + ] + }, + { + "id": "AAttributes", + "filters": ["*string:~*vars.QueryType:A", "*string:~*vars.QueryName:dns.google."], + "flags": ["*authorize","*attributes","*log"], + "request_fields":[ + {"tag": "Domain", "path": "*cgreq.Domain", + "type": "*constant", "value": "dns.google."}, + {"tag": "ADomain0", "path": "*cgreq.Aip0", + "type": "*constant", "value": "*attributes"}, + {"tag": "ADomain1", "path": "*cgreq.Aip1", + "type": "*constant", "value": "*attributes"} + ], + "reply_fields":[ + {"tag": "Aname", "path": "*rep.Answer.Hdr.Name", "type": "*constant", "value": "dns.google."}, + {"tag": "Attl", "path": "*rep.Answer.Hdr.Ttl", "type": "*constant", "value": "300"}, + {"tag": "Aclass", "path": "*rep.Answer.Hdr.Class", "type": "*constant", "value": "1"}, + {"tag": "Arrtype", "path": "*rep.Answer.Hdr.Rrtype", "type": "*constant", "value": "1"}, + {"tag": "Aip0", "path": "*rep.Answer.A", "type": "*variable", "value": "~*cgrep.Attributes.Aip0"}, + {"tag": "Aname1", "path": "*rep.Answer[1].Hdr.Name", "type": "*constant", "value": "dns.google."}, + {"tag": "Attl1", "path": "*rep.Answer[1].Hdr.Ttl", "type": "*constant", "value": "300"}, + {"tag": "Aclass1", "path": "*rep.Answer[1].Hdr.Class", "type": "*constant", "value": "1"}, + {"tag": "Arrtype1", "path": "*rep.Answer[1].Hdr.Rrtype", "type": "*constant", "value": "1"}, + {"tag": "Aip1", "path": "*rep.Answer[1].A", "type": "*variable", "value": "~*cgrep.Attributes.Aip1"} + ] + }, + { + "id": "SRVAttributes", + "filters": ["*string:~*vars.QueryType:SRV", "*string:~*vars.QueryName:_ldap._tcp.google.com."], + "flags": ["*authorize", "*attributes","*log"], + "request_fields":[ + {"tag": "SRVAddress", "path": "*cgreq.SRVAddress", + "type": "*constant", "value": "_ldap._tcp.google.com."}, + {"tag": "SRVName", "path": "*cgreq.SRVName", + "type": "*constant", "value": "*attributes"} + ], + "reply_fields":[ + {"tag": "SRVHdr", "path": "*rep.Answer.Hdr.Name", "type": "*constant", "value": "_ldap._tcp.google.com."}, + {"tag": "SRVPriority", "path": "*rep.Answer.Priority", "type": "*constant", "value": "5"}, + {"tag": "SRVWeight", "path": "*rep.Answer.Weight", "type": "*constant", "value": "0"}, + {"tag": "SRVPort", "path": "*rep.Answer.Port", "type": "*constant", "value": "389"}, + {"tag": "SRVTarget", "path": "*rep.Answer.Target", "type": "*variable", "value": "~*cgrep.Attributes.SRVName"} + ] + } + ] + } + } \ No newline at end of file diff --git a/data/conf/samples/dnsagent_mysql/cgrates.json b/data/conf/samples/dnsagent_mysql/cgrates.json index c5d09c3f5..54988625f 100644 --- a/data/conf/samples/dnsagent_mysql/cgrates.json +++ b/data/conf/samples/dnsagent_mysql/cgrates.json @@ -22,6 +22,32 @@ "cdrs_conns": ["*internal"], "chargers_conns": ["*internal"], "routes_conns": ["*localhost"], + "opts": { + "*attributes": [ + { + "Tenant": "*any", + "FilterIDs": [], + "Value": true, + }, + ], + "*routes": [ + { + "Tenant": "*any", + "FilterIDs": ["*string:~*req.Account:1001"], + "Value": true, + }, + { + "Tenant": "*any", + "FilterIDs": ["*string:~*req.Account:1002"], + "Value": true, + }, + { + "Tenant": "*any", + "FilterIDs": ["*string:~*req.Account:1003"], + "Value": true, + }, + ], + } }, @@ -29,6 +55,15 @@ "enabled": true, }, +"loaders": [ + { + "enabled":true, + "id": "*default", + "tp_in_dir": "/usr/share/cgrates/tariffplans/dnsagent", + "tp_out_dir": "", + "lockfile_path": "", + }, +], "cdrs": { "enabled": true, @@ -50,10 +85,30 @@ "enabled": true, }, +"tls": { + "server_certificate" : "/usr/share/cgrates/tls/server.crt", // path to server certificate(must conatin server.crt + ca.crt) + "server_key":"/usr/share/cgrates/tls/server.key", // path to server key + "client_certificate" : "/usr/share/cgrates/tls/client.crt", // path to client certificate(must conatin client.crt + ca.crt) + "client_key":"/usr/share/cgrates/tls/client.key", // path to client key + "ca_certificate":"/usr/share/cgrates/tls/ca.crt", +}, "dns_agent": { "enabled": true, - "listen": ":2053", + "listeners":[ + { + "address":":2053", + "network":"udp" + }, + { + "address":":2053", + "network":"tcp" + }, + { + "address":":2054", + "network":"tcp-tls" + } + ], "sessions_conns": ["*localhost"], }, diff --git a/data/conf/samples/dnsagent_mysql/dryrun.json b/data/conf/samples/dnsagent_mysql/dryrun.json index 242196a3c..f7803799d 100644 --- a/data/conf/samples/dnsagent_mysql/dryrun.json +++ b/data/conf/samples/dnsagent_mysql/dryrun.json @@ -4,9 +4,9 @@ { "id": "DryRunNAPTR", "filters": ["*string:~*vars.QueryType:NAPTR", "*string:~*vars.QueryName{*e164}:4986517174963"], - "flags": ["*dryrun","*log"], + "flags": ["*dryRun","*log"], "request_fields":[ - {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*sms"}, + {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*sms"} ], "reply_fields":[ {"tag": "NAPTROrder", "path": "*rep.Answer.Order", "type": "*constant", "value": "100"}, @@ -14,9 +14,39 @@ {"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": "."}, - ], + {"tag": "NAPTRReplacement", "path": "*rep.Answer.Replacement", "type": "*constant", "value": "."} + ] }, - ], -}, + { + "id": "DryRunA", + "filters": ["*string:~*vars.QueryType:A", "*string:~*vars.QueryName:cgrates.org."], + "flags": ["*dryRun","*log"], + "request_fields":[ + {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*sms"} + ], + "reply_fields":[ + {"tag": "Aname", "path": "*rep.Answer.Hdr.Name", "type": "*constant", "value": "cgrates.org."}, + {"tag": "Attl", "path": "*rep.Answer.Hdr.Ttl", "type": "*constant", "value": "300"}, + {"tag": "Aclass", "path": "*rep.Answer.Hdr.Class", "type": "*constant", "value": "1"}, + {"tag": "Arrtype", "path": "*rep.Answer.Hdr.Rrtype", "type": "*constant", "value": "1"}, + {"tag": "Aip", "path": "*rep.Answer.A", "type": "*constant", "value": "51.38.77.188"} + ] + }, + { + "id": "DryRunSRV", + "filters": ["*string:~*vars.QueryType:SRV", "*string:~*vars.QueryName:_sip._tcp.opensips.org."], + "flags": ["*dryRun","*log"], + "request_fields":[ + {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*sms"} + ], + "reply_fields":[ + {"tag": "SRVHdr", "path": "*rep.Answer.Hdr.Name", "type": "*constant", "value": "_sip._tcp.opensips.org."}, + {"tag": "SRVPort", "path": "*rep.Answer.Port", "type": "*constant", "value": "5060"}, + {"tag": "SRVPriority", "path": "*rep.Answer.Priority", "type": "*constant", "value": "0"}, + {"tag": "SRVWeight", "path": "*rep.Answer.Weight", "type": "*constant", "value": "50"}, + {"tag": "SRVTarget", "path": "*rep.Answer.Target", "type": "*constant", "value": "opensips.org."} + ] + } + ] +} } diff --git a/data/conf/samples/dnsagent_mysql/opts.json b/data/conf/samples/dnsagent_mysql/opts.json index 2da9770c6..9fd9b986e 100644 --- a/data/conf/samples/dnsagent_mysql/opts.json +++ b/data/conf/samples/dnsagent_mysql/opts.json @@ -4,9 +4,9 @@ { "id": "OptsNAPTR", "filters": ["*string:~*vars.QueryType:NAPTR", "*string:~*vars.QueryName{*e164}:5986517174965", "*string:~*req.Option[0].Uri:sip:cgrates@cgrates.org"], - "flags": ["*dryrun","*log"], + "flags": ["*dryRun","*log"], "request_fields":[ - {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*sms"}, + {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*sms"} ], "reply_fields":[ {"tag": "NAPTROrder", "path": "*rep.Answer.Order", "type": "*constant", "value": "100"}, @@ -17,8 +17,8 @@ {"tag": "NAPTRReplacement", "path": "*rep.Answer.Replacement", "type": "*constant", "value": "."}, {"tag": "Opts", "path": "*rep.Option.Uri", "type": "*constant", "value": "sip:cgrates@cgrates.co"}, {"tag": "Opts2", "path": "*rep.Option.Uri", "type": "*group", "value": "sip:cgrates@cgrates.net", "new_branch":true}, - {"tag": "Opts3", "path": "*rep.Option[0].Uri", "type": "*constant", "value": "sip:cgrates@cgrates.com"}, - ], + {"tag": "Opts3", "path": "*rep.Option[0].Uri", "type": "*constant", "value": "sip:cgrates@cgrates.com"} + ] }, { "id": "OptsWithAttributes", @@ -27,7 +27,7 @@ "request_fields":[ {"tag": "Origin", "path": "*cgreq.Origin", "type": "*variable", "value": "~*req.Option[0].Uri{*sipuri_user}"}, {"tag": "Domanin", "path": "*cgreq.Domanin", "type": "*variable", "value": "~*vars.QueryName{*e164Domain}"}, - {"tag": "NewSipURI", "path": "*cgreq.SipURI", "type": "*constant", "value": "*attributes"}, + {"tag": "NewSipURI", "path": "*cgreq.SipURI", "type": "*constant", "value": "*attributes"} ], "reply_fields":[ {"tag": "NAPTROrder", "path": "*rep.Answer.Order", "type": "*constant", "value": "100"}, @@ -36,10 +36,82 @@ {"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": "."}, - {"tag": "Opts", "path": "*rep.Option.Uri", "type": "*variable", "value": "~*cgrep.Attributes[*raw].SipURI", "mandatory": true}, - ], + {"tag": "Opts", "path": "*rep.Option.Uri", "type": "*variable", "value": "~*cgrep.Attributes[*raw].SipURI", "mandatory": true} + ] }, - ], - }, + { + "id": "OptsA", + "filters": ["*string:~*vars.QueryType:A", "*string:~*vars.QueryName:example.com.", "*string:~*req.Option[0].Uri:sip:cgrates@cgrates.org"], + "flags": ["*dryRun","*log"], + "request_fields":[ + {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*sms"} + ], + "reply_fields":[ + {"tag": "Aname", "path": "*rep.Answer.Hdr.Name", "type": "*constant", "value": "example.com."}, + {"tag": "Attl", "path": "*rep.Answer.Hdr.Ttl", "type": "*constant", "value": "300"}, + {"tag": "Aclass", "path": "*rep.Answer.Hdr.Class", "type": "*constant", "value": "1"}, + {"tag": "Arrtype", "path": "*rep.Answer.Hdr.Rrtype", "type": "*constant", "value": "1"}, + {"tag": "Aip", "path": "*rep.Answer.A", "type": "*constant", "value": "93.184.216.34"}, + {"tag": "Opts", "path": "*rep.Option.Uri", "type": "*constant", "value": "sip:cgrates@cgrates.co"}, + {"tag": "Opts2", "path": "*rep.Option.Uri", "type": "*group", "value": "sip:cgrates@cgrates.net", "new_branch":true}, + {"tag": "Opts3", "path": "*rep.Option[0].Uri", "type": "*constant", "value": "sip:cgrates@cgrates.com"} + ] + }, + { + "id": "AOptsWithAttributes", + "filters": ["*string:~*vars.QueryType:A", "*string:~*vars.QueryName:opendns.com."], + "flags": ["*event","*attributes"], + "request_fields":[ + {"tag": "Origin", "path": "*cgreq.AOrigin", "type": "*variable", "value": "~*req.Option[0].Uri{*sipuri_user}"}, + {"tag": "Domain", "path": "*cgreq.ASIPDomain", "type": "*variable", "value": "~*vars.QueryName"}, + {"tag": "NewSipURI", "path": "*cgreq.SipURI", "type": "*constant", "value": "*attributes"} + ], + "reply_fields":[ + {"tag": "Aname", "path": "*rep.Answer.Hdr.Name", "type": "*constant", "value": "example.com."}, + {"tag": "Attl", "path": "*rep.Answer.Hdr.Ttl", "type": "*constant", "value": "300"}, + {"tag": "Aclass", "path": "*rep.Answer.Hdr.Class", "type": "*constant", "value": "1"}, + {"tag": "Arrtype", "path": "*rep.Answer.Hdr.Rrtype", "type": "*constant", "value": "1"}, + {"tag": "Aip", "path": "*rep.Answer.A", "type": "*constant", "value": "146.112.62.105"}, + {"tag": "Opts", "path": "*rep.Option.Uri", "type": "*variable", "value": "~*cgrep.Attributes[*raw].SipURI", "mandatory": true} + ] + }, + { + "id": "OptsSRV", + "filters": ["*string:~*vars.QueryType:SRV", "*string:~*vars.QueryName:_matrix._tcp.matrix.org.", "*string:~*req.Option[0].Uri:sip:cgrates@cgrates.org"], + "flags": ["*dryRun","*log"], + "request_fields":[ + {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*sms"} + ], + "reply_fields":[ + {"tag": "SRVHdr", "path": "*rep.Answer.Hdr.Name", "type": "*constant", "value": "_xmpp-client._tcp.xmpp.org."}, + {"tag": "SRVPriority", "path": "*rep.Answer.Priority", "type": "*constant", "value": "10"}, + {"tag": "SRVWeight", "path": "*rep.Answer.Weight", "type": "*constant", "value": "5"}, + {"tag": "SRVPort", "path": "*rep.Answer.Port", "type": "*constant", "value": "8443"}, + {"tag": "SRVTarget", "path": "*rep.Answer.Target", "type": "*constant", "value": "matrix-federation.matrix.org.cdn.cloudflare.net."}, + {"tag": "Opts", "path": "*rep.Option.Uri", "type": "*constant", "value": "sip:cgrates@cgrates.co"}, + {"tag": "Opts2", "path": "*rep.Option.Uri", "type": "*group", "value": "sip:cgrates@cgrates.net", "new_branch":true}, + {"tag": "Opts3", "path": "*rep.Option[0].Uri", "type": "*constant", "value": "sip:cgrates@cgrates.com"} + ] + }, + { + "id": "SRVOptsWithAttributes", + "filters": ["*string:~*vars.QueryType:SRV", "*string:~*vars.QueryName:_sip._udp.opensips.org."], + "flags": ["*event","*attributes"], + "request_fields":[ + {"tag": "Origin", "path": "*cgreq.SRVOrigin", "type": "*variable", "value": "~*req.Option[0].Uri{*sipuri_user}"}, + {"tag": "Domain", "path": "*cgreq.SRVDomain", "type": "*variable", "value": "~*vars.QueryName"}, + {"tag": "NewSipURI", "path": "*cgreq.SipURI", "type": "*constant", "value": "*attributes"} + ], + "reply_fields":[ + {"tag": "SRVHdr", "path": "*rep.Answer.Hdr.Name", "type": "*constant", "value": "_sip._udp.opensips.org."}, + {"tag": "SRVPriority", "path": "*rep.Answer.Priority", "type": "*constant", "value": "0"}, + {"tag": "SRVWeight", "path": "*rep.Answer.Weight", "type": "*constant", "value": "50"}, + {"tag": "SRVPort", "path": "*rep.Answer.Port", "type": "*constant", "value": "5060"}, + {"tag": "SRVTarget", "path": "*rep.Answer.Target", "type": "*constant", "value": "opensips.org."}, + {"tag": "Opts", "path": "*rep.Option.Uri", "type": "*variable", "value": "~*cgrep.Attributes[*raw].SipURI", "mandatory": true} + ] + } + ] + } - } \ No newline at end of file +} \ No newline at end of file diff --git a/data/conf/samples/dnsagent_mysql/suppliers.json b/data/conf/samples/dnsagent_mysql/suppliers.json index 63cc738eb..53a321151 100644 --- a/data/conf/samples/dnsagent_mysql/suppliers.json +++ b/data/conf/samples/dnsagent_mysql/suppliers.json @@ -58,6 +58,92 @@ "type": "*group", "value": "."}, ], }, + { + "id": "ARoutesQuery", + "filters": ["*string:~*vars.QueryType:A", + "*string:~*vars.QueryName:go.dev."], + "flags": ["*message", "*routes","*continue"], + "request_fields":[ + {"tag": "ToR", "path": "*cgreq.Account", "type": "*constant", "value": "1002"} + ], + "reply_fields":[ + {"tag": "DispatchReply", "type": "*none", + "blocker": true} + ] + }, + { + "id": "ASuppliersOneSupplier", + "filters": ["*string:~*vars.QueryType:A", + "*string:~*vars.QueryName:go.dev.", + "*gte:~*cgrep.RouteProfiles.Length:1", + "*gte:~*cgrep.RouteProfiles[0].Routes.Length:2"], + "flags": ["*none","*continue"], + "reply_fields":[ + {"tag": "Aname", "path": "*rep.Answer.Hdr.Name", "type": "*group", "value": "go.dev."}, + {"tag": "Attl", "path": "*rep.Answer.Hdr.Ttl", "type": "*group", "value": "300"}, + {"tag": "Aclass", "path": "*rep.Answer.Hdr.Class", "type": "*group", "value": "1"}, + {"tag": "Arrtype", "path": "*rep.Answer.Hdr.Rrtype", "type": "*group", "value": "1"}, + {"tag": "Aip", "path": "*rep.Answer.A", "type": "*group", "value": "~*cgrep.RouteProfiles[0].Routes[0].RouteParameters"} + ] + }, + { + "id": "ASuppliersTwoSuppliers", + "filters": ["*string:~*vars.QueryType:A", + "*string:~*vars.QueryName:go.dev.", + "*gte:~*cgrep.RouteProfiles.Length:1", + "*gte:~*cgrep.RouteProfiles[0].Routes.Length:2"], + "flags": ["*none","*continue"], + "reply_fields":[ + {"tag": "Aname", "path": "*rep.Answer[1].Hdr.Name", "type": "*group", "value": "go.dev."}, + {"tag": "Attl", "path": "*rep.Answer[1].Hdr.Ttl", "type": "*group", "value": "300"}, + {"tag": "Aclass", "path": "*rep.Answer[1].Hdr.Class", "type": "*group", "value": "1"}, + {"tag": "Arrtype", "path": "*rep.Answer[1].Hdr.Rrtype", "type": "*group", "value": "1"}, + {"tag": "Aip", "path": "*rep.Answer[1].A", "type": "*group", "value": "~*cgrep.RouteProfiles[0].Routes[1].RouteParameters"} + ] + }, + { + "id": "SRVRoutesQuery", + "filters": ["*string:~*vars.QueryType:SRV", + "*string:~*vars.QueryName:_xmpp-client._tcp.xmpp.org."], + "flags": ["*message", "*routes","*continue"], + "request_fields":[ + {"tag": "ToR", "path": "*cgreq.Account", "type": "*constant", "value": "1003"} + ], + "reply_fields":[ + {"tag": "DispatchReply", "type": "*none", + "blocker": true} + ] + }, + { + "id": "SRVSuppliersOneSupplier", + "filters": ["*string:~*vars.QueryType:SRV", + "*string:~*vars.QueryName:_xmpp-client._tcp.xmpp.org.", + "*gte:~*cgrep.RouteProfiles.Length:1", + "*gte:~*cgrep.RouteProfiles[0].Routes.Length:1"], + "flags": ["*none","*continue"], + "reply_fields":[ + {"tag": "SRVHdr", "path": "*rep.Answer.Hdr.Name", "type": "*group", "value": "_xmpp-client._tcp.xmpp.org."}, + {"tag": "SRVPriority", "path": "*rep.Answer.Priority", "type": "*group", "value": "1"}, + {"tag": "SRVWeight", "path": "*rep.Answer.Weight", "type": "*group", "value": "1"}, + {"tag": "SRVPort", "path": "*rep.Answer.Port", "type": "*group", "value": "9222"}, + {"tag": "SRVTarget", "path": "*rep.Answer.Target", "type": "*group", "value": "~*cgrep.RouteProfiles[0].Routes[0].RouteParameters"} + ] + }, + { + "id": "SRVSuppliersTwoSuppliers", + "filters": ["*string:~*vars.QueryType:SRV", + "*string:~*vars.QueryName:_xmpp-client._tcp.xmpp.org.", + "*gte:~*cgrep.RouteProfiles.Length:1", + "*gte:~*cgrep.RouteProfiles[0].Routes.Length:2"], + "flags": ["*none","*continue"], + "reply_fields":[ + {"tag": "SRVHdr", "path": "*rep.Answer[1].Hdr.Name", "type": "*group", "value": "_xmpp-client._tcp.xmpp.org."}, + {"tag": "SRVPriority", "path": "*rep.Answer[1].Priority", "type": "*group", "value": "1"}, + {"tag": "SRVWeight", "path": "*rep.Answer[1].Weight", "type": "*group", "value": "1"}, + {"tag": "SRVPort", "path": "*rep.Answer[1].Port", "type": "*group", "value": "9222"}, + {"tag": "SRVTarget", "path": "*rep.Answer[1].Target", "type": "*group", "value": "~*cgrep.RouteProfiles[0].Routes[1].RouteParameters"} + ] + } ], }, diff --git a/data/conf/samples/dnsagent_reload/cgrates.json b/data/conf/samples/dnsagent_reload/cgrates.json index 38152aedc..124477cd4 100644 --- a/data/conf/samples/dnsagent_reload/cgrates.json +++ b/data/conf/samples/dnsagent_reload/cgrates.json @@ -50,7 +50,16 @@ "dns_agent": { "enabled": true, - "listen": ":2053", + "listeners":[ + { + "address":":2053", + "network":"udp" + }, + { + "address":":2054", + "network":"tcp" + } + ], "sessions_conns": ["*internal"], }, diff --git a/data/conf/samples/export_it_test_mongo/cgrates.json b/data/conf/samples/export_it_test_mongo/cgrates.json index 836e2d0bb..25d0e8ee6 100644 --- a/data/conf/samples/export_it_test_mongo/cgrates.json +++ b/data/conf/samples/export_it_test_mongo/cgrates.json @@ -146,7 +146,7 @@ "field_separator": ",", // separator used in case of csv files "tp_in_dir": "/tmp/archivesTP", // absolute path towards the directory where the TPs are stored "tp_out_dir": "", // absolute path towards the directory where processed TPs will be moved - "action": "*store", // what should the loader do<*store|*parse|*remove|*dryrun> + "action": "*store", // what should the loader do<*store|*parse|*remove|*dryRun> "opts": { // "*cache": "*reload", "*withIndex": true, diff --git a/data/tariffplans/dnsagent/Attributes.csv b/data/tariffplans/dnsagent/Attributes.csv index 6d9c43db9..acd375992 100644 --- a/data/tariffplans/dnsagent/Attributes.csv +++ b/data/tariffplans/dnsagent/Attributes.csv @@ -1,4 +1,8 @@ #Tenant,ID,FilterIDs,Weights,Blockers,AttributeFilterIDs,AttributeBlockers,Path,Type,Value cgrates.org,ATTR_NAPTR_ADDR,*string:~*req.E164Address:4986517174964,;20,;false,,,*req.NAPTRAddress,*constant,sip:\1@172.16.1.1. cgrates.org,ATTR_NAPTR_SIP_URI,*string:~*req.Origin:cgrates,;20,;false,,,*req.SipURI,*variable,sip:cgrates@;~*req.Domanin - +cgrates.org,ATTR_A_DOM,*string:~*req.Domain:dns.google.,;20,;false,,,*req.Aip0,*constant,8.8.8.8 +cgrates.org,ATTR_A_DOM,*string:~*req.Domain:dns.google.,;20,;false,,,*req.Aip1,*constant,8.8.4.4 +cgrates.org,ATTR_A_SIP_URI,*string:~*req.AOrigin:cgrates,;20,;false,,,*req.SipURI,*variable,sip:cgrates@;~*req.ASIPDomain +cgrates.org,ATTR_SRV,*string:~*req.SRVAddress:_ldap._tcp.google.com.,;20,;false,,,*req.SRVName,*constant,ldap.google.com. +cgrates.org,ATTR_SRV_SIP_URI,*string:~*req.SRVOrigin:cgrates,;20,;false,,,*req.SipURI,*variable,sip:cgrates@;~*req.SRVDomain \ No newline at end of file diff --git a/data/tariffplans/dnsagent/Routes.csv b/data/tariffplans/dnsagent/Routes.csv index 7a867a021..b28af82b0 100644 --- a/data/tariffplans/dnsagent/Routes.csv +++ b/data/tariffplans/dnsagent/Routes.csv @@ -1,4 +1,7 @@ #Tenant,ID,FilterIDs,Weights,Blockers,Sorting,SortingParameters,RouteID,RouteFilterIDs,RouteAccountIDs,RouteRateProfileIDs,RouteResourceIDs,RouteStatIDs,RouteWeights,RouteBlockers,RouteParameters cgrates.org,ROUTE_ACNT_1001,*string:~*req.Account:1001,;10,,*weight,,route1,,,,,,;10,,!^(.*)$!sip:\1@172.16.1.11! cgrates.org,ROUTE_ACNT_1001,,;10,,,,route2,,,,,,;5,,!^(.*)$!sip:\1@172.16.1.12! - +cgrates.org,ROUTE_ACNT_1002,*string:~*req.Account:1002,;10,,*weight,,aroute1,,,,,,;10,,216.239.32.21 +cgrates.org,ROUTE_ACNT_1002,,;10,,,,aroute2,,,,,,;5,,216.239.34.21 +cgrates.org,ROUTE_ACNT_1003,*string:~*req.Account:1003,;10,,*weight,,srvroute1,,,,,,;10,,xmpp.xmpp.org. +cgrates.org,ROUTE_ACNT_1003,,;10,,,,srvroute2,,,,,,;5,,xmpp.xmpp.com. \ No newline at end of file diff --git a/data/tutorial_tests/kamevapi/kamailio/etc/kamailio/kamailio-cgrates.cfg b/data/tutorial_tests/kamevapi/kamailio/etc/kamailio/kamailio-cgrates.cfg index 8b5abf6bd..6c52cae7c 100644 --- a/data/tutorial_tests/kamevapi/kamailio/etc/kamailio/kamailio-cgrates.cfg +++ b/data/tutorial_tests/kamevapi/kamailio/etc/kamailio/kamailio-cgrates.cfg @@ -161,6 +161,7 @@ route[CGR_CALL_START] { \"h_id\":\"$dlg(h_id)\", \"cgr_flags\":\"*attributes;*accounts;*resources;*thresholds\", \"OriginID\":\"$dlg_var(cgrOriginID)\", + \"OriginHost\":\"$dlg_var(cgrOriginHost)\", \"RequestType\":\"$dlg_var(cgrReqType)\", \"Tenant\":\"$dlg_var(cgrTenant)\", \"Account\":\"$dlg_var(cgrAccount)\", @@ -180,6 +181,7 @@ route[CGR_CALL_END] { evapi_relay("{\"event\":\"CGR_CALL_END\", \"cgr_flags\":\"*accounts;*resources\", \"OriginID\":\"$dlg_var(cgrOriginID)\", + \"OriginHost\":\"$dlg_var(cgrOriginHost)\", \"RequestType\":\"$dlg_var(cgrReqType)\", \"Tenant\":\"$dlg_var(cgrTenant)\", \"Account\":\"$dlg_var(cgrAccount)\", diff --git a/data/tutorial_tests/kamevapi/kamailio/etc/kamailio/kamailio.cfg b/data/tutorial_tests/kamevapi/kamailio/etc/kamailio/kamailio.cfg index 40ca2bab4..8a9b3849d 100644 --- a/data/tutorial_tests/kamevapi/kamailio/etc/kamailio/kamailio.cfg +++ b/data/tutorial_tests/kamevapi/kamailio/etc/kamailio/kamailio.cfg @@ -210,7 +210,8 @@ route[CGRATES_SESSIONAUTH_REPLY] { # cannot initialize the dialog sooner due to AUTH dlg_manage(); $dlg_var(SetupTime) = $TS; - $dlg_var(cgrOriginID) = $dlg(callid) + ";" + $dlg(from_tag); + $dlg_var(cgrOriginID) = $dlg(callid) + $dlg_var(cgrOriginHost) = "127.0.0.1"; $dlg_var(cgrTenant) = "cgrates.org"; $dlg_var(cgrReqType) = $avp(RequestType); $dlg_var(cgrAccount) = $fU; diff --git a/data/tutorials/kamevapi/kamailio/etc/kamailio/kamailio.cfg b/data/tutorials/kamevapi/kamailio/etc/kamailio/kamailio.cfg index 40ca2bab4..7e167db80 100644 --- a/data/tutorials/kamevapi/kamailio/etc/kamailio/kamailio.cfg +++ b/data/tutorials/kamevapi/kamailio/etc/kamailio/kamailio.cfg @@ -210,7 +210,7 @@ route[CGRATES_SESSIONAUTH_REPLY] { # cannot initialize the dialog sooner due to AUTH dlg_manage(); $dlg_var(SetupTime) = $TS; - $dlg_var(cgrOriginID) = $dlg(callid) + ";" + $dlg(from_tag); + $dlg_var(cgrOriginID) = $dlg(callid); $dlg_var(cgrTenant) = "cgrates.org"; $dlg_var(cgrReqType) = $avp(RequestType); $dlg_var(cgrAccount) = $fU; diff --git a/engine/libstats_test.go b/engine/libstats_test.go index 6abce0b7b..9c272f7dd 100644 --- a/engine/libstats_test.go +++ b/engine/libstats_test.go @@ -1732,12 +1732,12 @@ func TestStatQueueProfile_Set(t *testing.T) { } func TestStatQueueGobEncode(t *testing.T) { - exp := []byte{68, 255, 129, 3, 1, 1, 8, 115, 113, 69, 110, 99, 111, 100, 101, 1, 255, 130, 0, 1, 4, 1, 6, 84, 101, 110, 97, 110, 116, 1, 12, 0, 1, 2, 73, 68, 1, 12, 0, 1, 7, 83, 81, 73, 116, 101, 109, 115, 1, 255, 136, 0, 1, 9, 83, 81, 77, 101, 116, 114, 105, 99, 115, 1, 255, 138, 0, 0, 0, 30, 255, 135, 2, 1, 1, 15, 91, 93, 101, 110, 103, 105, 110, 101, 46, 83, 81, 73, 116, 101, 109, 1, 255, 136, 0, 1, 255, 132, 0, 0, 48, 255, 131, 3, 1, 1, 6, 83, 81, 73, 116, 101, 109, 1, 255, 132, 0, 1, 2, 1, 7, 69, 118, 101, 110, 116, 73, 68, 1, 12, 0, 1, 10, 69, 120, 112, 105, 114, 121, 84, 105, 109, 101, 1, 255, 134, 0, 0, 0, 10, 255, 133, 5, 1, 2, 255, 140, 0, 0, 0, 44, 255, 137, 4, 1, 1, 28, 109, 97, 112, 91, 115, 116, 114, 105, 110, 103, 93, 101, 110, 103, 105, 110, 101, 46, 83, 116, 97, 116, 77, 101, 116, 114, 105, 99, 1, 255, 138, 0, 1, 12, 1, 16, 0, 0, 3, 255, 130, 0} + exp := []byte{67, 127, 3, 1, 1, 8, 115, 113, 69, 110, 99, 111, 100, 101, 1, 255, 128, 0, 1, 4, 1, 6, 84, 101, 110, 97, 110, 116, 1, 12, 0, 1, 2, 73, 68, 1, 12, 0, 1, 7, 83, 81, 73, 116, 101, 109, 115, 1, 255, 134, 0, 1, 9, 83, 81, 77, 101, 116, 114, 105, 99, 115, 1, 255, 136, 0, 0, 0, 30, 255, 133, 2, 1, 1, 15, 91, 93, 101, 110, 103, 105, 110, 101, 46, 83, 81, 73, 116, 101, 109, 1, 255, 134, 0, 1, 255, 130, 0, 0, 48, 255, 129, 3, 1, 1, 6, 83, 81, 73, 116, 101, 109, 1, 255, 130, 0, 1, 2, 1, 7, 69, 118, 101, 110, 116, 73, 68, 1, 12, 0, 1, 10, 69, 120, 112, 105, 114, 121, 84, 105, 109, 101, 1, 255, 132, 0, 0, 0, 10, 255, 131, 5, 1, 2, 255, 138, 0, 0, 0, 44, 255, 135, 4, 1, 1, 28, 109, 97, 112, 91, 115, 116, 114, 105, 110, 103, 93, 101, 110, 103, 105, 110, 101, 46, 83, 116, 97, 116, 77, 101, 116, 114, 105, 99, 1, 255, 136, 0, 1, 12, 1, 16, 0, 0, 3, 255, 128, 0} sq := &StatQueue{} if rcv, err := sq.GobEncode(); err != nil { t.Error(err) } else if string(rcv) != string(exp) { - t.Errorf("Expected <%v>, \nReceived <%v>", exp, rcv) + t.Errorf("Expected <%v>, \nReceived <%v>", string(exp), string(rcv)) } } func TestStatQueueGobDecode(t *testing.T) { @@ -2073,3 +2073,100 @@ func TestStatQAddStatEventBlockerFromDynamicsErr(t *testing.T) { } } + +func TestStatQAddStatEventBlockNotLast(t *testing.T) { + + cfg := config.NewDefaultCGRConfig() + data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + cM := NewConnManager(cfg) + dm := NewDataManager(data, cfg.CacheCfg(), cM) + + fltrS := NewFilterS(cfg, cM, dm) + + sq = &StatQueue{ + SQMetrics: map[string]StatMetric{ + utils.MetaASR: &StatASR{ + Metric: &Metric{ + Value: utils.NewDecimal(1, 0), + Count: 1, + Events: map[string]*DecimalWithCompress{ + "cgrates.org:TestStatRemExpired_1": {Stat: utils.NewDecimalFromFloat64(1), CompressFactor: 1}, + }, + }, + }, + }, + sqPrfl: &StatQueueProfile{ + Metrics: []*MetricWithFilters{ + { + MetricID: utils.MetaASR, + Blockers: utils.DynamicBlockers{ + { + Blocker: true, + }, + }, + }, + { + MetricID: utils.MetaTCD, + Blockers: utils.DynamicBlockers{ + { + Blocker: true, + }, + }, + }, + }, + }, + } + asrMetric := sq.SQMetrics[utils.MetaASR].(*StatASR) + if asr := asrMetric.GetValue(); asr.Compare(utils.NewDecimalFromFloat64(100)) != 0 { + t.Errorf("received ASR: %v", asr) + } + ev1 := &utils.CGREvent{Tenant: "cgrates.org", ID: "TestStatAddStatEvent_1"} + + exp := &StatQueue{ + SQMetrics: map[string]StatMetric{ + utils.MetaASR: &StatASR{ + Metric: &Metric{ + Value: utils.NewDecimal(1, 0), + Count: 1, + Events: map[string]*DecimalWithCompress{ + "cgrates.org:TestStatRemExpired_1": {Stat: utils.NewDecimalFromFloat64(1), CompressFactor: 1}, + }, + }, + }, + }, + SQItems: []SQItem{ + { + EventID: "eventID", + }, + }, + sqPrfl: &StatQueueProfile{ + Metrics: []*MetricWithFilters{ + { + MetricID: utils.MetaASR, + Blockers: utils.DynamicBlockers{ + { + Blocker: true, + }, + }, + }, + { + MetricID: utils.MetaTCD, + Blockers: utils.DynamicBlockers{ + { + Blocker: true, + }, + }, + }, + }, + }, + } + + if err := sq.addStatEvent(context.Background(), ev1.Tenant, ev1.ID, fltrS, utils.MapStorage{utils.MetaOpts: ev1.Event}); err != nil { + t.Error(err) + } + + if !reflect.DeepEqual(exp.sqPrfl, sq.sqPrfl) { + t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", exp.sqPrfl, sq.sqPrfl) + } + +} diff --git a/general_tests/all_cfg_rld_it_test.go b/general_tests/all_cfg_rld_it_test.go index 5d08c956d..d8d499fc5 100644 --- a/general_tests/all_cfg_rld_it_test.go +++ b/general_tests/all_cfg_rld_it_test.go @@ -292,7 +292,7 @@ func testConfigSReload(t *testing.T) { t.Errorf("\nExpected %+v ,\n received: %+v", utils.ToIJSON(cfgStr), utils.ToIJSON(rpl18)) } - cfgStr = "{\"dns_agent\":{\"enabled\":false,\"listen\":\"127.0.0.1:2053\",\"listen_net\":\"udp\",\"request_processors\":[],\"sessions_conns\":[\"*internal\"],\"timezone\":\"\"}}" + cfgStr = "{\"dns_agent\":{\"enabled\":false,\"listeners\":[{\"address\":\"127.0.0.1:53\",\"network\":\"udp\"}],\"request_processors\":[],\"sessions_conns\":[\"*internal\"],\"timezone\":\"\"}}" var rpl19 string if err := testRPC.Call(context.Background(), utils.ConfigSv1GetConfigAsJSON, &config.SectionWithAPIOpts{ Tenant: "cgrates.org", diff --git a/general_tests/all_sections_cfg_rld_it_test.go b/general_tests/all_sections_cfg_rld_it_test.go index 0cd8431a5..5e70242a5 100644 --- a/general_tests/all_sections_cfg_rld_it_test.go +++ b/general_tests/all_sections_cfg_rld_it_test.go @@ -574,13 +574,13 @@ func testSectConfigSReloadDNSAgent(t *testing.T) { var reply string if err := testSectRPC.Call(context.Background(), utils.ConfigSv1SetConfigFromJSON, &config.SetConfigFromJSONArgs{ Tenant: "cgrates.org", - Config: "{\"dns_agent\":{\"enabled\":true,\"listen\":\"127.0.0.1:2053\",\"listen_net\":\"udp\",\"request_processors\":[],\"sessions_conns\":[\"*internal\"],\"timezone\":\"\"}}", + Config: "{\"dns_agent\":{\"enabled\":true,\"listeners\":[{\"address\":\"127.0.0.1:2053\",\"network\":\"udp\"}],\"request_processors\":[],\"sessions_conns\":[\"*internal\"],\"timezone\":\"\"}}", }, &reply); err != nil { t.Error(err) } else if reply != utils.OK { t.Errorf("Expected OK received: %+v", reply) } - cfgStr := "{\"dns_agent\":{\"enabled\":true,\"listen\":\"127.0.0.1:2053\",\"listen_net\":\"udp\",\"request_processors\":[],\"sessions_conns\":[\"*internal\"],\"timezone\":\"\"}}" + cfgStr := "{\"dns_agent\":{\"enabled\":true,\"listeners\":[{\"address\":\"127.0.0.1:2053\",\"network\":\"udp\"}],\"request_processors\":[],\"sessions_conns\":[\"*internal\"],\"timezone\":\"\"}}" var rpl string if err := testSectRPC.Call(context.Background(), utils.ConfigSv1GetConfigAsJSON, &config.SectionWithAPIOpts{ Tenant: "cgrates.org", diff --git a/services/dnsagent.go b/services/dnsagent.go index 26ecab778..2a0401989 100644 --- a/services/dnsagent.go +++ b/services/dnsagent.go @@ -86,7 +86,9 @@ func (dns *DNSAgent) Reload(ctx *context.Context, shtDwn context.CancelFunc) (er dns.Lock() defer dns.Unlock() - dns.Shutdown() + if dns.dns != nil { + close(dns.stopChan) + } dns.dns, err = agents.NewDNSAgent(dns.cfg, filterS, dns.connMgr) if err != nil { @@ -114,11 +116,12 @@ func (dns *DNSAgent) listenAndServe(stopChan chan struct{}, shtDwn context.Cance // Shutdown stops the service func (dns *DNSAgent) Shutdown() (err error) { - dns.Lock() - defer dns.Unlock() - if err = dns.dns.Shutdown(); err != nil { + if dns.dns == nil { return } + close(dns.stopChan) + dns.Lock() + defer dns.Unlock() dns.dns = nil return } @@ -127,7 +130,7 @@ func (dns *DNSAgent) Shutdown() (err error) { func (dns *DNSAgent) IsRunning() bool { dns.RLock() defer dns.RUnlock() - return dns != nil && dns.dns != nil + return dns.dns != nil } // ServiceName returns the service name diff --git a/services/dnsagent_it_test.go b/services/dnsagent_it_test.go index 06a7a4378..31549bf53 100644 --- a/services/dnsagent_it_test.go +++ b/services/dnsagent_it_test.go @@ -37,10 +37,69 @@ import ( "github.com/cgrates/cgrates/utils" ) -func TestDNSAgentReload(t *testing.T) { +func TestDNSAgentStartReloadShut(t *testing.T) { cfg := config.NewDefaultCGRConfig() cfg.SessionSCfg().Enabled = true cfg.SessionSCfg().ListenBijson = "" + cfg.DNSAgentCfg().Enabled = true + cfg.DNSAgentCfg().Listeners = []config.Listener{ + { + Network: "udp", + Address: ":2055", + }, + { + Network: "tcp", + Address: ":2056", + }, + } + utils.Logger, _ = utils.NewSysLogger(cfg.GeneralCfg().NodeID, 7) + filterSChan := make(chan *engine.FilterS, 1) + filterSChan <- nil + ctx, cancel := context.WithCancel(context.TODO()) + defer func() { + cancel() + time.Sleep(10 * time.Millisecond) + }() + srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} + srv := NewDNSAgent(cfg, filterSChan, nil, srvDep) + shdWg := new(sync.WaitGroup) + srvMngr := servmanager.NewServiceManager(shdWg, nil, cfg) + engine.NewConnManager(cfg) + db := NewDataDBService(cfg, nil, srvDep) + server := cores.NewServer(nil) + anz := NewAnalyzerService(cfg, server, filterSChan, make(chan birpc.ClientConnector, 1), srvDep) + sS := NewSessionService(cfg, db, filterSChan, server, make(chan birpc.ClientConnector, 1), + nil, anz, srvDep) + srvMngr.AddServices(srv, sS, + NewLoaderService(cfg, db, filterSChan, server, make(chan birpc.ClientConnector, 1), nil, anz, srvDep), db) + runtime.Gosched() + time.Sleep(10 * time.Millisecond) //need to switch to gorutine + if err := srv.Shutdown(); err != nil { + t.Error(err) + } + time.Sleep(10 * time.Millisecond) + if err := srv.Start(ctx, cancel); err != nil { + t.Error(err) + } + time.Sleep(10 * time.Millisecond) + if err := srv.Reload(ctx, cancel); err != nil { + t.Error(err) + } + time.Sleep(10 * time.Millisecond) + if err := srv.Shutdown(); err != nil { + t.Error(err) + } + time.Sleep(10 * time.Millisecond) + if srv.IsRunning() { + t.Errorf("service is still running") + } +} + +func TestDNSAgentReloadFirst(t *testing.T) { + cfg := config.NewDefaultCGRConfig() + cfg.SessionSCfg().Enabled = true + cfg.SessionSCfg().ListenBijson = "" + utils.Logger, _ = utils.NewLogger(utils.MetaSysLog, cfg.GeneralCfg().NodeID, 7) filterSChan := make(chan *engine.FilterS, 1) filterSChan <- nil ctx, cancel := context.WithCancel(context.TODO()) @@ -62,6 +121,7 @@ func TestDNSAgentReload(t *testing.T) { srvMngr.AddServices(srv, sS, NewLoaderService(cfg, db, filterSChan, server, make(chan birpc.ClientConnector, 1), nil, anz, srvDep), db) srvMngr.StartServices(ctx, cancel) + time.Sleep(100 * time.Millisecond) if srv.IsRunning() { t.Fatalf("Expected service to be down") } @@ -92,10 +152,11 @@ func TestDNSAgentReload(t *testing.T) { if err != nil { t.Fatalf("\nExpecting ,\n Received <%+v>", err) } - - cfg.DNSAgentCfg().Enabled = false - cfg.GetReloadChan() <- config.SectionToService[config.DNSAgentJSON] time.Sleep(10 * time.Millisecond) + cfg.DNSAgentCfg().Enabled = false + time.Sleep(10 * time.Millisecond) + cfg.GetReloadChan() <- config.SectionToService[config.DNSAgentJSON] + time.Sleep(100 * time.Millisecond) if srv.IsRunning() { t.Fatalf("Expected service to be down") } @@ -107,8 +168,8 @@ func TestDNSAgentReload2(t *testing.T) { cfg.SessionSCfg().Enabled = true cfg.SessionSCfg().ListenBijson = "" cfg.DNSAgentCfg().Enabled = true - cfg.DNSAgentCfg().ListenNet = "test" - cfg.DNSAgentCfg().Listen = "test" + cfg.DNSAgentCfg().Listeners[0].Network = "test" + cfg.DNSAgentCfg().Listeners[0].Address = "test" filterSChan := make(chan *engine.FilterS, 1) filterSChan <- nil srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} @@ -120,41 +181,17 @@ func TestDNSAgentReload2(t *testing.T) { runtime.Gosched() dnsSrv := srv.(*DNSAgent) dnsSrv.dns = agentSrv - err = dnsSrv.listenAndServe(func() {}) + err = dnsSrv.listenAndServe(make(chan struct{}), func() {}) if err == nil || err.Error() != "dns: bad network" { t.Fatalf("\nExpected <%+v>, \nReceived <%+v>", "dns: bad network", err) } } -func TestDNSAgentReload3(t *testing.T) { - cfg := config.NewDefaultCGRConfig() - cfg.SessionSCfg().Enabled = true - cfg.DNSAgentCfg().Enabled = true - cfg.DNSAgentCfg().ListenNet = "test" - cfg.DNSAgentCfg().Listen = "test" - filterSChan := make(chan *engine.FilterS, 1) - filterSChan <- nil - srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} - srv := NewDNSAgent(cfg, filterSChan, nil, srvDep) - agentSrv, err := agents.NewDNSAgent(cfg, nil, nil) - if err != nil { - t.Fatal(err) - } - runtime.Gosched() - dnsSrv := srv.(*DNSAgent) - dnsSrv.dns = agentSrv - ctx, cancel := context.WithCancel(context.TODO()) - err = dnsSrv.Reload(ctx, cancel) - if err == nil || err.Error() != "dns: server not started" { - t.Fatalf("\nExpected <%+v>, \nReceived <%+v>", "dns: server not started", err) - } -} - func TestDNSAgentReload4(t *testing.T) { cfg := config.NewDefaultCGRConfig() cfg.SessionSCfg().Enabled = true cfg.DNSAgentCfg().Enabled = true - cfg.DNSAgentCfg().ListenNet = "tls" + cfg.DNSAgentCfg().Listeners[0].Network = "tls" cfg.TLSCfg().ServerCerificate = "bad_certificate" cfg.TLSCfg().ServerKey = "bad_key" filterSChan := make(chan *engine.FilterS, 1) @@ -187,7 +224,6 @@ func TestDNSAgentReload5(t *testing.T) { if err != nil { t.Fatalf("\nExpected <%+v>, \nReceived <%+v>", nil, err) } - srv.(*DNSAgent).oldListen = "127.0.0.1:2093" time.Sleep(10 * time.Millisecond) runtime.Gosched() runtime.Gosched() @@ -206,14 +242,13 @@ func TestDNSAgentReload6(t *testing.T) { filterSChan <- nil srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} srv := NewDNSAgent(cfg, filterSChan, nil, srvDep) - cfg.DNSAgentCfg().Listen = "127.0.0.1:0" + cfg.DNSAgentCfg().Listeners[0].Address = "127.0.0.1:0" ctx, cancel := context.WithCancel(context.TODO()) err := srv.Start(ctx, cancel) if err != nil { t.Fatalf("\nExpected <%+v>, \nReceived <%+v>", nil, err) } - srv.(*DNSAgent).oldListen = "127.0.0.1:2093" - cfg.DNSAgentCfg().ListenNet = "tls" + cfg.DNSAgentCfg().Listeners[0].Network = "tls" cfg.TLSCfg().ServerCerificate = "bad_certificate" cfg.TLSCfg().ServerKey = "bad_key" time.Sleep(10 * time.Millisecond) diff --git a/services/dnsagent_test.go b/services/dnsagent_test.go index f07eefcc6..683057120 100644 --- a/services/dnsagent_test.go +++ b/services/dnsagent_test.go @@ -43,6 +43,7 @@ func TestDNSAgentCoverage(t *testing.T) { srv2 := DNSAgent{ cfg: cfg, filterSChan: filterSChan, + stopChan: make(chan struct{}), connMgr: nil, srvDep: srvDep, dns: dns, diff --git a/utils/consts.go b/utils/consts.go index 5b4bdcef0..e9a4acdd7 100644 --- a/utils/consts.go +++ b/utils/consts.go @@ -855,6 +855,9 @@ const ( DNSUri = "Uri" DNSHdr = "Hdr" DNSA = "A" + DNSTarget = "Target" + DNSPriority = "Priority" + DNSPort = "Port" DNSRrtype = "Rrtype" DNSClass = "Class" DNSTtl = "Ttl"