summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authornagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-02-07 17:28:57 +0000
committernagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-02-07 17:28:57 +0000
commitc59b391332768ab3742baa35871457dee66e797e (patch)
treeb05734e60b9f3a0fdeeae0c5f7a43a046c39fa36 /ext
parent1034b6d23dee1ab33e5da4f5d816b2af0cefc062 (diff)
merge revision(s) 55781,55783: [Backport #12604]
* ext/win32/resolv/resolv.c (get_dns_server_list): [Win32] get DNS servers only for connected network devices by GetNetworkParams API. [Bug #12604] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_3@57571 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext')
-rw-r--r--ext/win32/lib/win32/resolv.rb28
-rw-r--r--ext/win32/resolv/extconf.rb1
-rw-r--r--ext/win32/resolv/resolv.c71
3 files changed, 87 insertions, 13 deletions
diff --git a/ext/win32/lib/win32/resolv.rb b/ext/win32/lib/win32/resolv.rb
index 183d5d38da..18294c3f8b 100644
--- a/ext/win32/lib/win32/resolv.rb
+++ b/ext/win32/lib/win32/resolv.rb
@@ -33,6 +33,12 @@ module Win32
end
[ search, nameserver ]
end
+end
+
+begin
+ require 'win32/resolv.so'
+rescue LoadError
+end
module Kernel32
extend Importer
@@ -42,6 +48,7 @@ getv = Kernel32.extern "int GetVersionExA(void *)", :stdcall
info = [ 148, 0, 0, 0, 0 ].pack('V5') + "\0" * 128
getv.call(info)
if info.unpack('V5')[4] == 2 # VER_PLATFORM_WIN32_NT
+module Win32
#====================================================================
# Windows NT
#====================================================================
@@ -58,7 +65,7 @@ if info.unpack('V5')[4] == 2 # VER_PLATFORM_WIN32_NT
def get_info
search = nil
- nameserver = []
+ nameserver = get_dns_server_list
Registry::HKEY_LOCAL_MACHINE.open(TCPIP_NT) do |reg|
begin
slist = reg.read_s('SearchList')
@@ -85,20 +92,15 @@ if info.unpack('V5')[4] == 2 # VER_PLATFORM_WIN32_NT
reg.open('Interfaces') do |h|
h.each_key do |iface,|
h.open(iface) do |regif|
- begin
- [ 'NameServer', 'DhcpNameServer' ].each do |key|
- begin
- ns = regif.read_s(key)
- rescue
- else
- unless ns.empty?
- nameserver.concat(ns.split(/[,\s]\s*/))
- break
- end
- end
+ next unless ns = %w[NameServer DhcpNameServer].find do |key|
+ begin
+ ns = regif.read_s(key)
+ rescue Registry::Error
+ else
+ break ns.split(/[,\s]\s*/) unless ns.empty?
end
- rescue Registry::Error
end
+ next if (nameserver & ns).empty?
if add_search
begin
diff --git a/ext/win32/resolv/extconf.rb b/ext/win32/resolv/extconf.rb
new file mode 100644
index 0000000000..2ae4bb29f7
--- /dev/null
+++ b/ext/win32/resolv/extconf.rb
@@ -0,0 +1 @@
+create_makefile('win32/resolv')
diff --git a/ext/win32/resolv/resolv.c b/ext/win32/resolv/resolv.c
new file mode 100644
index 0000000000..436d62cc7b
--- /dev/null
+++ b/ext/win32/resolv/resolv.c
@@ -0,0 +1,71 @@
+#include <ruby.h>
+#include <ruby/encoding.h>
+#include <iphlpapi.h>
+
+static VALUE
+w32error_init(VALUE self, VALUE code)
+{
+ VALUE str = rb_str_new_cstr(rb_w32_strerror(NUM2INT(code)));
+ rb_ivar_set(self, rb_intern("@code"), code);
+ return rb_call_super(1, &str);
+}
+
+static VALUE
+w32error_make_error(DWORD e)
+{
+ VALUE code = ULONG2NUM(e);
+ return rb_class_new_instance(1, &code, rb_path2class("Win32::Error"));
+}
+
+static void
+w32error_raise(DWORD e)
+{
+ rb_exc_raise(w32error_make_error(e));
+}
+
+static VALUE
+get_dns_server_list(VALUE self)
+{
+ FIXED_INFO *fixedinfo = NULL;
+ ULONG buflen = 0;
+ DWORD ret;
+ VALUE buf, nameservers = Qnil;
+
+ ret = GetNetworkParams(NULL, &buflen);
+ if (ret != NO_ERROR && ret != ERROR_BUFFER_OVERFLOW) {
+ w32error_raise(ret);
+ }
+ fixedinfo = ALLOCV(buf, buflen);
+ ret = GetNetworkParams(fixedinfo, &buflen);
+ if (ret == NO_ERROR) {
+ const IP_ADDR_STRING *ipaddr = &fixedinfo->DnsServerList;
+ nameservers = rb_ary_new();
+ do {
+ const char *s = ipaddr->IpAddress.String;
+ if (!*s) continue;
+ if (strcmp(s, "0.0.0.0") == 0) continue;
+ rb_ary_push(nameservers, rb_str_new_cstr(s));
+ } while ((ipaddr = ipaddr->Next) != NULL);
+ }
+ ALLOCV_END(buf);
+ if (ret != NO_ERROR) w32error_raise(ret);
+
+ return nameservers;
+}
+
+void
+InitVM_resolv(void)
+{
+ VALUE mWin32 = rb_define_module("Win32");
+ VALUE resolv = rb_define_module_under(mWin32, "Resolv");
+ VALUE singl = rb_singleton_class(resolv);
+ VALUE eclass = rb_define_class_under(mWin32, "Error", rb_eStandardError);
+ rb_define_method(eclass, "initialize", w32error_init, 1);
+ rb_define_private_method(singl, "get_dns_server_list", get_dns_server_list, 0);
+}
+
+void
+Init_resolv(void)
+{
+ InitVM(resolv);
+}