resolv 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 56680c64e918a60193f43e3ca4a7093db20bbe66f516da79a159d9a3c05860d8
4
- data.tar.gz: f017a2c89fbcdf946b69ce57d41a67537b73f54ec6e99d18cc62865fd6ec1633
3
+ metadata.gz: f3c2610a9201afa7c69fdadb89357cfe4c44e0bec4f52c430ef6328897ebda0a
4
+ data.tar.gz: 06f9f301afe24165dd53683dd11c503a69cb367cc76f5885709552bab7444d61
5
5
  SHA512:
6
- metadata.gz: d57f866a30bc2b8da6dbcdb8c65d0a5db4630af4ec0244aa490e37370ba7b27c3031e153e76055e7f4f63114bd477944326b05dbb7319f97bf59478f8518d76a
7
- data.tar.gz: f07e85287b3bb9973c90900c1fbdc272e193d91493e63b407e696cc9f52de29fc0716f2ec11aba56d37d89a12b6d3fec55d21bd8ce756f02d56577940c454b06
6
+ metadata.gz: 15dafa5ebe1d4ba98fb40a1bec5d700beee853090230b08fcfc0a8c4ebd6cebf2657e4618c6de664a17a1b0ae0c8fa183c27dd0739957389140a5d001fc2d92a
7
+ data.tar.gz: e930fb5af7be91b0342d855486979f070aaf04c02ca054dd8a6dfb70313dcc2fe8037f52e0d9e61b31df21a7452c841e5c3f48889c85532155285ad7100948eb
@@ -0,0 +1,7 @@
1
+ # This is a file used by GitHub to ignore the following commits on `git blame`.
2
+ #
3
+ # You can also do the same thing in your local repository with:
4
+ # $ git config --local blame.ignoreRevsFile .git-blame-ignore-revs
5
+
6
+ # Expand tabs
7
+ 9ae210665a8524554e7c868d3ec67af54b0958bb
@@ -0,0 +1,46 @@
1
+ name: Publish gem to rubygems.org
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ push:
13
+ if: github.repository == 'ruby/resolv'
14
+ runs-on: ubuntu-latest
15
+
16
+ environment:
17
+ name: rubygems.org
18
+ url: https://rubygems.org/gems/resolv
19
+
20
+ permissions:
21
+ contents: write
22
+ id-token: write
23
+
24
+ steps:
25
+ - name: Harden Runner
26
+ uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1
27
+ with:
28
+ egress-policy: audit
29
+
30
+ - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
31
+
32
+ - name: Set up Ruby
33
+ uses: ruby/setup-ruby@a6e6f86333f0a2523ece813039b8b4be04560854 # v1.190.0
34
+ with:
35
+ bundler-cache: true
36
+ ruby-version: ruby
37
+
38
+ - name: Publish to RubyGems
39
+ uses: rubygems/release-gem@612653d273a73bdae1df8453e090060bb4db5f31 # v1
40
+
41
+ - name: Create GitHub release
42
+ run: |
43
+ tag_name="$(git describe --tags --abbrev=0)"
44
+ gh release create "${tag_name}" --verify-tag --generate-notes
45
+ env:
46
+ GITHUB_TOKEN: ${{ secrets.MATZBOT_GITHUB_WORKFLOW_TOKEN }}
@@ -19,6 +19,9 @@ jobs:
19
19
  include:
20
20
  - ruby: mswin
21
21
  os: windows-latest
22
+ exclude:
23
+ - ruby: 2.5
24
+ os: macos-latest
22
25
  runs-on: ${{ matrix.os }}
23
26
  steps:
24
27
  - uses: actions/checkout@v4
@@ -4,10 +4,10 @@ Redistribution and use in source and binary forms, with or without
4
4
  modification, are permitted provided that the following conditions
5
5
  are met:
6
6
  1. Redistributions of source code must retain the above copyright
7
- notice, this list of conditions and the following disclaimer.
7
+ notice, this list of conditions and the following disclaimer.
8
8
  2. Redistributions in binary form must reproduce the above copyright
9
- notice, this list of conditions and the following disclaimer in the
10
- documentation and/or other materials provided with the distribution.
9
+ notice, this list of conditions and the following disclaimer in the
10
+ documentation and/or other materials provided with the distribution.
11
11
 
