From owner-freebsd-net@FreeBSD.ORG Wed Jan 19 15:50:04 2005 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 327BB16A4CE for ; Wed, 19 Jan 2005 15:50:04 +0000 (GMT) Received: from kazi.fit.vutbr.cz (kazi.fit.vutbr.cz [147.229.8.12]) by mx1.FreeBSD.org (Postfix) with ESMTP id 03E6143D31 for ; Wed, 19 Jan 2005 15:50:01 +0000 (GMT) (envelope-from cejkar@fit.vutbr.cz) Received: from kazi.fit.vutbr.cz (localhost [127.0.0.1]) by kazi.fit.vutbr.cz (8.12.11/8.12.11) with ESMTP id j0JFntCg095177 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 19 Jan 2005 16:49:55 +0100 (CET) Received: (from cejkar@localhost) by kazi.fit.vutbr.cz (8.12.11/8.12.5/Submit) id j0JFnsKq095176; Wed, 19 Jan 2005 16:49:54 +0100 (CET) X-Authentication-Warning: kazi.fit.vutbr.cz: cejkar set sender to cejkar@fit.vutbr.cz using -f Date: Wed, 19 Jan 2005 16:49:54 +0100 From: Rudolf Cejka To: Giorgos Keramidas Message-ID: <20050119154954.GA92456@fit.vutbr.cz> References: <200501180952.j0I9qr8k045665@kazi.fit.vutbr.cz> <20050119110654.GB55252@orion.daedalusnetworks.priv> <20050119115913.GA65140@fit.vutbr.cz> <20050119121212.GA38988@orion.daedalusnetworks.priv> <20050119132000.GB73575@fit.vutbr.cz> <20050119143405.GA17656@orion.daedalusnetworks.priv> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20050119143405.GA17656@orion.daedalusnetworks.priv> User-Agent: Mutt/1.4.2.1i X-Scanned-By: MIMEDefang 2.16 (www . roaringpenguin . com / mimedefang) cc: freebsd-net@freebsd.org Subject: Re: docs/76399: [PATCH] sendto(2) is missing possible error EISCONN X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 19 Jan 2005 15:50:04 -0000 Hello to freebsd-net, please, do you have some net-points to our discussion? It groved from docs-only problem ( http://www.freebsd.org/cgi/query-pr.cgi?pr=76399 ) to net-related questions too. Thanks. Giorgos Keramidas wrote (2005/01/19): > On 2005-01-19 14:20, Rudolf Cejka wrote: > >Giorgos Keramidas wrote (2005/01/19): > >> Ah, I see now. We need to expand the description of sendto() a bit. > > > > I think that very good source would be > > http://www.opengroup.org/onlinepubs/009695399/functions/sendto.html > > if we have really permission to use it ;o) > > I think we do have their permission. I will ask around at freebsd-doc > to see if anyone remembers more clearly than me. > > > > SOCK_DGRAM sockets are a bit different. The handling of sendto() for > > > already connected UDP sockets is different than TCP. > > > > Hmm, it really seems that SOCK_DGRAM and SOCK_STREAM are handled in > > the different way and maybe it would not be a bad idea to change the > > behaviour of FreeBSD to just one unified way, like SUSv3 looks like: > > > > - If the socket is connection-mode, dest_addr shall be ignored. > > - [EISCONN] A destination address was specified and the socket is > > already connected. This error may or may not be returned for > > connection mode sockets. > > I'm not sure. You may have to bring this up to freebsd-net and ask if > there is something that will break by the change in behavior. As far > as I can tell, by reading the sys/netinet/udp_usrreq.c source, the > steps taken when udp_send() is called are: > > - If the socket has an attached inpcb it is passed to udp_output(). > > All UDP sockets have an inpcb attached to them, since they have > gone through udp_attach() at socket creation time. > > - In udp_output(), the part that makes sure packets cannot be sent > with a non-NULL destination address, after a socket has gone > through a connect() is: > > 791 if (addr) { > 792 sin = (struct sockaddr_in *)addr; > 793 if (td && jailed(td->td_ucred)) > 794 prison_remote_ip(td->td_ucred, 0, &sin->sin_addr.s_addr); > 795 if (inp->inp_faddr.s_addr != INADDR_ANY) { > 796 error = EISCONN; > 797 goto release; > 798 } > ... > > Lines 795-798 are the ones that enforce this. > > The TCP protocol does a similar check, but a bit earlier, since it > doesn't need to allow sending to multiple addresses for sockets that > are not connected (there aren't such TCP sockets anyway): > > 117 static int > 118 tcp_usr_attach(struct socket *so, int proto, struct thread *td) > 119 { > 120 int error; > 121 struct inpcb *inp; > 122 struct tcpcb *tp = 0; > 123 TCPDEBUG0; > 124 > 125 INP_INFO_WLOCK(&tcbinfo); > 126 TCPDEBUG1(); > 127 inp = sotoinpcb(so); > 128 if (inp) { > 129 error = EISCONN; > 130 goto out; > 131 } > > This is a bit early. I haven't checked the tcp_output.c source to see > what happens later on. I honestly have to admit that tcp_output() > still scares the hell out of me :-) > > >> to any number of addresses. After connect() is used to bind the > >> socket to a particular destination address it's not valid to > >> sendto() packets to any random address any more. > > > > Yes, target address has to be ignored from sendto() and the problem > > is that OS may or may not return an error. > > For connected SOCK_STREAM sockets no error is returned AFAICT. > The packet is just dropped. I tried it and it seems to me that TCP packet is sent to connected address, so TCP is SUSv3 compliant too, but just in the other way from UDP case, which I think is not very systematic. > Unconnected SOCK_STREAM sockets cannot send packets anyway (ENOTCONN). > > SOCK_DGRAM sockets need special documentation of their behavior :-) -- Rudolf Cejka http://www.fit.vutbr.cz/~cejkar Brno University of Technology, Faculty of Information Technology Bozetechova 2, 612 66 Brno, Czech Republic