-rcv_text(tp, t)
- register struct tcb *tp;
- register struct th *t;
-{
- register i;
- register struct th *p, *q;
- register struct mbuf *m, *n;
- struct th *savq;
- int last, j, k;
-COUNT(RCV_TEXT);
-
- /* throw away any data we have already received */
- if ((i = tp->rcv_nxt - t->t_seq) > 0) {
- if (i >= t->t_len)
- return;
- t->t_seq += i;
- t->t_len -= i;
- m_adj(dtom(t), i);
+ /*
+ * Process segments with URG.
+ */
+ if ((tiflags & TH_URG) && ti->ti_urp &&
+ 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
+ if ((tp->t_flags & TF_DOOOB) == 0)
+#endif
+ 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);
+ }