Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/processone/ejabberd.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBadlop <badlop@process-one.net>2009-03-05 23:03:18 +0300
committerBadlop <badlop@process-one.net>2009-03-05 23:03:18 +0300
commitac69fbb24daa2a641253f90cb7fe8e701a41f6eb (patch)
treee816e612bc5abdca4c68750cf4a52f772708e911
parent3454f2fe04f5efa39f95656883fee7c6fde4f1ef (diff)
* 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
-rw-r--r--ChangeLog5
-rw-r--r--src/ejabberd_app.erl13
-rw-r--r--src/win32_dns.erl122
3 files changed, 140 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 3b966a752..ffcb1d8ce 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/src/ejabberd_app.erl b/src/ejabberd_app.erl
index d914f73c5..1dad43cec 100644
--- a/src/ejabberd_app.erl
+++ b/src/ejabberd_app.erl
@@ -62,6 +62,7 @@ start(normal, _Args) ->
%eprof:start(),
%eprof:profile([self()]),
%fprof:trace(start, "/tmp/fprof"),
+ maybe_add_nameservers(),
start_modules(),
Sup;
start(_, _) ->
@@ -168,3 +169,15 @@ connect_nodes() ->
end, Nodes)
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).
diff --git a/src/win32_dns.erl b/src/win32_dns.erl
new file mode 100644
index 000000000..79725cbab
--- /dev/null
+++ b/src/win32_dns.erl
@@ -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.