Author: tuexen
Date: Fri May 29 13:18:10 2015
New Revision: 283732
URL: https://svnweb.freebsd.org/changeset/base/283732

Log:
  MFC r280459:
  
  Fix two bugs which resulted in a screwed up end point list:
  * Use a save way to walk throught a list while manipulting it.
  * Have to appropiate locks in place.
  Joint work with rrs@

Modified:
  stable/10/sys/netinet/sctp_pcb.c
  stable/10/sys/netinet/sctp_usrreq.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/netinet/sctp_pcb.c
==============================================================================
--- stable/10/sys/netinet/sctp_pcb.c    Fri May 29 13:13:12 2015        
(r283731)
+++ stable/10/sys/netinet/sctp_pcb.c    Fri May 29 13:18:10 2015        
(r283732)
@@ -1867,7 +1867,7 @@ sctp_swap_inpcb_for_listen(struct sctp_i
 {
        /* For 1-2-1 with port reuse */
        struct sctppcbhead *head;
-       struct sctp_inpcb *tinp;
+       struct sctp_inpcb *tinp, *ninp;
 
        if (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_PORTREUSE)) {
                /* only works with port reuse on */
@@ -1877,10 +1877,11 @@ sctp_swap_inpcb_for_listen(struct sctp_i
                return (0);
        }
        SCTP_INP_RUNLOCK(inp);
+       SCTP_INP_INFO_WLOCK();
        head = 
&SCTP_BASE_INFO(sctp_ephash)[SCTP_PCBHASH_ALLADDR(inp->sctp_lport,
            SCTP_BASE_INFO(hashmark))];
        /* Kick out all non-listeners to the TCP hash */
-       LIST_FOREACH(tinp, head, sctp_hash) {
+       LIST_FOREACH_SAFE(tinp, head, sctp_hash, ninp) {
                if (tinp->sctp_lport != inp->sctp_lport) {
                        continue;
                }
@@ -1908,6 +1909,7 @@ sctp_swap_inpcb_for_listen(struct sctp_i
        LIST_INSERT_HEAD(head, inp, sctp_hash);
        SCTP_INP_WUNLOCK(inp);
        SCTP_INP_RLOCK(inp);
+       SCTP_INP_INFO_WUNLOCK();
        return (0);
 }
 

Modified: stable/10/sys/netinet/sctp_usrreq.c
==============================================================================
--- stable/10/sys/netinet/sctp_usrreq.c Fri May 29 13:13:12 2015        
(r283731)
+++ stable/10/sys/netinet/sctp_usrreq.c Fri May 29 13:18:10 2015        
(r283732)
@@ -6965,8 +6965,8 @@ sctp_listen(struct socket *so, int backl
 #endif
        SOCK_LOCK(so);
        error = solisten_proto_check(so);
+       SOCK_UNLOCK(so);
        if (error) {
-               SOCK_UNLOCK(so);
                SCTP_INP_RUNLOCK(inp);
                return (error);
        }
@@ -6979,28 +6979,27 @@ sctp_listen(struct socket *so, int backl
                 * move the guy that was listener to the TCP Pool.
                 */
                if (sctp_swap_inpcb_for_listen(inp)) {
-                       goto in_use;
+                       SCTP_INP_RUNLOCK(inp);
+                       SCTP_LTRACE_ERR_RET(inp, NULL, NULL, 
SCTP_FROM_SCTP_USRREQ, EADDRINUSE);
+                       return (EADDRINUSE);
                }
        }
        if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
            (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) {
                /* We are already connected AND the TCP model */
-in_use:
                SCTP_INP_RUNLOCK(inp);
-               SOCK_UNLOCK(so);
                SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, 
EADDRINUSE);
                return (EADDRINUSE);
        }
        SCTP_INP_RUNLOCK(inp);
        if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) {
                /* We must do a bind. */
-               SOCK_UNLOCK(so);
                if ((error = sctp_inpcb_bind(so, NULL, NULL, p))) {
                        /* bind error, probably perm */
                        return (error);
                }
-               SOCK_LOCK(so);
        }
+       SOCK_LOCK(so);
        /* It appears for 7.0 and on, we must always call this. */
        solisten_proto(so, backlog);
        if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) {
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to