passivedns-client 2.1.6 → 2.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,7 +7,7 @@ module PassiveDNS #:nodoc: don't document this
7
7
  # The Provider module contains all the Passive DNS provider client code
8
8
  module Provider
9
9
  # Queries VirusTotal's passive DNS database
10
- class VirusTotal < PassiveDB
10
+ class VirusTotal < PassiveDB
11
11
  # Sets the modules self-reported name to "VirusTotal"
12
12
  def self.name
13
13
  "VirusTotal"
@@ -39,67 +39,81 @@ module PassiveDNS #:nodoc: don't document this
39
39
  #
40
40
  # PassiveDNS::Provider::VirusTotal.new(options)
41
41
  #
42
- def initialize(options={})
42
+ def initialize(options={})
43
43
  @debug = options[:debug] || false
44
+ @timeout = options[:timeout] || 20
44
45
  @apikey = options["APIKEY"] || raise("#{self.class.name} requires an APIKEY. See README.md")
45
46
  @url = options["URL"] || "https://www.virustotal.com/vtapi/v2/"
46
47
  end
47
48
 
48
49
  # Takes a label (either a domain or an IP address) and returns
49
50
  # an array of PassiveDNS::PDNSResult instances with the answers to the query
50
- def lookup(label, limit=nil)
51
- $stderr.puts "DEBUG: #{self.class.name}.lookup(#{label})" if @debug
52
- Timeout::timeout(240) {
53
- url = nil
54
- if label =~ /^[\d\.]+$/
55
- url = "#{@url}ip-address/report?ip=#{label}&apikey=#{@apikey}"
56
- else
57
- url = "#{@url}domain/report?domain=#{label}&apikey=#{@apikey}"
58
- end
59
- $stderr.puts "DEBUG: #{self.class.name} url = #{url}" if @debug
60
- url = URI.parse url
61
- http = Net::HTTP.new(url.host, url.port)
62
- http.use_ssl = (url.scheme == 'https')
63
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
64
- http.verify_depth = 5
65
- request = Net::HTTP::Get.new(url.path+"?"+url.query)
66
- request.add_field("User-Agent", "Ruby/#{RUBY_VERSION} passivedns-client rubygem v#{PassiveDNS::Client::VERSION}")
67
- t1 = Time.now
68
- response = http.request(request)
69
- t2 = Time.now
70
- recs = parse_json(response.body, label, t2-t1)
51
+ def lookup(label, limit=nil)
52
+ $stderr.puts "DEBUG: #{self.class.name}.lookup(#{label})" if @debug
53
+ Timeout::timeout(@timeout) {
54
+ url = nil
55
+ if label =~ /^[\d\.]+$/
56
+ url = "#{@url}ip-address/report?ip=#{label}&apikey=#{@apikey}"
57
+ else
58
+ url = "#{@url}domain/report?domain=#{label}&apikey=#{@apikey}"
59
+ end
60
+ $stderr.puts "DEBUG: #{self.class.name} url = #{url}" if @debug
61
+ begin
62
+ url = URI.parse url
63
+ rescue URI::InvalidURIError
64
+ $stderr.puts "ERROR: Invalid address: #{url}"
65
+ return
66
+ end
67
+ http = Net::HTTP.new(url.host, url.port)
68
+ http.use_ssl = (url.scheme == 'https')
69
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
70
+ http.verify_depth = 5
71
+ request = Net::HTTP::Get.new(url.path+"?"+url.query)
72
+ request.add_field("User-Agent", "Ruby/#{RUBY_VERSION} passivedns-client rubygem v#{PassiveDNS::Client::VERSION}")
73
+ t1 = Time.now
74
+ response = http.request(request)
75
+ if response.code.to_i == 204
76
+ $stderr.puts "DEBUG: empty response from server" if @debug
77
+ return
78
+ end
79
+ t2 = Time.now
80
+ recs = parse_json(response.body, label, t2-t1)
71
81
  if limit
72
82
  recs[0,limit]
73
83
  else
74
84
  recs
75
85
  end
76
- }
77
- rescue Timeout::Error => e
78
- $stderr.puts "#{self.class.name} lookup timed out: #{label}"
79
- end
86
+ }
87
+ rescue Timeout::Error
88
+ $stderr.puts "#{self.class.name} lookup timed out: #{label}"
89
+ end
80
90
 
81
91
  private
82
92
 
83
93
  # parses the response of virustotal's JSON reply to generate an array of PDNSResult