12
12
  THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
13
13
  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
data/COPYING ADDED
@@ -0,0 +1,56 @@
1
+ Ruby is copyrighted free software by Yukihiro Matsumoto <matz@netlab.jp>.
2
+ You can redistribute it and/or modify it under either the terms of the
3
+ 2-clause BSDL (see the file BSDL), or the conditions below:
4
+
5
+ 1. You may make and give away verbatim copies of the source form of the
6
+ software without restriction, provided that you duplicate all of the
7
+ original copyright notices and associated disclaimers.
8
+
9
+ 2. You may modify your copy of the software in any way, provided that
10
+ you do at least ONE of the following:
11
+
12
+ a. place your modifications in the Public Domain or otherwise
13
+ make them Freely Available, such as by posting said
14
+ modifications to Usenet or an equivalent medium, or by allowing
15
+ the author to include your modifications in the software.
16
+
17
+ b. use the modified software only within your corporation or
18
+ organization.
19
+
20
+ c. give non-standard binaries non-standard names, with
21
+ instructions on where to get the original software distribution.
22
+
23
+ d. make other distribution arrangements with the author.
24
+
25
+ 3. You may distribute the software in object code or binary form,
26
+ provided that you do at least ONE of the following:
27
+
28
+ a. distribute the binaries and library files of the software,
29
+ together with instructions (in the manual page or equivalent)
30
+ on where to get the original distribution.
31
+
32
+ b. accompany the distribution with the machine-readable source of
33
+ the software.
34
+
35
+ c. give non-standard binaries non-standard names, with
36
+ instructions on where to get the original software distribution.
37
+
38
+ d. make other distribution arrangements with the author.
39
+
40
+ 4. You may modify and include the part of the software into any other
41
+ software (possibly commercial). But some files in the distribution
42
+ are not written by the author, so that they are not under these terms.
43
+
44
+ For the list of those files and their copying conditions, see the
45
+ file LEGAL.
46
+
47
+ 5. The scripts and library files supplied as input to or produced as
48
+ output from the software do not automatically fall under the
49
+ copyright of the software, but belong to whomever generated them,
50
+ and may be sold commercially, and may be aggregated with this
51
+ software.
52
+
53
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
54
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
55
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
56
+ PURPOSE.
@@ -0,0 +1,6 @@
1
+ require 'mkmf'
2
+ if have_library('iphlpapi', 'GetNetworkParams')
3
+ create_makefile('win32/resolv')
4
+ else
5
+ File.write('Makefile', "all clean install:\n\t@echo Done: $(@)\n")
6
+ end
@@ -0,0 +1,135 @@
1
+ # frozen_string_literal: false
2
+ =begin
3
+ = Win32 DNS and DHCP I/F
4
+
5
+ =end
6
+
7
+ require 'win32/registry'
8
+
9
+ module Win32
10
+ module Resolv
11
+ API = Registry::API
12
+ Error = Registry::Error
13
+
14
+ def self.get_hosts_path
15
+ path = get_hosts_dir
16
+ path = File.expand_path('hosts', path)
17
+ File.exist?(path) ? path : nil
18
+ end
19
+
20
+ def self.get_resolv_info
21
+ search, nameserver = get_info
22
+ if search.empty?
23
+ search = nil
24
+ else
25
+ search.delete("")
26
+ search.uniq!
27
+ end
28
+ if nameserver.empty?
29
+ nameserver = nil
30
+ else
31
+ nameserver.delete("")
32
+ nameserver.delete("0.0.0.0")
33
+ nameserver.uniq!
34
+ end
35
+ [ search, nameserver ]
36
+ end
37
+ end
38
+ end
39
+
40
+ begin
41
+ require 'win32/resolv.so'
42
+ rescue LoadError
43
+ end
44
+
45
+ module Win32
46
+ #====================================================================
47
+ # Windows NT
48
+ #====================================================================
49
+ module Resolv
50
+ module SZ
51
+ refine Registry do
52
+ # ad hoc workaround for broken registry
53
+ def read_s(key)
54
+ type, str = read(key)
55
+ unless type == Registry::REG_SZ
56
+ warn "Broken registry, #{name}\\#{key} was #{Registry.type2name(type)}, ignored"
57
+ return String.new
58
+ end
59
+ str
60
+ end
61
+ end
62
+ end
63
+ using SZ
64
+
65
+ TCPIP_NT = 'SYSTEM\CurrentControlSet\Services\Tcpip\Parameters'
66
+
67
+ class << self
68
+ private
69
+ def get_hosts_dir
70
+ Registry::HKEY_LOCAL_MACHINE.open(TCPIP_NT) do |reg|
71
+ reg.read_s_expand('DataBasePath')
72
+ end
73
+ end
74
+
75
+ def get_info
76
+ search = nil
77
+ nameserver = get_dns_server_list
78
+ Registry::HKEY_LOCAL_MACHINE.open(TCPIP_NT) do |reg|
79
+ begin
80
+ slist = reg.read_s('SearchList')
81
+ search = slist.split(/,\s*/) unless slist.empty?
82
+ rescue Registry::Error
83
+ end
84
+
85
+ if add_search = search.nil?
86
+ search = []
87
+ begin
88
+ nvdom = reg.read_s('NV Domain')
89
+ unless nvdom.empty?
90
+ @search = [ nvdom ]
91
+ if reg.read_i('UseDomainNameDevolution') != 0
92
+ if /^\w+\./ =~ nvdom
93
+ devo = $'
94
+ end
95
+ end
96
+ end
97
+ rescue Registry::Error
98
+ end
99
+ end
100
+
101
+ reg.open('Interfaces') do |h|
102
+ h.each_key do |iface, |
103
+ h.open(iface) do |regif|
104
+ next unless ns = %w[NameServer DhcpNameServer].find do |key|
105
+ begin
106
+ ns = regif.read_s(key)
107
+ rescue Registry::Error
108
+ else
109
+ break ns.split(/[,\s]\s*/) unless ns.empty?
110
+ end
111
+ end
112
+ next if (nameserver & ns).empty?
113
+
114
+ if add_search
115
+ begin
116
+ [ 'Domain', 'DhcpDomain' ].each do |key|
117
+ dom = regif.read_s(key)
118
+ unless dom.empty?
119
+ search.concat(dom.split(/,\s*/))
120
+ break
121
+ end
122
+ end
123
+ rescue Registry::Error
124
+ end
125
+ end
126
+ end
127
+ end
128
+ end
129
+ search << devo if add_search and devo
130
+ end
131
+ [ search.uniq, nameserver.uniq ]
132
+ end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,65 @@
1
+ #include <ruby.h>
2
+ #include <ruby/encoding.h>
3
+ #include <windows.h>
4
+ #ifndef NTDDI_VERSION
5
+ #define NTDDI_VERSION 0x06000000
6
+ #endif
7
+ #include <iphlpapi.h>
8
+
9
+ static VALUE
10
+ w32error_make_error(DWORD e)
11
+ {
12
+ VALUE code = ULONG2NUM(e);
13
+ return rb_class_new_instance(1, &code, rb_path2class("Win32::Resolv::Error"));
14
+ }
15
+
16
+ static void
17
+ w32error_raise(DWORD e)
18
+ {
19
+ rb_exc_raise(w32error_make_error(e));
20
+ }
21
+
22
+ static VALUE
23
+ get_dns_server_list(VALUE self)
24
+ {
25
+ FIXED_INFO *fixedinfo = NULL;
26
+ ULONG buflen = 0;
27
+ DWORD ret;
28
+ VALUE buf, nameservers = Qnil;
29
+
30
+ ret = GetNetworkParams(NULL, &buflen);
31
+ if (ret != NO_ERROR && ret != ERROR_BUFFER_OVERFLOW) {
32
+ w32error_raise(ret);
33
+ }
34
+ fixedinfo = ALLOCV(buf, buflen);
35
+ ret = GetNetworkParams(fixedinfo, &buflen);
36
+ if (ret == NO_ERROR) {
37
+ const IP_ADDR_STRING *ipaddr = &fixedinfo->DnsServerList;
38
+ nameservers = rb_ary_new();
39
+ do {
40
+ const char *s = ipaddr->IpAddress.String;
41
+ if (!*s) continue;
42
+ if (strcmp(s, "0.0.0.0") == 0) continue;
43
+ rb_ary_push(nameservers, rb_str_new_cstr(s));
44
+ } while ((ipaddr = ipaddr->Next) != NULL);
45
+ }
46
+ ALLOCV_END(buf);
47
+ if (ret != NO_ERROR) w32error_raise(ret);
48
+
49
+ return nameservers;
50
+ }
51
+
52
+ void
53
+ InitVM_resolv(void)
54
+ {
55
+ VALUE mWin32 = rb_define_module("Win32");
56
+ VALUE resolv = rb_define_module_under(mWin32, "Resolv");
57
+ VALUE singl = rb_singleton_class(resolv);
58
+ rb_define_private_method(singl, "get_dns_server_list", get_dns_server_list, 0);
59
+ }
60
+
61
+ void
62
+ Init_resolv(void)
63
+ {
64
+ InitVM(resolv);
65
+ }
data/lib/resolv.rb CHANGED
@@ -37,7 +37,7 @@ end
37
37
 
