rubysl-resolv 2.0.0 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|