Hi Eric, Paolo, Simon, About sendto, I wrote: > > > -extern int rpl_sendto (int, const void *, int, int, struct sockaddr *, > > > int); > > > +extern int rpl_sendto (int, const void *, int, int, struct sockaddr *, > > > int) > > > + _GL_ARG_NONNULL ((2, 5)); > > > > Bug: Arg 5 can be NULL, since POSIX states that "The send( ) function is > > equivalent to sendto( ) with a null pointer dest_len argument" (well, > > that's > > also a bug in POSIX, since dest_len is socklen_t; it obviously meant a null > > dest_addr argument). > > The only indication in the sendto specification that I can see is the > sentence "If the socket is connection-mode, dest_addr shall be ignored." > So, if a user knows that the socket is connection-mode, he may pass NULL. > But I would qualify this as dangerous practice, therefore I leave the warning > in.
Now I see in the Linux manpage <http://www.kernel.org/doc/man-pages/online/pages/man2/sendto.2.html> that it is recommended practice to pass a 5th argument NULL in some cases: "If sendto() is used on a connection-mode (SOCK_STREAM, SOCK_SEQPACKET) socket, the arguments dest_addr and addrlen are ignored (and the error EISCONN may be returned when they are not NULL and 0)" So I remove the warning for arg 5. > > > -extern int rpl_recvfrom (int, void *, int, int, struct sockaddr *, int > > > *); > > > +extern int rpl_recvfrom (int, void *, int, int, struct sockaddr *, int *) > > > + _GL_ARG_NONNULL ((2, 6)); > > > > Bug: Arg 6 can be NULL, since POSIX states that "The recv( ) function is > > equivalent to recvfrom( ) with a zero address_len argument" (well, > > technically, > > a null address_len argument only makes sense when address [arg 5] is also > > NULL). > > Indeed, when the 5th argument is NULL, the 6th argument can be NULL as well. > Corrected. The Linux manpage <http://www.kernel.org/doc/man-pages/online/pages/man2/recvfrom.2.html> also mentions this possibility: "When src_addr is NULL, nothing is filled in; in this case, addrlen is not used, and should also be NULL." But this also means that our recvfrom wrapper makes invalid memory accesses. Here is a proposed patch: 2009-12-10 Bruno Haible <[email protected]> * lib/recvfrom.c (rpl_recvfrom): Allow the from argument to be NULL. --- lib/recvfrom.c.orig 2009-12-11 00:33:28.000000000 +0100 +++ lib/recvfrom.c 2009-12-11 00:14:22.000000000 +0100 @@ -1,6 +1,6 @@ /* recvfrom.c --- wrappers for Windows recvfrom function - Copyright (C) 2008 Free Software Foundation, Inc. + Copyright (C) 2008-2009 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -32,7 +32,7 @@ rpl_recvfrom (int fd, void *buf, int len, int flags, struct sockaddr *from, int *fromlen) { - int frombufsize = *fromlen; + int frombufsize = (from != NULL ? *fromlen : 0); SOCKET sock = FD_TO_SOCKET (fd); int r = recvfrom (sock, buf, len, flags, from, fromlen); @@ -41,7 +41,7 @@ /* Winsock recvfrom() only returns a valid 'from' when the socket is connectionless. POSIX gives a valid 'from' for all types of sockets. */ - else if (*fromlen == frombufsize) + else if (from != NULL && *fromlen == frombufsize) rpl_getpeername (fd, from, fromlen); return r;
