your mail
Maxim Dounin
mdounin at mdounin.ru
Thu Jun 2 13:32:50 MSD 2011
Hello!
On Wed, Jun 01, 2011 at 10:33:42AM -0400, Les Aker wrote:
> I've found what appears to be a bug in the handling of listen
> directives for ipv4 and ipv6.
>
> When running two vhosts, one of which listens on [::], the other
> on localhost, nginx will fail with this error:
> 2011/06/01 10:12:35 [emerg] 9750#0: bind() to 127.0.0.1:80 failed (98: Address already in use)
> My understanding was that this error stems from [::] being
> inclusive of 127.0.0.1, causing nginx to attempt to bind it
> twice.
> However, replacing the `listen localhost;` with `listen [::1];`
> removes the error, despite the fact that [::1] is also included
> within [::]. -- Les Aker
Linux, I suppose? There are two problems here:
1. Linux doesn't allow multiple bind()'s on the same port, even
with setsockopt(SO_REUSEADDR).
2. nginx doesn't expect [::] to conflict with / include 127.0.0.1,
as these two belong to different address families. But in fact
depending on v6only system (or socket) setting [::] may either
include 127.0.0.1 or not.
With [::] and [::1] nginx expects conflict to happen and
workarounds it for Linux by using single bind() on [::] and
getsockaddr() call on each new connection. With [::] and
127.0.0.1 it doesn't (see (2)) and that's why you see conflict.
Simple solution is to explicitly listen on ipv4 and ipv6 (with
v6only option) sockets, like this:
listen *:80;
listen [::]:80 ipv6only=on;
(actually, this is how it works on other operating systems
with v6only being on by default, and either on Linux with
appropriate sysctl being set)
Maxim Dounin
More information about the nginx
mailing list