func (h *IPRangeHolder) FindCountry(ip string) (string, error) { v, err := helper.IPv42Int(ip) if nil != err { log.Printf("Failed to convert ip to int for reason:%v", err) return "z2", err } compare := func(i int) bool { return h.ranges[i].Start >= uint64(v) } index := sort.Search(len(h.ranges), compare) if index == len(h.ranges) { //log.Printf("####%d\n", len(h.ranges)) return "zz", errIPRangeNotMatch } if index > 0 { if h.ranges[index].Start == uint64(v) && h.ranges[index].End >= uint64(v) { log.Printf("%s match ip range %s-%s", ip, helper.Long2IPv4(h.ranges[index].Start), helper.Long2IPv4(h.ranges[index].End)) return h.ranges[index].Country, nil } if index > 0 { if h.ranges[index-1].Start <= uint64(v) && h.ranges[index-1].End >= uint64(v) { log.Printf("%s match ip range %s-%s", ip, helper.Long2IPv4(h.ranges[index-1].Start), helper.Long2IPv4(h.ranges[index-1].End)) return h.ranges[index-1].Country, nil } } // if h.ranges[index].Start > uint64(v) || h.ranges[index].End < uint64(v) { // log.Printf("Got start:%d - %d for %d", h.ranges[index].Start, h.ranges[index].End, v) // return "z1", errIPRangeNotMatch // } // return h.ranges[index].Country, nil } return "", errIPRangeNotMatch }
func parseApnicIPReader(rc io.ReadCloser, persist bool) (*IPRangeHolder, error) { var err error reader := bufio.NewReader(rc) var buffer bytes.Buffer var ( part []byte prefix bool ) defer rc.Close() holder := new(IPRangeHolder) var perststFile *os.File if persist { var err error perststFile, err = os.Create(proxyHome + "/" + cnIPFile) if nil == err { defer perststFile.Close() } else { log.Printf("[ERROR]Failed to open CN IP file:%v", err) } } for { if part, prefix, err = reader.ReadLine(); err != nil { if err != io.EOF { return nil, err } break } buffer.Write(part) if !prefix { line := buffer.String() buffer.Reset() if strings.HasPrefix(line, "#") { continue } sp := strings.Split(line, "|") if len(sp) >= 6 { if sp[1] == "CN" && sp[2] == "ipv4" { startip, _ := helper.IPv42Int(sp[3]) ipcount, _ := strconv.ParseUint(sp[4], 10, 32) tmp := &IPRange{uint64(startip), uint64(startip) + uint64(ipcount-1), sp[1]} holder.ranges = append(holder.ranges, tmp) if nil != perststFile { perststFile.Write([]byte(line)) perststFile.Write([]byte("\r\n")) } } } } } holder.sort() return holder, nil }