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
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,
_______________________________________________
freebsd-net@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-unsubscr...@freebsd.org"

Reply via email to