pub struct MaxMindIntel { /* private fields */ }maxmind only.Expand description
Country, city, ASN, network name and anonymizer lookups from MaxMind databases
(GeoLite2-City / GeoLite2-Country / GeoIP2-* for the country, and the city with a City
edition; GeoLite2-ASN for the autonomous system number and organization name; and
optionally GeoIP2-Anonymous-IP, GeoIP-Anonymous-Plus or GeoIP2-IP-Risk for VPNs,
proxies and Tor, added with with_anonymizer).
Databases are read into memory once, so lookups on the request path never touch the disk and are lock-free. Unknown addresses and lookup errors yield empty fields.
§Anonymizers
The anonymizer databases are paid GeoIP2 products; there is no GeoLite2 edition. With
one loaded, every lookup sets IpInfo::anonymity, which feeds the
TorOrProxyEntered and
AnonymizerEntered checks. The database’s flags map to
the most severe Anonymity that applies:
| Flag | Anonymity |
|---|---|
is_tor_exit_node | TorExitNode |
is_public_proxy | PublicProxy |
is_residential_proxy | ResidentialProxy |
is_anonymous_vpn, unless anonymizer_confidence is below 50 | Vpn |
is_hosting_provider | HostingProvider |
| none of these, or an address the database does not list | Direct |
A failed lookup (e.g. an IPv6 address in an IPv4-only database) leaves the anonymity
unknown, so it never fires a check. The IP Risk database’s ip_risk score is not used: the
guard scores what changed during a session rather than how risky an address is on its own.
use session_guard::MaxMindIntel;
let intel = MaxMindIntel::open("/var/lib/GeoIP/GeoLite2-Country.mmdb", None::<&str>)?
.with_anonymizer("/var/lib/GeoIP/GeoIP2-Anonymous-IP.mmdb")?;use session_guard::{Guard, GuardConfig, MaxMindIntel, MemoryStore};
let intel = MaxMindIntel::open(
"/var/lib/GeoIP/GeoLite2-Country.mmdb",
Some("/var/lib/GeoIP/GeoLite2-ASN.mmdb"),
)?;
let guard = Guard::builder(MemoryStore::new(), GuardConfig::default()).ip_intel(intel).build();§Keeping the databases up to date
MaxMind publishes new databases weekly or twice a week, and geoipupdate (as a cron job,
a sidecar or a shared volume) replaces the files on disk. Those new files are only used once
they are reloaded:
spawn_reload(featuretokio) checks the files on an interval and reloads them when they change. This is the usual choice.reload_if_changeddoes a single check, to drive from your own scheduler or runtime.reloadandreload_from_bytesswap the databases unconditionally.
A change is detected from each file’s modification time and size, so it works on every kind
of mount, including network file systems and Kubernetes volumes that deliver no file system
events. A reload swaps the country and ASN databases at once; in-flight lookups finish on the
old ones. The anonymizer database is checked and reloaded on its own, so a failed update of
one never holds back the other. reload and
reload_from_bytes leave the anonymizer in place; swap it with
reload_anonymizer or
reload_anonymizer_from_bytes.
To reload a source the guard uses, wrap it in an Arc, pass a clone to
GuardBuilder::ip_intel and keep the other:
use std::sync::Arc;
use std::time::Duration;
use session_guard::{Guard, GuardConfig, MaxMindIntel, MemoryStore};
let intel = Arc::new(MaxMindIntel::open(
"/var/lib/GeoIP/GeoLite2-Country.mmdb",
Some("/var/lib/GeoIP/GeoLite2-ASN.mmdb"),
)?);
intel.spawn_reload(Duration::from_secs(60 * 60));
let guard = Guard::builder(MemoryStore::new(), GuardConfig::default())
.ip_intel(Arc::clone(&intel))
.build();Implementations§
Source§impl MaxMindIntel
impl MaxMindIntel
Sourcepub fn open(
country_db: impl AsRef<Path>,
asn_db: Option<impl AsRef<Path>>,
) -> Result<Self, MaxMindError>
pub fn open( country_db: impl AsRef<Path>, asn_db: Option<impl AsRef<Path>>, ) -> Result<Self, MaxMindError>
Reads the country database (City or Country edition) and, optionally, the ASN database.
§Errors
Fails when a file cannot be read, is not a valid MMDB file, or is the wrong kind of database.
Sourcepub fn from_bytes(
country_db: Vec<u8>,
asn_db: Option<Vec<u8>>,
) -> Result<Self, MaxMindError>
pub fn from_bytes( country_db: Vec<u8>, asn_db: Option<Vec<u8>>, ) -> Result<Self, MaxMindError>
Sourcepub fn with_anonymizer(
self,
anonymizer_db: impl AsRef<Path>,
) -> Result<Self, MaxMindError>
pub fn with_anonymizer( self, anonymizer_db: impl AsRef<Path>, ) -> Result<Self, MaxMindError>
Adds an Anonymous IP, Anonymous Plus or IP Risk database, so lookups also report the
Anonymity of the network; see Anonymizers.
reload_if_changed follows its file too.
§Errors
Fails when the file cannot be read, is not a valid MMDB file, or is the wrong kind of database.
Sourcepub fn with_anonymizer_bytes(
self,
anonymizer_db: Vec<u8>,
) -> Result<Self, MaxMindError>
pub fn with_anonymizer_bytes( self, anonymizer_db: Vec<u8>, ) -> Result<Self, MaxMindError>
Like with_anonymizer, from database contents already in
memory.
§Errors
Fails when the bytes are not a valid MMDB file or the wrong kind of database.
Sourcepub fn reload(
&self,
country_db: impl AsRef<Path>,
asn_db: Option<impl AsRef<Path>>,
) -> Result<(), MaxMindError>
pub fn reload( &self, country_db: impl AsRef<Path>, asn_db: Option<impl AsRef<Path>>, ) -> Result<(), MaxMindError>
Replaces the country and ASN databases with freshly read files, which later
reload_if_changed checks follow. In-flight lookups finish on
the old databases. On error the current databases and files stay in place. The
anonymizer database is left as it is.
§Errors
As for open.
Sourcepub fn reload_from_bytes(
&self,
country_db: Vec<u8>,
asn_db: Option<Vec<u8>>,
) -> Result<(), MaxMindError>
pub fn reload_from_bytes( &self, country_db: Vec<u8>, asn_db: Option<Vec<u8>>, ) -> Result<(), MaxMindError>
Like reload, from database contents already in memory. The databases
no longer come from files, so reload_if_changed stops
checking them (but still checks the anonymizer database’s file, if it has one).
§Errors
As for from_bytes.
Sourcepub fn reload_anonymizer(
&self,
anonymizer_db: impl AsRef<Path>,
) -> Result<(), MaxMindError>
pub fn reload_anonymizer( &self, anonymizer_db: impl AsRef<Path>, ) -> Result<(), MaxMindError>
Replaces (or adds) the anonymizer database with a freshly read file, which later
reload_if_changed checks follow. On error the current
anonymizer database and file stay in place.
§Errors
As for with_anonymizer.
Sourcepub fn reload_anonymizer_from_bytes(
&self,
anonymizer_db: Vec<u8>,
) -> Result<(), MaxMindError>
pub fn reload_anonymizer_from_bytes( &self, anonymizer_db: Vec<u8>, ) -> Result<(), MaxMindError>
Like reload_anonymizer, from database contents already in
memory. reload_if_changed then stops checking the
anonymizer database.
§Errors
As for with_anonymizer_bytes.
Sourcepub fn reload_if_changed(&self) -> Result<bool, MaxMindError>
pub fn reload_if_changed(&self) -> Result<bool, MaxMindError>
Reloads the databases if their files changed since they were last read, and returns whether it did.
The files are those given to open or the latest
reload, and to with_anonymizer or the latest
reload_anonymizer. Each is compared by modification time and
size, which costs a stat per file; unchanged files are not read. The country and ASN
databases are reloaded together, the anonymizer database on its own. Databases from
bytes have no files and are never reloaded here.
This blocks while it reads and parses changed files (tens of megabytes for a City
database), so call it off the async runtime, or use spawn_reload.
§Errors
As for open, for example when a file is missing, or only partly written
by a tool that does not replace it atomically. The databases that failed then stay in
place and the next call tries again; the others are still reloaded. With failures on both
sides, the country or ASN error is returned.
Sourcepub fn spawn_reload(self: &Arc<Self>, every: Duration) -> JoinHandle<()> ⓘ
Available on crate feature tokio only.
pub fn spawn_reload(self: &Arc<Self>, every: Duration) -> JoinHandle<()> ⓘ
tokio only.Runs reload_if_changed now and then every every on the
tokio runtime, reading files on its blocking pool. Each reload is logged (info, with
the databases’ build times) and each failure too (warn), with tracing. A failed check
does not stop the task and is retried on the next tick; abort the handle to stop it.
MaxMind releases new databases at most twice a week, so an interval of minutes to an
hour is plenty, and a check of unchanged files is cheap.
§Panics
Outside a tokio runtime, or if every is zero.
Trait Implementations§
Source§impl Debug for MaxMindIntel
impl Debug for MaxMindIntel
Auto Trait Implementations§
impl !Freeze for MaxMindIntel
impl RefUnwindSafe for MaxMindIntel
impl Send for MaxMindIntel
impl Sync for MaxMindIntel
impl Unpin for MaxMindIntel
impl UnsafeUnpin for MaxMindIntel
impl UnwindSafe for MaxMindIntel
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more