rrs 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.standard.yml +3 -0
- data/README.md +31 -0
- data/Rakefile +6 -0
- data/lib/rrs/a.rb +26 -0
- data/lib/rrs/inflector.rb +13 -0
- data/lib/rrs/ipv4.rb +69 -0
- data/lib/rrs/ipv6.rb +154 -0
- data/lib/rrs.rb +15 -0
- data/sig/rrs.rbs +4 -0
- metadata +55 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c0d9733af6339a12ce11ff22d41f27142c86f16b46755c9b12c671f9a851fa6e
|
4
|
+
data.tar.gz: a3df3377fa1a8f10e93281536fb4ccdcfc1cdd2bf19ab3bf5ce8e2840f575a60
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f8ab7a7e7b4d8046101570b92a1ac8e7e07fd55100a3d43f4287b6c48ad317e5f13c07ccd80c743a6cd46a624d21dd82f5f27c993ea90430f79ace1e0b790f21
|
7
|
+
data.tar.gz: 6e2479f8d855d39afb625f61699501ec4d2d00c7d177d2f950d63dc845c260e0a6a02b6daf37e8f1e5fdb9b73b51357d9e58f735ddc3b35599025674b4688317
|
data/.standard.yml
ADDED
data/README.md
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# RRs
|
2
|
+
|
3
|
+
TODO: Delete this and the text below, and describe your gem
|
4
|
+
|
5
|
+
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/rrs`. To experiment with that code, run `bin/console` for an interactive prompt.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
TODO: Replace `UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG` with your gem name right after releasing it to RubyGems.org. Please do not do it earlier due to security reasons. Alternatively, replace this section with instructions to install your gem from git if you don't plan to release to RubyGems.org.
|
10
|
+
|
11
|
+
Install the gem and add to the application's Gemfile by executing:
|
12
|
+
|
13
|
+
$ bundle add UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
|
14
|
+
|
15
|
+
If bundler is not being used to manage dependencies, install the gem by executing:
|
16
|
+
|
17
|
+
$ gem install UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Development
|
24
|
+
|
25
|
+
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
26
|
+
|
27
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
28
|
+
|
29
|
+
## Contributing
|
30
|
+
|
31
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/rrs.
|
data/Rakefile
ADDED
data/lib/rrs/a.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
module RRs
|
2
|
+
class A
|
3
|
+
TypeValue = 1
|
4
|
+
ClassValue = 1
|
5
|
+
|
6
|
+
##
|
7
|
+
# Creates a new A for +address+.
|
8
|
+
|
9
|
+
def initialize(address)
|
10
|
+
@address = IPv4.create(address)
|
11
|
+
end
|
12
|
+
|
13
|
+
##
|
14
|
+
# The IPv4 address for this A.
|
15
|
+
|
16
|
+
attr_reader :address
|
17
|
+
|
18
|
+
def encode_rdata(msg) # :nodoc:
|
19
|
+
msg.put_bytes(@address.address)
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.decode_rdata(msg) # :nodoc:
|
23
|
+
return self.new(IPv4.new(msg.get_bytes(4)))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/rrs/ipv4.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
module RRs
|
2
|
+
class IPv4
|
3
|
+
|
4
|
+
##
|
5
|
+
# Regular expression IPv4 addresses must match.
|
6
|
+
|
7
|
+
Regex256 = /0
|
8
|
+
|1(?:[0-9][0-9]?)?
|
9
|
+
|2(?:[0-4][0-9]?|5[0-5]?|[6-9])?
|
10
|
+
|[3-9][0-9]?/x
|
11
|
+
Regex = /\A(#{Regex256})\.(#{Regex256})\.(#{Regex256})\.(#{Regex256})\z/
|
12
|
+
|
13
|
+
def self.create(arg)
|
14
|
+
case arg
|
15
|
+
when IPv4
|
16
|
+
return arg
|
17
|
+
when Regex
|
18
|
+
if (0..255) === (a = $1.to_i) &&
|
19
|
+
(0..255) === (b = $2.to_i) &&
|
20
|
+
(0..255) === (c = $3.to_i) &&
|
21
|
+
(0..255) === (d = $4.to_i)
|
22
|
+
return self.new([a, b, c, d].pack("CCCC"))
|
23
|
+
else
|
24
|
+
raise ArgumentError.new("IPv4 address with invalid value: " + arg)
|
25
|
+
end
|
26
|
+
else
|
27
|
+
raise ArgumentError.new("cannot interpret as IPv4 address: #{arg.inspect}")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def initialize(address) # :nodoc:
|
32
|
+
unless address.kind_of?(String)
|
33
|
+
raise ArgumentError, 'IPv4 address must be a string'
|
34
|
+
end
|
35
|
+
unless address.length == 4
|
36
|
+
raise ArgumentError, "IPv4 address expects 4 bytes but #{address.length} bytes"
|
37
|
+
end
|
38
|
+
@address = address
|
39
|
+
end
|
40
|
+
|
41
|
+
##
|
42
|
+
# A String representation of this IPv4 address.
|
43
|
+
|
44
|
+
##
|
45
|
+
# The raw IPv4 address as a String.
|
46
|
+
|
47
|
+
attr_reader :address
|
48
|
+
|
49
|
+
def to_s # :nodoc:
|
50
|
+
return sprintf("%d.%d.%d.%d", *@address.unpack("CCCC"))
|
51
|
+
end
|
52
|
+
|
53
|
+
def inspect # :nodoc:
|
54
|
+
return "#<#{self.class} #{self}>"
|
55
|
+
end
|
56
|
+
|
57
|
+
def ==(other) # :nodoc:
|
58
|
+
return @address == other.address
|
59
|
+
end
|
60
|
+
|
61
|
+
def eql?(other) # :nodoc:
|
62
|
+
return self == other
|
63
|
+
end
|
64
|
+
|
65
|
+
def hash # :nodoc:
|
66
|
+
return @address.hash
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/lib/rrs/ipv6.rb
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
module RRs
|
2
|
+
class IPv6
|
3
|
+
|
4
|
+
##
|
5
|
+
# IPv6 address format a:b:c:d:e:f:g:h
|
6
|
+
Regex_8Hex = /\A
|
7
|
+
(?:[0-9A-Fa-f]{1,4}:){7}
|
8
|
+
[0-9A-Fa-f]{1,4}
|
9
|
+
\z/x
|
10
|
+
|
11
|
+
##
|
12
|
+
# Compressed IPv6 address format a::b
|
13
|
+
|
14
|
+
Regex_CompressedHex = /\A
|
15
|
+
((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?) ::
|
16
|
+
((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)
|
17
|
+
\z/x
|
18
|
+
|
19
|
+
##
|
20
|
+
# IPv4 mapped IPv6 address format a:b:c:d:e:f:w.x.y.z
|
21
|
+
|
22
|
+
Regex_6Hex4Dec = /\A
|
23
|
+
((?:[0-9A-Fa-f]{1,4}:){6,6})
|
24
|
+
(\d+)\.(\d+)\.(\d+)\.(\d+)
|
25
|
+
\z/x
|
26
|
+
|
27
|
+
##
|
28
|
+
# Compressed IPv4 mapped IPv6 address format a::b:w.x.y.z
|
29
|
+
|
30
|
+
Regex_CompressedHex4Dec = /\A
|
31
|
+
((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?) ::
|
32
|
+
((?:[0-9A-Fa-f]{1,4}:)*)
|
33
|
+
(\d+)\.(\d+)\.(\d+)\.(\d+)
|
34
|
+
\z/x
|
35
|
+
|
36
|
+
##
|
37
|
+
# IPv6 link local address format fe80:b:c:d:e:f:g:h%em1
|
38
|
+
Regex_8HexLinkLocal = /\A
|
39
|
+
[Ff][Ee]80
|
40
|
+
(?::[0-9A-Fa-f]{1,4}){7}
|
41
|
+
%[-0-9A-Za-z._~]+
|
42
|
+
\z/x
|
43
|
+
|
44
|
+
##
|
45
|
+
# Compressed IPv6 link local address format fe80::b%em1
|
46
|
+
|
47
|
+
Regex_CompressedHexLinkLocal = /\A
|
48
|
+
[Ff][Ee]80:
|
49
|
+
(?:
|
50
|
+
((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?) ::
|
51
|
+
((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)
|
52
|
+
|
|
53
|
+
:((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)
|
54
|
+
)?
|
55
|
+
:[0-9A-Fa-f]{1,4}%[-0-9A-Za-z._~]+
|
56
|
+
\z/x
|
57
|
+
|
58
|
+
##
|
59
|
+
# A composite IPv6 address Regexp.
|
60
|
+
|
61
|
+
Regex = /
|
62
|
+
(?:#{Regex_8Hex}) |
|
63
|
+
(?:#{Regex_CompressedHex}) |
|
64
|
+
(?:#{Regex_6Hex4Dec}) |
|
65
|
+
(?:#{Regex_CompressedHex4Dec}) |
|
66
|
+
(?:#{Regex_8HexLinkLocal}) |
|
67
|
+
(?:#{Regex_CompressedHexLinkLocal})
|
68
|
+
/x
|
69
|
+
|
70
|
+
##
|
71
|
+
# Creates a new IPv6 address from +arg+ which may be:
|
72
|
+
#
|
73
|
+
# IPv6:: returns +arg+.
|
74
|
+
# String:: +arg+ must match one of the IPv6::Regex* constants
|
75
|
+
|
76
|
+
def self.create(arg)
|
77
|
+
case arg
|
78
|
+
when IPv6
|
79
|
+
return arg
|
80
|
+
when String
|
81
|
+
address = ''.b
|
82
|
+
if Regex_8Hex =~ arg
|
83
|
+
arg.scan(/[0-9A-Fa-f]+/) {|hex| address << [hex.hex].pack('n')}
|
84
|
+
elsif Regex_CompressedHex =~ arg
|
85
|
+
prefix = $1
|
86
|
+
suffix = $2
|
87
|
+
a1 = ''.b
|
88
|
+
a2 = ''.b
|
89
|
+
prefix.scan(/[0-9A-Fa-f]+/) {|hex| a1 << [hex.hex].pack('n')}
|
90
|
+
suffix.scan(/[0-9A-Fa-f]+/) {|hex| a2 << [hex.hex].pack('n')}
|
91
|
+
omitlen = 16 - a1.length - a2.length
|
92
|
+
address << a1 << "\0" * omitlen << a2
|
93
|
+
elsif Regex_6Hex4Dec =~ arg
|
94
|
+
prefix, a, b, c, d = $1, $2.to_i, $3.to_i, $4.to_i, $5.to_i
|
95
|
+
if (0..255) === a && (0..255) === b && (0..255) === c && (0..255) === d
|
96
|
+
prefix.scan(/[0-9A-Fa-f]+/) {|hex| address << [hex.hex].pack('n')}
|
97
|
+
address << [a, b, c, d].pack('CCCC')
|
98
|
+
else
|
99
|
+
raise ArgumentError.new("not numeric IPv6 address: " + arg)
|
100
|
+
end
|
101
|
+
elsif Regex_CompressedHex4Dec =~ arg
|
102
|
+
prefix, suffix, a, b, c, d = $1, $2, $3.to_i, $4.to_i, $5.to_i, $6.to_i
|
103
|
+
if (0..255) === a && (0..255) === b && (0..255) === c && (0..255) === d
|
104
|
+
a1 = ''.b
|
105
|
+
a2 = ''.b
|
106
|
+
prefix.scan(/[0-9A-Fa-f]+/) {|hex| a1 << [hex.hex].pack('n')}
|
107
|
+
suffix.scan(/[0-9A-Fa-f]+/) {|hex| a2 << [hex.hex].pack('n')}
|
108
|
+
omitlen = 12 - a1.length - a2.length
|
109
|
+
address << a1 << "\0" * omitlen << a2 << [a, b, c, d].pack('CCCC')
|
110
|
+
else
|
111
|
+
raise ArgumentError.new("not numeric IPv6 address: " + arg)
|
112
|
+
end
|
113
|
+
else
|
114
|
+
raise ArgumentError.new("not numeric IPv6 address: " + arg)
|
115
|
+
end
|
116
|
+
return IPv6.new(address)
|
117
|
+
else
|
118
|
+
raise ArgumentError.new("cannot interpret as IPv6 address: #{arg.inspect}")
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def initialize(address) # :nodoc:
|
123
|
+
unless address.kind_of?(String) && address.length == 16
|
124
|
+
raise ArgumentError.new('IPv6 address must be 16 bytes')
|
125
|
+
end
|
126
|
+
@address = address
|
127
|
+
end
|
128
|
+
|
129
|
+
##
|
130
|
+
# The raw IPv6 address as a String.
|
131
|
+
|
132
|
+
attr_reader :address
|
133
|
+
|
134
|
+
def to_s # :nodoc:
|
135
|
+
sprintf("%x:%x:%x:%x:%x:%x:%x:%x", *@address.unpack("nnnnnnnn")).sub(/(^|:)0(:0)+(:|$)/, '::')
|
136
|
+
end
|
137
|
+
|
138
|
+
def inspect # :nodoc:
|
139
|
+
return "#<#{self.class} #{self}>"
|
140
|
+
end
|
141
|
+
|
142
|
+
def ==(other) # :nodoc:
|
143
|
+
return @address == other.address
|
144
|
+
end
|
145
|
+
|
146
|
+
def eql?(other) # :nodoc:
|
147
|
+
return self == other
|
148
|
+
end
|
149
|
+
|
150
|
+
def hash # :nodoc:
|
151
|
+
return @address.hash
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
data/lib/rrs.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "zeitwerk"
|
3
|
+
require_relative "rrs/inflector"
|
4
|
+
|
5
|
+
loader = Zeitwerk::Loader.for_gem
|
6
|
+
loader.inflector = RRs::Inflector.new
|
7
|
+
loader.setup
|
8
|
+
|
9
|
+
module RRs
|
10
|
+
VERSION = "0.1.0"
|
11
|
+
|
12
|
+
class Error < StandardError; end
|
13
|
+
end
|
14
|
+
|
15
|
+
loader.eager_load
|
data/sig/rrs.rbs
ADDED
metadata
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rrs
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- reesericci
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-08-17 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: "RRs is a set of self-contained DNS primitives that do not share state,
|
14
|
+
which makes them suitable for use in Ractors. \n\nThis is a contrast to the Resolv::DNS
|
15
|
+
and Dnsruby primitives which use a ClassHash."
|
16
|
+
email:
|
17
|
+
- me@reeseric.ci
|
18
|
+
executables: []
|
19
|
+
extensions: []
|
20
|
+
extra_rdoc_files: []
|
21
|
+
files:
|
22
|
+
- ".standard.yml"
|
23
|
+
- README.md
|
24
|
+
- Rakefile
|
25
|
+
- lib/rrs.rb
|
26
|
+
- lib/rrs/a.rb
|
27
|
+
- lib/rrs/inflector.rb
|
28
|
+
- lib/rrs/ipv4.rb
|
29
|
+
- lib/rrs/ipv6.rb
|
30
|
+
- sig/rrs.rbs
|
31
|
+
homepage: https://codeberg.org/reesericci/rrs
|
32
|
+
licenses: []
|
33
|
+
metadata:
|
34
|
+
homepage_uri: https://codeberg.org/reesericci/rrs
|
35
|
+
source_code_uri: https://codeberg.org/reesericci/rrs
|
36
|
+
post_install_message:
|
37
|
+
rdoc_options: []
|
38
|
+
require_paths:
|
39
|
+
- lib
|
40
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: 3.0.0
|
45
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0'
|
50
|
+
requirements: []
|
51
|
+
rubygems_version: 3.5.17
|
52
|
+
signing_key:
|
53
|
+
specification_version: 4
|
54
|
+
summary: RRs is a set of self-contained DNS primitives
|
55
|
+
test_files: []
|