func GetIpinfoStartEnd(i Ipinfo) (uint32, string, uint32, string) { // defer DeleteIpinfo(i) // Must delete ipinfo ! m := NewIpitem() defer DeleteIpitem(m) x := Il_bin2human(i, m, Id_code) if x != nil { x1, x2 := x.GetStart(), x.GetEnd() return utils.Ip4ToInt32(utils.StrToIP(x1)), x1, utils.Ip4ToInt32(utils.StrToIP(x2)), x2 } else { return uint32(0), "", uint32(0), "" } }
func TestIlSearch(t *testing.T) { ipinfo := NewIpinfo() defer DeleteIpinfo(ipinfo) for _, ip := range IPS { if ok := Il_open(DBPATH); ok > 0 { defer Il_close(ok) nip := NewIp(ip) defer DeleteIp(nip) t.Log(nip.GetIn()) n := Il_search(nip, ipinfo, ok) if n > 0 { t.Log(n) // t.Log(ipinfo.GetStart(), ipinfo.GetEnd()) // t.Log(ipinfo.GetStart().GetIn(), ipinfo.GetEnd().GetIn()) // t.Log(reflect.ValueOf(ipinfo.GetStart().GetIn()), reflect.ValueOf(ipinfo.GetEnd().GetIn())) // GetIpValid(ipinfo.GetStart()) n1, n2, n3, n4 := GetIpinfoStartEnd(ipinfo) t.Log(n1, n2, n3, n4) m := NewIpitem() x := Il_bin2human(ipinfo, m, Text) t.Log(m, x, x.GetStart(), x.GetEnd()) t.Log(utils.Ip4ToInt32(utils.StrToIP(x.GetStart())), utils.Ip4ToInt32(utils.StrToIP(x.GetEnd()))) } else { t.Log(n) t.Log(ipinfo.GetStart(), ipinfo.GetEnd()) if ip != "192.168.1.1" { t.Fail() } } } } }
func GetAFromMySQLBackend(dst, srcIP string, regionTree *RegionTree) (bool, []dns.RR, uint16, *MyError.MyError) { domainId, e := RRMySQL.GetDomainIDFromMySQL(dst) if e != nil { //todo: //fmt.Println(utils.GetDebugLine(), "Error, GetDomainIDFromMySQL:", e) return false, nil, uint16(0), e } region, ee := RRMySQL.GetRegionWithIPFromMySQL(utils.Ip4ToInt32(utils.StrToIP(srcIP))) if ee != nil { //fmt.Println(utils.GetDebugLine(), "Error GetRegionWithIPFromMySQL:", ee) return false, nil, uint16(0), MyError.NewError(ee.ErrorNo, "GetRegionWithIPFromMySQL return "+ee.Error()) } RR, eee := RRMySQL.GetRRFromMySQL(uint32(domainId), region.IdRegion) if eee != nil && eee.ErrorNo == MyError.ERROR_NORESULT { //fmt.Println(utils.GetDebugLine(), "Error GetRRFromMySQL with DomainID:", domainId, // "RegionID:", region.IdRegion, eee) //fmt.Println(utils.GetDebugLine(), "Try to GetRRFromMySQL with Default Region") utils.ServerLogger.Debug("Try to GetRRFromMySQL with Default Region") RR, eee = RRMySQL.GetRRFromMySQL(uint32(domainId), uint32(0)) if eee != nil { //fmt.Println(utils.GetDebugLine(), "Error GetRRFromMySQL with DomainID:", domainId, // "RegionID:", 0, eee) return false, nil, uint16(0), MyError.NewError(eee.ErrorNo, "Error GetRRFromMySQL with DomainID:"+strconv.Itoa(domainId)+eee.Error()) } } else if eee != nil { utils.ServerLogger.Error(eee.Error()) return false, nil, uint16(0), eee } //fmt.Println(utils.GetDebugLine(), "GetRRFromMySQL Succ!:", RR) utils.ServerLogger.Debug("GetRRFromMySQL Succ!: ", RR) var R []dns.RR var rtype uint16 var reE *MyError.MyError hdr := dns.RR_Header{ Name: dst, Class: RR.RR.Class, Rrtype: RR.RR.RrType, Ttl: RR.RR.Ttl, } //fmt.Println(utils.GetDebugLine(), mr.RR) if RR.RR.RrType == dns.TypeA { for _, mr := range RR.RR.Target { rh := &dns.A{ Hdr: hdr, A: utils.StrToIP(mr), } R = append(R, dns.RR(rh)) } rtype = dns.TypeA // fmt.Println(utils.GetDebugLine(), "Get A RR from MySQL, requery dst:", dst) } else if RR.RR.RrType == dns.TypeCNAME { for _, mr := range RR.RR.Target { rh := &dns.CNAME{ Hdr: hdr, Target: mr, } R = append(R, dns.RR(rh)) } rtype = dns.TypeCNAME //fmt.Println(utils.GetDebugLine(), "Get CNAME RR from MySQL, requery dst:", dst) reE = MyError.NewError(MyError.ERROR_NOTVALID, "Got CNAME result for dst : "+dst+" with srcIP : "+srcIP) } if len(R) > 0 { //Add timer for auto refrech the RegionCache go func(dst, srcIP string, r dns.RR, regionTree *RegionTree) { //fmt.Println(utils.GetDebugLine(), " Refresh record after ", r.Header().Ttl-5, // " Second, dst: ", dst, " srcIP: ", srcIP, "add timer ") time.AfterFunc(time.Duration(r.Header().Ttl-5)*time.Second, func() { GetAFromMySQLBackend(dst, srcIP, regionTree) }) }(dst, srcIP, R[0], regionTree) go func(regionTree *RegionTree, R []dns.RR, srcIP string) { //fmt.Println(utils.GetDebugLine(), "GetAFromMySQLBackend: ", e) startIP, endIP := region.Region.StarIP, region.Region.EndIP cidrmask := utils.GetCIDRMaskWithUint32Range(startIP, endIP) //fmt.Println(utils.GetDebugLine(), " GetRegionWithIPFromMySQL with srcIP: ", // srcIP, " StartIP : ", startIP, "==", utils.Int32ToIP4(startIP).String(), // " EndIP: ", endIP, "==", utils.Int32ToIP4(endIP).String(), " cidrmask : ", cidrmask) // netaddr, mask := DefaultNetaddr, DefaultMask r, _ := NewRegion(R, startIP, cidrmask) regionTree.AddRegionToCache(r) //fmt.Println(utils.GetDebugLine(), "GetAFromMySQLBackend: ", r) // fmt.Println(regionTree.GetRegionFromCacheWithAddr(startIP, cidrmask)) }(regionTree, R, srcIP) return true, R, rtype, reE } return false, nil, uint16(0), MyError.NewError(MyError.ERROR_UNKNOWN, utils.GetDebugLine()+"Unknown Error ") }
func TestMubitRadix(t *testing.T) { cidrNet := []string{ "10.0.0.2/8", "10.20.0.0/14", "10.21.0.0/16", "192.168.0.0/16", "192.168.2.0/24", "8.0.0.0/9", "8.8.8.0/24", "0.0.0.0/0", // "128.0.0.0/1", } ip2Find := []string{ "10.20.1.2", "10.22.1.2", "10.19.0.1", "10.21.0.1", "192.168.2.3", "10.22.0.5", "202.106.0.20", "172.16.3.133", "8.8.8.8", "8.8.7.1", } RadixTree := NewDomainRegionTree() for _, x := range cidrNet { i, n, e := net.ParseCIDR(x) if e != nil { t.Log(e.Error()) t.Fail() continue } a, m := utils.IpNetToInt32(n) RadixTree.AddRegionToCache(&Region{ NetworkAddr: a, NetworkMask: m, RR: []dns.RR{ dns.RR(&dns.A{ A: i, Hdr: dns.RR_Header{ Rrtype: 1, Class: 1, Ttl: 60, }, }), }, }) } // For default route RadixTree.AddRegionToCache(&Region{ NetworkAddr: DefaultRadixNetaddr, NetworkMask: DefaultRadixNetMask, RR: []dns.RR{ dns.RR(&dns.A{ A: utils.Int32ToIP4(DefaultRadixNetaddr), Hdr: dns.RR_Header{ Rrtype: 1, Class: 1, Ttl: 60, }, }), }, }) for _, i := range ip2Find { ii := utils.Ip4ToInt32(utils.StrToIP(i)) r, e := RadixTree.GetRegionFromCacheWithAddr(ii, DefaultRadixSearchMask) if e != nil { t.Log(e) t.Log(i) t.Fail() } else { t.Log(r) } } RadixTree.Radix32.Do(func(r1 *bitradix.Radix32, i int) { t.Log(r1.Key(), r1.Value, r1.Bits()) }) }