38
38
  class Resolv
39
39
 
40
- VERSION = "0.4.0"
40
+ VERSION = "0.5.0"
41
41
 
42
42
  ##
43
43
  # Looks up the first IP address for +name+.
@@ -396,13 +396,15 @@ class Resolv
396
396
  # be a Resolv::IPv4 or Resolv::IPv6
397
397
 
398
398
  def each_address(name)
399
- each_resource(name, Resource::IN::A) {|resource| yield resource.address}
400
399
  if use_ipv6?
401
400
  each_resource(name, Resource::IN::AAAA) {|resource| yield resource.address}
402
401
  end
402
+ each_resource(name, Resource::IN::A) {|resource| yield resource.address}
403
403
  end
404
404
 
405
405
  def use_ipv6? # :nodoc:
406
+ @config.lazy_initialize unless @config.instance_variable_get(:@initialized)
407
+
406
408
  use_ipv6 = @config.use_ipv6?
407
409
  unless use_ipv6.nil?
408
410
  return use_ipv6
@@ -513,35 +515,40 @@ class Resolv
513
515
 
514
516
  def fetch_resource(name, typeclass)
515
517
  lazy_initialize
516
- begin
517
- requester = make_udp_requester
518
+ truncated = {}
519
+ requesters = {}
520
+ udp_requester = begin
521
+ make_udp_requester
518
522
  rescue Errno::EACCES
