win32/resolv: get_dns_server_list
* 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/trunk@55781 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
bfb5b0f84b
commit
925d48e496
@ -1,3 +1,9 @@
|
|||||||
|
Sun Jul 31 16:17:23 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* ext/win32/resolv/resolv.c (get_dns_server_list): [Win32] get DNS
|
||||||
|
servers only for connected network devices by GetNetworkParams
|
||||||
|
API. [Bug #12604]
|
||||||
|
|
||||||
Sat Jul 30 12:13:26 2016 Martin Duerst <duerst@it.aoyama.ac.jp>
|
Sat Jul 30 12:13:26 2016 Martin Duerst <duerst@it.aoyama.ac.jp>
|
||||||
|
|
||||||
* string.c (String#downcase), NEWS: Mentioned that case mapping for all
|
* string.c (String#downcase), NEWS: Mentioned that case mapping for all
|
||||||
|
@ -34,6 +34,12 @@ module Win32
|
|||||||
[ search, nameserver ]
|
[ search, nameserver ]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
begin
|
||||||
|
require 'win32/resolv.so'
|
||||||
|
rescue LoadError
|
||||||
|
end
|
||||||
|
|
||||||
nt = Module.new do
|
nt = Module.new do
|
||||||
break true if [nil].pack("p").size > 4
|
break true if [nil].pack("p").size > 4
|
||||||
@ -48,6 +54,7 @@ if not nt
|
|||||||
require_relative 'resolv9x'
|
require_relative 'resolv9x'
|
||||||
# return # does not work yet
|
# return # does not work yet
|
||||||
else
|
else
|
||||||
|
module Win32
|
||||||
#====================================================================
|
#====================================================================
|
||||||
# Windows NT
|
# Windows NT
|
||||||
#====================================================================
|
#====================================================================
|
||||||
@ -64,7 +71,7 @@ else
|
|||||||
|
|
||||||
def get_info
|
def get_info
|
||||||
search = nil
|
search = nil
|
||||||
nameserver = []
|
nameserver = get_dns_server_list
|
||||||
Registry::HKEY_LOCAL_MACHINE.open(TCPIP_NT) do |reg|
|
Registry::HKEY_LOCAL_MACHINE.open(TCPIP_NT) do |reg|
|
||||||
begin
|
begin
|
||||||
slist = reg.read_s('SearchList')
|
slist = reg.read_s('SearchList')
|
||||||
@ -91,20 +98,15 @@ else
|
|||||||
reg.open('Interfaces') do |h|
|
reg.open('Interfaces') do |h|
|
||||||
h.each_key do |iface, |
|
h.each_key do |iface, |
|
||||||
h.open(iface) do |regif|
|
h.open(iface) do |regif|
|
||||||
begin
|
next unless ns = %w[NameServer DhcpNameServer].find do |key|
|
||||||
[ 'NameServer', 'DhcpNameServer' ].each do |key|
|
|
||||||
begin
|
begin
|
||||||
ns = regif.read_s(key)
|
ns = regif.read_s(key)
|
||||||
rescue
|
|
||||||
else
|
|
||||||
unless ns.empty?
|
|
||||||
nameserver.concat(ns.split(/[,\s]\s*/))
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
rescue Registry::Error
|
rescue Registry::Error
|
||||||
|
else
|
||||||
|
break ns.split(/[,\s]\s*/) unless ns.empty?
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
next if (nameserver & ns).empty?
|
||||||
|
|
||||||
if add_search
|
if add_search
|
||||||
begin
|
begin
|
||||||
|
1
ext/win32/resolv/extconf.rb
Normal file
1
ext/win32/resolv/extconf.rb
Normal file
@ -0,0 +1 @@
|
|||||||
|
create_makefile('win32/resolv')
|
72
ext/win32/resolv/resolv.c
Normal file
72
ext/win32/resolv/resolv.c
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
#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)
|
||||||
|
{
|
||||||
|
message_free = (rb_w32_osver() >= 10) ? heap_free : local_free;
|
||||||
|
InitVM(resolv);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user