You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@directory.apache.org by Stefan Seelmann <ma...@stefan-seelmann.de> on 2016/01/08 21:26:06 UTC

getLoopbackAddress() vs getLocalHost(), was: Bind Address of @CreateLdapServer/@CreateTransport

On 12/27/2015 12:22 AM, Emmanuel Lécharny wrote:
> Le 26/12/15 23:05, Stefan Seelmann a écrit :
>> Hi,
>>
>> in Studio integration tests we use our own ApacheDS test framwork with
>> @CreateLdapServer and @CreateTransport annotations, for example
>>
>> @RunWith(FrameworkRunner.class)
>> @CreateLdapServer(transports =
>>     { @CreateTransport(protocol = "LDAP"),
>>       @CreateTransport(protocol = "LDAPS") })
>>
>> Since upgrade to ApacheDS 2.0.0-M21 I noticed that the tests failed on
>> Jenkins, on a Linux server, and also on my Mac, but it works on my main
>> Linux Laptop. After some debugging I found out that the started ApacheDS
>> only binds to the public interface but not to the loopback device, and
>> in the Studio tests I create a connection with host "localhost" and then
>> only get a "connection refused".
>>
>> One workaround I tried is to bind to all network interfaces by changing
>> annotations to this:
>>
>> @CreateLdapServer(transports =
>>     { @CreateTransport(address = "0.0.0.0", protocol = "LDAP"),
>> +        @CreateTransport(address = "0.0.0.0", protocol = "LDAPS") })
>>
>> In ApacheDS tests i noticed that we don't use "localhost" but lookup the
>> hostname by our old friend
>>
>>     InetAddress.getLocalHost().getHostName()
>>
>> That would be the 2nd change I can do to fix Studio tests.
>>
>> But I wonder if it is good that the ApacheDS started by the test
>> framworks binds to public interace at all? I mean the default use case
>> is to run tests on the same hosts. I think it is not a good idea to bind
>> to public interface at all.
>>
>> Thoughts?
> 
> I think that listening on 0.0.0.0 is a bit wide. We surely should use
> the InetAddress.getLocalHost().getHostName()instead.
> 
> Actually, when you don't specify any address, here is what is used :
> 
> 
>         if ( Strings.isEmpty( address ) )
>         {
>             try
>             {
>                 address = InetAddress.getLocalHost().getHostName();
>             }
>             catch ( UnknownHostException uhe )
>             {
>                 // Default to "localhost"...
>                 address = "localhost";
>             }
>         }
> 
> so I guess you can do the same in Studio, instead of using Localhost.

Ok, I did that now: http://svn.apache.org/viewvc?rev=1723789&view=rev

However I think we should try to change that and use the following all
over in API, ApacheDS, Kerby, and Studio:

	InetAddress.getLoopbackAddress().getHostname();

Note getLoopbackAddress() instead of getLocalHost(). That method was
added in Java 7. According to javadoc it returns the the address of the
loopback device. It doesn't query DNS to looup the hostname and hence
also doesn't throw an UnknownHostException. I only see advantages in
using that method.

If there are now objection I'd try to change it. Thoughts?

Kind Reards,
Stefan


Re: getLoopbackAddress() vs getLocalHost(), was: Bind Address of @CreateLdapServer/@CreateTransport

