out-of-band fixed up
authorBill Joy <wnj@ucbvax.Berkeley.EDU>
Tue, 19 Jan 1982 11:44:00 +0000 (03:44 -0800)
committerBill Joy <wnj@ucbvax.Berkeley.EDU>
Tue, 19 Jan 1982 11:44:00 +0000 (03:44 -0800)
SCCS-vsn: sys/netinet/tcp.h 1.21
SCCS-vsn: sys/netinet/tcp_input.c 1.50
SCCS-vsn: sys/netinet/tcp_output.c 4.30
SCCS-vsn: sys/netinet/tcp_usrreq.c 1.49
SCCS-vsn: sys/netinet/tcp_var.h 4.16

usr/src/sys/netinet/tcp.h
usr/src/sys/netinet/tcp_input.c
usr/src/sys/netinet/tcp_output.c
usr/src/sys/netinet/tcp_usrreq.c
usr/src/sys/netinet/tcp_var.h

index f885d73..4432b03 100644 (file)
@@ -1,4 +1,4 @@
-/* tcp.h 1.20 82/01/17 */
+/* tcp.h 1.21 82/01/18 */
 
 typedef        u_long  tcp_seq;
 /*
 
 typedef        u_long  tcp_seq;
 /*
@@ -38,6 +38,6 @@ struct tcphdr {
  * exists; peer should ack with TCPOPT_OOBACK in segment.
  */
 #define        TCPOPT_WILLOOB  64              /* bytes: 64, 2 */
  * exists; peer should ack with TCPOPT_OOBACK in segment.
  */
 #define        TCPOPT_WILLOOB  64              /* bytes: 64, 2 */
-#define        TCPOPT_OOBDATA  65              /* bytes: 65, 4, seq#, data */
+#define        TCPOPT_OOBDATA  65              /* bytes: 65, 8, seq#, data, markseq */
 #define        TCPOPT_OOBACK   66              /* bytes: 66, 3, ack# */
 #endif
 #define        TCPOPT_OOBACK   66              /* bytes: 66, 3, ack# */
 #endif
