Details

    • Type: Bug Bug
    • Status: Closed Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: ejabberd 2.0.0-beta, ejabberd 2.0.0, ejabberd 2.0.1, ejabberd 2.0.2, ejabberd 2.0.3
    • Component/s: s2s
    • Labels:
      None
    • Environment:
      Windows

      Description

      all srv lookups fail on windows machines with timeout:

      =INFO REPORT==== 2009-01-27 22:37:17 ===
      D(<0.416.0>:ejabberd_s2s_out:956) : srv lookup of 'gmail.com' failed: timeout

      this problem came up several times in the erlang mailing list and in the ejabberd bugtracker. It was not resolved yet.

      see:
      http://erlang.org/pipermail/erlang-bugs/2007-September/000415.html
      https://support.process-one.net/browse/EJAB-493;jsessionid=D5F16309A909F58662EC768FD175C4DE

      1. 860-ipconfig.diff
        2 kB
        Badlop
      2. 860-windows-add-dnssrv.diff
        2 kB
        Badlop
      3. dns_test.erl
        3 kB
        Geoff Cant
      4. ejabberd_app.beam
        4 kB
        Badlop

        Issue Links

          Activity

          Hide
          Badlop
          added a comment -

          I've tried in Windows XP and Vista, using ejabberd 2.0.0-rc1, 2.0.3 and Erlang R10B-10, R11B-5 and R12B-5.

          In all cases the proposed solutions:

          • 'erl -name' instead of '-sname'
          • '-kernel inetrc FILE' where contents of FILE is: { registry, win32 }

            .

          • ERL_INETRC=FILE; export $ERL_INETRC

          did not help:

          erl -name asd@qwe
          
          Erlang (BEAM) emulator version 5.6.4 [async-threads:0]
          Eshell V5.6.4  (abort with ^G)
          
          (asd@qwe)1> inet:get_rc().
          [{host,{127,0,0,1},["localhost"]},
           {search,[[]]},
           {lookup,[native]}]
          
          (asd@qwe)2> inet_res:getbyname("_xmpp-server._tcp.digium.com", srv).
          {error,timeout}
          

          A workaround that works for me is to explicitly put some name servers in ejabberd-2.0.3/conf/inetrc In this example I set OpenDNS IPs:

          {nameserver, {208,67,222,222}}.
          {nameserver, {208,67,220,220}}.
          {registry, win32}.
          

          That way I can resolve:

          erl -name asd@qwe
          
          Erlang (BEAM) emulator version 5.6.4 [async-threads:0]
          Eshell V5.6.4  (abort with ^G)
          
          (asd@qwe)1> inet:get_rc().
          [{host,{127,0,0,1},["localhost"]},
           {nameserver,{208,67,222,222}},
           {nameserver,{208,67,220,220}},
           {search,[[]]},
           {lookup,[native]}]
          
          (asd@qwe)2> inet_res:getbyname("_xmpp-server._tcp.digium.com", srv).
          {ok,{hostent,"_xmpp-server._tcp.digium.com",[],srv,1,
                       [{5,0,5269,"jabber.digium.com"}]}}
          

          It would be preferable that Erlang automatically gets the name servers defined in the machine, instead of requiring the admin to explicitly define them in that file.

          Show
          Badlop
          added a comment - I've tried in Windows XP and Vista, using ejabberd 2.0.0-rc1, 2.0.3 and Erlang R10B-10, R11B-5 and R12B-5. In all cases the proposed solutions: 'erl -name' instead of '-sname' '-kernel inetrc FILE' where contents of FILE is: { registry, win32 } . ERL_INETRC=FILE; export $ERL_INETRC did not help: erl -name asd@qwe Erlang (BEAM) emulator version 5.6.4 [async-threads:0] Eshell V5.6.4 (abort with ^G) (asd@qwe)1> inet:get_rc(). [{host,{127,0,0,1},[ "localhost" ]}, {search,[[]]}, {lookup,[ native ]}] (asd@qwe)2> inet_res:getbyname( "_xmpp-server._tcp.digium.com" , srv). {error,timeout} A workaround that works for me is to explicitly put some name servers in ejabberd-2.0.3/conf/inetrc In this example I set OpenDNS IPs: {nameserver, {208,67,222,222}}. {nameserver, {208,67,220,220}}. {registry, win32}. That way I can resolve: erl -name asd@qwe Erlang (BEAM) emulator version 5.6.4 [async-threads:0] Eshell V5.6.4 (abort with ^G) (asd@qwe)1> inet:get_rc(). [{host,{127,0,0,1},[ "localhost" ]}, {nameserver,{208,67,222,222}}, {nameserver,{208,67,220,220}}, {search,[[]]}, {lookup,[ native ]}] (asd@qwe)2> inet_res:getbyname( "_xmpp-server._tcp.digium.com" , srv). {ok,{hostent, "_xmpp-server._tcp.digium.com" ,[],srv,1, [{5,0,5269, "jabber.digium.com" }]}} It would be preferable that Erlang automatically gets the name servers defined in the machine, instead of requiring the admin to explicitly define them in that file.
          Hide
          Alexander Gnauck
          added a comment -

          thanks, I added my name server and can confirm that its working now.

          Show
          Alexander Gnauck
          added a comment - thanks, I added my name server and can confirm that its working now.
          Hide
          Badlop
          added a comment - - edited

          Alexander pointed me to two ways to get the name servers defined in Windows:

          The first alternative would require writing a C program and calling it either at installation time or when ejabberd starts.

          I prefer the second alternative. It could be like this:
          1. When ejabberd starts, check if if it is running in a Windows machine
          2. If so, call a new ejabberd function get_windows_nameservers/0 to get a list of IP tuples
          3. For each DNS IP, call inet_db:add_ns(IPTuple)

          get_windows_nameservers/0 would call os:cmd("ipconfig /all"), parse the resulting string and return a list of IP tuples.

          For example, given the string

          "\r\r\nConfiguración IP de Windows\r\r\n\r\r\n Nombre del host . . . . . . . . . : desktop\r\r\n Sufijo DNS principal . . . . . . : \r\r\n Tipo de nodo . . . . . . . . . . : desconocido\r\r\n Enrutamiento habilitado. . . . . .: No\r\r\n Proxy WINS habilitado. . . . . : No\r\r\n\r\r\nAdaptador Ethernet Conexión de área local :\r\r\n\r\r\n Sufijo de conexión específica DNS : \r\r\n Descripción. . . . . . . . . . . : Adaptador Ethernet PCI AMD PCNET Family\r\r\n Dirección física. . . . . . . . . : 08-00-27-B6-C8-55\r\r\n DHCP habilitado. . . . . . . . . : No\r\r\n Autoconfiguración habilitada. . . : Sí\r\r\n Dirección IP. . . . . . . . . . . : 10.0.2.15\r\r\n Máscara de subred . . . . . . . . : 255.255.255.0\r\r\n Puerta de enlace predeterminada : 10.0.2.2\r\r\n Servidor DHCP . . . . . . . . . . : 10.0.2.2\r\r\n Servidores DNS . . . . . . . . . .: 62.42.230.24\r\r\n 62.42.62.51\r\r\n Concesión obtenida . . . . . . . : martes, 03 de febrero de 2009 15:27:02\r\r\n Concesión expira . . . . . . . . .: miércoles, 04 de febrero de 2009 15:27:02\r\r\n"

          it would return

          [{ 62, 42, 230, 246 }, { 62, 42, 62, 51 }]

          Some possible problems:

          • The result of ipconfig is slightly different in each language, as the words are translated. The parsing code must be smart enough to extract correctly the IPs.
          • Maybe different versions of Windows provide different results for ipconfig. Alexander can provide example results of many different Windows versions, and I can test the erlang code with those examples.
          • Maybe future versions of Windows remove ipconfig, or strongly change its result. So, when new versions of Windows are published, this topic must be reevaluated again, unfortunately.
          Show
          Badlop
          added a comment - - edited Alexander pointed me to two ways to get the name servers defined in Windows: GetNetworkParams in Iphlpapi.dll Command line tool: ipconfig The first alternative would require writing a C program and calling it either at installation time or when ejabberd starts. I prefer the second alternative. It could be like this: 1. When ejabberd starts, check if if it is running in a Windows machine 2. If so, call a new ejabberd function get_windows_nameservers/0 to get a list of IP tuples 3. For each DNS IP, call inet_db:add_ns(IPTuple) get_windows_nameservers/0 would call os:cmd("ipconfig /all"), parse the resulting string and return a list of IP tuples. For example, given the string "\r\r\nConfiguración IP de Windows\r\r\n\r\r\n Nombre del host . . . . . . . . . : desktop\r\r\n Sufijo DNS principal . . . . . . : \r\r\n Tipo de nodo . . . . . . . . . . : desconocido\r\r\n Enrutamiento habilitado. . . . . .: No\r\r\n Proxy WINS habilitado. . . . . : No\r\r\n\r\r\nAdaptador Ethernet Conexión de área local :\r\r\n\r\r\n Sufijo de conexión específica DNS : \r\r\n Descripción. . . . . . . . . . . : Adaptador Ethernet PCI AMD PCNET Family\r\r\n Dirección física. . . . . . . . . : 08-00-27-B6-C8-55\r\r\n DHCP habilitado. . . . . . . . . : No\r\r\n Autoconfiguración habilitada. . . : Sí\r\r\n Dirección IP. . . . . . . . . . . : 10.0.2.15\r\r\n Máscara de subred . . . . . . . . : 255.255.255.0\r\r\n Puerta de enlace predeterminada : 10.0.2.2\r\r\n Servidor DHCP . . . . . . . . . . : 10.0.2.2\r\r\n Servidores DNS . . . . . . . . . .: 62.42.230.24\r\r\n 62.42.62.51\r\r\n Concesión obtenida . . . . . . . : martes, 03 de febrero de 2009 15:27:02\r\r\n Concesión expira . . . . . . . . .: miércoles, 04 de febrero de 2009 15:27:02\r\r\n" it would return [{ 62, 42, 230, 246 }, { 62, 42, 62, 51 }] Some possible problems: The result of ipconfig is slightly different in each language, as the words are translated. The parsing code must be smart enough to extract correctly the IPs. Maybe different versions of Windows provide different results for ipconfig. Alexander can provide example results of many different Windows versions, and I can test the erlang code with those examples. Maybe future versions of Windows remove ipconfig, or strongly change its result. So, when new versions of Windows are published, this topic must be reevaluated again, unfortunately.
          Hide
          Badlop
          added a comment -

          This patch for ejabberd 2.0.3 solves the problem.

          The new code does this:

          1. When ejabberd starts, if it is running in a Windows machine, it calls 'ipconfig /all' to get the machine's network configuration.
          2. The response is parsed to extract the IP addresses of the DNS configured in the machine.
          3. Those IPs are added to the Erlang machine with inet_db:add_ns(IP).

          Alexander has provided me the results of ipconfig from several Windows versions: 2kserver, 2kworkstation, 2k3server, 2k8server, xppro, xpprov6, vista, windows7. I have tested that for all those versions, the patch parses it correctly and extracts the correct DNS IPs, including IPv4 and IPv6 addresses.

          How to install the attached binary file:

          1. ejabberd must be installed with ejabberd-2.0.3-windows-installer.exe
          2. Copy ejabberd_app.beam in the installed directory: ejabberd-2.0.3/lib/ejabberd-2.0.3/lib it will overwrite the previous file.
          3. Start ejabberd
          4. In the file logs/ejabberd.log you should see something like:
            =INFO REPORT==== 2009-02-04 11:49:47 ===
            I(<0.36.0>:ejabberd_app:188) : Adding machine's DNS IPs to Erlang system:
            [{61,22,230,24},{61,22,62,51}]
            

          If you want to verify that DNS SRV works correctly, you can try this:

          1. ejabberd is started with the patched file
          2. Execute: Start -> Programs -> ProcessOne -> Debug console
          3. In the Erlang console, try this command. If you get a similar response it means DNS SRV works correctly:
            Erlang (BEAM) emulator version 5.6.4 [async-threads:0]
            
            Eshell V5.6.4  (abort with ^G)
            (ejabberd@localhost)1> inet_res:getbyname("_xmpp-server._tcp.digium.com", srv).
            {ok,{hostent,"_xmpp-server._tcp.digium.com",[],srv,1,
                         [{5,0,5269,"jabber.digium.com"}]}}
            (ejabberd@localhost)2> 
            

          With that patch, the file inetrc is useless in Windows. However, it doesn't hurt to keep it in the installer, so I propose to not make any change in the installer. Maybe in the future the inetrc file works in Window's Erlang.

          Show
          Badlop
          added a comment - This patch for ejabberd 2.0.3 solves the problem. The new code does this: When ejabberd starts, if it is running in a Windows machine, it calls 'ipconfig /all' to get the machine's network configuration. The response is parsed to extract the IP addresses of the DNS configured in the machine. Those IPs are added to the Erlang machine with inet_db:add_ns(IP). Alexander has provided me the results of ipconfig from several Windows versions: 2kserver, 2kworkstation, 2k3server, 2k8server, xppro, xpprov6, vista, windows7. I have tested that for all those versions, the patch parses it correctly and extracts the correct DNS IPs, including IPv4 and IPv6 addresses. How to install the attached binary file: ejabberd must be installed with ejabberd-2.0.3-windows-installer.exe Copy ejabberd_app.beam in the installed directory: ejabberd-2.0.3/lib/ejabberd-2.0.3/lib it will overwrite the previous file. Start ejabberd In the file logs/ejabberd.log you should see something like: =INFO REPORT==== 2009-02-04 11:49:47 === I(<0.36.0>:ejabberd_app:188) : Adding machine's DNS IPs to Erlang system: [{61,22,230,24},{61,22,62,51}] If you want to verify that DNS SRV works correctly, you can try this: ejabberd is started with the patched file Execute: Start -> Programs -> ProcessOne -> Debug console In the Erlang console, try this command. If you get a similar response it means DNS SRV works correctly: Erlang (BEAM) emulator version 5.6.4 [async-threads:0] Eshell V5.6.4 (abort with ^G) (ejabberd@localhost)1> inet_res:getbyname( "_xmpp-server._tcp.digium.com" , srv). {ok,{hostent, "_xmpp-server._tcp.digium.com" ,[],srv,1, [{5,0,5269, "jabber.digium.com" }]}} (ejabberd@localhost)2> With that patch, the file inetrc is useless in Windows. However, it doesn't hurt to keep it in the installer, so I propose to not make any change in the installer. Maybe in the future the inetrc file works in Window's Erlang.
          Hide
          Badlop
          added a comment -

          The DNS SRV Erlang Windows problem can have several solutions:
          A) erlang code to call ipconfig and parse result
          B) write a patch for erlang/otp and submit it
          C) C code to call a windows api and parse result

          The patch 860-ipconfig.diff for ejabberd trunk implements option A in 50 lines of erlang code.

          I have tested it to work in Windows XP Spanish, and many German versions of Windows.

          When preparing the ejabberd 2.1.0 release, if there isn't any other working patch, this one will be committed.

          Show
          Badlop
          added a comment - The DNS SRV Erlang Windows problem can have several solutions: A) erlang code to call ipconfig and parse result B) write a patch for erlang/otp and submit it C) C code to call a windows api and parse result The patch 860-ipconfig.diff for ejabberd trunk implements option A in 50 lines of erlang code. I have tested it to work in Windows XP Spanish, and many German versions of Windows. When preparing the ejabberd 2.1.0 release, if there isn't any other working patch, this one will be committed.
          Hide
          Geoff Cant
          added a comment -

          The dns_test file shows how to retrieve NameServer settings from the windows registry. OTP already does this in the inet_config module, but it seems that windows has moved where it stores the data in the registry. When I get more access to a windows machine I'll try and update inet_config and send the patch to the OTP team for some future erlang release.

          I think the data in the registry will be less susceptible to ipconfig locale settings - but someone needs to come up with an algorithm for selecting one or more dns servers to use.

          My pick would be to examine the NameServer configuration for each interface one by one, and use inet_res:nnslookup/5 to try a well known query specifying the nameserver for the selected interface. If this lookup succeeds then add all the NameServers for this interface, otherwise, try the next interface.

          The well known query should be something that all dns servers are expected to have a local copy of like the list of root name servers - if you query for "." IN NS and get any results then the nameserver is almost certainly working.

          Show
          Geoff Cant
          added a comment - The dns_test file shows how to retrieve NameServer settings from the windows registry. OTP already does this in the inet_config module, but it seems that windows has moved where it stores the data in the registry. When I get more access to a windows machine I'll try and update inet_config and send the patch to the OTP team for some future erlang release. I think the data in the registry will be less susceptible to ipconfig locale settings - but someone needs to come up with an algorithm for selecting one or more dns servers to use. My pick would be to examine the NameServer configuration for each interface one by one, and use inet_res:nnslookup/5 to try a well known query specifying the nameserver for the selected interface. If this lookup succeeds then add all the NameServers for this interface, otherwise, try the next interface. The well known query should be something that all dns servers are expected to have a local copy of like the list of root name servers - if you query for "." IN NS and get any results then the nameserver is almost certainly working.
          Hide
          Badlop
          added a comment -

          I've replaced my ipconfig-code with Geoff Cant's module, with some minor additions.

          Applied to 2.0.x, trunk and road-to-exmpp branches in SVN r1968.

          Show
          Badlop
          added a comment - I've replaced my ipconfig-code with Geoff Cant's module, with some minor additions. Applied to 2.0.x, trunk and road-to-exmpp branches in SVN r1968.

            People

            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:
                Days since last comment:
                5 years, 7 weeks, 5 days ago

                Issue deployment