• Vladislav Yasevich's avatar
    [SCTP]: A better solution to fix the race between sctp_peeloff() and · 61c9fed4
    Vladislav Yasevich authored
    sctp_rcv().
    
    The goal is to hold the ref on the association/endpoint throughout the
    state-machine process.  We accomplish like this:
    
      /* ref on the assoc/ep is taken during lookup */
    
      if owned_by_user(sk)
     	sctp_add_backlog(skb, sk);
      else
     	inqueue_push(skb, sk);
    
      /* drop the ref on the assoc/ep */
    
    However, in sctp_add_backlog() we take the ref on assoc/ep and hold it
    while the skb is on the backlog queue.  This allows us to get rid of the
    sock_hold/sock_put in the lookup routines.
    
    Now sctp_backlog_rcv() needs to account for potential association move.
    In the unlikely event that association moved, we need to retest if the
    new socket is locked by user.  If we don't this, we may have two packets
    racing up the stack toward the same socket and we can't deal with it.
    If the new socket is still locked, we'll just add the skb to its backlog
    continuing to hold the ref on the association.  This get's rid of the
    need to move packets from one backlog to another and it also safe in
    case new packets arrive on the same backlog queue.
    
    The last step, is to lock the new socket when we are moving the
    association to it.  This is needed in case any new packets arrive on
    the association when it moved.  We want these to go to the backlog since
    we would like to avoid the race between this new packet and a packet
    that may be sitting on the backlog queue of the old socket toward the
    same association.
    Signed-off-by: default avatarVladislav Yasevich <vladislav.yasevich@hp.com>
    Signed-off-by: default avatarSridhar Samudrala <sri@us.ibm.com>
    61c9fed4
input.c 25.5 KB