celluloid-dns 0.0.1 → 0.17.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +0 -2
  3. data/.simplecov +15 -0
  4. data/.travis.yml +13 -7
  5. data/Gemfile +5 -6
  6. data/README.md +118 -41
  7. data/Rakefile +8 -3
  8. data/celluloid-dns.gemspec +29 -18
  9. data/lib/celluloid/dns.rb +30 -7
  10. data/lib/celluloid/dns/chunked.rb +34 -0
  11. data/lib/celluloid/dns/extensions/resolv.rb +136 -0
  12. data/lib/celluloid/dns/extensions/string.rb +28 -0
  13. data/lib/celluloid/dns/handler.rb +198 -0
  14. data/lib/celluloid/dns/logger.rb +31 -0
  15. data/lib/celluloid/dns/message.rb +76 -0
  16. data/lib/celluloid/dns/replace.rb +54 -0
  17. data/lib/celluloid/dns/resolver.rb +288 -0
  18. data/lib/celluloid/dns/server.rb +151 -27
  19. data/lib/celluloid/dns/system.rb +146 -0
  20. data/lib/celluloid/dns/transaction.rb +202 -0
  21. data/lib/celluloid/dns/transport.rb +75 -0
  22. data/lib/celluloid/dns/version.rb +23 -3
  23. data/spec/celluloid/dns/celluloid_bug_spec.rb +92 -0
  24. data/spec/celluloid/dns/hosts.txt +2 -0
  25. data/spec/celluloid/dns/ipv6_spec.rb +70 -0
  26. data/spec/celluloid/dns/message_spec.rb +56 -0
  27. data/spec/celluloid/dns/origin_spec.rb +106 -0
  28. data/spec/celluloid/dns/replace_spec.rb +42 -0
  29. data/spec/celluloid/dns/resolver_performance_spec.rb +110 -0
  30. data/spec/celluloid/dns/resolver_spec.rb +152 -0
  31. data/spec/celluloid/dns/server/bind9/generate-local.rb +25 -0
  32. data/spec/celluloid/dns/server/bind9/local.zone +5014 -0
  33. data/spec/celluloid/dns/server/bind9/named.conf +14 -0
  34. data/spec/celluloid/dns/server/bind9/named.run +0 -0
  35. data/spec/celluloid/dns/server/million.rb +85 -0
  36. data/spec/celluloid/dns/server_performance_spec.rb +139 -0
  37. data/spec/celluloid/dns/slow_server_spec.rb +91 -0
  38. data/spec/celluloid/dns/socket_spec.rb +71 -0
  39. data/spec/celluloid/dns/system_spec.rb +60 -0
  40. data/spec/celluloid/dns/transaction_spec.rb +138 -0
  41. data/spec/celluloid/dns/truncation_spec.rb +62 -0
  42. metadata +124 -56
  43. data/.coveralls.yml +0 -1
  44. data/.gitignore +0 -17
  45. data/CHANGES.md +0 -3
  46. data/LICENSE.txt +0 -22
  47. data/lib/celluloid/dns/request.rb +0 -46
  48. data/spec/celluloid/dns/server_spec.rb +0 -26
  49. data/spec/spec_helper.rb +0 -5
  50. data/tasks/rspec.task +0 -7
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 29e1cad84a40b70653b74e2e83c6b5689bae12c1
4
+ data.tar.gz: 81a1d5628a6a87f5287ac28d0da32f58fe536cb2
5
+ SHA512:
6
+ metadata.gz: bb292adfcede83a136d78469e948ecc22dd89c247d5ceed0ecdcd9a05124aa48d15066f787152ce5abcc4b9e2b29aa693b560698005894710397db43abd348ab
7
+ data.tar.gz: ecd62d8c8265e14a7bca932f48c7ce759c5711a071e5b971973d1212aa98b399abc619be511cb4283f8375105a12ebf9eb483fa704f3b7dfa656d41eeb7e9066
data/.rspec CHANGED
@@ -1,4 +1,2 @@
1
1
  --color
2
2
  --format documentation