519
523
  # fall back to TCP
520
524
  end
521
525
  senders = {}
526
+
522
527
  begin
523
- @config.resolv(name) {|candidate, tout, nameserver, port|
524
- requester ||= make_tcp_requester(nameserver, port)
528
+ @config.resolv(name) do |candidate, tout, nameserver, port|
525
529
  msg = Message.new
526
530
  msg.rd = 1
527
531
  msg.add_question(candidate, typeclass)
528
- unless sender = senders[[candidate, nameserver, port]]
532
+
533
+ requester = requesters.fetch([nameserver, port]) do
534
+ if !truncated[candidate] && udp_requester
535
+ udp_requester
536
+ else
537
+ requesters[[nameserver, port]] = make_tcp_requester(nameserver, port)
538
+ end
539
+ end
540
+
541
+ unless sender = senders[[candidate, requester, nameserver, port]]
529
542
  sender = requester.sender(msg, candidate, nameserver, port)
530
543
  next if !sender
531
- senders[[candidate, nameserver, port]] = sender
544
+ senders[[candidate, requester, nameserver, port]] = sender
532
545
  end
533
546
  reply, reply_name = requester.request(sender, tout)
534
547
  case reply.rcode
535
548
  when RCode::NoError
536
549
  if reply.tc == 1 and not Requester::TCP === requester
537
- requester.close
538
550
  # Retry via TCP:
539
- requester = make_tcp_requester(nameserver, port)
540
- senders = {}
541
- # This will use TCP for all remaining candidates (assuming the
542
- # current candidate does not already respond successfully via
543
- # TCP). This makes sense because we already know the full
544
- # response will not fit in an untruncated UDP packet.
551
+ truncated[candidate] = true
545
552
  redo
546
553
  else
547
554
  yield(reply, reply_name)
@@ -552,9 +559,10 @@ class Resolv
552
559
  else
553
560
  raise Config::OtherResolvError.new(reply_name.to_s)
554
561
  end
555
- }
562
+ end
556
563
  ensure
