diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2016-07-31 07:17:25 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2016-07-31 07:17:25 +0000 |
commit | 925d48e4969c9fdcf558ddfa4ac95443eb464393 (patch) | |
tree | 44e34cbbe1bdea04da1037a68279b76137cc2622 /ext/win32/resolv | |
parent | bfb5b0f84b87387ab85819dd155fb91f1e873e01 (diff) | |
download | ruby-925d48e4969c9fdcf558ddfa4ac95443eb464393.tar.gz |
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
Diffstat (limited to 'ext/win32/resolv')
-rw-r--r-- | ext/win32/resolv/extconf.rb | 1 | ||||
-rw-r--r-- | ext/win32/resolv/resolv.c | 72 |
2 files changed, 73 insertions, 0 deletions
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..03252f5ffc --- /dev/null +++ b/ext/win32/resolv/resolv.c @@ -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); +} |