84
- def parse_json(page,query,response_time=0)
85
- res = []
86
- data = JSON.parse(page)
87
- if data['resolutions']
88
- data['resolutions'].each do |row|
94
+ def parse_json(page,query,response_time=0)
95
+ res = []
96
+ return res if !page
97
+ data = JSON.parse(page)
98
+ if data['resolutions']
99
+ data['resolutions'].each do |row|
89
100
  lastseen = Time.parse(row['last_resolved']+" +0000")
90
- if row['ip_address']
91
- res << PDNSResult.new(self.class.name,response_time,query,row['ip_address'],'A',nil,nil,lastseen)
92
- elsif row['hostname']
93
- res << PDNSResult.new(self.class.name,response_time,row['hostname'],query,'A',nil,nil,lastseen)
94
- end
95
- end
96
- end
97
- res
98
- rescue Exception => e
99
- $stderr.puts "VirusTotal Exception: #{e}"
100
- raise e
101
- end
101
+ if row['ip_address']
102
+ res << PDNSResult.new(self.class.name,response_time,query,row['ip_address'],'A',nil,nil,lastseen, 'yellow')
103
+ elsif row['hostname']
104
+ res << PDNSResult.new(self.class.name,response_time,row['hostname'],query,'A',nil,nil,lastseen, 'yellow')
105
+ end
106
+ end
107
+ end
108
+ if data['response_code'] == 0
109
+ $stderr.puts "DEBUG: server returned error: #{data['verbose_msg']}" if @debug
110
+ end
111
+ res
112
+ rescue Exception => e
113
+ $stderr.puts "VirusTotal Exception: #{e}"
114
+ raise e
115
+ end
102
116
 
103
- end
117
+ end
104
118
  end
105
- end
119
+ end
@@ -4,297 +4,298 @@ require 'structformatter'
4
4
 
5
5
  module PassiveDNS # :nodoc:
6
6
  # struct to hold pending entries for query
7
- class PDNSQueueEntry < Struct.new(:query, :state, :level); end
7
+ class PDNSQueueEntry < Struct.new(:query, :state, :level); end
8
8
 
9
9
  # holds state in memory of the queue to be queried, records returned, and the level of recursion
10
- class PDNSToolState
10
+ class PDNSToolState
11
11
  # :debug enables verbose logging to standard output
12
- attr_accessor :debug
12
+ attr_accessor :debug
13
13
  # :level is the recursion depth
14
- attr_reader :level
14
+ attr_reader :level
15
15
 
16
16
  # creates a new, blank PDNSToolState instance
17
- def initialize
18
- @queue = []
19
- @recs = []
20
- @level = 0
21
- end
17
+ def initialize
18
+ @queue = []
19
+ @recs = []
20
+ @level = 0
21
+ end
22
22
 
23
23
  # returns the next record
24
- def next_result
25
- @recs.each do |rec|
26
- yield rec
27
- end
28
- end
24
+ def next_result
25
+ @recs.each do |rec|
26
+ yield rec
27
+ end
28
+ end
29
29
 
30
30
  # adds the record to the list of records received and tries to add the answer and query back to the queue for future query
31
- def add_result(res)
32
- @recs << res
33
- add_query(res.answer,'pending')
34
- add_query(res.query,'pending')
35
- end
31
+ def add_result(res)
32
+ @recs << res
33
+ add_query(res.answer,'pending')
34
+ add_query(res.query,'pending')
35
+ end
36
36
 
37
37
  # sets the state of a given query
38
- def update_query(query,state)
39
- @queue.each do |q|
40
- if q.query == query
41
- puts "update_query: #{query} (#{q.state}) -> (#{state})" if @debug
42
- q.state = state
43
- break
44
- end
45
- end
46
- end
38
+ def update_query(query,state)
39
+ @queue.each do |q|
40
+ if q.query == query
41
+ puts "update_query: #{query} (#{q.state}) -> (#{state})" if @debug
42
+ q.state = state
43
+ break
44
+ end
45
+ end
46
+ end
47
47
 
48
48
  # returns the state of a provided query
49
- def get_state(query)
50
- @queue.each do |q|
51
- if q.query == query
52
- return q.state
53
- end
54
- end
55
- false
56
- end
49
+ def get_state(query)
50
+ @queue.each do |q|
51
+ if q.query == query
52
+ return q.state
53
+ end
54
+ end
55
+ false
56
+ end
57
57
 
58
58
  # adding a query to the queue of things to be queried, but only if the query isn't already queued or answered
59
- def add_query(query,state,level=@level+1)
60
- if query =~ /^\d+ \w+\./
61
- query = query.split(/ /,2)[1]
62
- end
63
- return if get_state(query)
64
- puts "Adding query: #{query}, #{state}, #{level}" if @debug
65
- @queue << PDNSQueueEntry.new(query,state,level)
66
- end
59
+ def add_query(query,state,level=@level+1)
60
+ if query =~ /^\d+ \w+\./
61
+ query = query.split(/ /,2)[1]
62
+ end
63
+ return if get_state(query)
64
+ puts "Adding query: #{query}, #{state}, #{level}" if @debug
65
+ @queue << PDNSQueueEntry.new(query,state,level)
66
+ end
67
67
 
68
68
  # returns each query waiting on the queue
69
- def each_query(max_level=20)
70
- @queue.each do |q|
71
- if q.state == 'pending' or q.state == 'failed'
72
- @level = q.level
73
- q.state = 'queried'
74
- if q.level < max_level
75
- yield q.query
76
- end
77
- end
78
- end
79
- end
69
+ def each_query(max_level=20)
70
+ @queue.each do |q|
71
+ if q.state == 'pending' or q.state == 'failed'
72
+ @level = q.level
73
+ q.state = 'queried'
74
+ if q.level < max_level
75
+ yield q.query
76
+ end
77
+ end
78
+ end
79
+ end
80
80
 
81
81
  # transforms a set of results into GDF syntax