Posted by Lucas Theisen <lu...@pastdev.com>.
On Jan 8, 2016 3:26 PM, "Stefan Seelmann" <ma...@stefan-seelmann.de> wrote:
>
> On 12/27/2015 12:22 AM, Emmanuel Lécharny wrote:
> > Le 26/12/15 23:05, Stefan Seelmann a écrit :
> >> Hi,
> >>
> >> in Studio integration tests we use our own ApacheDS test framwork with
> >> @CreateLdapServer and @CreateTransport annotations, for example
> >>
> >> @RunWith(FrameworkRunner.class)
> >> @CreateLdapServer(transports =
> >>     { @CreateTransport(protocol = "LDAP"),
> >>       @CreateTransport(protocol = "LDAPS") })
> >>
> >> Since upgrade to ApacheDS 2.0.0-M21 I noticed that the tests failed on
> >> Jenkins, on a Linux server, and also on my Mac, but it works on my main
> >> Linux Laptop. After some debugging I found out that the started
ApacheDS
> >> only binds to the public interface but not to the loopback device, and
> >> in the Studio tests I create a connection with host "localhost" and
then
> >> only get a "connection refused".
> >>
> >> One workaround I tried is to bind to all network interfaces by changing
> >> annotations to this:
> >>
> >> @CreateLdapServer(transports =
> >>     { @CreateTransport(address = "0.0.0.0", protocol = "LDAP"),
> >> +        @CreateTransport(address = "0.0.0.0", protocol = "LDAPS") })
> >>
> >> In ApacheDS tests i noticed that we don't use "localhost" but lookup
the
> >> hostname by our old friend
> >>
> >>     InetAddress.getLocalHost().getHostName()
> >>
> >> That would be the 2nd change I can do to fix Studio tests.
> >>
> >> But I wonder if it is good that the ApacheDS started by the test
> >> framworks binds to public interace at all? I mean the default use case
> >> is to run tests on the same hosts. I think it is not a good idea to
bind
> >> to public interface at all.
> >>
> >> Thoughts?
> >
> > I think that listening on 0.0.0.0 is a bit wide. We surely should use
> > the InetAddress.getLocalHost().getHostName()instead.
> >
> > Actually, when you don't specify any address, here is what is used :
> >
> >
> >         if ( Strings.isEmpty( address ) )
> >         {
> >             try
> >             {
> >                 address = InetAddress.getLocalHost().getHostName();
> >             }
> >             catch ( UnknownHostException uhe )
> >             {
> >                 // Default to "localhost"...
> >                 address = "localhost";
> >             }
> >         }
> >
> > so I guess you can do the same in Studio, instead of using Localhost.
>
> Ok, I did that now: http://svn.apache.org/viewvc?rev=1723789&view=rev
>
> However I think we should try to change that and use the following all
> over in API, ApacheDS, Kerby, and Studio:
>
>         InetAddress.getLoopbackAddress().getHostname();
>
> Note getLoopbackAddress() instead of getLocalHost(). That method was
> added in Java 7. According to javadoc it returns the the address of the
> loopback device. It doesn't query DNS to looup the hostname and hence
> also doesn't throw an UnknownHostException. I only see advantages in
> using that method.
>
> If there are now objection I'd try to change it. Thoughts?
>
> Kind Reards,
> Stefan
>

I wholeheartedly agree.  DNS lookup during unit tests is a horrible
pattern...

Lucas

Re: getLoopbackAddress() vs getLocalHost(), was: Bind Address of @CreateLdapServer/@CreateTransport

Posted by Emmanuel Lécharny <el...@gmail.com>.
Le 08/01/16 21:26, Stefan Seelmann a écrit :
> On 12/27/2015 12:22 AM, Emmanuel Lécharny wrote:
>> Le 26/12/15 23:05, Stefan Seelmann a écrit :
>>> Hi,
>>>
>>> in Studio integration tests we use our own ApacheDS test framwork with
>>> @CreateLdapServer and @CreateTransport annotations, for example
>>>
>>> @RunWith(FrameworkRunner.class)
>>> @CreateLdapServer(transports =
>>>     { @CreateTransport(protocol = "LDAP"),
>>>       @CreateTransport(protocol = "LDAPS") })
>>>
>>> Since upgrade to ApacheDS 2.0.0-M21 I noticed that the tests failed on
>>> Jenkins, on a Linux server, and also on my Mac, but it works on my main
>>> Linux Laptop. After some debugging I found out that the started ApacheDS
>>> only binds to the public interface but not to the loopback device, and
>>> in the Studio tests I create a connection with host "localhost" and then
>>> only get a "connection refused".
>>>
>>> One workaround I tried is to bind to all network interfaces by changing
>>> annotations to this:
>>>
>>> @CreateLdapServer(transports =
>>>     { @CreateTransport(address = "0.0.0.0", protocol = "LDAP"),
>>> +        @CreateTransport(address = "0.0.0.0", protocol = "LDAPS") })
>>>
>>> In ApacheDS tests i noticed that we don't use "localhost" but lookup the
>>> hostname by our old friend
>>>
>>>     InetAddress.getLocalHost().getHostName()
>>>
>>> That would be the 2nd change I can do to fix Studio tests.
>>>
>>> But I wonder if it is good that the ApacheDS started by the test
>>> framworks binds to public interace at all? I mean the default use case
>>> is to run tests on the same hosts. I think it is not a good idea to bind
>>> to public interface at all.
>>>
>>> Thoughts?
>> I think that listening on 0.0.0.0 is a bit wide. We surely should use
>> the InetAddress.getLocalHost().getHostName()instead.
>>
>> Actually, when you don't specify any address, here is what is used :
>>
>>
>>         if ( Strings.isEmpty( address ) )
>>         {
>>             try
>>             {
>>                 address = InetAddress.getLocalHost().getHostName();
>>             }
>>             catch ( UnknownHostException uhe )
>>             {
>>                 // Default to "localhost"...
>>                 address = "localhost";
>>             }
>>         }
>>
>> so I guess you can do the same in Studio, instead of using Localhost.
> Ok, I did that now: http://svn.apache.org/viewvc?rev=1723789&view=rev
>
> However I think we should try to change that and use the following all
> over in API, ApacheDS, Kerby, and Studio:
>
> 	InetAddress.getLoopbackAddress().getHostname();
>
> Note getLoopbackAddress() instead of getLocalHost(). That method was
> added in Java 7. According to javadoc it returns the the address of the
> loopback device. It doesn't query DNS to looup the hostname and hence
> also doesn't throw an UnknownHostException. I only see advantages in
> using that method.
>
> If there are now objection I'd try to change it. Thoughts?