index f209e18..f41558e 100644 (file)
@@ -1,4 +1,4 @@
-/*     tcp_input.c     1.49    82/01/17        */
+/*     tcp_input.c     1.50    82/01/18        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
@@ -531,29 +531,37 @@ printf("wl1 %x seq %x wl2 %x ack %x win %x wnd %x\n", tp->snd_wl1, ti->ti_seq, t
        }
 
        /*
        }
 
        /*
-        * If an URG bit is set and in the segment and is greater than the
-        * current known urgent pointer, then mark the data stream.
-        * If the TCP is not doing out-of-band data, then indicate
-        * urgent to the user.  This should not happen
-        * in CLOSE_WAIT, CLOSING, LAST-ACK or TIME_WAIT STATES since
-        * a FIN has been received from the remote side.  In these states
-        * we ignore the URG.
-        */
-       if ((tiflags & TH_URG) && TCPS_HAVERCVDFIN(tp->t_state) == 0 &&
-           SEQ_GT(ti->ti_seq+ti->ti_urp, tp->rcv_up)) {
-               tp->rcv_up = ti->ti_seq + ti->ti_urp;
-               so->so_oobmark = so->so_rcv.sb_cc +
-                   (tp->rcv_up - tp->rcv_nxt) - 1;
-               if (so->so_oobmark == 0)
-                       so->so_state |= SS_RCVATMARK;
+        * Process segments with URG.
+        */
+       if ((tiflags & TH_URG) && TCPS_HAVERCVDFIN(tp->t_state) == 0) {
+               /*
+                * If this segment advances the known urgent pointer,
+                * then mark the data stream.  This should not happen
+                * in CLOSE_WAIT, CLOSING, LAST_ACK or TIME_WAIT STATES since
+                * a FIN has been received from the remote side. 
+                * In these states we ignore the URG.
+                */
+               if (SEQ_GT(ti->ti_seq+ti->ti_urp, tp->rcv_up)) {
+                       tp->rcv_up = ti->ti_seq + ti->ti_urp;
+                       so->so_oobmark = so->so_rcv.sb_cc +
+                           (tp->rcv_up - tp->rcv_nxt) - 1;
+                       if (so->so_oobmark == 0)
+                               so->so_state |= SS_RCVATMARK;
 #ifdef TCPTRUEOOB
 #ifdef TCPTRUEOOB
-               if ((tp->t_flags & TF_DOOOB) == 0)
+                       if ((tp->t_flags & TF_DOOOB) == 0)
 #endif
 #endif
-               {
-                       sohasoutofband(so);
-                       tp->t_oobflags |= TCPOOB_HAVEDATA;
+                               sohasoutofband(so);
+                       tp->t_oobflags &= ~TCPOOB_HAVEDATA;
+               }
+               /*
+                * Remove out of band data so doesn't get presented to user.
+                * This can happen independent of advancing the URG pointer,
+                * but if two URG's are pending at once, some out-of-band
+                * data may creep in... ick.
+                */
+               if (ti->ti_urp <= ti->ti_len) {
+                       tcp_pulloutofband(so, ti);
                }
                }
-
        }
 
        /*
        }
 
        /*
@@ -712,8 +720,10 @@ printf("tp %x dooob\n", tp);
 
                case TCPOPT_OOBDATA: {
                        int seq;
 
                case TCPOPT_OOBDATA: {
                        int seq;
+                       register struct socket *so = tp->t_inpcb->inp_socket;
+                       tcp_seq mark;
 
 
-                       if (optlen != 4)
+                       if (optlen != 8)
                                continue;
                        seq = cp[2];
                        if (seq < tp->t_iobseq)
                                continue;
                        seq = cp[2];
                        if (seq < tp->t_iobseq)
@@ -726,8 +736,15 @@ printf("bad seq\n");
                        }
                        tp->t_iobseq = cp[2];
                        tp->t_iobc = cp[3];
                        }
                        tp->t_iobseq = cp[2];
                        tp->t_iobc = cp[3];
+                       mark = *(tcp_seq *)(cp + 4);
+#if vax
+                       mark = ntohl(mark);
+#endif
+                       so->so_oobmark = so->so_rcv.sb_cc + (mark-tp->rcv_nxt);
+                       if (so->so_oobmark == 0)
+                               so->so_state |= SS_RCVATMARK;
 printf("take oob data %x input iobseq now %x\n", tp->t_iobc, tp->t_iobseq);
 printf("take oob data %x input iobseq now %x\n", tp->t_iobc, tp->t_iobseq);
-                       sohasoutofband(tp->t_inpcb->inp_socket);
+                       sohasoutofband(so);
                        break;
                }
 
                        break;
                }
 
@@ -751,6 +768,39 @@ printf("take oob ack %x and cancel rexmt\n", cp[2]);
        m_free(om);
 }
 
        m_free(om);
 }
 
+/*
+ * Pull out of band byte out of a segment so
+ * it doesn't appear in the user's data queue.
+ * It is still reflected in the segment length for
+ * sequencing purposes.
+ */
+tcp_pulloutofband(so, ti)
+       struct socket *so;
+       struct tcpiphdr *ti;
+{
+       register struct mbuf *m;
+       int cnt = sizeof (struct tcpiphdr) + ti->ti_urp - 1;
+       
+       m = dtom(ti);
+       while (cnt >= 0) {
+               if (m->m_len > cnt) {
+                       char *cp = mtod(m, caddr_t) + cnt;
+                       struct tcpcb *tp = sototcpcb(so);
+
+                       tp->t_iobc = *cp;
+                       tp->t_oobflags |= TCPOOB_HAVEDATA;
+                       bcopy(cp+1, cp, m->m_len - cnt - 1);
+                       m->m_len--;
+                       return;
+               }
+               cnt -= m->m_len;
+               m = m->m_next;
+               if (m == 0)
+                       break;
+       }
+       panic("tcp_pulloutofband");
+}
+
 /*
  * Insert segment ti into reassembly queue of tcp with
  * control block tp.  Return TH_FIN if reassembly now includes
 /*
  * Insert segment ti into reassembly queue of tcp with
  * control block tp.  Return TH_FIN if reassembly now includes
index 30041f6..2e6573e 100644 (file)
@@ -1,4 +1,4 @@
-/*     tcp_output.c    4.29    82/01/17        */
+/*     tcp_output.c    4.30    82/01/18        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
@@ -182,10 +182,14 @@ printf("tp %x send OOBACK for %x\n", tp->t_iobseq);
                if (tp->t_oobflags&TCPOOB_NEEDACK) {
 printf("tp %x send OOBDATA seq %x data %x\n", tp->t_oobseq, tp->t_oobc);
                        *opt++ = TCPOPT_OOBDATA;
                if (tp->t_oobflags&TCPOOB_NEEDACK) {
 printf("tp %x send OOBDATA seq %x data %x\n", tp->t_oobseq, tp->t_oobc);
                        *opt++ = TCPOPT_OOBDATA;
-                       *opt++ = 4;
+                       *opt++ = 8;
                        *opt++ = tp->t_oobseq;
                        *opt++ = tp->t_oobc;
                        *opt++ = tp->t_oobseq;
                        *opt++ = tp->t_oobc;
-                       m0->m_len += 4;
+                       *(tcp_seq *)opt = tp->t_oobmark - tp->snd_nxt;
+#ifdef vax
+                       *(tcp_seq *)opt = htonl((unsigned)*(tcp_seq *)opt);
+#endif
+                       m0->m_len += 8;
                        TCPT_RANGESET(tp->t_timer[TCPT_OOBREXMT],
                            tcp_beta * tp->t_srtt, TCPTV_MIN, TCPTV_MAX);
                }
                        TCPT_RANGESET(tp->t_timer[TCPT_OOBREXMT],
                            tcp_beta * tp->t_srtt, TCPTV_MIN, TCPTV_MAX);
                }
index 05c5a58..7983ae0 100644 (file)
@@ -1,4 +1,4 @@
-/* tcp_usrreq.c 1.48 82/01/17 */
+/* tcp_usrreq.c 1.49 82/01/18 */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
@@ -204,38 +204,29 @@ COUNT(TCP_USRREQ);
 /* END UNIMPLEMENTED HOOKS */
 
        case PRU_RCVOOB:
 /* END UNIMPLEMENTED HOOKS */
 
        case PRU_RCVOOB:
-#if TCPTRUEOOB
-               if (tp->t_flags & TF_DOOOB) {
-                       if ((tp->t_oobflags & TCPOOB_HAVEDATA) == 0) {
-                               error = EWOULDBLOCK;
-                               break;
-                       }
-                       *mtod(m, caddr_t) = tp->t_iobc;
-                       tp->t_oobflags &= ~TCPOOB_HAVEDATA;
-                       break;
-               }
-#endif
                if (so->so_oobmark == 0 &&
                    (so->so_state & SS_RCVATMARK) == 0) {
                        error = EINVAL;
                        break;
                }
                if (so->so_oobmark == 0 &&
                    (so->so_state & SS_RCVATMARK) == 0) {
                        error = EINVAL;
                        break;
                }
-               if (so->so_rcv.sb_cc < so->so_oobmark) {
+               if ((tp->t_oobflags & TCPOOB_HAVEDATA) == 0) {
                        error = EWOULDBLOCK;
                        error = EWOULDBLOCK;
-                       return;
-               }
-               { struct mbuf *n = so->so_rcv.sb_mb;
-                 int cnt = so->so_oobmark;
-                 while (cnt > n->m_len) {
-                       cnt -= n->m_len;
-                       n = n->m_next;
-                 }
-                 *mtod(m, caddr_t) = *(mtod(n, caddr_t) + cnt);
+                       break;
                }
                }
-               tp->t_oobflags &= ~TCPOOB_HAVEDATA;
+               *mtod(m, caddr_t) = tp->t_iobc;
                break;
 
        case PRU_SENDOOB:
                break;
 
        case PRU_SENDOOB:
+#ifdef TCPTRUEOOB
+               if (tp->t_flags & TF_DOOOB) {
+                       tp->t_oobseq++;
+                       tp->t_oobc = *mtod(m, caddr_t);
+                       tp->t_oobmark = tp->snd_una + so->so_snd.sb_cc;
+printf("sendoob seq now %x oobc %x\n", tp->t_oobseq, tp->t_oobc);
+                       tp->t_oobflags |= TCPOOB_NEEDACK;
+                       (void) tcp_output(tp);
+               }
+#endif
                if (sbspace(&so->so_snd) < -512) {
                        error = ENOBUFS;
                        break;
                if (sbspace(&so->so_snd) < -512) {
                        error = ENOBUFS;
                        break;
@@ -246,15 +237,9 @@ COUNT(TCP_USRREQ);
                if (tp->t_flags & TF_PUSH)
                        tp->snd_end = tp->snd_una + so->so_snd.sb_cc;
  */
                if (tp->t_flags & TF_PUSH)
                        tp->snd_end = tp->snd_una + so->so_snd.sb_cc;
  */
-#ifdef TCPTRUEOOB
-               if (tp->t_flags & TF_DOOOB) {
-                       tp->t_oobseq++;
-                       tp->t_oobc = *mtod(m, caddr_t);
-printf("sendoob seq now %x oobc %x\n", tp->t_oobseq, tp->t_oobc);
-                       tp->t_oobflags |= TCPOOB_NEEDACK;
-               }
-#endif
-               tp->t_force = 1; (void) tcp_output(tp); tp->t_force = 0;
+               tp->t_force = 1;
+               (void) tcp_output(tp);
+               tp->t_force = 0;
                break;
 
        /*
                break;
 
        /*
index ba523c3..ca27a98 100644 (file)
@@ -1,4 +1,4 @@
-/*     tcp_var.h       4.15    82/01/17        */
+/*     tcp_var.h       4.16    82/01/18        */
 
 /*
  * Kernel variables for tcp.
 
 /*
  * Kernel variables for tcp.
@@ -59,13 +59,14 @@ struct tcpcb {
        float   t_srtt;                 /* smoothed round-trip time */
 /* out-of-band data */
        char    t_oobflags;             /* have some */
        float   t_srtt;                 /* smoothed round-trip time */
 /* out-of-band data */
        char    t_oobflags;             /* have some */
+       char    t_iobc;                 /* input character */
 #define        TCPOOB_HAVEDATA 0x01
 
 #ifdef TCPTRUEOOB
 #define        TCPOOB_OWEACK   0x02
 #define        TCPOOB_NEEDACK  0x04
 #define        TCPOOB_HAVEDATA 0x01
 
 #ifdef TCPTRUEOOB
 #define        TCPOOB_OWEACK   0x02
 #define        TCPOOB_NEEDACK  0x04
-       char    t_iobc;                 /* input character */
        u_char  t_iobseq;               /* input receive sequence number */
        u_char  t_iobseq;               /* input receive sequence number */
+       tcp_seq t_oobmark;              /* output mark position */
        char    t_oobc;                 /* output character */
        u_char  t_oobseq;               /* output transmit sequence number */
 #endif
        char    t_oobc;                 /* output character */
        u_char  t_oobseq;               /* output transmit sequence number */
 #endif