Date: Sun, 29 Aug 2010 17:22:13 +0200 From: Andre Oppermann <andre@freebsd.org> To: freebsd-net@freebsd.org Subject: Removal of deprecated implied connect for TCP Message-ID: <4C7A7B25.9040300@freebsd.org>
next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format. --------------030501000301080006010502 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit When T/TCP RFC1644 support was introduced in r6283 by wollman 15 years ago the semantics of sendto(2) with regard to TCP sockets were changed. It became possible directly do a sendto(2) call with the target address in the *to argument instead of doing a connect(2) first and subsequent write(2) or send(2) calls as the standard TCP API specifies. Optionally MSG_EOR could be specified to close the connection again right again after the data has been sent out. This is totally non-portable and no other OS (Linux, NetBSD, OpenBSD, Solaris, HP-UX) ever supported this functionality for TCP sockets. FreeBSD was the only OS to ever ship this. T/TCP was ill-defined and had major security issues and never gained any support. It has been defunct in FreeBSD and most code has been removed about 6 years ago. The sendto(2) extended functionality is one of the last parts that persisted and remained around living a zombie life. I want to remove it now because it is totally non-portable, has no known users and complicates the TCP send path. The patch is attached. If you have any objections speak up now. -- Andre --------------030501000301080006010502 Content-Type: text/plain; name="tcp_usrreq-implied-connect.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="tcp_usrreq-implied-connect.diff" Index: netinet/tcp_usrreq.c =================================================================== --- netinet/tcp_usrreq.c (revision 211874) +++ netinet/tcp_usrreq.c (working copy) @@ -740,86 +740,34 @@ int error = 0; struct inpcb *inp; struct tcpcb *tp = NULL; - int headlocked = 0; -#ifdef INET6 - int isipv6; -#endif + TCPDEBUG0; - /* - * We require the pcbinfo lock in two cases: - * - * (1) An implied connect is taking place, which can result in - * binding IPs and ports and hence modification of the pcb hash - * chains. - * - * (2) PRUS_EOF is set, resulting in explicit close on the send. - */ - if ((nam != NULL) || (flags & PRUS_EOF)) { - INP_INFO_WLOCK(&V_tcbinfo); - headlocked = 1; + /* TCP doesn't do control messages (rights, creds, etc.) */ + if (control != NULL && control->m_len) { + error = EINVAL; + goto out; } + inp = sotoinpcb(so); - KASSERT(inp != NULL, ("tcp_usr_send: inp == NULL")); + KASSERT(inp != NULL, ("%s: inp == NULL", __func__)); INP_WLOCK(inp); - if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) { - if (control) - m_freem(control); - if (m) - m_freem(m); + if (inp->inp_flags & (INP_DROPPED | INP_TIMEWAIT)) { error = ECONNRESET; - goto out; + goto done; } -#ifdef INET6 - isipv6 = nam && nam->sa_family == AF_INET6; -#endif /* INET6 */ tp = intotcpcb(inp); + TCPDEBUG1(); - if (control) { - /* TCP doesn't do control messages (rights, creds, etc) */ - if (control->m_len) { - m_freem(control); - if (m) - m_freem(m); - error = EINVAL; - goto out; - } - m_freem(control); /* empty control, just free it */ - } + + /* + * Append the new data to the send socket buffer and + * try to send it (may be limited by CWND). + */ if (!(flags & PRUS_OOB)) { sbappendstream(&so->so_snd, m); - if (nam && tp->t_state < TCPS_SYN_SENT) { - /* - * Do implied connect if not yet connected, - * initialize window to default value, and - * initialize maxseg/maxopd using peer's cached - * MSS. - */ - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); -#ifdef INET6 - if (isipv6) - error = tcp6_connect(tp, nam, td); - else -#endif /* INET6 */ - error = tcp_connect(tp, nam, td); - if (error) - goto out; - tp->snd_wnd = TTCP_CLIENT_SND_WND; - tcp_mss(tp, -1); - } - if (flags & PRUS_EOF) { - /* - * Close the send side of the connection after - * the data is sent. - */ - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); - socantsendmore(so); - tcp_usrclosed(tp); - } - if (headlocked) { - INP_INFO_WUNLOCK(&V_tcbinfo); - headlocked = 0; - } + m = NULL; + if (!(inp->inp_flags & INP_DROPPED)) { if (flags & PRUS_MORETOCOME) tp->t_flags |= TF_MORETOCOME; @@ -828,15 +776,11 @@ tp->t_flags &= ~TF_MORETOCOME; } } else { - /* - * XXXRW: PRUS_EOF not implemented with PRUS_OOB? - */ SOCKBUF_LOCK(&so->so_snd); if (sbspace(&so->so_snd) < -512) { SOCKBUF_UNLOCK(&so->so_snd); - m_freem(m); error = ENOBUFS; - goto out; + goto done; } /* * According to RFC961 (Assigned Protocols), @@ -847,42 +791,24 @@ * Otherwise, snd_up should be one lower. */ sbappendstream_locked(&so->so_snd, m); + m = NULL; SOCKBUF_UNLOCK(&so->so_snd); - if (nam && tp->t_state < TCPS_SYN_SENT) { - /* - * Do implied connect if not yet connected, - * initialize window to default value, and - * initialize maxseg/maxopd using peer's cached - * MSS. - */ - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); -#ifdef INET6 - if (isipv6) - error = tcp6_connect(tp, nam, td); - else -#endif /* INET6 */ - error = tcp_connect(tp, nam, td); - if (error) - goto out; - tp->snd_wnd = TTCP_CLIENT_SND_WND; - tcp_mss(tp, -1); - INP_INFO_WUNLOCK(&V_tcbinfo); - headlocked = 0; - } else if (nam) { - INP_INFO_WUNLOCK(&V_tcbinfo); - headlocked = 0; - } + tp->snd_up = tp->snd_una + so->so_snd.sb_cc; tp->t_flags |= TF_FORCEDATA; error = tcp_output_send(tp); tp->t_flags &= ~TF_FORCEDATA; } -out: - TCPDEBUG2((flags & PRUS_OOB) ? PRU_SENDOOB : - ((flags & PRUS_EOF) ? PRU_SEND_EOF : PRU_SEND)); + TCPDEBUG2((flags & PRUS_OOB) ? PRU_SENDOOB : PRU_SEND); +done: INP_WUNLOCK(inp); - if (headlocked) - INP_INFO_WUNLOCK(&V_tcbinfo); +out: + /* Free mbufs in error cases. */ + if (m != NULL) + m_freem(m); + if (control != NULL) + m_freem(control); + return (error); } Index: netinet/in_proto.c =================================================================== --- netinet/in_proto.c (revision 211874) +++ netinet/in_proto.c (working copy) @@ -134,7 +134,7 @@ .pr_type = SOCK_STREAM, .pr_domain = &inetdomain, .pr_protocol = IPPROTO_TCP, - .pr_flags = PR_CONNREQUIRED|PR_IMPLOPCL|PR_WANTRCVD, + .pr_flags = PR_CONNREQUIRED|PR_WANTRCVD, .pr_input = tcp_input, .pr_ctlinput = tcp_ctlinput, .pr_ctloutput = tcp_ctloutput, --------------030501000301080006010502--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4C7A7B25.9040300>