Re: [PATCH] Added so_freebind and so_transparent to the listen directive

2014-03-28 Thread Trygve Vea
- Opprinnelig melding -
 On Mar 27, 2014, at 22:14 , Trygve Vea wrote:
 
  - Opprinnelig melding -
  Hello!
  
  Hello!
  
  On Thu, Mar 27, 2014 at 04:34:37PM +0100, Trygve Vea wrote:
  # HG changeset patch
  # User Trygve Vea trygve@redpill-linpro.com
  # Date 1395933815 -3600
  #  Thu Mar 27 16:23:35 2014 +0100
  # Node ID 13e6a37c2f57443b0d5dd0abce8d9d4ab00e31e3
  # Parent  2411d4b5be2ca690a5a00a1d8ad96ff69a00317f
  Added so_freebind and so_transparent to the listen directive
  
  This solves a Linux/IPv6-specific problem.
  
  To be able to listen to an IPv6 address that is not yet available on the
  host,
  one need to use the IP_FREEBIND and IP_TRANSPARENT socket options.
  
  The use case in question is for a failover setup with several service-
  addresses in a IPv6-only environment.
  
  IPv4 has a sysctl available (ip_nonlocal_bind), which is not available
  for
  IPv6 - thus making these patches necessary.
  
  Isn't bind on INADDR_ANY/IN6ADDR_ANY works for you?
  
  It is expected to work fine and allows to accept connections on
  all addresses currently available on a host without any
  non-portable tricks.
  - Opprinnelig melding -
  IPv4 has a sysctl available (ip_nonlocal_bind), which is not available
  for
  IPv6 - thus making these patches necessary.
  
  Isn't bind on INADDR_ANY/IN6ADDR_ANY works for you?
  
  It is expected to work fine and allows to accept connections on
  all addresses currently available on a host without any
  non-portable tricks.
  
  That would be sufficient for HTTP - and my preferred option, since we can
  handle routing after the end-user have provided us with the Host-header,
  and thus know where to send the user.
  
  However, with SSL enabled - while we have end users that still do not
  support SNI
  (http://en.wikipedia.org/wiki/Server_Name_Indication#Client_side), and
  using multiple SSL-certificates, for multiple applications - we will need
  to bind each certificate to its own dedicated service address.  From here,
  we can do routing / forward the connections further down the stack.
 
 This can be handled with following configuration:
 
 server {
listen  *:443 ssl;
listen  any.non.existent.ip1:443  ssl;
ssl_certificate ...
...
 }
 
 
 server {
listen  any.non.existent.ip2:443  ssl;
ssl_certificate ...
...
 }
 
 nginx will bind only to *:443 and then will call getsockname() to get real
 local address.

Hm, are you sure?

I haven't been able to succeed - as this was what I was initially attempting to 
do.

server {
  listen   *:443 ssl;
  
  listen [2a02:c0:209::F1]:443 ssl;


nginx: [emerg] bind() to [2a02:c0:209::f1]:443 failed (99: Cannot assign 
requested address)


Are there any additional requirements to make this work?


-- 
Trygve Vea
Redpill Linpro AS

___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel


Re: [PATCH] Added so_freebind and so_transparent to the listen directive

2014-03-28 Thread Trygve Vea
- Opprinnelig melding -
 On Mar 28, 2014, at 14:45 , Trygve Vea wrote:
 
  - Opprinnelig melding -
  On Mar 27, 2014, at 22:14 , Trygve Vea wrote:
  
  - Opprinnelig melding -
  Hello!
  
  Hello!
  
  On Thu, Mar 27, 2014 at 04:34:37PM +0100, Trygve Vea wrote:
  # HG changeset patch
  # User Trygve Vea trygve@redpill-linpro.com
  # Date 1395933815 -3600
  #  Thu Mar 27 16:23:35 2014 +0100
  # Node ID 13e6a37c2f57443b0d5dd0abce8d9d4ab00e31e3
  # Parent  2411d4b5be2ca690a5a00a1d8ad96ff69a00317f
  Added so_freebind and so_transparent to the listen directive
  
  This solves a Linux/IPv6-specific problem.
  
  To be able to listen to an IPv6 address that is not yet available on
  the
  host,
  one need to use the IP_FREEBIND and IP_TRANSPARENT socket options.
  
  The use case in question is for a failover setup with several service-
  addresses in a IPv6-only environment.
  
  IPv4 has a sysctl available (ip_nonlocal_bind), which is not available
  for
  IPv6 - thus making these patches necessary.
  
  Isn't bind on INADDR_ANY/IN6ADDR_ANY works for you?
  
  It is expected to work fine and allows to accept connections on
  all addresses currently available on a host without any
  non-portable tricks.
  - Opprinnelig melding -
  IPv4 has a sysctl available (ip_nonlocal_bind), which is not available
  for
  IPv6 - thus making these patches necessary.
  
  Isn't bind on INADDR_ANY/IN6ADDR_ANY works for you?
  
  It is expected to work fine and allows to accept connections on
  all addresses currently available on a host without any
  non-portable tricks.
  
  That would be sufficient for HTTP - and my preferred option, since we can
  handle routing after the end-user have provided us with the Host-header,
  and thus know where to send the user.
  
  However, with SSL enabled - while we have end users that still do not
  support SNI
  (http://en.wikipedia.org/wiki/Server_Name_Indication#Client_side), and
  using multiple SSL-certificates, for multiple applications - we will need
  to bind each certificate to its own dedicated service address.  From
  here,
  we can do routing / forward the connections further down the stack.
  
  This can be handled with following configuration:
  
  server {
listen  *:443 ssl;
listen  any.non.existent.ip1:443  ssl;
ssl_certificate ...
...
  }
  
  
  server {
listen  any.non.existent.ip2:443  ssl;
ssl_certificate ...
...
  }
  
  nginx will bind only to *:443 and then will call getsockname() to get real
  local address.
  
  Hm, are you sure?
  
  I haven't been able to succeed - as this was what I was initially
  attempting to do.
  
  server {
   listen   *:443 ssl;
  
   listen [2a02:c0:209::F1]:443 ssl;
  
  
  nginx: [emerg] bind() to [2a02:c0:209::f1]:443 failed (99: Cannot assign
  requested address)
  
  
  Are there any additional requirements to make this work?
 
 You need to add also:
listen  [::]:443   ssl;

Ah, thank you.

This seems to do the trick.

I spoke with a colleague about this, and he pointed out that this does not 
cover the use case where you do NOT want to listen on *:443 (which the patch 
does cover).  However, that is not something I need.

Feel free to both ignore and merge the patch; if you would like to merge it 
with some modifications, feel free to tell me what to change - and I'd be happy 
to make them.


Regards
-- 
Trygve Vea
Redpill Linpro AS

___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel


Re: [PATCH] Added so_freebind and so_transparent to the listen directive

2014-03-27 Thread Maxim Dounin
Hello!

On Thu, Mar 27, 2014 at 04:34:37PM +0100, Trygve Vea wrote:

 # HG changeset patch
 # User Trygve Vea trygve@redpill-linpro.com
 # Date 1395933815 -3600
 #  Thu Mar 27 16:23:35 2014 +0100
 # Node ID 13e6a37c2f57443b0d5dd0abce8d9d4ab00e31e3
 # Parent  2411d4b5be2ca690a5a00a1d8ad96ff69a00317f
 Added so_freebind and so_transparent to the listen directive
 
 This solves a Linux/IPv6-specific problem.
 
 To be able to listen to an IPv6 address that is not yet available on the host,
 one need to use the IP_FREEBIND and IP_TRANSPARENT socket options.
 
 The use case in question is for a failover setup with several service-
 addresses in a IPv6-only environment.
 
 IPv4 has a sysctl available (ip_nonlocal_bind), which is not available for
 IPv6 - thus making these patches necessary.

Isn't bind on INADDR_ANY/IN6ADDR_ANY works for you?

It is expected to work fine and allows to accept connections on 
all addresses currently available on a host without any 
non-portable tricks.

-- 
Maxim Dounin
http://nginx.org/

___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel


Re: [PATCH] Added so_freebind and so_transparent to the listen directive

2014-03-27 Thread Trygve Vea
- Opprinnelig melding -
 Hello!

Hello!

 On Thu, Mar 27, 2014 at 04:34:37PM +0100, Trygve Vea wrote:
  # HG changeset patch
  # User Trygve Vea trygve@redpill-linpro.com
  # Date 1395933815 -3600
  #  Thu Mar 27 16:23:35 2014 +0100
  # Node ID 13e6a37c2f57443b0d5dd0abce8d9d4ab00e31e3
  # Parent  2411d4b5be2ca690a5a00a1d8ad96ff69a00317f
  Added so_freebind and so_transparent to the listen directive
  
  This solves a Linux/IPv6-specific problem.
  
  To be able to listen to an IPv6 address that is not yet available on the
  host,
  one need to use the IP_FREEBIND and IP_TRANSPARENT socket options.
  
  The use case in question is for a failover setup with several service-
  addresses in a IPv6-only environment.
  
  IPv4 has a sysctl available (ip_nonlocal_bind), which is not available for
  IPv6 - thus making these patches necessary.
 
 Isn't bind on INADDR_ANY/IN6ADDR_ANY works for you?
 
 It is expected to work fine and allows to accept connections on
 all addresses currently available on a host without any
 non-portable tricks.
- Opprinnelig melding -
  IPv4 has a sysctl available (ip_nonlocal_bind), which is not available for
  IPv6 - thus making these patches necessary.
 
 Isn't bind on INADDR_ANY/IN6ADDR_ANY works for you?
 
 It is expected to work fine and allows to accept connections on
 all addresses currently available on a host without any
 non-portable tricks.

That would be sufficient for HTTP - and my preferred option, since we can 
handle routing after the end-user have provided us with the Host-header, and 
thus know where to send the user.

However, with SSL enabled - while we have end users that still do not support 
SNI (http://en.wikipedia.org/wiki/Server_Name_Indication#Client_side), and 
using multiple SSL-certificates, for multiple applications - we will need to 
bind each certificate to its own dedicated service address.  From here, we can 
do routing / forward the connections further down the stack.

After I submitted the patch, I noticed that it will probably not build on Linux 
versions prior to 2.4, so I intend to create a new one addressing that issue 
tomorrow when I'm back at the office.

Are there any issues with the patch that I should take into consideration when 
making changes?


Regards
-- 
Trygve Vea

___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel


Re: [PATCH] Added so_freebind and so_transparent to the listen directive

2014-03-27 Thread Piotr Sikora
Hi Trygve,

 Added so_freebind and so_transparent to the listen directive

 This solves a Linux/IPv6-specific problem.

 To be able to listen to an IPv6 address that is not yet available on the host,
 one need to use the IP_FREEBIND and IP_TRANSPARENT socket options.

 The use case in question is for a failover setup with several service-
 addresses in a IPv6-only environment.

 IPv4 has a sysctl available (ip_nonlocal_bind), which is not available for
 IPv6 - thus making these patches necessary.

Non-local bind() isn't Linux-specific feature. FreeBSD has
IP_BINDANY/IPV6_BINDANY options and OpenBSD has SO_BINDANY option, so
it would be good to add support for all of them.

Also, requiring user to add both: so_freebind and so_transparent
options to enable single feature doesn't look very user friendly,
especially because according to your description, non-local bind()
would work just fine with only so_freebind for IPv4 addresses, but
it would fail for IPv6 addresses... I don't think that the so_
prefix is necessary, how about just bindany or nonlocal
(freebind is just stupid name)?

Best regards,
Piotr Sikora

___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel


Re: [PATCH] Added so_freebind and so_transparent to the listen directive

2014-03-27 Thread Trygve Vea
- Opprinnelig melding -
 Hi Trygve,
 
  Added so_freebind and so_transparent to the listen directive
 
  This solves a Linux/IPv6-specific problem.
 
  To be able to listen to an IPv6 address that is not yet available on the
  host,
  one need to use the IP_FREEBIND and IP_TRANSPARENT socket options.
 
  The use case in question is for a failover setup with several service-
  addresses in a IPv6-only environment.
 
  IPv4 has a sysctl available (ip_nonlocal_bind), which is not available for
  IPv6 - thus making these patches necessary.
 
 Non-local bind() isn't Linux-specific feature. FreeBSD has
 IP_BINDANY/IPV6_BINDANY options and OpenBSD has SO_BINDANY option, so
 it would be good to add support for all of them.

That makes sense.

 Also, requiring user to add both: so_freebind and so_transparent
 options to enable single feature doesn't look very user friendly,
 especially because according to your description, non-local bind()
 would work just fine with only so_freebind for IPv4 addresses, but
 it would fail for IPv6 addresses... I don't think that the so_
 prefix is necessary, how about just bindany or nonlocal
 (freebind is just stupid name)?

The so_-prefix was something I took from the existing so_keepalive option.  Are 
there any conventions I should follow when I name these values?

I agree that creating a single option that can handle multiple platforms the 
same is a good idea.

What if I do something like;

* Create a configuration variable for the listen-directive named 'nonlocal'.
* If IPv6 and Linux = 2.4, attempt to set the socket options in question. (I'm 
not sure if I would need to deal with dual stack in a certain way, here - I'll 
check with one of the IPv6-evangelists at work tomorrow)
* If IPv4 and Linux = 2.4, set the IP_FREEBIND socket option.
* Else, throw warning that the parameter will be ignored because running on an 
unsupported platform.

Adding support for more platforms for the configuration option can be easily 
added by someone with access and knowledge about the platforms.  I have 
actually never used FreeBSD/OpenBSD, so my knowledge is fairly limited.

Would that be acceptable?

-- 
Trygve

___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel