rubysl-resolv 2.0.0 → 2.1.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 +4 -4
- data/.travis.yml +10 -3
- data/lib/rubysl/resolv/resolv.rb +465 -29
- data/lib/rubysl/resolv/version.rb +1 -1
- data/rubysl-resolv.gemspec +1 -0
- metadata +27 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 70fb96e5c839213a9643ffac29c5be3498aee4fa
|
4
|
+
data.tar.gz: 6ecacc7fa6ebf9243c40c33b3e233905a711a366
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9fcdec1fd50945fd720068ec027c820ba6644623c0bb94bc9917fd39fd0507fd81256c549ba77918cc40d45a540b1766d80b4fbb0eed54089e68b77f689a4406
|
7
|
+
data.tar.gz: 9fff4616e686c1c6905b46b3c7d5ef4b5233c410b2b0a41cfc2408b0e997d37e7a24b4f23403b27c51c1df50b714e4e87c6fdaf1d77a239d52f168b5614d6a31
|
data/.travis.yml
CHANGED
@@ -1,7 +1,14 @@
|
|
1
1
|
language: ruby
|
2
2
|
env:
|
3
3
|
- RUBYLIB=lib
|
4
|
-
|
4
|
+
- RUBYLIB=
|
5
|
+
script: mspec spec
|
5
6
|
rvm:
|
6
|
-
- 1.
|
7
|
-
- rbx-
|
7
|
+
- 2.1.0
|
8
|
+
- rbx-2
|
9
|
+
matrix:
|
10
|
+
exclude:
|
11
|
+
- rvm: 2.1.0
|
12
|
+
env: RUBYLIB=lib
|
13
|
+
- rvm: rbx-2
|
14
|
+
env: RUBYLIB=
|
data/lib/rubysl/resolv/resolv.rb
CHANGED
@@ -9,7 +9,7 @@ rescue LoadError
|
|
9
9
|
end
|
10
10
|
|
11
11
|
# Resolv is a thread-aware DNS resolver library written in Ruby. Resolv can
|
12
|
-
# handle multiple DNS requests concurrently without blocking the entire
|
12
|
+
# handle multiple DNS requests concurrently without blocking the entire Ruby
|
13
13
|
# interpreter.
|
14
14
|
#
|
15
15
|
# See also resolv-replace.rb to replace the libc resolver with Resolv.
|
@@ -165,10 +165,11 @@ class Resolv
|
|
165
165
|
# Resolv::Hosts is a hostname resolver that uses the system hosts file.
|
166
166
|
|
167
167
|
class Hosts
|
168
|
-
|
168
|
+
begin
|
169
|
+
raise LoadError unless /mswin|mingw|cygwin/ =~ RUBY_PLATFORM
|
169
170
|
require 'win32/resolv'
|
170
171
|
DefaultFileName = Win32::Resolv.get_hosts_path
|
171
|
-
|
172
|
+
rescue LoadError
|
172
173
|
DefaultFileName = '/etc/hosts'
|
173
174
|
end
|
174
175
|
|
@@ -186,7 +187,7 @@ class Resolv
|
|
186
187
|
unless @initialized
|
187
188
|
@name2addr = {}
|
188
189
|
@addr2name = {}
|
189
|
-
open(@filename) {|f|
|
190
|
+
open(@filename, 'rb') {|f|
|
190
191
|
f.each {|line|
|
191
192
|
line.sub!(/#.*/, '')
|
192
193
|
addr, hostname, *aliases = line.split(/\s+/)
|
@@ -506,6 +507,12 @@ class Resolv
|
|
506
507
|
# #getresource for argument details.
|
507
508
|
|
508
509
|
def each_resource(name, typeclass, &proc)
|
510
|
+
fetch_resource(name, typeclass) {|reply, reply_name|
|
511
|
+
extract_resources(reply, reply_name, typeclass, &proc)
|
512
|
+
}
|
513
|
+
end
|
514
|
+
|
515
|
+
def fetch_resource(name, typeclass)
|
509
516
|
lazy_initialize
|
510
517
|
requester = make_udp_requester
|
511
518
|
senders = {}
|
@@ -515,8 +522,9 @@ class Resolv
|
|
515
522
|
msg.rd = 1
|
516
523
|
msg.add_question(candidate, typeclass)
|
517
524
|
unless sender = senders[[candidate, nameserver, port]]
|
518
|
-
sender =
|
519
|
-
|
525
|
+
sender = requester.sender(msg, candidate, nameserver, port)
|
526
|
+
next if !sender
|
527
|
+
senders[[candidate, nameserver, port]] = sender
|
520
528
|
end
|
521
529
|
reply, reply_name = requester.request(sender, tout)
|
522
530
|
case reply.rcode
|
@@ -532,7 +540,7 @@ class Resolv
|
|
532
540
|
# response will not fit in an untruncated UDP packet.
|
533
541
|
redo
|
534
542
|
else
|
535
|
-
|
543
|
+
yield(reply, reply_name)
|
536
544
|
end
|
537
545
|
return
|
538
546
|
when RCode::NXDomain
|
@@ -645,7 +653,9 @@ class Resolv
|
|
645
653
|
begin
|
646
654
|
port = rangerand(1024..65535)
|
647
655
|
udpsock.bind(bind_host, port)
|
648
|
-
rescue Errno::EADDRINUSE
|
656
|
+
rescue Errno::EADDRINUSE, # POSIX
|
657
|
+
Errno::EACCES, # SunOS: See PRIV_SYS_NFS in privileges(5)
|
658
|
+
Errno::EPERM # FreeBSD: security.mac.portacl.port_high is configurable. See mac_portacl(4).
|
649
659
|
retry
|
650
660
|
end
|
651
661
|
end
|
@@ -659,7 +669,12 @@ class Resolv
|
|
659
669
|
def request(sender, tout)
|
660
670
|
start = Time.now
|
661
671
|
timelimit = start + tout
|
662
|
-
|
672
|
+
begin
|
673
|
+
sender.send
|
674
|
+
rescue Errno::EHOSTUNREACH
|
675
|
+
# multi-homed IPv6 may generate this
|
676
|
+
raise ResolvTimeout
|
677
|
+
end
|
663
678
|
while true
|
664
679
|
before_select = Time.now
|
665
680
|
timeout = timelimit - before_select
|
@@ -685,7 +700,7 @@ class Resolv
|
|
685
700
|
rescue DecodeError
|
686
701
|
next # broken DNS message ignored
|
687
702
|
end
|
688
|
-
if s =
|
703
|
+
if s = sender_for(from, msg)
|
689
704
|
break
|
690
705
|
else
|
691
706
|
# unexpected DNS message ignored
|
@@ -694,6 +709,10 @@ class Resolv
|
|
694
709
|
return msg, s.data
|
695
710
|
end
|
696
711
|
|
712
|
+
def sender_for(addr, msg)
|
713
|
+
@senders[[addr,msg.id]]
|
714
|
+
end
|
715
|
+
|
697
716
|
def close
|
698
717
|
socks = @socks
|
699
718
|
@socks = nil
|
@@ -725,9 +744,12 @@ class Resolv
|
|
725
744
|
af = Socket::AF_INET
|
726
745
|
end
|
727
746
|
next if @socks_hash[bind_host]
|
728
|
-
|
747
|
+
begin
|
748
|
+
sock = UDPSocket.new(af)
|
749
|
+
rescue Errno::EAFNOSUPPORT
|
750
|
+
next # The kernel doesn't support the address family.
|
751
|
+
end
|
729
752
|
sock.do_not_reverse_lookup = true
|
730
|
-
sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::F_SETFD
|
731
753
|
DNS.bind_random_port(sock, bind_host)
|
732
754
|
@socks << sock
|
733
755
|
@socks_hash[bind_host] = sock
|
@@ -740,11 +762,12 @@ class Resolv
|
|
740
762
|
end
|
741
763
|
|
742
764
|
def sender(msg, data, host, port=Port)
|
765
|
+
sock = @socks_hash[host.index(':') ? "::" : "0.0.0.0"]
|
766
|
+
return nil if !sock
|
743
767
|
service = [host, port]
|
744
768
|
id = DNS.allocate_request_id(host, port)
|
745
769
|
request = msg.encode
|
746
770
|
request[0,2] = [id].pack('n')
|
747
|
-
sock = @socks_hash[host.index(':') ? "::" : "0.0.0.0"]
|
748
771
|
return @senders[[service, id]] =
|
749
772
|
Sender.new(request, data, sock, host, port)
|
750
773
|
end
|
@@ -765,6 +788,7 @@ class Resolv
|
|
765
788
|
attr_reader :data
|
766
789
|
|
767
790
|
def send
|
791
|
+
raise "@sock is nil." if @sock.nil?
|
768
792
|
@sock.send(@msg, 0, @host, @port)
|
769
793
|
end
|
770
794
|
end
|
@@ -779,7 +803,6 @@ class Resolv
|
|
779
803
|
sock = UDPSocket.new(is_ipv6 ? Socket::AF_INET6 : Socket::AF_INET)
|
780
804
|
@socks = [sock]
|
781
805
|
sock.do_not_reverse_lookup = true
|
782
|
-
sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::F_SETFD
|
783
806
|
DNS.bind_random_port(sock, is_ipv6 ? "::" : "0.0.0.0")
|
784
807
|
sock.connect(host, port)
|
785
808
|
end
|
@@ -808,12 +831,28 @@ class Resolv
|
|
808
831
|
|
809
832
|
class Sender < Requester::Sender # :nodoc:
|
810
833
|
def send
|
834
|
+
raise "@sock is nil." if @sock.nil?
|
811
835
|
@sock.send(@msg, 0)
|
812
836
|
end
|
813
837
|
attr_reader :data
|
814
838
|
end
|
815
839
|
end
|
816
840
|
|
841
|
+
class MDNSOneShot < UnconnectedUDP # :nodoc:
|
842
|
+
def sender(msg, data, host, port=Port)
|
843
|
+
id = DNS.allocate_request_id(host, port)
|
844
|
+
request = msg.encode
|
845
|
+
request[0,2] = [id].pack('n')
|
846
|
+
sock = @socks_hash[host.index(':') ? "::" : "0.0.0.0"]
|
847
|
+
return @senders[id] =
|
848
|
+
UnconnectedUDP::Sender.new(request, data, sock, host, port)
|
849
|
+
end
|
850
|
+
|
851
|
+
def sender_for(addr, msg)
|
852
|
+
@senders[msg.id]
|
853
|
+
end
|
854
|
+
end
|
855
|
+
|
817
856
|
class TCP < Requester # :nodoc:
|
818
857
|
def initialize(host, port=Port)
|
819
858
|
super()
|
@@ -821,7 +860,6 @@ class Resolv
|
|
821
860
|
@port = port
|
822
861
|
sock = TCPSocket.new(@host, @port)
|
823
862
|
@socks = [sock]
|
824
|
-
sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::F_SETFD
|
825
863
|
@senders = {}
|
826
864
|
end
|
827
865
|
|
@@ -877,7 +915,7 @@ class Resolv
|
|
877
915
|
values = Array(values)
|
878
916
|
values.each do |t|
|
879
917
|
Numeric === t or raise ArgumentError, "#{t.inspect} is not numeric"
|
880
|
-
t > 0.0 or raise ArgumentError, "timeout=#{t} must be
|
918
|
+
t > 0.0 or raise ArgumentError, "timeout=#{t} must be positive"
|
881
919
|
end
|
882
920
|
@timeouts = values
|
883
921
|
else
|
@@ -889,7 +927,7 @@ class Resolv
|
|
889
927
|
nameserver = []
|
890
928
|
search = nil
|
891
929
|
ndots = 1
|
892
|
-
open(filename) {|f|
|
930
|
+
open(filename, 'rb') {|f|
|
893
931
|
f.each {|line|
|
894
932
|
line.sub!(/[#;].*/, '')
|
895
933
|
keyword, *args = line.split(/\s+/)
|
@@ -1489,6 +1527,7 @@ class Resolv
|
|
1489
1527
|
end
|
1490
1528
|
|
1491
1529
|
def get_bytes(len = @limit - @index)
|
1530
|
+
raise DecodeError.new("limit exceeded") if @limit < @index + len
|
1492
1531
|
d = @data[@index, len]
|
1493
1532
|
@index += len
|
1494
1533
|
return d
|
@@ -1516,6 +1555,7 @@ class Resolv
|
|
1516
1555
|
end
|
1517
1556
|
|
1518
1557
|
def get_string
|
1558
|
+
raise DecodeError.new("limit exceeded") if @limit <= @index
|
1519
1559
|
len = @data[@index].ord
|
1520
1560
|
raise DecodeError.new("limit exceeded") if @limit < @index + 1 + len
|
1521
1561
|
d = @data[@index + 1, len]
|
@@ -1535,29 +1575,33 @@ class Resolv
|
|
1535
1575
|
return Name.new(self.get_labels)
|
1536
1576
|
end
|
1537
1577
|
|
1538
|
-
def get_labels
|
1539
|
-
|
1578
|
+
def get_labels
|
1579
|
+
prev_index = @index
|
1580
|
+
save_index = nil
|
1540
1581
|
d = []
|
1541
1582
|
while true
|
1583
|
+
raise DecodeError.new("limit exceeded") if @limit <= @index
|
1542
1584
|
case @data[@index].ord
|
1543
1585
|
when 0
|
1544
1586
|
@index += 1
|
1587
|
+
if save_index
|
1588
|
+
@index = save_index
|
1589
|
+
end
|
1545
1590
|
return d
|
1546
1591
|
when 192..255
|
1547
1592
|
idx = self.get_unpack('n')[0] & 0x3fff
|
1548
|
-
if
|
1593
|
+
if prev_index <= idx
|
1549
1594
|
raise DecodeError.new("non-backward name pointer")
|
1550
1595
|
end
|
1551
|
-
|
1596
|
+
prev_index = idx
|
1597
|
+
if !save_index
|
1598
|
+
save_index = @index
|
1599
|
+
end
|
1552
1600
|
@index = idx
|
1553
|
-
d += self.get_labels(limit)
|
1554
|
-
@index = save_index
|
1555
|
-
return d
|
1556
1601
|
else
|
1557
1602
|
d << self.get_label
|
1558
1603
|
end
|
1559
1604
|
end
|
1560
|
-
return d
|
1561
1605
|
end
|
1562
1606
|
|
1563
1607
|
def get_label
|
@@ -1932,10 +1976,10 @@ class Resolv
|
|
1932
1976
|
attr_reader :strings
|
1933
1977
|
|
1934
1978
|
##
|
1935
|
-
# Returns the
|
1979
|
+
# Returns the concatenated string from +strings+.
|
1936
1980
|
|
1937
1981
|
def data
|
1938
|
-
@strings
|
1982
|
+
@strings.join("")
|
1939
1983
|
end
|
1940
1984
|
|
1941
1985
|
def encode_rdata(msg) # :nodoc:
|
@@ -1948,6 +1992,97 @@ class Resolv
|
|
1948
1992
|
end
|
1949
1993
|
end
|
1950
1994
|
|
1995
|
+
##
|
1996
|
+
# Location resource
|
1997
|
+
|
1998
|
+
class LOC < Resource
|
1999
|
+
|
2000
|
+
TypeValue = 29 # :nodoc:
|
2001
|
+
|
2002
|
+
def initialize(version, ssize, hprecision, vprecision, latitude, longitude, altitude)
|
2003
|
+
@version = version
|
2004
|
+
@ssize = Resolv::LOC::Size.create(ssize)
|
2005
|
+
@hprecision = Resolv::LOC::Size.create(hprecision)
|
2006
|
+
@vprecision = Resolv::LOC::Size.create(vprecision)
|
2007
|
+
@latitude = Resolv::LOC::Coord.create(latitude)
|
2008
|
+
@longitude = Resolv::LOC::Coord.create(longitude)
|
2009
|
+
@altitude = Resolv::LOC::Alt.create(altitude)
|
2010
|
+
end
|
2011
|
+
|
2012
|
+
##
|
2013
|
+
# Returns the version value for this LOC record which should always be 00
|
2014
|
+
|
2015
|
+
attr_reader :version
|
2016
|
+
|
2017
|
+
##
|
2018
|
+
# The spherical size of this LOC
|
2019
|
+
# in meters using scientific notation as 2 integers of XeY
|
2020
|
+
|
2021
|
+
attr_reader :ssize
|
2022
|
+
|
2023
|
+
##
|
2024
|
+
# The horizontal precision using ssize type values
|
2025
|
+
# in meters using scientific notation as 2 integers of XeY
|
2026
|
+
# for precision use value/2 e.g. 2m = +/-1m
|
2027
|
+
|
2028
|
+
attr_reader :hprecision
|
2029
|
+
|
2030
|
+
##
|
2031
|
+
# The vertical precision using ssize type values
|
2032
|
+
# in meters using scientific notation as 2 integers of XeY
|
2033
|
+
# for precision use value/2 e.g. 2m = +/-1m
|
2034
|
+
|
2035
|
+
attr_reader :vprecision
|
2036
|
+
|
2037
|
+
##
|
2038
|
+
# The latitude for this LOC where 2**31 is the equator
|
2039
|
+
# in thousandths of an arc second as an unsigned 32bit integer
|
2040
|
+
|
2041
|
+
attr_reader :latitude
|
2042
|
+
|
2043
|
+
##
|
2044
|
+
# The longitude for this LOC where 2**31 is the prime meridian
|
2045
|
+
# in thousandths of an arc second as an unsigned 32bit integer
|
2046
|
+
|
2047
|
+
attr_reader :longitude
|
2048
|
+
|
2049
|
+
##
|
2050
|
+
# The altitude of the LOC above a reference sphere whose surface sits 100km below the WGS84 spheroid
|
2051
|
+
# in centimeters as an unsigned 32bit integer
|
2052
|
+
|
2053
|
+
attr_reader :altitude
|
2054
|
+
|
2055
|
+
|
2056
|
+
def encode_rdata(msg) # :nodoc:
|
2057
|
+
msg.put_bytes(@version)
|
2058
|
+
msg.put_bytes(@ssize.scalar)
|
2059
|
+
msg.put_bytes(@hprecision.scalar)
|
2060
|
+
msg.put_bytes(@vprecision.scalar)
|
2061
|
+
msg.put_bytes(@latitude.coordinates)
|
2062
|
+
msg.put_bytes(@longitude.coordinates)
|
2063
|
+
msg.put_bytes(@altitude.altitude)
|
2064
|
+
end
|
2065
|
+
|
2066
|
+
def self.decode_rdata(msg) # :nodoc:
|
2067
|
+
version = msg.get_bytes(1)
|
2068
|
+
ssize = msg.get_bytes(1)
|
2069
|
+
hprecision = msg.get_bytes(1)
|
2070
|
+
vprecision = msg.get_bytes(1)
|
2071
|
+
latitude = msg.get_bytes(4)
|
2072
|
+
longitude = msg.get_bytes(4)
|
2073
|
+
altitude = msg.get_bytes(4)
|
2074
|
+
return self.new(
|
2075
|
+
version,
|
2076
|
+
Resolv::LOC::Size.new(ssize),
|
2077
|
+
Resolv::LOC::Size.new(hprecision),
|
2078
|
+
Resolv::LOC::Size.new(vprecision),
|
2079
|
+
Resolv::LOC::Coord.new(latitude,"lat"),
|
2080
|
+
Resolv::LOC::Coord.new(longitude,"lon"),
|
2081
|
+
Resolv::LOC::Alt.new(altitude)
|
2082
|
+
)
|
2083
|
+
end
|
2084
|
+
end
|
2085
|
+
|
1951
2086
|
##
|
1952
2087
|
# A Query type requesting any RR.
|
1953
2088
|
|
@@ -1956,7 +2091,7 @@ class Resolv
|
|
1956
2091
|
end
|
1957
2092
|
|
1958
2093
|
ClassInsensitiveTypes = [ # :nodoc:
|
1959
|
-
NS, CNAME, SOA, PTR, HINFO, MINFO, MX, TXT, ANY
|
2094
|
+
NS, CNAME, SOA, PTR, HINFO, MINFO, MX, TXT, LOC, ANY
|
1960
2095
|
]
|
1961
2096
|
|
1962
2097
|
##
|
@@ -2381,15 +2516,316 @@ class Resolv
|
|
2381
2516
|
end
|
2382
2517
|
end
|
2383
2518
|
|
2519
|
+
##
|
2520
|
+
# Resolv::MDNS is a one-shot Multicast DNS (mDNS) resolver. It blindly
|
2521
|
+
# makes queries to the mDNS addresses without understanding anything about
|
2522
|
+
# multicast ports.
|
2523
|
+
#
|
2524
|
+
# Information taken form the following places:
|
2525
|
+
#
|
2526
|
+
# * RFC 6762
|
2527
|
+
|
2528
|
+
class MDNS < DNS
|
2529
|
+
|
2530
|
+
##
|
2531
|
+
# Default mDNS Port
|
2532
|
+
|
2533
|
+
Port = 5353
|
2534
|
+
|
2535
|
+
##
|
2536
|
+
# Default IPv4 mDNS address
|
2537
|
+
|
2538
|
+
AddressV4 = '224.0.0.251'
|
2539
|
+
|
2540
|
+
##
|
2541
|
+
# Default IPv6 mDNS address
|
2542
|
+
|
2543
|
+
AddressV6 = 'ff02::fb'
|
2544
|
+
|
2545
|
+
##
|
2546
|
+
# Default mDNS addresses
|
2547
|
+
|
2548
|
+
Addresses = [
|
2549
|
+
[AddressV4, Port],
|
2550
|
+
[AddressV6, Port],
|
2551
|
+
]
|
2552
|
+
|
2553
|
+
##
|
2554
|
+
# Creates a new one-shot Multicast DNS (mDNS) resolver.
|
2555
|
+
#
|
2556
|
+
# +config_info+ can be:
|
2557
|
+
#
|
2558
|
+
# nil::
|
2559
|
+
# Uses the default mDNS addresses
|
2560
|
+
#
|
2561
|
+
# Hash::
|
2562
|
+
# Must contain :nameserver or :nameserver_port like
|
2563
|
+
# Resolv::DNS#initialize.
|
2564
|
+
|
2565
|
+
def initialize(config_info=nil)
|
2566
|
+
if config_info then
|
2567
|
+
super({ nameserver_port: Addresses }.merge(config_info))
|
2568
|
+
else
|
2569
|
+
super(nameserver_port: Addresses)
|
2570
|
+
end
|
2571
|
+
end
|
2572
|
+
|
2573
|
+
##
|
2574
|
+
# Iterates over all IP addresses for +name+ retrieved from the mDNS
|
2575
|
+
# resolver, provided name ends with "local". If the name does not end in
|
2576
|
+
# "local" no records will be returned.
|
2577
|
+
#
|
2578
|
+
# +name+ can be a Resolv::DNS::Name or a String. Retrieved addresses will
|
2579
|
+
# be a Resolv::IPv4 or Resolv::IPv6
|
2580
|
+
|
2581
|
+
def each_address(name)
|
2582
|
+
name = Resolv::DNS::Name.create(name)
|
2583
|
+
|
2584
|
+
return unless name.to_a.last == 'local'
|
2585
|
+
|
2586
|
+
super(name)
|
2587
|
+
end
|
2588
|
+
|
2589
|
+
def make_udp_requester # :nodoc:
|
2590
|
+
nameserver_port = @config.nameserver_port
|
2591
|
+
Requester::MDNSOneShot.new(*nameserver_port)
|
2592
|
+
end
|
2593
|
+
|
2594
|
+
end
|
2595
|
+
|
2596
|
+
module LOC
|
2597
|
+
|
2598
|
+
##
|
2599
|
+
# A Resolv::LOC::Size
|
2600
|
+
|
2601
|
+
class Size
|
2602
|
+
|
2603
|
+
Regex = /^(\d+\.*\d*)[m]$/
|
2604
|
+
|
2605
|
+
##
|
2606
|
+
# Creates a new LOC::Size from +arg+ which may be:
|
2607
|
+
#
|
2608
|
+
# LOC::Size:: returns +arg+.
|
2609
|
+
# String:: +arg+ must match the LOC::Size::Regex constant
|
2610
|
+
|
2611
|
+
def self.create(arg)
|
2612
|
+
case arg
|
2613
|
+
when Size
|
2614
|
+
return arg
|
2615
|
+
when String
|
2616
|
+
scalar = ''
|
2617
|
+
if Regex =~ arg
|
2618
|
+
scalar = [(($1.to_f*(1e2)).to_i.to_s[0].to_i*(2**4)+(($1.to_f*(1e2)).to_i.to_s.length-1))].pack("C")
|
2619
|
+
else
|
2620
|
+
raise ArgumentError.new("not a properly formed Size string: " + arg)
|
2621
|
+
end
|
2622
|
+
return Size.new(scalar)
|
2623
|
+
else
|
2624
|
+
raise ArgumentError.new("cannot interpret as Size: #{arg.inspect}")
|
2625
|
+
end
|
2626
|
+
end
|
2627
|
+
|
2628
|
+
def initialize(scalar)
|
2629
|
+
@scalar = scalar
|
2630
|
+
end
|
2631
|
+
|
2632
|
+
##
|
2633
|
+
# The raw size
|
2634
|
+
|
2635
|
+
attr_reader :scalar
|
2636
|
+
|
2637
|
+
def to_s # :nodoc:
|
2638
|
+
s = @scalar.unpack("H2").join.to_s
|
2639
|
+
return ((s[0].to_i)*(10**(s[1].to_i-2))).to_s << "m"
|
2640
|
+
end
|
2641
|
+
|
2642
|
+
def inspect # :nodoc:
|
2643
|
+
return "#<#{self.class} #{self.to_s}>"
|
2644
|
+
end
|
2645
|
+
|
2646
|
+
def ==(other) # :nodoc:
|
2647
|
+
return @scalar == other.scalar
|
2648
|
+
end
|
2649
|
+
|
2650
|
+
def eql?(other) # :nodoc:
|
2651
|
+
return self == other
|
2652
|
+
end
|
2653
|
+
|
2654
|
+
def hash # :nodoc:
|
2655
|
+
return @scalar.hash
|
2656
|
+
end
|
2657
|
+
|
2658
|
+
end
|
2659
|
+
|
2660
|
+
##
|
2661
|
+
# A Resolv::LOC::Coord
|
2662
|
+
|
2663
|
+
class Coord
|
2664
|
+
|
2665
|
+
Regex = /^(\d+)\s(\d+)\s(\d+\.\d+)\s([NESW])$/
|
2666
|
+
|
2667
|
+
##
|
2668
|
+
# Creates a new LOC::Coord from +arg+ which may be:
|
2669
|
+
#
|
2670
|
+
# LOC::Coord:: returns +arg+.
|
2671
|
+
# String:: +arg+ must match the LOC::Coord::Regex constant
|
2672
|
+
|
2673
|
+
def self.create(arg)
|
2674
|
+
case arg
|
2675
|
+
when Coord
|
2676
|
+
return arg
|
2677
|
+
when String
|
2678
|
+
coordinates = ''
|
2679
|
+
if Regex =~ arg && $1<180
|
2680
|
+
hemi = ($4[/([NE])/,1]) || ($4[/([SW])/,1]) ? 1 : -1
|
2681
|
+
coordinates = [(($1.to_i*(36e5))+($2.to_i*(6e4))+($3.to_f*(1e3)))*hemi+(2**31)].pack("N")
|
2682
|
+
(orientation ||= '') << $4[[/NS/],1] ? 'lat' : 'lon'
|
2683
|
+
else
|
2684
|
+
raise ArgumentError.new("not a properly formed Coord string: " + arg)
|
2685
|
+
end
|
2686
|
+
return Coord.new(coordinates,orientation)
|
2687
|
+
else
|
2688
|
+
raise ArgumentError.new("cannot interpret as Coord: #{arg.inspect}")
|
2689
|
+
end
|
2690
|
+
end
|
2691
|
+
|
2692
|
+
def initialize(coordinates,orientation)
|
2693
|
+
unless coordinates.kind_of?(String)
|
2694
|
+
raise ArgumentError.new("Coord must be a 32bit unsigned integer in hex format: #{coordinates.inspect}")
|
2695
|
+
end
|
2696
|
+
unless orientation.kind_of?(String) && orientation[/^lon$|^lat$/]
|
2697
|
+
raise ArgumentError.new('Coord expects orientation to be a String argument of "lat" or "lon"')
|
2698
|
+
end
|
2699
|
+
@coordinates = coordinates
|
2700
|
+
@orientation = orientation
|
2701
|
+
end
|
2702
|
+
|
2703
|
+
##
|
2704
|
+
# The raw coordinates
|
2705
|
+
|
2706
|
+
attr_reader :coordinates
|
2707
|
+
|
2708
|
+
## The orientation of the hemisphere as 'lat' or 'lon'
|
2709
|
+
|
2710
|
+
attr_reader :orientation
|
2711
|
+
|
2712
|
+
def to_s # :nodoc:
|
2713
|
+
c = @coordinates.unpack("N").join.to_i
|
2714
|
+
val = (c - (2**31)).abs
|
2715
|
+
fracsecs = (val % 1e3).to_i.to_s
|
2716
|
+
val = val / 1e3
|
2717
|
+
secs = (val % 60).to_i.to_s
|
2718
|
+
val = val / 60
|
2719
|
+
mins = (val % 60).to_i.to_s
|
2720
|
+
degs = (val / 60).to_i.to_s
|
2721
|
+
posi = (c >= 2**31)
|
2722
|
+
case posi
|
2723
|
+
when true
|
2724
|
+
hemi = @orientation[/^lat$/] ? "N" : "E"
|
2725
|
+
else
|
2726
|
+
hemi = @orientation[/^lon$/] ? "W" : "S"
|
2727
|
+
end
|
2728
|
+
return degs << " " << mins << " " << secs << "." << fracsecs << " " << hemi
|
2729
|
+
end
|
2730
|
+
|
2731
|
+
def inspect # :nodoc:
|
2732
|
+
return "#<#{self.class} #{self.to_s}>"
|
2733
|
+
end
|
2734
|
+
|
2735
|
+
def ==(other) # :nodoc:
|
2736
|
+
return @coordinates == other.coordinates
|
2737
|
+
end
|
2738
|
+
|
2739
|
+
def eql?(other) # :nodoc:
|
2740
|
+
return self == other
|
2741
|
+
end
|
2742
|
+
|
2743
|
+
def hash # :nodoc:
|
2744
|
+
return @coordinates.hash
|
2745
|
+
end
|
2746
|
+
|
2747
|
+
end
|
2748
|
+
|
2749
|
+
##
|
2750
|
+
# A Resolv::LOC::Alt
|
2751
|
+
|
2752
|
+
class Alt
|
2753
|
+
|
2754
|
+
Regex = /^([+-]*\d+\.*\d*)[m]$/
|
2755
|
+
|
2756
|
+
##
|
2757
|
+
# Creates a new LOC::Alt from +arg+ which may be:
|
2758
|
+
#
|
2759
|
+
# LOC::Alt:: returns +arg+.
|
2760
|
+
# String:: +arg+ must match the LOC::Alt::Regex constant
|
2761
|
+
|
2762
|
+
def self.create(arg)
|
2763
|
+
case arg
|
2764
|
+
when Alt
|
2765
|
+
return arg
|
2766
|
+
when String
|
2767
|
+
altitude = ''
|
2768
|
+
if Regex =~ arg
|
2769
|
+
altitude = [($1.to_f*(1e2))+(1e7)].pack("N")
|
2770
|
+
else
|
2771
|
+
raise ArgumentError.new("not a properly formed Alt string: " + arg)
|
2772
|
+
end
|
2773
|
+
return Alt.new(altitude)
|
2774
|
+
else
|
2775
|
+
raise ArgumentError.new("cannot interpret as Alt: #{arg.inspect}")
|
2776
|
+
end
|
2777
|
+
end
|
2778
|
+
|
2779
|
+
def initialize(altitude)
|
2780
|
+
@altitude = altitude
|
2781
|
+
end
|
2782
|
+
|
2783
|
+
##
|
2784
|
+
# The raw altitude
|
2785
|
+
|
2786
|
+
attr_reader :altitude
|
2787
|
+
|
2788
|
+
def to_s # :nodoc:
|
2789
|
+
a = @altitude.unpack("N").join.to_i
|
2790
|
+
return ((a.to_f/1e2)-1e5).to_s + "m"
|
2791
|
+
end
|
2792
|
+
|
2793
|
+
def inspect # :nodoc:
|
2794
|
+
return "#<#{self.class} #{self.to_s}>"
|
2795
|
+
end
|
2796
|
+
|
2797
|
+
def ==(other) # :nodoc:
|
2798
|
+
return @altitude == other.altitude
|
2799
|
+
end
|
2800
|
+
|
2801
|
+
def eql?(other) # :nodoc:
|
2802
|
+
return self == other
|
2803
|
+
end
|
2804
|
+
|
2805
|
+
def hash # :nodoc:
|
2806
|
+
return @altitude.hash
|
2807
|
+
end
|
2808
|
+
|
2809
|
+
end
|
2810
|
+
|
2811
|
+
end
|
2812
|
+
|
2384
2813
|
##
|
2385
2814
|
# Default resolver to use for Resolv class methods.
|
2386
2815
|
|
2387
2816
|
DefaultResolver = self.new
|
2388
2817
|
|
2818
|
+
##
|
2819
|
+
# Replaces the resolvers in the default resolver with +new_resolvers+. This
|
2820
|
+
# allows resolvers to be changed for resolv-replace.
|
2821
|
+
|
2822
|
+
def DefaultResolver.replace_resolvers new_resolvers
|
2823
|
+
@resolvers = new_resolvers
|
2824
|
+
end
|
2825
|
+
|
2389
2826
|
##
|
2390
2827
|
# Address Regexp to use for matching IP addresses.
|
2391
2828
|
|
2392
2829
|
AddressRegex = /(?:#{IPv4::Regex})|(?:#{IPv6::Regex})/
|
2393
2830
|
|
2394
2831
|
end
|
2395
|
-
|
data/rubysl-resolv.gemspec
CHANGED
metadata
CHANGED
@@ -1,57 +1,71 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubysl-resolv
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Shirai
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-02-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.3'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.3'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - ~>
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '10.0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - ~>
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '10.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: mspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - ~>
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '1.5'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - ~>
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '1.5'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubysl-prettyprint
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '2.0'
|
55
69
|
description: Ruby standard library resolv.
|
56
70
|
email:
|
57
71
|
- brixen@gmail.com
|
@@ -59,8 +73,8 @@ executables: []
|
|
59
73
|
extensions: []
|
60
74
|
extra_rdoc_files: []
|
61
75
|
files:
|
62
|
-
- .gitignore
|
63
|
-
- .travis.yml
|
76
|
+
- ".gitignore"
|
77
|
+
- ".travis.yml"
|
64
78
|
- Gemfile
|
65
79
|
- LICENSE
|
66
80
|
- README.md
|
@@ -84,17 +98,17 @@ require_paths:
|
|
84
98
|
- lib
|
85
99
|
required_ruby_version: !ruby/object:Gem::Requirement
|
86
100
|
requirements:
|
87
|
-
- - ~>
|
101
|
+
- - "~>"
|
88
102
|
- !ruby/object:Gem::Version
|
89
103
|
version: '2.0'
|
90
104
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
91
105
|
requirements:
|
92
|
-
- -
|
106
|
+
- - ">="
|
93
107
|
- !ruby/object:Gem::Version
|
94
108
|
version: '0'
|
95
109
|
requirements: []
|
96
110
|
rubyforge_project:
|
97
|
-
rubygems_version: 2.
|
111
|
+
rubygems_version: 2.2.1
|
98
112
|
signing_key:
|
99
113
|
specification_version: 4
|
100
114
|
summary: Ruby standard library resolv.
|