Module: OpenASN

Defined in:
lib/openasn.rb,
lib/openasn/ip.rb,
lib/openasn/errors.rb,
lib/openasn/result.rb,
lib/openasn/tier_b.rb,
lib/openasn/dataset.rb,
lib/openasn/parsers.rb,
lib/openasn/railtie.rb,
lib/openasn/updater.rb,
lib/openasn/version.rb,
lib/openasn/snapshot.rb,
lib/openasn/cidr_utils.rb,
lib/openasn/classifier.rb,
lib/openasn/middleware.rb,
lib/openasn/update_job.rb,
lib/openasn/http_client.rb,
lib/openasn/binary_format.rb,
lib/openasn/configuration.rb,
lib/openasn/overlay_store.rb,
lib/openasn/special_ranges.rb

Overview

OpenASN — offline IP origin intelligence.

OpenASN.lookup("203.0.113.42")
# => #<OpenASN::Result 203.0.113.42 verdict=unknown …>

r = OpenASN.lookup(request.remote_ip)
r.verdict          # :residential_isp | :mobile | :business | :hosting |
                 # :vpn | :tor_exit | :relay | :enterprise_gateway |
                 # :education | :government | :cgnat | :private | :unknown
r.infrastructure?  # verdict in {hosting, vpn, tor_exit} — the honest boolean
r.likely_human?    # verdict in {residential_isp, mobile, relay, cgnat, enterprise_gateway}
r.asn / r.as_org / r.category / r.network_role / r.provider / r.sources

Every lookup is local (microseconds, no network). Data ships as a bundled seed and refreshes from OpenASN's nightly releases + Tier B authorities via OpenASN.update! / OpenASN::UpdateJob.

REMEMBER WHAT VERDICTS MEAN: a clean/residential_isp verdict is absence of evidence, NOT proof of innocence — residential proxies are invisible to any offline dataset. vpn/hosting/tor_exit are high-confidence; treat everything else as a signal, not a sentence. Never hard-block relay, cgnat, or mobile: those are real people.

Defined Under Namespace

Modules: BinaryFormat, CidrUtils, Classifier, IP, Parsers, SpecialRanges Classes: Configuration, Dataset, Error, FormatError, HttpClient, IntegrityError, InvalidIPError, Middleware, OverlayStore, Railtie, Result, Snapshot, TierB, UpdateError, UpdateJob, Updater

Constant Summary collapse

VERSION =
"0.2.0"

Class Method Summary collapse

Class Method Details

.configurationObject



52
53
54
# File 'lib/openasn.rb', line 52

def configuration
  @configuration ||= Configuration.new
end

.configure {|configuration| ... } ⇒ Object

Yields:



56
57
58
59
60
61
# File 'lib/openasn.rb', line 56

def configure
  yield(configuration)
  # Config affects how snapshots load (data_dir, memory_mode, tier_b…):
  # drop any snapshot built under the old config. Cheap; lazy reload.
  @dataset = nil
end

.data_stale_on_disk?(max_age: Dataset::STALE_AFTER) ⇒ Boolean

Cheap "is the on-disk data old?" probe that does NOT load the dataset. Considers the freshest of data_dir and the bundled seed (used by the Railtie's boot staleness check).

Returns:

  • (Boolean)


96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/openasn.rb', line 96

def data_stale_on_disk?(max_age: Dataset::STALE_AFTER)
  build_ids = [File.join(configuration.data_dir, "manifest.json"),
               File.join(Snapshot::SEED_DIR, "manifest.json")].filter_map do |path|
    next unless File.exist?(path)

    JSON.parse(File.read(path))["build_id"]
  rescue JSON::ParserError
    nil
  end
  newest = build_ids.filter_map { |id| Time.iso8601(id) rescue nil }.max # rubocop:disable Style/RescueModifier
  newest.nil? || (Time.now - newest) > max_age
end

.datasetObject



63
64
65
# File 'lib/openasn.rb', line 63

def dataset
  @dataset ||= Dataset.new(configuration)
end

.dataset_infoObject



89
90
91
# File 'lib/openasn.rb', line 89

def dataset_info
  dataset.info
end

.eager_load!Object

Load the dataset at boot instead of on first lookup (call from an initializer in latency-sensitive apps; first lazy load costs ~50-200ms depending on memory_mode).



85
86
87
# File 'lib/openasn.rb', line 85

def eager_load!
  dataset.eager_load!
end

.lookup(ip) ⇒ Object Also known as: check, []

Classify an IP (String or IPAddr). Never returns nil; raises OpenASN::InvalidIPError (an ArgumentError) on unparseable input.



69
70
71
# File 'lib/openasn.rb', line 69

def lookup(ip)
  Classifier.classify(dataset.snapshot, ip)
end

.reset!Object

Test/console helper: forget configuration and loaded data.



110
111
112
113
# File 'lib/openasn.rb', line 110

def reset!
  @configuration = nil
  @dataset = nil
end

.update!(force: false) ⇒ Object

Refresh canonical artifacts + Tier B overlays now, atomically swapping the in-memory dataset on success. -> :updated | :tier_b_only | :unchanged | :locked



78
79
80
# File 'lib/openasn.rb', line 78

def update!(force: false)
  Updater.new(configuration, dataset).run(force: force)
end