557
- requester&.close
564
+ udp_requester&.close
565
+ requesters.each_value { |requester| requester&.close }
558
566
  end
559
567
  end
560
568
 
@@ -569,6 +577,11 @@ class Resolv
569
577
 
570
578
  def make_tcp_requester(host, port) # :nodoc:
571
579
  return Requester::TCP.new(host, port)
580
+ rescue Errno::ECONNREFUSED
581
+ # Treat a refused TCP connection attempt to a nameserver like a timeout,
582
+ # as Resolv::DNS::Config#resolv considers ResolvTimeout exceptions as a
583
+ # hint to try the next nameserver:
584
+ raise ResolvTimeout
572
585
  end
573
586
 
574
587
  def extract_resources(msg, name, typeclass) # :nodoc:
@@ -1800,7 +1813,6 @@ class Resolv
1800
1813
  end
1801
1814
  end
1802
1815
 
1803
-
1804
1816
  ##
1805
1817
  # Base class for SvcParam. [RFC9460]
1806
1818
 
@@ -2499,7 +2511,6 @@ class Resolv
2499
2511
 
2500
2512
  attr_reader :altitude
2501
2513
 
2502
-
2503
2514
  def encode_rdata(msg) # :nodoc:
2504
2515
  msg.put_bytes(@version)
2505
2516
  msg.put_bytes(@ssize.scalar)
@@ -3439,4 +3450,3 @@ class Resolv
3439
3450
  AddressRegex = /(?:#{IPv4::Regex})|(?:#{IPv6::Regex})/
3440
3451
 
3441
3452
  end
3442
-
data/resolv.gemspec CHANGED
@@ -16,6 +16,7 @@ Gem::Specification.new do |spec|
16
16
  spec.homepage = "https://github.com/ruby/resolv"
17
17
  spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
18
18
  spec.licenses = ["Ruby", "BSD-2-Clause"]
19
+ spec.extensions << "ext/win32/resolv/extconf.rb"
19
20
 
20
21
  spec.metadata["homepage_uri"] = spec.homepage
21
22
  spec.metadata["source_code_uri"] = spec.homepage
metadata CHANGED
@@ -1,30 +1,38 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: resolv
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tanaka Akira
8
+ autorequire:
8
9
  bindir: exe
9
10
  cert_chain: []
10
- date: 2024-03-19 00:00:00.000000000 Z
11
+ date: 2024-11-11 00:00:00.000000000 Z
11
12
  dependencies: []
12
13
  description: Thread-aware DNS resolver library in Ruby.
13
14
  email:
14
15
  - akr@fsij.org
15
16
  executables: []
16
- extensions: []
17
+ extensions:
18
+ - ext/win32/resolv/extconf.rb
17
19
  extra_rdoc_files: []
18
20
  files:
21
+ - ".git-blame-ignore-revs"
19
22
  - ".github/dependabot.yml"
23
+ - ".github/workflows/push_gem.yml"
20
24
  - ".github/workflows/test.yml"
21
25
  - ".gitignore"
26
+ - BSDL
27
+ - COPYING
22
28
  - Gemfile
23
- - LICENSE.txt
24
29
  - README.md
25
30
  - Rakefile
26
31
  - bin/console
27
32
  - bin/setup
33
+ - ext/win32/resolv/extconf.rb
34
+ - ext/win32/resolv/lib/win32/resolv.rb
35
+ - ext/win32/resolv/resolv.c
28
36
  - lib/resolv.rb
29
37
  - resolv.gemspec
30
38
  homepage: https://github.com/ruby/resolv
@@ -34,6 +42,7 @@ licenses:
34
42
  metadata:
35
43
  homepage_uri: https://github.com/ruby/resolv
36
44
  source_code_uri: https://github.com/ruby/resolv
45
+ post_install_message:
37
46
  rdoc_options: []
38
47
  require_paths:
39
48
  - lib
@@ -48,7 +57,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
48
57
  - !ruby/object:Gem::Version
49
58
  version: '0'
50
59
  requirements: []
51
- rubygems_version: 3.6.0.dev
60
+ rubygems_version: 3.5.11
61
+ signing_key:
52
62
  specification_version: 4
53
63
  summary: Thread-aware DNS resolver library in Ruby.
54
64
  test_files: []