Subject: Re: Passing assoc_id arround

From: "Xiaodan Tang" <[email-masked]>
Date: Tue, 15 Apr 2003 23:07:39 -0400

Hello Randall,

Thanks for the Patch.  For the Assoc_id thing, I understand that's a quick
hack.
After all, I agree there is no "easy & cheap" way to varify the pointer.

I applied your patch, retried the peeloff test, this still not work (faild
on second
pass with check sum error). I believe the problem is at sctp_uerreq.c code:

    case PRU_RCVD:
           if( so->so_rcv.sb_mb->m_flags & M_PKTHDR )
                       /* a full record
                        * was read if the first buf
                        * has a M_PKTHDR on the top.
                        */

             error = sctp_usr_recvd(so, MSG_EOR);
                } else

             error = sctp_usr_recvd(so, 0);
                }
             break;

First of all, you want to check so->so_rcv.sb_mb != NULL. Then, if
you check the soreceive() (where our sctp_usrreq() is called), I think
it moved the first MBUF off the so_rcv, and then called us. That means,
it is too late to check the mbuf with M_PKTHDR.

Also, if you check soreceive(), you can see it build up the flags according
to the information in mbuf it removed, and passed that flags into us as
our "nam" paramater...

I switched back to pass down the "nam" to sctp_usr_recvd(), and things
start to working...

I still have question about sctp_grub_through_socket_buffer(). In
another email you explained the code as:

> 1) It first checks that vtag_last... in case a partial read has been
>     done before the sctp_peeloff() was called... if so it pulls the top
chain
>    of mbufs...
>
> 2) After that check, it then goes through the entire chain looking for
>     matching vtags in the recv'd messages that are on queue.
>
> 3) After all are taken we do NOT want to touch vtag_last unless <1>
>     above was true.. i.e. the top of the mbuf chain contained one that was
>     moved.

In 1) we are checking "inp->sctp_vtag_last == asoc->my_vtag",
but in 3) we are checking "tcb->sctp_ep->sctp_vtag_last == asoc->my_vtag".
The "tcb->sctp_ep" is not the same "inp" in this case, it is the new
inp belongs to the new socket that created in sctp_get_peeloff().

So it looks to me it's wrong to repositon "tcb->sctp_ep->sctp_vtag_last".
Since it is the new socket, the "tcb->sctp_ep->sctp_vtag_last" should
just assigned with assoc->my_vtag (just in case, the user do another
sctp_peeloff() on the new peeled off socket)

As for inp->sctp_vtag_last, you want to reposition it to the mbufs still
left in oldsb->so_rcv. That's what I inteded to do in the code I sent
you last time.

It is arguable if one need to reposition on inp->sctp_vtag_last, cause
after some socket buffer moved to new socket, what left, should
always be a FULL packet (M_PKTHDR), where sctp_vtag_last
will be initialized if the user did another read on it.  If the user
do another peeloff() without any read, since the first packet
is a M_PKTHDR packet, we should be fine. We probably
just want to zero it, in cause after peeloff() there is no mbuf
left in old socket.

-xtang