3
- --backtrace
4
- --default_path spec
@@ -0,0 +1,15 @@
1
+
2
+ SimpleCov.start do
3
+ add_filter "/spec/"
4
+ end
5
+
6
+ # Work correctly across forks:
7
+ pid = Process.pid
8
+ SimpleCov.at_exit do
9
+ SimpleCov.result.format! if Process.pid == pid
10
+ end
11
+
12
+ if ENV['TRAVIS']
13
+ require 'coveralls'
14
+ Coveralls.wear!
15
+ end
@@ -1,16 +1,22 @@
1
+ language: ruby
2
+ sudo: false
3
+ addons:
4
+ apt:
5
+ packages:
6
+ - bind9
1
7
  rvm:
2
- - 1.9.3
3
8
  - 2.0.0
9
+ - 2.1.8
10
+ - 2.2.4
11
+ - 2.3.0
12
+ - rbx-2
4
13
  - ruby-head
5
- - jruby-19mode
6
14
  - jruby-head
7
- - rbx-19mode
8
-
9
15
  matrix:
10
16
  allow_failures:
17
+ - rvm: rbx-2
11
18
  - rvm: ruby-head
12
19
  - rvm: jruby-head
13
- - rvm: rbx-19mode # deadlocks :(
14
-
20
+ env: COVERAGE=true
15
21
  notifications:
16
- irc: "irc.freenode.org#celluloid"
22
+ irc: "irc.freenode.org#celluloid"
data/Gemfile CHANGED
@@ -1,9 +1,8 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'celluloid', github: 'celluloid/celluloid'
4
- gem 'celluloid-io', github: 'celluloid/celluloid-io'
5
-
6
- gem 'coveralls', require: false
7
-
8
- # Specify your gem's dependencies in celluloid-dns.gemspec
9
3
  gemspec
4
+
5
+ group :test do
6
+ gem 'simplecov'
7
+ gem 'coveralls', require: false
8
+ end
data/README.md CHANGED
@@ -1,69 +1,146 @@
1
1
  ![Celluloid::DNS](https://github.com/celluloid/celluloid-dns/raw/master/logo.png)
2
- =================
3
- [![Build Status](https://secure.travis-ci.org/celluloid/celluloid-dns.png?branch=master)](http://travis-ci.org/celluloid/celluloid-dns)
4
- [![Dependency Status](https://gemnasium.com/celluloid/celluloid-dns.png)](https://gemnasium.com/celluloid/celluloid-dns)
5
- [![Code Climate](https://codeclimate.com/github/celluloid/celluloid-dns.png)](https://codeclimate.com/github/celluloid/celluloid-dns)
6
- [![Coverage Status](https://coveralls.io/repos/celluloid/celluloid-dns/badge.png?branch=master)](https://coveralls.io/r/celluloid/celluloid-dns)
7
2
 
8
- Celluloid::DNS is a programmable Celluloid "cell" for answering DNS requests.
9
- It's implemented using Celluloid::IO and is great for programatic DNS servers
10
- which dynamically generate DNS responses, particularly within Celluloid-based
11
- programs.
3
+ Celluloid::DNS is a high-performance DNS client resolver and server which can be easily integrated into other projects or used as a stand-alone daemon. It was forked from [RubyDNS][1] which is now implemented in terms of this library.
12
4
 
13
- A nonblocking DNS client is already built into Celluloid::IO itself.
14
- Celluloid::DNS is just for servers.
5
+ [1]: https://github.com/ioquatix/rubydns
15
6
 
16
- Installation
17
- ------------
7
+ [![Gem Version](https://badge.fury.io/rb/celluloid-dns.svg)](http://rubygems.org/gems/celluloid-dns)
8
+ [![Build Status](https://secure.travis-ci.org/celluloid/celluloid-dns.svg?branch=master)](http://travis-ci.org/celluloid/celluloid-dns)
9
+ [![Dependency Status](https://gemnasium.com/celluloid/celluloid-dns.svg)](https://gemnasium.com/celluloid/celluloid-dns)
10
+ [![Code Climate](https://codeclimate.com/github/celluloid/celluloid-dns.svg)](https://codeclimate.com/github/celluloid/celluloid-dns)
11
+ [![Coverage Status](https://coveralls.io/repos/celluloid/celluloid-dns/badge.svg?branch=master)](https://coveralls.io/r/celluloid/celluloid-dns)
12
+
13
+ ## Installation
18
14
 
19
15
  Add this line to your application's Gemfile:
20
16
 
21
- gem 'celluloid-dns'
17
+ gem 'celluloid-dns'
22
18
 
23
19
  And then execute:
24
20
 
25
- $ bundle
21
+ $ bundle
26
22
 
27
23
  Or install it yourself as:
28
24
 
29
- $ gem install celluloid-dns
25
+ $ gem install celluloid-dns
26
+
27
+ ## Usage
28
+
29
+ ### Resolver
30
+
31
+ Here is a simple example showing how to use the resolver:
32
+
33
+ resolver = Celluloid::DNS::Resolver.new([[:udp, "8.8.8.8", 53], [:tcp, "8.8.8.8", 53]])
34
+
35
+ addresses = resolver.addresses_for("www.google.com.")
36
+
37
+ expect(addresses.size).to be > 0
38
+
39
+ addresses.each do |address|
40
+ expect(address).to be_kind_of(Resolv::IPv4) | be_kind_of(Resolv::IPv6)
41
+ end
42
+
43
+ ### Server
44
+
45
+ Here is a simple example showing how to use the server:
46
+
47
+ class TestServer < Celluloid::DNS::Server
48
+ def process(name, resource_class, transaction)
49
+ @resolver ||= Celluloid::DNS::Resolver.new([[:udp, "8.8.8.8", 53], [:tcp, "8.8.8.8", 53]])
50
+
51
+ transaction.passthrough!(@resolver)
52
+ end
53
+ end
54
+
55
+ server = TestServer.new(listen: [[:udp, 'localhost', 2346]])
56
+ server.run
57
+
58
+ sleep
59
+
60
+ Then to test you could use `dig` like so:
61
+
62
+ dig @localhost -p 2346 google.com
63
+
64
+ ## FAQ
65
+
66
+ ### File Handle Limitations
67
+
68
+ I get the error `Errno::EMFILE: Too many open files - socket(2) - udp` when trying to run a server. What should I do?
69
+
70
+ On some platforms (e.g. Mac OS X) the number of file descriptors is relatively low by default and should be increased by calling `ulimit -n 10000` before running tests or even before starting a server which expects a large number of concurrent incoming connections.
71
+
72
+ ### Server
73
+
74
+ The performance is on the same magnitude as `bind9`. Some basic benchmarks resolving 1000 names concurrently, repeated 5 times, using `Celluloid::DNS::Resolver` gives the following:
75
+
76
+ user system total real
77
+ Celluloid::DNS::Server 4.280000 0.450000 4.730000 ( 4.854862)
78
+ Bind9 4.970000 0.520000 5.490000 ( 5.541213)
79
+
80
+ These benchmarks are included in the unit tests. To test bind9 performance, it must be installed and `which named` must return the executable.
81
+
82
+
83
+ ## Performance
84
+
85
+ We welcome additional benchmarks and feedback regarding Celluloid::DNS performance. To check the current performance results, consult the [travis build job output](https://travis-ci.org/celluloid/celluloid-dns).
86
+
87
+ ### Resolver
88
+
89
+ The `Celluloid::DNS::Resolver` is highly concurrent and can resolve individual names as fast as the built in `Resolv::DNS` resolver. Because the resolver is asynchronous, when dealing with multiple names, it can work more efficiently:
90
+
91
+ user system total real
92
+ Celluloid::DNS::Resolver 0.020000 0.010000 0.030000 ( 0.030507)
93
+ Resolv::DNS 0.070000 0.010000 0.080000 ( 1.465975)
94
+
95
+ These benchmarks are included in the unit tests.
96
+
97
+ ### Server
30
98
 
31
- Inside of your Ruby project, use:
99
+ The performance is on the same magnitude as `bind9`. Some basic benchmarks resolving 1000 names concurrently, repeated 5 times, using `Celluloid::DNS::Resolver` gives the following:
32
100
 
33
- require 'celluloid/dns'
101
+ user system total real
102
+ Celluloid::DNS::Server 4.280000 0.450000 4.730000 ( 4.854862)
103
+ Bind9 4.970000 0.520000 5.490000 ( 5.541213)
34
104
 
35
- ...to pull Celluloid::DNS in as a dependency.
105
+ These benchmarks are included in the unit tests. To test bind9 performance, it must be installed and `which named` must return the executable.
36
106
 
37
- Usage
38
- -----
107
+ ### DNSSEC support
39
108
 
40
- Start a DNS server that always resolves to `127.0.0.1`:
109
+ DNSSEC is currently not supported and is [unlikely to be supported in the future](http://sockpuppet.org/blog/2015/01/15/against-dnssec/). Feel free to submit a PR.
41
110
 
42
- ```ruby
43
- require "celluloid/dns"
111
+ ## Contributing
44
112
 
45
- Celluloid::DNS::Server.new("127.0.0.1", 1234) do |request|
46
- request.answer request.questions.map { |q| [q, "127.0.0.1"] }
47
- end
113
+ 1. Fork it
114
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
115
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
116
+ 4. Push to the branch (`git push origin my-new-feature`)
117
+ 5. Create new Pull Request
48
118
 
49
- sleep
50
- ```
119
+ ### Desired Features
51
120
 
52
- Query the server:
121
+ * Support for more features of DNS such as zone transfer.
122
+ * Some kind of system level integration, e.g. registering a DNS server with the currently running system resolver.
53
123
 
54
- $ dig @localhost -p 1234 anything.com
124
+ ## License
55
125
 
126
+ Released under the MIT license.
56
127
 
57
- Contributing to Celluloid::DNS
58
- ------------------------------
128
+ Copyright, 2015, by [Samuel G. D. Williams](http://www.codeotaku.com/samuel-williams).
59
129
 
60
- * Fork this repository on github
61
- * Make your changes and send me a pull request
62
- * If I like them I'll merge them
63
- * If I've accepted a patch, feel free to ask for commit access
130
+ Permission is hereby granted, free of charge, to any person obtaining a copy
131
+ of this software and associated documentation files (the "Software"), to deal
132
+ in the Software without restriction, including without limitation the rights
133
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
134
+ copies of the Software, and to permit persons to whom the Software is
135
+ furnished to do so, subject to the following conditions:
64
136
 
65
- License
66
- -------
137
+ The above copyright notice and this permission notice shall be included in
138
+ all copies or substantial portions of the Software.
67
139
 
68
- Copyright (c) 2012 Tony Arcieri. Distributed under the MIT License. See
69
- LICENSE.txt for further details.
140
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
141
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
142
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
143
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
144
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
145
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
146
+ THE SOFTWARE.
data/Rakefile CHANGED
@@ -1,5 +1,10 @@
1
- #!/usr/bin/env rake
2
1
  require "bundler/gem_tasks"
3
- Dir["tasks/**/*.task"].each { |task| load task }
2
+ require "rspec/core/rake_task"
4
3
 
5
- task :default => :spec
4
+ RSpec::Core::RakeTask.new(:spec) do |task|
5
+ task.rspec_opts = ["--require", "simplecov"] if ENV['COVERAGE']
6
+ end
7
+
8
+ task :default => :spec
9
+
10
+ require 'celluloid/current'
@@ -1,23 +1,34 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
  require File.expand_path('../lib/celluloid/dns/version', __FILE__)
3
3
 
4
- Gem::Specification.new do |gem|
5
- gem.authors = ["Tony Arcieri"]
6
- gem.email = ["tony.arcieri@gmail.com"]
7
- gem.description = "Celluloid::IO-powered DNS server"
8
- gem.summary = "Celluloid::DNS provides a DNS server implemented as a Celluloid cell"
9
- gem.homepage = "https://github.com/celluloid/celluloid-dns"
4
+ Gem::Specification.new do |spec|
5
+ spec.name = "celluloid-dns"
6
+ spec.version = Celluloid::DNS::VERSION
7
+ spec.authors = ["Samuel Williams"]
8
+ spec.email = ["samuel.williams@oriontransfer.co.nz"]
9
+ spec.description = <<-EOF
10
+ Celluloid::DNS provides a high-performance DNS client resolver and server
11
+ which can be easily integrated into other projects or used as a stand-alone
12
+ daemon.
13
+ EOF
14
+ spec.summary = "An easy to use DNS client resolver and server for Ruby."
15
+ spec.homepage = "https://github.com/celluloid/celluloid-dns"
16
+ spec.license = "MIT"
10
17
 
11
- gem.files = `git ls-files`.split($\)
12
- gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
- gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
- gem.name = "celluloid-dns"
15
- gem.require_paths = ["lib"]
16
- gem.version = Celluloid::DNS::VERSION
17
-
18
- gem.add_runtime_dependency 'celluloid', '>= 0.11.0'
19
- gem.add_runtime_dependency 'celluloid-io', '>= 0.11.0'
20
-
21
- gem.add_development_dependency 'rake'
22
- gem.add_development_dependency 'rspec'
18
+ spec.files = `git ls-files`.split($/)
19
+ spec.executables = spec.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
20
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
21
+ spec.require_paths = ["lib"]
22
+ spec.has_rdoc = "yard"
23
+
24
+ spec.required_ruby_version = '>= 2.0.0'
25
+
26
+ spec.add_dependency("celluloid", "~> 0.17.3")
27
+ spec.add_dependency("celluloid-io", "~> 0.17.3")
28
+ spec.add_dependency("timers", "~> 4.1.0")
29
+
30
+ spec.add_development_dependency "bundler", "~> 1.3"
31
+ spec.add_development_dependency "process-daemon", "~> 1.0.0"
32
+ spec.add_development_dependency "rspec", "~> 3.4.0"
33
+ spec.add_development_dependency "rake"
23
34
  end
@@ -1,12 +1,35 @@
1
- require 'celluloid/dns/version'
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 'celluloid/current'
2
22
  require 'celluloid/io'
3
23
 
4
- require 'celluloid/dns/request'
5
- require 'celluloid/dns/server'
24
+ require_relative 'dns/version'
25
+
26
+ require_relative 'dns/message'
27
+ require_relative 'dns/server'
28
+ require_relative 'dns/resolver'
29
+ require_relative 'dns/handler'
30
+ require_relative 'dns/logger'
6
31
 
7
32
  module Celluloid
8
- module DNS
9
- # Default time-to-live for DNS responses
10
- DEFAULT_TTL = 900
11
- end
33
+ module DNS
34
+ end
12
35
  end
@@ -0,0 +1,34 @@
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
+ module Celluloid::DNS
22
+ # Produces an array of arrays of binary data with each sub-array a maximum of chunk_size bytes.
23
+ def self.chunked(string, chunk_size = 255)
24
+ chunks = []
25
+
26
+ offset = 0
27
+ while offset < string.bytesize
28
+ chunks << string.byteslice(offset, chunk_size)
29
+ offset += chunk_size
30
+ end
31
+
32
+ return chunks
33
+ end
34
+ end
@@ -0,0 +1,136 @@
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 'resolv'
22
+
23
+ class Resolv
24
+ class DNS
25
+ class Message
26
+ # Merge the given message with this message. A number of heuristics are applied in order to ensure that the result makes sense. For example, If the current message is not recursive but is being merged with a message that was recursive, this bit is maintained. If either message is authoritive, then the result is also authoritive.
27
+ #
28
+ # Modifies the current message in place.
29
+ def merge! (other)
30
+ # Authoritive Answer
31
+ @aa = @aa && other.aa
32
+
33
+ @question += other.question
34
+ @answer += other.answer
35
+ @authority += other.authority
36
+ @additional += other.additional
37
+
38
+ # Recursion Available
39
+ @ra = @ra || other.ra
40
+
41
+ # Result Code (Error Code)
42
+ @rcode = other.rcode unless other.rcode == 0
43
+
44
+ # Recursion Desired
45
+ @rd = @rd || other.rd
46
+ end
47
+ end
48
+
49
+ class OriginError < ArgumentError
50
+ end
51
+
52
+ class Name
53
+ def to_s
54
+ "#{@labels.join('.')}#{@absolute ? '.' : ''}"
55
+ end
56
+
57
+ def inspect
58
+ "#<#{self.class}: #{self.to_s}>"
59
+ end
60
+
61
+ # Return the name, typically absolute, with the specified origin as a suffix. If the origin is nil, don't change the name, but change it to absolute (as specified).
62
+ def with_origin(origin, absolute = true)
63
+ return self.class.new(@labels, absolute) if origin == nil
64
+
65
+ origin = Label.split(origin) if String === origin
66
+
67
+ return self.class.new(@labels + origin, absolute)
68
+ end
69
+
70
+
71
+ # Return the name, typically relative, without the specified origin suffix. If the origin is nil, don't change the name, but change it to absolute (as specified).
72
+ def without_origin(origin, absolute = false)
73
+ return self.class.new(@labels, absolute) if origin == nil
74
+
75
+ origin = Label.split(origin) if String === origin
76
+
77
+ if @labels.last(origin.length) == origin
78
+ return self.class.new(@labels.first(@labels.length - origin.length), absolute)
79
+ else
80
+ raise OriginError.new("#{self} does not end with #{origin.join('.')}")
81
+ end
82
+ end
83
+ end
84
+ end
85
+
86
+ if RUBY_VERSION == "2.3.0"
87
+ # Clearly, the Ruby 2.3.0 release was throughly tested.
88
+ class IPv6
89
+ def self.create(arg)
90
+ case arg
91
+ when IPv6
92
+ return arg
93
+ when String
94
+ address = ''.b
95
+ if Regex_8Hex =~ arg
96
+ arg.scan(/[0-9A-Fa-f]+/) {|hex| address << [hex.hex].pack('n')}
97
+ elsif Regex_CompressedHex =~ arg
98
+ prefix = $1
99
+ suffix = $2
100
+ a1 = ''.b
101
+ a2 = ''.b
102
+ prefix.scan(/[0-9A-Fa-f]+/) {|hex| a1 << [hex.hex].pack('n')}
103
+ suffix.scan(/[0-9A-Fa-f]+/) {|hex| a2 << [hex.hex].pack('n')}
104
+ omitlen = 16 - a1.length - a2.length
105
+ address << a1 << "\0" * omitlen << a2
106
+ elsif Regex_6Hex4Dec =~ arg
107
+ prefix, a, b, c, d = $1, $2.to_i, $3.to_i, $4.to_i, $5.to_i
108
+ if (0..255) === a && (0..255) === b && (0..255) === c && (0..255) === d
109
+ prefix.scan(/[0-9A-Fa-f]+/) {|hex| address << [hex.hex].pack('n')}
110
+ address << [a, b, c, d].pack('CCCC')
111
+ else
112
+ raise ArgumentError.new("not numeric IPv6 address: " + arg)
113
+ end
114
+ elsif Regex_CompressedHex4Dec =~ arg
115
+ prefix, suffix, a, b, c, d = $1, $2, $3.to_i, $4.to_i, $5.to_i, $6.to_i
116
+ if (0..255) === a && (0..255) === b && (0..255) === c && (0..255) === d
117
+ a1 = ''.b
118
+ a2 = ''.b
119
+ prefix.scan(/[0-9A-Fa-f]+/) {|hex| a1 << [hex.hex].pack('n')}
120
+ suffix.scan(/[0-9A-Fa-f]+/) {|hex| a2 << [hex.hex].pack('n')}
121
+ omitlen = 12 - a1.length - a2.length
122
+ address << a1 << "\0" * omitlen << a2 << [a, b, c, d].pack('CCCC')
123
+ else
124
+ raise ArgumentError.new("not numeric IPv6 address: " + arg)
125
+ end
126
+ else
127
+ raise ArgumentError.new("not numeric IPv6 address: " + arg)
128
+ end
129
+ return IPv6.new(address)
130
+ else
131
+ raise ArgumentError.new("cannot interpret as IPv6 address: #{arg.inspect}")
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end