No objection.

Thanks Stefan !

Re: getLoopbackAddress() vs getLocalHost(), was: Bind Address of @CreateLdapServer/@CreateTransport

Posted by Stefan Seelmann <ma...@stefan-seelmann.de>.
On 01/08/2016 09:26 PM, Stefan Seelmann wrote:
> On 12/27/2015 12:22 AM, Emmanuel Lécharny wrote:
>> Le 26/12/15 23:05, Stefan Seelmann a écrit :
>>> Hi,
>>>
>>> in Studio integration tests we use our own ApacheDS test framwork with
>>> @CreateLdapServer and @CreateTransport annotations, for example
>>>
>>> @RunWith(FrameworkRunner.class)
>>> @CreateLdapServer(transports =
>>>     { @CreateTransport(protocol = "LDAP"),
>>>       @CreateTransport(protocol = "LDAPS") })
>>>
>>> Since upgrade to ApacheDS 2.0.0-M21 I noticed that the tests failed on
>>> Jenkins, on a Linux server, and also on my Mac, but it works on my main
>>> Linux Laptop. After some debugging I found out that the started ApacheDS
>>> only binds to the public interface but not to the loopback device, and
>>> in the Studio tests I create a connection with host "localhost" and then
>>> only get a "connection refused".
>>>
>>> One workaround I tried is to bind to all network interfaces by changing
>>> annotations to this:
>>>
>>> @CreateLdapServer(transports =
>>>     { @CreateTransport(address = "0.0.0.0", protocol = "LDAP"),
>>> +        @CreateTransport(address = "0.0.0.0", protocol = "LDAPS") })
>>>
>>> In ApacheDS tests i noticed that we don't use "localhost" but lookup the
>>> hostname by our old friend
>>>
>>>     InetAddress.getLocalHost().getHostName()
>>>
>>> That would be the 2nd change I can do to fix Studio tests.
>>>
>>> But I wonder if it is good that the ApacheDS started by the test
>>> framworks binds to public interace at all? I mean the default use case
>>> is to run tests on the same hosts. I think it is not a good idea to bind
>>> to public interface at all.
>>>
>>> Thoughts?
>>
>> I think that listening on 0.0.0.0 is a bit wide. We surely should use
>> the InetAddress.getLocalHost().getHostName()instead.
>>
>> Actually, when you don't specify any address, here is what is used :
>>
>>
>>         if ( Strings.isEmpty( address ) )
>>         {
>>             try
>>             {
>>                 address = InetAddress.getLocalHost().getHostName();
>>             }
>>             catch ( UnknownHostException uhe )
>>             {
>>                 // Default to "localhost"...
>>                 address = "localhost";
>>             }
>>         }
>>
>> so I guess you can do the same in Studio, instead of using Localhost.
> 
> Ok, I did that now: http://svn.apache.org/viewvc?rev=1723789&view=rev
> 
> However I think we should try to change that and use the following all
> over in API, ApacheDS, Kerby, and Studio:
> 
> 	InetAddress.getLoopbackAddress().getHostname();
> 
> Note getLoopbackAddress() instead of getLocalHost(). That method was
> added in Java 7. According to javadoc it returns the the address of the
> loopback device. It doesn't query DNS to looup the hostname and hence
> also doesn't throw an UnknownHostException. I only see advantages in
> using that method.

Finally I found time to do that.

There is a new utility org.apache.directory.api.util.Network in api-util
that provides a constant of the loopback address and hostname. I removed
all occurences of InetAddress.getLocalhost() in the code and use that
Network utility now.

I tested with different /etc/hosts settings. In the end I choosed to use
getCanonicalHostName() instead of getHostName(). I hope that this change
now works on all your computers including our Jenkins. If you get errors
please let met know.

Kind Regards,
Stefan