class PassiveDNS::PDNSToolStateDB

creates persistence to the tool state by leveraging SQLite3

Attributes

level[R]

Public Class Methods

new(sqlitedb=nil) click to toggle source

creates an SQLite3-based Passive DNS Client state only argument is the filename of the sqlite3 database

# File lib/passivedns/client/state.rb, line 207
def initialize(sqlitedb=nil)
  @debug = false
  puts "PDNSToolState  initialize  #{sqlitedb}" if @debug
  @level = 0
  @sqlitedb = sqlitedb
  raise "Cannot use this class without a database file" unless @sqlitedb
  unless File.exist?(@sqlitedb)
    newdb = true
  end
  @sqlitedbh = SQLite3::Database.new(@sqlitedb)
  if newdb
    create_tables
  end
  res = @sqlitedbh.execute("select min(level) from queue where state = 'pending'")
  if res
    res.each do |row|
      @level = row[0].to_i
      puts "changed @level = #{@level}" if @debug
    end
  end
end

Public Instance Methods

add_query(query,state,level=@level+1) click to toggle source

adding a query to the queue of things to be queried, but only if the query isn't already queued or answered

# File lib/passivedns/client/state.rb, line 259
def add_query(query,state,level=@level+1)
  return if get_state(query)
  curtime = Time.now().to_f
  begin
    puts "add_query(#{query},#{state},level=#{level})" if @debug
    @sqlitedbh.execute("insert into queue values ('#{query}','#{state}',#{level},#{curtime})")
  rescue
  end
end
add_result(res) click to toggle source

adds the record to the list of records received and tries to add the answer and query back to the queue for future query

# File lib/passivedns/client/state.rb, line 249
def add_result(res)
  puts "adding result: #{res.to_s}" if @debug
  curtime = Time.now().to_f
  @sqlitedbh.execute("insert into results values ('#{res.query}','#{res.answer}','#{res.rrtype}','#{res.ttl}','#{res.firstseen}','#{res.lastseen}',#{curtime})")

  add_query(res.answer,'pending')
  add_query(res.query,'pending')
end
create_tables() click to toggle source

creates the sqlite3 tables needed to track the state of this tool as itqueries and recurses

# File lib/passivedns/client/state.rb, line 230
def create_tables
  puts "creating tables" if @debug
  @sqlitedbh.execute("create table results (query, answer, rrtype, ttl, firstseen, lastseen, ts REAL)")
  @sqlitedbh.execute("create table queue (query, state, level INTEGER, ts REAL)")
  @sqlitedbh.execute("create index residx on results (ts)")
  @sqlitedbh.execute("create unique index queue_unique on queue (query)")
  @sqlitedbh.execute("create index queue_level_idx on queue (level)")
  @sqlitedbh.execute("create index queue_state_idx on queue (state)")
end
each_query(max_level=20) { |query| ... } click to toggle source

returns each query waiting on the queue

# File lib/passivedns/client/state.rb, line 286
def each_query(max_level=20)
  puts "each_query max_level=#{max_level} curlevel=#{@level}" if @debug
  rows = @sqlitedbh.execute("select query, state, level from queue where state = 'failed' or state = 'pending' order by level limit 1")
  if rows
    rows.each do |row|
      query,state,level = row
      puts "  #{query},#{state},#{level}" if @debug
      if level < max_level
        update_query(query,'queried')
        yield query
      end
    end
  end
end
get_state(query) click to toggle source

returns each query waiting on the queue

# File lib/passivedns/client/state.rb, line 275
def get_state(query)
  rows = @sqlitedbh.execute("select state from queue where query = '#{query}'")
  if rows
    rows.each do |row|
      return row[0]
    end
  end
  false
end
next_result() { |pdns_result(*row)| ... } click to toggle source

returns the next record

# File lib/passivedns/client/state.rb, line 241
def next_result
  rows = @sqlitedbh.execute("select query, answer, rrtype, ttl, firstseen, lastseen from results order by ts")
  rows.each do |row|
    yield PDNSResult.new(*row)
  end
end
update_query(query,state) click to toggle source

sets the state of a given query

# File lib/passivedns/client/state.rb, line 270
def update_query(query,state)
  @sqlitedbh.execute("update queue set state = '#{state}' where query = '#{query}'")
end