func (server *Server) lookupCountry(req *http.Request) (string, error) { // Use the country CloudFlare gives us if it's available. cf := req.Header.Get("Cf-Ipcountry") if cf != "" { return cf, nil } clientIp := getClientIp(req) if clientIp == "" { log.Debug("Unable to determine client ip for geolookup") return "", nil } country := "" cachedCountry, found := server.geoCache.Get(clientIp) if found { log.Tracef("Country for %v found in cache", clientIp) country = cachedCountry.(string) } else { log.Tracef("Country for %v not cached, perform geolookup", clientIp) city, _, err := geolookup.LookupIPWithClient(clientIp, nil) if err != nil { log.Debugf("Unable to perform geolookup for ip %v: %v", clientIp, err) return country, err } country = strings.ToUpper(city.Country.IsoCode) server.geoCache.Add(clientIp, country) } return country, nil }
func (peer *Peer) doGeolocate() error { geodata, _, err := geolookup.LookupIPWithClient(peer.IP, geoClient.Load().(*http.Client)) if err != nil { return err } peer.Country = geodata.Country.IsoCode peer.Latitude = geodata.Location.Latitude peer.Longitude = geodata.Location.Longitude return nil }
func write() { consecutiveFailures := 0 for { // Wait a random amount of time (to avoid looking too suspicious) // Note - rand was seeded with the startup time in flashlight.go n := rand.Intn(publishSecondsVariance) wait := time.Duration(basePublishSeconds-publishSecondsVariance/2+n) * time.Second oldLocation := GetLocation() newLocation, err := geolookup.LookupIPWithClient("", client.Load().(*http.Client)) if err == nil { consecutiveFailures = 0 if !reflect.DeepEqual(newLocation, oldLocation) { log.Debugf("Location changed") location.Store(newLocation) pubsub.Pub(pubsub.Location, newLocation) } // Always publish location, even if unchanged service.Out <- newLocation } else { msg := fmt.Sprintf("Unable to get current location: %s", err) // When retrying after a failure, wait a different amount of time retryWait := time.Duration(math.Pow(2, float64(consecutiveFailures))*float64(retryWaitMillis)) * time.Millisecond if retryWait < wait { log.Debug(msg) wait = retryWait } else { log.Error(msg) } log.Debugf("Waiting %v before retrying", wait) consecutiveFailures += 1 // If available, publish last known location if oldLocation != nil { service.Out <- oldLocation } } time.Sleep(wait) } }
func (server *Server) checkForDisallowedCountry(req *http.Request) error { clientIp := getClientIp(req) if clientIp == "" { log.Debug("Unable to determine client ip for geolookup") return nil } country := "" cachedCountry, found := server.geoCache.Get(clientIp) if found { log.Tracef("Country for %v found in cache", clientIp) country = cachedCountry.(string) } else { log.Tracef("Country for %v not cached, perform geolookup", clientIp) city, err := geolookup.LookupIPWithClient(clientIp, nil) if err != nil { log.Debugf("Unable to perform geolookup for ip %v: %v", clientIp, err) return nil } country = strings.ToUpper(city.Country.IsoCode) server.geoCache.Add(clientIp, country) } countryAllowed := false for _, allowed := range server.AllowedCountries { if country == strings.ToUpper(allowed) { countryAllowed = true break } } if !countryAllowed { return fmt.Errorf("Not accepting connections from country %v", country) } return nil }