Hello!
Linux IPv6 stack provides the ability for IPv6 applications to
interoperate with IPv4 applications. Port space for TCP (or UDP) is
shared by IPv6 and IPv4. This conforms to RFC2553.
However, some kind of applications may want to restrict their use of
an IPv6 socket to IPv6 communication only. IPV6_V6ONLY socket option is
defined for such applications in RFC2553bis, which is successor of RFC2553.
This patch allows to bind both IPv6 and IPv4 sockets with the single
port number at the same time if IPV6_V6ONLY socket options is set to
the IPv6 socket.
We also prohibit a completely duplicate set of (local-addr, local-port,
remote-addr, remote-port) set even if SO_REUSEADDR is set unless
the local address is a multicast address; it is ambiguous and it may
steal packets from others; i.e. a kind of DoS.
Packet delivery strategy is similar to one before, but we prefer
IPv4 a bit.
Following patch is against linux-2.4.19.
Thank you in advance.
-------------------------------------------------------------------
Patch-Name: Allow Both IPv6 and IPv4 Sockets on the Same Port Number (IPV6_V6ONLY Support)
Patch-Id: FIX_2_4_19_DOUBLEBIND-20020909
Patch-Author: YOSHIFUJI Hideaki / USAGI Project [off-list ref]
Credit: YOSHIFUJI Hideaki / USAGI Project [off-list ref]
Reference: RFC2553bis
-------------------------------------------------------------------
Index: include/linux/in6.h
===================================================================
RCS file: /cvsroot/usagi/usagi-backport/linux24/include/linux/in6.h,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.8.1
diff -u -r1.1.1.1 -r1.1.1.1.8.1
@@ -177,23 +185,92 @@staticinlineinttcp_bind_conflict(structsock*sk,structtcp_bind_bucket*tb){structsock*sk2=tb->owners;-intsk_reuse=sk->reuse;+intsk_reuse,sk2_reuse;+intaddr_type2;+intret;++sk_reuse=0;+if(sk->reuse)+sk_reuse|=1;for(;sk2!=NULL;sk2=sk2->bind_next){-if(sk!=sk2&&-sk2->reuse<=1&&-sk->bound_dev_if==sk2->bound_dev_if){-if(!sk_reuse||-!sk2->reuse||-sk2->state==TCP_LISTEN){-if(!sk2->rcv_saddr||-!sk->rcv_saddr||-(sk2->rcv_saddr==sk->rcv_saddr))-break;+intboth_specified=0;++if(sk2==sk||+(sk2->bound_dev_if&&sk->bound_dev_if&&+sk2->bound_dev_if!=sk->bound_dev_if))+continue;++#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)+if(sk2->family==AF_INET6){+structin6_addr*sk2_rcv_saddr6=sk2->state!=TCP_TIME_WAIT?+&sk2->net_pinfo.af_inet6.rcv_saddr:+&((structtcp_tw_bucket*)sk2)->v6_rcv_saddr;+if(IN6_IS_ADDR_UNSPECIFIED(sk2_rcv_saddr6))+addr_type2=IPV6_ADDR_ANY;+elseif(IN6_IS_ADDR_V4MAPPED(sk2_rcv_saddr6))+addr_type2=IPV6_ADDR_MAPPED;+else+addr_type2=IPV6_ADDR_UNICAST;/*XXX*/+}else+addr_type2=IPV6_ADDR_MAPPED;+#else+addr_type2=IPV6_ADDR_MAPPED;+#endif+if((addr_type2!=IPV6_ADDR_MAPPED?addr_type2!=IPV6_ADDR_ANY:sk2->rcv_saddr)&&+sk->rcv_saddr){+if(sk2->rcv_saddr!=sk->rcv_saddr)+continue;+both_specified=1;+}++#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)+if(addr_type2!=IPV6_ADDR_MAPPED&&sk2->net_pinfo.af_inet6.ipv6only){+continue;+}+#endif++sk2_reuse=0;+if(sk2->reuse)+sk2_reuse|=1;++if(sk2_reuse&sk_reuse&3){/* NOT && */+ret=1;+if(both_specified){+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)+structin6_addr*sk2_daddr6=sk2->state!=TCP_TIME_WAIT?+&sk2->net_pinfo.af_inet6.daddr:+&((structtcp_tw_bucket*)sk2)->v6_daddr;+#endif+intaddr_type2d;+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)+if(sk2->family==AF_INET6){+if(IN6_IS_ADDR_UNSPECIFIED(sk2_daddr6))+addr_type2d=IPV6_ADDR_ANY;+elseif(IN6_IS_ADDR_V4MAPPED(sk2_daddr6))+addr_type2d=IPV6_ADDR_MAPPED;+else+addr_type2d=IPV6_ADDR_UNICAST;/*XXX*/+}else+addr_type2d=IPV6_ADDR_MAPPED;+#else+addr_type2d=IPV6_ADDR_MAPPED;+#endif+if(addr_type2d!=IPV6_ADDR_MAPPED?addr_type2d!=IPV6_ADDR_ANY:sk2->daddr)+continue;+}else{+if((addr_type2!=IPV6_ADDR_MAPPED?addr_type2!=IPV6_ADDR_ANY:sk2->rcv_saddr)||+sk->rcv_saddr)+continue;}}+ret=1;+gotofailed;}-returnsk2!=NULL;+/* If we found a conflict, fail. */+ret=sk2!=NULL;+failed:+returnret;}/* Obtain a reference to a local port for the given sock,
@@ -173,6 +173,8 @@sk->net_pinfo.af_inet6.mc_loop=1;sk->net_pinfo.af_inet6.pmtudisc=IPV6_PMTUDISC_WANT;+sk->net_pinfo.af_inet6.ipv6only=ipv6_devconf.bindv6only;+/* Init the ipv4 part of the socket since we can have sockets*usingv6APIforipv4.*/
@@ -248,6 +250,8 @@/* Check if the address belongs to the host. */if(addr_type==IPV6_ADDR_MAPPED){+if(sk->net_pinfo.af_inet6.ipv6only)+return-EADDRNOTAVAIL;v4addr=addr->sin6_addr.s6_addr32[3];if(inet_addr_type(v4addr)!=RTN_LOCAL)return-EADDRNOTAVAIL;
@@ -137,28 +145,70 @@gotosuccess;}else{structsock*sk2=tb->owners;-intsk_reuse=sk->reuse;-intaddr_type=ipv6_addr_type(&sk->net_pinfo.af_inet6.rcv_saddr);+intsk_reuse,sk2_reuse;+structin6_addr*sk_rcv_saddr6=sk->state!=TCP_TIME_WAIT?+&sk->net_pinfo.af_inet6.rcv_saddr:+&((structtcp_tw_bucket*)sk)->v6_rcv_saddr;+intaddr_type=ipv6_addr_type(sk_rcv_saddr6),+addr_type2;++sk_reuse=0;+if(sk->reuse)+sk_reuse|=1;/* We must walk the whole port owner list in this case. -DaveM */for(;sk2!=NULL;sk2=sk2->bind_next){-if(sk!=sk2&&-sk->bound_dev_if==sk2->bound_dev_if){-if(!sk_reuse||-!sk2->reuse||-sk2->state==TCP_LISTEN){-/* NOTE: IPv6 tw bucket have different format */-if(!sk2->rcv_saddr||-addr_type==IPV6_ADDR_ANY||-!ipv6_addr_cmp(&sk->net_pinfo.af_inet6.rcv_saddr,-sk2->state!=TCP_TIME_WAIT?-&sk2->net_pinfo.af_inet6.rcv_saddr:-&((structtcp_tw_bucket*)sk)->v6_rcv_saddr)||-(addr_type==IPV6_ADDR_MAPPED&&sk2->family==AF_INET&&-sk->rcv_saddr==sk2->rcv_saddr))-break;+intboth_specified=0;+structin6_addr*sk2_rcv_saddr6;+if(sk2==sk||+(sk2->bound_dev_if&&sk->bound_dev_if&&+sk2->bound_dev_if!=sk->bound_dev_if))+continue;+sk2_rcv_saddr6=sk2->state!=TCP_TIME_WAIT?+&sk2->net_pinfo.af_inet6.rcv_saddr:+&((structtcp_tw_bucket*)sk2)->v6_rcv_saddr;++if((addr_type2!=IPV6_ADDR_MAPPED?addr_type2!=IPV6_ADDR_ANY:sk2->rcv_saddr)&&+(addr_type!=IPV6_ADDR_MAPPED?addr_type!=IPV6_ADDR_ANY:sk->rcv_saddr)){+if(addr_type2==IPV6_ADDR_MAPPED||addr_type==IPV6_ADDR_MAPPED){+if(addr_type2!=addr_type||+sk2->rcv_saddr!=sk->rcv_saddr)+continue;+}else{+if(ipv6_addr_cmp(sk2_rcv_saddr6,sk_rcv_saddr6))+continue;}+both_specified=1;}++if((addr_type2==IPV6_ADDR_MAPPED&&+addr_type!=IPV6_ADDR_MAPPED&&sk->net_pinfo.af_inet6.ipv6only)||+(addr_type==IPV6_ADDR_MAPPED&&+addr_type2!=IPV6_ADDR_MAPPED&&sk2->net_pinfo.af_inet6.ipv6only)){+continue;+}++sk2_reuse=0;+if(sk2->reuse)+sk2_reuse|=1;++if(sk2_reuse&sk_reuse&3){/* NOT && */+ret=1;+if(both_specified){+structin6_addr*sk2_daddr6=sk2->state!=TCP_TIME_WAIT?+&sk2->net_pinfo.af_inet6.daddr:+&((structtcp_tw_bucket*)sk2)->v6_daddr;+intaddr_type2d=sk2->family==AF_INET6?ipv6_addr_type(sk2_daddr6):IPV6_ADDR_MAPPED;+if(addr_type2d!=IPV6_ADDR_MAPPED?addr_type2d!=IPV6_ADDR_ANY:sk2->daddr)+continue;+}else{+if((addr_type2!=IPV6_ADDR_MAPPED?addr_type2!=IPV6_ADDR_ANY:sk2->rcv_saddr)||+(addr_type!=IPV6_ADDR_MAPPED?addr_type!=IPV6_ADDR_ANY:sk->rcv_saddr))+continue;+}+}+ret=1;+gotofail_unlock;}/* If we found a conflict, fail. */ret=1;
Please use plain htonl, __constant_htonl is only needed in static
initializations, in all other cases with constants as a parameter it
generates the same code as htonl, so lets prefer using the shorter,
more readable format.
- Arnaldo
Please use plain htonl, __constant_htonl is only needed in static
initializations, in all other cases with constants as a parameter it
generates the same code as htonl, so lets prefer using the shorter,
more readable format.
- Arnaldo
From: Pekka Savola <hidden> Date: 2002-10-03 06:55:13
Please add a short description of 'bindv6only' in
Documentation/networking/ip-sysctl.txt.
This toggle seems usable only in interface "all" context.
Didn't really look at the rest of the patch.
On Thu, 3 Oct 2002, YOSHIFUJI Hideaki / [iso-2022-jp] $B5HF#1QL@(B wrote:
quoted hunk
Hello!
Linux IPv6 stack provides the ability for IPv6 applications to
interoperate with IPv4 applications. Port space for TCP (or UDP) is
shared by IPv6 and IPv4. This conforms to RFC2553.
However, some kind of applications may want to restrict their use of
an IPv6 socket to IPv6 communication only. IPV6_V6ONLY socket option is
defined for such applications in RFC2553bis, which is successor of RFC2553.
This patch allows to bind both IPv6 and IPv4 sockets with the single
port number at the same time if IPV6_V6ONLY socket options is set to
the IPv6 socket.
We also prohibit a completely duplicate set of (local-addr, local-port,
remote-addr, remote-port) set even if SO_REUSEADDR is set unless
the local address is a multicast address; it is ambiguous and it may
steal packets from others; i.e. a kind of DoS.
Packet delivery strategy is similar to one before, but we prefer
IPv4 a bit.
Following patch is against linux-2.4.19.
Thank you in advance.
-------------------------------------------------------------------
Patch-Name: Allow Both IPv6 and IPv4 Sockets on the Same Port Number (IPV6_V6ONLY Support)
Patch-Id: FIX_2_4_19_DOUBLEBIND-20020909
Patch-Author: YOSHIFUJI Hideaki / USAGI Project [off-list ref]
Credit: YOSHIFUJI Hideaki / USAGI Project [off-list ref]
Reference: RFC2553bis
-------------------------------------------------------------------
Index: include/linux/in6.h
===================================================================
RCS file: /cvsroot/usagi/usagi-backport/linux24/include/linux/in6.h,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.8.1
diff -u -r1.1.1.1 -r1.1.1.1.8.1
@@ -177,23 +185,92 @@staticinlineinttcp_bind_conflict(structsock*sk,structtcp_bind_bucket*tb){structsock*sk2=tb->owners;-intsk_reuse=sk->reuse;+intsk_reuse,sk2_reuse;+intaddr_type2;+intret;++sk_reuse=0;+if(sk->reuse)+sk_reuse|=1;for(;sk2!=NULL;sk2=sk2->bind_next){-if(sk!=sk2&&-sk2->reuse<=1&&-sk->bound_dev_if==sk2->bound_dev_if){-if(!sk_reuse||-!sk2->reuse||-sk2->state==TCP_LISTEN){-if(!sk2->rcv_saddr||-!sk->rcv_saddr||-(sk2->rcv_saddr==sk->rcv_saddr))-break;+intboth_specified=0;++if(sk2==sk||+(sk2->bound_dev_if&&sk->bound_dev_if&&+sk2->bound_dev_if!=sk->bound_dev_if))+continue;++#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)+if(sk2->family==AF_INET6){+structin6_addr*sk2_rcv_saddr6=sk2->state!=TCP_TIME_WAIT?+&sk2->net_pinfo.af_inet6.rcv_saddr:+&((structtcp_tw_bucket*)sk2)->v6_rcv_saddr;+if(IN6_IS_ADDR_UNSPECIFIED(sk2_rcv_saddr6))+addr_type2=IPV6_ADDR_ANY;+elseif(IN6_IS_ADDR_V4MAPPED(sk2_rcv_saddr6))+addr_type2=IPV6_ADDR_MAPPED;+else+addr_type2=IPV6_ADDR_UNICAST;/*XXX*/+}else+addr_type2=IPV6_ADDR_MAPPED;+#else+addr_type2=IPV6_ADDR_MAPPED;+#endif+if((addr_type2!=IPV6_ADDR_MAPPED?addr_type2!=IPV6_ADDR_ANY:sk2->rcv_saddr)&&+sk->rcv_saddr){+if(sk2->rcv_saddr!=sk->rcv_saddr)+continue;+both_specified=1;+}++#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)+if(addr_type2!=IPV6_ADDR_MAPPED&&sk2->net_pinfo.af_inet6.ipv6only){+continue;+}+#endif++sk2_reuse=0;+if(sk2->reuse)+sk2_reuse|=1;++if(sk2_reuse&sk_reuse&3){/* NOT && */+ret=1;+if(both_specified){+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)+structin6_addr*sk2_daddr6=sk2->state!=TCP_TIME_WAIT?+&sk2->net_pinfo.af_inet6.daddr:+&((structtcp_tw_bucket*)sk2)->v6_daddr;+#endif+intaddr_type2d;+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)+if(sk2->family==AF_INET6){+if(IN6_IS_ADDR_UNSPECIFIED(sk2_daddr6))+addr_type2d=IPV6_ADDR_ANY;+elseif(IN6_IS_ADDR_V4MAPPED(sk2_daddr6))+addr_type2d=IPV6_ADDR_MAPPED;+else+addr_type2d=IPV6_ADDR_UNICAST;/*XXX*/+}else+addr_type2d=IPV6_ADDR_MAPPED;+#else+addr_type2d=IPV6_ADDR_MAPPED;+#endif+if(addr_type2d!=IPV6_ADDR_MAPPED?addr_type2d!=IPV6_ADDR_ANY:sk2->daddr)+continue;+}else{+if((addr_type2!=IPV6_ADDR_MAPPED?addr_type2!=IPV6_ADDR_ANY:sk2->rcv_saddr)||+sk->rcv_saddr)+continue;}}+ret=1;+gotofailed;}-returnsk2!=NULL;+/* If we found a conflict, fail. */+ret=sk2!=NULL;+failed:+returnret;}/* Obtain a reference to a local port for the given sock,
@@ -173,6 +173,8 @@sk->net_pinfo.af_inet6.mc_loop=1;sk->net_pinfo.af_inet6.pmtudisc=IPV6_PMTUDISC_WANT;+sk->net_pinfo.af_inet6.ipv6only=ipv6_devconf.bindv6only;+/* Init the ipv4 part of the socket since we can have sockets*usingv6APIforipv4.*/
@@ -248,6 +250,8 @@/* Check if the address belongs to the host. */if(addr_type==IPV6_ADDR_MAPPED){+if(sk->net_pinfo.af_inet6.ipv6only)+return-EADDRNOTAVAIL;v4addr=addr->sin6_addr.s6_addr32[3];if(inet_addr_type(v4addr)!=RTN_LOCAL)return-EADDRNOTAVAIL;
@@ -137,28 +145,70 @@gotosuccess;}else{structsock*sk2=tb->owners;-intsk_reuse=sk->reuse;-intaddr_type=ipv6_addr_type(&sk->net_pinfo.af_inet6.rcv_saddr);+intsk_reuse,sk2_reuse;+structin6_addr*sk_rcv_saddr6=sk->state!=TCP_TIME_WAIT?+&sk->net_pinfo.af_inet6.rcv_saddr:+&((structtcp_tw_bucket*)sk)->v6_rcv_saddr;+intaddr_type=ipv6_addr_type(sk_rcv_saddr6),+addr_type2;++sk_reuse=0;+if(sk->reuse)+sk_reuse|=1;/* We must walk the whole port owner list in this case. -DaveM */for(;sk2!=NULL;sk2=sk2->bind_next){-if(sk!=sk2&&-sk->bound_dev_if==sk2->bound_dev_if){-if(!sk_reuse||-!sk2->reuse||-sk2->state==TCP_LISTEN){-/* NOTE: IPv6 tw bucket have different format */-if(!sk2->rcv_saddr||-addr_type==IPV6_ADDR_ANY||-!ipv6_addr_cmp(&sk->net_pinfo.af_inet6.rcv_saddr,-sk2->state!=TCP_TIME_WAIT?-&sk2->net_pinfo.af_inet6.rcv_saddr:-&((structtcp_tw_bucket*)sk)->v6_rcv_saddr)||-(addr_type==IPV6_ADDR_MAPPED&&sk2->family==AF_INET&&-sk->rcv_saddr==sk2->rcv_saddr))-break;+intboth_specified=0;+structin6_addr*sk2_rcv_saddr6;+if(sk2==sk||+(sk2->bound_dev_if&&sk->bound_dev_if&&+sk2->bound_dev_if!=sk->bound_dev_if))+continue;+sk2_rcv_saddr6=sk2->state!=TCP_TIME_WAIT?+&sk2->net_pinfo.af_inet6.rcv_saddr:+&((structtcp_tw_bucket*)sk2)->v6_rcv_saddr;++if((addr_type2!=IPV6_ADDR_MAPPED?addr_type2!=IPV6_ADDR_ANY:sk2->rcv_saddr)&&+(addr_type!=IPV6_ADDR_MAPPED?addr_type!=IPV6_ADDR_ANY:sk->rcv_saddr)){+if(addr_type2==IPV6_ADDR_MAPPED||addr_type==IPV6_ADDR_MAPPED){+if(addr_type2!=addr_type||+sk2->rcv_saddr!=sk->rcv_saddr)+continue;+}else{+if(ipv6_addr_cmp(sk2_rcv_saddr6,sk_rcv_saddr6))+continue;}+both_specified=1;}++if((addr_type2==IPV6_ADDR_MAPPED&&+addr_type!=IPV6_ADDR_MAPPED&&sk->net_pinfo.af_inet6.ipv6only)||+(addr_type==IPV6_ADDR_MAPPED&&+addr_type2!=IPV6_ADDR_MAPPED&&sk2->net_pinfo.af_inet6.ipv6only)){+continue;+}++sk2_reuse=0;+if(sk2->reuse)+sk2_reuse|=1;++if(sk2_reuse&sk_reuse&3){/* NOT && */+ret=1;+if(both_specified){+structin6_addr*sk2_daddr6=sk2->state!=TCP_TIME_WAIT?+&sk2->net_pinfo.af_inet6.daddr:+&((structtcp_tw_bucket*)sk2)->v6_daddr;+intaddr_type2d=sk2->family==AF_INET6?ipv6_addr_type(sk2_daddr6):IPV6_ADDR_MAPPED;+if(addr_type2d!=IPV6_ADDR_MAPPED?addr_type2d!=IPV6_ADDR_ANY:sk2->daddr)+continue;+}else{+if((addr_type2!=IPV6_ADDR_MAPPED?addr_type2!=IPV6_ADDR_ANY:sk2->rcv_saddr)||+(addr_type!=IPV6_ADDR_MAPPED?addr_type!=IPV6_ADDR_ANY:sk->rcv_saddr))+continue;+}+}+ret=1;+gotofail_unlock;}/* If we found a conflict, fail. */ret=1;
--
Pekka Savola "Tell me of difficulties surmounted,
Netcore Oy not those you stumble over and fall"
Systems. Networks. Security. -- Robert Jordan: A Crown of Swords
From: David S. Miller <hidden> Date: 2002-10-03 08:30:49
From: YOSHIFUJI Hideaki / 吉藤英明 [off-list ref]
Date: Thu, 03 Oct 2002 12:13:50 +0900 (JST)
Linux IPv6 stack provides the ability for IPv6 applications to
interoperate with IPv4 applications. Port space for TCP (or UDP) is
shared by IPv6 and IPv4. This conforms to RFC2553.
However, some kind of applications may want to restrict their use of
an IPv6 socket to IPv6 communication only. IPV6_V6ONLY socket option is
defined for such applications in RFC2553bis, which is successor of RFC2553.
I really wish BSD socket features did not get standardized
in RFC's, we must live with their mistakes.
For example, this IPV6_V6ONLY socket option is flawed. What we
really need is a generic socket option which says "my family only"
There is nothing ipv6 specific about such a socket attribute.
So please, create instead "SO_ONEFAMILY" or similar generic
socket option.
I still need to review the rest of the patch for functional
correctness. This is probably the most complex area of the
socket identity code in TCP/UDP :-)
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On Thu, 3 Oct 2002 18:29, David S. Miller wrote:
For example, this IPV6_V6ONLY socket option is flawed. What we
really need is a generic socket option which says "my family only"
There is nothing ipv6 specific about such a socket attribute.
So please, create instead "SO_ONEFAMILY" or similar generic
socket option.
I still need to review the rest of the patch for functional
correctness. This is probably the most complex area of the
socket identity code in TCP/UDP :-)
While you are grotting aroung in this area - a thought / request.
When we get IPv4 link-local autoconf addressing in widespread use, there is a
problem on multi-homed machines.
Assume B has two network interfaces (B1 and B2) on seperate IPv4 links (net1
and net2). Host A is on net1 and Host C is on net2. Assume that both Host A
and Host C have the same autoconf address. So IP address is not enough
information for Host B to use to determine which interface to use in order to
contact Host A (instead of Host C).
If host B has socket binding on IP+port+local interface, it all works out.
Is this going to work?
Brad
- --
http://conf.linux.org.au. 22-25Jan2003. Perth, Aust. Tickets booked.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org
iD8DBQE9nAXwW6pHgIdAuOMRAscOAKC/TyYdV1IOjDMlYZghhLf1mYtrKgCfbDEh
VJAdPL1Rc1Z2uM6RCIgSYOE=
=JZGw
-----END PGP SIGNATURE-----
From: David S. Miller <hidden> Date: 2002-10-03 09:01:02
From: Brad Hards [off-list ref]
Date: Thu, 3 Oct 2002 18:55:11 +1000
Assume B has two network interfaces (B1 and B2) on seperate IPv4 links (net1
and net2). Host A is on net1 and Host C is on net2. Assume that both Host A
and Host C have the same autoconf address. So IP address is not enough
information for Host B to use to determine which interface to use in order to
contact Host A (instead of Host C).
If host B has socket binding on IP+port+local interface, it all works out.
You want SO_BINDTODEVICE, which we have.
We also prohibit a completely duplicate set of (local-addr, local-port,
remote-addr, remote-port) set even if SO_REUSEADDR is set unless
the local address is a multicast address; it is ambiguous and it may
steal packets from others; i.e. a kind of DoS.
This part of the patch is noop.
While doing *_get_port() daddr/dport are _unknown_ and always zero,
so it never works.
Please, remove these bits, the patch will become simpler.
What's about the problem, it cannot be a problem for TCP, connection
uniqueness is verified by tcp_*_check_established() not depending
on value of SO_REUSEADDR. What's about UDP, the problem really might
be a real problem, let's defer the issue, it looks absoluteky unrelated.
BTW the question: why is bindv6only in device configuration directory?
Alexey
@@ -177,23 +185,92 @@staticinlineinttcp_bind_conflict(structsock*sk,structtcp_bind_bucket*tb){structsock*sk2=tb->owners;-intsk_reuse=sk->reuse;+intsk_reuse,sk2_reuse;+intaddr_type2;+intret;++sk_reuse=0;+if(sk->reuse)+sk_reuse|=1;for(;sk2!=NULL;sk2=sk2->bind_next){-if(sk!=sk2&&-sk2->reuse<=1&&-sk->bound_dev_if==sk2->bound_dev_if){-if(!sk_reuse||-!sk2->reuse||-sk2->state==TCP_LISTEN){-if(!sk2->rcv_saddr||-!sk->rcv_saddr||-(sk2->rcv_saddr==sk->rcv_saddr))-break;+intboth_specified=0;++if(sk2==sk||+(sk2->bound_dev_if&&sk->bound_dev_if&&+sk2->bound_dev_if!=sk->bound_dev_if))+continue;++#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)+if(sk2->family==AF_INET6){+structin6_addr*sk2_rcv_saddr6=sk2->state!=TCP_TIME_WAIT?+&sk2->net_pinfo.af_inet6.rcv_saddr:+&((structtcp_tw_bucket*)sk2)->v6_rcv_saddr;+if(IN6_IS_ADDR_UNSPECIFIED(sk2_rcv_saddr6))+addr_type2=IPV6_ADDR_ANY;+elseif(IN6_IS_ADDR_V4MAPPED(sk2_rcv_saddr6))+addr_type2=IPV6_ADDR_MAPPED;+else+addr_type2=IPV6_ADDR_UNICAST;/*XXX*/+}else+addr_type2=IPV6_ADDR_MAPPED;+#else+addr_type2=IPV6_ADDR_MAPPED;+#endif+if((addr_type2!=IPV6_ADDR_MAPPED?addr_type2!=IPV6_ADDR_ANY:sk2->rcv_saddr)&&+sk->rcv_saddr){+if(sk2->rcv_saddr!=sk->rcv_saddr)+continue;+both_specified=1;+}++#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)+if(addr_type2!=IPV6_ADDR_MAPPED&&sk2->net_pinfo.af_inet6.ipv6only){+continue;+}+#endif++sk2_reuse=0;+if(sk2->reuse)+sk2_reuse|=1;++if(sk2_reuse&sk_reuse&3){/* NOT && */+ret=1;+if(both_specified){+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)+structin6_addr*sk2_daddr6=sk2->state!=TCP_TIME_WAIT?+&sk2->net_pinfo.af_inet6.daddr:+&((structtcp_tw_bucket*)sk2)->v6_daddr;+#endif+intaddr_type2d;+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)+if(sk2->family==AF_INET6){+if(IN6_IS_ADDR_UNSPECIFIED(sk2_daddr6))+addr_type2d=IPV6_ADDR_ANY;+elseif(IN6_IS_ADDR_V4MAPPED(sk2_daddr6))+addr_type2d=IPV6_ADDR_MAPPED;+else+addr_type2d=IPV6_ADDR_UNICAST;/*XXX*/+}else+addr_type2d=IPV6_ADDR_MAPPED;+#else+addr_type2d=IPV6_ADDR_MAPPED;+#endif+if(addr_type2d!=IPV6_ADDR_MAPPED?addr_type2d!=IPV6_ADDR_ANY:sk2->daddr)+continue;+}else{+if((addr_type2!=IPV6_ADDR_MAPPED?addr_type2!=IPV6_ADDR_ANY:sk2->rcv_saddr)||+sk->rcv_saddr)+continue;}}+ret=1;+gotofailed;}-returnsk2!=NULL;+/* If we found a conflict, fail. */+ret=sk2!=NULL;+failed:+returnret;}/* Obtain a reference to a local port for the given sock,
@@ -173,6 +173,8 @@sk->net_pinfo.af_inet6.mc_loop=1;sk->net_pinfo.af_inet6.pmtudisc=IPV6_PMTUDISC_WANT;+sk->net_pinfo.af_inet6.ipv6only=ipv6_devconf.bindv6only;+/* Init the ipv4 part of the socket since we can have sockets*usingv6APIforipv4.*/
@@ -248,6 +250,8 @@/* Check if the address belongs to the host. */if(addr_type==IPV6_ADDR_MAPPED){+if(sk->net_pinfo.af_inet6.ipv6only)+return-EADDRNOTAVAIL;v4addr=addr->sin6_addr.s6_addr32[3];if(inet_addr_type(v4addr)!=RTN_LOCAL)return-EADDRNOTAVAIL;
@@ -137,28 +145,70 @@gotosuccess;}else{structsock*sk2=tb->owners;-intsk_reuse=sk->reuse;-intaddr_type=ipv6_addr_type(&sk->net_pinfo.af_inet6.rcv_saddr);+intsk_reuse,sk2_reuse;+structin6_addr*sk_rcv_saddr6=sk->state!=TCP_TIME_WAIT?+&sk->net_pinfo.af_inet6.rcv_saddr:+&((structtcp_tw_bucket*)sk)->v6_rcv_saddr;+intaddr_type=ipv6_addr_type(sk_rcv_saddr6),+addr_type2;++sk_reuse=0;+if(sk->reuse)+sk_reuse|=1;/* We must walk the whole port owner list in this case. -DaveM */for(;sk2!=NULL;sk2=sk2->bind_next){-if(sk!=sk2&&-sk->bound_dev_if==sk2->bound_dev_if){-if(!sk_reuse||-!sk2->reuse||-sk2->state==TCP_LISTEN){-/* NOTE: IPv6 tw bucket have different format */-if(!sk2->rcv_saddr||-addr_type==IPV6_ADDR_ANY||-!ipv6_addr_cmp(&sk->net_pinfo.af_inet6.rcv_saddr,-sk2->state!=TCP_TIME_WAIT?-&sk2->net_pinfo.af_inet6.rcv_saddr:-&((structtcp_tw_bucket*)sk)->v6_rcv_saddr)||-(addr_type==IPV6_ADDR_MAPPED&&sk2->family==AF_INET&&-sk->rcv_saddr==sk2->rcv_saddr))-break;+intboth_specified=0;+structin6_addr*sk2_rcv_saddr6;+if(sk2==sk||+(sk2->bound_dev_if&&sk->bound_dev_if&&+sk2->bound_dev_if!=sk->bound_dev_if))+continue;+sk2_rcv_saddr6=sk2->state!=TCP_TIME_WAIT?+&sk2->net_pinfo.af_inet6.rcv_saddr:+&((structtcp_tw_bucket*)sk2)->v6_rcv_saddr;++if((addr_type2!=IPV6_ADDR_MAPPED?addr_type2!=IPV6_ADDR_ANY:sk2->rcv_saddr)&&+(addr_type!=IPV6_ADDR_MAPPED?addr_type!=IPV6_ADDR_ANY:sk->rcv_saddr)){+if(addr_type2==IPV6_ADDR_MAPPED||addr_type==IPV6_ADDR_MAPPED){+if(addr_type2!=addr_type||+sk2->rcv_saddr!=sk->rcv_saddr)+continue;+}else{+if(ipv6_addr_cmp(sk2_rcv_saddr6,sk_rcv_saddr6))+continue;}+both_specified=1;}++if((addr_type2==IPV6_ADDR_MAPPED&&+addr_type!=IPV6_ADDR_MAPPED&&sk->net_pinfo.af_inet6.ipv6only)||+(addr_type==IPV6_ADDR_MAPPED&&+addr_type2!=IPV6_ADDR_MAPPED&&sk2->net_pinfo.af_inet6.ipv6only)){+continue;+}++sk2_reuse=0;+if(sk2->reuse)+sk2_reuse|=1;++if(sk2_reuse&sk_reuse&3){/* NOT && */+ret=1;+if(both_specified){+structin6_addr*sk2_daddr6=sk2->state!=TCP_TIME_WAIT?+&sk2->net_pinfo.af_inet6.daddr:+&((structtcp_tw_bucket*)sk2)->v6_daddr;+intaddr_type2d=sk2->family==AF_INET6?ipv6_addr_type(sk2_daddr6):IPV6_ADDR_MAPPED;+if(addr_type2d!=IPV6_ADDR_MAPPED?addr_type2d!=IPV6_ADDR_ANY:sk2->daddr)+continue;+}else{+if((addr_type2!=IPV6_ADDR_MAPPED?addr_type2!=IPV6_ADDR_ANY:sk2->rcv_saddr)||+(addr_type!=IPV6_ADDR_MAPPED?addr_type!=IPV6_ADDR_ANY:sk->rcv_saddr))+continue;+}+}+ret=1;+gotofail_unlock;}/* If we found a conflict, fail. */ret=1;
From: David S. Miller <hidden> Date: 2002-10-03 13:02:54
From: kuznet@ms2.inr.ac.ru
Date: Thu, 3 Oct 2002 17:06:48 +0400 (MSD)
No, really! __Sharing__ of port space between IPv4 and IPv6 was mad
idea. It cannot generalized to other protocol families.
So, IPV6_V6ONLY is really unique for IPv6. Well, actually, it could
be negated: be default and the option would be called
IPV6_SHARE_THIS_PORT_TO_IPV4.
I think what I want to really say is that I want to provide
way for ipv4 application to say "no ipv6 connections on this
listening socket please".
So does it make no sense at all to have IP_V4ONLY?
For example, this IPV6_V6ONLY socket option is flawed. What we
really need is a generic socket option which says "my family only"
There is nothing ipv6 specific about such a socket attribute.
So please, create instead "SO_ONEFAMILY" or similar generic
socket option.
No, really! __Sharing__ of port space between IPv4 and IPv6 was mad
idea. It cannot generalized to other protocol families.
So, IPV6_V6ONLY is really unique for IPv6. Well, actually, it could
be negated: be default and the option would be called
IPV6_SHARE_THIS_PORT_TO_IPV4.
Alexey
From: David S. Miller <hidden> Date: 2002-10-03 13:13:40
From: Pekka Savola [off-list ref]
Date: Thu, 3 Oct 2002 16:18:53 +0300 (EEST)
On Thu, 3 Oct 2002, David S. Miller wrote:
> So does it make no sense at all to have IP_V4ONLY?
Umm, I think an app guy can do that with creating an AF_INET socket; there
will not be IPv6 there. Folks Who Think They Know Best decided that dual
use for AF_INET6 would be best, and IPV6_V6ONLY was invented (note: it'd
already implemented by some others) to repair that.
Ok, ignore my silly idea then.
Let us continue with verifying correctness of the USAGI
patch.
From: Pekka Savola <hidden> Date: 2002-10-03 13:18:53
On Thu, 3 Oct 2002, David S. Miller wrote:
From: kuznet@ms2.inr.ac.ru
Date: Thu, 3 Oct 2002 17:06:48 +0400 (MSD)
No, really! __Sharing__ of port space between IPv4 and IPv6 was mad
idea. It cannot generalized to other protocol families.
So, IPV6_V6ONLY is really unique for IPv6. Well, actually, it could
be negated: be default and the option would be called
IPV6_SHARE_THIS_PORT_TO_IPV4.
I think what I want to really say is that I want to provide
way for ipv4 application to say "no ipv6 connections on this
listening socket please".
So does it make no sense at all to have IP_V4ONLY?
Umm, I think an app guy can do that with creating an AF_INET socket; there
will not be IPv6 there. Folks Who Think They Know Best decided that dual
use for AF_INET6 would be best, and IPV6_V6ONLY was invented (note: it'd
already implemented by some others) to repair that.
--
Pekka Savola "Tell me of difficulties surmounted,
Netcore Oy not those you stumble over and fall"
Systems. Networks. Security. -- Robert Jordan: A Crown of Swords
From: David S. Miller <hidden> Date: 2002-10-03 14:10:58
From: YOSHIFUJI Hideaki / 吉藤英明 [off-list ref]
Date: Thu, 03 Oct 2002 23:15:34 +0900 (JST)
In article [off-list ref] (at Thu, 3 Oct 2002 17:01:11 +0400 (MSD)), kuznet@ms2.inr.ac.ru says:
> What's about the problem, it cannot be a problem for TCP, connection
> uniqueness is verified by tcp_*_check_established() not depending
> on value of SO_REUSEADDR. What's about UDP, the problem really might
> be a real problem, let's defer the issue, it looks absoluteky unrelated.
Hmm, but I'm afraid that different behavior between TCP and UDP would
confuse users.
He is saying we should do the TCP part first to make the patch simpler
and easier to verify.
Then we can investigate the UDP side seperately.
> BTW the question: why is bindv6only in device configuration directory?
Because I thought that net.ipv6.conf is the place for all
configuration...
It is for interface level configuration.
Do you propose to move it to parent directory (net.ipv6.bindv6only),
and put other general settings there?
Yes.
In article [off-list ref] (at Thu, 3 Oct 2002 17:01:11 +0400 (MSD)), kuznet@ms2.inr.ac.ru says:
While doing *_get_port() daddr/dport are _unknown_ and always zero,
so it never works.
Please, remove these bits, the patch will become simpler.
Ok, I'll do that.
What's about the problem, it cannot be a problem for TCP, connection
uniqueness is verified by tcp_*_check_established() not depending
on value of SO_REUSEADDR. What's about UDP, the problem really might
be a real problem, let's defer the issue, it looks absoluteky unrelated.
Hmm, but I'm afraid that different behavior between TCP and UDP would
confuse users.
BTW the question: why is bindv6only in device configuration directory?
Because I thought that net.ipv6.conf is the place for all
configuration...
Do you propose to move it to parent directory (net.ipv6.bindv6only),
and put other general settings there?
--yoshfuji
From: David S. Miller <hidden> Date: 2002-10-03 15:04:08
From: YOSHIFUJI Hideaki / 吉藤英明 [off-list ref]
Date: Fri, 04 Oct 2002 00:06:31 +0900 (JST)
In article [off-list ref] (at Thu, 03 Oct 2002 23:15:34 +0900 (JST)), YOSHIFUJI Hideaki / 吉藤英明 [off-list ref] says:
> In article [off-list ref] (at Thu, 3 Oct 2002 17:01:11 +0400 (MSD)), kuznet@ms2.inr.ac.ru says:
>
> > While doing *_get_port() daddr/dport are _unknown_ and always zero,
> > so it never works.
> >
> > Please, remove these bits, the patch will become simpler.
>
> Ok, I'll do that.
I remember that test for daddr is for existing sockets,
not for socket doing XXX_get_port().
So, I think I don't need to remove that.
Where can daddr/dport be non-zero during get_port()?
In article [off-list ref] (at Thu, 03 Oct 2002 08:04:08 -0700 (PDT)), "David S. Miller" [off-list ref] says:
I remember that test for daddr is for existing sockets,
not for socket doing XXX_get_port().
So, I think I don't need to remove that.
Where can daddr/dport be non-zero during get_port()?
test for daddr if for sk2.
sk2 is iterator for existing sockets, which can be "connected."
daddr can be non-zero, can't it?
Am I wrong???
--yoshfuji
test for daddr if for sk2.
sk2 is iterator for existing sockets, which can be "connected."
daddr can be non-zero, can't it?
Am I wrong???
You are absolutely right.
But then I am put to coma. Now I do not understand the goal of the check.
Can you give a simple example showing what illegal case this check is supposed
to eliminate?
Actually, it would be great if you said what is wrong in that my patch?
It looks so simple that I am not ready to agree that real one should be
so complicated. :-)
Alexey
From: David S. Miller <hidden> Date: 2002-10-23 07:23:03
From: YOSHIFUJI Hideaki / 吉藤英明 [off-list ref]
Date: Wed, 23 Oct 2002 16:24:39 +0900 (JST)
Well, I've refered alexey's patch and simplified many if-clauses.
Here's the new patch and test results. seems ok.
So, because you simplified some if clauses in Alexey's patch, USAGI is
the only entity who deserves credit for the work in the comments?
That's dishonest. Please fix this.
In article [off-list ref] (at Thu, 3 Oct 2002 19:52:40 +0400 (MSD)), kuznet@ms2.inr.ac.ru says:
Actually, it would be great if you said what is wrong in that my patch?
It looks so simple that I am not ready to agree that real one should be
so complicated. :-)
Well, I've refered alexey's patch and simplified many if-clauses.
Here's the new patch and test results. seems ok.
--------------------
Linux IPv6 stack provides the ability for IPv6 applications to
interoperate with IPv4 applications. Port space for TCP (or UDP) is
shared by IPv6 and IPv4. This conforms to RFC2553.
However, some kind of applications may want to restrict their use of
an IPv6 socket to IPv6 communication only. IPV6_V6ONLY socket option is
defined for such applications in RFC2553bis, which is successor of RFC2553.
This patch allows to bind both IPv6 and IPv4 sockets with the single
port number at the same time if IPV6_V6ONLY socket options is set to
the IPv6 socket.
Packet delivery strategy is similar to one before, but we prefer
IPv4 a bit.
Test results and patch against 2.4.20-pre11 follows.
*** Test for bind(2) ***
[SOCK_DGRAM w/o IPV6_V6ONLY]
0 :: 127.1 ::1
0 x x x x
:: x x x x
127.1 x x x o
::1 x x o x
==> OK
[SOCK_DGRAM w/ IPV6_V6ONLY]
0 :: 127.1 ::1
0 x o x o
:: o x o x
127.1 x o x o
::1 o x o x
==> OK
[SOCK_DGRAM w/ SO_REUSEADDR w/o IPV6_V6ONLY]
0 :: 127.1 ::1
0 o o o o
:: o o o o
127.1 o o o o
::1 o o o o
==> OK
[SOCK_DGRAM w/ SO_REUSEADDR w IPV6_V6ONLY]
0 :: 127.1 ::1
0 o o o o
:: o o o o
127.1 o o o o
::1 o o o o
==> OK
[SOCK_STREAM w/o IPV6_V6ONLY]
0 :: 127.1 ::1
0 x x x x
:: x x x x
127.1 x x x o
::1 x x o x
==> OK
[SOCK_STREAM w/ IPV6_V6ONLY]
0 :: 127.1 ::1
0 x o x o
:: o x o x
127.1 x o x o
::1 o x o x
==> OK
[SOCK_STREAM w/ SO_REUSEADDR w/o IPV6_V6ONLY]
0 :: 127.1 ::1
0 o o o o
:: o o o o
127.1 o o o o
::1 o o o o
==> OK
[SOCK_STREAM w/ SO_REUSEADDR w IPV6_V6ONLY]
0 :: 127.1 ::1
0 o o o o
:: o o o o
127.1 o o o o
::1 o o o o
==> OK
*** Test for Receiver ***
[IPv6]
1a. :: <- ::1
received from ::1
1b. :: w/IPV6_V6ONLY <- ::1
received from ::1
2a. :: <- 127.0.0.1
received from ::1
2b. :: w/IPV6_V6ONLY <- 127.0.0.1
none received
3a. :: <- ff02::1
received from fe80::EUI64
3b. :: w/IPV6_V6ONLY <- ff02::1
received from fe80::EUI64
4a. :: <- 224.0.0.1
received from ::ffff:ipv4addr
4b. :: w/IPV6_V6ONLY <- 224.0.0.1
none received
==> OK
[IPv4]
1. 0.0.0.0 <- ::1
none received
2. 0.0.0.0 <- 127.0.0.1
received from 127.0.0.1
3. 0.0.0.0 <- ff02::1
none received
4. 0.0.0.0 <- 224.0.0.1
received from ipv4addr
==> OK
[IPv6 vs IPv4]
5. :: w/IPV6_V6ONLY vs 0.0.0.0 <- ::1
ipv6 received from ::1
6. :: w/IPV6_V6ONLY vs 0.0.0.0 <- 127.0.0.1
ipv4 received from 127.0.0.1
7. :: w/IPV6_V6ONLY vs 0.0.0.0 <- ff02::1
ipv6 received from fe80::EUI64
8. :: w/IPV6_V6ONLY vs 0.0.0.0 <- 224.0.0.1
ipv4 received from ipv4addra
==> OK
-------------------------------------------------------------------
Patch-Name: Allow Both IPv6 and IPv4 Sockets on the Same Port Number (IPV6_V6ONLY Support) - Rev.2
Patch-Id: FIX_2_4_20_pre11_DOUBLEBIND-20021023
Patch-Author: YOSHIFUJI Hideaki / USAGI Project [off-list ref]
Credit: YOSHIFUJI Hideaki / USAGI Project [off-list ref]
Reference: RFC2553bis
-------------------------------------------------------------------
Index: Documentation/networking/ip-sysctl.txt
===================================================================
RCS file: /cvsroot/usagi/usagi-backport/linux24/Documentation/networking/ip-sysctl.txt,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.42.1
diff -u -r1.1.1.1 -r1.1.1.1.42.1
--- Documentation/networking/ip-sysctl.txt 20 Aug 2002 09:48:10 -0000 1.1.1.1+++ Documentation/networking/ip-sysctl.txt 22 Oct 2002 19:19:48 -0000 1.1.1.1.42.1
@@ -462,6 +462,15 @@ IPv6 has no global variables such as tcp_*. tcp_* settings under ipv4/ also apply to IPv6 [XXX?].+bindv6only - BOOLEAN+ Default value for IPV6_V6ONLY socket option,+ which restricts use of the IPv6 socket to IPv6 communication + only.+ TRUE: disable IPv4-mapped address feature+ FALSE: enable IPv4-mapped address feature++ Default: FALSE (as specified in RFC2553bis)+ conf/default/*: Change the interface-specific default settings.
@@ -173,6 +175,8 @@sk->net_pinfo.af_inet6.mc_loop=1;sk->net_pinfo.af_inet6.pmtudisc=IPV6_PMTUDISC_WANT;+sk->net_pinfo.af_inet6.ipv6only=sysctl_ipv6_bindv6only;+/* Init the ipv4 part of the socket since we can have sockets*usingv6APIforipv4.*/
@@ -148,14 +151,23 @@!sk2->reuse||sk2->state==TCP_LISTEN){/* NOTE: IPv6 tw bucket have different format */-if(!sk2->rcv_saddr||-addr_type==IPV6_ADDR_ANY||-!ipv6_addr_cmp(&sk->net_pinfo.af_inet6.rcv_saddr,-sk2->state!=TCP_TIME_WAIT?-&sk2->net_pinfo.af_inet6.rcv_saddr:-&((structtcp_tw_bucket*)sk)->v6_rcv_saddr)||-(addr_type==IPV6_ADDR_MAPPED&&sk2->family==AF_INET&&-sk->rcv_saddr==sk2->rcv_saddr))+if((!sk2->rcv_saddr&&!ipv6_only_sock(sk))||+(sk2->family==AF_INET6&&+ipv6_addr_any(&sk2->net_pinfo.af_inet6.rcv_saddr)&&+!(ipv6_only_sock(sk2)&&addr_type==IPV6_ADDR_MAPPED))||+(addr_type==IPV6_ADDR_ANY&&+(!ipv6_only_sock(sk)||+!(sk2->family==AF_INET6?ipv6_addr_type(&sk2->net_pinfo.af_inet6.rcv_saddr)==IPV6_ADDR_MAPPED:1)))||+(sk2->family==AF_INET6&&+!ipv6_addr_cmp(&sk->net_pinfo.af_inet6.rcv_saddr,+sk2->state!=TCP_TIME_WAIT?+&sk2->net_pinfo.af_inet6.rcv_saddr:+&((structtcp_tw_bucket*)sk)->v6_rcv_saddr))||+(addr_type==IPV6_ADDR_MAPPED&&+!ipv6_only_sock(sk2)&&+(!sk2->rcv_saddr||+!sk->rcv_saddr||+sk->rcv_saddr==sk2->rcv_saddr)))break;}}
From: Pekka Savola <hidden> Date: 2002-10-23 07:36:19
Overview looks good.
Does Bind 9.2.1 work this so that it can receive packets, when IPv6 is
also enabled, from IPv4 addresses using TCP without
'match-mapped-addresses yes', or is that a separate problem?
(with IPV6_V6ONLY if supported that would work all right.)
On Wed, 23 Oct 2002, YOSHIFUJI Hideaki / [iso-2022-jp] $B5HF#1QL@(B wrote:
quoted hunk
In article [off-list ref] (at Thu, 3 Oct 2002 19:52:40 +0400 (MSD)), kuznet@ms2.inr.ac.ru says:
quoted
Actually, it would be great if you said what is wrong in that my patch?
It looks so simple that I am not ready to agree that real one should be
so complicated. :-)
Well, I've refered alexey's patch and simplified many if-clauses.
Here's the new patch and test results. seems ok.
--------------------
Linux IPv6 stack provides the ability for IPv6 applications to
interoperate with IPv4 applications. Port space for TCP (or UDP) is
shared by IPv6 and IPv4. This conforms to RFC2553.
However, some kind of applications may want to restrict their use of
an IPv6 socket to IPv6 communication only. IPV6_V6ONLY socket option is
defined for such applications in RFC2553bis, which is successor of RFC2553.
This patch allows to bind both IPv6 and IPv4 sockets with the single
port number at the same time if IPV6_V6ONLY socket options is set to
the IPv6 socket.
Packet delivery strategy is similar to one before, but we prefer
IPv4 a bit.
Test results and patch against 2.4.20-pre11 follows.
*** Test for bind(2) ***
[SOCK_DGRAM w/o IPV6_V6ONLY]
0 :: 127.1 ::1
0 x x x x
:: x x x x
127.1 x x x o
::1 x x o x
==> OK
[SOCK_DGRAM w/ IPV6_V6ONLY]
0 :: 127.1 ::1
0 x o x o
:: o x o x
127.1 x o x o
::1 o x o x
==> OK
[SOCK_DGRAM w/ SO_REUSEADDR w/o IPV6_V6ONLY]
0 :: 127.1 ::1
0 o o o o
:: o o o o
127.1 o o o o
::1 o o o o
==> OK
[SOCK_DGRAM w/ SO_REUSEADDR w IPV6_V6ONLY]
0 :: 127.1 ::1
0 o o o o
:: o o o o
127.1 o o o o
::1 o o o o
==> OK
[SOCK_STREAM w/o IPV6_V6ONLY]
0 :: 127.1 ::1
0 x x x x
:: x x x x
127.1 x x x o
::1 x x o x
==> OK
[SOCK_STREAM w/ IPV6_V6ONLY]
0 :: 127.1 ::1
0 x o x o
:: o x o x
127.1 x o x o
::1 o x o x
==> OK
[SOCK_STREAM w/ SO_REUSEADDR w/o IPV6_V6ONLY]
0 :: 127.1 ::1
0 o o o o
:: o o o o
127.1 o o o o
::1 o o o o
==> OK
[SOCK_STREAM w/ SO_REUSEADDR w IPV6_V6ONLY]
0 :: 127.1 ::1
0 o o o o
:: o o o o
127.1 o o o o
::1 o o o o
==> OK
*** Test for Receiver ***
[IPv6]
1a. :: <- ::1
received from ::1
1b. :: w/IPV6_V6ONLY <- ::1
received from ::1
2a. :: <- 127.0.0.1
received from ::1
2b. :: w/IPV6_V6ONLY <- 127.0.0.1
none received
3a. :: <- ff02::1
received from fe80::EUI64
3b. :: w/IPV6_V6ONLY <- ff02::1
received from fe80::EUI64
4a. :: <- 224.0.0.1
received from ::ffff:ipv4addr
4b. :: w/IPV6_V6ONLY <- 224.0.0.1
none received
==> OK
[IPv4]
1. 0.0.0.0 <- ::1
none received
2. 0.0.0.0 <- 127.0.0.1
received from 127.0.0.1
3. 0.0.0.0 <- ff02::1
none received
4. 0.0.0.0 <- 224.0.0.1
received from ipv4addr
==> OK
[IPv6 vs IPv4]
5. :: w/IPV6_V6ONLY vs 0.0.0.0 <- ::1
ipv6 received from ::1
6. :: w/IPV6_V6ONLY vs 0.0.0.0 <- 127.0.0.1
ipv4 received from 127.0.0.1
7. :: w/IPV6_V6ONLY vs 0.0.0.0 <- ff02::1
ipv6 received from fe80::EUI64
8. :: w/IPV6_V6ONLY vs 0.0.0.0 <- 224.0.0.1
ipv4 received from ipv4addra
==> OK
-------------------------------------------------------------------
Patch-Name: Allow Both IPv6 and IPv4 Sockets on the Same Port Number (IPV6_V6ONLY Support) - Rev.2
Patch-Id: FIX_2_4_20_pre11_DOUBLEBIND-20021023
Patch-Author: YOSHIFUJI Hideaki / USAGI Project [off-list ref]
Credit: YOSHIFUJI Hideaki / USAGI Project [off-list ref]
Reference: RFC2553bis
-------------------------------------------------------------------
Index: Documentation/networking/ip-sysctl.txt
===================================================================
RCS file: /cvsroot/usagi/usagi-backport/linux24/Documentation/networking/ip-sysctl.txt,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.42.1
diff -u -r1.1.1.1 -r1.1.1.1.42.1
--- Documentation/networking/ip-sysctl.txt 20 Aug 2002 09:48:10 -0000 1.1.1.1+++ Documentation/networking/ip-sysctl.txt 22 Oct 2002 19:19:48 -0000 1.1.1.1.42.1
@@ -462,6 +462,15 @@ IPv6 has no global variables such as tcp_*. tcp_* settings under ipv4/ also apply to IPv6 [XXX?].+bindv6only - BOOLEAN+ Default value for IPV6_V6ONLY socket option,+ which restricts use of the IPv6 socket to IPv6 communication + only.+ TRUE: disable IPv4-mapped address feature+ FALSE: enable IPv4-mapped address feature++ Default: FALSE (as specified in RFC2553bis)+ conf/default/*: Change the interface-specific default settings.
@@ -173,6 +175,8 @@sk->net_pinfo.af_inet6.mc_loop=1;sk->net_pinfo.af_inet6.pmtudisc=IPV6_PMTUDISC_WANT;+sk->net_pinfo.af_inet6.ipv6only=sysctl_ipv6_bindv6only;+/* Init the ipv4 part of the socket since we can have sockets*usingv6APIforipv4.*/
@@ -148,14 +151,23 @@!sk2->reuse||sk2->state==TCP_LISTEN){/* NOTE: IPv6 tw bucket have different format */-if(!sk2->rcv_saddr||-addr_type==IPV6_ADDR_ANY||-!ipv6_addr_cmp(&sk->net_pinfo.af_inet6.rcv_saddr,-sk2->state!=TCP_TIME_WAIT?-&sk2->net_pinfo.af_inet6.rcv_saddr:-&((structtcp_tw_bucket*)sk)->v6_rcv_saddr)||-(addr_type==IPV6_ADDR_MAPPED&&sk2->family==AF_INET&&-sk->rcv_saddr==sk2->rcv_saddr))+if((!sk2->rcv_saddr&&!ipv6_only_sock(sk))||+(sk2->family==AF_INET6&&+ipv6_addr_any(&sk2->net_pinfo.af_inet6.rcv_saddr)&&+!(ipv6_only_sock(sk2)&&addr_type==IPV6_ADDR_MAPPED))||+(addr_type==IPV6_ADDR_ANY&&+(!ipv6_only_sock(sk)||+!(sk2->family==AF_INET6?ipv6_addr_type(&sk2->net_pinfo.af_inet6.rcv_saddr)==IPV6_ADDR_MAPPED:1)))||+(sk2->family==AF_INET6&&+!ipv6_addr_cmp(&sk->net_pinfo.af_inet6.rcv_saddr,+sk2->state!=TCP_TIME_WAIT?+&sk2->net_pinfo.af_inet6.rcv_saddr:+&((structtcp_tw_bucket*)sk)->v6_rcv_saddr))||+(addr_type==IPV6_ADDR_MAPPED&&+!ipv6_only_sock(sk2)&&+(!sk2->rcv_saddr||+!sk->rcv_saddr||+sk->rcv_saddr==sk2->rcv_saddr)))break;}}
--
Pekka Savola "Tell me of difficulties surmounted,
Netcore Oy not those you stumble over and fall"
Systems. Networks. Security. -- Robert Jordan: A Crown of Swords
In article [off-list ref] (at Wed, 23 Oct 2002 00:23:03 -0700 (PDT)), "David S. Miller" [off-list ref] says:
So, because you simplified some if clauses in Alexey's patch, USAGI is
the only entity who deserves credit for the work in the comments?
That's dishonest. Please fix this.
Hmm, we simplified our patch based on original linux kernel.
In fact, I use ipv6_only_sock() from his patch.
Sorry about that, apply this agaist that patch:
Index: net/ipv4/tcp_ipv4.c
===================================================================
RCS file: /cvsroot/usagi/usagi-backport/linux24/net/ipv4/tcp_ipv4.c,v
retrieving revision 1.1.1.2.16.2
diff -u -r1.1.1.2.16.2 tcp_ipv4.c
--- net/ipv4/tcp_ipv4.c 22 Oct 2002 19:40:48 -0000 1.1.1.2.16.2+++ net/ipv4/tcp_ipv4.c 23 Oct 2002 07:46:23 -0000
In article [off-list ref] (at Wed, 23 Oct 2002 10:36:19 +0300 (EEST)), Pekka Savola [off-list ref] says:
Does Bind 9.2.1 work this so that it can receive packets, when IPv6 is
also enabled, from IPv4 addresses using TCP without
'match-mapped-addresses yes', or is that a separate problem?
Bind9 trys to bind :: and all ipv4 addresses on the node.
--
Hideaki YOSHIFUJI @ USAGI Project [off-list ref]
GPG FP: 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA
From: David S. Miller <hidden> Date: 2002-10-23 10:12:24
From: Pekka Savola [off-list ref]
Date: Wed, 23 Oct 2002 13:15:26 +0300 (EEST)
Will this work too?
It should work as a side effect of the USAGI patch.
Because when bind9 does ipv6only bind on wildcarded ipv6,
the ipv4 specific IP binds will then be allowed.
From: Pekka Savola <hidden> Date: 2002-10-23 10:15:26
On Wed, 23 Oct 2002, YOSHIFUJI Hideaki / [iso-2022-jp] $B5HF#1QL@(B wrote:
In article [off-list ref] (at Wed, 23 Oct 2002 10:36:19 +0300 (EEST)), Pekka Savola [off-list ref] says:
quoted
Does Bind 9.2.1 work this so that it can receive packets, when IPv6 is
also enabled, from IPv4 addresses using TCP without
'match-mapped-addresses yes', or is that a separate problem?
Bind9 trys to bind :: and all ipv4 addresses on the node.
Yes, but binding those IPv4 addresses _for TCP_ failed after binding to
::, at least previously. That worked e.g. on BSD. Does that work now,
too?
I.e. I have two boxes, both running Bind 9.2.1. Linux gives:
$ netstat -an | grep :53
tcp 0 0 :::53 :::* LISTEN
udp 0 0 193.94.160.1:53 0.0.0.0:*
udp 0 0 127.0.0.1:53 0.0.0.0:*
udp 0 0 :::53 :::*
and BSD gives:
# netstat -an | grep .53
tcp6 0 0 ::1.953 *.* LISTEN
tcp4 0 0 127.0.0.1.953 *.* LISTEN
tcp4 0 0 127.0.0.1.53 *.* LISTEN
tcp4 0 0 193.166.4.206.53 *.* LISTEN
tcp4 0 0 193.166.187.10.53 *.* LISTEN
tcp6 0 0 *.53 *.* LISTEN
udp4 0 0 127.0.0.1.53 *.*
udp4 0 0 193.166.4.206.53 *.*
udp4 0 0 193.166.187.10.53 *.*
udp6 0 0 *.53 *.*
Will this work too?
--
Pekka Savola "Tell me of difficulties surmounted,
Netcore Oy not those you stumble over and fall"
Systems. Networks. Security. -- Robert Jordan: A Crown of Swords
From: Kyle C Quest <hidden> Date: 2002-10-23 15:53:07
I'm just curious... what happened to the generic option, SO_ONEFAMILY, that
would replace
the need for IPV6_V6ONLY?
In article [off-list ref] (at Thu, 3 Oct 2002
19:52:40 +0400 (MSD)), kuznet@ms2.inr.ac.ru says:
quoted
Actually, it would be great if you said what is wrong in that my patch?
It looks so simple that I am not ready to agree that real one should be
so complicated. :-)
Well, I've refered alexey's patch and simplified many if-clauses.
Here's the new patch and test results. seems ok.
--------------------
Linux IPv6 stack provides the ability for IPv6 applications to
interoperate with IPv4 applications. Port space for TCP (or UDP) is
shared by IPv6 and IPv4. This conforms to RFC2553.
However, some kind of applications may want to restrict their use of
an IPv6 socket to IPv6 communication only. IPV6_V6ONLY socket option is
defined for such applications in RFC2553bis, which is successor of
RFC2553.
This patch allows to bind both IPv6 and IPv4 sockets with the single
port number at the same time if IPV6_V6ONLY socket options is set to
the IPv6 socket.
Packet delivery strategy is similar to one before, but we prefer
IPv4 a bit.
Test results and patch against 2.4.20-pre11 follows.
*** Test for bind(2) ***
[SOCK_DGRAM w/o IPV6_V6ONLY]
0 :: 127.1 ::1
0 x x x x
:: x x x x
127.1 x x x o
::1 x x o x
==> OK
[SOCK_DGRAM w/ IPV6_V6ONLY]
0 :: 127.1 ::1
0 x o x o
:: o x o x
127.1 x o x o
::1 o x o x
==> OK
[SOCK_DGRAM w/ SO_REUSEADDR w/o IPV6_V6ONLY]
0 :: 127.1 ::1
0 o o o o
:: o o o o
127.1 o o o o
::1 o o o o
==> OK
[SOCK_DGRAM w/ SO_REUSEADDR w IPV6_V6ONLY]
0 :: 127.1 ::1
0 o o o o
:: o o o o
127.1 o o o o
::1 o o o o
==> OK
[SOCK_STREAM w/o IPV6_V6ONLY]
0 :: 127.1 ::1
0 x x x x
:: x x x x
127.1 x x x o
::1 x x o x
==> OK
[SOCK_STREAM w/ IPV6_V6ONLY]
0 :: 127.1 ::1
0 x o x o
:: o x o x
127.1 x o x o
::1 o x o x
==> OK
[SOCK_STREAM w/ SO_REUSEADDR w/o IPV6_V6ONLY]
0 :: 127.1 ::1
0 o o o o
:: o o o o
127.1 o o o o
::1 o o o o
==> OK
[SOCK_STREAM w/ SO_REUSEADDR w IPV6_V6ONLY]
0 :: 127.1 ::1
0 o o o o
:: o o o o
127.1 o o o o
::1 o o o o
==> OK
*** Test for Receiver ***
[IPv6]
1a. :: <- ::1
received from ::1
1b. :: w/IPV6_V6ONLY <- ::1
received from ::1
2a. :: <- 127.0.0.1
received from ::1
2b. :: w/IPV6_V6ONLY <- 127.0.0.1
none received
3a. :: <- ff02::1
received from fe80::EUI64
3b. :: w/IPV6_V6ONLY <- ff02::1
received from fe80::EUI64
4a. :: <- 224.0.0.1
received from ::ffff:ipv4addr
4b. :: w/IPV6_V6ONLY <- 224.0.0.1
none received
==> OK
[IPv4]
1. 0.0.0.0 <- ::1
none received
2. 0.0.0.0 <- 127.0.0.1
received from 127.0.0.1
3. 0.0.0.0 <- ff02::1
none received
4. 0.0.0.0 <- 224.0.0.1
received from ipv4addr
==> OK
[IPv6 vs IPv4]
5. :: w/IPV6_V6ONLY vs 0.0.0.0 <- ::1
ipv6 received from ::1
6. :: w/IPV6_V6ONLY vs 0.0.0.0 <- 127.0.0.1
ipv4 received from 127.0.0.1
7. :: w/IPV6_V6ONLY vs 0.0.0.0 <- ff02::1
ipv6 received from fe80::EUI64
8. :: w/IPV6_V6ONLY vs 0.0.0.0 <- 224.0.0.1
ipv4 received from ipv4addra
==> OK
-------------------------------------------------------------------
Patch-Name: Allow Both IPv6 and IPv4 Sockets on the Same Port Number
@@ -173,6 +175,8 @@sk->net_pinfo.af_inet6.mc_loop=1;sk->net_pinfo.af_inet6.pmtudisc=IPV6_PMTUDISC_WANT;+sk->net_pinfo.af_inet6.ipv6only=sysctl_ipv6_bindv6only;+/* Init the ipv4 part of the socket since we can have sockets*usingv6APIforipv4.*/
@@ -148,14 +151,23 @@!sk2->reuse||sk2->state==TCP_LISTEN){/* NOTE: IPv6 tw bucket have different format */-if(!sk2->rcv_saddr||-addr_type==IPV6_ADDR_ANY||-!ipv6_addr_cmp(&sk->net_pinfo.af_inet6.rcv_saddr,-sk2->state!=TCP_TIME_WAIT?-&sk2->net_pinfo.af_inet6.rcv_saddr:-&((structtcp_tw_bucket*)sk)->v6_rcv_saddr)||-(addr_type==IPV6_ADDR_MAPPED&&sk2->family==AF_INET&&-sk->rcv_saddr==sk2->rcv_saddr))+if((!sk2->rcv_saddr&&!ipv6_only_sock(sk))||+(sk2->family==AF_INET6&&+ipv6_addr_any(&sk2->net_pinfo.af_inet6.rcv_saddr)&&+!(ipv6_only_sock(sk2)&&addr_type==IPV6_ADDR_MAPPED))||+(addr_type==IPV6_ADDR_ANY&&+(!ipv6_only_sock(sk)||+!(sk2->family==AF_INET6?
From: Pekka Savola <hidden> Date: 2002-10-23 16:06:08
On Wed, 23 Oct 2002, Kyle C Quest wrote:
I'm just curious... what happened to the generic option, SO_ONEFAMILY, that
would replace
the need for IPV6_V6ONLY?
This kind of thing is only applicable to IPv4 and IPv6 (and badly even
there), there is no use trying to generalize it -- the idea was discarded.
quoted
In article [off-list ref] (at Thu, 3 Oct 2002
19:52:40 +0400 (MSD)), kuznet@ms2.inr.ac.ru says:
quoted
quoted
Actually, it would be great if you said what is wrong in that my patch?
It looks so simple that I am not ready to agree that real one should be
so complicated. :-)
Well, I've refered alexey's patch and simplified many if-clauses.
Here's the new patch and test results. seems ok.
--------------------
Linux IPv6 stack provides the ability for IPv6 applications to
interoperate with IPv4 applications. Port space for TCP (or UDP) is
shared by IPv6 and IPv4. This conforms to RFC2553.
However, some kind of applications may want to restrict their use of
an IPv6 socket to IPv6 communication only. IPV6_V6ONLY socket option is
defined for such applications in RFC2553bis, which is successor of
RFC2553.
quoted
This patch allows to bind both IPv6 and IPv4 sockets with the single
port number at the same time if IPV6_V6ONLY socket options is set to
the IPv6 socket.
Packet delivery strategy is similar to one before, but we prefer
IPv4 a bit.
Test results and patch against 2.4.20-pre11 follows.
*** Test for bind(2) ***
[SOCK_DGRAM w/o IPV6_V6ONLY]
0 :: 127.1 ::1
0 x x x x
:: x x x x
127.1 x x x o
::1 x x o x
==> OK
[SOCK_DGRAM w/ IPV6_V6ONLY]
0 :: 127.1 ::1
0 x o x o
:: o x o x
127.1 x o x o
::1 o x o x
==> OK
[SOCK_DGRAM w/ SO_REUSEADDR w/o IPV6_V6ONLY]
0 :: 127.1 ::1
0 o o o o
:: o o o o
127.1 o o o o
::1 o o o o
==> OK
[SOCK_DGRAM w/ SO_REUSEADDR w IPV6_V6ONLY]
0 :: 127.1 ::1
0 o o o o
:: o o o o
127.1 o o o o
::1 o o o o
==> OK
[SOCK_STREAM w/o IPV6_V6ONLY]
0 :: 127.1 ::1
0 x x x x
:: x x x x
127.1 x x x o
::1 x x o x
==> OK
[SOCK_STREAM w/ IPV6_V6ONLY]
0 :: 127.1 ::1
0 x o x o
:: o x o x
127.1 x o x o
::1 o x o x
==> OK
[SOCK_STREAM w/ SO_REUSEADDR w/o IPV6_V6ONLY]
0 :: 127.1 ::1
0 o o o o
:: o o o o
127.1 o o o o
::1 o o o o
==> OK
[SOCK_STREAM w/ SO_REUSEADDR w IPV6_V6ONLY]
0 :: 127.1 ::1
0 o o o o
:: o o o o
127.1 o o o o
::1 o o o o
==> OK
*** Test for Receiver ***
[IPv6]
1a. :: <- ::1
received from ::1
1b. :: w/IPV6_V6ONLY <- ::1
received from ::1
2a. :: <- 127.0.0.1
received from ::1
2b. :: w/IPV6_V6ONLY <- 127.0.0.1
none received
3a. :: <- ff02::1
received from fe80::EUI64
3b. :: w/IPV6_V6ONLY <- ff02::1
received from fe80::EUI64
4a. :: <- 224.0.0.1
received from ::ffff:ipv4addr
4b. :: w/IPV6_V6ONLY <- 224.0.0.1
none received
==> OK
[IPv4]
1. 0.0.0.0 <- ::1
none received
2. 0.0.0.0 <- 127.0.0.1
received from 127.0.0.1
3. 0.0.0.0 <- ff02::1
none received
4. 0.0.0.0 <- 224.0.0.1
received from ipv4addr
==> OK
[IPv6 vs IPv4]
5. :: w/IPV6_V6ONLY vs 0.0.0.0 <- ::1
ipv6 received from ::1
6. :: w/IPV6_V6ONLY vs 0.0.0.0 <- 127.0.0.1
ipv4 received from 127.0.0.1
7. :: w/IPV6_V6ONLY vs 0.0.0.0 <- ff02::1
ipv6 received from fe80::EUI64
8. :: w/IPV6_V6ONLY vs 0.0.0.0 <- 224.0.0.1
ipv4 received from ipv4addra
==> OK
-------------------------------------------------------------------
Patch-Name: Allow Both IPv6 and IPv4 Sockets on the Same Port Number
@@ -173,6 +175,8 @@sk->net_pinfo.af_inet6.mc_loop=1;sk->net_pinfo.af_inet6.pmtudisc=IPV6_PMTUDISC_WANT;+sk->net_pinfo.af_inet6.ipv6only=sysctl_ipv6_bindv6only;+/* Init the ipv4 part of the socket since we can have sockets*usingv6APIforipv4.*/
@@ -148,14 +151,23 @@!sk2->reuse||sk2->state==TCP_LISTEN){/* NOTE: IPv6 tw bucket have different format */-if(!sk2->rcv_saddr||-addr_type==IPV6_ADDR_ANY||-!ipv6_addr_cmp(&sk->net_pinfo.af_inet6.rcv_saddr,-sk2->state!=TCP_TIME_WAIT?-&sk2->net_pinfo.af_inet6.rcv_saddr:-&((structtcp_tw_bucket*)sk)->v6_rcv_saddr)||-(addr_type==IPV6_ADDR_MAPPED&&sk2->family==AF_INET&&-sk->rcv_saddr==sk2->rcv_saddr))+if((!sk2->rcv_saddr&&!ipv6_only_sock(sk))||+(sk2->family==AF_INET6&&+ipv6_addr_any(&sk2->net_pinfo.af_inet6.rcv_saddr)&&+!(ipv6_only_sock(sk2)&&addr_type==IPV6_ADDR_MAPPED))||+(addr_type==IPV6_ADDR_ANY&&+(!ipv6_only_sock(sk)||+!(sk2->family==AF_INET6?
--
Pekka Savola "Tell me of difficulties surmounted,
Netcore Oy not those you stumble over and fall"
Systems. Networks. Security. -- Robert Jordan: A Crown of Swords
No.
The question follows: what the hell does it make this? What is special
in ipv4 that it needs to bind to its addresses? With IPV6_V6ONLY connections
to all the IPv4 addresses but listed ones will be refused. I guess it is
not _that_ thing which bind expects.
Alexey
No.
The question follows: what the hell does it make this? What is special
in ipv4 that it needs to bind to its addresses? With IPV6_V6ONLY connections
to all the IPv4 addresses but listed ones will be refused. I guess it is
not _that_ thing which bind expects.
I'm not sure I understand what you mean. Note that the last line is
_tcp6_:
tcp6 0 0 *.53 *.* LISTEN
So, I belive using IPV6_V6ONLY it should indeed work.
(The reasoning in Bind is that you can bind to addresses _only_ in IPv4
but you don't have to. It's done in these cases. For IPv6, it's
all-or-nothing.)
--
Pekka Savola "Tell me of difficulties surmounted,
Netcore Oy not those you stumble over and fall"
Systems. Networks. Security. -- Robert Jordan: A Crown of Swords