82
- def to_gdf
83
- output = "nodedef> name,description VARCHAR(12),color,style\n"
84
- # IP "$node2,,white,1"
85
- # domain "$node2,,gray,2"
86
- # Struct.new(:query, :answer, :rrtype, :ttl, :firstseen, :lastseen)
87
- colors = {"MX" => "green", "A" => "blue", "CNAME" => "pink", "NS" => "red", "SOA" => "white", "PTR" => "purple", "TXT" => "brown"}
88
- nodes = {}
89
- edges = {}
90
- next_result do |i|
91
- if i
92
- nodes[i.query + ",,gray,2"] = true
93
- if i.answer =~ /[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/ then
94
- nodes[i.answer + ",,white,1"] = true
95
- else
96
- nodes[i.answer + ",,gray,2"] = true
97
- end
98
- color = colors[i.rrtype]
99
- color ||= "blue"
100
- edges[i.query + "," + i.answer + "," + color] = true
101
- end
102
- end
103
- nodes.each do |i,j|
104
- output += i+"\n"
105
- end
106
- output += "edgedef> node1,node2,color\n"
107
- edges.each do |i,j|
108
- output += i+"\n"
109
- end
110
- output
111
- end
82
+ def to_gdf
83
+ output = "nodedef> name,description VARCHAR(12),color,style\n"
84
+ # IP "$node2,,white,1"
85
+ # domain "$node2,,gray,2"
86
+ # Struct.new(:query, :answer, :rrtype, :ttl, :firstseen, :lastseen)
87
+ colors = {"MX" => "green", "A" => "blue", "CNAME" => "pink", "NS" => "red", "SOA" => "white", "PTR" => "purple", "TXT" => "brown"}
88
+ nodes = {}
89
+ edges = {}
90
+ next_result do |i|
91
+ if i
92
+ nodes[i.query + ",,gray,2"] = true
93
+ if i.answer =~ /[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/ then
94
+ nodes[i.answer + ",,white,1"] = true
95
+ else
96
+ nodes[i.answer + ",,gray,2"] = true
97
+ end
98
+ color = colors[i.rrtype]
99
+ color ||= "blue"
100
+ edges[i.query + "," + i.answer + "," + color] = true
101
+ end
102
+ end
103
+ nodes.each do |i,j|
104
+ output += i+"\n"
105
+ end
106
+ output += "edgedef> node1,node2,color\n"
107
+ edges.each do |i,j|
108
+ output += i+"\n"
109
+ end
110
+ output
111
+ end
112
112
 
113
113
  # transforms a set of results into graphviz syntax
114
- def to_graphviz
115
- colors = {"MX" => "green", "A" => "blue", "CNAME" => "pink", "NS" => "red", "SOA" => "white", "PTR" => "purple", "TXT" => "brown"}
116
- output = "graph pdns {\n"
117
- nodes = {}
118
- next_result do |l|
119
- if l
120
- unless nodes[l.query]
121
- output += " \"#{l.query}\" [shape=ellipse, style=filled, color=gray];\n"
122
- if l.answer =~ /^\d{3}\.\d{3}\.\d{3}\.\d{3}$/
123
- output += " \"#{l.answer}\" [shape=box, style=filled, color=white];\n"
124
- else
125
- output += " \"#{l.answer}\" [shape=ellipse, style=filled, color=gray];\n"
126
- end
127
- nodes[l.query] = true
128
- end
129
- output += " \"#{l.query}\" -- \"#{l.answer}\" [color=#{colors[l.rrtype]}];\n"
130
- end
131
- end
132
- output += "}\n"
133
- end
114
+ def to_graphviz
115
+ colors = {"MX" => "green", "A" => "blue", "CNAME" => "pink", "NS" => "red", "SOA" => "white", "PTR" => "purple", "TXT" => "brown"}
116
+ output = "graph pdns {\n"
117
+ nodes = {}
118
+ next_result do |l|
119
+ if l
120
+ unless nodes[l.query]
121
+ output += " \"#{l.query}\" [shape=ellipse, style=filled, color=gray];\n"
122
+ if l.answer =~ /^\d{3}\.\d{3}\.\d{3}\.\d{3}$/
123
+ output += " \"#{l.answer}\" [shape=box, style=filled, color=white];\n"
124
+ else
125
+ output += " \"#{l.answer}\" [shape=ellipse, style=filled, color=gray];\n"
126
+ end
127
+ nodes[l.query] = true
128
+ end
129
+ output += " \"#{l.query}\" -- \"#{l.answer}\" [color=#{colors[l.rrtype]}];\n"
130
+ end
131
+ end
132
+ output += "}\n"
133
+ end
134
134
 
135
135
  # transforms a set of results into graphml syntax
136
- def to_graphml
137
- output = '<?xml version="1.0" encoding="UTF-8"?>
136
+ def to_graphml
137
+ output = '<?xml version="1.0" encoding="UTF-8"?>
138
138
  <graphml xmlns="http://graphml.graphdrawing.org/xmlns"
139
139
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
140
140
  xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
141
141
  http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
142
142
  <graph id="G" edgedefault="directed">
143
143
  '
144
- nodes = {}
145
- edges = {}
146
- next_result do |r|
147
- if r
148
- output += " <node id='#{r.query}'/>\n" unless nodes["#{r.query}"]
149
- nodes[r.query] = true
150
- output += " <node id='#{r.answer}'/>\n" unless nodes["#{r.answer}"]
151
- nodes[r.answer] = true
152
- output += " <edge source='#{r.query}' target='#{r.answer}'/>\n" unless edges["#{r.query}|#{r.answer}"]
153
- end
154
- end
155
- output += '</graph></graphml>'+"\n"
156
- end
144
+ nodes = {}
145
+ edges = {}
146
+ next_result do |r|
147
+ if r
148
+ output += " <node id='#{r.query}'/>\n" unless nodes["#{r.query}"]
149
+ nodes[r.query] = true
150
+ output += " <node id='#{r.answer}'/>\n" unless nodes["#{r.answer}"]
151
+ nodes[r.answer] = true
152
+ output += " <edge source='#{r.query}' target='#{r.answer}'/>\n" unless edges["#{r.query}|#{r.answer}"]
153
+ end
154
+ end
155
+ output += '</graph></graphml>'+"\n"
156
+ end
157
157
 
158
158
  # transforms a set of results into XML
159
- def to_xml
160
- output = '<?xml version="1.0" encoding="UTF-8" ?>'+"\n"
161
- output += "<report>\n"
162
- output += " <results>\n"
163
- next_result do |rec|
164
- output += " "+rec.to_xml+"\n"
165
- end
166
- output += " </results>\n"
167
- output += "</report>\n"
168
- end
159
+ def to_xml
160
+ output = '<?xml version="1.0" encoding="UTF-8" ?>'+"\n"
161
+ output += "<report>\n"
162
+ output += " <results>\n"
163
+ next_result do |rec|
164
+ output += " "+rec.to_xml+"\n"
165
+ end
166
+ output += " </results>\n"
167
+ output += "</report>\n"
168
+ end
169
169
 
170
170
  # transforms a set of results into YAML
171
- def to_yaml
172
- output = ""
173
- next_result do |rec|
174
- output += rec.to_yaml+"\n"
175
- end
176
- output
177
- end
171
+ def to_yaml
172
+ output = ""
173
+ next_result do |rec|
174
+ output += rec.to_yaml+"\n"
175
+ end
176
+ output
177
+ end
178
178
 
179
179
  # transforms a set of results into JSON
180
- def to_json
181
- output = "[\n"
182
- sep = ""
183
- next_result do |rec|
184
- output += sep
185
- output += rec.to_json
186
- sep = ",\n"
187
- end
188
- output += "\n]\n"
189
- end
180
+ def to_json
181
+ output = "[\n"
182
+ sep = ""
183
+ next_result do |rec|
184
+ output += sep
185
+ output += rec.to_json
186
+ sep = ",\n"
187
+ end
188
+ output += "\n]\n"
189
+ end
190
190
 
191
191
  # transforms a set of results into a text string
192
- def to_s(sep="\t")
193
- output = ""
194
- next_result do |rec|
195
- output += rec.to_s(sep)+"\n"
196
- end
197
- output
198
- end
199
- end # class PDNSToolState
192
+ def to_s(sep="\t")
193
+ output = ""
194
+ next_result do |rec|
195
+ output += rec.to_s(sep)+"\n"
196
+ end
197
+ output
198
+ end
199
+ end # class PDNSToolState
200
200
 
201
201
 
202
202
  # creates persistence to the tool state by leveraging SQLite3
203
- class PDNSToolStateDB < PDNSToolState
204
- attr_reader :level
203
+ class PDNSToolStateDB < PDNSToolState
204
+ attr_reader :level
205
205
  # creates an SQLite3-based Passive DNS Client state
206
206
  # only argument is the filename of the sqlite3 database
207
- def initialize(sqlitedb=nil)
208
- puts "PDNSToolState initialize #{sqlitedb}" if @debug
209
- @level = 0
210
- @sqlitedb = sqlitedb
211
- raise "Cannot use this class without a database file" unless @sqlitedb
212
- unless File.exists?(@sqlitedb)
213
- newdb = true
214
- end
215
- @sqlitedbh = SQLite3::Database.new(@sqlitedb)
216
- if newdb
217
- create_tables
218
- end
219
- res = @sqlitedbh.execute("select min(level) from queue where state = 'pending'")
220
- if res
221
- res.each do |row|
222
- @level = row[0].to_i
223
- puts "changed @level = #{@level}" if @debug
224
- end
225
- end
226
- end
207
+ def initialize(sqlitedb=nil)
208
+ @debug = false
209
+ puts "PDNSToolState initialize #{sqlitedb}" if @debug
210
+ @level = 0
211
+ @sqlitedb = sqlitedb
212
+ raise "Cannot use this class without a database file" unless @sqlitedb
213
+ unless File.exist?(@sqlitedb)
214
+ newdb = true
215
+ end
216
+ @sqlitedbh = SQLite3::Database.new(@sqlitedb)
217
+ if newdb
218
+ create_tables
219
+ end
220
+ res = @sqlitedbh.execute("select min(level) from queue where state = 'pending'")
221
+ if res
222
+ res.each do |row|
223
+ @level = row[0].to_i
224
+ puts "changed @level = #{@level}" if @debug
225
+ end
226
+ end
227
+ end
227
228
 
228
229
  # creates the sqlite3 tables needed to track the state of this tool as itqueries and recurses
229
- def create_tables
230
- puts "creating tables" if @debug
231
- @sqlitedbh.execute("create table results (query, answer, rrtype, ttl, firstseen, lastseen, ts REAL)")
232
- @sqlitedbh.execute("create table queue (query, state, level INTEGER, ts REAL)")
233
- @sqlitedbh.execute("create index residx on results (ts)")
234
- @sqlitedbh.execute("create unique index queue_unique on queue (query)")
235
- @sqlitedbh.execute("create index queue_level_idx on queue (level)")
236
- @sqlitedbh.execute("create index queue_state_idx on queue (state)")
237
- end
230
+ def create_tables
231
+ puts "creating tables" if @debug
232
+ @sqlitedbh.execute("create table results (query, answer, rrtype, ttl, firstseen, lastseen, ts REAL)")
233
+ @sqlitedbh.execute("create table queue (query, state, level INTEGER, ts REAL)")
234
+ @sqlitedbh.execute("create index residx on results (ts)")
235
+ @sqlitedbh.execute("create unique index queue_unique on queue (query)")
236
+ @sqlitedbh.execute("create index queue_level_idx on queue (level)")
237
+ @sqlitedbh.execute("create index queue_state_idx on queue (state)")
238
+ end
238
239
 
239
240
  # returns the next record
240
- def next_result
241
- rows = @sqlitedbh.execute("select query, answer, rrtype, ttl, firstseen, lastseen from results order by ts")
242
- rows.each do |row|
243
- yield PDNSResult.new(*row)
244
- end
245
- end
241
+ def next_result
242
+ rows = @sqlitedbh.execute("select query, answer, rrtype, ttl, firstseen, lastseen from results order by ts")
243
+ rows.each do |row|
244
+ yield PDNSResult.new(*row)
245
+ end
246
+ end
246
247
 
247
248
  # 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
- def add_result(res)
249
- puts "adding result: #{res.to_s}" if @debug
250
- curtime = Time.now().to_f
251
- @sqlitedbh.execute("insert into results values ('#{res.query}','#{res.answer}','#{res.rrtype}','#{res.ttl}','#{res.firstseen}','#{res.lastseen}',#{curtime})")
249
+ def add_result(res)
250
+ puts "adding result: #{res.to_s}" if @debug
251
+ curtime = Time.now().to_f
252
+ @sqlitedbh.execute("insert into results values ('#{res.query}','#{res.answer}','#{res.rrtype}','#{res.ttl}','#{res.firstseen}','#{res.lastseen}',#{curtime})")
252
253
 
253
- add_query(res.answer,'pending')
254
- add_query(res.query,'pending')
255
- end
254
+ add_query(res.answer,'pending')
255
+ add_query(res.query,'pending')
256
+ end
256
257
 
257
258
  # adding a query to the queue of things to be queried, but only if the query isn't already queued or answered
258
- def add_query(query,state,level=@level+1)
259
- return if get_state(query)
260
- curtime = Time.now().to_f
261
- begin
262
- puts "add_query(#{query},#{state},level=#{level})" if @debug
263
- @sqlitedbh.execute("insert into queue values ('#{query}','#{state}',#{level},#{curtime})")
264
- rescue
265
- end
266
- end
259
+ def add_query(query,state,level=@level+1)
260
+ return if get_state(query)
261
+ curtime = Time.now().to_f
262
+ begin
263
+ puts "add_query(#{query},#{state},level=#{level})" if @debug
264
+ @sqlitedbh.execute("insert into queue values ('#{query}','#{state}',#{level},#{curtime})")
265
+ rescue
266
+ end
267
+ end
267
268
 
268
269
  # sets the state of a given query
269
- def update_query(query,state)
270
- @sqlitedbh.execute("update queue set state = '#{state}' where query = '#{query}'")
271
- end
270
+ def update_query(query,state)
271
+ @sqlitedbh.execute("update queue set state = '#{state}' where query = '#{query}'")
272
+ end
272
273
 
273
274
  # returns each query waiting on the queue
274
- def get_state(query)
275
- rows = @sqlitedbh.execute("select state from queue where query = '#{query}'")
276
- if rows
277
- rows.each do |row|
278
- return row[0]
279
- end
280
- end
281
- false
282
- end
275
+ def get_state(query)
276
+ rows = @sqlitedbh.execute("select state from queue where query = '#{query}'")
277
+ if rows
278
+ rows.each do |row|
279
+ return row[0]
280
+ end
281
+ end
282
+ false
283
+ end
283
284
 
284
285
  # returns each query waiting on the queue
285
- def each_query(max_level=20)
286
- puts "each_query max_level=#{max_level} curlevel=#{@level}" if @debug
287
- rows = @sqlitedbh.execute("select query, state, level from queue where state = 'failed' or state = 'pending' order by level limit 1")
288
- if rows
289
- rows.each do |row|
290
- query,state,level = row
291
- puts " #{query},#{state},#{level}" if @debug
292
- if level < max_level
293
- update_query(query,'queried')
294
- yield query
295
- end
296
- end
297
- end
298
- end
299
- end # class PDNSToolStateDB
300
- end
286
+ def each_query(max_level=20)
287
+ puts "each_query max_level=#{max_level} curlevel=#{@level}" if @debug
288
+ rows = @sqlitedbh.execute("select query, state, level from queue where state = 'failed' or state = 'pending' order by level limit 1")
289
+ if rows
290
+ rows.each do |row|
291
+ query,state,level = row
292
+ puts " #{query},#{state},#{level}" if @debug
293
+ if level < max_level
294
+ update_query(query,'queried')
295
+ yield query
296
+ end
297
+ end
298
+ end
299
+ end
300
+ end # class PDNSToolStateDB
301
+ end