rubydns 0.6.0 → 2.0.0
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.
- checksums.yaml +6 -14
- data/.gitignore +23 -14
- data/.rspec +4 -0
- data/.simplecov +15 -0
- data/.travis.yml +9 -5
- data/.yardopts +1 -0
- data/Gemfile +6 -2
- data/README.md +82 -92
- data/Rakefile +2 -5
- data/bin/rubydns-check +374 -0
- data/examples/Gemfile +7 -0
- data/examples/README.md +137 -0
- data/examples/basic-dns.rb +24 -0
- data/examples/cname.rb +25 -0
- data/{test/examples/dropping-dns.rb → examples/flakey-dns.rb} +28 -31
- data/{test/examples → examples}/fortune-dns.rb +42 -46
- data/examples/geoip-dns.rb +115 -0
- data/examples/simple.rb +25 -0
- data/{test/examples → examples}/soa-dns.rb +27 -27
- data/{test/examples → examples}/test-dns-1.rb +26 -20
- data/{test/examples → examples}/test-dns-2.rb +17 -19
- data/examples/wikipedia-dns.rb +107 -0
- data/lib/rubydns/rule_based_server.rb +180 -0
- data/lib/rubydns/version.rb +1 -1
- data/lib/rubydns.rb +13 -63
- data/rubydns.gemspec +29 -23
- data/spec/rubydns/daemon_spec.rb +114 -0
- data/{test/test_system.rb → spec/rubydns/injected_supervisor_spec.rb} +32 -25
- data/spec/rubydns/passthrough_spec.rb +85 -0
- data/spec/rubydns/rules_spec.rb +74 -0
- data/spec/spec_helper.rb +30 -0
- metadata +101 -78
- data/bin/rd-dns-check +0 -374
- data/bin/rd-resolve-test +0 -160
- data/lib/rubydns/chunked.rb +0 -34
- data/lib/rubydns/extensions/hexdump.rb +0 -38
- data/lib/rubydns/extensions/logger.rb +0 -30
- data/lib/rubydns/extensions/resolv.rb +0 -53
- data/lib/rubydns/extensions/string-1.8.rb +0 -35
- data/lib/rubydns/extensions/string-1.9.2.rb +0 -29
- data/lib/rubydns/extensions/string-1.9.3.rb +0 -31
- data/lib/rubydns/extensions/string.rb +0 -27
- data/lib/rubydns/handler.rb +0 -140
- data/lib/rubydns/message.rb +0 -41
- data/lib/rubydns/resolver.rb +0 -239
- data/lib/rubydns/server.rb +0 -241
- data/lib/rubydns/system.rb +0 -146
- data/lib/rubydns/transaction.rb +0 -250
- data/test/examples/geoip-dns.rb +0 -86
- data/test/helper.rb +0 -9
- data/test/test_daemon.rb +0 -100
- data/test/test_domains.txt +0 -185
- data/test/test_passthrough.rb +0 -80
- data/test/test_resolver.rb +0 -105
- data/test/test_rules.rb +0 -74
- data/test/test_slow_server.rb +0 -98
- data/test/test_truncation.rb +0 -78
- /data/{test → spec/rubydns}/hosts.txt +0 -0
data/lib/rubydns/transaction.rb
DELETED
|
@@ -1,250 +0,0 @@
|
|
|
1
|
-
# Copyright, 2009, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
|
2
|
-
#
|
|
3
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
-
# of this software and associated documentation files (the "Software"), to deal
|
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
|
8
|
-
# furnished to do so, subject to the following conditions:
|
|
9
|
-
#
|
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
|
11
|
-
# all copies or substantial portions of the Software.
|
|
12
|
-
#
|
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
19
|
-
# THE SOFTWARE.
|
|
20
|
-
|
|
21
|
-
require 'eventmachine'
|
|
22
|
-
|
|
23
|
-
module RubyDNS
|
|
24
|
-
|
|
25
|
-
# This class provides all details of a single DNS question and answer. This
|
|
26
|
-
# is used by the DSL to provide DNS related functionality.
|
|
27
|
-
class Transaction
|
|
28
|
-
include EventMachine::Deferrable
|
|
29
|
-
|
|
30
|
-
def initialize(server, query, question, resource_class, answer, options = {})
|
|
31
|
-
@server = server
|
|
32
|
-
@query = query
|
|
33
|
-
@question = question
|
|
34
|
-
@resource_class = resource_class
|
|
35
|
-
@answer = answer
|
|
36
|
-
|
|
37
|
-
@options = options
|
|
38
|
-
|
|
39
|
-
@deferred = false
|
|
40
|
-
@question_appended = false
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
# The resource_class that was requested. This is typically used to generate a
|
|
44
|
-
# response.
|
|
45
|
-
attr :resource_class
|
|
46
|
-
|
|
47
|
-
# The incoming query which is a set of questions.
|
|
48
|
-
attr :query
|
|
49
|
-
|
|
50
|
-
# The question that this transaction represents.
|
|
51
|
-
attr :question
|
|
52
|
-
|
|
53
|
-
# The current full answer to the incoming query.
|
|
54
|
-
attr :answer
|
|
55
|
-
|
|
56
|
-
# Any options or configuration associated with the given transaction.
|
|
57
|
-
attr :options
|
|
58
|
-
|
|
59
|
-
# Return the name of the question, which is typically the requested hostname.
|
|
60
|
-
def name
|
|
61
|
-
@question.to_s
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
# Suitable for debugging purposes
|
|
65
|
-
def to_s
|
|
66
|
-
"#{name} #{@resource_class.name}"
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
# Run a new query through the rules with the given name and resource type. The
|
|
70
|
-
# results of this query are appended to the current transactions <tt>answer</tt>.
|
|
71
|
-
def append_query!(name, resource_class = nil, options = {})
|
|
72
|
-
Transaction.new(@server, @query, name, resource_class || @resource_class, @answer, options).process
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
def process(&finished)
|
|
76
|
-
@server.process(name, @resource_class, self)
|
|
77
|
-
|
|
78
|
-
unless @deferred
|
|
79
|
-
succeed(self)
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def defer!
|
|
84
|
-
@deferred = true
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
# Use the given resolver to respond to the question. The default functionality is
|
|
88
|
-
# implemented by passthrough, and if a reply is received, it will be merged with the
|
|
89
|
-
# answer for this transaction.
|
|
90
|
-
#
|
|
91
|
-
# If a block is supplied, this function yields with the reply and reply_name if
|
|
92
|
-
# successful. This could be used, for example, to update a cache or modify the
|
|
93
|
-
# reply.
|
|
94
|
-
def passthrough!(resolver, options = {}, &block)
|
|
95
|
-
passthrough(resolver, options) do |response|
|
|
96
|
-
if block_given?
|
|
97
|
-
yield response
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
@answer.merge!(response)
|
|
101
|
-
|
|
102
|
-
succeed if @deferred
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
true
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
# Use the given resolver to respond to the question. If recursion is
|
|
109
|
-
# not requested, the result is <tt>failure!(:Refused)</tt>. If the resolver does
|
|
110
|
-
# not respond, the result is <tt>failure!(:NXDomain)</tt>
|
|
111
|
-
#
|
|
112
|
-
# If a block is supplied, this function yields with the reply and reply_name if
|
|
113
|
-
# successful. This block is responsible for doing something useful with the reply,
|
|
114
|
-
# such as merging it or conditionally discarding it.
|
|
115
|
-
#
|
|
116
|
-
# A second argument, options, provides some control over the passthrough process.
|
|
117
|
-
# :force => true, ensures that the query will occur even if recursion is not requested.
|
|
118
|
-
def passthrough(resolver, options = {}, &block)
|
|
119
|
-
if @query.rd || options[:force]
|
|
120
|
-
# Resolver is asynchronous, so we are now deferred:
|
|
121
|
-
defer!
|
|
122
|
-
|
|
123
|
-
resolver.query(name, resource_class) do |response|
|
|
124
|
-
case response
|
|
125
|
-
when RubyDNS::Message
|
|
126
|
-
yield response
|
|
127
|
-
when RubyDNS::ResolutionFailure
|
|
128
|
-
failure!(:ServFail)
|
|
129
|
-
else
|
|
130
|
-
# This shouldn't ever happen, but if it does for some reason we shouldn't hang.
|
|
131
|
-
fail(response)
|
|
132
|
-
end
|
|
133
|
-
end
|
|
134
|
-
else
|
|
135
|
-
failure!(:Refused)
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
true
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
# Respond to the given query with a resource record. The arguments to this
|
|
142
|
-
# function depend on the <tt>resource_class</tt> requested. The last argument
|
|
143
|
-
# can optionally be a hash of options.
|
|
144
|
-
#
|
|
145
|
-
# <tt>options[:resource_class]</tt>:: Override the default <tt>resource_class</tt>
|
|
146
|
-
# <tt>options[:ttl]</tt>:: Specify the TTL for the resource
|
|
147
|
-
# <tt>options[:name]</tt>:: Override the name (question) of the response.
|
|
148
|
-
#
|
|
149
|
-
# for A records:: <tt>respond!("1.2.3.4")</tt>
|
|
150
|
-
# for MX records:: <tt>respond!("mail.blah.com", 10)</tt>
|
|
151
|
-
#
|
|
152
|
-
# This function instantiates the resource class with the supplied arguments, and
|
|
153
|
-
# then passes it to <tt>append!</tt>.
|
|
154
|
-
#
|
|
155
|
-
# See <tt>Resolv::DNS::Resource</tt> for more information about the various
|
|
156
|
-
# <tt>resource_class</tt>s available.
|
|
157
|
-
# http://www.ruby-doc.org/stdlib/libdoc/resolv/rdoc/index.html
|
|
158
|
-
def respond! (*data)
|
|
159
|
-
options = data.last.kind_of?(Hash) ? data.pop : {}
|
|
160
|
-
resource_class = options[:resource_class] || @resource_class
|
|
161
|
-
|
|
162
|
-
if resource_class == nil
|
|
163
|
-
raise ArgumentError, "Could not instantiate resource #{resource_class}!"
|
|
164
|
-
end
|
|
165
|
-
|
|
166
|
-
@server.logger.info "Resource class: #{resource_class.inspect}"
|
|
167
|
-
resource = resource_class.new(*data)
|
|
168
|
-
@server.logger.info "Resource: #{resource.inspect}"
|
|
169
|
-
|
|
170
|
-
append!(resource, options)
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
# Append a given set of resources to the answer. The last argument can
|
|
174
|
-
# optionally be a hash of options.
|
|
175
|
-
#
|
|
176
|
-
# <tt>options[:ttl]</tt>:: Specify the TTL for the resource
|
|
177
|
-
# <tt>options[:name]</tt>:: Override the name (question) of the response.
|
|
178
|
-
# <tt>options[:section]</tt>:: Specify whether the response should go in the `:answer`
|
|
179
|
-
# `:authority` or `:additional` section.
|
|
180
|
-
#
|
|
181
|
-
# This function can be used to supply multiple responses to a given question.
|
|
182
|
-
# For example, each argument is expected to be an instantiated resource from
|
|
183
|
-
# <tt>Resolv::DNS::Resource</tt> module.
|
|
184
|
-
def append! (*resources)
|
|
185
|
-
append_question!
|
|
186
|
-
|
|
187
|
-
if resources.last.kind_of?(Hash)
|
|
188
|
-
options = resources.pop
|
|
189
|
-
else
|
|
190
|
-
options = {}
|
|
191
|
-
end
|
|
192
|
-
|
|
193
|
-
# Use the default options if provided:
|
|
194
|
-
options = options.merge(@options)
|
|
195
|
-
|
|
196
|
-
options[:ttl] ||= 16000
|
|
197
|
-
options[:name] ||= @question.to_s + "."
|
|
198
|
-
|
|
199
|
-
method = ("add_" + (options[:section] || 'answer').to_s).to_sym
|
|
200
|
-
|
|
201
|
-
resources.each do |resource|
|
|
202
|
-
@server.logger.debug "#{method}: #{resource.inspect} #{resource.class::TypeValue} #{resource.class::ClassValue}"
|
|
203
|
-
|
|
204
|
-
@answer.send(method, options[:name], options[:ttl], resource)
|
|
205
|
-
end
|
|
206
|
-
|
|
207
|
-
succeed if @deferred
|
|
208
|
-
|
|
209
|
-
true
|
|
210
|
-
end
|
|
211
|
-
|
|
212
|
-
# This function indicates that there was a failure to resolve the given
|
|
213
|
-
# question. The single argument must be an integer error code, typically
|
|
214
|
-
# given by the constants in <tt>Resolv::DNS::RCode</tt>.
|
|
215
|
-
#
|
|
216
|
-
# The easiest way to use this function it to simply supply a symbol. Here is
|
|
217
|
-
# a list of the most commonly used ones:
|
|
218
|
-
#
|
|
219
|
-
# <tt>:NoError</tt>:: No error occurred.
|
|
220
|
-
# <tt>:FormErr</tt>:: The incoming data was not formatted correctly.
|
|
221
|
-
# <tt>:ServFail</tt>:: The operation caused a server failure (internal error, etc).
|
|
222
|
-
# <tt>:NXDomain</tt>:: Non-eXistant Domain (domain record does not exist).
|
|
223
|
-
# <tt>:NotImp</tt>:: The operation requested is not implemented.
|
|
224
|
-
# <tt>:Refused</tt>:: The operation was refused by the server.
|
|
225
|
-
# <tt>:NotAuth</tt>:: The server is not authoritive for the zone.
|
|
226
|
-
#
|
|
227
|
-
# See http://www.rfc-editor.org/rfc/rfc2929.txt for more information
|
|
228
|
-
# about DNS error codes (specifically, page 3).
|
|
229
|
-
def failure! (rcode)
|
|
230
|
-
append_question!
|
|
231
|
-
|
|
232
|
-
if rcode.kind_of? Symbol
|
|
233
|
-
@answer.rcode = Resolv::DNS::RCode.const_get(rcode)
|
|
234
|
-
else
|
|
235
|
-
@answer.rcode = rcode.to_i
|
|
236
|
-
end
|
|
237
|
-
|
|
238
|
-
# The transaction itself has completed, but contains a failure:
|
|
239
|
-
succeed(rcode) if @deferred
|
|
240
|
-
|
|
241
|
-
true
|
|
242
|
-
end
|
|
243
|
-
|
|
244
|
-
def append_question!
|
|
245
|
-
if @answer.question.size == 0
|
|
246
|
-
@answer.add_question(@question, @resource_class) unless @question_appended
|
|
247
|
-
end
|
|
248
|
-
end
|
|
249
|
-
end
|
|
250
|
-
end
|
data/test/examples/geoip-dns.rb
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
|
|
3
|
-
# Copyright, 2009, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
|
4
|
-
#
|
|
5
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
# of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
# in the Software without restriction, including without limitation the rights
|
|
8
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
# copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
# furnished to do so, subject to the following conditions:
|
|
11
|
-
#
|
|
12
|
-
# The above copyright notice and this permission notice shall be included in
|
|
13
|
-
# all copies or substantial portions of the Software.
|
|
14
|
-
#
|
|
15
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
-
# THE SOFTWARE.
|
|
22
|
-
|
|
23
|
-
require 'rubygems'
|
|
24
|
-
|
|
25
|
-
require 'geoip'
|
|
26
|
-
|
|
27
|
-
require 'rexec'
|
|
28
|
-
require 'rexec/daemon'
|
|
29
|
-
|
|
30
|
-
require 'rubygems'
|
|
31
|
-
require 'rubydns'
|
|
32
|
-
|
|
33
|
-
require 'rubydns/resolver'
|
|
34
|
-
require 'rubydns/system'
|
|
35
|
-
|
|
36
|
-
INTERFACES = [
|
|
37
|
-
[:udp, "0.0.0.0", 5300]
|
|
38
|
-
]
|
|
39
|
-
|
|
40
|
-
# This daemon requires the file downloaded from http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
|
|
41
|
-
# For more information, please see http://www.maxmind.com/en/geolite and http://geoip.rubyforge.org
|
|
42
|
-
|
|
43
|
-
class GeoIPDNSDaemon < RExec::Daemon::Base
|
|
44
|
-
# You can specify a specific directory to use for run-time information (pid, logs, etc):
|
|
45
|
-
# @@base_directory = File.expand_path("../", __FILE__)
|
|
46
|
-
# @@base_directory = "/var"
|
|
47
|
-
|
|
48
|
-
Name = Resolv::DNS::Name
|
|
49
|
-
IN = Resolv::DNS::Resource::IN
|
|
50
|
-
R = RubyDNS::Resolver.new(RubyDNS::System::nameservers)
|
|
51
|
-
GEO = GeoIP.new(File.expand_path('../GeoLiteCountry.dat', __FILE__))
|
|
52
|
-
|
|
53
|
-
def self.run
|
|
54
|
-
RubyDNS::run_server(:listen => INTERFACES) do
|
|
55
|
-
match(//, IN::A) do |transaction|
|
|
56
|
-
location = nil
|
|
57
|
-
peer = transaction.options[:peer]
|
|
58
|
-
|
|
59
|
-
if peer
|
|
60
|
-
logger.debug "Looking up geographic information for peer #{peer}"
|
|
61
|
-
location = GEO.country(peer[0])
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
if location
|
|
65
|
-
logger.debug "Found location #{location}"
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
case location.continent_code
|
|
69
|
-
when "EU"
|
|
70
|
-
transaction.respond!("1.1.1.1")
|
|
71
|
-
when "CN", "JP"
|
|
72
|
-
transaction.respond!("1.1.2.1")
|
|
73
|
-
else
|
|
74
|
-
transaction.respond!("1.1.3.1")
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
# Default DNS handler
|
|
79
|
-
otherwise do |transaction|
|
|
80
|
-
transaction.passthrough!(R)
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
GeoIPDNSDaemon.daemonize
|
data/test/helper.rb
DELETED
data/test/test_daemon.rb
DELETED
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
|
|
3
|
-
# Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
|
4
|
-
#
|
|
5
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
# of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
# in the Software without restriction, including without limitation the rights
|
|
8
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
# copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
# furnished to do so, subject to the following conditions:
|
|
11
|
-
#
|
|
12
|
-
# The above copyright notice and this permission notice shall be included in
|
|
13
|
-
# all copies or substantial portions of the Software.
|
|
14
|
-
#
|
|
15
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
-
# THE SOFTWARE.
|
|
22
|
-
|
|
23
|
-
require 'helper'
|
|
24
|
-
require 'pathname'
|
|
25
|
-
|
|
26
|
-
require 'rubydns'
|
|
27
|
-
require 'rubydns/resolver'
|
|
28
|
-
|
|
29
|
-
require 'rexec'
|
|
30
|
-
require 'rexec/daemon'
|
|
31
|
-
|
|
32
|
-
class BasicTestServer < RExec::Daemon::Base
|
|
33
|
-
SERVER_PORTS = [[:udp, '127.0.0.1', 5350], [:tcp, '127.0.0.1', 5350]]
|
|
34
|
-
|
|
35
|
-
@@base_directory = File.dirname(__FILE__)
|
|
36
|
-
|
|
37
|
-
def self.run
|
|
38
|
-
# Start the RubyDNS server
|
|
39
|
-
RubyDNS::run_server(:listen => SERVER_PORTS) do
|
|
40
|
-
match("test.local", IN::A) do |transaction|
|
|
41
|
-
transaction.respond!("192.168.1.1")
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
match(/foo.*/, IN::A) do |transaction|
|
|
45
|
-
transaction.respond!("192.168.1.2")
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
# Default DNS handler
|
|
49
|
-
otherwise do |transaction|
|
|
50
|
-
transaction.failure!(:NXDomain)
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
class DaemonTest < Test::Unit::TestCase
|
|
57
|
-
def setup
|
|
58
|
-
$stderr.puts "Starting test server..."
|
|
59
|
-
BasicTestServer.start
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def teardown
|
|
63
|
-
$stderr.puts "Stoping test server..."
|
|
64
|
-
BasicTestServer.stop
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def test_basic_dns
|
|
68
|
-
assert_equal :running, RExec::Daemon::ProcessFile.status(BasicTestServer)
|
|
69
|
-
|
|
70
|
-
EventMachine.run do
|
|
71
|
-
resolver = resolver = RubyDNS::Resolver.new(BasicTestServer::SERVER_PORTS)
|
|
72
|
-
|
|
73
|
-
resolver.query("test.local") do |response|
|
|
74
|
-
answer = response.answer.first
|
|
75
|
-
|
|
76
|
-
assert_equal "test.local", answer[0].to_s
|
|
77
|
-
assert_equal "192.168.1.1", answer[2].address.to_s
|
|
78
|
-
|
|
79
|
-
EventMachine.stop
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
def test_pattern_matching
|
|
85
|
-
assert_equal :running, RExec::Daemon::ProcessFile.status(BasicTestServer)
|
|
86
|
-
|
|
87
|
-
EventMachine.run do
|
|
88
|
-
resolver = resolver = RubyDNS::Resolver.new(BasicTestServer::SERVER_PORTS)
|
|
89
|
-
|
|
90
|
-
resolver.query("foobar") do |response|
|
|
91
|
-
answer = response.answer.first
|
|
92
|
-
|
|
93
|
-
assert_equal "foobar", answer[0].to_s
|
|
94
|
-
assert_equal "192.168.1.2", answer[2].address.to_s
|
|
95
|
-
|
|
96
|
-
EventMachine.stop
|
|
97
|
-
end
|
|
98
|
-
end
|
|
99
|
-
end
|
|
100
|
-
end
|
data/test/test_domains.txt
DELETED
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
0.channel18.facebook.com
|
|
2
|
-
2leep.com
|
|
3
|
-
EVIntl-ocsp.verisign.com
|
|
4
|
-
EVSecure-ocsp.verisign.com
|
|
5
|
-
a.tribalfusion.com
|
|
6
|
-
a1059.g.akamai.net
|
|
7
|
-
a126.g.akamai.net
|
|
8
|
-
a1338.g.akamai.net
|
|
9
|
-
a199.gi3.akamai.net
|
|
10
|
-
a248.e.akamai.net
|
|
11
|
-
a696.g.akamai.net
|
|
12
|
-
a803.g.akamai.net
|
|
13
|
-
ad.doubleclick.net
|
|
14
|
-
ad.yieldmanager.com
|
|
15
|
-
ad1.netshelter.net
|
|
16
|
-
ad2.netshelter.net
|
|
17
|
-
address.yahoo.com
|
|
18
|
-
ads.adbrite.com
|
|
19
|
-
ads.trademe.co.nz
|
|
20
|
-
ads.tw.adsonar.com
|
|
21
|
-
ads1.perfadbrite.com.akadns.net
|
|
22
|
-
adsfac.us
|
|
23
|
-
ajax.googleapis.com
|
|
24
|
-
aleccolocco.blogspot.com
|
|
25
|
-
anycast-asia.quantserve.com.akadns.net
|
|
26
|
-
apps.facebook.com
|
|
27
|
-
appspot.l.google.com
|
|
28
|
-
ayako.oriontransfer.org
|
|
29
|
-
b.scorecardresearch.com
|
|
30
|
-
b1.adbrite.com
|
|
31
|
-
backend.deviantart.com
|
|
32
|
-
blog.nominet.org.uk
|
|
33
|
-
c.fsdn.com
|
|
34
|
-
cache-01.cleanprint.net
|
|
35
|
-
clients.l.google.com
|
|
36
|
-
clients1.google.com
|
|
37
|
-
cms.myspacecdn.com
|
|
38
|
-
configuration.apple.com
|
|
39
|
-
d.yimg.com
|
|
40
|
-
d1.openx.org
|
|
41
|
-
data.coremetrics.com
|
|
42
|
-
developer.apple.com
|
|
43
|
-
devimages.apple.com
|
|
44
|
-
dg.specificclick.net
|
|
45
|
-
digg.analytics.live.com
|
|
46
|
-
digg.com
|
|
47
|
-
e.vistaprint.com
|
|
48
|
-
englishrussia.com
|
|
49
|
-
feeds.digg.com
|
|
50
|
-
feeds.dzone.com
|
|
51
|
-
feeds.feedburner.com
|
|
52
|
-
feeds2.feedburner.com
|
|
53
|
-
filetransfer.msg.yahoo.com
|
|
54
|
-
filterforge.com
|
|
55
|
-
financier.oriontransfer.co.nz
|
|
56
|
-
gems.oriontransfer.org
|
|
57
|
-
ghs.l.google.com
|
|
58
|
-
googleads.g.doubleclick.net
|
|
59
|
-
googlemail-pop.l.google.com
|
|
60
|
-
groups.google.com
|
|
61
|
-
hat.bmanpn.com
|
|
62
|
-
hogbaysoftware.appspot.com
|
|
63
|
-
i.creativecommons.org
|
|
64
|
-
id.google.com
|
|
65
|
-
images.apple.com
|
|
66
|
-
images.macrumors.com
|
|
67
|
-
images.trademe.co.nz
|
|
68
|
-
img.slate.com
|
|
69
|
-
js.adsonar.com
|
|
70
|
-
js.revsci.net
|
|
71
|
-
kotaku.com
|
|
72
|
-
l.sharethis.com
|
|
73
|
-
l.yimg.com
|
|
74
|
-
lambda-the-ultimate.org
|
|
75
|
-
login.facebook.com
|
|
76
|
-
login.live.com
|
|
77
|
-
login.messaging.aol.com
|
|
78
|
-
login.oscar.aol.com
|
|
79
|
-
login.yahoo.com
|
|
80
|
-
lus.sharethis.com.akadns.net
|
|
81
|
-
m1.2mdn.net
|
|
82
|
-
mac.com
|
|
83
|
-
mail.google.com
|
|
84
|
-
mail.mac.com
|
|
85
|
-
mail.me.com
|
|
86
|
-
managingosx.wordpress.com
|
|
87
|
-
maps.google.com
|
|
88
|
-
marketing.vistaprint.com
|
|
89
|
-
media.digg.com
|
|
90
|
-
media.washingtonpost.com
|
|
91
|
-
messenger.hotmail.com
|
|
92
|
-
metrics.washingtonpost.com
|
|
93
|
-
metro-amz-lb1-1649407802.us-east-1.elb.amazonaws.com
|
|
94
|
-
mm.chitika.net
|
|
95
|
-
news.ycombinator.com
|
|
96
|
-
o.aolcdn.com
|
|
97
|
-
o.sa.aol.com
|
|
98
|
-
ocsp.verisign.net
|
|
99
|
-
odb.outbrain.com
|
|
100
|
-
omega.contacts.msn.com
|
|
101
|
-
omega.contacts.msn.com.nsatc.net
|
|
102
|
-
pagead2.googlesyndication.com
|
|
103
|
-
partner.googleadservices.com
|
|
104
|
-
partnerad.l.google.com
|
|
105
|
-
pixel.quantserve.com
|
|
106
|
-
pop.googlemail.com
|
|
107
|
-
ps.friendconnect.gmodules.com
|
|
108
|
-
publish.iwork.com
|
|
109
|
-
r1rk9np7bpcsfoeekl0khkd2juj27q3o.friendconnect.gmodules.com
|
|
110
|
-
rad.msn.com
|
|
111
|
-
regretfulmorning.com
|
|
112
|
-
resources.infolinks.com
|
|
113
|
-
rss.lists.apple.com
|
|
114
|
-
rss.slashdot.org
|
|
115
|
-
s24.sitemeter.com
|
|
116
|
-
s26.sitemeter.com
|
|
117
|
-
s7.addthis.com
|
|
118
|
-
safebrowsing-cache.google.com
|
|
119
|
-
safebrowsing.clients.google.com
|
|
120
|
-
scripts.chitika.net
|
|
121
|
-
scsa.msg.yahoo.com
|
|
122
|
-
seal.verisign.com
|
|
123
|
-
sec.westpac.co.nz
|
|
124
|
-
secure-nz.imrworldwide.com
|
|
125
|
-
shared-hosted-1561031087.us-east-1.elb.amazonaws.com
|
|
126
|
-
slashdot.org
|
|
127
|
-
slate.cleanprint.net
|
|
128
|
-
spacemusic.libsyn.com
|
|
129
|
-
ssl-google-analytics.l.google.com
|
|
130
|
-
ssl-hints.netflame.cc
|
|
131
|
-
ssl.google-analytics.com
|
|
132
|
-
static.ak.connect.facebook.com
|
|
133
|
-
static.ak.facebook.com
|
|
134
|
-
static.getclicky.com
|
|
135
|
-
stats.wordpress.com
|
|
136
|
-
syndication.thedailywtf.com
|
|
137
|
-
tags.expo9.exponential.com
|
|
138
|
-
talk.google.com
|
|
139
|
-
time.asia.apple.com
|
|
140
|
-
tools.google.com
|
|
141
|
-
votes.buzz.yahoo.com
|
|
142
|
-
widgets.outbrain.com
|
|
143
|
-
wiki.oriontransfer.org
|
|
144
|
-
www-google-analytics.l.google.com
|
|
145
|
-
www.acquire.co.nz
|
|
146
|
-
www.apple.com
|
|
147
|
-
www.apple.com.akadns.net
|
|
148
|
-
www.applejoe.com
|
|
149
|
-
www.apples.com
|
|
150
|
-
www.ascent.co.nz
|
|
151
|
-
www.bing.com
|
|
152
|
-
www.blogcdn.com
|
|
153
|
-
www.blogger.com
|
|
154
|
-
www.blogsmithmedia.com
|
|
155
|
-
www.co2stats.com
|
|
156
|
-
www.demonoid.com
|
|
157
|
-
www.digg.com
|
|
158
|
-
www.drobostore.com
|
|
159
|
-
www.dzone.com
|
|
160
|
-
www.em6live.co.nz
|
|
161
|
-
www.engadget.com
|
|
162
|
-
www.facebook.com
|
|
163
|
-
www.filterforge.com
|
|
164
|
-
www.friendconnect.gmodules.com
|
|
165
|
-
www.geekologie.com
|
|
166
|
-
www.google-analytics.com
|
|
167
|
-
www.google.com
|
|
168
|
-
www.idevgames.com
|
|
169
|
-
www.iwatchstuff.com
|
|
170
|
-
www.l.google.com
|
|
171
|
-
www.linuxquestions.org
|
|
172
|
-
www.lucidsystems.org
|
|
173
|
-
www.macrumors.com
|
|
174
|
-
www.michael.net.nz
|
|
175
|
-
www.potionfactory.com
|
|
176
|
-
www.recipepuppy.com
|
|
177
|
-
www.slashdot.org
|
|
178
|
-
www.slate.com
|
|
179
|
-
www.sqlite.org
|
|
180
|
-
www.trademe.co.nz
|
|
181
|
-
www.vistaprint.com
|
|
182
|
-
www.washingtonpost.com
|
|
183
|
-
www.westpac.co.nz
|
|
184
|
-
www4.l.google.com
|
|
185
|
-
z.digg.com
|
data/test/test_passthrough.rb
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
|
|
3
|
-
# Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
|
4
|
-
#
|
|
5
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
# of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
# in the Software without restriction, including without limitation the rights
|
|
8
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
# copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
# furnished to do so, subject to the following conditions:
|
|
11
|
-
#
|
|
12
|
-
# The above copyright notice and this permission notice shall be included in
|
|
13
|
-
# all copies or substantial portions of the Software.
|
|
14
|
-
#
|
|
15
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
-
# THE SOFTWARE.
|
|
22
|
-
|
|
23
|
-
require 'helper'
|
|
24
|
-
require 'pathname'
|
|
25
|
-
|
|
26
|
-
require 'rubydns'
|
|
27
|
-
require 'rubydns/resolver'
|
|
28
|
-
|
|
29
|
-
require 'rexec'
|
|
30
|
-
require 'rexec/daemon'
|
|
31
|
-
|
|
32
|
-
class TestPassthroughServer < RExec::Daemon::Base
|
|
33
|
-
SERVER_PORTS = [[:udp, '127.0.0.1', 5340], [:tcp, '127.0.0.1', 5340]]
|
|
34
|
-
|
|
35
|
-
@@base_directory = File.dirname(__FILE__)
|
|
36
|
-
|
|
37
|
-
def self.run
|
|
38
|
-
resolver = RubyDNS::Resolver.new([[:udp, "8.8.8.8", 53], [:tcp, "8.8.8.8", 53]])
|
|
39
|
-
|
|
40
|
-
# Start the RubyDNS server
|
|
41
|
-
RubyDNS::run_server(:listen => SERVER_PORTS) do
|
|
42
|
-
match(/.*\.com/, IN::A) do |transaction|
|
|
43
|
-
transaction.passthrough!(resolver)
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
# Default DNS handler
|
|
47
|
-
otherwise do |transaction|
|
|
48
|
-
transaction.failure!(:NXDomain)
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
class PassthroughTest < Test::Unit::TestCase
|
|
55
|
-
def setup
|
|
56
|
-
TestPassthroughServer.start
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def teardown
|
|
60
|
-
TestPassthroughServer.stop
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def test_basic_dns
|
|
64
|
-
answer = nil
|
|
65
|
-
|
|
66
|
-
assert_equal :running, RExec::Daemon::ProcessFile.status(TestPassthroughServer)
|
|
67
|
-
|
|
68
|
-
EventMachine.run do
|
|
69
|
-
resolver = RubyDNS::Resolver.new(TestPassthroughServer::SERVER_PORTS)
|
|
70
|
-
|
|
71
|
-
resolver.query("google.com") do |response|
|
|
72
|
-
answer = response.answer.first
|
|
73
|
-
|
|
74
|
-
EventMachine.stop
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
assert answer.count > 0
|
|
79
|
-
end
|
|
80
|
-
end
|