Class: PassiveDNS::PDNSToolStateDB

Inherits:
PDNSToolState show all
Defined in:
lib/passivedns/client/state.rb

Overview

creates persistence to the tool state by leveraging SQLite3

Instance Attribute Summary collapse

Attributes inherited from PDNSToolState

#debug

Instance Method Summary collapse

Methods inherited from PDNSToolState

#to_gdf, #to_graphml, #to_graphviz, #to_json, #to_s, #to_xml, #to_yaml

Constructor Details

#initialize(sqlitedb = nil) ⇒ PDNSToolStateDB

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



207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'lib/passivedns/client/state.rb', line 207

def initialize(sqlitedb=nil)
	puts "PDNSToolState  initialize  #{sqlitedb}" if @debug
	@level = 0
	@sqlitedb = sqlitedb
	raise "Cannot use this class without a database file" unless @sqlitedb
	unless File.exists?(@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

Instance Attribute Details

#levelObject (readonly)

Returns the value of attribute level.



204
205
206
# File 'lib/passivedns/client/state.rb', line 204

def level
  @level
end

Instance Method Details

#add_query(query, state, level = @level+1) ⇒ Object

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



258
259
260
261
262
263
264
265
266
# File 'lib/passivedns/client/state.rb', line 258

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) ⇒ Object

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



248
249
250
251
252
253
254
255
# File 'lib/passivedns/client/state.rb', line 248

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_tablesObject

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



229
230
231
232
233
234
235
236
237
# File 'lib/passivedns/client/state.rb', line 229

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) ⇒ Object

returns each query waiting on the queue



285
286
287
288
289
290
291
292
293
294
295
296
297
298
# File 'lib/passivedns/client/state.rb', line 285

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) ⇒ Object

returns each query waiting on the queue



274
275
276
277
278
279
280
281
282
# File 'lib/passivedns/client/state.rb', line 274

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_resultObject

returns the next record



240
241
242
243
244
245
# File 'lib/passivedns/client/state.rb', line 240

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) ⇒ Object

sets the state of a given query



269
270
271
# File 'lib/passivedns/client/state.rb', line 269

def update_query(query,state)
	@sqlitedbh.execute("update queue set state = '#{state}' where query = '#{query}'")
end