25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-12-24 17:29:28 +01:00

* src/ejabberd_app.erl: In a Windows machine, explicitly add the

nameservers, as it seems Erlang does not do itself (EJAB-860)
* src/win32_dns.erl: Get name servers from Windows registy (thanks
to Geoff Cant)

SVN Revision: 1968
This commit is contained in:
Badlop 2009-03-05 20:03:18 +00:00
parent 5cc3985b73
commit f826dc2f9f
3 changed files with 141 additions and 0 deletions

View File

@ -1,5 +1,10 @@
2009-03-05 Badlop <badlop@process-one.net>
* src/ejabberd_app.erl: In a Windows machine, explicitly add the
nameservers, as it seems Erlang does not do itself (EJAB-860)
* src/win32_dns.erl: Get name servers from Windows registy (thanks
to Geoff Cant)
* doc/guide.tex: Require OpenSSL 0.9.8f or higher (EJAB-877)
* doc/guide.html: Likewise

View File

@ -63,6 +63,7 @@ start(normal, _Args) ->
%eprof:start(),
%eprof:profile([self()]),
%fprof:trace(start, "/tmp/fprof"),
maybe_add_nameservers(),
start_modules(),
ejabberd_listener:start_listeners(),
?INFO_MSG("ejabberd ~s is started in the node ~p", [?VERSION, node()]),
@ -180,3 +181,16 @@ get_log_path() ->
Path
end
end.
%% If ejabberd is running on some Windows machine, get nameservers and add to Erlang
maybe_add_nameservers() ->
case os:type() of
{win32, _} -> add_windows_nameservers();
_ -> ok
end.
add_windows_nameservers() ->
IPTs = win32_dns_test:get_nameservers(),
?INFO_MSG("Adding machine's DNS IPs to Erlang system:~n~p", [IPTs]),
lists:foreach(fun(IPT) -> inet_db:add_ns(IPT) end, IPTs).

122
src/win32_dns.erl Normal file
View File

@ -0,0 +1,122 @@
%%%----------------------------------------------------------------------
%%% File : win32_dns.erl
%%% Author : Geoff Cant
%%% Purpose : Get name servers in a Windows machine
%%% Created : 5 Mar 2009 by Geoff Cant
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
%%% published by the Free Software Foundation; either version 2 of the
%%% License, or (at your option) any later version.
%%%
%%% This program is distributed in the hope that it will be useful,
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%%
%%%----------------------------------------------------------------------
-module(win32_dns).
-export([get_nameservers/0]).
-define(IF_KEY, "\\hklm\\system\\CurrentControlSet\\Services\\TcpIp\\Parameters\\Interfaces").
-define(TOP_KEY, "\\hklm\\system\\CurrentControlSet\\Services\\TcpIp\\Parameters").
get_nameservers() ->
{_, Config} = pick_config(),
IPTs = get_value(["NameServer"], Config),
lists:filter(fun(IPTuple) -> is_good_ns(IPTuple) end, IPTs).
is_good_ns(Addr) ->
element(1,
inet_res:nnslookup("a.root-servers.net", in, any, [{Addr,53}],
timer:seconds(5)
)
) =:= ok.
reg() ->
{ok, R} = win32reg:open([read]),
R.
interfaces(R) ->
ok = win32reg:change_key(R, ?IF_KEY),
{ok, I} = win32reg:sub_keys(R),
I.
config_keys(R, Key) ->
ok = win32reg:change_key(R, Key),
[ {K,
case win32reg:value(R, K) of
{ok, V} -> translate(K, V);
_ -> undefined
end
} || K <- ["Domain", "DhcpDomain",
"NameServer", "DhcpNameServer", "SearchList"]].
translate(NS, V) when NS =:= "NameServer"; NS =:= "DhcpNameServer" ->
IPsStrings = [string:tokens(IP, ".") || IP <- string:tokens(V, ",")],
[ list_to_tuple([list_to_integer(String) || String <- IpStrings])
|| IpStrings <- IPsStrings];
translate(_, V) -> V.
interface_configs(R) ->
[{If, config_keys(R, ?IF_KEY ++ "\\" ++ If)}
|| If <- interfaces(R)].
sort_configs(Configs) ->
lists:sort(fun ({_, A}, {_, B}) ->
ANS = proplists:get_value("NameServer", A),
BNS = proplists:get_value("NameServer", B),
if ANS =/= undefined, BNS =:= undefined -> false;
true -> count_undef(A) < count_undef(B)
end
end,
Configs).
count_undef(L) when is_list(L) ->
lists:foldl(fun ({_K, undefined}, Acc) -> Acc +1;
({_K, []}, Acc) -> Acc +1;
(_, Acc) -> Acc
end, 0, L).
all_configs() ->
R = reg(),
TopConfig = config_keys(R, ?TOP_KEY),
Configs = [{top, TopConfig}
| interface_configs(R)],
win32reg:close(R),
{TopConfig, Configs}.
pick_config() ->
{TopConfig, Configs} = all_configs(),
NSConfigs = [{If, C} || {If, C} <- Configs,
get_value(["DhcpNameServer","NameServer"], C)
=/= undefined],
case get_value(["DhcpNameServer","NameServer"],
TopConfig) of
%% No top level nameserver to pick interface with
undefined ->
hd(sort_configs(NSConfigs));
%% Top level has a nameserver - use this to select an interface.
NS ->
Cs = [ {If, C}
|| {If, C} <- Configs,
lists:member(NS,
[get_value(["NameServer"], C),
get_value(["DhcpNameServer"], C)])],
hd(sort_configs(Cs))
end.
get_value([], _Config) -> undefined;
get_value([K|Keys], Config) ->
case proplists:get_value(K, Config) of
undefined -> get_value(Keys, Config);
V -> V
end.