From 35dd972a1db8760a9fdfb7d6c08b4bcd6189277d Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Tue, 9 Oct 2012 17:02:22 +0200 Subject: erts: Add configure test for IPV6_V6ONLY --- erts/configure.in | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'erts') diff --git a/erts/configure.in b/erts/configure.in index 8d70a1b74a..43f6cf39c9 100644 --- a/erts/configure.in +++ b/erts/configure.in @@ -2000,8 +2000,12 @@ case "$erts_cv_have_in6addr_loopback" in [Define to 1 if you have the variable in6addr_loopback declared.]) esac -AC_CHECK_DECLS([IN6ADDR_ANY_INIT, IN6ADDR_LOOPBACK_INIT], [], [], - [#include ]) +AC_CHECK_DECLS([IN6ADDR_ANY_INIT, IN6ADDR_LOOPBACK_INIT, IPV6_V6ONLY], [], [], + [ + #include + #include + #include + ]) dnl ---------------------------------------------------------------------- dnl Checks for features/quirks in the system that affects Erlang. -- cgit v1.2.3 From 487ff0f54a3a311d1e3f79ae5be5e6b4a9c2f40c Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Fri, 12 Oct 2012 09:41:28 +0200 Subject: erts: Implement socket option IPV6_V6ONLY --- erts/emulator/drivers/common/inet_drv.c | 67 +++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) (limited to 'erts') diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c index dea910e89f..8981050228 100644 --- a/erts/emulator/drivers/common/inet_drv.c +++ b/erts/emulator/drivers/common/inet_drv.c @@ -660,6 +660,7 @@ static int my_strncasecmp(const char *s1, const char *s2, size_t n) #define UDP_OPT_MULTICAST_LOOP 13 /* set/get IP multicast loopback */ #define UDP_OPT_ADD_MEMBERSHIP 14 /* add an IP group membership */ #define UDP_OPT_DROP_MEMBERSHIP 15 /* drop an IP group membership */ +#define INET_OPT_IPV6_V6ONLY 16 /* IPv6 only socket, no mapped v4 addrs */ /* LOPT is local options */ #define INET_LOPT_BUFFER 20 /* min buffer size hint */ #define INET_LOPT_HEADER 21 /* list header size */ @@ -1167,6 +1168,7 @@ static ErlDrvTermData am_reuseaddr; static ErlDrvTermData am_dontroute; static ErlDrvTermData am_priority; static ErlDrvTermData am_tos; +static ErlDrvTermData am_ipv6_v6only; #endif /* speical errors for bad ports and sequences */ @@ -3486,6 +3488,7 @@ static void inet_init_sctp(void) { INIT_ATOM(dontroute); INIT_ATOM(priority); INIT_ATOM(tos); + INIT_ATOM(ipv6_v6only); /* Option names */ INIT_ATOM(sctp_rtoinfo); @@ -5618,6 +5621,23 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len) #endif /* HAVE_MULTICAST_SUPPORT */ + case INET_OPT_IPV6_V6ONLY: +#if HAVE_DECL_IPV6_V6ONLY + proto = IPPROTO_IPV6; + type = IPV6_V6ONLY; + propagate = 1; + DEBUGF(("inet_set_opts(%ld): s=%d, IPV6_V6ONLY=%d\r\n", + (long)desc->port, desc->s, ival)); + break; +#elif defined(__WIN32__) && defined(HAVE_IN6) && defined(AF_INET6) + /* Fake a'la OpenBSD; set to 'true' is fine but 'false' invalid. */ + if (ival != 0) continue; + else return -1; + break; +#else + continue; +#endif + case INET_OPT_RAW: if (len < 8) { return -1; @@ -5947,6 +5967,22 @@ static int sctp_set_opts(inet_descriptor* desc, char* ptr, int len) continue; /* Option not supported -- ignore it */ # endif + case INET_OPT_IPV6_V6ONLY: +# if HAVE_DECL_IPV6_V6ONLY + { + arg.ival= get_int32 (curr); curr += 4; + proto = IPPROTO_IPV6; + type = IPV6_V6ONLY; + arg_ptr = (char*) (&arg.ival); + arg_sz = sizeof ( arg.ival); + break; + } +# elif defined(__WIN32__) && defined(HAVE_IN6) && defined(AF_INET6) +# error Here is a fix for Win IPv6 SCTP missing +# else + continue; /* Option not supported -- ignore it */ +# endif + case SCTP_OPT_AUTOCLOSE: { arg.ival= get_int32 (curr); curr += 4; @@ -6435,6 +6471,22 @@ static ErlDrvSSizeT inet_fill_opts(inet_descriptor* desc, break; #endif /* HAVE_MULTICAST_SUPPORT */ + case INET_OPT_IPV6_V6ONLY: +#if HAVE_DECL_IPV6_V6ONLY + proto = IPPROTO_IPV6; + type = IPV6_V6ONLY; + break; +#elif defined(__WIN32__) && defined(HAVE_IN6) && defined(AF_INET6) + /* Fake reading 'true' */ + *ptr++ = opt; + put_int32(1, ptr); + ptr += 4; + continue; +#else + TRUNCATE_TO(0,ptr); + continue; /* skip - no result */ +#endif + case INET_OPT_RAW: { int data_provided; @@ -6739,6 +6791,7 @@ static ErlDrvSSizeT sctp_fill_opts(inet_descriptor* desc, case INET_OPT_DONTROUTE: case INET_OPT_PRIORITY : case INET_OPT_TOS : + case INET_OPT_IPV6_V6ONLY: case SCTP_OPT_AUTOCLOSE: case SCTP_OPT_MAXSEG : /* The following options return true or false: */ @@ -6811,6 +6864,20 @@ static ErlDrvSSizeT sctp_fill_opts(inet_descriptor* desc, continue; # endif } + case INET_OPT_IPV6_V6ONLY: +# if HAVE_DECL_IPV6_V6ONLY + { + proto = IPPROTO_IPV6; + type = IPV6_V6ONLY; + tag = am_ipv6_v6only; + break; + } +# elif defined(__WIN32__) && defined(HAVE_IN6) && defined(AF_INET6) +# error Here is a fix for Win IPv6 SCTP needed +# else + /* Not supported -- ignore */ + continue; +# endif case SCTP_OPT_AUTOCLOSE: { proto = IPPROTO_SCTP; -- cgit v1.2.3 From 654e820db89c42eb30c3c4b4f1be747265df1e10 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Fri, 12 Oct 2012 09:42:08 +0200 Subject: erts,kernel: Implement socket option ipv6_v6only in erlang code --- erts/preloaded/ebin/prim_inet.beam | Bin 69764 -> 69964 bytes erts/preloaded/src/prim_inet.erl | 3 +++ 2 files changed, 3 insertions(+) (limited to 'erts') diff --git a/erts/preloaded/ebin/prim_inet.beam b/erts/preloaded/ebin/prim_inet.beam index 5409cf2dfc..b2d224e560 100644 Binary files a/erts/preloaded/ebin/prim_inet.beam and b/erts/preloaded/ebin/prim_inet.beam differ diff --git a/erts/preloaded/src/prim_inet.erl b/erts/preloaded/src/prim_inet.erl index b639b1efdd..b9800a05da 100644 --- a/erts/preloaded/src/prim_inet.erl +++ b/erts/preloaded/src/prim_inet.erl @@ -1062,6 +1062,7 @@ enc_opt(multicast_ttl) -> ?UDP_OPT_MULTICAST_TTL; enc_opt(multicast_loop) -> ?UDP_OPT_MULTICAST_LOOP; enc_opt(add_membership) -> ?UDP_OPT_ADD_MEMBERSHIP; enc_opt(drop_membership) -> ?UDP_OPT_DROP_MEMBERSHIP; +enc_opt(ipv6_v6only) -> ?INET_OPT_IPV6_V6ONLY; enc_opt(buffer) -> ?INET_LOPT_BUFFER; enc_opt(header) -> ?INET_LOPT_HEADER; enc_opt(active) -> ?INET_LOPT_ACTIVE; @@ -1115,6 +1116,7 @@ dec_opt(?UDP_OPT_MULTICAST_TTL) -> multicast_ttl; dec_opt(?UDP_OPT_MULTICAST_LOOP) -> multicast_loop; dec_opt(?UDP_OPT_ADD_MEMBERSHIP) -> add_membership; dec_opt(?UDP_OPT_DROP_MEMBERSHIP) -> drop_membership; +dec_opt(?INET_OPT_IPV6_V6ONLY) -> ipv6_v6only; dec_opt(?INET_LOPT_BUFFER) -> buffer; dec_opt(?INET_LOPT_HEADER) -> header; dec_opt(?INET_LOPT_ACTIVE) -> active; @@ -1178,6 +1180,7 @@ type_opt_1(recbuf) -> int; type_opt_1(priority) -> int; type_opt_1(tos) -> int; type_opt_1(nodelay) -> bool; +type_opt_1(ipv6_v6only) -> bool; %% multicast type_opt_1(multicast_ttl) -> int; type_opt_1(multicast_loop) -> bool; -- cgit v1.2.3