The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netinet/sctp_peeloff.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $KAME: sctp_peeloff.c,v 1.12 2004/08/17 04:06:19 itojun Exp $   */
    2 /*      $DragonFly: src/sys/netinet/sctp_peeloff.c,v 1.5 2006/12/22 23:57:52 swildner Exp $     */
    3 
    4 /*
    5  * Copyright (C) 2002, 2003 Cisco Systems Inc,
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. Neither the name of the project nor the names of its contributors
   17  *    may be used to endorse or promote products derived from this software
   18  *    without specific prior written permission.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
   21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
   24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   30  * SUCH DAMAGE.
   31  */
   32 #if !(defined(__OpenBSD__) || defined(__APPLE__))
   33 #include "opt_ipsec.h"
   34 #endif
   35 #if defined(__FreeBSD__) || defined(__DragonFly__)
   36 #include "opt_inet6.h"
   37 #include "opt_inet.h"
   38 #endif
   39 #if defined(__NetBSD__)
   40 #include "opt_inet.h"
   41 #endif
   42 
   43 #ifdef __APPLE__
   44 #include <sctp.h>
   45 #elif !defined(__OpenBSD__)
   46 #include "opt_sctp.h"
   47 #endif
   48 
   49 #include <sys/param.h>
   50 #include <sys/systm.h>
   51 #include <sys/kernel.h>
   52 #include <sys/malloc.h>
   53 #include <sys/mbuf.h>
   54 #include <sys/domain.h>
   55 #include <sys/proc.h>
   56 #include <sys/protosw.h>
   57 #include <sys/socket.h>
   58 #include <sys/socketvar.h>
   59 #include <sys/socketvar2.h>
   60 #include <sys/sysctl.h>
   61 #include <sys/syslog.h>
   62 #include <net/if.h>
   63 #include <net/route.h>
   64 #include <netinet/in.h>
   65 #include <netinet/in_systm.h>
   66 #include <netinet/ip.h>
   67 #ifdef INET6
   68 #include <netinet/ip6.h>
   69 #endif
   70 #include <netinet/in_pcb.h>
   71 #include <netinet/in_var.h>
   72 #include <netinet/ip_var.h>
   73 #ifdef INET6
   74 #include <netinet6/ip6_var.h>
   75 #endif
   76 #include <netinet/ip_icmp.h>
   77 #include <netinet/icmp_var.h>
   78 #include <netinet/sctp_pcb.h>
   79 #include <netinet/sctp.h>
   80 #include <netinet/sctp_uio.h>
   81 #include <netinet/sctp_var.h>
   82 #include <netinet/sctp_peeloff.h>
   83 #include <netinet/sctputil.h>
   84 
   85 #ifdef IPSEC
   86 #ifndef __OpenBSD__
   87 #include <netinet6/ipsec.h>
   88 #include <netproto/key/key.h>
   89 #else
   90 #undef IPSEC
   91 #endif
   92 #endif /*IPSEC*/
   93 
   94 #ifdef SCTP_DEBUG
   95 extern u_int32_t sctp_debug_on;
   96 #endif /* SCTP_DEBUG */
   97 
   98 
   99 int
  100 sctp_can_peel_off(struct socket *head, caddr_t assoc_id)
  101 {
  102         struct sctp_inpcb *inp;
  103         struct sctp_tcb *stcb;
  104         inp = (struct sctp_inpcb *)head->so_pcb;
  105         if (inp == NULL) {
  106                 return (EFAULT);
  107         }
  108         stcb = sctp_findassociation_ep_asocid(inp, assoc_id);
  109         if (stcb == NULL) {
  110                 return (ENOTCONN);
  111         }
  112         /* We are clear to peel this one off */
  113         return (0);
  114 }
  115 
  116 int
  117 sctp_do_peeloff(struct socket *head, struct socket *so, caddr_t assoc_id)
  118 {
  119         struct sctp_inpcb *inp, *n_inp;
  120         struct sctp_tcb *stcb;
  121 
  122         inp = (struct sctp_inpcb *)head->so_pcb;
  123         if (inp == NULL)
  124                 return (EFAULT);
  125         stcb = sctp_findassociation_ep_asocid(inp, assoc_id);
  126         if (stcb == NULL)
  127                 return (ENOTCONN);
  128 
  129         n_inp = (struct sctp_inpcb *)so->so_pcb;
  130         n_inp->sctp_flags = (SCTP_PCB_FLAGS_UDPTYPE |
  131             SCTP_PCB_FLAGS_CONNECTED |
  132             SCTP_PCB_FLAGS_IN_TCPPOOL | /* Turn on Blocking IO */
  133             (SCTP_PCB_COPY_FLAGS & inp->sctp_flags));
  134         n_inp->sctp_socket = so;
  135 
  136         /*
  137          * Now we must move it from one hash table to another and get
  138          * the stcb in the right place.
  139          */
  140         sctp_move_pcb_and_assoc(inp, n_inp, stcb);
  141         /*
  142          * And now the final hack. We move data in the
  143          * pending side i.e. head to the new socket
  144          * buffer. Let the GRUBBING begin :-0
  145          */
  146         sctp_grub_through_socket_buffer(inp, head, so, stcb);
  147         return (0);
  148 }
  149 
  150 struct socket *
  151 sctp_get_peeloff(struct socket *head, caddr_t assoc_id, int *error)
  152 {
  153         struct socket *newso;
  154         struct sctp_inpcb *inp, *n_inp;
  155         struct sctp_tcb *stcb;
  156 
  157 #ifdef SCTP_DEBUG
  158         if (sctp_debug_on & SCTP_DEBUG_PEEL1) {
  159                 kprintf("SCTP peel-off called\n");
  160         }
  161 #endif /* SCTP_DEBUG */
  162 
  163         inp = (struct sctp_inpcb *)head->so_pcb;
  164         if (inp == NULL) {
  165                 *error = EFAULT;
  166                 return (NULL);
  167         }
  168         stcb = sctp_findassociation_ep_asocid(inp, assoc_id);
  169         if (stcb == NULL) {
  170                 *error = ENOTCONN;
  171                 return (NULL);
  172         }
  173         newso = sonewconn(head, SS_ISCONNECTED);
  174         if (newso == NULL) {
  175 #ifdef SCTP_DEBUG
  176                 if (sctp_debug_on & SCTP_DEBUG_PEEL1) {
  177                         kprintf("sctp_peeloff:sonewconn failed err\n");
  178                 }
  179 #endif /* SCTP_DEBUG */
  180                 *error = ENOMEM;
  181                 SCTP_TCB_UNLOCK(stcb);
  182                 return (NULL);
  183         }
  184         n_inp = (struct sctp_inpcb *)newso->so_pcb;
  185         SCTP_INP_WLOCK(n_inp);
  186         n_inp->sctp_flags = (SCTP_PCB_FLAGS_UDPTYPE |
  187             SCTP_PCB_FLAGS_CONNECTED |
  188             SCTP_PCB_FLAGS_IN_TCPPOOL | /* Turn on Blocking IO */
  189             (SCTP_PCB_COPY_FLAGS & inp->sctp_flags));
  190         n_inp->sctp_socket = newso;
  191         sosetstate(newso, SS_ISCONNECTED);
  192         /* We remove it right away */
  193 #if defined(__FreeBSD__) || defined(__APPLE__) || defined(__DragonFly__)
  194         SOCK_LOCK(head);
  195         lwkt_gettoken(&head->so_rcv.ssb_token);
  196         TAILQ_REMOVE(&head->so_comp, newso, so_list);
  197         head->so_qlen--;
  198         lwkt_reltoken(&head->so_rcv.ssb_token);
  199         SOCK_UNLOCK(head);
  200 #else
  201 
  202 #if defined(__NetBSD__) || defined(__OpenBSD__)
  203         newso = TAILQ_FIRST(&head->so_q);
  204 #else
  205         newso = head->so_q;
  206 #endif
  207         if (soqremque(newso, 1) == 0)
  208                 panic("sctp_peeloff");
  209 #endif /* __FreeBSD__ */
  210         /*
  211          * Now we must move it from one hash table to another and get
  212          * the stcb in the right place.
  213          */
  214         SCTP_INP_WUNLOCK(n_inp);
  215         sctp_move_pcb_and_assoc(inp, n_inp, stcb);
  216         /*
  217          * And now the final hack. We move data in the
  218          * pending side i.e. head to the new socket
  219          * buffer. Let the GRUBBING begin :-0
  220          */
  221         sctp_grub_through_socket_buffer(inp, head, newso, stcb);
  222         SCTP_TCB_UNLOCK(stcb);
  223         return (newso);
  224 }

Cache object: 183ac854fc75de138602aa4f66365c74


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.