mirror of
https://github.com/ZeroTier/ZeroTierOne
synced 2025-08-20 13:24:09 -07:00
.
This commit is contained in:
parent
af471af8ef
commit
02c3727ccd
7 changed files with 211 additions and 322 deletions
|
@ -21,37 +21,61 @@
|
|||
|
||||
#ifdef ZT_ENABLE_CLUSTER
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
#include "../node/Constants.hpp"
|
||||
#include "../node/InetAddress.hpp"
|
||||
#include "../node/Mutex.hpp"
|
||||
#include "../osdep/Thread.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
/**
|
||||
* Runs the Cluster GeoIP service in the background and resolves geoIP queries
|
||||
* Loads a DBIP CSV into memory for fast lookup, reloading as needed
|
||||
*
|
||||
* This was designed around the CSV from https://db-ip.com but can be used
|
||||
* with any similar GeoIP CSV database that is presented in the form of an
|
||||
* IP range and lat/long coordinates.
|
||||
*
|
||||
* It loads the whole database into memory, which can be kind of large. If
|
||||
* the CSV file changes, the changes are loaded automatically.
|
||||
*/
|
||||
class ClusterGeoIpService
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @param pathToExe Path to cluster geo-resolution service executable
|
||||
*/
|
||||
ClusterGeoIpService(const char *pathToExe);
|
||||
|
||||
ClusterGeoIpService();
|
||||
~ClusterGeoIpService();
|
||||
|
||||
/**
|
||||
* Load or reload CSV file
|
||||
*
|
||||
* CSV column indexes start at zero. CSVs can be quoted with single or
|
||||
* double quotes. Whitespace before or after commas is ignored. Backslash
|
||||
* may be used for escaping whitespace as well.
|
||||
*
|
||||
* @param pathToCsv Path to (uncompressed) CSV file
|
||||
* @param ipStartColumn Column with IP range start
|
||||
* @param ipEndColumn Column with IP range end (inclusive)
|
||||
* @param latitudeColumn Column with latitude
|
||||
* @param longitudeColumn Column with longitude
|
||||
* @return Number of valid records loaded or -1 on error (invalid file, not found, etc.)
|
||||
*/
|
||||
inline long load(const char *pathToCsv,int ipStartColumn,int ipEndColumn,int latitudeColumn,int longitudeColumn)
|
||||
{
|
||||
Mutex::Lock _l(_lock);
|
||||
return _load(pathToCsv,ipStartColumn,ipEndColumn,latitudeColumn,longitudeColumn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to locate an IP
|
||||
*
|
||||
* This returns true if x, y, and z are set. Otherwise it returns false
|
||||
* and a geo-locate job is ordered in the background. This usually takes
|
||||
* 500-1500ms to complete, after which time results will be available.
|
||||
* If false is returned the supplied coordinate variables are unchanged.
|
||||
* This returns true if x, y, and z are set. If the return value is false
|
||||
* the values of x, y, and z are undefined.
|
||||
*
|
||||
* @param ip IPv4 or IPv6 address
|
||||
* @param x Reference to variable to receive X
|
||||
|
@ -61,21 +85,41 @@ public:
|
|||
*/
|
||||
bool locate(const InetAddress &ip,int &x,int &y,int &z);
|
||||
|
||||
void threadMain()
|
||||
throw();
|
||||
|
||||
private:
|
||||
const std::string _pathToExe;
|
||||
int _sOutputFd;
|
||||
int _sInputFd;
|
||||
volatile long _sPid;
|
||||
volatile bool _run;
|
||||
Thread _thread;
|
||||
Mutex _sOutputLock;
|
||||
long _load(const char *pathToCsv,int ipStartColumn,int ipEndColumn,int latitudeColumn,int longitudeColumn);
|
||||
|
||||
struct _CE { uint64_t ts; int x,y,z; };
|
||||
std::map< InetAddress,_CE > _cache;
|
||||
Mutex _cache_m;
|
||||
std::string _pathToCsv;
|
||||
int _ipStartColumn;
|
||||
int _ipEndColumn;
|
||||
int _latitudeColumn;
|
||||
int _longitudeColumn;
|
||||
|
||||
uint64_t _lastFileCheckTime;
|
||||
uint64_t _csvModificationTime;
|
||||
int64_t _csvFileSize;
|
||||
|
||||
struct _V4E
|
||||
{
|
||||
uint32_t start;
|
||||
uint32_t end;
|
||||
int x,y,z;
|
||||
|
||||
inline bool operator<(const _V4E &e) const { return (start < e.start); }
|
||||
};
|
||||
|
||||
struct _V6E
|
||||
{
|
||||
uint8_t start[16];
|
||||
uint8_t end[16];
|
||||
int x,y,z;
|
||||
|
||||
inline bool operator<(const _V6E &e) const { return (memcmp(start,e.start,16) < 0); }
|
||||
};
|
||||
|
||||
std::vector<_V4E> _v4db;
|
||||
std::vector<_V6E> _v6db;
|
||||
|
||||
Mutex _lock;
|
||||
};
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue