celluloid-dns 0.0.1 → 0.17.3

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.
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