Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 02 Apr 2015 12:26:16 +0200
From:      Sebastian Huber <sebastian.huber@embedded-brains.de>
To:        freebsd-hackers@freebsd.org
Subject:   A tcp_do_segment() question
Message-ID:  <551D1948.3090805@embedded-brains.de>

next in thread | raw e-mail | index | archive | help
Hello,

I do currently some tests with a port of the FreeBSD 9.3 network stack=20
to the RTEMS real-time operating system. I do an FTP transfer from my=20
development machine to the target (curl -T /dev/zero=20
ftp://anonymous@192.168.96.157/dev/null). So this is a one-sided TCP=20
transfer.

In tcp_do_segment() there is one path as explained here:

     /*
      * Header prediction: check for the two common cases
      * of a uni-directional data xfer.  If the packet has
      * no control flags, is in-sequence, the window didn't
      * change and we're not retransmitting, it's a
      * candidate.  If the length is zero and the ack moved
      * forward, we're the sender side of the xfer.  Just
      * free the data acked & wake any higher level process
      * that was blocked waiting for space.  If the length
      * is non-zero and the ack didn't move, we're the
      * receiver side.  If we're getting packets in-order
      * (the reassembly queue is empty), add the data to
      * the socket buffer and note that we need a delayed ack.
      * Make sure that the hidden state-flags are also off.
      * Since we check for TCPS_ESTABLISHED first, it can only
      * be TH_NEEDSYN.
      */
     if (tp->t_state =3D=3D TCPS_ESTABLISHED &&
         th->th_seq =3D=3D tp->rcv_nxt &&
         (thflags & (TH_SYN|TH_FIN|TH_RST|TH_URG|TH_ACK)) =3D=3D TH_ACK &=
&
         tp->snd_nxt =3D=3D tp->snd_max &&
         tiwin && tiwin =3D=3D tp->snd_wnd &&
         ((tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN)) =3D=3D 0) &&
         LIST_EMPTY(&tp->t_segq) &&
         ((to.to_flags & TOF_TS) =3D=3D 0 ||
          TSTMP_GEQ(to.to_tsval, tp->ts_recent)) ) {

It seems that after some initial setup phase I end up always in this=20
branch. The problem is now that the retransmit timer is ticking (TT_REXMT=
).

In this branch there are three alternatives:

1. if (tlen =3D=3D 0) {

Since I transfer to the target, tlen !=3D 0.

2.         } else if (th->th_ack =3D=3D tp->snd_una &&
             tlen <=3D sbspace(&so->so_rcv)) {

It seems I always end up here.

3. Otherwise.

In the (1) alternative we end up in:

                 if (tp->snd_una =3D=3D tp->snd_max)
                     tcp_timer_activate(tp, TT_REXMT, 0);
                 else if (!tcp_timer_active(tp, TT_PERSIST))
                     tcp_timer_activate(tp, TT_REXMT,
                               tp->t_rxtcur);
                 sowwakeup(so);
                 if (so->so_snd.sb_cc)
                     (void) tcp_output(tp);
                 goto check_delack;

So here we reset the retransmit timer if possible.

In the (2) alternative we don't reset the retransmit timer! All my=20
connections stop after approx. 2:30min via tcp_timer_rexmt(). If I apply=20
the following hack

@@ -1852,6 +1866,13 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th,=20
struct socket *so,
                         }
                         /* NB: sorwakeup_locked() does an implicit=20
unlock. */
                         sorwakeup_locked(so);
+
+                       if (tp->snd_una =3D=3D tp->snd_max)
+                               tcp_timer_activate(tp, TT_REXMT, 0);
+                       else if (!tcp_timer_active(tp, TT_PERSIST))
+                               tcp_timer_activate(tp, TT_REXMT,
+                                             tp->t_rxtcur);
+
                         if (DELAY_ACK(tp)) {
                                 tp->t_flags |=3D TF_DELACK;
                         } else {

in the (2) alternative, then I can transfer for hours.

Does anyone know why the retransmit timer is not reset in the (2)=20
alternative?

--=20
Sebastian Huber, embedded brains GmbH

Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone   : +49 89 189 47 41-16
Fax     : +49 89 189 47 41-09
E-Mail  : sebastian.huber@embedded-brains.de
PGP     : Public key available on request.

Diese Nachricht ist keine gesch=C3=A4ftliche Mitteilung im Sinne des EHUG=
.




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?551D1948.3090805>