Re: bind() allowed to non-local addresses
Eric Lammerts wrote: > > On Fri, 20 Oct 2000, Matt Peterson wrote: > > Are you also suggesting that every other program that expects bind() to > > fail with EADDRNOTAVAIL are broken too? Just for fun, I greped all > > sources of software shipped in Caldera's distributions for instances of > > where a check is made for EADDRNOTAVAIL after a call to bind(). Guess > > what else besides Java is probably "broken" ... > > > > - lpng > > - bind 8.2 > > - automount > > - cvs > > - dhcpd > > - KDE > > - UCL mbone > > - ncftp > > - netatalk > > - nfsd > > - rexec > > - pppd > > - sendmail > > - xchat > > Just for fun I looked at the sources of cvs, ncftp, netatalk, rexec > and pppd. Guess what? None of them check for EADDRNOTAVAIL after a > call to bind(). I stand corrected. I double checked and not all of the above check EADDRNOTAVAIL after a bind(). My grep script was only smart enough to check for calls to bind() and EADDRNOTAVAIL . It turns out that EADDRNOTAVAIL is also a commonly checked return code to the ioctl(SIOCDIFADDR) which is not an issue because it probably does not follow the bind() code path through the kernel. > Cvs and pppd don't even call bind()! > > Get your facts straight, please. cvs-1.10.8/vms/rcmd.c:64:rs = bind(s, (struct sockaddr *)&local_isa, sizeof(local_isa)); cvs-1.10.8/vms/rcmd.c:79:rs = bind(s, (struct sockaddr *)&local_isa, sizeof(local_isa)); The cvs code does call bind, but you are right, it does not check rs for EADDRNOTAVAIL. pppd uses the ioctl() mentioned above. My apologies. I do not have time to go through an analize code to see if the success of bind when the interface is not known would cause any problems. My guess is that it would not because before binding the interface is looked up via ioctl() or gethostbyname(). Also as mentioned earlier in this thread, INADDR_ANY is also commonly used. The point I probably failed in making is that (right or wrong) many developers (because of tradition, documentation and various specs) expect bind() on a non-local address to fail. This is certainly the case with Sun and many authors of Sockets interface documentation. Anyway, I am through discussing the issue. We will probably use the sysctl solution posted by David Miller earlier in the thread with default bind() behavior reverted. -- Matthew Peterson Sr. Software Engineer Caldera Systems, Inc [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] Please read the FAQ at http://www.tux.org/lkml/
Re: bind() allowed to non-local addresses
David Woodhouse wrote: > > [EMAIL PROTECTED] said: > > There is NOT a bug in the JVM code that handles java.net.DatagramSock > > et. Don't you find it a little compelling that the nearly identical > > JVM code passes the Java Compatibility test suite on Linux 2.2, > > Solaris, HPUX, SCO, and even Windows? > > If the JVM spec says that it 'MUST' fail when used on a non-local address, > and the POSIX spec for bind does not say that it 'MUST' fail, then yes, > there is a bug in the JVM if it assumes that the two are compatible. Does some one have a copy of the posix 1003.1g draft so this can be verified. This is the kind of ammunition I was talking about earlier that I would need to convince Sun to change the compatibility test suite. However, if the 1003.1g draft even mentions failure with errno set to EADDRNOTAVAIL in a "SHOULD" context, or if EADDRNOTAVAIL is mentioned at all as a error code for non-local bind, then I am afraid (given the widespread acceptance of bind() behavior), Sun will not change the test suite. > The fact that they just happen to behave the same in certain phases of the > moon and on other operating systems is not relevant. Huh? Please give me one example of a sockets implementation (besides Linux 2.4) of where bind() does not fail if an attempt is made to bind do a non-local address. Your telling me that developers who are used to seeing a consistant behavior across OSes will think that the difference in Linux 2.4 is irrelivant? I don't think so. > We may decide that we want to pander to this brokenness, especially given > the widespread nature of the false assumption that bind() will fail when > given a non-local address. But that doesn't make the JVM non-broken. > Are you also suggesting that every other program that expects bind() to fail with EADDRNOTAVAIL are broken too? Just for fun, I greped all sources of software shipped in Caldera's distributions for instances of where a check is made for EADDRNOTAVAIL after a call to bind(). Guess what else besides Java is probably "broken" ... - lpng - bind 8.2 - automount - cvs - dhcpd - KDE - UCL mbone - ncftp - netatalk - nfsd - rexec - pppd - sendmail - xchat ... but the Linux kernel... Nope, it's not broken. Lets email maintainers of all these projects and tell them that they have been mistaken all this time in their understanding how bind() should work and see what kind of a response we get. Matt - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] Please read the FAQ at http://www.tux.org/lkml/
Re: bind() allowed to non-local addresses
Andi Kleen wrote: > > > The JRE compliance tests have a test which makes sure that for a > > non-local addresses, bind() returns an error code, specifically > > -EADDRNOTAVAIL. > > Sounds like a bug that should be reported to Sun. > Hello? Send a bug to Sun? I don't see any logic here. I have traced through the Sun code all the way to the bind() call and through to the code in the kernel where the check for local interfaces is ignored. The JVM code path is VERY simple and ends up in a straightforward call to bind(). The same problem is easily reproduced in C code. There is NOT a bug in the JVM code that handles java.net.DatagramSocket. Don't you find it a little compelling that the nearly identical JVM code passes the Java Compatibility test suite on Linux 2.2, Solaris, HPUX, SCO, and even Windows? I might even go as far as to argue that there is not a problem with the JCK test suite either. The BSD Socket interface is documented. It may be a little shady in some areas (this being one of them) but at least the Sun test suite is expecting the documented (look at any man page or sockets reference) and long standing behavior of bind(). Any argument for changing the way bind() works needs to be able to stand up to the challenge of developers who are expecting bind() to behave the way it has for many years on many different platforms. Again, there is not a bug in the JVM's handling of java.net.DatagramSocket(). I offered the JVM as an example only because it is one application that I know of expects the standardized behavior of bind(). The bind() behavior in Linux 2.4 is not an issue because it affects Java only -- it is an issue because it also affects other applications and developers that are likewise expecting the traditional bind() behavior. -- Matthew Peterson Sr. Software Engineer Caldera Systems, Inc [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] Please read the FAQ at http://www.tux.org/lkml/
Re: bind() allowed to non-local addresses
"David S. Miller" wrote: > >Date: Thu, 19 Oct 2000 09:23:26 -0600 >From: Matt Peterson <[EMAIL PROTECTED]> > >Have you thought about an SOL_SOCKET level socket option? It might >be more intuitive for programmers than an ioctl and could be >documented with sockets where it will be used. > > Where did I say "ioctl"? Sorry, I've had ioctl on the brain lately. Yes, sysctl is a good solution. -- Matthew Peterson Sr. Software Engineer Caldera Systems, Inc [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] Please read the FAQ at http://www.tux.org/lkml/
Re: bind() allowed to non-local addresses
"David S. Miller" wrote: > >Date: Thu, 19 Oct 2000 09:07:57 -0600 >From: Matt Peterson <[EMAIL PROTECTED]> > >Hence, the JVM fails compatibility on Linux 2.4. > > Due ot this and other reasons I'm restoring the 2.2.x behavior by > default, but adding a sysctl so that systems using dynamic addressing > may elect to get the different bind() behavior. > > Later, > David S. Miller > [EMAIL PROTECTED] Have you thought about an SOL_SOCKET level socket option? It might be more intuitive for programmers than an ioctl and could be documented with sockets where it will be used. Again, we would run into compatibility issues with other Sockets implementations, but traditionally the sockopt funtionality between implementations are (sorta) expected to vary. Just an idea. -- Matthew Peterson Sr. Software Engineer Caldera Systems, Inc [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] Please read the FAQ at http://www.tux.org/lkml/
Re: bind() allowed to non-local addresses
"David S. Miller" wrote: > >Date:Wed, 18 Oct 2000 17:20:22 -0600 >From: Matt Peterson <[EMAIL PROTECTED]> > >Assuming that my "compatibility argument" is not considered valid. >What I really need is some good ammunition for going back to Sun to >ask them to change the JRE spec -- like some significant kernel >features or Linux applications that relies on this new bind() >behavior. > > How about first finding out why their buggy JRE detects whether an > address is local by trying to bind() to it :-) > > Really, when an application feeds a specific address into bind() it > must have good reason for selecting it. All I want to know in this > specific instance, is why Sun's JRE is sending non-local addresses > into bind(), that's all. > > Later, > David S. Miller > [EMAIL PROTECTED] The JVM is simply running the appropriate native code for bytecodes that represents the java.net.DatagramSocket(int port, InetAddress laddr) constructor. Documentation for this constructor reads "Creates a datagram socket, bound to the specified local address." What do you expect the JVM to will do? It trys to bind() to the supplied address and port. There are no bugs here. java.net.DatagramSocket is just trying to emulate the expected Sockets interface behavior. The Sun JVM compatibility test suite appropriately includes some test to ensure that error conditions are handled correctly. Supplying a non-local IP address to bind() is an error condition. Hence, the JVM fails compatibility on Linux 2.4. -- Matthew Peterson Sr. Software Engineer Caldera Systems, Inc [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] Please read the FAQ at http://www.tux.org/lkml/
Re: bind() allowed to non-local addresses
[EMAIL PROTECTED] wrote: > > Hello! > > > Using linux-2.4.0-test9, bind() incorrectly allows a bind to a non-local > > address. The correct behavior should be a return code of -1 with errno > > set to EADDRNOTAVAIL. > > You can bind to any address, it is your right. You will not able > to receive on or to send from such socket until address will become > really local. > > Such bind is allowed because the address can be dynamic. > Nobody wants that a service did not start only because > the moment of start address was temporarily off-line. > > Alexey This issue here is mostly one of compatibility and standards compliance. You may not be able to obtain the Posix draft P1003.1g but you should be able to see XNS Issue 5.2 which defines the industry-standard Open Systems interfaces to communications services (including Sockets). You might be required to supply name and email address to see the free online copy: http://www.opengroup.org/onlinepubs/009619199/bind.htm#tagcjh_03_03 According to the specs and numerous implementations, looks like the way bind() is supposed to work is that it returns EADDRNOTAVAIL if the specified address is not available from the local machine rather than waiting for a recv() or send() to fail. Many developers working on software ports have felt the pain of loose interpretations of the Sockets interface. This divergence would add yet another headache. Your argument for supporting dynamic interfaces is valid, I really like the idea of being able to bind to an interface that is not up yet. I can definitely see where this would be helpful -- too bad is is not part of the spec. What I don't like about it is that it may break existing applications. Is the Socket spec so loose that Linux 2.4 can be comfortable in its current condition? I hope not. Since it is possible that this "bug" un-repairably breaks the portability of our application (a Java virtual machine) to the new kernel, I suspect that there may be other applications that it breaks too. Assuming that my "compatibility argument" is not considered valid. What I really need is some good ammunition for going back to Sun to ask them to change the JRE spec -- like some significant kernel features or Linux applications that relies on this new bind() behavior. -- Matthew Peterson Sr. Software Engineer Caldera Systems, Inc [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] Please read the FAQ at http://www.tux.org/lkml/
bind() allowed to non-local addresses
Using linux-2.4.0-test9, bind() incorrectly allows a bind to a non-local address. The correct behavior should be a return code of -1 with errno set to EADDRNOTAVAIL. (Simple snippet to reproduce/debug the problem is available on request) There appears to be significant differences between the net/ipv4/af_inet.c:inet_bind() in the 2.2 and 2.4 sources. The inet_bind() in the 2.2 sources contains a check to ensure that the value returned by inet_addr_type() is RTN_LOCAL as well as a #ifdef'ed check to allow the bind in certain cases if the kernel was compiled with transparent proxy is enabled. In inet_bind() of the 2.4 tree all of these checks are conspicuously absent. The following patch fixes the problem for me, but I am still concerned possibly breaking transparent proxy. Basically the patch is nothing more than the addition of a simple check for RTN_LOCAL. (Moving call to inet_addr_type() is a *very* nit-picky "optimization" that eliminates wasted time in the call in the event that subsequent port and capability check fails). *** af_inet.c Wed Oct 18 11:06:15 2000 --- af_inet.c.orig Mon Sep 18 16:04:13 2000 *** *** 459,471 if (addr_len < sizeof(struct sockaddr_in)) return -EINVAL; snum = ntohs(addr->sin_port); if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE)) return -EACCES; ! chk_addr_ret = inet_addr_type(addr->sin_addr.s_addr); ! /* We keep a pair of addresses. rcv_saddr is the one * used by hash lookups, and saddr is used for transmit. * * In the BSD API these are the same except where it --- 459,471 if (addr_len < sizeof(struct sockaddr_in)) return -EINVAL; + chk_addr_ret = inet_addr_type(addr->sin_addr.s_addr); + snum = ntohs(addr->sin_port); if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE)) return -EACCES; /* We keep a pair of addresses. rcv_saddr is the one * used by hash lookups, and saddr is used for transmit. * * In the BSD API these are the same except where it *** *** 483,493 sk->rcv_saddr = sk->saddr = addr->sin_addr.s_addr; if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST) sk->saddr = 0; /* Use device */ ! else if(chk_addr_ret != RTN_LOCAL){ ! err = -EADDERNOTAVAIL; ! goto out; ! } ! /* Make sure we are allowed to bind here. */ if (sk->prot->get_port(sk, snum) != 0) { sk->saddr = sk->rcv_saddr = 0; --- 483,489 sk->rcv_saddr = sk->saddr = addr->sin_addr.s_addr; if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST) sk->saddr = 0; /* Use device */ ! /* Make sure we are allowed to bind here. */ if (sk->prot->get_port(sk, snum) != 0) { sk->saddr = sk->rcv_saddr = 0; Discussion? Please personally CC me <[EMAIL PROTECTED]> as I am not currently subscribed to the linux-kernel list. Thanks. -- Matthew Peterson Software Engineer Caldera Systems, Inc - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] Please read the FAQ at http://www.tux.org/lkml/