Skip to main content

Fast radix tree for IP addresses and DNS names

Project description

RadixTarget

Python Version Rust Version License Black tests Codecov

RadixTarget is a performant radix implementation designed for quick lookups of IP addresses/networks and DNS hostnames.

RadixTarget is:

  • Written in Rust with Python bindings
  • Capable of ~200,000 lookups per second regardless of database size
  • 100% test coverage
  • Available as both a Rust crate and Python package
  • Used by:

Python

Installation

pip install radixtarget

Usage

from radixtarget import RadixTarget

rt = RadixTarget()

# IPv4
rt.add("192.168.1.0/24")
rt.get("192.168.1.10") # IPv4Network("192.168.1.0/24")
rt.get("192.168.2.10") # None

# IPv6
rt.add("dead::/64")
rt.get("dead::beef") # IPv6Network("dead::/64")
rt.get("dead:cafe::beef") # None

# DNS
rt.add("net")
rt.add("www.example.com")
rt.add("test.www.example.com")
rt.get("net") # "net"
rt.get("evilcorp.net") # "net"
rt.get("www.example.com") # "www.example.com"
rt.get("asdf.test.www.example.com") # "test.www.example.com"
rt.get("example.com") # None

# Custom data nodes
rt.add("evilcorp.co.uk", "custom_data")
rt.get("www.evilcorp.co.uk") # "custom_data"

Rust

Installation

cargo add radixtarget

Usage

use radixtarget::{RadixTarget, ScopeMode};
use std::collections::HashSet;

// Create a new RadixTarget
let mut rt = RadixTarget::new(&[], ScopeMode::Normal);

// IPv4 networks and addresses
rt.insert("192.168.1.0/24"); 
assert_eq!(rt.get("192.168.1.100"), Some("192.168.1.0/24".to_string()));
assert_eq!(rt.get("192.168.2.100"), None);

// IPv6 networks and addresses  
rt.insert("dead::/64");
assert_eq!(rt.get("dead::beef"), Some("dead::/64".to_string()));
assert_eq!(rt.get("cafe::beef"), None);

// DNS hostnames
rt.insert("example.com");
rt.insert("api.test.www.example.com");
assert_eq!(rt.get("example.com"), Some("example.com".to_string()));
assert_eq!(rt.get("subdomain.api.test.www.example.com"), 
           Some("api.test.www.example.com".to_string()));

// Check if target contains a value
assert!(rt.contains("192.168.1.50"));
assert!(rt.contains("dead::1234"));
assert!(rt.contains("example.com"));

// Get all hosts
let hosts: HashSet<String> = rt.hosts();
println!("All hosts: {:?}", hosts);

// Delete targets
assert!(rt.delete("192.168.1.0/24"));
assert!(!rt.delete("192.168.1.0/24")); // false - already deleted

// Utility operations
println!("Number of hosts: {}", rt.len());
println!("Is empty: {}", rt.is_empty());

// Prune dead nodes (returns number of pruned nodes)
let pruned_count = rt.prune();

// Defragment overlapping networks (returns (cleaned, new) hosts)
let (cleaned_hosts, new_hosts) = rt.defrag();

Scope Modes

RadixTarget supports different scope modes for DNS matching:

use radixtarget::{RadixTarget, ScopeMode};

// Normal mode: standard radix tree behavior (default)
let mut rt_normal = RadixTarget::new(&[], ScopeMode::Normal);
rt_normal.insert("example.com");
assert_eq!(rt_normal.get("subdomain.example.com"), Some("example.com".to_string()));

// Strict mode: exact matching only
let mut rt_strict = RadixTarget::new(&[], ScopeMode::Strict);
rt_strict.insert("example.com");
assert_eq!(rt_strict.get("example.com"), Some("example.com".to_string()));
assert_eq!(rt_strict.get("subdomain.example.com"), None); // No subdomain matching

// ACL mode: Same behavior as normal, but keeps only the highest parent subnet for efficiency
let mut rt_acl = RadixTarget::new(&[], ScopeMode::Acl);
rt_acl.insert("192.168.1.0/24");
rt_acl.insert("192.168.1.0/28");
// Least specific match is returned instead of most specific
assert_eq!(rt_acl.get("192.168.1.1"), Some("192.168.1.0/24".to_string()));

Initialization with Hosts

use radixtarget::{RadixTarget, ScopeMode};

// Initialize with existing hosts
let hosts = vec!["192.168.1.0/24", "example.com", "dead::/64"];
let rt = RadixTarget::new(&hosts, ScopeMode::Normal);

assert!(rt.contains("192.168.1.100"));
assert!(rt.contains("subdomain.example.com"));
assert!(rt.contains("dead::beef"));

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

radixtarget-4.0.0rc1.tar.gz (668.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

radixtarget-4.0.0rc1-cp312-cp312-manylinux_2_34_x86_64.whl (465.5 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.34+ x86-64

File details

Details for the file radixtarget-4.0.0rc1.tar.gz.

File metadata

  • Download URL: radixtarget-4.0.0rc1.tar.gz
  • Upload date:
  • Size: 668.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.9.4

File hashes

Hashes for radixtarget-4.0.0rc1.tar.gz
Algorithm Hash digest
SHA256 36c8c47be7c4ecd096dc5af6a7d6bdf319cd5639d74c5abe062fa0190ade025f
MD5 5749ae7e55cb1ba2aefe011b6b34d2c4
BLAKE2b-256 be61ffbe28eecef0e002c795d33876ca53e6289a477ed07f2f31004e28d734db

See more details on using hashes here.

File details

Details for the file radixtarget-4.0.0rc1-cp312-cp312-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for radixtarget-4.0.0rc1-cp312-cp312-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 df79d6eeac171a55f8a8e6bda7a4ac17dd1bf84800bd862530e8a12b0854eb51
MD5 6db1bb3cacdd6e4476a32a5547ed63d2
BLAKE2b-256 fc4060b97d0bf1a97d467a2befdfe4f99594cbbba54d44bbd7ede51153b33b3d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page