Exemple #1
0
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
}
Exemple #2
0
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
}
Exemple #3
0
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)
	}
}
Exemple #4
0
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
}