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