Author: tuexen
Date: Fri Feb 10 22:57:50 2012
New Revision: 231462
URL: http://svn.freebsd.org/changeset/base/231462

Log:
  MFC r225559:
  Ensure that 1-to-1 style SCTP sockets can only be connected once.
  Allow implicit setup also for 1-to-1 style sockets as described
  in the latest version of the socket API ID.

Modified:
  stable/8/sys/netinet/sctp_output.c
  stable/8/sys/netinet/sctp_pcb.c
  stable/8/sys/netinet/sctp_usrreq.c
  stable/8/sys/netinet/sctputil.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/boot/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/e1000/   (props changed)

Modified: stable/8/sys/netinet/sctp_output.c
==============================================================================
--- stable/8/sys/netinet/sctp_output.c  Fri Feb 10 22:55:22 2012        
(r231461)
+++ stable/8/sys/netinet/sctp_output.c  Fri Feb 10 22:57:50 2012        
(r231462)
@@ -12628,14 +12628,10 @@ sctp_lower_sosend(struct socket *so,
            (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
                SCTP_INP_RLOCK(inp);
                stcb = LIST_FIRST(&inp->sctp_asoc_list);
-               if (stcb == NULL) {
-                       SCTP_INP_RUNLOCK(inp);
-                       SCTP_LTRACE_ERR_RET(inp, stcb, net, 
SCTP_FROM_SCTP_OUTPUT, ENOTCONN);
-                       error = ENOTCONN;
-                       goto out_unlocked;
+               if (stcb) {
+                       SCTP_TCB_LOCK(stcb);
+                       hold_tcblock = 1;
                }
-               SCTP_TCB_LOCK(stcb);
-               hold_tcblock = 1;
                SCTP_INP_RUNLOCK(inp);
        } else if (sinfo_assoc_id) {
                stcb = sctp_findassociation_ep_asocid(inp, sinfo_assoc_id, 0);
@@ -12700,21 +12696,12 @@ sctp_lower_sosend(struct socket *so,
                }
        }
        if (stcb == NULL) {
-               if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
-                   (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
-                       SCTP_LTRACE_ERR_RET(inp, stcb, net, 
SCTP_FROM_SCTP_OUTPUT, ENOTCONN);
-                       error = ENOTCONN;
-                       goto out_unlocked;
-               }
                if (addr == NULL) {
                        SCTP_LTRACE_ERR_RET(inp, stcb, net, 
SCTP_FROM_SCTP_OUTPUT, ENOENT);
                        error = ENOENT;
                        goto out_unlocked;
                } else {
-                       /*
-                        * UDP style, we must go ahead and start the INIT
-                        * process
-                        */
+                       /* We must go ahead and start the INIT process */
                        uint32_t vrf_id;
 
                        if ((sinfo_flags & SCTP_ABORT) ||
@@ -12741,6 +12728,14 @@ sctp_lower_sosend(struct socket *so,
                                /* Error is setup for us in the call */
                                goto out_unlocked;
                        }
+                       if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) 
{
+                               stcb->sctp_ep->sctp_flags |= 
SCTP_PCB_FLAGS_CONNECTED;
+                               /*
+                                * Set the connected flag so we can queue
+                                * data
+                                */
+                               soisconnecting(so);
+                       }
                        hold_tcblock = 1;
                        if (create_lock_applied) {
                                SCTP_ASOC_CREATE_UNLOCK(inp);

Modified: stable/8/sys/netinet/sctp_pcb.c
==============================================================================
--- stable/8/sys/netinet/sctp_pcb.c     Fri Feb 10 22:55:22 2012        
(r231461)
+++ stable/8/sys/netinet/sctp_pcb.c     Fri Feb 10 22:57:50 2012        
(r231462)
@@ -4291,6 +4291,16 @@ sctp_aloc_assoc(struct sctp_inpcb *inp, 
                *error = EINVAL;
                return (NULL);
        }
+       if ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
+           (inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE)) {
+               if ((inp->sctp_flags & SCTP_PCB_FLAGS_WAS_CONNECTED) ||
+                   (inp->sctp_flags & SCTP_PCB_FLAGS_WAS_ABORTED)) {
+                       SCTP_INP_RUNLOCK(inp);
+                       SCTP_LTRACE_ERR_RET(inp, NULL, NULL, 
SCTP_FROM_SCTP_PCB, EINVAL);
+                       *error = EINVAL;
+                       return (NULL);
+               }
+       }
        SCTPDBG(SCTP_DEBUG_PCB3, "Allocate an association for peer:");
 #ifdef SCTP_DEBUG
        if (firstaddr) {

Modified: stable/8/sys/netinet/sctp_usrreq.c
==============================================================================
--- stable/8/sys/netinet/sctp_usrreq.c  Fri Feb 10 22:55:22 2012        
(r231461)
+++ stable/8/sys/netinet/sctp_usrreq.c  Fri Feb 10 22:57:50 2012        
(r231462)
@@ -1541,6 +1541,11 @@ sctp_do_connect_x(struct socket *so, str
                /* Gak! no memory */
                goto out_now;
        }
+       if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) {
+               stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED;
+               /* Set the connected flag so we can queue data */
+               soisconnecting(so);
+       }
        SCTP_SET_STATE(&stcb->asoc, SCTP_STATE_COOKIE_WAIT);
        /* move to second address */
        switch (sa->sa_family) {
@@ -5740,15 +5745,6 @@ sctp_connect(struct socket *so, struct s
        if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) {
                stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED;
                /* Set the connected flag so we can queue data */
-               SOCKBUF_LOCK(&so->so_rcv);
-               so->so_rcv.sb_state &= ~SBS_CANTRCVMORE;
-               SOCKBUF_UNLOCK(&so->so_rcv);
-               SOCKBUF_LOCK(&so->so_snd);
-               so->so_snd.sb_state &= ~SBS_CANTSENDMORE;
-               SOCKBUF_UNLOCK(&so->so_snd);
-               SOCK_LOCK(so);
-               so->so_state &= ~SS_ISDISCONNECTING;
-               SOCK_UNLOCK(so);
                soisconnecting(so);
        }
        SCTP_SET_STATE(&stcb->asoc, SCTP_STATE_COOKIE_WAIT);

Modified: stable/8/sys/netinet/sctputil.c
==============================================================================
--- stable/8/sys/netinet/sctputil.c     Fri Feb 10 22:55:22 2012        
(r231461)
+++ stable/8/sys/netinet/sctputil.c     Fri Feb 10 22:57:50 2012        
(r231462)
@@ -3622,10 +3622,14 @@ sctp_abort_notification(struct sctp_tcb 
 #endif
 )
 {
-
        if (stcb == NULL) {
                return;
        }
+       if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
+           ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
+           (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED))) {
+               stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_WAS_ABORTED;
+       }
        if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
            (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
            (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET)) {
@@ -3633,11 +3637,6 @@ sctp_abort_notification(struct sctp_tcb 
        }
        /* Tell them we lost the asoc */
        sctp_report_all_outbound(stcb, 1, so_locked);
-       if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
-           ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
-           (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED))) {
-               stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_WAS_ABORTED;
-       }
        sctp_ulp_notify(SCTP_NOTIFY_ASSOC_ABORTED, stcb, error, NULL, 
so_locked);
 }
 
@@ -5098,17 +5097,6 @@ restart_nosblocks:
                                         */
                                        SCTP_LTRACE_ERR_RET(inp, NULL, NULL, 
SCTP_FROM_SCTPUTIL, ECONNRESET);
                                        error = ECONNRESET;
-                                       /*
-                                        * You get this once if you are
-                                        * active open side
-                                        */
-                                       if (!(inp->sctp_flags & 
SCTP_PCB_FLAGS_IN_TCPPOOL)) {
-                                               /*
-                                                * Remove flag if on the
-                                                * active open side
-                                                */
-                                               inp->sctp_flags &= 
~SCTP_PCB_FLAGS_WAS_ABORTED;
-                                       }
                                }
                                so->so_state &= ~(SS_ISCONNECTING |
                                    SS_ISDISCONNECTING |
@@ -5118,8 +5106,6 @@ restart_nosblocks:
                                        if ((inp->sctp_flags & 
SCTP_PCB_FLAGS_WAS_CONNECTED) == 0) {
                                                SCTP_LTRACE_ERR_RET(inp, NULL, 
NULL, SCTP_FROM_SCTPUTIL, ENOTCONN);
                                                error = ENOTCONN;
-                                       } else {
-                                               inp->sctp_flags &= 
~SCTP_PCB_FLAGS_WAS_CONNECTED;
                                        }
                                }
                                goto out;
@@ -5152,18 +5138,6 @@ restart_nosblocks:
                                                 */
                                                SCTP_LTRACE_ERR_RET(inp, NULL, 
NULL, SCTP_FROM_SCTPUTIL, ECONNRESET);
                                                error = ECONNRESET;
-                                               /*
-                                                * You get this once if you
-                                                * are active open side
-                                                */
-                                               if (!(inp->sctp_flags & 
SCTP_PCB_FLAGS_IN_TCPPOOL)) {
-                                                       /*
-                                                        * Remove flag if on
-                                                        * the active open
-                                                        * side
-                                                        */
-                                                       inp->sctp_flags &= 
~SCTP_PCB_FLAGS_WAS_ABORTED;
-                                               }
                                        }
                                        so->so_state &= ~(SS_ISCONNECTING |
                                            SS_ISDISCONNECTING |
@@ -5173,8 +5147,6 @@ restart_nosblocks:
                                                if ((inp->sctp_flags & 
SCTP_PCB_FLAGS_WAS_CONNECTED) == 0) {
                                                        
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, ENOTCONN);
                                                        error = ENOTCONN;
-                                               } else {
-                                                       inp->sctp_flags &= 
~SCTP_PCB_FLAGS_WAS_CONNECTED;
                                                }
                                        }
                                        goto out;
_______________________________________________
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