LCOV - code coverage report
Current view: top level - netwerk/sctp/src/netinet - sctp_output.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 4935 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 82 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-
       2             :  * Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved.
       3             :  * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
       4             :  * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
       5             :  *
       6             :  * Redistribution and use in source and binary forms, with or without
       7             :  * modification, are permitted provided that the following conditions are met:
       8             :  *
       9             :  * a) Redistributions of source code must retain the above copyright notice,
      10             :  *    this list of conditions and the following disclaimer.
      11             :  *
      12             :  * b) Redistributions in binary form must reproduce the above copyright
      13             :  *    notice, this list of conditions and the following disclaimer in
      14             :  *    the documentation and/or other materials provided with the distribution.
      15             :  *
      16             :  * c) Neither the name of Cisco Systems, Inc. nor the names of its
      17             :  *    contributors may be used to endorse or promote products derived
      18             :  *    from this software without specific prior written permission.
      19             :  *
      20             :  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      21             :  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
      22             :  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      23             :  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
      24             :  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      25             :  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
      26             :  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
      27             :  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
      28             :  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      29             :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
      30             :  * THE POSSIBILITY OF SUCH DAMAGE.
      31             :  */
      32             : 
      33             : #ifdef __FreeBSD__
      34             : #include <sys/cdefs.h>
      35             : __FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 280371 2015-03-23 15:12:02Z tuexen $");
      36             : #endif
      37             : 
      38             : #include <netinet/sctp_os.h>
      39             : #ifdef __FreeBSD__
      40             : #include <sys/proc.h>
      41             : #endif
      42             : #include <netinet/sctp_var.h>
      43             : #include <netinet/sctp_sysctl.h>
      44             : #include <netinet/sctp_header.h>
      45             : #include <netinet/sctp_pcb.h>
      46             : #include <netinet/sctputil.h>
      47             : #include <netinet/sctp_output.h>
      48             : #include <netinet/sctp_uio.h>
      49             : #include <netinet/sctputil.h>
      50             : #include <netinet/sctp_auth.h>
      51             : #include <netinet/sctp_timer.h>
      52             : #include <netinet/sctp_asconf.h>
      53             : #include <netinet/sctp_indata.h>
      54             : #include <netinet/sctp_bsd_addr.h>
      55             : #include <netinet/sctp_input.h>
      56             : #include <netinet/sctp_crc32.h>
      57             : #if defined(__Userspace_os_Linux)
      58             : #define __FAVOR_BSD    /* (on Ubuntu at least) enables UDP header field names like BSD in RFC 768 */
      59             : #endif
      60             : #if defined(INET) || defined(INET6)
      61             : #if !defined(__Userspace_os_Windows)
      62             : #include <netinet/udp.h>
      63             : #endif
      64             : #endif
      65             : #if defined(__APPLE__)
      66             : #include <netinet/in.h>
      67             : #endif
      68             : #if defined(__FreeBSD__)
      69             : #if defined(__FreeBSD__) && __FreeBSD_version >= 800000
      70             : #include <netinet/udp_var.h>
      71             : #endif
      72             : #include <machine/in_cksum.h>
      73             : #endif
      74             : #if defined(__Userspace__) && defined(INET6)
      75             : #include <netinet6/sctp6_var.h>
      76             : #endif
      77             : 
      78             : #if defined(__APPLE__)
      79             : #define APPLE_FILE_NO 3
      80             : #endif
      81             : 
      82             : #if defined(__APPLE__)
      83             : #if !(defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD))
      84             : #define SCTP_MAX_LINKHDR 16
      85             : #endif
      86             : #endif
      87             : 
      88             : #define SCTP_MAX_GAPS_INARRAY 4
      89             : struct sack_track {
      90             :         uint8_t right_edge;     /* mergable on the right edge */
      91             :         uint8_t left_edge;      /* mergable on the left edge */
      92             :         uint8_t num_entries;
      93             :         uint8_t spare;
      94             :         struct sctp_gap_ack_block gaps[SCTP_MAX_GAPS_INARRAY];
      95             : };
      96             : 
      97             : struct sack_track sack_array[256] = {
      98             :         {0, 0, 0, 0,            /* 0x00 */
      99             :                 {{0, 0},
     100             :                 {0, 0},
     101             :                 {0, 0},
     102             :                 {0, 0}
     103             :                 }
     104             :         },
     105             :         {1, 0, 1, 0,            /* 0x01 */
     106             :                 {{0, 0},
     107             :                 {0, 0},
     108             :                 {0, 0},
     109             :                 {0, 0}
     110             :                 }
     111             :         },
     112             :         {0, 0, 1, 0,            /* 0x02 */
     113             :                 {{1, 1},
     114             :                 {0, 0},
     115             :                 {0, 0},
     116             :                 {0, 0}
     117             :                 }
     118             :         },
     119             :         {1, 0, 1, 0,            /* 0x03 */
     120             :                 {{0, 1},
     121             :                 {0, 0},
     122             :                 {0, 0},
     123             :                 {0, 0}
     124             :                 }
     125             :         },
     126             :         {0, 0, 1, 0,            /* 0x04 */
     127             :                 {{2, 2},
     128             :                 {0, 0},
     129             :                 {0, 0},
     130             :                 {0, 0}
     131             :                 }
     132             :         },
     133             :         {1, 0, 2, 0,            /* 0x05 */
     134             :                 {{0, 0},
     135             :                 {2, 2},
     136             :                 {0, 0},
     137             :                 {0, 0}
     138             :                 }
     139             :         },
     140             :         {0, 0, 1, 0,            /* 0x06 */
     141             :                 {{1, 2},
     142             :                 {0, 0},
     143             :                 {0, 0},
     144             :                 {0, 0}
     145             :                 }
     146             :         },
     147             :         {1, 0, 1, 0,            /* 0x07 */
     148             :                 {{0, 2},
     149             :                 {0, 0},
     150             :                 {0, 0},
     151             :                 {0, 0}
     152             :                 }
     153             :         },
     154             :         {0, 0, 1, 0,            /* 0x08 */
     155             :                 {{3, 3},
     156             :                 {0, 0},
     157             :                 {0, 0},
     158             :                 {0, 0}
     159             :                 }
     160             :         },
     161             :         {1, 0, 2, 0,            /* 0x09 */
     162             :                 {{0, 0},
     163             :                 {3, 3},
     164             :                 {0, 0},
     165             :                 {0, 0}
     166             :                 }
     167             :         },
     168             :         {0, 0, 2, 0,            /* 0x0a */
     169             :                 {{1, 1},
     170             :                 {3, 3},
     171             :                 {0, 0},
     172             :                 {0, 0}
     173             :                 }
     174             :         },
     175             :         {1, 0, 2, 0,            /* 0x0b */
     176             :                 {{0, 1},
     177             :                 {3, 3},
     178             :                 {0, 0},
     179             :                 {0, 0}
     180             :                 }
     181             :         },
     182             :         {0, 0, 1, 0,            /* 0x0c */
     183             :                 {{2, 3},
     184             :                 {0, 0},
     185             :                 {0, 0},
     186             :                 {0, 0}
     187             :                 }
     188             :         },
     189             :         {1, 0, 2, 0,            /* 0x0d */
     190             :                 {{0, 0},
     191             :                 {2, 3},
     192             :                 {0, 0},
     193             :                 {0, 0}
     194             :                 }
     195             :         },
     196             :         {0, 0, 1, 0,            /* 0x0e */
     197             :                 {{1, 3},
     198             :                 {0, 0},
     199             :                 {0, 0},
     200             :                 {0, 0}
     201             :                 }
     202             :         },
     203             :         {1, 0, 1, 0,            /* 0x0f */
     204             :                 {{0, 3},
     205             :                 {0, 0},
     206             :                 {0, 0},
     207             :                 {0, 0}
     208             :                 }
     209             :         },
     210             :         {0, 0, 1, 0,            /* 0x10 */
     211             :                 {{4, 4},
     212             :                 {0, 0},
     213             :                 {0, 0},
     214             :                 {0, 0}
     215             :                 }
     216             :         },
     217             :         {1, 0, 2, 0,            /* 0x11 */
     218             :                 {{0, 0},
     219             :                 {4, 4},
     220             :                 {0, 0},
     221             :                 {0, 0}
     222             :                 }
     223             :         },
     224             :         {0, 0, 2, 0,            /* 0x12 */
     225             :                 {{1, 1},
     226             :                 {4, 4},
     227             :                 {0, 0},
     228             :                 {0, 0}
     229             :                 }
     230             :         },
     231             :         {1, 0, 2, 0,            /* 0x13 */
     232             :                 {{0, 1},
     233             :                 {4, 4},
     234             :                 {0, 0},
     235             :                 {0, 0}
     236             :                 }
     237             :         },
     238             :         {0, 0, 2, 0,            /* 0x14 */
     239             :                 {{2, 2},
     240             :                 {4, 4},
     241             :                 {0, 0},
     242             :                 {0, 0}
     243             :                 }
     244             :         },
     245             :         {1, 0, 3, 0,            /* 0x15 */
     246             :                 {{0, 0},
     247             :                 {2, 2},
     248             :                 {4, 4},
     249             :                 {0, 0}
     250             :                 }
     251             :         },
     252             :         {0, 0, 2, 0,            /* 0x16 */
     253             :                 {{1, 2},
     254             :                 {4, 4},
     255             :                 {0, 0},
     256             :                 {0, 0}
     257             :                 }
     258             :         },
     259             :         {1, 0, 2, 0,            /* 0x17 */
     260             :                 {{0, 2},
     261             :                 {4, 4},
     262             :                 {0, 0},
     263             :                 {0, 0}
     264             :                 }
     265             :         },
     266             :         {0, 0, 1, 0,            /* 0x18 */
     267             :                 {{3, 4},
     268             :                 {0, 0},
     269             :                 {0, 0},
     270             :                 {0, 0}
     271             :                 }
     272             :         },
     273             :         {1, 0, 2, 0,            /* 0x19 */
     274             :                 {{0, 0},
     275             :                 {3, 4},
     276             :                 {0, 0},
     277             :                 {0, 0}
     278             :                 }
     279             :         },
     280             :         {0, 0, 2, 0,            /* 0x1a */
     281             :                 {{1, 1},
     282             :                 {3, 4},
     283             :                 {0, 0},
     284             :                 {0, 0}
     285             :                 }
     286             :         },
     287             :         {1, 0, 2, 0,            /* 0x1b */
     288             :                 {{0, 1},
     289             :                 {3, 4},
     290             :                 {0, 0},
     291             :                 {0, 0}
     292             :                 }
     293             :         },
     294             :         {0, 0, 1, 0,            /* 0x1c */
     295             :                 {{2, 4},
     296             :                 {0, 0},
     297             :                 {0, 0},
     298             :                 {0, 0}
     299             :                 }
     300             :         },
     301             :         {1, 0, 2, 0,            /* 0x1d */
     302             :                 {{0, 0},
     303             :                 {2, 4},
     304             :                 {0, 0},
     305             :                 {0, 0}
     306             :                 }
     307             :         },
     308             :         {0, 0, 1, 0,            /* 0x1e */
     309             :                 {{1, 4},
     310             :                 {0, 0},
     311             :                 {0, 0},
     312             :                 {0, 0}
     313             :                 }
     314             :         },
     315             :         {1, 0, 1, 0,            /* 0x1f */
     316             :                 {{0, 4},
     317             :                 {0, 0},
     318             :                 {0, 0},
     319             :                 {0, 0}
     320             :                 }
     321             :         },
     322             :         {0, 0, 1, 0,            /* 0x20 */
     323             :                 {{5, 5},
     324             :                 {0, 0},
     325             :                 {0, 0},
     326             :                 {0, 0}
     327             :                 }
     328             :         },
     329             :         {1, 0, 2, 0,            /* 0x21 */
     330             :                 {{0, 0},
     331             :                 {5, 5},
     332             :                 {0, 0},
     333             :                 {0, 0}
     334             :                 }
     335             :         },
     336             :         {0, 0, 2, 0,            /* 0x22 */
     337             :                 {{1, 1},
     338             :                 {5, 5},
     339             :                 {0, 0},
     340             :                 {0, 0}
     341             :                 }
     342             :         },
     343             :         {1, 0, 2, 0,            /* 0x23 */
     344             :                 {{0, 1},
     345             :                 {5, 5},
     346             :                 {0, 0},
     347             :                 {0, 0}
     348             :                 }
     349             :         },
     350             :         {0, 0, 2, 0,            /* 0x24 */
     351             :                 {{2, 2},
     352             :                 {5, 5},
     353             :                 {0, 0},
     354             :                 {0, 0}
     355             :                 }
     356             :         },
     357             :         {1, 0, 3, 0,            /* 0x25 */
     358             :                 {{0, 0},
     359             :                 {2, 2},
     360             :                 {5, 5},
     361             :                 {0, 0}
     362             :                 }
     363             :         },
     364             :         {0, 0, 2, 0,            /* 0x26 */
     365             :                 {{1, 2},
     366             :                 {5, 5},
     367             :                 {0, 0},
     368             :                 {0, 0}
     369             :                 }
     370             :         },
     371             :         {1, 0, 2, 0,            /* 0x27 */
     372             :                 {{0, 2},
     373             :                 {5, 5},
     374             :                 {0, 0},
     375             :                 {0, 0}
     376             :                 }
     377             :         },
     378             :         {0, 0, 2, 0,            /* 0x28 */
     379             :                 {{3, 3},
     380             :                 {5, 5},
     381             :                 {0, 0},
     382             :                 {0, 0}
     383             :                 }
     384             :         },
     385             :         {1, 0, 3, 0,            /* 0x29 */
     386             :                 {{0, 0},
     387             :                 {3, 3},
     388             :                 {5, 5},
     389             :                 {0, 0}
     390             :                 }
     391             :         },
     392             :         {0, 0, 3, 0,            /* 0x2a */
     393             :                 {{1, 1},
     394             :                 {3, 3},
     395             :                 {5, 5},
     396             :                 {0, 0}
     397             :                 }
     398             :         },
     399             :         {1, 0, 3, 0,            /* 0x2b */
     400             :                 {{0, 1},
     401             :                 {3, 3},
     402             :                 {5, 5},
     403             :                 {0, 0}
     404             :                 }
     405             :         },
     406             :         {0, 0, 2, 0,            /* 0x2c */
     407             :                 {{2, 3},
     408             :                 {5, 5},
     409             :                 {0, 0},
     410             :                 {0, 0}
     411             :                 }
     412             :         },
     413             :         {1, 0, 3, 0,            /* 0x2d */
     414             :                 {{0, 0},
     415             :                 {2, 3},
     416             :                 {5, 5},
     417             :                 {0, 0}
     418             :                 }
     419             :         },
     420             :         {0, 0, 2, 0,            /* 0x2e */
     421             :                 {{1, 3},
     422             :                 {5, 5},
     423             :                 {0, 0},
     424             :                 {0, 0}
     425             :                 }
     426             :         },
     427             :         {1, 0, 2, 0,            /* 0x2f */
     428             :                 {{0, 3},
     429             :                 {5, 5},
     430             :                 {0, 0},
     431             :                 {0, 0}
     432             :                 }
     433             :         },
     434             :         {0, 0, 1, 0,            /* 0x30 */
     435             :                 {{4, 5},
     436             :                 {0, 0},
     437             :                 {0, 0},
     438             :                 {0, 0}
     439             :                 }
     440             :         },
     441             :         {1, 0, 2, 0,            /* 0x31 */
     442             :                 {{0, 0},
     443             :                 {4, 5},
     444             :                 {0, 0},
     445             :                 {0, 0}
     446             :                 }
     447             :         },
     448             :         {0, 0, 2, 0,            /* 0x32 */
     449             :                 {{1, 1},
     450             :                 {4, 5},
     451             :                 {0, 0},
     452             :                 {0, 0}
     453             :                 }
     454             :         },
     455             :         {1, 0, 2, 0,            /* 0x33 */
     456             :                 {{0, 1},
     457             :                 {4, 5},
     458             :                 {0, 0},
     459             :                 {0, 0}
     460             :                 }
     461             :         },
     462             :         {0, 0, 2, 0,            /* 0x34 */
     463             :                 {{2, 2},
     464             :                 {4, 5},
     465             :                 {0, 0},
     466             :                 {0, 0}
     467             :                 }
     468             :         },
     469             :         {1, 0, 3, 0,            /* 0x35 */
     470             :                 {{0, 0},
     471             :                 {2, 2},
     472             :                 {4, 5},
     473             :                 {0, 0}
     474             :                 }
     475             :         },
     476             :         {0, 0, 2, 0,            /* 0x36 */
     477             :                 {{1, 2},
     478             :                 {4, 5},
     479             :                 {0, 0},
     480             :                 {0, 0}
     481             :                 }
     482             :         },
     483             :         {1, 0, 2, 0,            /* 0x37 */
     484             :                 {{0, 2},
     485             :                 {4, 5},
     486             :                 {0, 0},
     487             :                 {0, 0}
     488             :                 }
     489             :         },
     490             :         {0, 0, 1, 0,            /* 0x38 */
     491             :                 {{3, 5},
     492             :                 {0, 0},
     493             :                 {0, 0},
     494             :                 {0, 0}
     495             :                 }
     496             :         },
     497             :         {1, 0, 2, 0,            /* 0x39 */
     498             :                 {{0, 0},
     499             :                 {3, 5},
     500             :                 {0, 0},
     501             :                 {0, 0}
     502             :                 }
     503             :         },
     504             :         {0, 0, 2, 0,            /* 0x3a */
     505             :                 {{1, 1},
     506             :                 {3, 5},
     507             :                 {0, 0},
     508             :                 {0, 0}
     509             :                 }
     510             :         },
     511             :         {1, 0, 2, 0,            /* 0x3b */
     512             :                 {{0, 1},
     513             :                 {3, 5},
     514             :                 {0, 0},
     515             :                 {0, 0}
     516             :                 }
     517             :         },
     518             :         {0, 0, 1, 0,            /* 0x3c */
     519             :                 {{2, 5},
     520             :                 {0, 0},
     521             :                 {0, 0},
     522             :                 {0, 0}
     523             :                 }
     524             :         },
     525             :         {1, 0, 2, 0,            /* 0x3d */
     526             :                 {{0, 0},
     527             :                 {2, 5},
     528             :                 {0, 0},
     529             :                 {0, 0}
     530             :                 }
     531             :         },
     532             :         {0, 0, 1, 0,            /* 0x3e */
     533             :                 {{1, 5},
     534             :                 {0, 0},
     535             :                 {0, 0},
     536             :                 {0, 0}
     537             :                 }
     538             :         },
     539             :         {1, 0, 1, 0,            /* 0x3f */
     540             :                 {{0, 5},
     541             :                 {0, 0},
     542             :                 {0, 0},
     543             :                 {0, 0}
     544             :                 }
     545             :         },
     546             :         {0, 0, 1, 0,            /* 0x40 */
     547             :                 {{6, 6},
     548             :                 {0, 0},
     549             :                 {0, 0},
     550             :                 {0, 0}
     551             :                 }
     552             :         },
     553             :         {1, 0, 2, 0,            /* 0x41 */
     554             :                 {{0, 0},
     555             :                 {6, 6},
     556             :                 {0, 0},
     557             :                 {0, 0}
     558             :                 }
     559             :         },
     560             :         {0, 0, 2, 0,            /* 0x42 */
     561             :                 {{1, 1},
     562             :                 {6, 6},
     563             :                 {0, 0},
     564             :                 {0, 0}
     565             :                 }
     566             :         },
     567             :         {1, 0, 2, 0,            /* 0x43 */
     568             :                 {{0, 1},
     569             :                 {6, 6},
     570             :                 {0, 0},
     571             :                 {0, 0}
     572             :                 }
     573             :         },
     574             :         {0, 0, 2, 0,            /* 0x44 */
     575             :                 {{2, 2},
     576             :                 {6, 6},
     577             :                 {0, 0},
     578             :                 {0, 0}
     579             :                 }
     580             :         },
     581             :         {1, 0, 3, 0,            /* 0x45 */
     582             :                 {{0, 0},
     583             :                 {2, 2},
     584             :                 {6, 6},
     585             :                 {0, 0}
     586             :                 }
     587             :         },
     588             :         {0, 0, 2, 0,            /* 0x46 */
     589             :                 {{1, 2},
     590             :                 {6, 6},
     591             :                 {0, 0},
     592             :                 {0, 0}
     593             :                 }
     594             :         },
     595             :         {1, 0, 2, 0,            /* 0x47 */
     596             :                 {{0, 2},
     597             :                 {6, 6},
     598             :                 {0, 0},
     599             :                 {0, 0}
     600             :                 }
     601             :         },
     602             :         {0, 0, 2, 0,            /* 0x48 */
     603             :                 {{3, 3},
     604             :                 {6, 6},
     605             :                 {0, 0},
     606             :                 {0, 0}
     607             :                 }
     608             :         },
     609             :         {1, 0, 3, 0,            /* 0x49 */
     610             :                 {{0, 0},
     611             :                 {3, 3},
     612             :                 {6, 6},
     613             :                 {0, 0}
     614             :                 }
     615             :         },
     616             :         {0, 0, 3, 0,            /* 0x4a */
     617             :                 {{1, 1},
     618             :                 {3, 3},
     619             :                 {6, 6},
     620             :                 {0, 0}
     621             :                 }
     622             :         },
     623             :         {1, 0, 3, 0,            /* 0x4b */
     624             :                 {{0, 1},
     625             :                 {3, 3},
     626             :                 {6, 6},
     627             :                 {0, 0}
     628             :                 }
     629             :         },
     630             :         {0, 0, 2, 0,            /* 0x4c */
     631             :                 {{2, 3},
     632             :                 {6, 6},
     633             :                 {0, 0},
     634             :                 {0, 0}
     635             :                 }
     636             :         },
     637             :         {1, 0, 3, 0,            /* 0x4d */
     638             :                 {{0, 0},
     639             :                 {2, 3},
     640             :                 {6, 6},
     641             :                 {0, 0}
     642             :                 }
     643             :         },
     644             :         {0, 0, 2, 0,            /* 0x4e */
     645             :                 {{1, 3},
     646             :                 {6, 6},
     647             :                 {0, 0},
     648             :                 {0, 0}
     649             :                 }
     650             :         },
     651             :         {1, 0, 2, 0,            /* 0x4f */
     652             :                 {{0, 3},
     653             :                 {6, 6},
     654             :                 {0, 0},
     655             :                 {0, 0}
     656             :                 }
     657             :         },
     658             :         {0, 0, 2, 0,            /* 0x50 */
     659             :                 {{4, 4},
     660             :                 {6, 6},
     661             :                 {0, 0},
     662             :                 {0, 0}
     663             :                 }
     664             :         },
     665             :         {1, 0, 3, 0,            /* 0x51 */
     666             :                 {{0, 0},
     667             :                 {4, 4},
     668             :                 {6, 6},
     669             :                 {0, 0}
     670             :                 }
     671             :         },
     672             :         {0, 0, 3, 0,            /* 0x52 */
     673             :                 {{1, 1},
     674             :                 {4, 4},
     675             :                 {6, 6},
     676             :                 {0, 0}
     677             :                 }
     678             :         },
     679             :         {1, 0, 3, 0,            /* 0x53 */
     680             :                 {{0, 1},
     681             :                 {4, 4},
     682             :                 {6, 6},
     683             :                 {0, 0}
     684             :                 }
     685             :         },
     686             :         {0, 0, 3, 0,            /* 0x54 */
     687             :                 {{2, 2},
     688             :                 {4, 4},
     689             :                 {6, 6},
     690             :                 {0, 0}
     691             :                 }
     692             :         },
     693             :         {1, 0, 4, 0,            /* 0x55 */
     694             :                 {{0, 0},
     695             :                 {2, 2},
     696             :                 {4, 4},
     697             :                 {6, 6}
     698             :                 }
     699             :         },
     700             :         {0, 0, 3, 0,            /* 0x56 */
     701             :                 {{1, 2},
     702             :                 {4, 4},
     703             :                 {6, 6},
     704             :                 {0, 0}
     705             :                 }
     706             :         },
     707             :         {1, 0, 3, 0,            /* 0x57 */
     708             :                 {{0, 2},
     709             :                 {4, 4},
     710             :                 {6, 6},
     711             :                 {0, 0}
     712             :                 }
     713             :         },
     714             :         {0, 0, 2, 0,            /* 0x58 */
     715             :                 {{3, 4},
     716             :                 {6, 6},
     717             :                 {0, 0},
     718             :                 {0, 0}
     719             :                 }
     720             :         },
     721             :         {1, 0, 3, 0,            /* 0x59 */
     722             :                 {{0, 0},
     723             :                 {3, 4},
     724             :                 {6, 6},
     725             :                 {0, 0}
     726             :                 }
     727             :         },
     728             :         {0, 0, 3, 0,            /* 0x5a */
     729             :                 {{1, 1},
     730             :                 {3, 4},
     731             :                 {6, 6},
     732             :                 {0, 0}
     733             :                 }
     734             :         },
     735             :         {1, 0, 3, 0,            /* 0x5b */
     736             :                 {{0, 1},
     737             :                 {3, 4},
     738             :                 {6, 6},
     739             :                 {0, 0}
     740             :                 }
     741             :         },
     742             :         {0, 0, 2, 0,            /* 0x5c */
     743             :                 {{2, 4},
     744             :                 {6, 6},
     745             :                 {0, 0},
     746             :                 {0, 0}
     747             :                 }
     748             :         },
     749             :         {1, 0, 3, 0,            /* 0x5d */
     750             :                 {{0, 0},
     751             :                 {2, 4},
     752             :                 {6, 6},
     753             :                 {0, 0}
     754             :                 }
     755             :         },
     756             :         {0, 0, 2, 0,            /* 0x5e */
     757             :                 {{1, 4},
     758             :                 {6, 6},
     759             :                 {0, 0},
     760             :                 {0, 0}
     761             :                 }
     762             :         },
     763             :         {1, 0, 2, 0,            /* 0x5f */
     764             :                 {{0, 4},
     765             :                 {6, 6},
     766             :                 {0, 0},
     767             :                 {0, 0}
     768             :                 }
     769             :         },
     770             :         {0, 0, 1, 0,            /* 0x60 */
     771             :                 {{5, 6},
     772             :                 {0, 0},
     773             :                 {0, 0},
     774             :                 {0, 0}
     775             :                 }
     776             :         },
     777             :         {1, 0, 2, 0,            /* 0x61 */
     778             :                 {{0, 0},
     779             :                 {5, 6},
     780             :                 {0, 0},
     781             :                 {0, 0}
     782             :                 }
     783             :         },
     784             :         {0, 0, 2, 0,            /* 0x62 */
     785             :                 {{1, 1},
     786             :                 {5, 6},
     787             :                 {0, 0},
     788             :                 {0, 0}
     789             :                 }
     790             :         },
     791             :         {1, 0, 2, 0,            /* 0x63 */
     792             :                 {{0, 1},
     793             :                 {5, 6},
     794             :                 {0, 0},
     795             :                 {0, 0}
     796             :                 }
     797             :         },
     798             :         {0, 0, 2, 0,            /* 0x64 */
     799             :                 {{2, 2},
     800             :                 {5, 6},
     801             :                 {0, 0},
     802             :                 {0, 0}
     803             :                 }
     804             :         },
     805             :         {1, 0, 3, 0,            /* 0x65 */
     806             :                 {{0, 0},
     807             :                 {2, 2},
     808             :                 {5, 6},
     809             :                 {0, 0}
     810             :                 }
     811             :         },
     812             :         {0, 0, 2, 0,            /* 0x66 */
     813             :                 {{1, 2},
     814             :                 {5, 6},
     815             :                 {0, 0},
     816             :                 {0, 0}
     817             :                 }
     818             :         },
     819             :         {1, 0, 2, 0,            /* 0x67 */
     820             :                 {{0, 2},
     821             :                 {5, 6},
     822             :                 {0, 0},
     823             :                 {0, 0}
     824             :                 }
     825             :         },
     826             :         {0, 0, 2, 0,            /* 0x68 */
     827             :                 {{3, 3},
     828             :                 {5, 6},
     829             :                 {0, 0},
     830             :                 {0, 0}
     831             :                 }
     832             :         },
     833             :         {1, 0, 3, 0,            /* 0x69 */
     834             :                 {{0, 0},
     835             :                 {3, 3},
     836             :                 {5, 6},
     837             :                 {0, 0}
     838             :                 }
     839             :         },
     840             :         {0, 0, 3, 0,            /* 0x6a */
     841             :                 {{1, 1},
     842             :                 {3, 3},
     843             :                 {5, 6},
     844             :                 {0, 0}
     845             :                 }
     846             :         },
     847             :         {1, 0, 3, 0,            /* 0x6b */
     848             :                 {{0, 1},
     849             :                 {3, 3},
     850             :                 {5, 6},
     851             :                 {0, 0}
     852             :                 }
     853             :         },
     854             :         {0, 0, 2, 0,            /* 0x6c */
     855             :                 {{2, 3},
     856             :                 {5, 6},
     857             :                 {0, 0},
     858             :                 {0, 0}
     859             :                 }
     860             :         },
     861             :         {1, 0, 3, 0,            /* 0x6d */
     862             :                 {{0, 0},
     863             :                 {2, 3},
     864             :                 {5, 6},
     865             :                 {0, 0}
     866             :                 }
     867             :         },
     868             :         {0, 0, 2, 0,            /* 0x6e */
     869             :                 {{1, 3},
     870             :                 {5, 6},
     871             :                 {0, 0},
     872             :                 {0, 0}
     873             :                 }
     874             :         },
     875             :         {1, 0, 2, 0,            /* 0x6f */
     876             :                 {{0, 3},
     877             :                 {5, 6},
     878             :                 {0, 0},
     879             :                 {0, 0}
     880             :                 }
     881             :         },
     882             :         {0, 0, 1, 0,            /* 0x70 */
     883             :                 {{4, 6},
     884             :                 {0, 0},
     885             :                 {0, 0},
     886             :                 {0, 0}
     887             :                 }
     888             :         },
     889             :         {1, 0, 2, 0,            /* 0x71 */
     890             :                 {{0, 0},
     891             :                 {4, 6},
     892             :                 {0, 0},
     893             :                 {0, 0}
     894             :                 }
     895             :         },
     896             :         {0, 0, 2, 0,            /* 0x72 */
     897             :                 {{1, 1},
     898             :                 {4, 6},
     899             :                 {0, 0},
     900             :                 {0, 0}
     901             :                 }
     902             :         },
     903             :         {1, 0, 2, 0,            /* 0x73 */
     904             :                 {{0, 1},
     905             :                 {4, 6},
     906             :                 {0, 0},
     907             :                 {0, 0}
     908             :                 }
     909             :         },
     910             :         {0, 0, 2, 0,            /* 0x74 */
     911             :                 {{2, 2},
     912             :                 {4, 6},
     913             :                 {0, 0},
     914             :                 {0, 0}
     915             :                 }
     916             :         },
     917             :         {1, 0, 3, 0,            /* 0x75 */
     918             :                 {{0, 0},
     919             :                 {2, 2},
     920             :                 {4, 6},
     921             :                 {0, 0}
     922             :                 }
     923             :         },
     924             :         {0, 0, 2, 0,            /* 0x76 */
     925             :                 {{1, 2},
     926             :                 {4, 6},
     927             :                 {0, 0},
     928             :                 {0, 0}
     929             :                 }
     930             :         },
     931             :         {1, 0, 2, 0,            /* 0x77 */
     932             :                 {{0, 2},
     933             :                 {4, 6},
     934             :                 {0, 0},
     935             :                 {0, 0}
     936             :                 }
     937             :         },
     938             :         {0, 0, 1, 0,            /* 0x78 */
     939             :                 {{3, 6},
     940             :                 {0, 0},
     941             :                 {0, 0},
     942             :                 {0, 0}
     943             :                 }
     944             :         },
     945             :         {1, 0, 2, 0,            /* 0x79 */
     946             :                 {{0, 0},
     947             :                 {3, 6},
     948             :                 {0, 0},
     949             :                 {0, 0}
     950             :                 }
     951             :         },
     952             :         {0, 0, 2, 0,            /* 0x7a */
     953             :                 {{1, 1},
     954             :                 {3, 6},
     955             :                 {0, 0},
     956             :                 {0, 0}
     957             :                 }
     958             :         },
     959             :         {1, 0, 2, 0,            /* 0x7b */
     960             :                 {{0, 1},
     961             :                 {3, 6},
     962             :                 {0, 0},
     963             :                 {0, 0}
     964             :                 }
     965             :         },
     966             :         {0, 0, 1, 0,            /* 0x7c */
     967             :                 {{2, 6},
     968             :                 {0, 0},
     969             :                 {0, 0},
     970             :                 {0, 0}
     971             :                 }
     972             :         },
     973             :         {1, 0, 2, 0,            /* 0x7d */
     974             :                 {{0, 0},
     975             :                 {2, 6},
     976             :                 {0, 0},
     977             :                 {0, 0}
     978             :                 }
     979             :         },
     980             :         {0, 0, 1, 0,            /* 0x7e */
     981             :                 {{1, 6},
     982             :                 {0, 0},
     983             :                 {0, 0},
     984             :                 {0, 0}
     985             :                 }
     986             :         },
     987             :         {1, 0, 1, 0,            /* 0x7f */
     988             :                 {{0, 6},
     989             :                 {0, 0},
     990             :                 {0, 0},
     991             :                 {0, 0}
     992             :                 }
     993             :         },
     994             :         {0, 1, 1, 0,            /* 0x80 */
     995             :                 {{7, 7},
     996             :                 {0, 0},
     997             :                 {0, 0},
     998             :                 {0, 0}
     999             :                 }
    1000             :         },
    1001             :         {1, 1, 2, 0,            /* 0x81 */
    1002             :                 {{0, 0},
    1003             :                 {7, 7},
    1004             :                 {0, 0},
    1005             :                 {0, 0}
    1006             :                 }
    1007             :         },
    1008             :         {0, 1, 2, 0,            /* 0x82 */
    1009             :                 {{1, 1},
    1010             :                 {7, 7},
    1011             :                 {0, 0},
    1012             :                 {0, 0}
    1013             :                 }
    1014             :         },
    1015             :         {1, 1, 2, 0,            /* 0x83 */
    1016             :                 {{0, 1},
    1017             :                 {7, 7},
    1018             :                 {0, 0},
    1019             :                 {0, 0}
    1020             :                 }
    1021             :         },
    1022             :         {0, 1, 2, 0,            /* 0x84 */
    1023             :                 {{2, 2},
    1024             :                 {7, 7},
    1025             :                 {0, 0},
    1026             :                 {0, 0}
    1027             :                 }
    1028             :         },
    1029             :         {1, 1, 3, 0,            /* 0x85 */
    1030             :                 {{0, 0},
    1031             :                 {2, 2},
    1032             :                 {7, 7},
    1033             :                 {0, 0}
    1034             :                 }
    1035             :         },
    1036             :         {0, 1, 2, 0,            /* 0x86 */
    1037             :                 {{1, 2},
    1038             :                 {7, 7},
    1039             :                 {0, 0},
    1040             :                 {0, 0}
    1041             :                 }
    1042             :         },
    1043             :         {1, 1, 2, 0,            /* 0x87 */
    1044             :                 {{0, 2},
    1045             :                 {7, 7},
    1046             :                 {0, 0},
    1047             :                 {0, 0}
    1048             :                 }
    1049             :         },
    1050             :         {0, 1, 2, 0,            /* 0x88 */
    1051             :                 {{3, 3},
    1052             :                 {7, 7},
    1053             :                 {0, 0},
    1054             :                 {0, 0}
    1055             :                 }
    1056             :         },
    1057             :         {1, 1, 3, 0,            /* 0x89 */
    1058             :                 {{0, 0},
    1059             :                 {3, 3},
    1060             :                 {7, 7},
    1061             :                 {0, 0}
    1062             :                 }
    1063             :         },
    1064             :         {0, 1, 3, 0,            /* 0x8a */
    1065             :                 {{1, 1},
    1066             :                 {3, 3},
    1067             :                 {7, 7},
    1068             :                 {0, 0}
    1069             :                 }
    1070             :         },
    1071             :         {1, 1, 3, 0,            /* 0x8b */
    1072             :                 {{0, 1},
    1073             :                 {3, 3},
    1074             :                 {7, 7},
    1075             :                 {0, 0}
    1076             :                 }
    1077             :         },
    1078             :         {0, 1, 2, 0,            /* 0x8c */
    1079             :                 {{2, 3},
    1080             :                 {7, 7},
    1081             :                 {0, 0},
    1082             :                 {0, 0}
    1083             :                 }
    1084             :         },
    1085             :         {1, 1, 3, 0,            /* 0x8d */
    1086             :                 {{0, 0},
    1087             :                 {2, 3},
    1088             :                 {7, 7},
    1089             :                 {0, 0}
    1090             :                 }
    1091             :         },
    1092             :         {0, 1, 2, 0,            /* 0x8e */
    1093             :                 {{1, 3},
    1094             :                 {7, 7},
    1095             :                 {0, 0},
    1096             :                 {0, 0}
    1097             :                 }
    1098             :         },
    1099             :         {1, 1, 2, 0,            /* 0x8f */
    1100             :                 {{0, 3},
    1101             :                 {7, 7},
    1102             :                 {0, 0},
    1103             :                 {0, 0}
    1104             :                 }
    1105             :         },
    1106             :         {0, 1, 2, 0,            /* 0x90 */
    1107             :                 {{4, 4},
    1108             :                 {7, 7},
    1109             :                 {0, 0},
    1110             :                 {0, 0}
    1111             :                 }
    1112             :         },
    1113             :         {1, 1, 3, 0,            /* 0x91 */
    1114             :                 {{0, 0},
    1115             :                 {4, 4},
    1116             :                 {7, 7},
    1117             :                 {0, 0}
    1118             :                 }
    1119             :         },
    1120             :         {0, 1, 3, 0,            /* 0x92 */
    1121             :                 {{1, 1},
    1122             :                 {4, 4},
    1123             :                 {7, 7},
    1124             :                 {0, 0}
    1125             :                 }
    1126             :         },
    1127             :         {1, 1, 3, 0,            /* 0x93 */
    1128             :                 {{0, 1},
    1129             :                 {4, 4},
    1130             :                 {7, 7},
    1131             :                 {0, 0}
    1132             :                 }
    1133             :         },
    1134             :         {0, 1, 3, 0,            /* 0x94 */
    1135             :                 {{2, 2},
    1136             :                 {4, 4},
    1137             :                 {7, 7},
    1138             :                 {0, 0}
    1139             :                 }
    1140             :         },
    1141             :         {1, 1, 4, 0,            /* 0x95 */
    1142             :                 {{0, 0},
    1143             :                 {2, 2},
    1144             :                 {4, 4},
    1145             :                 {7, 7}
    1146             :                 }
    1147             :         },
    1148             :         {0, 1, 3, 0,            /* 0x96 */
    1149             :                 {{1, 2},
    1150             :                 {4, 4},
    1151             :                 {7, 7},
    1152             :                 {0, 0}
    1153             :                 }
    1154             :         },
    1155             :         {1, 1, 3, 0,            /* 0x97 */
    1156             :                 {{0, 2},
    1157             :                 {4, 4},
    1158             :                 {7, 7},
    1159             :                 {0, 0}
    1160             :                 }
    1161             :         },
    1162             :         {0, 1, 2, 0,            /* 0x98 */
    1163             :                 {{3, 4},
    1164             :                 {7, 7},
    1165             :                 {0, 0},
    1166             :                 {0, 0}
    1167             :                 }
    1168             :         },
    1169             :         {1, 1, 3, 0,            /* 0x99 */
    1170             :                 {{0, 0},
    1171             :                 {3, 4},
    1172             :                 {7, 7},
    1173             :                 {0, 0}
    1174             :                 }
    1175             :         },
    1176             :         {0, 1, 3, 0,            /* 0x9a */
    1177             :                 {{1, 1},
    1178             :                 {3, 4},
    1179             :                 {7, 7},
    1180             :                 {0, 0}
    1181             :                 }
    1182             :         },
    1183             :         {1, 1, 3, 0,            /* 0x9b */
    1184             :                 {{0, 1},
    1185             :                 {3, 4},
    1186             :                 {7, 7},
    1187             :                 {0, 0}
    1188             :                 }
    1189             :         },
    1190             :         {0, 1, 2, 0,            /* 0x9c */
    1191             :                 {{2, 4},
    1192             :                 {7, 7},
    1193             :                 {0, 0},
    1194             :                 {0, 0}
    1195             :                 }
    1196             :         },
    1197             :         {1, 1, 3, 0,            /* 0x9d */
    1198             :                 {{0, 0},
    1199             :                 {2, 4},
    1200             :                 {7, 7},
    1201             :                 {0, 0}
    1202             :                 }
    1203             :         },
    1204             :         {0, 1, 2, 0,            /* 0x9e */
    1205             :                 {{1, 4},
    1206             :                 {7, 7},
    1207             :                 {0, 0},
    1208             :                 {0, 0}
    1209             :                 }
    1210             :         },
    1211             :         {1, 1, 2, 0,            /* 0x9f */
    1212             :                 {{0, 4},
    1213             :                 {7, 7},
    1214             :                 {0, 0},
    1215             :                 {0, 0}
    1216             :                 }
    1217             :         },
    1218             :         {0, 1, 2, 0,            /* 0xa0 */
    1219             :                 {{5, 5},
    1220             :                 {7, 7},
    1221             :                 {0, 0},
    1222             :                 {0, 0}
    1223             :                 }
    1224             :         },
    1225             :         {1, 1, 3, 0,            /* 0xa1 */
    1226             :                 {{0, 0},
    1227             :                 {5, 5},
    1228             :                 {7, 7},
    1229             :                 {0, 0}
    1230             :                 }
    1231             :         },
    1232             :         {0, 1, 3, 0,            /* 0xa2 */
    1233             :                 {{1, 1},
    1234             :                 {5, 5},
    1235             :                 {7, 7},
    1236             :                 {0, 0}
    1237             :                 }
    1238             :         },
    1239             :         {1, 1, 3, 0,            /* 0xa3 */
    1240             :                 {{0, 1},
    1241             :                 {5, 5},
    1242             :                 {7, 7},
    1243             :                 {0, 0}
    1244             :                 }
    1245             :         },
    1246             :         {0, 1, 3, 0,            /* 0xa4 */
    1247             :                 {{2, 2},
    1248             :                 {5, 5},
    1249             :                 {7, 7},
    1250             :                 {0, 0}
    1251             :                 }
    1252             :         },
    1253             :         {1, 1, 4, 0,            /* 0xa5 */
    1254             :                 {{0, 0},
    1255             :                 {2, 2},
    1256             :                 {5, 5},
    1257             :                 {7, 7}
    1258             :                 }
    1259             :         },
    1260             :         {0, 1, 3, 0,            /* 0xa6 */
    1261             :                 {{1, 2},
    1262             :                 {5, 5},
    1263             :                 {7, 7},
    1264             :                 {0, 0}
    1265             :                 }
    1266             :         },
    1267             :         {1, 1, 3, 0,            /* 0xa7 */
    1268             :                 {{0, 2},
    1269             :                 {5, 5},
    1270             :                 {7, 7},
    1271             :                 {0, 0}
    1272             :                 }
    1273             :         },
    1274             :         {0, 1, 3, 0,            /* 0xa8 */
    1275             :                 {{3, 3},
    1276             :                 {5, 5},
    1277             :                 {7, 7},
    1278             :                 {0, 0}
    1279             :                 }
    1280             :         },
    1281             :         {1, 1, 4, 0,            /* 0xa9 */
    1282             :                 {{0, 0},
    1283             :                 {3, 3},
    1284             :                 {5, 5},
    1285             :                 {7, 7}
    1286             :                 }
    1287             :         },
    1288             :         {0, 1, 4, 0,            /* 0xaa */
    1289             :                 {{1, 1},
    1290             :                 {3, 3},
    1291             :                 {5, 5},
    1292             :                 {7, 7}
    1293             :                 }
    1294             :         },
    1295             :         {1, 1, 4, 0,            /* 0xab */
    1296             :                 {{0, 1},
    1297             :                 {3, 3},
    1298             :                 {5, 5},
    1299             :                 {7, 7}
    1300             :                 }
    1301             :         },
    1302             :         {0, 1, 3, 0,            /* 0xac */
    1303             :                 {{2, 3},
    1304             :                 {5, 5},
    1305             :                 {7, 7},
    1306             :                 {0, 0}
    1307             :                 }
    1308             :         },
    1309             :         {1, 1, 4, 0,            /* 0xad */
    1310             :                 {{0, 0},
    1311             :                 {2, 3},
    1312             :                 {5, 5},
    1313             :                 {7, 7}
    1314             :                 }
    1315             :         },
    1316             :         {0, 1, 3, 0,            /* 0xae */
    1317             :                 {{1, 3},
    1318             :                 {5, 5},
    1319             :                 {7, 7},
    1320             :                 {0, 0}
    1321             :                 }
    1322             :         },
    1323             :         {1, 1, 3, 0,            /* 0xaf */
    1324             :                 {{0, 3},
    1325             :                 {5, 5},
    1326             :                 {7, 7},
    1327             :                 {0, 0}
    1328             :                 }
    1329             :         },
    1330             :         {0, 1, 2, 0,            /* 0xb0 */
    1331             :                 {{4, 5},
    1332             :                 {7, 7},
    1333             :                 {0, 0},
    1334             :                 {0, 0}
    1335             :                 }
    1336             :         },
    1337             :         {1, 1, 3, 0,            /* 0xb1 */
    1338             :                 {{0, 0},
    1339             :                 {4, 5},
    1340             :                 {7, 7},
    1341             :                 {0, 0}
    1342             :                 }
    1343             :         },
    1344             :         {0, 1, 3, 0,            /* 0xb2 */
    1345             :                 {{1, 1},
    1346             :                 {4, 5},
    1347             :                 {7, 7},
    1348             :                 {0, 0}
    1349             :                 }
    1350             :         },
    1351             :         {1, 1, 3, 0,            /* 0xb3 */
    1352             :                 {{0, 1},
    1353             :                 {4, 5},
    1354             :                 {7, 7},
    1355             :                 {0, 0}
    1356             :                 }
    1357             :         },
    1358             :         {0, 1, 3, 0,            /* 0xb4 */
    1359             :                 {{2, 2},
    1360             :                 {4, 5},
    1361             :                 {7, 7},
    1362             :                 {0, 0}
    1363             :                 }
    1364             :         },
    1365             :         {1, 1, 4, 0,            /* 0xb5 */
    1366             :                 {{0, 0},
    1367             :                 {2, 2},
    1368             :                 {4, 5},
    1369             :                 {7, 7}
    1370             :                 }
    1371             :         },
    1372             :         {0, 1, 3, 0,            /* 0xb6 */
    1373             :                 {{1, 2},
    1374             :                 {4, 5},
    1375             :                 {7, 7},
    1376             :                 {0, 0}
    1377             :                 }
    1378             :         },
    1379             :         {1, 1, 3, 0,            /* 0xb7 */
    1380             :                 {{0, 2},
    1381             :                 {4, 5},
    1382             :                 {7, 7},
    1383             :                 {0, 0}
    1384             :                 }
    1385             :         },
    1386             :         {0, 1, 2, 0,            /* 0xb8 */
    1387             :                 {{3, 5},
    1388             :                 {7, 7},
    1389             :                 {0, 0},
    1390             :                 {0, 0}
    1391             :                 }
    1392             :         },
    1393             :         {1, 1, 3, 0,            /* 0xb9 */
    1394             :                 {{0, 0},
    1395             :                 {3, 5},
    1396             :                 {7, 7},
    1397             :                 {0, 0}
    1398             :                 }
    1399             :         },
    1400             :         {0, 1, 3, 0,            /* 0xba */
    1401             :                 {{1, 1},
    1402             :                 {3, 5},
    1403             :                 {7, 7},
    1404             :                 {0, 0}
    1405             :                 }
    1406             :         },
    1407             :         {1, 1, 3, 0,            /* 0xbb */
    1408             :                 {{0, 1},
    1409             :                 {3, 5},
    1410             :                 {7, 7},
    1411             :                 {0, 0}
    1412             :                 }
    1413             :         },
    1414             :         {0, 1, 2, 0,            /* 0xbc */
    1415             :                 {{2, 5},
    1416             :                 {7, 7},
    1417             :                 {0, 0},
    1418             :                 {0, 0}
    1419             :                 }
    1420             :         },
    1421             :         {1, 1, 3, 0,            /* 0xbd */
    1422             :                 {{0, 0},
    1423             :                 {2, 5},
    1424             :                 {7, 7},
    1425             :                 {0, 0}
    1426             :                 }
    1427             :         },
    1428             :         {0, 1, 2, 0,            /* 0xbe */
    1429             :                 {{1, 5},
    1430             :                 {7, 7},
    1431             :                 {0, 0},
    1432             :                 {0, 0}
    1433             :                 }
    1434             :         },
    1435             :         {1, 1, 2, 0,            /* 0xbf */
    1436             :                 {{0, 5},
    1437             :                 {7, 7},
    1438             :                 {0, 0},
    1439             :                 {0, 0}
    1440             :                 }
    1441             :         },
    1442             :         {0, 1, 1, 0,            /* 0xc0 */
    1443             :                 {{6, 7},
    1444             :                 {0, 0},
    1445             :                 {0, 0},
    1446             :                 {0, 0}
    1447             :                 }
    1448             :         },
    1449             :         {1, 1, 2, 0,            /* 0xc1 */
    1450             :                 {{0, 0},
    1451             :                 {6, 7},
    1452             :                 {0, 0},
    1453             :                 {0, 0}
    1454             :                 }
    1455             :         },
    1456             :         {0, 1, 2, 0,            /* 0xc2 */
    1457             :                 {{1, 1},
    1458             :                 {6, 7},
    1459             :                 {0, 0},
    1460             :                 {0, 0}
    1461             :                 }
    1462             :         },
    1463             :         {1, 1, 2, 0,            /* 0xc3 */
    1464             :                 {{0, 1},
    1465             :                 {6, 7},
    1466             :                 {0, 0},
    1467             :                 {0, 0}
    1468             :                 }
    1469             :         },
    1470             :         {0, 1, 2, 0,            /* 0xc4 */
    1471             :                 {{2, 2},
    1472             :                 {6, 7},
    1473             :                 {0, 0},
    1474             :                 {0, 0}
    1475             :                 }
    1476             :         },
    1477             :         {1, 1, 3, 0,            /* 0xc5 */
    1478             :                 {{0, 0},
    1479             :                 {2, 2},
    1480             :                 {6, 7},
    1481             :                 {0, 0}
    1482             :                 }
    1483             :         },
    1484             :         {0, 1, 2, 0,            /* 0xc6 */
    1485             :                 {{1, 2},
    1486             :                 {6, 7},
    1487             :                 {0, 0},
    1488             :                 {0, 0}
    1489             :                 }
    1490             :         },
    1491             :         {1, 1, 2, 0,            /* 0xc7 */
    1492             :                 {{0, 2},
    1493             :                 {6, 7},
    1494             :                 {0, 0},
    1495             :                 {0, 0}
    1496             :                 }
    1497             :         },
    1498             :         {0, 1, 2, 0,            /* 0xc8 */
    1499             :                 {{3, 3},
    1500             :                 {6, 7},
    1501             :                 {0, 0},
    1502             :                 {0, 0}
    1503             :                 }
    1504             :         },
    1505             :         {1, 1, 3, 0,            /* 0xc9 */
    1506             :                 {{0, 0},
    1507             :                 {3, 3},
    1508             :                 {6, 7},
    1509             :                 {0, 0}
    1510             :                 }
    1511             :         },
    1512             :         {0, 1, 3, 0,            /* 0xca */
    1513             :                 {{1, 1},
    1514             :                 {3, 3},
    1515             :                 {6, 7},
    1516             :                 {0, 0}
    1517             :                 }
    1518             :         },
    1519             :         {1, 1, 3, 0,            /* 0xcb */
    1520             :                 {{0, 1},
    1521             :                 {3, 3},
    1522             :                 {6, 7},
    1523             :                 {0, 0}
    1524             :                 }
    1525             :         },
    1526             :         {0, 1, 2, 0,            /* 0xcc */
    1527             :                 {{2, 3},
    1528             :                 {6, 7},
    1529             :                 {0, 0},
    1530             :                 {0, 0}
    1531             :                 }
    1532             :         },
    1533             :         {1, 1, 3, 0,            /* 0xcd */
    1534             :                 {{0, 0},
    1535             :                 {2, 3},
    1536             :                 {6, 7},
    1537             :                 {0, 0}
    1538             :                 }
    1539             :         },
    1540             :         {0, 1, 2, 0,            /* 0xce */
    1541             :                 {{1, 3},
    1542             :                 {6, 7},
    1543             :                 {0, 0},
    1544             :                 {0, 0}
    1545             :                 }
    1546             :         },
    1547             :         {1, 1, 2, 0,            /* 0xcf */
    1548             :                 {{0, 3},
    1549             :                 {6, 7},
    1550             :                 {0, 0},
    1551             :                 {0, 0}
    1552             :                 }
    1553             :         },
    1554             :         {0, 1, 2, 0,            /* 0xd0 */
    1555             :                 {{4, 4},
    1556             :                 {6, 7},
    1557             :                 {0, 0},
    1558             :                 {0, 0}
    1559             :                 }
    1560             :         },
    1561             :         {1, 1, 3, 0,            /* 0xd1 */
    1562             :                 {{0, 0},
    1563             :                 {4, 4},
    1564             :                 {6, 7},
    1565             :                 {0, 0}
    1566             :                 }
    1567             :         },
    1568             :         {0, 1, 3, 0,            /* 0xd2 */
    1569             :                 {{1, 1},
    1570             :                 {4, 4},
    1571             :                 {6, 7},
    1572             :                 {0, 0}
    1573             :                 }
    1574             :         },
    1575             :         {1, 1, 3, 0,            /* 0xd3 */
    1576             :                 {{0, 1},
    1577             :                 {4, 4},
    1578             :                 {6, 7},
    1579             :                 {0, 0}
    1580             :                 }
    1581             :         },
    1582             :         {0, 1, 3, 0,            /* 0xd4 */
    1583             :                 {{2, 2},
    1584             :                 {4, 4},
    1585             :                 {6, 7},
    1586             :                 {0, 0}
    1587             :                 }
    1588             :         },
    1589             :         {1, 1, 4, 0,            /* 0xd5 */
    1590             :                 {{0, 0},
    1591             :                 {2, 2},
    1592             :                 {4, 4},
    1593             :                 {6, 7}
    1594             :                 }
    1595             :         },
    1596             :         {0, 1, 3, 0,            /* 0xd6 */
    1597             :                 {{1, 2},
    1598             :                 {4, 4},
    1599             :                 {6, 7},
    1600             :                 {0, 0}
    1601             :                 }
    1602             :         },
    1603             :         {1, 1, 3, 0,            /* 0xd7 */
    1604             :                 {{0, 2},
    1605             :                 {4, 4},
    1606             :                 {6, 7},
    1607             :                 {0, 0}
    1608             :                 }
    1609             :         },
    1610             :         {0, 1, 2, 0,            /* 0xd8 */
    1611             :                 {{3, 4},
    1612             :                 {6, 7},
    1613             :                 {0, 0},
    1614             :                 {0, 0}
    1615             :                 }
    1616             :         },
    1617             :         {1, 1, 3, 0,            /* 0xd9 */
    1618             :                 {{0, 0},
    1619             :                 {3, 4},
    1620             :                 {6, 7},
    1621             :                 {0, 0}
    1622             :                 }
    1623             :         },
    1624             :         {0, 1, 3, 0,            /* 0xda */
    1625             :                 {{1, 1},
    1626             :                 {3, 4},
    1627             :                 {6, 7},
    1628             :                 {0, 0}
    1629             :                 }
    1630             :         },
    1631             :         {1, 1, 3, 0,            /* 0xdb */
    1632             :                 {{0, 1},
    1633             :                 {3, 4},
    1634             :                 {6, 7},
    1635             :                 {0, 0}
    1636             :                 }
    1637             :         },
    1638             :         {0, 1, 2, 0,            /* 0xdc */
    1639             :                 {{2, 4},
    1640             :                 {6, 7},
    1641             :                 {0, 0},
    1642             :                 {0, 0}
    1643             :                 }
    1644             :         },
    1645             :         {1, 1, 3, 0,            /* 0xdd */
    1646             :                 {{0, 0},
    1647             :                 {2, 4},
    1648             :                 {6, 7},
    1649             :                 {0, 0}
    1650             :                 }
    1651             :         },
    1652             :         {0, 1, 2, 0,            /* 0xde */
    1653             :                 {{1, 4},
    1654             :                 {6, 7},
    1655             :                 {0, 0},
    1656             :                 {0, 0}
    1657             :                 }
    1658             :         },
    1659             :         {1, 1, 2, 0,            /* 0xdf */
    1660             :                 {{0, 4},
    1661             :                 {6, 7},
    1662             :                 {0, 0},
    1663             :                 {0, 0}
    1664             :                 }
    1665             :         },
    1666             :         {0, 1, 1, 0,            /* 0xe0 */
    1667             :                 {{5, 7},
    1668             :                 {0, 0},
    1669             :                 {0, 0},
    1670             :                 {0, 0}
    1671             :                 }
    1672             :         },
    1673             :         {1, 1, 2, 0,            /* 0xe1 */
    1674             :                 {{0, 0},
    1675             :                 {5, 7},
    1676             :                 {0, 0},
    1677             :                 {0, 0}
    1678             :                 }
    1679             :         },
    1680             :         {0, 1, 2, 0,            /* 0xe2 */
    1681             :                 {{1, 1},
    1682             :                 {5, 7},
    1683             :                 {0, 0},
    1684             :                 {0, 0}
    1685             :                 }
    1686             :         },
    1687             :         {1, 1, 2, 0,            /* 0xe3 */
    1688             :                 {{0, 1},
    1689             :                 {5, 7},
    1690             :                 {0, 0},
    1691             :                 {0, 0}
    1692             :                 }
    1693             :         },
    1694             :         {0, 1, 2, 0,            /* 0xe4 */
    1695             :                 {{2, 2},
    1696             :                 {5, 7},
    1697             :                 {0, 0},
    1698             :                 {0, 0}
    1699             :                 }
    1700             :         },
    1701             :         {1, 1, 3, 0,            /* 0xe5 */
    1702             :                 {{0, 0},
    1703             :                 {2, 2},
    1704             :                 {5, 7},
    1705             :                 {0, 0}
    1706             :                 }
    1707             :         },
    1708             :         {0, 1, 2, 0,            /* 0xe6 */
    1709             :                 {{1, 2},
    1710             :                 {5, 7},
    1711             :                 {0, 0},
    1712             :                 {0, 0}
    1713             :                 }
    1714             :         },
    1715             :         {1, 1, 2, 0,            /* 0xe7 */
    1716             :                 {{0, 2},
    1717             :                 {5, 7},
    1718             :                 {0, 0},
    1719             :                 {0, 0}
    1720             :                 }
    1721             :         },
    1722             :         {0, 1, 2, 0,            /* 0xe8 */
    1723             :                 {{3, 3},
    1724             :                 {5, 7},
    1725             :                 {0, 0},
    1726             :                 {0, 0}
    1727             :                 }
    1728             :         },
    1729             :         {1, 1, 3, 0,            /* 0xe9 */
    1730             :                 {{0, 0},
    1731             :                 {3, 3},
    1732             :                 {5, 7},
    1733             :                 {0, 0}
    1734             :                 }
    1735             :         },
    1736             :         {0, 1, 3, 0,            /* 0xea */
    1737             :                 {{1, 1},
    1738             :                 {3, 3},
    1739             :                 {5, 7},
    1740             :                 {0, 0}
    1741             :                 }
    1742             :         },
    1743             :         {1, 1, 3, 0,            /* 0xeb */
    1744             :                 {{0, 1},
    1745             :                 {3, 3},
    1746             :                 {5, 7},
    1747             :                 {0, 0}
    1748             :                 }
    1749             :         },
    1750             :         {0, 1, 2, 0,            /* 0xec */
    1751             :                 {{2, 3},
    1752             :                 {5, 7},
    1753             :                 {0, 0},
    1754             :                 {0, 0}
    1755             :                 }
    1756             :         },
    1757             :         {1, 1, 3, 0,            /* 0xed */
    1758             :                 {{0, 0},
    1759             :                 {2, 3},
    1760             :                 {5, 7},
    1761             :                 {0, 0}
    1762             :                 }
    1763             :         },
    1764             :         {0, 1, 2, 0,            /* 0xee */
    1765             :                 {{1, 3},
    1766             :                 {5, 7},
    1767             :                 {0, 0},
    1768             :                 {0, 0}
    1769             :                 }
    1770             :         },
    1771             :         {1, 1, 2, 0,            /* 0xef */
    1772             :                 {{0, 3},
    1773             :                 {5, 7},
    1774             :                 {0, 0},
    1775             :                 {0, 0}
    1776             :                 }
    1777             :         },
    1778             :         {0, 1, 1, 0,            /* 0xf0 */
    1779             :                 {{4, 7},
    1780             :                 {0, 0},
    1781             :                 {0, 0},
    1782             :                 {0, 0}
    1783             :                 }
    1784             :         },
    1785             :         {1, 1, 2, 0,            /* 0xf1 */
    1786             :                 {{0, 0},
    1787             :                 {4, 7},
    1788             :                 {0, 0},
    1789             :                 {0, 0}
    1790             :                 }
    1791             :         },
    1792             :         {0, 1, 2, 0,            /* 0xf2 */
    1793             :                 {{1, 1},
    1794             :                 {4, 7},
    1795             :                 {0, 0},
    1796             :                 {0, 0}
    1797             :                 }
    1798             :         },
    1799             :         {1, 1, 2, 0,            /* 0xf3 */
    1800             :                 {{0, 1},
    1801             :                 {4, 7},
    1802             :                 {0, 0},
    1803             :                 {0, 0}
    1804             :                 }
    1805             :         },
    1806             :         {0, 1, 2, 0,            /* 0xf4 */
    1807             :                 {{2, 2},
    1808             :                 {4, 7},
    1809             :                 {0, 0},
    1810             :                 {0, 0}
    1811             :                 }
    1812             :         },
    1813             :         {1, 1, 3, 0,            /* 0xf5 */
    1814             :                 {{0, 0},
    1815             :                 {2, 2},
    1816             :                 {4, 7},
    1817             :                 {0, 0}
    1818             :                 }
    1819             :         },
    1820             :         {0, 1, 2, 0,            /* 0xf6 */
    1821             :                 {{1, 2},
    1822             :                 {4, 7},
    1823             :                 {0, 0},
    1824             :                 {0, 0}
    1825             :                 }
    1826             :         },
    1827             :         {1, 1, 2, 0,            /* 0xf7 */
    1828             :                 {{0, 2},
    1829             :                 {4, 7},
    1830             :                 {0, 0},
    1831             :                 {0, 0}
    1832             :                 }
    1833             :         },
    1834             :         {0, 1, 1, 0,            /* 0xf8 */
    1835             :                 {{3, 7},
    1836             :                 {0, 0},
    1837             :                 {0, 0},
    1838             :                 {0, 0}
    1839             :                 }
    1840             :         },
    1841             :         {1, 1, 2, 0,            /* 0xf9 */
    1842             :                 {{0, 0},
    1843             :                 {3, 7},
    1844             :                 {0, 0},
    1845             :                 {0, 0}
    1846             :                 }
    1847             :         },
    1848             :         {0, 1, 2, 0,            /* 0xfa */
    1849             :                 {{1, 1},
    1850             :                 {3, 7},
    1851             :                 {0, 0},
    1852             :                 {0, 0}
    1853             :                 }
    1854             :         },
    1855             :         {1, 1, 2, 0,            /* 0xfb */
    1856             :                 {{0, 1},
    1857             :                 {3, 7},
    1858             :                 {0, 0},
    1859             :                 {0, 0}
    1860             :                 }
    1861             :         },
    1862             :         {0, 1, 1, 0,            /* 0xfc */
    1863             :                 {{2, 7},
    1864             :                 {0, 0},
    1865             :                 {0, 0},
    1866             :                 {0, 0}
    1867             :                 }
    1868             :         },
    1869             :         {1, 1, 2, 0,            /* 0xfd */
    1870             :                 {{0, 0},
    1871             :                 {2, 7},
    1872             :                 {0, 0},
    1873             :                 {0, 0}
    1874             :                 }
    1875             :         },
    1876             :         {0, 1, 1, 0,            /* 0xfe */
    1877             :                 {{1, 7},
    1878             :                 {0, 0},
    1879             :                 {0, 0},
    1880             :                 {0, 0}
    1881             :                 }
    1882             :         },
    1883             :         {1, 1, 1, 0,            /* 0xff */
    1884             :                 {{0, 7},
    1885             :                 {0, 0},
    1886             :                 {0, 0},
    1887             :                 {0, 0}
    1888             :                 }
    1889             :         }
    1890             : };
    1891             : 
    1892             : 
    1893             : int
    1894           0 : sctp_is_address_in_scope(struct sctp_ifa *ifa,
    1895             :                          struct sctp_scoping *scope,
    1896             :                          int do_update)
    1897             : {
    1898           0 :         if ((scope->loopback_scope == 0) &&
    1899           0 :             (ifa->ifn_p) && SCTP_IFN_IS_IFT_LOOP(ifa->ifn_p)) {
    1900             :                 /*
    1901             :                  * skip loopback if not in scope *
    1902             :                  */
    1903           0 :                 return (0);
    1904             :         }
    1905           0 :         switch (ifa->address.sa.sa_family) {
    1906             : #ifdef INET
    1907             :         case AF_INET:
    1908             :                 if (scope->ipv4_addr_legal) {
    1909             :                         struct sockaddr_in *sin;
    1910             : 
    1911             :                         sin = &ifa->address.sin;
    1912             :                         if (sin->sin_addr.s_addr == 0) {
    1913             :                                 /* not in scope , unspecified */
    1914             :                                 return (0);
    1915             :                         }
    1916             :                         if ((scope->ipv4_local_scope == 0) &&
    1917             :                             (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
    1918             :                                 /* private address not in scope */
    1919             :                                 return (0);
    1920             :                         }
    1921             :                 } else {
    1922             :                         return (0);
    1923             :                 }
    1924             :                 break;
    1925             : #endif
    1926             : #ifdef INET6
    1927             :         case AF_INET6:
    1928             :                 if (scope->ipv6_addr_legal) {
    1929             :                         struct sockaddr_in6 *sin6;
    1930             : 
    1931             : #if !defined(__Panda__)
    1932             :                         /* Must update the flags,  bummer, which
    1933             :                          * means any IFA locks must now be applied HERE <->
    1934             :                          */
    1935             :                         if (do_update) {
    1936             :                                 sctp_gather_internal_ifa_flags(ifa);
    1937             :                         }
    1938             : #endif
    1939             :                         if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
    1940             :                                 return (0);
    1941             :                         }
    1942             :                         /* ok to use deprecated addresses? */
    1943             :                         sin6 = &ifa->address.sin6;
    1944             :                         if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
    1945             :                                 /* skip unspecifed addresses */
    1946             :                                 return (0);
    1947             :                         }
    1948             :                         if (            /* (local_scope == 0) && */
    1949             :                             (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))) {
    1950             :                                 return (0);
    1951             :                         }
    1952             :                         if ((scope->site_scope == 0) &&
    1953             :                             (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) {
    1954             :                                 return (0);
    1955             :                         }
    1956             :                 } else {
    1957             :                         return (0);
    1958             :                 }
    1959             :                 break;
    1960             : #endif
    1961             : #if defined(__Userspace__)
    1962             :         case AF_CONN:
    1963           0 :                 if (!scope->conn_addr_legal) {
    1964           0 :                         return (0);
    1965             :                 }
    1966           0 :                 break;
    1967             : #endif
    1968             :         default:
    1969           0 :                 return (0);
    1970             :         }
    1971           0 :         return (1);
    1972             : }
    1973             : 
    1974             : static struct mbuf *
    1975           0 : sctp_add_addr_to_mbuf(struct mbuf *m, struct sctp_ifa *ifa, uint16_t *len)
    1976             : {
    1977             : #if defined(INET) || defined(INET6)
    1978             :         struct sctp_paramhdr *parmh;
    1979             :         struct mbuf *mret;
    1980             :         uint16_t plen;
    1981             : #endif
    1982             : 
    1983           0 :         switch (ifa->address.sa.sa_family) {
    1984             : #ifdef INET
    1985             :         case AF_INET:
    1986             :                 plen = (uint16_t)sizeof(struct sctp_ipv4addr_param);
    1987             :                 break;
    1988             : #endif
    1989             : #ifdef INET6
    1990             :         case AF_INET6:
    1991             :                 plen = (uint16_t)sizeof(struct sctp_ipv6addr_param);
    1992             :                 break;
    1993             : #endif
    1994             :         default:
    1995           0 :                 return (m);
    1996             :         }
    1997             : #if defined(INET) || defined(INET6)
    1998             :         if (M_TRAILINGSPACE(m) >= plen) {
    1999             :                 /* easy side we just drop it on the end */
    2000             :                 parmh = (struct sctp_paramhdr *)(SCTP_BUF_AT(m, SCTP_BUF_LEN(m)));
    2001             :                 mret = m;
    2002             :         } else {
    2003             :                 /* Need more space */
    2004             :                 mret = m;
    2005             :                 while (SCTP_BUF_NEXT(mret) != NULL) {
    2006             :                         mret = SCTP_BUF_NEXT(mret);
    2007             :                 }
    2008             :                 SCTP_BUF_NEXT(mret) = sctp_get_mbuf_for_msg(plen, 0, M_NOWAIT, 1, MT_DATA);
    2009             :                 if (SCTP_BUF_NEXT(mret) == NULL) {
    2010             :                         /* We are hosed, can't add more addresses */
    2011             :                         return (m);
    2012             :                 }
    2013             :                 mret = SCTP_BUF_NEXT(mret);
    2014             :                 parmh = mtod(mret, struct sctp_paramhdr *);
    2015             :         }
    2016             :         /* now add the parameter */
    2017             :         switch (ifa->address.sa.sa_family) {
    2018             : #ifdef INET
    2019             :         case AF_INET:
    2020             :         {
    2021             :                 struct sctp_ipv4addr_param *ipv4p;
    2022             :                 struct sockaddr_in *sin;
    2023             : 
    2024             :                 sin = &ifa->address.sin;
    2025             :                 ipv4p = (struct sctp_ipv4addr_param *)parmh;
    2026             :                 parmh->param_type = htons(SCTP_IPV4_ADDRESS);
    2027             :                 parmh->param_length = htons(plen);
    2028             :                 ipv4p->addr = sin->sin_addr.s_addr;
    2029             :                 SCTP_BUF_LEN(mret) += plen;
    2030             :                 break;
    2031             :         }
    2032             : #endif
    2033             : #ifdef INET6
    2034             :         case AF_INET6:
    2035             :         {
    2036             :                 struct sctp_ipv6addr_param *ipv6p;
    2037             :                 struct sockaddr_in6 *sin6;
    2038             : 
    2039             :                 sin6 = &ifa->address.sin6;
    2040             :                 ipv6p = (struct sctp_ipv6addr_param *)parmh;
    2041             :                 parmh->param_type = htons(SCTP_IPV6_ADDRESS);
    2042             :                 parmh->param_length = htons(plen);
    2043             :                 memcpy(ipv6p->addr, &sin6->sin6_addr,
    2044             :                     sizeof(ipv6p->addr));
    2045             : #if defined(SCTP_EMBEDDED_V6_SCOPE)
    2046             :                 /* clear embedded scope in the address */
    2047             :                 in6_clearscope((struct in6_addr *)ipv6p->addr);
    2048             : #endif
    2049             :                 SCTP_BUF_LEN(mret) += plen;
    2050             :                 break;
    2051             :         }
    2052             : #endif
    2053             :         default:
    2054             :                 return (m);
    2055             :         }
    2056             :         if (len != NULL) {
    2057             :                 *len += plen;
    2058             :         }
    2059             :         return (mret);
    2060             : #endif
    2061             : }
    2062             : 
    2063             : 
    2064             : struct mbuf *
    2065           0 : sctp_add_addresses_to_i_ia(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
    2066             :                            struct sctp_scoping *scope,
    2067             :                            struct mbuf *m_at, int cnt_inits_to,
    2068             :                            uint16_t *padding_len, uint16_t *chunk_len)
    2069             : {
    2070           0 :         struct sctp_vrf *vrf = NULL;
    2071           0 :         int cnt, limit_out = 0, total_count;
    2072             :         uint32_t vrf_id;
    2073             : 
    2074           0 :         vrf_id = inp->def_vrf_id;
    2075           0 :         SCTP_IPI_ADDR_RLOCK();
    2076           0 :         vrf = sctp_find_vrf(vrf_id);
    2077           0 :         if (vrf == NULL) {
    2078           0 :                 SCTP_IPI_ADDR_RUNLOCK();
    2079           0 :                 return (m_at);
    2080             :         }
    2081           0 :         if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
    2082             :                 struct sctp_ifa *sctp_ifap;
    2083             :                 struct sctp_ifn *sctp_ifnp;
    2084             : 
    2085           0 :                 cnt = cnt_inits_to;
    2086           0 :                 if (vrf->total_ifa_count > SCTP_COUNT_LIMIT) {
    2087           0 :                         limit_out = 1;
    2088           0 :                         cnt = SCTP_ADDRESS_LIMIT;
    2089           0 :                         goto skip_count;
    2090             :                 }
    2091           0 :                 LIST_FOREACH(sctp_ifnp, &vrf->ifnlist, next_ifn) {
    2092           0 :                         if ((scope->loopback_scope == 0) &&
    2093           0 :                             SCTP_IFN_IS_IFT_LOOP(sctp_ifnp)) {
    2094             :                                 /*
    2095             :                                  * Skip loopback devices if loopback_scope
    2096             :                                  * not set
    2097             :                                  */
    2098           0 :                                 continue;
    2099             :                         }
    2100           0 :                         LIST_FOREACH(sctp_ifap, &sctp_ifnp->ifalist, next_ifa) {
    2101             : #if defined(__FreeBSD__)
    2102             : #ifdef INET
    2103             :                                 if ((sctp_ifap->address.sa.sa_family == AF_INET) &&
    2104             :                                     (prison_check_ip4(inp->ip_inp.inp.inp_cred,
    2105             :                                                       &sctp_ifap->address.sin.sin_addr) != 0)) {
    2106             :                                         continue;
    2107             :                                 }
    2108             : #endif
    2109             : #ifdef INET6
    2110             :                                 if ((sctp_ifap->address.sa.sa_family == AF_INET6) &&
    2111             :                                     (prison_check_ip6(inp->ip_inp.inp.inp_cred,
    2112             :                                                       &sctp_ifap->address.sin6.sin6_addr) != 0)) {
    2113             :                                         continue;
    2114             :                                 }
    2115             : #endif
    2116             : #endif
    2117           0 :                                 if (sctp_is_addr_restricted(stcb, sctp_ifap)) {
    2118           0 :                                         continue;
    2119             :                                 }
    2120             : #if defined(__Userspace__)
    2121           0 :                                 if (sctp_ifap->address.sa.sa_family == AF_CONN) {
    2122           0 :                                         continue;
    2123             :                                 }
    2124             : #endif
    2125           0 :                                 if (sctp_is_address_in_scope(sctp_ifap, scope, 1) == 0) {
    2126           0 :                                         continue;
    2127             :                                 }
    2128           0 :                                 cnt++;
    2129           0 :                                 if (cnt > SCTP_ADDRESS_LIMIT) {
    2130           0 :                                         break;
    2131             :                                 }
    2132             :                         }
    2133           0 :                         if (cnt > SCTP_ADDRESS_LIMIT) {
    2134           0 :                                 break;
    2135             :                         }
    2136             :                 }
    2137             :         skip_count:
    2138           0 :                 if (cnt > 1) {
    2139           0 :                         total_count = 0;
    2140           0 :                         LIST_FOREACH(sctp_ifnp, &vrf->ifnlist, next_ifn) {
    2141           0 :                                 cnt = 0;
    2142           0 :                                 if ((scope->loopback_scope == 0) &&
    2143           0 :                                     SCTP_IFN_IS_IFT_LOOP(sctp_ifnp)) {
    2144             :                                         /*
    2145             :                                          * Skip loopback devices if
    2146             :                                          * loopback_scope not set
    2147             :                                          */
    2148           0 :                                         continue;
    2149             :                                 }
    2150           0 :                                 LIST_FOREACH(sctp_ifap, &sctp_ifnp->ifalist, next_ifa) {
    2151             : #if defined(__FreeBSD__)
    2152             : #ifdef INET
    2153             :                                         if ((sctp_ifap->address.sa.sa_family == AF_INET) &&
    2154             :                                             (prison_check_ip4(inp->ip_inp.inp.inp_cred,
    2155             :                                                               &sctp_ifap->address.sin.sin_addr) != 0)) {
    2156             :                                                 continue;
    2157             :                                         }
    2158             : #endif
    2159             : #ifdef INET6
    2160             :                                         if ((sctp_ifap->address.sa.sa_family == AF_INET6) &&
    2161             :                                             (prison_check_ip6(inp->ip_inp.inp.inp_cred,
    2162             :                                                               &sctp_ifap->address.sin6.sin6_addr) != 0)) {
    2163             :                                                 continue;
    2164             :                                         }
    2165             : #endif
    2166             : #endif
    2167           0 :                                         if (sctp_is_addr_restricted(stcb, sctp_ifap)) {
    2168           0 :                                                 continue;
    2169             :                                         }
    2170             : #if defined(__Userspace__)
    2171           0 :                                         if (sctp_ifap->address.sa.sa_family == AF_CONN) {
    2172           0 :                                                 continue;
    2173             :                                         }
    2174             : #endif
    2175           0 :                                         if (sctp_is_address_in_scope(sctp_ifap,
    2176             :                                                                      scope, 0) == 0) {
    2177           0 :                                                 continue;
    2178             :                                         }
    2179           0 :                                         if ((chunk_len != NULL) &&
    2180           0 :                                             (padding_len != NULL) &&
    2181           0 :                                             (*padding_len > 0)) {
    2182           0 :                                                 memset(mtod(m_at, caddr_t) + *chunk_len, 0, *padding_len);
    2183           0 :                                                 SCTP_BUF_LEN(m_at) += *padding_len;
    2184           0 :                                                 *chunk_len += *padding_len;
    2185           0 :                                                 *padding_len = 0;
    2186             :                                         }
    2187           0 :                                         m_at = sctp_add_addr_to_mbuf(m_at, sctp_ifap, chunk_len);
    2188           0 :                                         if (limit_out) {
    2189           0 :                                                 cnt++;
    2190           0 :                                                 total_count++;
    2191           0 :                                                 if (cnt >= 2) {
    2192             :                                                         /* two from each address */
    2193           0 :                                                         break;
    2194             :                                                 }
    2195           0 :                                                 if (total_count > SCTP_ADDRESS_LIMIT) {
    2196             :                                                         /* No more addresses */
    2197           0 :                                                         break;
    2198             :                                                 }
    2199             :                                         }
    2200             :                                 }
    2201             :                         }
    2202             :                 }
    2203             :         } else {
    2204             :                 struct sctp_laddr *laddr;
    2205             : 
    2206           0 :                 cnt = cnt_inits_to;
    2207             :                 /* First, how many ? */
    2208           0 :                 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
    2209           0 :                         if (laddr->ifa == NULL) {
    2210           0 :                                 continue;
    2211             :                         }
    2212           0 :                         if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED)
    2213             :                                 /* Address being deleted by the system, dont
    2214             :                                  * list.
    2215             :                                  */
    2216           0 :                                 continue;
    2217           0 :                         if (laddr->action == SCTP_DEL_IP_ADDRESS) {
    2218             :                                 /* Address being deleted on this ep
    2219             :                                  * don't list.
    2220             :                                  */
    2221           0 :                                 continue;
    2222             :                         }
    2223             : #if defined(__Userspace__)
    2224           0 :                         if (laddr->ifa->address.sa.sa_family == AF_CONN) {
    2225           0 :                                 continue;
    2226             :                         }
    2227             : #endif
    2228           0 :                         if (sctp_is_address_in_scope(laddr->ifa,
    2229             :                                                      scope, 1) == 0) {
    2230           0 :                                 continue;
    2231             :                         }
    2232           0 :                         cnt++;
    2233             :                 }
    2234             :                 /*
    2235             :                  * To get through a NAT we only list addresses if we have
    2236             :                  * more than one. That way if you just bind a single address
    2237             :                  * we let the source of the init dictate our address.
    2238             :                  */
    2239           0 :                 if (cnt > 1) {
    2240           0 :                         cnt = cnt_inits_to;
    2241           0 :                         LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
    2242           0 :                                 if (laddr->ifa == NULL) {
    2243           0 :                                         continue;
    2244             :                                 }
    2245           0 :                                 if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED) {
    2246           0 :                                         continue;
    2247             :                                 }
    2248             : #if defined(__Userspace__)
    2249           0 :                                 if (laddr->ifa->address.sa.sa_family == AF_CONN) {
    2250           0 :                                         continue;
    2251             :                                 }
    2252             : #endif
    2253           0 :                                 if (sctp_is_address_in_scope(laddr->ifa,
    2254             :                                                              scope, 0) == 0) {
    2255           0 :                                         continue;
    2256             :                                 }
    2257           0 :                                 if ((chunk_len != NULL) &&
    2258           0 :                                     (padding_len != NULL) &&
    2259           0 :                                     (*padding_len > 0)) {
    2260           0 :                                         memset(mtod(m_at, caddr_t) + *chunk_len, 0, *padding_len);
    2261           0 :                                         SCTP_BUF_LEN(m_at) += *padding_len;
    2262           0 :                                         *chunk_len += *padding_len;
    2263           0 :                                         *padding_len = 0;
    2264             :                                 }
    2265           0 :                                 m_at = sctp_add_addr_to_mbuf(m_at, laddr->ifa, chunk_len);
    2266           0 :                                 cnt++;
    2267           0 :                                 if (cnt >= SCTP_ADDRESS_LIMIT) {
    2268           0 :                                         break;
    2269             :                                 }
    2270             :                         }
    2271             :                 }
    2272             :         }
    2273           0 :         SCTP_IPI_ADDR_RUNLOCK();
    2274           0 :         return (m_at);
    2275             : }
    2276             : 
    2277             : static struct sctp_ifa *
    2278           0 : sctp_is_ifa_addr_preferred(struct sctp_ifa *ifa,
    2279             :                            uint8_t dest_is_loop,
    2280             :                            uint8_t dest_is_priv,
    2281             :                            sa_family_t fam)
    2282             : {
    2283           0 :         uint8_t dest_is_global = 0;
    2284             :         /* dest_is_priv is true if destination is a private address */
    2285             :         /* dest_is_loop is true if destination is a loopback addresses */
    2286             : 
    2287             :         /**
    2288             :          * Here we determine if its a preferred address. A preferred address
    2289             :          * means it is the same scope or higher scope then the destination.
    2290             :          * L = loopback, P = private, G = global
    2291             :          * -----------------------------------------
    2292             :          *    src    |  dest | result
    2293             :          *  ----------------------------------------
    2294             :          *     L     |    L  |    yes
    2295             :          *  -----------------------------------------
    2296             :          *     P     |    L  |    yes-v4 no-v6
    2297             :          *  -----------------------------------------
    2298             :          *     G     |    L  |    yes-v4 no-v6
    2299             :          *  -----------------------------------------
    2300             :          *     L     |    P  |    no
    2301             :          *  -----------------------------------------
    2302             :          *     P     |    P  |    yes
    2303             :          *  -----------------------------------------
    2304             :          *     G     |    P  |    no
    2305             :          *   -----------------------------------------
    2306             :          *     L     |    G  |    no
    2307             :          *   -----------------------------------------
    2308             :          *     P     |    G  |    no
    2309             :          *    -----------------------------------------
    2310             :          *     G     |    G  |    yes
    2311             :          *    -----------------------------------------
    2312             :          */
    2313             : 
    2314           0 :         if (ifa->address.sa.sa_family != fam) {
    2315             :                 /* forget mis-matched family */
    2316           0 :                 return (NULL);
    2317             :         }
    2318           0 :         if ((dest_is_priv == 0) && (dest_is_loop == 0)) {
    2319           0 :                 dest_is_global = 1;
    2320             :         }
    2321           0 :         SCTPDBG(SCTP_DEBUG_OUTPUT2, "Is destination preferred:");
    2322           0 :         SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, &ifa->address.sa);
    2323             :         /* Ok the address may be ok */
    2324             : #ifdef INET6
    2325             :         if (fam == AF_INET6) {
    2326             :                 /* ok to use deprecated addresses? no lets not! */
    2327             :                 if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
    2328             :                         SCTPDBG(SCTP_DEBUG_OUTPUT3, "NO:1\n");
    2329             :                         return (NULL);
    2330             :                 }
    2331             :                 if (ifa->src_is_priv && !ifa->src_is_loop) {
    2332             :                         if (dest_is_loop) {
    2333             :                                 SCTPDBG(SCTP_DEBUG_OUTPUT3, "NO:2\n");
    2334             :                                 return (NULL);
    2335             :                         }
    2336             :                 }
    2337             :                 if (ifa->src_is_glob) {
    2338             :                         if (dest_is_loop) {
    2339             :                                 SCTPDBG(SCTP_DEBUG_OUTPUT3, "NO:3\n");
    2340             :                                 return (NULL);
    2341             :                         }
    2342             :                 }
    2343             :         }
    2344             : #endif
    2345             :         /* Now that we know what is what, implement or table
    2346             :          * this could in theory be done slicker (it used to be), but this
    2347             :          * is straightforward and easier to validate :-)
    2348             :          */
    2349           0 :         SCTPDBG(SCTP_DEBUG_OUTPUT3, "src_loop:%d src_priv:%d src_glob:%d\n",
    2350             :                 ifa->src_is_loop, ifa->src_is_priv, ifa->src_is_glob);
    2351           0 :         SCTPDBG(SCTP_DEBUG_OUTPUT3, "dest_loop:%d dest_priv:%d dest_glob:%d\n",
    2352             :                 dest_is_loop, dest_is_priv, dest_is_global);
    2353             : 
    2354           0 :         if ((ifa->src_is_loop) && (dest_is_priv)) {
    2355           0 :                 SCTPDBG(SCTP_DEBUG_OUTPUT3, "NO:4\n");
    2356           0 :                 return (NULL);
    2357             :         }
    2358           0 :         if ((ifa->src_is_glob) && (dest_is_priv)) {
    2359           0 :                 SCTPDBG(SCTP_DEBUG_OUTPUT3, "NO:5\n");
    2360           0 :                 return (NULL);
    2361             :         }
    2362           0 :         if ((ifa->src_is_loop) && (dest_is_global)) {
    2363           0 :                 SCTPDBG(SCTP_DEBUG_OUTPUT3, "NO:6\n");
    2364           0 :                 return (NULL);
    2365             :         }
    2366           0 :         if ((ifa->src_is_priv) && (dest_is_global)) {
    2367           0 :                 SCTPDBG(SCTP_DEBUG_OUTPUT3, "NO:7\n");
    2368           0 :                 return (NULL);
    2369             :         }
    2370           0 :         SCTPDBG(SCTP_DEBUG_OUTPUT3, "YES\n");
    2371             :         /* its a preferred address */
    2372           0 :         return (ifa);
    2373             : }
    2374             : 
    2375             : static struct sctp_ifa *
    2376           0 : sctp_is_ifa_addr_acceptable(struct sctp_ifa *ifa,
    2377             :                             uint8_t dest_is_loop,
    2378             :                             uint8_t dest_is_priv,
    2379             :                             sa_family_t fam)
    2380             : {
    2381           0 :         uint8_t dest_is_global = 0;
    2382             : 
    2383             :         /**
    2384             :          * Here we determine if its a acceptable address. A acceptable
    2385             :          * address means it is the same scope or higher scope but we can
    2386             :          * allow for NAT which means its ok to have a global dest and a
    2387             :          * private src.
    2388             :          *
    2389             :          * L = loopback, P = private, G = global
    2390             :          * -----------------------------------------
    2391             :          *  src    |  dest | result
    2392             :          * -----------------------------------------
    2393             :          *   L     |   L   |    yes
    2394             :          *  -----------------------------------------
    2395             :          *   P     |   L   |    yes-v4 no-v6
    2396             :          *  -----------------------------------------
    2397             :          *   G     |   L   |    yes
    2398             :          * -----------------------------------------
    2399             :          *   L     |   P   |    no
    2400             :          * -----------------------------------------
    2401             :          *   P     |   P   |    yes
    2402             :          * -----------------------------------------
    2403             :          *   G     |   P   |    yes - May not work
    2404             :          * -----------------------------------------
    2405             :          *   L     |   G   |    no
    2406             :          * -----------------------------------------
    2407             :          *   P     |   G   |    yes - May not work
    2408             :          * -----------------------------------------
    2409             :          *   G     |   G   |    yes
    2410             :          * -----------------------------------------
    2411             :          */
    2412             : 
    2413           0 :         if (ifa->address.sa.sa_family != fam) {
    2414             :                 /* forget non matching family */
    2415           0 :                 SCTPDBG(SCTP_DEBUG_OUTPUT3, "ifa_fam:%d fam:%d\n",
    2416             :                         ifa->address.sa.sa_family, fam);
    2417           0 :                 return (NULL);
    2418             :         }
    2419             :         /* Ok the address may be ok */
    2420           0 :         SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT3, &ifa->address.sa);
    2421           0 :         SCTPDBG(SCTP_DEBUG_OUTPUT3, "dst_is_loop:%d dest_is_priv:%d\n",
    2422             :                 dest_is_loop, dest_is_priv);
    2423           0 :         if ((dest_is_loop == 0) && (dest_is_priv == 0)) {
    2424           0 :                 dest_is_global = 1;
    2425             :         }
    2426             : #ifdef INET6
    2427             :         if (fam == AF_INET6) {
    2428             :                 /* ok to use deprecated addresses? */
    2429             :                 if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
    2430             :                         return (NULL);
    2431             :                 }
    2432             :                 if (ifa->src_is_priv) {
    2433             :                         /* Special case, linklocal to loop */
    2434             :                         if (dest_is_loop)
    2435             :                                 return (NULL);
    2436             :                 }
    2437             :         }
    2438             : #endif
    2439             :         /*
    2440             :          * Now that we know what is what, implement our table.
    2441             :          * This could in theory be done slicker (it used to be), but this
    2442             :          * is straightforward and easier to validate :-)
    2443             :          */
    2444           0 :         SCTPDBG(SCTP_DEBUG_OUTPUT3, "ifa->src_is_loop:%d dest_is_priv:%d\n",
    2445             :                 ifa->src_is_loop,
    2446             :                 dest_is_priv);
    2447           0 :         if ((ifa->src_is_loop == 1) && (dest_is_priv)) {
    2448           0 :                 return (NULL);
    2449             :         }
    2450           0 :         SCTPDBG(SCTP_DEBUG_OUTPUT3, "ifa->src_is_loop:%d dest_is_glob:%d\n",
    2451             :                 ifa->src_is_loop,
    2452             :                 dest_is_global);
    2453           0 :         if ((ifa->src_is_loop == 1) && (dest_is_global)) {
    2454           0 :                 return (NULL);
    2455             :         }
    2456           0 :         SCTPDBG(SCTP_DEBUG_OUTPUT3, "address is acceptable\n");
    2457             :         /* its an acceptable address */
    2458           0 :         return (ifa);
    2459             : }
    2460             : 
    2461             : int
    2462           0 : sctp_is_addr_restricted(struct sctp_tcb *stcb, struct sctp_ifa *ifa)
    2463             : {
    2464             :         struct sctp_laddr *laddr;
    2465             : 
    2466           0 :         if (stcb == NULL) {
    2467             :                 /* There are no restrictions, no TCB :-) */
    2468           0 :                 return (0);
    2469             :         }
    2470           0 :         LIST_FOREACH(laddr, &stcb->asoc.sctp_restricted_addrs, sctp_nxt_addr) {
    2471           0 :                 if (laddr->ifa == NULL) {
    2472           0 :                         SCTPDBG(SCTP_DEBUG_OUTPUT1, "%s: NULL ifa\n",
    2473             :                                 __FUNCTION__);
    2474           0 :                         continue;
    2475             :                 }
    2476           0 :                 if (laddr->ifa == ifa) {
    2477             :                         /* Yes it is on the list */
    2478           0 :                         return (1);
    2479             :                 }
    2480             :         }
    2481           0 :         return (0);
    2482             : }
    2483             : 
    2484             : 
    2485             : int
    2486           0 : sctp_is_addr_in_ep(struct sctp_inpcb *inp, struct sctp_ifa *ifa)
    2487             : {
    2488             :         struct sctp_laddr *laddr;
    2489             : 
    2490           0 :         if (ifa == NULL)
    2491           0 :                 return (0);
    2492           0 :         LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
    2493           0 :                 if (laddr->ifa == NULL) {
    2494           0 :                         SCTPDBG(SCTP_DEBUG_OUTPUT1, "%s: NULL ifa\n",
    2495             :                                 __FUNCTION__);
    2496           0 :                         continue;
    2497             :                 }
    2498           0 :                 if ((laddr->ifa == ifa) && laddr->action == 0)
    2499             :                         /* same pointer */
    2500           0 :                         return (1);
    2501             :         }
    2502           0 :         return (0);
    2503             : }
    2504             : 
    2505             : 
    2506             : 
    2507             : static struct sctp_ifa *
    2508           0 : sctp_choose_boundspecific_inp(struct sctp_inpcb *inp,
    2509             :                               sctp_route_t *ro,
    2510             :                               uint32_t vrf_id,
    2511             :                               int non_asoc_addr_ok,
    2512             :                               uint8_t dest_is_priv,
    2513             :                               uint8_t dest_is_loop,
    2514             :                               sa_family_t fam)
    2515             : {
    2516             :         struct sctp_laddr *laddr, *starting_point;
    2517             :         void *ifn;
    2518           0 :         int resettotop = 0;
    2519             :         struct sctp_ifn *sctp_ifn;
    2520             :         struct sctp_ifa *sctp_ifa, *sifa;
    2521             :         struct sctp_vrf *vrf;
    2522             :         uint32_t ifn_index;
    2523             : 
    2524           0 :         vrf = sctp_find_vrf(vrf_id);
    2525           0 :         if (vrf == NULL)
    2526           0 :                 return (NULL);
    2527             : 
    2528           0 :         ifn = SCTP_GET_IFN_VOID_FROM_ROUTE(ro);
    2529           0 :         ifn_index = SCTP_GET_IF_INDEX_FROM_ROUTE(ro);
    2530           0 :         sctp_ifn = sctp_find_ifn(ifn, ifn_index);
    2531             :         /*
    2532             :          * first question, is the ifn we will emit on in our list, if so, we
    2533             :          * want such an address. Note that we first looked for a
    2534             :          * preferred address.
    2535             :          */
    2536           0 :         if (sctp_ifn) {
    2537             :                 /* is a preferred one on the interface we route out? */
    2538           0 :                 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
    2539             : #if defined(__FreeBSD__)
    2540             : #ifdef INET
    2541             :                         if ((sctp_ifa->address.sa.sa_family == AF_INET) &&
    2542             :                             (prison_check_ip4(inp->ip_inp.inp.inp_cred,
    2543             :                                               &sctp_ifa->address.sin.sin_addr) != 0)) {
    2544             :                                 continue;
    2545             :                         }
    2546             : #endif
    2547             : #ifdef INET6
    2548             :                         if ((sctp_ifa->address.sa.sa_family == AF_INET6) &&
    2549             :                             (prison_check_ip6(inp->ip_inp.inp.inp_cred,
    2550             :                                               &sctp_ifa->address.sin6.sin6_addr) != 0)) {
    2551             :                                 continue;
    2552             :                         }
    2553             : #endif
    2554             : #endif
    2555           0 :                         if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) &&
    2556             :                             (non_asoc_addr_ok == 0))
    2557           0 :                                 continue;
    2558           0 :                         sifa = sctp_is_ifa_addr_preferred(sctp_ifa,
    2559             :                                                           dest_is_loop,
    2560             :                                                           dest_is_priv, fam);
    2561           0 :                         if (sifa == NULL)
    2562           0 :                                 continue;
    2563           0 :                         if (sctp_is_addr_in_ep(inp, sifa)) {
    2564           0 :                                 atomic_add_int(&sifa->refcount, 1);
    2565           0 :                                 return (sifa);
    2566             :                         }
    2567             :                 }
    2568             :         }
    2569             :         /*
    2570             :          * ok, now we now need to find one on the list of the addresses.
    2571             :          * We can't get one on the emitting interface so let's find first
    2572             :          * a preferred one. If not that an acceptable one otherwise...
    2573             :          * we return NULL.
    2574             :          */
    2575           0 :         starting_point = inp->next_addr_touse;
    2576             :  once_again:
    2577           0 :         if (inp->next_addr_touse == NULL) {
    2578           0 :                 inp->next_addr_touse = LIST_FIRST(&inp->sctp_addr_list);
    2579           0 :                 resettotop = 1;
    2580             :         }
    2581           0 :         for (laddr = inp->next_addr_touse; laddr;
    2582           0 :              laddr = LIST_NEXT(laddr, sctp_nxt_addr)) {
    2583           0 :                 if (laddr->ifa == NULL) {
    2584             :                         /* address has been removed */
    2585           0 :                         continue;
    2586             :                 }
    2587           0 :                 if (laddr->action == SCTP_DEL_IP_ADDRESS) {
    2588             :                         /* address is being deleted */
    2589           0 :                         continue;
    2590             :                 }
    2591           0 :                 sifa = sctp_is_ifa_addr_preferred(laddr->ifa, dest_is_loop,
    2592             :                                                   dest_is_priv, fam);
    2593           0 :                 if (sifa == NULL)
    2594           0 :                         continue;
    2595           0 :                 atomic_add_int(&sifa->refcount, 1);
    2596           0 :                 return (sifa);
    2597             :         }
    2598           0 :         if (resettotop == 0) {
    2599           0 :                 inp->next_addr_touse = NULL;
    2600           0 :                 goto once_again;
    2601             :         }
    2602             : 
    2603           0 :         inp->next_addr_touse = starting_point;
    2604           0 :         resettotop = 0;
    2605             :  once_again_too:
    2606           0 :         if (inp->next_addr_touse == NULL) {
    2607           0 :                 inp->next_addr_touse = LIST_FIRST(&inp->sctp_addr_list);
    2608           0 :                 resettotop = 1;
    2609             :         }
    2610             : 
    2611             :         /* ok, what about an acceptable address in the inp */
    2612           0 :         for (laddr = inp->next_addr_touse; laddr;
    2613           0 :              laddr = LIST_NEXT(laddr, sctp_nxt_addr)) {
    2614           0 :                 if (laddr->ifa == NULL) {
    2615             :                         /* address has been removed */
    2616           0 :                         continue;
    2617             :                 }
    2618           0 :                 if (laddr->action == SCTP_DEL_IP_ADDRESS) {
    2619             :                         /* address is being deleted */
    2620           0 :                         continue;
    2621             :                 }
    2622           0 :                 sifa = sctp_is_ifa_addr_acceptable(laddr->ifa, dest_is_loop,
    2623             :                                                    dest_is_priv, fam);
    2624           0 :                 if (sifa == NULL)
    2625           0 :                         continue;
    2626           0 :                 atomic_add_int(&sifa->refcount, 1);
    2627           0 :                 return (sifa);
    2628             :         }
    2629           0 :         if (resettotop == 0) {
    2630           0 :                 inp->next_addr_touse = NULL;
    2631           0 :                 goto once_again_too;
    2632             :         }
    2633             : 
    2634             :         /*
    2635             :          * no address bound can be a source for the destination we are in
    2636             :          * trouble
    2637             :          */
    2638           0 :         return (NULL);
    2639             : }
    2640             : 
    2641             : 
    2642             : 
    2643             : static struct sctp_ifa *
    2644           0 : sctp_choose_boundspecific_stcb(struct sctp_inpcb *inp,
    2645             :                                struct sctp_tcb *stcb,
    2646             :                                sctp_route_t *ro,
    2647             :                                uint32_t vrf_id,
    2648             :                                uint8_t dest_is_priv,
    2649             :                                uint8_t dest_is_loop,
    2650             :                                int non_asoc_addr_ok,
    2651             :                                sa_family_t fam)
    2652             : {
    2653             :         struct sctp_laddr *laddr, *starting_point;
    2654             :         void *ifn;
    2655             :         struct sctp_ifn *sctp_ifn;
    2656             :         struct sctp_ifa *sctp_ifa, *sifa;
    2657           0 :         uint8_t start_at_beginning = 0;
    2658             :         struct sctp_vrf *vrf;
    2659             :         uint32_t ifn_index;
    2660             : 
    2661             :         /*
    2662             :          * first question, is the ifn we will emit on in our list, if so, we
    2663             :          * want that one.
    2664             :          */
    2665           0 :         vrf = sctp_find_vrf(vrf_id);
    2666           0 :         if (vrf == NULL)
    2667           0 :                 return (NULL);
    2668             : 
    2669           0 :         ifn = SCTP_GET_IFN_VOID_FROM_ROUTE(ro);
    2670           0 :         ifn_index = SCTP_GET_IF_INDEX_FROM_ROUTE(ro);
    2671           0 :         sctp_ifn = sctp_find_ifn( ifn, ifn_index);
    2672             : 
    2673             :         /*
    2674             :          * first question, is the ifn we will emit on in our list?  If so,
    2675             :          * we want that one. First we look for a preferred. Second, we go
    2676             :          * for an acceptable.
    2677             :          */
    2678           0 :         if (sctp_ifn) {
    2679             :                 /* first try for a preferred address on the ep */
    2680           0 :                 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
    2681             : #if defined(__FreeBSD__)
    2682             : #ifdef INET
    2683             :                         if ((sctp_ifa->address.sa.sa_family == AF_INET) &&
    2684             :                             (prison_check_ip4(inp->ip_inp.inp.inp_cred,
    2685             :                                               &sctp_ifa->address.sin.sin_addr) != 0)) {
    2686             :                                 continue;
    2687             :                         }
    2688             : #endif
    2689             : #ifdef INET6
    2690             :                         if ((sctp_ifa->address.sa.sa_family == AF_INET6) &&
    2691             :                             (prison_check_ip6(inp->ip_inp.inp.inp_cred,
    2692             :                                               &sctp_ifa->address.sin6.sin6_addr) != 0)) {
    2693             :                                 continue;
    2694             :                         }
    2695             : #endif
    2696             : #endif
    2697           0 :                         if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0))
    2698           0 :                                 continue;
    2699           0 :                         if (sctp_is_addr_in_ep(inp, sctp_ifa)) {
    2700           0 :                                 sifa = sctp_is_ifa_addr_preferred(sctp_ifa, dest_is_loop, dest_is_priv, fam);
    2701           0 :                                 if (sifa == NULL)
    2702           0 :                                         continue;
    2703           0 :                                 if (((non_asoc_addr_ok == 0) &&
    2704           0 :                                      (sctp_is_addr_restricted(stcb, sifa))) ||
    2705           0 :                                     (non_asoc_addr_ok &&
    2706           0 :                                      (sctp_is_addr_restricted(stcb, sifa)) &&
    2707           0 :                                      (!sctp_is_addr_pending(stcb, sifa)))) {
    2708             :                                         /* on the no-no list */
    2709           0 :                                         continue;
    2710             :                                 }
    2711           0 :                                 atomic_add_int(&sifa->refcount, 1);
    2712           0 :                                 return (sifa);
    2713             :                         }
    2714             :                 }
    2715             :                 /* next try for an acceptable address on the ep */
    2716           0 :                 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
    2717             : #if defined(__FreeBSD__)
    2718             : #ifdef INET
    2719             :                         if ((sctp_ifa->address.sa.sa_family == AF_INET) &&
    2720             :                             (prison_check_ip4(inp->ip_inp.inp.inp_cred,
    2721             :                                               &sctp_ifa->address.sin.sin_addr) != 0)) {
    2722             :                                 continue;
    2723             :                         }
    2724             : #endif
    2725             : #ifdef INET6
    2726             :                         if ((sctp_ifa->address.sa.sa_family == AF_INET6) &&
    2727             :                             (prison_check_ip6(inp->ip_inp.inp.inp_cred,
    2728             :                                               &sctp_ifa->address.sin6.sin6_addr) != 0)) {
    2729             :                                 continue;
    2730             :                         }
    2731             : #endif
    2732             : #endif
    2733           0 :                         if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0))
    2734           0 :                                 continue;
    2735           0 :                         if (sctp_is_addr_in_ep(inp, sctp_ifa)) {
    2736           0 :                                 sifa= sctp_is_ifa_addr_acceptable(sctp_ifa, dest_is_loop, dest_is_priv,fam);
    2737           0 :                                 if (sifa == NULL)
    2738           0 :                                         continue;
    2739           0 :                                 if (((non_asoc_addr_ok == 0) &&
    2740           0 :                                      (sctp_is_addr_restricted(stcb, sifa))) ||
    2741           0 :                                     (non_asoc_addr_ok &&
    2742           0 :                                      (sctp_is_addr_restricted(stcb, sifa)) &&
    2743           0 :                                      (!sctp_is_addr_pending(stcb, sifa)))) {
    2744             :                                         /* on the no-no list */
    2745           0 :                                         continue;
    2746             :                                 }
    2747           0 :                                 atomic_add_int(&sifa->refcount, 1);
    2748           0 :                                 return (sifa);
    2749             :                         }
    2750             :                 }
    2751             : 
    2752             :         }
    2753             :         /*
    2754             :          * if we can't find one like that then we must look at all
    2755             :          * addresses bound to pick one at first preferable then
    2756             :          * secondly acceptable.
    2757             :          */
    2758           0 :         starting_point = stcb->asoc.last_used_address;
    2759             :  sctp_from_the_top:
    2760           0 :         if (stcb->asoc.last_used_address == NULL) {
    2761           0 :                 start_at_beginning = 1;
    2762           0 :                 stcb->asoc.last_used_address = LIST_FIRST(&inp->sctp_addr_list);
    2763             :         }
    2764             :         /* search beginning with the last used address */
    2765           0 :         for (laddr = stcb->asoc.last_used_address; laddr;
    2766           0 :              laddr = LIST_NEXT(laddr, sctp_nxt_addr)) {
    2767           0 :                 if (laddr->ifa == NULL) {
    2768             :                         /* address has been removed */
    2769           0 :                         continue;
    2770             :                 }
    2771           0 :                 if (laddr->action == SCTP_DEL_IP_ADDRESS) {
    2772             :                         /* address is being deleted */
    2773           0 :                         continue;
    2774             :                 }
    2775           0 :                 sifa = sctp_is_ifa_addr_preferred(laddr->ifa, dest_is_loop, dest_is_priv, fam);
    2776           0 :                 if (sifa == NULL)
    2777           0 :                         continue;
    2778           0 :                 if (((non_asoc_addr_ok == 0) &&
    2779           0 :                      (sctp_is_addr_restricted(stcb, sifa))) ||
    2780           0 :                     (non_asoc_addr_ok &&
    2781           0 :                      (sctp_is_addr_restricted(stcb, sifa)) &&
    2782           0 :                      (!sctp_is_addr_pending(stcb, sifa)))) {
    2783             :                         /* on the no-no list */
    2784           0 :                         continue;
    2785             :                 }
    2786           0 :                 stcb->asoc.last_used_address = laddr;
    2787           0 :                 atomic_add_int(&sifa->refcount, 1);
    2788           0 :                 return (sifa);
    2789             :         }
    2790           0 :         if (start_at_beginning == 0) {
    2791           0 :                 stcb->asoc.last_used_address = NULL;
    2792           0 :                 goto sctp_from_the_top;
    2793             :         }
    2794             :         /* now try for any higher scope than the destination */
    2795           0 :         stcb->asoc.last_used_address = starting_point;
    2796           0 :         start_at_beginning = 0;
    2797             :  sctp_from_the_top2:
    2798           0 :         if (stcb->asoc.last_used_address == NULL) {
    2799           0 :                 start_at_beginning = 1;
    2800           0 :                 stcb->asoc.last_used_address = LIST_FIRST(&inp->sctp_addr_list);
    2801             :         }
    2802             :         /* search beginning with the last used address */
    2803           0 :         for (laddr = stcb->asoc.last_used_address; laddr;
    2804           0 :              laddr = LIST_NEXT(laddr, sctp_nxt_addr)) {
    2805           0 :                 if (laddr->ifa == NULL) {
    2806             :                         /* address has been removed */
    2807           0 :                         continue;
    2808             :                 }
    2809           0 :                 if (laddr->action == SCTP_DEL_IP_ADDRESS) {
    2810             :                         /* address is being deleted */
    2811           0 :                         continue;
    2812             :                 }
    2813           0 :                 sifa = sctp_is_ifa_addr_acceptable(laddr->ifa, dest_is_loop,
    2814             :                                                    dest_is_priv, fam);
    2815           0 :                 if (sifa == NULL)
    2816           0 :                         continue;
    2817           0 :                 if (((non_asoc_addr_ok == 0) &&
    2818           0 :                      (sctp_is_addr_restricted(stcb, sifa))) ||
    2819           0 :                     (non_asoc_addr_ok &&
    2820           0 :                      (sctp_is_addr_restricted(stcb, sifa)) &&
    2821           0 :                      (!sctp_is_addr_pending(stcb, sifa)))) {
    2822             :                         /* on the no-no list */
    2823           0 :                         continue;
    2824             :                 }
    2825           0 :                 stcb->asoc.last_used_address = laddr;
    2826           0 :                 atomic_add_int(&sifa->refcount, 1);
    2827           0 :                 return (sifa);
    2828             :         }
    2829           0 :         if (start_at_beginning == 0) {
    2830           0 :                 stcb->asoc.last_used_address = NULL;
    2831           0 :                 goto sctp_from_the_top2;
    2832             :         }
    2833           0 :         return (NULL);
    2834             : }
    2835             : 
    2836             : static struct sctp_ifa *
    2837           0 : sctp_select_nth_preferred_addr_from_ifn_boundall(struct sctp_ifn *ifn,
    2838             : #if defined(__FreeBSD__)
    2839             :                                                  struct sctp_inpcb *inp,
    2840             : #else
    2841             :                                                  struct sctp_inpcb *inp SCTP_UNUSED,
    2842             : #endif
    2843             :                                                  struct sctp_tcb *stcb,
    2844             :                                                  int non_asoc_addr_ok,
    2845             :                                                  uint8_t dest_is_loop,
    2846             :                                                  uint8_t dest_is_priv,
    2847             :                                                  int addr_wanted,
    2848             :                                                  sa_family_t fam,
    2849             :                                                  sctp_route_t *ro
    2850             :                                                  )
    2851             : {
    2852             :         struct sctp_ifa *ifa, *sifa;
    2853           0 :         int num_eligible_addr = 0;
    2854             : #ifdef INET6
    2855             : #ifdef SCTP_EMBEDDED_V6_SCOPE
    2856             :         struct sockaddr_in6 sin6, lsa6;
    2857             : 
    2858             :         if (fam == AF_INET6) {
    2859             :                 memcpy(&sin6, &ro->ro_dst, sizeof(struct sockaddr_in6));
    2860             : #ifdef SCTP_KAME
    2861             :                 (void)sa6_recoverscope(&sin6);
    2862             : #else
    2863             :                 (void)in6_recoverscope(&sin6, &sin6.sin6_addr, NULL);
    2864             : #endif  /* SCTP_KAME */
    2865             :         }
    2866             : #endif  /* SCTP_EMBEDDED_V6_SCOPE */
    2867             : #endif  /* INET6 */
    2868           0 :         LIST_FOREACH(ifa, &ifn->ifalist, next_ifa) {
    2869             : #if defined(__FreeBSD__)
    2870             : #ifdef INET
    2871             :                 if ((ifa->address.sa.sa_family == AF_INET) &&
    2872             :                     (prison_check_ip4(inp->ip_inp.inp.inp_cred,
    2873             :                                       &ifa->address.sin.sin_addr) != 0)) {
    2874             :                         continue;
    2875             :                 }
    2876             : #endif
    2877             : #ifdef INET6
    2878             :                 if ((ifa->address.sa.sa_family == AF_INET6) &&
    2879             :                     (prison_check_ip6(inp->ip_inp.inp.inp_cred,
    2880             :                                       &ifa->address.sin6.sin6_addr) != 0)) {
    2881             :                         continue;
    2882             :                 }
    2883             : #endif
    2884             : #endif
    2885           0 :                 if ((ifa->localifa_flags & SCTP_ADDR_DEFER_USE) &&
    2886             :                     (non_asoc_addr_ok == 0))
    2887           0 :                         continue;
    2888           0 :                 sifa = sctp_is_ifa_addr_preferred(ifa, dest_is_loop,
    2889             :                                                   dest_is_priv, fam);
    2890           0 :                 if (sifa == NULL)
    2891           0 :                         continue;
    2892             : #ifdef INET6
    2893             :                 if (fam == AF_INET6 &&
    2894             :                     dest_is_loop &&
    2895             :                     sifa->src_is_loop && sifa->src_is_priv) {
    2896             :                         /* don't allow fe80::1 to be a src on loop ::1, we don't list it
    2897             :                          * to the peer so we will get an abort.
    2898             :                          */
    2899             :                         continue;
    2900             :                 }
    2901             : #ifdef SCTP_EMBEDDED_V6_SCOPE
    2902             :                 if (fam == AF_INET6 &&
    2903             :                     IN6_IS_ADDR_LINKLOCAL(&sifa->address.sin6.sin6_addr) &&
    2904             :                     IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr)) {
    2905             :                         /* link-local <-> link-local must belong to the same scope. */
    2906             :                         memcpy(&lsa6, &sifa->address.sin6, sizeof(struct sockaddr_in6));
    2907             : #ifdef SCTP_KAME
    2908             :                         (void)sa6_recoverscope(&lsa6);
    2909             : #else
    2910             :                         (void)in6_recoverscope(&lsa6, &lsa6.sin6_addr, NULL);
    2911             : #endif  /* SCTP_KAME */
    2912             :                         if (sin6.sin6_scope_id != lsa6.sin6_scope_id) {
    2913             :                                 continue;
    2914             :                         }
    2915             :                 }
    2916             : #endif  /* SCTP_EMBEDDED_V6_SCOPE */
    2917             : #endif  /* INET6 */
    2918             : 
    2919             : #if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Userspace__)
    2920             :                 /* Check if the IPv6 address matches to next-hop.
    2921             :                    In the mobile case, old IPv6 address may be not deleted
    2922             :                    from the interface. Then, the interface has previous and
    2923             :                    new addresses.  We should use one corresponding to the
    2924             :                    next-hop.  (by micchie)
    2925             :                  */
    2926             : #ifdef INET6
    2927             :                 if (stcb && fam == AF_INET6 &&
    2928             :                     sctp_is_mobility_feature_on(stcb->sctp_ep, SCTP_MOBILITY_BASE)) {
    2929             :                         if (sctp_v6src_match_nexthop(&sifa->address.sin6, ro)
    2930             :                             == 0) {
    2931             :                                 continue;
    2932             :                         }
    2933             :                 }
    2934             : #endif
    2935             : #ifdef INET
    2936             :                 /* Avoid topologically incorrect IPv4 address */
    2937             :                 if (stcb && fam == AF_INET &&
    2938             :                     sctp_is_mobility_feature_on(stcb->sctp_ep, SCTP_MOBILITY_BASE)) {
    2939             :                         if (sctp_v4src_match_nexthop(sifa, ro) == 0) {
    2940             :                                 continue;
    2941             :                         }
    2942             :                 }
    2943             : #endif
    2944             : #endif
    2945           0 :                 if (stcb) {
    2946           0 :                         if (sctp_is_address_in_scope(ifa, &stcb->asoc.scope, 0) == 0) {
    2947           0 :                                 continue;
    2948             :                         }
    2949           0 :                         if (((non_asoc_addr_ok == 0) &&
    2950           0 :                              (sctp_is_addr_restricted(stcb, sifa))) ||
    2951           0 :                             (non_asoc_addr_ok &&
    2952           0 :                              (sctp_is_addr_restricted(stcb, sifa)) &&
    2953           0 :                              (!sctp_is_addr_pending(stcb, sifa)))) {
    2954             :                                 /*
    2955             :                                  * It is restricted for some reason..
    2956             :                                  * probably not yet added.
    2957             :                                  */
    2958           0 :                                 continue;
    2959             :                         }
    2960             :                 }
    2961           0 :                 if (num_eligible_addr >= addr_wanted) {
    2962           0 :                         return (sifa);
    2963             :                 }
    2964           0 :                 num_eligible_addr++;
    2965             :         }
    2966           0 :         return (NULL);
    2967             : }
    2968             : 
    2969             : 
    2970             : static int
    2971           0 : sctp_count_num_preferred_boundall(struct sctp_ifn *ifn,
    2972             : #if defined(__FreeBSD__)
    2973             :                                   struct sctp_inpcb *inp,
    2974             : #else
    2975             :                                   struct sctp_inpcb *inp SCTP_UNUSED,
    2976             : #endif
    2977             :                                   struct sctp_tcb *stcb,
    2978             :                                   int non_asoc_addr_ok,
    2979             :                                   uint8_t dest_is_loop,
    2980             :                                   uint8_t dest_is_priv,
    2981             :                                   sa_family_t fam)
    2982             : {
    2983             :         struct sctp_ifa *ifa, *sifa;
    2984           0 :         int num_eligible_addr = 0;
    2985             : 
    2986           0 :         LIST_FOREACH(ifa, &ifn->ifalist, next_ifa) {
    2987             : #if defined(__FreeBSD__)
    2988             : #ifdef INET
    2989             :                 if ((ifa->address.sa.sa_family == AF_INET) &&
    2990             :                     (prison_check_ip4(inp->ip_inp.inp.inp_cred,
    2991             :                                       &ifa->address.sin.sin_addr) != 0)) {
    2992             :                         continue;
    2993             :                 }
    2994             : #endif
    2995             : #ifdef INET6
    2996             :                 if ((ifa->address.sa.sa_family == AF_INET6) &&
    2997             :                     (stcb != NULL) &&
    2998             :                     (prison_check_ip6(inp->ip_inp.inp.inp_cred,
    2999             :                                       &ifa->address.sin6.sin6_addr) != 0)) {
    3000             :                         continue;
    3001             :                 }
    3002             : #endif
    3003             : #endif
    3004           0 :                 if ((ifa->localifa_flags & SCTP_ADDR_DEFER_USE) &&
    3005             :                     (non_asoc_addr_ok == 0)) {
    3006           0 :                         continue;
    3007             :                 }
    3008           0 :                 sifa = sctp_is_ifa_addr_preferred(ifa, dest_is_loop,
    3009             :                                                   dest_is_priv, fam);
    3010           0 :                 if (sifa == NULL) {
    3011           0 :                         continue;
    3012             :                 }
    3013           0 :                 if (stcb) {
    3014           0 :                         if (sctp_is_address_in_scope(ifa, &stcb->asoc.scope, 0) == 0) {
    3015           0 :                                 continue;
    3016             :                         }
    3017           0 :                         if (((non_asoc_addr_ok == 0) &&
    3018           0 :                              (sctp_is_addr_restricted(stcb, sifa))) ||
    3019           0 :                             (non_asoc_addr_ok &&
    3020           0 :                              (sctp_is_addr_restricted(stcb, sifa)) &&
    3021           0 :                              (!sctp_is_addr_pending(stcb, sifa)))) {
    3022             :                                 /*
    3023             :                                  * It is restricted for some reason..
    3024             :                                  * probably not yet added.
    3025             :                                  */
    3026           0 :                                 continue;
    3027             :                         }
    3028             :                 }
    3029           0 :                 num_eligible_addr++;
    3030             :         }
    3031           0 :         return (num_eligible_addr);
    3032             : }
    3033             : 
    3034             : static struct sctp_ifa *
    3035           0 : sctp_choose_boundall(struct sctp_inpcb *inp,
    3036             :                      struct sctp_tcb *stcb,
    3037             :                      struct sctp_nets *net,
    3038             :                      sctp_route_t *ro,
    3039             :                      uint32_t vrf_id,
    3040             :                      uint8_t dest_is_priv,
    3041             :                      uint8_t dest_is_loop,
    3042             :                      int non_asoc_addr_ok,
    3043             :                      sa_family_t fam)
    3044             : {
    3045           0 :         int cur_addr_num = 0, num_preferred = 0;
    3046             :         void *ifn;
    3047           0 :         struct sctp_ifn *sctp_ifn, *looked_at = NULL, *emit_ifn;
    3048             :         struct sctp_ifa *sctp_ifa, *sifa;
    3049             :         uint32_t ifn_index;
    3050             :         struct sctp_vrf *vrf;
    3051             : #ifdef INET
    3052             :         int retried = 0;
    3053             : #endif
    3054             : 
    3055             :         /*-
    3056             :          * For boundall we can use any address in the association.
    3057             :          * If non_asoc_addr_ok is set we can use any address (at least in
    3058             :          * theory). So we look for preferred addresses first. If we find one,
    3059             :          * we use it. Otherwise we next try to get an address on the
    3060             :          * interface, which we should be able to do (unless non_asoc_addr_ok
    3061             :          * is false and we are routed out that way). In these cases where we
    3062             :          * can't use the address of the interface we go through all the
    3063             :          * ifn's looking for an address we can use and fill that in. Punting
    3064             :          * means we send back address 0, which will probably cause problems
    3065             :          * actually since then IP will fill in the address of the route ifn,
    3066             :          * which means we probably already rejected it.. i.e. here comes an
    3067             :          * abort :-<.
    3068             :          */
    3069           0 :         vrf = sctp_find_vrf(vrf_id);
    3070           0 :         if (vrf == NULL)
    3071           0 :                 return (NULL);
    3072             : 
    3073           0 :         ifn = SCTP_GET_IFN_VOID_FROM_ROUTE(ro);
    3074           0 :         ifn_index = SCTP_GET_IF_INDEX_FROM_ROUTE(ro);
    3075           0 :         SCTPDBG(SCTP_DEBUG_OUTPUT2,"ifn from route:%p ifn_index:%d\n", ifn, ifn_index);
    3076           0 :         emit_ifn = looked_at = sctp_ifn = sctp_find_ifn(ifn, ifn_index);
    3077           0 :         if (sctp_ifn == NULL) {
    3078             :                 /* ?? We don't have this guy ?? */
    3079           0 :                 SCTPDBG(SCTP_DEBUG_OUTPUT2,"No ifn emit interface?\n");
    3080           0 :                 goto bound_all_plan_b;
    3081             :         }
    3082           0 :         SCTPDBG(SCTP_DEBUG_OUTPUT2,"ifn_index:%d name:%s is emit interface\n",
    3083             :                 ifn_index, sctp_ifn->ifn_name);
    3084             : 
    3085           0 :         if (net) {
    3086           0 :                 cur_addr_num = net->indx_of_eligible_next_to_use;
    3087             :         }
    3088           0 :         num_preferred = sctp_count_num_preferred_boundall(sctp_ifn,
    3089             :                                                           inp, stcb,
    3090             :                                                           non_asoc_addr_ok,
    3091             :                                                           dest_is_loop,
    3092             :                                                           dest_is_priv, fam);
    3093           0 :         SCTPDBG(SCTP_DEBUG_OUTPUT2, "Found %d preferred source addresses for intf:%s\n",
    3094             :                 num_preferred, sctp_ifn->ifn_name);
    3095           0 :         if (num_preferred == 0) {
    3096             :                 /*
    3097             :                  * no eligible addresses, we must use some other interface
    3098             :                  * address if we can find one.
    3099             :                  */
    3100           0 :                 goto bound_all_plan_b;
    3101             :         }
    3102             :         /*
    3103             :          * Ok we have num_eligible_addr set with how many we can use, this
    3104             :          * may vary from call to call due to addresses being deprecated
    3105             :          * etc..
    3106             :          */
    3107           0 :         if (cur_addr_num >= num_preferred) {
    3108           0 :                 cur_addr_num = 0;
    3109             :         }
    3110             :         /*
    3111             :          * select the nth address from the list (where cur_addr_num is the
    3112             :          * nth) and 0 is the first one, 1 is the second one etc...
    3113             :          */
    3114           0 :         SCTPDBG(SCTP_DEBUG_OUTPUT2, "cur_addr_num:%d\n", cur_addr_num);
    3115             : 
    3116           0 :         sctp_ifa = sctp_select_nth_preferred_addr_from_ifn_boundall(sctp_ifn, inp, stcb, non_asoc_addr_ok, dest_is_loop,
    3117             :                                                                     dest_is_priv, cur_addr_num, fam, ro);
    3118             : 
    3119             :         /* if sctp_ifa is NULL something changed??, fall to plan b. */
    3120           0 :         if (sctp_ifa) {
    3121           0 :                 atomic_add_int(&sctp_ifa->refcount, 1);
    3122           0 :                 if (net) {
    3123             :                         /* save off where the next one we will want */
    3124           0 :                         net->indx_of_eligible_next_to_use = cur_addr_num + 1;
    3125             :                 }
    3126           0 :                 return (sctp_ifa);
    3127             :         }
    3128             :         /*
    3129             :          * plan_b: Look at all interfaces and find a preferred address. If
    3130             :          * no preferred fall through to plan_c.
    3131             :          */
    3132             :  bound_all_plan_b:
    3133           0 :         SCTPDBG(SCTP_DEBUG_OUTPUT2, "Trying Plan B\n");
    3134           0 :         LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
    3135           0 :                 SCTPDBG(SCTP_DEBUG_OUTPUT2, "Examine interface %s\n",
    3136             :                         sctp_ifn->ifn_name);
    3137           0 :                 if (dest_is_loop == 0 && SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
    3138             :                         /* wrong base scope */
    3139           0 :                         SCTPDBG(SCTP_DEBUG_OUTPUT2, "skip\n");
    3140           0 :                         continue;
    3141             :                 }
    3142           0 :                 if ((sctp_ifn == looked_at) && looked_at) {
    3143             :                         /* already looked at this guy */
    3144           0 :                         SCTPDBG(SCTP_DEBUG_OUTPUT2, "already seen\n");
    3145           0 :                         continue;
    3146             :                 }
    3147           0 :                 num_preferred = sctp_count_num_preferred_boundall(sctp_ifn, inp, stcb, non_asoc_addr_ok,
    3148             :                                                                   dest_is_loop, dest_is_priv, fam);
    3149           0 :                 SCTPDBG(SCTP_DEBUG_OUTPUT2,
    3150             :                         "Found ifn:%p %d preferred source addresses\n",
    3151             :                         ifn, num_preferred);
    3152           0 :                 if (num_preferred == 0) {
    3153             :                         /* None on this interface. */
    3154           0 :                         SCTPDBG(SCTP_DEBUG_OUTPUT2, "No prefered -- skipping to next\n");
    3155           0 :                         continue;
    3156             :                 }
    3157           0 :                 SCTPDBG(SCTP_DEBUG_OUTPUT2,
    3158             :                         "num preferred:%d on interface:%p cur_addr_num:%d\n",
    3159             :                         num_preferred, (void *)sctp_ifn, cur_addr_num);
    3160             : 
    3161             :                 /*
    3162             :                  * Ok we have num_eligible_addr set with how many we can
    3163             :                  * use, this may vary from call to call due to addresses
    3164             :                  * being deprecated etc..
    3165             :                  */
    3166           0 :                 if (cur_addr_num >= num_preferred) {
    3167           0 :                         cur_addr_num = 0;
    3168             :                 }
    3169           0 :                 sifa = sctp_select_nth_preferred_addr_from_ifn_boundall(sctp_ifn, inp, stcb, non_asoc_addr_ok, dest_is_loop,
    3170             :                                                                         dest_is_priv, cur_addr_num, fam, ro);
    3171           0 :                 if (sifa == NULL)
    3172           0 :                         continue;
    3173           0 :                 if (net) {
    3174           0 :                         net->indx_of_eligible_next_to_use = cur_addr_num + 1;
    3175           0 :                         SCTPDBG(SCTP_DEBUG_OUTPUT2, "we selected %d\n",
    3176             :                                 cur_addr_num);
    3177           0 :                         SCTPDBG(SCTP_DEBUG_OUTPUT2, "Source:");
    3178           0 :                         SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, &sifa->address.sa);
    3179           0 :                         SCTPDBG(SCTP_DEBUG_OUTPUT2, "Dest:");
    3180           0 :                         SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, &net->ro._l_addr.sa);
    3181             :                 }
    3182           0 :                 atomic_add_int(&sifa->refcount, 1);
    3183           0 :                 return (sifa);
    3184             :         }
    3185             : #ifdef INET
    3186             : again_with_private_addresses_allowed:
    3187             : #endif
    3188             :         /* plan_c: do we have an acceptable address on the emit interface */
    3189           0 :         sifa = NULL;
    3190           0 :         SCTPDBG(SCTP_DEBUG_OUTPUT2,"Trying Plan C: find acceptable on interface\n");
    3191           0 :         if (emit_ifn == NULL) {
    3192           0 :                 SCTPDBG(SCTP_DEBUG_OUTPUT2,"Jump to Plan D - no emit_ifn\n");
    3193           0 :                 goto plan_d;
    3194             :         }
    3195           0 :         LIST_FOREACH(sctp_ifa, &emit_ifn->ifalist, next_ifa) {
    3196           0 :                 SCTPDBG(SCTP_DEBUG_OUTPUT2, "ifa:%p\n", (void *)sctp_ifa);
    3197             : #if defined(__FreeBSD__)
    3198             : #ifdef INET
    3199             :                 if ((sctp_ifa->address.sa.sa_family == AF_INET) &&
    3200             :                     (prison_check_ip4(inp->ip_inp.inp.inp_cred,
    3201             :                                       &sctp_ifa->address.sin.sin_addr) != 0)) {
    3202             :                         SCTPDBG(SCTP_DEBUG_OUTPUT2,"Jailed\n");
    3203             :                         continue;
    3204             :                 }
    3205             : #endif
    3206             : #ifdef INET6
    3207             :                 if ((sctp_ifa->address.sa.sa_family == AF_INET6) &&
    3208             :                     (prison_check_ip6(inp->ip_inp.inp.inp_cred,
    3209             :                                       &sctp_ifa->address.sin6.sin6_addr) != 0)) {
    3210             :                         SCTPDBG(SCTP_DEBUG_OUTPUT2,"Jailed\n");
    3211             :                         continue;
    3212             :                 }
    3213             : #endif
    3214             : #endif
    3215           0 :                 if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) &&
    3216             :                     (non_asoc_addr_ok == 0)) {
    3217           0 :                         SCTPDBG(SCTP_DEBUG_OUTPUT2,"Defer\n");
    3218           0 :                         continue;
    3219             :                 }
    3220           0 :                 sifa = sctp_is_ifa_addr_acceptable(sctp_ifa, dest_is_loop,
    3221             :                                                    dest_is_priv, fam);
    3222           0 :                 if (sifa == NULL) {
    3223           0 :                         SCTPDBG(SCTP_DEBUG_OUTPUT2, "IFA not acceptable\n");
    3224           0 :                         continue;
    3225             :                 }
    3226           0 :                 if (stcb) {
    3227           0 :                         if (sctp_is_address_in_scope(sifa, &stcb->asoc.scope, 0) == 0) {
    3228           0 :                                 SCTPDBG(SCTP_DEBUG_OUTPUT2, "NOT in scope\n");
    3229           0 :                                 sifa = NULL;
    3230           0 :                                 continue;
    3231             :                         }
    3232           0 :                         if (((non_asoc_addr_ok == 0) &&
    3233           0 :                              (sctp_is_addr_restricted(stcb, sifa))) ||
    3234           0 :                             (non_asoc_addr_ok &&
    3235           0 :                              (sctp_is_addr_restricted(stcb, sifa)) &&
    3236           0 :                              (!sctp_is_addr_pending(stcb, sifa)))) {
    3237             :                                 /*
    3238             :                                  * It is restricted for some
    3239             :                                  * reason.. probably not yet added.
    3240             :                                  */
    3241           0 :                                 SCTPDBG(SCTP_DEBUG_OUTPUT2, "Its resticted\n");
    3242           0 :                                 sifa = NULL;
    3243           0 :                                 continue;
    3244             :                         }
    3245             :                 } else {
    3246           0 :                         SCTP_PRINTF("Stcb is null - no print\n");
    3247             :                 }
    3248           0 :                 atomic_add_int(&sifa->refcount, 1);
    3249           0 :                 goto out;
    3250             :         }
    3251             :  plan_d:
    3252             :         /*
    3253             :          * plan_d: We are in trouble. No preferred address on the emit
    3254             :          * interface. And not even a preferred address on all interfaces.
    3255             :          * Go out and see if we can find an acceptable address somewhere
    3256             :          * amongst all interfaces.
    3257             :          */
    3258           0 :         SCTPDBG(SCTP_DEBUG_OUTPUT2, "Trying Plan D looked_at is %p\n", (void *)looked_at);
    3259           0 :         LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
    3260           0 :                 if (dest_is_loop == 0 && SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
    3261             :                         /* wrong base scope */
    3262           0 :                         continue;
    3263             :                 }
    3264           0 :                 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
    3265             : #if defined(__FreeBSD__)
    3266             : #ifdef INET
    3267             :                         if ((sctp_ifa->address.sa.sa_family == AF_INET) &&
    3268             :                             (prison_check_ip4(inp->ip_inp.inp.inp_cred,
    3269             :                                               &sctp_ifa->address.sin.sin_addr) != 0)) {
    3270             :                                 continue;
    3271             :                         }
    3272             : #endif
    3273             : #ifdef INET6
    3274             :                         if ((sctp_ifa->address.sa.sa_family == AF_INET6) &&
    3275             :                             (prison_check_ip6(inp->ip_inp.inp.inp_cred,
    3276             :                                               &sctp_ifa->address.sin6.sin6_addr) != 0)) {
    3277             :                                 continue;
    3278             :                         }
    3279             : #endif
    3280             : #endif
    3281           0 :                         if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) &&
    3282             :                             (non_asoc_addr_ok == 0))
    3283           0 :                                 continue;
    3284           0 :                         sifa = sctp_is_ifa_addr_acceptable(sctp_ifa,
    3285             :                                                            dest_is_loop,
    3286             :                                                            dest_is_priv, fam);
    3287           0 :                         if (sifa == NULL)
    3288           0 :                                 continue;
    3289           0 :                         if (stcb) {
    3290           0 :                                 if (sctp_is_address_in_scope(sifa, &stcb->asoc.scope, 0) == 0) {
    3291           0 :                                         sifa = NULL;
    3292           0 :                                         continue;
    3293             :                                 }
    3294           0 :                                 if (((non_asoc_addr_ok == 0) &&
    3295           0 :                                      (sctp_is_addr_restricted(stcb, sifa))) ||
    3296           0 :                                     (non_asoc_addr_ok &&
    3297           0 :                                      (sctp_is_addr_restricted(stcb, sifa)) &&
    3298           0 :                                      (!sctp_is_addr_pending(stcb, sifa)))) {
    3299             :                                         /*
    3300             :                                          * It is restricted for some
    3301             :                                          * reason.. probably not yet added.
    3302             :                                          */
    3303           0 :                                         sifa = NULL;
    3304           0 :                                         continue;
    3305             :                                 }
    3306             :                         }
    3307           0 :                         goto out;
    3308             :                 }
    3309             :         }
    3310             : #ifdef INET
    3311             :         if ((retried == 0) && (stcb->asoc.scope.ipv4_local_scope == 0)) {
    3312             :                 stcb->asoc.scope.ipv4_local_scope = 1;
    3313             :                 retried = 1;
    3314             :                 goto again_with_private_addresses_allowed;
    3315             :         } else if (retried == 1) {
    3316             :                 stcb->asoc.scope.ipv4_local_scope = 0;
    3317             :         }
    3318             : #endif
    3319             : out:
    3320             : #ifdef INET
    3321             :         if (sifa) {
    3322             :                 if (retried == 1) {
    3323             :                         LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
    3324             :                                 if (dest_is_loop == 0 && SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
    3325             :                                         /* wrong base scope */
    3326             :                                         continue;
    3327             :                                 }
    3328             :                                 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
    3329             :                                         struct sctp_ifa *tmp_sifa;
    3330             : 
    3331             : #if defined(__FreeBSD__)
    3332             : #ifdef INET
    3333             :                                         if ((sctp_ifa->address.sa.sa_family == AF_INET) &&
    3334             :                                             (prison_check_ip4(inp->ip_inp.inp.inp_cred,
    3335             :                                                               &sctp_ifa->address.sin.sin_addr) != 0)) {
    3336             :                                                 continue;
    3337             :                                         }
    3338             : #endif
    3339             : #ifdef INET6
    3340             :                                         if ((sctp_ifa->address.sa.sa_family == AF_INET6) &&
    3341             :                                             (prison_check_ip6(inp->ip_inp.inp.inp_cred,
    3342             :                                                               &sctp_ifa->address.sin6.sin6_addr) != 0)) {
    3343             :                                                 continue;
    3344             :                                         }
    3345             : #endif
    3346             : #endif
    3347             :                                         if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) &&
    3348             :                                             (non_asoc_addr_ok == 0))
    3349             :                                                 continue;
    3350             :                                         tmp_sifa = sctp_is_ifa_addr_acceptable(sctp_ifa,
    3351             :                                                                                dest_is_loop,
    3352             :                                                                                dest_is_priv, fam);
    3353             :                                         if (tmp_sifa == NULL) {
    3354             :                                                 continue;
    3355             :                                         }
    3356             :                                         if (tmp_sifa == sifa) {
    3357             :                                                 continue;
    3358             :                                         }
    3359             :                                         if (stcb) {
    3360             :                                                 if (sctp_is_address_in_scope(tmp_sifa,
    3361             :                                                                              &stcb->asoc.scope, 0) == 0) {
    3362             :                                                         continue;
    3363             :                                                 }
    3364             :                                                 if (((non_asoc_addr_ok == 0) &&
    3365             :                                                      (sctp_is_addr_restricted(stcb, tmp_sifa))) ||
    3366             :                                                     (non_asoc_addr_ok &&
    3367             :                                                      (sctp_is_addr_restricted(stcb, tmp_sifa)) &&
    3368             :                                                      (!sctp_is_addr_pending(stcb, tmp_sifa)))) {
    3369             :                                                         /*
    3370             :                                                          * It is restricted for some
    3371             :                                                          * reason.. probably not yet added.
    3372             :                                                          */
    3373             :                                                         continue;
    3374             :                                                 }
    3375             :                                         }
    3376             :                                         if ((tmp_sifa->address.sin.sin_family == AF_INET) &&
    3377             :                                             (IN4_ISPRIVATE_ADDRESS(&(tmp_sifa->address.sin.sin_addr)))) {
    3378             :                                                 sctp_add_local_addr_restricted(stcb, tmp_sifa);
    3379             :                                         }
    3380             :                                 }
    3381             :                         }
    3382             :                 }
    3383             :                 atomic_add_int(&sifa->refcount, 1);
    3384             :         }
    3385             : #endif
    3386           0 :         return (sifa);
    3387             : }
    3388             : 
    3389             : 
    3390             : 
    3391             : /* tcb may be NULL */
    3392             : struct sctp_ifa *
    3393           0 : sctp_source_address_selection(struct sctp_inpcb *inp,
    3394             :                               struct sctp_tcb *stcb,
    3395             :                               sctp_route_t *ro,
    3396             :                               struct sctp_nets *net,
    3397             :                               int non_asoc_addr_ok, uint32_t vrf_id)
    3398             : {
    3399             :         struct sctp_ifa *answer;
    3400             :         uint8_t dest_is_priv, dest_is_loop;
    3401             :         sa_family_t fam;
    3402             : #ifdef INET
    3403             :         struct sockaddr_in *to = (struct sockaddr_in *)&ro->ro_dst;
    3404             : #endif
    3405             : #ifdef INET6
    3406             :         struct sockaddr_in6 *to6 = (struct sockaddr_in6 *)&ro->ro_dst;
    3407             : #endif
    3408             : 
    3409             :         /**
    3410             :          * Rules: - Find the route if needed, cache if I can. - Look at
    3411             :          * interface address in route, Is it in the bound list. If so we
    3412             :          * have the best source. - If not we must rotate amongst the
    3413             :          * addresses.
    3414             :          *
    3415             :          * Cavets and issues
    3416             :          *
    3417             :          * Do we need to pay attention to scope. We can have a private address
    3418             :          * or a global address we are sourcing or sending to. So if we draw
    3419             :          * it out
    3420             :          * zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
    3421             :          * For V4
    3422             :          * ------------------------------------------
    3423             :          *      source     *      dest  *  result
    3424             :          * -----------------------------------------
    3425             :          * <a>  Private    *    Global  *  NAT
    3426             :          * -----------------------------------------
    3427             :          * <b>  Private    *    Private *  No problem
    3428             :          * -----------------------------------------
    3429             :          * <c>  Global     *    Private *  Huh, How will this work?
    3430             :          * -----------------------------------------
    3431             :          * <d>  Global     *    Global  *  No Problem
    3432             :          *------------------------------------------
    3433             :          * zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
    3434             :          * For V6
    3435             :          *------------------------------------------
    3436             :          *      source     *      dest  *  result
    3437             :          * -----------------------------------------
    3438             :          * <a>  Linklocal  *    Global  *
    3439             :          * -----------------------------------------
    3440             :          * <b>  Linklocal  * Linklocal  *  No problem
    3441             :          * -----------------------------------------
    3442             :          * <c>  Global     * Linklocal  *  Huh, How will this work?
    3443             :          * -----------------------------------------
    3444             :          * <d>  Global     *    Global  *  No Problem
    3445             :          *------------------------------------------
    3446             :          * zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
    3447             :          *
    3448             :          * And then we add to that what happens if there are multiple addresses
    3449             :          * assigned to an interface. Remember the ifa on a ifn is a linked
    3450             :          * list of addresses. So one interface can have more than one IP
    3451             :          * address. What happens if we have both a private and a global
    3452             :          * address? Do we then use context of destination to sort out which
    3453             :          * one is best? And what about NAT's sending P->G may get you a NAT
    3454             :          * translation, or should you select the G thats on the interface in
    3455             :          * preference.
    3456             :          *
    3457             :          * Decisions:
    3458             :          *
    3459             :          * - count the number of addresses on the interface.
    3460             :          * - if it is one, no problem except case <c>.
    3461             :          *   For <a> we will assume a NAT out there.
    3462             :          * - if there are more than one, then we need to worry about scope P
    3463             :          *   or G. We should prefer G -> G and P -> P if possible.
    3464             :          *   Then as a secondary fall back to mixed types G->P being a last
    3465             :          *   ditch one.
    3466             :          * - The above all works for bound all, but bound specific we need to
    3467             :          *   use the same concept but instead only consider the bound
    3468             :          *   addresses. If the bound set is NOT assigned to the interface then
    3469             :          *   we must use rotation amongst the bound addresses..
    3470             :          */
    3471           0 :         if (ro->ro_rt == NULL) {
    3472             :                 /*
    3473             :                  * Need a route to cache.
    3474             :                  */
    3475           0 :                 SCTP_RTALLOC(ro, vrf_id);
    3476             :         }
    3477           0 :         if (ro->ro_rt == NULL) {
    3478           0 :                 return (NULL);
    3479             :         }
    3480             : #if defined(__Userspace_os_Windows)
    3481             :         /* On Windows the sa_family is U_SHORT or ADDRESS_FAMILY */
    3482             :         fam = (sa_family_t)ro->ro_dst.sa_family;
    3483             : #else
    3484           0 :         fam = ro->ro_dst.sa_family;
    3485             : #endif
    3486           0 :         dest_is_priv = dest_is_loop = 0;
    3487             :         /* Setup our scopes for the destination */
    3488           0 :         switch (fam) {
    3489             : #ifdef INET
    3490             :         case AF_INET:
    3491             :                 /* Scope based on outbound address */
    3492             :                 if (IN4_ISLOOPBACK_ADDRESS(&to->sin_addr)) {
    3493             :                         dest_is_loop = 1;
    3494             :                         if (net != NULL) {
    3495             :                                 /* mark it as local */
    3496             :                                 net->addr_is_local = 1;
    3497             :                         }
    3498             :                 } else if ((IN4_ISPRIVATE_ADDRESS(&to->sin_addr))) {
    3499             :                         dest_is_priv = 1;
    3500             :                 }
    3501             :                 break;
    3502             : #endif
    3503             : #ifdef INET6
    3504             :         case AF_INET6:
    3505             :                 /* Scope based on outbound address */
    3506             : #if defined(__Userspace_os_Windows)
    3507             :                 if (IN6_IS_ADDR_LOOPBACK(&to6->sin6_addr)) {
    3508             : #else
    3509             :                 if (IN6_IS_ADDR_LOOPBACK(&to6->sin6_addr) ||
    3510             :                     SCTP_ROUTE_IS_REAL_LOOP(ro)) {
    3511             : #endif
    3512             :                         /*
    3513             :                          * If the address is a loopback address, which
    3514             :                          * consists of "::1" OR "fe80::1%lo0", we are loopback
    3515             :                          * scope. But we don't use dest_is_priv (link local
    3516             :                          * addresses).
    3517             :                          */
    3518             :                         dest_is_loop = 1;
    3519             :                         if (net != NULL) {
    3520             :                                 /* mark it as local */
    3521             :                                 net->addr_is_local = 1;
    3522             :                         }
    3523             :                 } else if (IN6_IS_ADDR_LINKLOCAL(&to6->sin6_addr)) {
    3524             :                         dest_is_priv = 1;
    3525             :                 }
    3526             :                 break;
    3527             : #endif
    3528             :         }
    3529           0 :         SCTPDBG(SCTP_DEBUG_OUTPUT2, "Select source addr for:");
    3530           0 :         SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, (struct sockaddr *)&ro->ro_dst);
    3531           0 :         SCTP_IPI_ADDR_RLOCK();
    3532           0 :         if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
    3533             :                 /*
    3534             :                  * Bound all case
    3535             :                  */
    3536           0 :                 answer = sctp_choose_boundall(inp, stcb, net, ro, vrf_id,
    3537             :                                               dest_is_priv, dest_is_loop,
    3538             :                                               non_asoc_addr_ok, fam);
    3539           0 :                 SCTP_IPI_ADDR_RUNLOCK();
    3540           0 :                 return (answer);
    3541             :         }
    3542             :         /*
    3543             :          * Subset bound case
    3544             :          */
    3545           0 :         if (stcb) {
    3546           0 :                 answer = sctp_choose_boundspecific_stcb(inp, stcb, ro,
    3547             :                                                         vrf_id, dest_is_priv,
    3548             :                                                         dest_is_loop,
    3549             :                                                         non_asoc_addr_ok, fam);
    3550             :         } else {
    3551           0 :                 answer = sctp_choose_boundspecific_inp(inp, ro, vrf_id,
    3552             :                                                        non_asoc_addr_ok,
    3553             :                                                        dest_is_priv,
    3554             :                                                        dest_is_loop, fam);
    3555             :         }
    3556           0 :         SCTP_IPI_ADDR_RUNLOCK();
    3557           0 :         return (answer);
    3558             : }
    3559             : 
    3560             : static int
    3561           0 : sctp_find_cmsg(int c_type, void *data, struct mbuf *control, size_t cpsize)
    3562             : {
    3563             : #if defined(__Userspace_os_Windows)
    3564             :         WSACMSGHDR cmh;
    3565             : #else
    3566             :         struct cmsghdr cmh;
    3567             : #endif
    3568             :         int tlen, at, found;
    3569             :         struct sctp_sndinfo sndinfo;
    3570             :         struct sctp_prinfo prinfo;
    3571             :         struct sctp_authinfo authinfo;
    3572             : 
    3573           0 :         tlen = SCTP_BUF_LEN(control);
    3574           0 :         at = 0;
    3575           0 :         found = 0;
    3576             :         /*
    3577             :          * Independent of how many mbufs, find the c_type inside the control
    3578             :          * structure and copy out the data.
    3579             :          */
    3580           0 :         while (at < tlen) {
    3581           0 :                 if ((tlen - at) < (int)CMSG_ALIGN(sizeof(cmh))) {
    3582             :                         /* There is not enough room for one more. */
    3583           0 :                         return (found);
    3584             :                 }
    3585           0 :                 m_copydata(control, at, sizeof(cmh), (caddr_t)&cmh);
    3586           0 :                 if (cmh.cmsg_len < CMSG_ALIGN(sizeof(cmh))) {
    3587             :                         /* We dont't have a complete CMSG header. */
    3588           0 :                         return (found);
    3589             :                 }
    3590           0 :                 if (((int)cmh.cmsg_len + at) > tlen) {
    3591             :                         /* We don't have the complete CMSG. */
    3592           0 :                         return (found);
    3593             :                 }
    3594           0 :                 if ((cmh.cmsg_level == IPPROTO_SCTP) &&
    3595           0 :                     ((c_type == cmh.cmsg_type) ||
    3596           0 :                      ((c_type == SCTP_SNDRCV) &&
    3597           0 :                       ((cmh.cmsg_type == SCTP_SNDINFO) ||
    3598           0 :                        (cmh.cmsg_type == SCTP_PRINFO) ||
    3599           0 :                        (cmh.cmsg_type == SCTP_AUTHINFO))))) {
    3600           0 :                         if (c_type == cmh.cmsg_type) {
    3601           0 :                                 if ((size_t)(cmh.cmsg_len - CMSG_ALIGN(sizeof(cmh))) < cpsize) {
    3602           0 :                                         return (found);
    3603             :                                 }
    3604             :                                 /* It is exactly what we want. Copy it out. */
    3605           0 :                                 m_copydata(control, at + CMSG_ALIGN(sizeof(cmh)), cpsize, (caddr_t)data);
    3606           0 :                                 return (1);
    3607             :                         } else {
    3608             :                                 struct sctp_sndrcvinfo *sndrcvinfo;
    3609             : 
    3610           0 :                                 sndrcvinfo = (struct sctp_sndrcvinfo *)data;
    3611           0 :                                 if (found == 0) {
    3612           0 :                                         if (cpsize < sizeof(struct sctp_sndrcvinfo)) {
    3613           0 :                                                 return (found);
    3614             :                                         }
    3615           0 :                                         memset(sndrcvinfo, 0, sizeof(struct sctp_sndrcvinfo));
    3616             :                                 }
    3617           0 :                                 switch (cmh.cmsg_type) {
    3618             :                                 case SCTP_SNDINFO:
    3619           0 :                                         if ((size_t)(cmh.cmsg_len - CMSG_ALIGN(sizeof(cmh))) < sizeof(struct sctp_sndinfo)) {
    3620           0 :                                                 return (found);
    3621             :                                         }
    3622           0 :                                         m_copydata(control, at + CMSG_ALIGN(sizeof(cmh)), sizeof(struct sctp_sndinfo), (caddr_t)&sndinfo);
    3623           0 :                                         sndrcvinfo->sinfo_stream = sndinfo.snd_sid;
    3624           0 :                                         sndrcvinfo->sinfo_flags = sndinfo.snd_flags;
    3625           0 :                                         sndrcvinfo->sinfo_ppid = sndinfo.snd_ppid;
    3626           0 :                                         sndrcvinfo->sinfo_context = sndinfo.snd_context;
    3627           0 :                                         sndrcvinfo->sinfo_assoc_id = sndinfo.snd_assoc_id;
    3628           0 :                                         break;
    3629             :                                 case SCTP_PRINFO:
    3630           0 :                                         if ((size_t)(cmh.cmsg_len - CMSG_ALIGN(sizeof(cmh))) < sizeof(struct sctp_prinfo)) {
    3631           0 :                                                 return (found);
    3632             :                                         }
    3633           0 :                                         m_copydata(control, at + CMSG_ALIGN(sizeof(cmh)), sizeof(struct sctp_prinfo), (caddr_t)&prinfo);
    3634           0 :                                         if (prinfo.pr_policy != SCTP_PR_SCTP_NONE) {
    3635           0 :                                                 sndrcvinfo->sinfo_timetolive = prinfo.pr_value;
    3636             :                                         } else {
    3637           0 :                                                 sndrcvinfo->sinfo_timetolive = 0;
    3638             :                                         }
    3639           0 :                                         sndrcvinfo->sinfo_flags |= prinfo.pr_policy;
    3640           0 :                                         break;
    3641             :                                 case SCTP_AUTHINFO:
    3642           0 :                                         if ((size_t)(cmh.cmsg_len - CMSG_ALIGN(sizeof(cmh))) < sizeof(struct sctp_authinfo)) {
    3643           0 :                                                 return (found);
    3644             :                                         }
    3645           0 :                                         m_copydata(control, at + CMSG_ALIGN(sizeof(cmh)), sizeof(struct sctp_authinfo), (caddr_t)&authinfo);
    3646           0 :                                         sndrcvinfo->sinfo_keynumber_valid = 1;
    3647           0 :                                         sndrcvinfo->sinfo_keynumber = authinfo.auth_keynumber;
    3648           0 :                                         break;
    3649             :                                 default:
    3650           0 :                                         return (found);
    3651             :                                 }
    3652           0 :                                 found = 1;
    3653             :                         }
    3654             :                 }
    3655           0 :                 at += CMSG_ALIGN(cmh.cmsg_len);
    3656             :         }
    3657           0 :         return (found);
    3658             : }
    3659             : 
    3660             : static int
    3661           0 : sctp_process_cmsgs_for_init(struct sctp_tcb *stcb, struct mbuf *control, int *error)
    3662             : {
    3663             : #if defined(__Userspace_os_Windows)
    3664             :         WSACMSGHDR cmh;
    3665             : #else
    3666             :         struct cmsghdr cmh;
    3667             : #endif
    3668             :         int tlen, at;
    3669             :         struct sctp_initmsg initmsg;
    3670             : #ifdef INET
    3671             :         struct sockaddr_in sin;
    3672             : #endif
    3673             : #ifdef INET6
    3674             :         struct sockaddr_in6 sin6;
    3675             : #endif
    3676             : 
    3677           0 :         tlen = SCTP_BUF_LEN(control);
    3678           0 :         at = 0;
    3679           0 :         while (at < tlen) {
    3680           0 :                 if ((tlen - at) < (int)CMSG_ALIGN(sizeof(cmh))) {
    3681             :                         /* There is not enough room for one more. */
    3682           0 :                         *error = EINVAL;
    3683           0 :                         return (1);
    3684             :                 }
    3685           0 :                 m_copydata(control, at, sizeof(cmh), (caddr_t)&cmh);
    3686           0 :                 if (cmh.cmsg_len < CMSG_ALIGN(sizeof(cmh))) {
    3687             :                         /* We dont't have a complete CMSG header. */
    3688           0 :                         *error = EINVAL;
    3689           0 :                         return (1);
    3690             :                 }
    3691           0 :                 if (((int)cmh.cmsg_len + at) > tlen) {
    3692             :                         /* We don't have the complete CMSG. */
    3693           0 :                         *error = EINVAL;
    3694           0 :                         return (1);
    3695             :                 }
    3696           0 :                 if (cmh.cmsg_level == IPPROTO_SCTP) {
    3697           0 :                         switch (cmh.cmsg_type) {
    3698             :                         case SCTP_INIT:
    3699           0 :                                 if ((size_t)(cmh.cmsg_len - CMSG_ALIGN(sizeof(cmh))) < sizeof(struct sctp_initmsg)) {
    3700           0 :                                         *error = EINVAL;
    3701           0 :                                         return (1);
    3702             :                                 }
    3703           0 :                                 m_copydata(control, at + CMSG_ALIGN(sizeof(cmh)), sizeof(struct sctp_initmsg), (caddr_t)&initmsg);
    3704           0 :                                 if (initmsg.sinit_max_attempts)
    3705           0 :                                         stcb->asoc.max_init_times = initmsg.sinit_max_attempts;
    3706           0 :                                 if (initmsg.sinit_num_ostreams)
    3707           0 :                                         stcb->asoc.pre_open_streams = initmsg.sinit_num_ostreams;
    3708           0 :                                 if (initmsg.sinit_max_instreams)
    3709           0 :                                         stcb->asoc.max_inbound_streams = initmsg.sinit_max_instreams;
    3710           0 :                                 if (initmsg.sinit_max_init_timeo)
    3711           0 :                                         stcb->asoc.initial_init_rto_max = initmsg.sinit_max_init_timeo;
    3712           0 :                                 if (stcb->asoc.streamoutcnt < stcb->asoc.pre_open_streams) {
    3713             :                                         struct sctp_stream_out *tmp_str;
    3714             :                                         unsigned int i;
    3715             : #if defined(SCTP_DETAILED_STR_STATS)
    3716             :                                         int j;
    3717             : #endif
    3718             : 
    3719             :                                         /* Default is NOT correct */
    3720           0 :                                         SCTPDBG(SCTP_DEBUG_OUTPUT1, "Ok, default:%d pre_open:%d\n",
    3721             :                                                 stcb->asoc.streamoutcnt, stcb->asoc.pre_open_streams);
    3722           0 :                                         SCTP_TCB_UNLOCK(stcb);
    3723           0 :                                         SCTP_MALLOC(tmp_str,
    3724             :                                                     struct sctp_stream_out *,
    3725             :                                                     (stcb->asoc.pre_open_streams * sizeof(struct sctp_stream_out)),
    3726             :                                                     SCTP_M_STRMO);
    3727           0 :                                         SCTP_TCB_LOCK(stcb);
    3728           0 :                                         if (tmp_str != NULL) {
    3729           0 :                                                 SCTP_FREE(stcb->asoc.strmout, SCTP_M_STRMO);
    3730           0 :                                                 stcb->asoc.strmout = tmp_str;
    3731           0 :                                                 stcb->asoc.strm_realoutsize = stcb->asoc.streamoutcnt = stcb->asoc.pre_open_streams;
    3732             :                                         } else {
    3733           0 :                                                 stcb->asoc.pre_open_streams = stcb->asoc.streamoutcnt;
    3734             :                                         }
    3735           0 :                                         for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
    3736           0 :                                                 TAILQ_INIT(&stcb->asoc.strmout[i].outqueue);
    3737           0 :                                                 stcb->asoc.strmout[i].chunks_on_queues = 0;
    3738           0 :                                                 stcb->asoc.strmout[i].next_sequence_send = 0;
    3739             : #if defined(SCTP_DETAILED_STR_STATS)
    3740             :                                                 for (j = 0; j < SCTP_PR_SCTP_MAX + 1; j++) {
    3741             :                                                         stcb->asoc.strmout[i].abandoned_sent[j] = 0;
    3742             :                                                         stcb->asoc.strmout[i].abandoned_unsent[j] = 0;
    3743             :                                                 }
    3744             : #else
    3745           0 :                                                 stcb->asoc.strmout[i].abandoned_sent[0] = 0;
    3746           0 :                                                 stcb->asoc.strmout[i].abandoned_unsent[0] = 0;
    3747             : #endif
    3748           0 :                                                 stcb->asoc.strmout[i].stream_no = i;
    3749           0 :                                                 stcb->asoc.strmout[i].last_msg_incomplete = 0;
    3750           0 :                                                 stcb->asoc.ss_functions.sctp_ss_init_stream(&stcb->asoc.strmout[i], NULL);
    3751             :                                         }
    3752             :                                 }
    3753           0 :                                 break;
    3754             : #ifdef INET
    3755             :                         case SCTP_DSTADDRV4:
    3756             :                                 if ((size_t)(cmh.cmsg_len - CMSG_ALIGN(sizeof(cmh))) < sizeof(struct in_addr)) {
    3757             :                                         *error = EINVAL;
    3758             :                                         return (1);
    3759             :                                 }
    3760             :                                 memset(&sin, 0, sizeof(struct sockaddr_in));
    3761             :                                 sin.sin_family = AF_INET;
    3762             : #ifdef HAVE_SIN_LEN
    3763             :                                 sin.sin_len = sizeof(struct sockaddr_in);
    3764             : #endif
    3765             :                                 sin.sin_port = stcb->rport;
    3766             :                                 m_copydata(control, at + CMSG_ALIGN(sizeof(cmh)), sizeof(struct in_addr), (caddr_t)&sin.sin_addr);
    3767             :                                 if ((sin.sin_addr.s_addr == INADDR_ANY) ||
    3768             :                                     (sin.sin_addr.s_addr == INADDR_BROADCAST) ||
    3769             :                                     IN_MULTICAST(ntohl(sin.sin_addr.s_addr))) {
    3770             :                                         *error = EINVAL;
    3771             :                                         return (1);
    3772             :                                 }
    3773             :                                 if (sctp_add_remote_addr(stcb, (struct sockaddr *)&sin, NULL,
    3774             :                                                          SCTP_DONOT_SETSCOPE, SCTP_ADDR_IS_CONFIRMED)) {
    3775             :                                         *error = ENOBUFS;
    3776             :                                         return (1);
    3777             :                                 }
    3778             :                                 break;
    3779             : #endif
    3780             : #ifdef INET6
    3781             :                         case SCTP_DSTADDRV6:
    3782             :                                 if ((size_t)(cmh.cmsg_len - CMSG_ALIGN(sizeof(cmh))) < sizeof(struct in6_addr)) {
    3783             :                                         *error = EINVAL;
    3784             :                                         return (1);
    3785             :                                 }
    3786             :                                 memset(&sin6, 0, sizeof(struct sockaddr_in6));
    3787             :                                 sin6.sin6_family = AF_INET6;
    3788             : #ifdef HAVE_SIN6_LEN
    3789             :                                 sin6.sin6_len = sizeof(struct sockaddr_in6);
    3790             : #endif
    3791             :                                 sin6.sin6_port = stcb->rport;
    3792             :                                 m_copydata(control, at + CMSG_ALIGN(sizeof(cmh)), sizeof(struct in6_addr), (caddr_t)&sin6.sin6_addr);
    3793             :                                 if (IN6_IS_ADDR_UNSPECIFIED(&sin6.sin6_addr) ||
    3794             :                                     IN6_IS_ADDR_MULTICAST(&sin6.sin6_addr)) {
    3795             :                                         *error = EINVAL;
    3796             :                                         return (1);
    3797             :                                 }
    3798             : #ifdef INET
    3799             :                                 if (IN6_IS_ADDR_V4MAPPED(&sin6.sin6_addr)) {
    3800             :                                         in6_sin6_2_sin(&sin, &sin6);
    3801             :                                         if ((sin.sin_addr.s_addr == INADDR_ANY) ||
    3802             :                                             (sin.sin_addr.s_addr == INADDR_BROADCAST) ||
    3803             :                                             IN_MULTICAST(ntohl(sin.sin_addr.s_addr))) {
    3804             :                                                 *error = EINVAL;
    3805             :                                                 return (1);
    3806             :                                         }
    3807             :                                         if (sctp_add_remote_addr(stcb, (struct sockaddr *)&sin, NULL,
    3808             :                                                                  SCTP_DONOT_SETSCOPE, SCTP_ADDR_IS_CONFIRMED)) {
    3809             :                                                 *error = ENOBUFS;
    3810             :                                                 return (1);
    3811             :                                         }
    3812             :                                 } else
    3813             : #endif
    3814             :                                         if (sctp_add_remote_addr(stcb, (struct sockaddr *)&sin6, NULL,
    3815             :                                                                  SCTP_DONOT_SETSCOPE, SCTP_ADDR_IS_CONFIRMED)) {
    3816             :                                                 *error = ENOBUFS;
    3817             :                                                 return (1);
    3818             :                                         }
    3819             :                                 break;
    3820             : #endif
    3821             :                         default:
    3822           0 :                                 break;
    3823             :                         }
    3824             :                 }
    3825           0 :                 at += CMSG_ALIGN(cmh.cmsg_len);
    3826             :         }
    3827           0 :         return (0);
    3828             : }
    3829             : 
    3830             : static struct sctp_tcb *
    3831           0 : sctp_findassociation_cmsgs(struct sctp_inpcb **inp_p,
    3832             :                            uint16_t port,
    3833             :                            struct mbuf *control,
    3834             :                            struct sctp_nets **net_p,
    3835             :                            int *error)
    3836             : {
    3837             : #if defined(__Userspace_os_Windows)
    3838             :         WSACMSGHDR cmh;
    3839             : #else
    3840             :         struct cmsghdr cmh;
    3841             : #endif
    3842             :         int tlen, at;
    3843             :         struct sctp_tcb *stcb;
    3844             :         struct sockaddr *addr;
    3845             : #ifdef INET
    3846             :         struct sockaddr_in sin;
    3847             : #endif
    3848             : #ifdef INET6
    3849             :         struct sockaddr_in6 sin6;
    3850             : #endif
    3851             : 
    3852           0 :         tlen = SCTP_BUF_LEN(control);
    3853           0 :         at = 0;
    3854           0 :         while (at < tlen) {
    3855           0 :                 if ((tlen - at) < (int)CMSG_ALIGN(sizeof(cmh))) {
    3856             :                         /* There is not enough room for one more. */
    3857           0 :                         *error = EINVAL;
    3858           0 :                         return (NULL);
    3859             :                 }
    3860           0 :                 m_copydata(control, at, sizeof(cmh), (caddr_t)&cmh);
    3861           0 :                 if (cmh.cmsg_len < CMSG_ALIGN(sizeof(cmh))) {
    3862             :                         /* We dont't have a complete CMSG header. */
    3863           0 :                         *error = EINVAL;
    3864           0 :                         return (NULL);
    3865             :                 }
    3866           0 :                 if (((int)cmh.cmsg_len + at) > tlen) {
    3867             :                         /* We don't have the complete CMSG. */
    3868           0 :                         *error = EINVAL;
    3869           0 :                         return (NULL);
    3870             :                 }
    3871           0 :                 if (cmh.cmsg_level == IPPROTO_SCTP) {
    3872           0 :                         switch (cmh.cmsg_type) {
    3873             : #ifdef INET
    3874             :                         case SCTP_DSTADDRV4:
    3875             :                                 if ((size_t)(cmh.cmsg_len - CMSG_ALIGN(sizeof(cmh))) < sizeof(struct in_addr)) {
    3876             :                                         *error = EINVAL;
    3877             :                                         return (NULL);
    3878             :                                 }
    3879             :                                 memset(&sin, 0, sizeof(struct sockaddr_in));
    3880             :                                 sin.sin_family = AF_INET;
    3881             : #ifdef HAVE_SIN_LEN
    3882             :                                 sin.sin_len = sizeof(struct sockaddr_in);
    3883             : #endif
    3884             :                                 sin.sin_port = port;
    3885             :                                 m_copydata(control, at + CMSG_ALIGN(sizeof(cmh)), sizeof(struct in_addr), (caddr_t)&sin.sin_addr);
    3886             :                                 addr = (struct sockaddr *)&sin;
    3887             :                                 break;
    3888             : #endif
    3889             : #ifdef INET6
    3890             :                         case SCTP_DSTADDRV6:
    3891             :                                 if ((size_t)(cmh.cmsg_len - CMSG_ALIGN(sizeof(cmh))) < sizeof(struct in6_addr)) {
    3892             :                                         *error = EINVAL;
    3893             :                                         return (NULL);
    3894             :                                 }
    3895             :                                 memset(&sin6, 0, sizeof(struct sockaddr_in6));
    3896             :                                 sin6.sin6_family = AF_INET6;
    3897             : #ifdef HAVE_SIN6_LEN
    3898             :                                 sin6.sin6_len = sizeof(struct sockaddr_in6);
    3899             : #endif
    3900             :                                 sin6.sin6_port = port;
    3901             :                                 m_copydata(control, at + CMSG_ALIGN(sizeof(cmh)), sizeof(struct in6_addr), (caddr_t)&sin6.sin6_addr);
    3902             : #ifdef INET
    3903             :                                 if (IN6_IS_ADDR_V4MAPPED(&sin6.sin6_addr)) {
    3904             :                                         in6_sin6_2_sin(&sin, &sin6);
    3905             :                                         addr = (struct sockaddr *)&sin;
    3906             :                                 } else
    3907             : #endif
    3908             :                                         addr = (struct sockaddr *)&sin6;
    3909             :                                 break;
    3910             : #endif
    3911             :                         default:
    3912           0 :                                 addr = NULL;
    3913           0 :                                 break;
    3914             :                         }
    3915           0 :                         if (addr) {
    3916           0 :                                 stcb = sctp_findassociation_ep_addr(inp_p, addr, net_p, NULL, NULL);
    3917           0 :                                 if (stcb != NULL) {
    3918           0 :                                         return (stcb);
    3919             :                                 }
    3920             :                         }
    3921             :                 }
    3922           0 :                 at += CMSG_ALIGN(cmh.cmsg_len);
    3923             :         }
    3924           0 :         return (NULL);
    3925             : }
    3926             : 
    3927             : static struct mbuf *
    3928           0 : sctp_add_cookie(struct mbuf *init, int init_offset,
    3929             :     struct mbuf *initack, int initack_offset, struct sctp_state_cookie *stc_in, uint8_t **signature)
    3930             : {
    3931             :         struct mbuf *copy_init, *copy_initack, *m_at, *sig, *mret;
    3932             :         struct sctp_state_cookie *stc;
    3933             :         struct sctp_paramhdr *ph;
    3934             :         uint8_t *foo;
    3935             :         int sig_offset;
    3936             :         uint16_t cookie_sz;
    3937             : 
    3938           0 :         mret = sctp_get_mbuf_for_msg((sizeof(struct sctp_state_cookie) +
    3939             :                                       sizeof(struct sctp_paramhdr)), 0,
    3940             :                                      M_NOWAIT, 1, MT_DATA);
    3941           0 :         if (mret == NULL) {
    3942           0 :                 return (NULL);
    3943             :         }
    3944           0 :         copy_init = SCTP_M_COPYM(init, init_offset, M_COPYALL, M_NOWAIT);
    3945           0 :         if (copy_init == NULL) {
    3946           0 :                 sctp_m_freem(mret);
    3947           0 :                 return (NULL);
    3948             :         }
    3949             : #ifdef SCTP_MBUF_LOGGING
    3950             :         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
    3951             :                 sctp_log_mbc(copy_init, SCTP_MBUF_ICOPY);
    3952             :         }
    3953             : #endif
    3954           0 :         copy_initack = SCTP_M_COPYM(initack, initack_offset, M_COPYALL,
    3955             :             M_NOWAIT);
    3956           0 :         if (copy_initack == NULL) {
    3957           0 :                 sctp_m_freem(mret);
    3958           0 :                 sctp_m_freem(copy_init);
    3959           0 :                 return (NULL);
    3960             :         }
    3961             : #ifdef SCTP_MBUF_LOGGING
    3962             :         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
    3963             :                 sctp_log_mbc(copy_initack, SCTP_MBUF_ICOPY);
    3964             :         }
    3965             : #endif
    3966             :         /* easy side we just drop it on the end */
    3967           0 :         ph = mtod(mret, struct sctp_paramhdr *);
    3968           0 :         SCTP_BUF_LEN(mret) = sizeof(struct sctp_state_cookie) +
    3969             :             sizeof(struct sctp_paramhdr);
    3970           0 :         stc = (struct sctp_state_cookie *)((caddr_t)ph +
    3971             :             sizeof(struct sctp_paramhdr));
    3972           0 :         ph->param_type = htons(SCTP_STATE_COOKIE);
    3973           0 :         ph->param_length = 0;        /* fill in at the end */
    3974             :         /* Fill in the stc cookie data */
    3975           0 :         memcpy(stc, stc_in, sizeof(struct sctp_state_cookie));
    3976             : 
    3977             :         /* tack the INIT and then the INIT-ACK onto the chain */
    3978           0 :         cookie_sz = 0;
    3979           0 :         for (m_at = mret; m_at; m_at = SCTP_BUF_NEXT(m_at)) {
    3980           0 :                 cookie_sz += SCTP_BUF_LEN(m_at);
    3981           0 :                 if (SCTP_BUF_NEXT(m_at) == NULL) {
    3982           0 :                         SCTP_BUF_NEXT(m_at) = copy_init;
    3983           0 :                         break;
    3984             :                 }
    3985             :         }
    3986           0 :         for (m_at = copy_init; m_at; m_at = SCTP_BUF_NEXT(m_at)) {
    3987           0 :                 cookie_sz += SCTP_BUF_LEN(m_at);
    3988           0 :                 if (SCTP_BUF_NEXT(m_at) == NULL) {
    3989           0 :                         SCTP_BUF_NEXT(m_at) = copy_initack;
    3990           0 :                         break;
    3991             :                 }
    3992             :         }
    3993           0 :         for (m_at = copy_initack; m_at; m_at = SCTP_BUF_NEXT(m_at)) {
    3994           0 :                 cookie_sz += SCTP_BUF_LEN(m_at);
    3995           0 :                 if (SCTP_BUF_NEXT(m_at) == NULL) {
    3996           0 :                         break;
    3997             :                 }
    3998             :         }
    3999           0 :         sig = sctp_get_mbuf_for_msg(SCTP_SECRET_SIZE, 0, M_NOWAIT, 1, MT_DATA);
    4000           0 :         if (sig == NULL) {
    4001             :                 /* no space, so free the entire chain */
    4002           0 :                 sctp_m_freem(mret);
    4003           0 :                 return (NULL);
    4004             :         }
    4005           0 :         SCTP_BUF_LEN(sig) = 0;
    4006           0 :         SCTP_BUF_NEXT(m_at) = sig;
    4007           0 :         sig_offset = 0;
    4008           0 :         foo = (uint8_t *) (mtod(sig, caddr_t) + sig_offset);
    4009           0 :         memset(foo, 0, SCTP_SIGNATURE_SIZE);
    4010           0 :         *signature = foo;
    4011           0 :         SCTP_BUF_LEN(sig) += SCTP_SIGNATURE_SIZE;
    4012           0 :         cookie_sz += SCTP_SIGNATURE_SIZE;
    4013           0 :         ph->param_length = htons(cookie_sz);
    4014           0 :         return (mret);
    4015             : }
    4016             : 
    4017             : 
    4018             : static uint8_t
    4019           0 : sctp_get_ect(struct sctp_tcb *stcb)
    4020             : {
    4021           0 :         if ((stcb != NULL) && (stcb->asoc.ecn_supported == 1)) {
    4022           0 :                 return (SCTP_ECT0_BIT);
    4023             :         } else {
    4024           0 :                 return (0);
    4025             :         }
    4026             : }
    4027             : 
    4028             : #if defined(INET) || defined(INET6)
    4029             : static void
    4030             : sctp_handle_no_route(struct sctp_tcb *stcb,
    4031             :                      struct sctp_nets *net,
    4032             :                      int so_locked)
    4033             : {
    4034             :         SCTPDBG(SCTP_DEBUG_OUTPUT1, "dropped packet - no valid source addr\n");
    4035             : 
    4036             :         if (net) {
    4037             :                 SCTPDBG(SCTP_DEBUG_OUTPUT1, "Destination was ");
    4038             :                 SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT1, &net->ro._l_addr.sa);
    4039             :                 if (net->dest_state & SCTP_ADDR_CONFIRMED) {
    4040             :                         if ((net->dest_state & SCTP_ADDR_REACHABLE) && stcb) {
    4041             :                                 SCTPDBG(SCTP_DEBUG_OUTPUT1, "no route takes interface %p down\n", (void *)net);
    4042             :                                 sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN,
    4043             :                                                 stcb, 0,
    4044             :                                                 (void *)net,
    4045             :                                                 so_locked);
    4046             :                                 net->dest_state &= ~SCTP_ADDR_REACHABLE;
    4047             :                                 net->dest_state &= ~SCTP_ADDR_PF;
    4048             :                         }
    4049             :                 }
    4050             :                 if (stcb) {
    4051             :                         if (net == stcb->asoc.primary_destination) {
    4052             :                                 /* need a new primary */
    4053             :                                 struct sctp_nets *alt;
    4054             : 
    4055             :                                 alt = sctp_find_alternate_net(stcb, net, 0);
    4056             :                                 if (alt != net) {
    4057             :                                         if (stcb->asoc.alternate) {
    4058             :                                                 sctp_free_remote_addr(stcb->asoc.alternate);
    4059             :                                         }
    4060             :                                         stcb->asoc.alternate = alt;
    4061             :                                         atomic_add_int(&stcb->asoc.alternate->ref_count, 1);
    4062             :                                         if (net->ro._s_addr) {
    4063             :                                                 sctp_free_ifa(net->ro._s_addr);
    4064             :                                                 net->ro._s_addr = NULL;
    4065             :                                         }
    4066             :                                         net->src_addr_selected = 0;
    4067             :                                 }
    4068             :                         }
    4069             :                 }
    4070             :         }
    4071             : }
    4072             : #endif
    4073             : 
    4074             : static int
    4075           0 : sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
    4076             :     struct sctp_tcb *stcb,      /* may be NULL */
    4077             :     struct sctp_nets *net,
    4078             :     struct sockaddr *to,
    4079             :     struct mbuf *m,
    4080             :     uint32_t auth_offset,
    4081             :     struct sctp_auth_chunk *auth,
    4082             :     uint16_t auth_keyid,
    4083             :     int nofragment_flag,
    4084             :     int ecn_ok,
    4085             :     int out_of_asoc_ok,
    4086             :     uint16_t src_port,
    4087             :     uint16_t dest_port,
    4088             :     uint32_t v_tag,
    4089             :     uint16_t port,
    4090             :     union sctp_sockstore *over_addr,
    4091             : #if defined(__FreeBSD__)
    4092             :     uint8_t mflowtype, uint32_t mflowid,
    4093             : #endif
    4094             : #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
    4095             :     int so_locked SCTP_UNUSED
    4096             : #else
    4097             :     int so_locked
    4098             : #endif
    4099             :     )
    4100             : /* nofragment_flag to tell if IP_DF should be set (IPv4 only) */
    4101             : {
    4102             :         /**
    4103             :          * Given a mbuf chain (via SCTP_BUF_NEXT()) that holds a packet header
    4104             :          * WITH an SCTPHDR but no IP header, endpoint inp and sa structure:
    4105             :          * - fill in the HMAC digest of any AUTH chunk in the packet.
    4106             :          * - calculate and fill in the SCTP checksum.
    4107             :          * - prepend an IP address header.
    4108             :          * - if boundall use INADDR_ANY.
    4109             :          * - if boundspecific do source address selection.
    4110             :          * - set fragmentation option for ipV4.
    4111             :          * - On return from IP output, check/adjust mtu size of output
    4112             :          *   interface and smallest_mtu size as well.
    4113             :          */
    4114             :         /* Will need ifdefs around this */
    4115             : #ifdef __Panda__
    4116             :         pakhandle_type o_pak;
    4117             : #endif
    4118             :         struct mbuf *newm;
    4119             :         struct sctphdr *sctphdr;
    4120             :         int packet_length;
    4121             :         int ret;
    4122             : #if defined(INET) || defined(INET6)
    4123             :         uint32_t vrf_id;
    4124             : #endif
    4125             : #if defined(INET) || defined(INET6)
    4126             : #if !defined(__Panda__)
    4127             :         struct mbuf *o_pak;
    4128             : #endif
    4129             :         sctp_route_t *ro = NULL;
    4130             :         struct udphdr *udp = NULL;
    4131             : #endif
    4132             :         uint8_t tos_value;
    4133             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    4134             :         struct socket *so = NULL;
    4135             : #endif
    4136             : 
    4137             : #if defined(__APPLE__)
    4138             :         if (so_locked) {
    4139             :                 sctp_lock_assert(SCTP_INP_SO(inp));
    4140             :                 SCTP_TCB_LOCK_ASSERT(stcb);
    4141             :         } else {
    4142             :                 sctp_unlock_assert(SCTP_INP_SO(inp));
    4143             :         }
    4144             : #endif
    4145           0 :         if ((net) && (net->dest_state & SCTP_ADDR_OUT_OF_SCOPE)) {
    4146             :                 SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EFAULT);
    4147           0 :                 sctp_m_freem(m);
    4148           0 :                 return (EFAULT);
    4149             :         }
    4150             : #if defined(INET) || defined(INET6)
    4151             :         if (stcb) {
    4152             :                 vrf_id = stcb->asoc.vrf_id;
    4153             :         } else {
    4154             :                 vrf_id = inp->def_vrf_id;
    4155             :         }
    4156             : #endif
    4157             :         /* fill in the HMAC digest for any AUTH chunk in the packet */
    4158           0 :         if ((auth != NULL) && (stcb != NULL)) {
    4159           0 :                 sctp_fill_hmac_digest_m(m, auth_offset, auth, stcb, auth_keyid);
    4160             :         }
    4161             : 
    4162           0 :         if (net) {
    4163           0 :                 tos_value = net->dscp;
    4164           0 :         } else if (stcb) {
    4165           0 :                 tos_value = stcb->asoc.default_dscp;
    4166             :         } else {
    4167           0 :                 tos_value = inp->sctp_ep.default_dscp;
    4168             :         }
    4169             : 
    4170           0 :         switch (to->sa_family) {
    4171             : #ifdef INET
    4172             :         case AF_INET:
    4173             :         {
    4174             :                 struct ip *ip = NULL;
    4175             :                 sctp_route_t iproute;
    4176             :                 int len;
    4177             : 
    4178             :                 len = sizeof(struct ip) + sizeof(struct sctphdr);
    4179             :                 if (port) {
    4180             :                         len += sizeof(struct udphdr);
    4181             :                 }
    4182             :                 newm = sctp_get_mbuf_for_msg(len, 1, M_NOWAIT, 1, MT_DATA);
    4183             :                 if (newm == NULL) {
    4184             :                         sctp_m_freem(m);
    4185             :                         SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
    4186             :                         return (ENOMEM);
    4187             :                 }
    4188             :                 SCTP_ALIGN_TO_END(newm, len);
    4189             :                 SCTP_BUF_LEN(newm) = len;
    4190             :                 SCTP_BUF_NEXT(newm) = m;
    4191             :                 m = newm;
    4192             : #if defined(__FreeBSD__)
    4193             :                 if (net != NULL) {
    4194             :                         m->m_pkthdr.flowid = net->flowid;
    4195             :                         M_HASHTYPE_SET(m, net->flowtype);
    4196             :                 } else {
    4197             :                         m->m_pkthdr.flowid = mflowid;
    4198             :                         M_HASHTYPE_SET(m, mflowtype);
    4199             :                 }
    4200             : #endif
    4201             :                 packet_length = sctp_calculate_len(m);
    4202             :                 ip = mtod(m, struct ip *);
    4203             :                 ip->ip_v = IPVERSION;
    4204             :                 ip->ip_hl = (sizeof(struct ip) >> 2);
    4205             :                 if (tos_value == 0) {
    4206             :                         /*
    4207             :                          * This means especially, that it is not set at the
    4208             :                          * SCTP layer. So use the value from the IP layer.
    4209             :                          */
    4210             : #if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Panda__) || defined(__Windows__) || defined(__Userspace__)
    4211             :                         tos_value = inp->ip_inp.inp.inp_ip_tos;
    4212             : #else
    4213             :                         tos_value = inp->inp_ip_tos;
    4214             : #endif
    4215             :                 }
    4216             :                 tos_value &= 0xfc;
    4217             :                 if (ecn_ok) {
    4218             :                         tos_value |= sctp_get_ect(stcb);
    4219             :                 }
    4220             :                 if ((nofragment_flag) && (port == 0)) {
    4221             : #if defined(__FreeBSD__)
    4222             : #if __FreeBSD_version >= 1000000
    4223             :                         ip->ip_off = htons(IP_DF);
    4224             : #else
    4225             :                         ip->ip_off = IP_DF;
    4226             : #endif
    4227             : #elif defined(WITH_CONVERT_IP_OFF) || defined(__APPLE__) || defined(__Userspace__)
    4228             :                         ip->ip_off = IP_DF;
    4229             : #else
    4230             :                         ip->ip_off = htons(IP_DF);
    4231             : #endif
    4232             :                 } else {
    4233             : #if defined(__FreeBSD__) && __FreeBSD_version >= 1000000
    4234             :                         ip->ip_off = htons(0);
    4235             : #else
    4236             :                         ip->ip_off = 0;
    4237             : #endif
    4238             :                 }
    4239             : #if defined(__FreeBSD__)
    4240             :                 /* FreeBSD has a function for ip_id's */
    4241             :                 ip->ip_id = ip_newid();
    4242             : #elif defined(RANDOM_IP_ID)
    4243             :                 /* Apple has RANDOM_IP_ID switch */
    4244             :                 ip->ip_id = htons(ip_randomid());
    4245             : #elif defined(__Userspace__)
    4246             :                 ip->ip_id = htons(SCTP_IP_ID(inp)++);
    4247             : #else
    4248             :                 ip->ip_id = SCTP_IP_ID(inp)++;
    4249             : #endif
    4250             : 
    4251             : #if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Panda__) || defined(__Windows__) || defined(__Userspace__)
    4252             :                 ip->ip_ttl = inp->ip_inp.inp.inp_ip_ttl;
    4253             : #else
    4254             :                 ip->ip_ttl = inp->inp_ip_ttl;
    4255             : #endif
    4256             : #if defined(__FreeBSD__) && __FreeBSD_version >= 1000000
    4257             :                 ip->ip_len = htons(packet_length);
    4258             : #else
    4259             :                 ip->ip_len = packet_length;
    4260             : #endif
    4261             :                 ip->ip_tos = tos_value;
    4262             :                 if (port) {
    4263             :                         ip->ip_p = IPPROTO_UDP;
    4264             :                 } else {
    4265             :                         ip->ip_p = IPPROTO_SCTP;
    4266             :                 }
    4267             :                 ip->ip_sum = 0;
    4268             :                 if (net == NULL) {
    4269             :                         ro = &iproute;
    4270             :                         memset(&iproute, 0, sizeof(iproute));
    4271             : #ifdef HAVE_SA_LEN
    4272             :                         memcpy(&ro->ro_dst, to, to->sa_len);
    4273             : #else
    4274             :                         memcpy(&ro->ro_dst, to, sizeof(struct sockaddr_in));
    4275             : #endif
    4276             :                 } else {
    4277             :                         ro = (sctp_route_t *)&net->ro;
    4278             :                 }
    4279             :                 /* Now the address selection part */
    4280             :                 ip->ip_dst.s_addr = ((struct sockaddr_in *)to)->sin_addr.s_addr;
    4281             : 
    4282             :                 /* call the routine to select the src address */
    4283             :                 if (net && out_of_asoc_ok == 0) {
    4284             :                         if (net->ro._s_addr && (net->ro._s_addr->localifa_flags & (SCTP_BEING_DELETED|SCTP_ADDR_IFA_UNUSEABLE))) {
    4285             :                                 sctp_free_ifa(net->ro._s_addr);
    4286             :                                 net->ro._s_addr = NULL;
    4287             :                                 net->src_addr_selected = 0;
    4288             :                                 if (ro->ro_rt) {
    4289             :                                         RTFREE(ro->ro_rt);
    4290             :                                         ro->ro_rt = NULL;
    4291             :                                 }
    4292             :                         }
    4293             :                         if (net->src_addr_selected == 0) {
    4294             :                                 /* Cache the source address */
    4295             :                                 net->ro._s_addr = sctp_source_address_selection(inp,stcb,
    4296             :                                                                                 ro, net, 0,
    4297             :                                                                                 vrf_id);
    4298             :                                 net->src_addr_selected = 1;
    4299             :                         }
    4300             :                         if (net->ro._s_addr == NULL) {
    4301             :                                 /* No route to host */
    4302             :                                 net->src_addr_selected = 0;
    4303             :                                 sctp_handle_no_route(stcb, net, so_locked);
    4304             :                                 SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, EHOSTUNREACH);
    4305             :                                 sctp_m_freem(m);
    4306             :                                 return (EHOSTUNREACH);
    4307             :                         }
    4308             :                         ip->ip_src = net->ro._s_addr->address.sin.sin_addr;
    4309             :                 } else {
    4310             :                         if (over_addr == NULL) {
    4311             :                                 struct sctp_ifa *_lsrc;
    4312             : 
    4313             :                                 _lsrc = sctp_source_address_selection(inp, stcb, ro,
    4314             :                                                                       net,
    4315             :                                                                       out_of_asoc_ok,
    4316             :                                                                       vrf_id);
    4317             :                                 if (_lsrc == NULL) {
    4318             :                                         sctp_handle_no_route(stcb, net, so_locked);
    4319             :                                         SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, EHOSTUNREACH);
    4320             :                                         sctp_m_freem(m);
    4321             :                                         return (EHOSTUNREACH);
    4322             :                                 }
    4323             :                                 ip->ip_src = _lsrc->address.sin.sin_addr;
    4324             :                                 sctp_free_ifa(_lsrc);
    4325             :                         } else {
    4326             :                                 ip->ip_src = over_addr->sin.sin_addr;
    4327             :                                 SCTP_RTALLOC(ro, vrf_id);
    4328             :                         }
    4329             :                 }
    4330             :                 if (port) {
    4331             :                         if (htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)) == 0) {
    4332             :                                 sctp_handle_no_route(stcb, net, so_locked);
    4333             :                                 SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, EHOSTUNREACH);
    4334             :                                 sctp_m_freem(m);
    4335             :                                 return (EHOSTUNREACH);
    4336             :                         }
    4337             :                         udp = (struct udphdr *)((caddr_t)ip + sizeof(struct ip));
    4338             :                         udp->uh_sport = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port));
    4339             :                         udp->uh_dport = port;
    4340             :                         udp->uh_ulen = htons(packet_length - sizeof(struct ip));
    4341             : #if !defined(__Windows__) && !defined(__Userspace__)
    4342             : #if defined(__FreeBSD__) && ((__FreeBSD_version > 803000 && __FreeBSD_version < 900000) || __FreeBSD_version > 900000)
    4343             :                         if (V_udp_cksum) {
    4344             :                                 udp->uh_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, udp->uh_ulen + htons(IPPROTO_UDP));
    4345             :                         } else {
    4346             :                                 udp->uh_sum = 0;
    4347             :                         }
    4348             : #else
    4349             :                         udp->uh_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, udp->uh_ulen + htons(IPPROTO_UDP));
    4350             : #endif
    4351             : #else
    4352             :                         udp->uh_sum = 0;
    4353             : #endif
    4354             :                         sctphdr = (struct sctphdr *)((caddr_t)udp + sizeof(struct udphdr));
    4355             :                 } else {
    4356             :                         sctphdr = (struct sctphdr *)((caddr_t)ip + sizeof(struct ip));
    4357             :                 }
    4358             : 
    4359             :                 sctphdr->src_port = src_port;
    4360             :                 sctphdr->dest_port = dest_port;
    4361             :                 sctphdr->v_tag = v_tag;
    4362             :                 sctphdr->checksum = 0;
    4363             : 
    4364             :                 /*
    4365             :                  * If source address selection fails and we find no route
    4366             :                  * then the ip_output should fail as well with a
    4367             :                  * NO_ROUTE_TO_HOST type error. We probably should catch
    4368             :                  * that somewhere and abort the association right away
    4369             :                  * (assuming this is an INIT being sent).
    4370             :                  */
    4371             :                 if (ro->ro_rt == NULL) {
    4372             :                         /*
    4373             :                          * src addr selection failed to find a route (or
    4374             :                          * valid source addr), so we can't get there from
    4375             :                          * here (yet)!
    4376             :                          */
    4377             :                         sctp_handle_no_route(stcb, net, so_locked);
    4378             :                         SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, EHOSTUNREACH);
    4379             :                         sctp_m_freem(m);
    4380             :                         return (EHOSTUNREACH);
    4381             :                 }
    4382             :                 if (ro != &iproute) {
    4383             :                         memcpy(&iproute, ro, sizeof(*ro));
    4384             :                 }
    4385             :                 SCTPDBG(SCTP_DEBUG_OUTPUT3, "Calling ipv4 output routine from low level src addr:%x\n",
    4386             :                         (uint32_t) (ntohl(ip->ip_src.s_addr)));
    4387             :                 SCTPDBG(SCTP_DEBUG_OUTPUT3, "Destination is %x\n",
    4388             :                         (uint32_t)(ntohl(ip->ip_dst.s_addr)));
    4389             :                 SCTPDBG(SCTP_DEBUG_OUTPUT3, "RTP route is %p through\n",
    4390             :                         (void *)ro->ro_rt);
    4391             : 
    4392             :                 if (SCTP_GET_HEADER_FOR_OUTPUT(o_pak)) {
    4393             :                         /* failed to prepend data, give up */
    4394             :                         SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
    4395             :                         sctp_m_freem(m);
    4396             :                         return (ENOMEM);
    4397             :                 }
    4398             :                 SCTP_ATTACH_CHAIN(o_pak, m, packet_length);
    4399             :                 if (port) {
    4400             : #if defined(SCTP_WITH_NO_CSUM)
    4401             :                         SCTP_STAT_INCR(sctps_sendnocrc);
    4402             : #else
    4403             :                         sctphdr->checksum = sctp_calculate_cksum(m, sizeof(struct ip) + sizeof(struct udphdr));
    4404             :                         SCTP_STAT_INCR(sctps_sendswcrc);
    4405             : #endif
    4406             : #if defined(__FreeBSD__) && ((__FreeBSD_version > 803000 && __FreeBSD_version < 900000) || __FreeBSD_version > 900000)
    4407             :                         if (V_udp_cksum) {
    4408             :                                 SCTP_ENABLE_UDP_CSUM(o_pak);
    4409             :                         }
    4410             : #else
    4411             :                         SCTP_ENABLE_UDP_CSUM(o_pak);
    4412             : #endif
    4413             :                 } else {
    4414             : #if defined(SCTP_WITH_NO_CSUM)
    4415             :                         SCTP_STAT_INCR(sctps_sendnocrc);
    4416             : #else
    4417             : #if defined(__FreeBSD__) && __FreeBSD_version >= 800000
    4418             :                         m->m_pkthdr.csum_flags = CSUM_SCTP;
    4419             :                         m->m_pkthdr.csum_data = offsetof(struct sctphdr, checksum);
    4420             :                         SCTP_STAT_INCR(sctps_sendhwcrc);
    4421             : #else
    4422             :                         if (!(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
    4423             :                               (stcb) && (stcb->asoc.scope.loopback_scope))) {
    4424             :                                 sctphdr->checksum = sctp_calculate_cksum(m, sizeof(struct ip));
    4425             :                                 SCTP_STAT_INCR(sctps_sendswcrc);
    4426             :                         } else {
    4427             :                                 SCTP_STAT_INCR(sctps_sendnocrc);
    4428             :                         }
    4429             : #endif
    4430             : #endif
    4431             :                 }
    4432             : #ifdef SCTP_PACKET_LOGGING
    4433             :                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING)
    4434             :                         sctp_packet_log(o_pak);
    4435             : #endif
    4436             :                 /* send it out.  table id is taken from stcb */
    4437             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    4438             :                 if ((SCTP_BASE_SYSCTL(sctp_output_unlocked)) && (so_locked)) {
    4439             :                         so = SCTP_INP_SO(inp);
    4440             :                         SCTP_SOCKET_UNLOCK(so, 0);
    4441             :                 }
    4442             : #endif
    4443             :                 SCTP_IP_OUTPUT(ret, o_pak, ro, stcb, vrf_id);
    4444             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    4445             :                 if ((SCTP_BASE_SYSCTL(sctp_output_unlocked)) && (so_locked)) {
    4446             :                         atomic_add_int(&stcb->asoc.refcnt, 1);
    4447             :                         SCTP_TCB_UNLOCK(stcb);
    4448             :                         SCTP_SOCKET_LOCK(so, 0);
    4449             :                         SCTP_TCB_LOCK(stcb);
    4450             :                         atomic_subtract_int(&stcb->asoc.refcnt, 1);
    4451             :                 }
    4452             : #endif
    4453             :                 SCTP_STAT_INCR(sctps_sendpackets);
    4454             :                 SCTP_STAT_INCR_COUNTER64(sctps_outpackets);
    4455             :                 if (ret)
    4456             :                         SCTP_STAT_INCR(sctps_senderrors);
    4457             : 
    4458             :                 SCTPDBG(SCTP_DEBUG_OUTPUT3, "IP output returns %d\n", ret);
    4459             :                 if (net == NULL) {
    4460             :                         /* free tempy routes */
    4461             : #if defined(__FreeBSD__) && __FreeBSD_version > 901000
    4462             :                         RO_RTFREE(ro);
    4463             : #else
    4464             :                         if (ro->ro_rt) {
    4465             :                                 RTFREE(ro->ro_rt);
    4466             :                                 ro->ro_rt = NULL;
    4467             :                         }
    4468             : #endif
    4469             :                 } else {
    4470             :                         /* PMTU check versus smallest asoc MTU goes here */
    4471             :                         if ((ro->ro_rt != NULL) &&
    4472             :                             (net->ro._s_addr)) {
    4473             :                                 uint32_t mtu;
    4474             :                                 mtu = SCTP_GATHER_MTU_FROM_ROUTE(net->ro._s_addr, &net->ro._l_addr.sa, ro->ro_rt);
    4475             :                                 if (net->port) {
    4476             :                                         mtu -= sizeof(struct udphdr);
    4477             :                                 }
    4478             :                                 if (mtu && (stcb->asoc.smallest_mtu > mtu)) {
    4479             :                                         sctp_mtu_size_reset(inp, &stcb->asoc, mtu);
    4480             :                                         net->mtu = mtu;
    4481             :                                 }
    4482             :                         } else if (ro->ro_rt == NULL) {
    4483             :                                 /* route was freed */
    4484             :                                 if (net->ro._s_addr &&
    4485             :                                     net->src_addr_selected) {
    4486             :                                         sctp_free_ifa(net->ro._s_addr);
    4487             :                                         net->ro._s_addr = NULL;
    4488             :                                 }
    4489             :                                 net->src_addr_selected = 0;
    4490             :                         }
    4491             :                 }
    4492             :                 return (ret);
    4493             :         }
    4494             : #endif
    4495             : #ifdef INET6
    4496             :         case AF_INET6:
    4497             :         {
    4498             :                 uint32_t flowlabel, flowinfo;
    4499             :                 struct ip6_hdr *ip6h;
    4500             :                 struct route_in6 ip6route;
    4501             : #if !(defined(__Panda__) || defined(__Userspace__))
    4502             :                 struct ifnet *ifp;
    4503             : #endif
    4504             :                 struct sockaddr_in6 *sin6, tmp, *lsa6, lsa6_tmp;
    4505             :                 int prev_scope = 0;
    4506             : #ifdef SCTP_EMBEDDED_V6_SCOPE
    4507             :                 struct sockaddr_in6 lsa6_storage;
    4508             :                 int error;
    4509             : #endif
    4510             :                 u_short prev_port = 0;
    4511             :                 int len;
    4512             : 
    4513             :                 if (net) {
    4514             :                         flowlabel = net->flowlabel;
    4515             :                 } else if (stcb) {
    4516             :                         flowlabel = stcb->asoc.default_flowlabel;
    4517             :                 } else {
    4518             :                         flowlabel = inp->sctp_ep.default_flowlabel;
    4519             :                 }
    4520             :                 if (flowlabel == 0) {
    4521             :                         /*
    4522             :                          * This means especially, that it is not set at the
    4523             :                          * SCTP layer. So use the value from the IP layer.
    4524             :                          */
    4525             : #if defined(__APPLE__) && (!defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) && !defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION))
    4526             :                         flowlabel = ntohl(inp->ip_inp.inp.inp_flow);
    4527             : #else
    4528             :                         flowlabel = ntohl(((struct in6pcb *)inp)->in6p_flowinfo);
    4529             : #endif
    4530             :                 }
    4531             :                 flowlabel &= 0x000fffff;
    4532             :                 len = sizeof(struct ip6_hdr) + sizeof(struct sctphdr);
    4533             :                 if (port) {
    4534             :                         len += sizeof(struct udphdr);
    4535             :                 }
    4536             :                 newm = sctp_get_mbuf_for_msg(len, 1, M_NOWAIT, 1, MT_DATA);
    4537             :                 if (newm == NULL) {
    4538             :                         sctp_m_freem(m);
    4539             :                         SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
    4540             :                         return (ENOMEM);
    4541             :                 }
    4542             :                 SCTP_ALIGN_TO_END(newm, len);
    4543             :                 SCTP_BUF_LEN(newm) = len;
    4544             :                 SCTP_BUF_NEXT(newm) = m;
    4545             :                 m = newm;
    4546             : #if defined(__FreeBSD__)
    4547             :                 if (net != NULL) {
    4548             :                         m->m_pkthdr.flowid = net->flowid;
    4549             :                         M_HASHTYPE_SET(m, net->flowtype);
    4550             :                 } else {
    4551             :                         m->m_pkthdr.flowid = mflowid;
    4552             :                         M_HASHTYPE_SET(m, mflowtype);
    4553             :                 }
    4554             : #endif
    4555             :                 packet_length = sctp_calculate_len(m);
    4556             : 
    4557             :                 ip6h = mtod(m, struct ip6_hdr *);
    4558             :                 /* protect *sin6 from overwrite */
    4559             :                 sin6 = (struct sockaddr_in6 *)to;
    4560             :                 tmp = *sin6;
    4561             :                 sin6 = &tmp;
    4562             : 
    4563             : #ifdef SCTP_EMBEDDED_V6_SCOPE
    4564             :                 /* KAME hack: embed scopeid */
    4565             : #if defined(__APPLE__)
    4566             : #if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD)
    4567             :                 if (in6_embedscope(&sin6->sin6_addr, sin6, NULL, NULL) != 0)
    4568             : #else
    4569             :                 if (in6_embedscope(&sin6->sin6_addr, sin6, NULL, NULL, NULL) != 0)
    4570             : #endif
    4571             : #elif defined(SCTP_KAME)
    4572             :                 if (sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone)) != 0)
    4573             : #else
    4574             :                 if (in6_embedscope(&sin6->sin6_addr, sin6) != 0)
    4575             : #endif
    4576             :                 {
    4577             :                         SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
    4578             :                         return (EINVAL);
    4579             :                 }
    4580             : #endif /* SCTP_EMBEDDED_V6_SCOPE */
    4581             :                 if (net == NULL) {
    4582             :                         memset(&ip6route, 0, sizeof(ip6route));
    4583             :                         ro = (sctp_route_t *)&ip6route;
    4584             : #ifdef HAVE_SIN6_LEN
    4585             :                         memcpy(&ro->ro_dst, sin6, sin6->sin6_len);
    4586             : #else
    4587             :                         memcpy(&ro->ro_dst, sin6, sizeof(struct sockaddr_in6));
    4588             : #endif
    4589             :                 } else {
    4590             :                         ro = (sctp_route_t *)&net->ro;
    4591             :                 }
    4592             :                 /*
    4593             :                  * We assume here that inp_flow is in host byte order within
    4594             :                  * the TCB!
    4595             :                  */
    4596             :                 if (tos_value == 0) {
    4597             :                         /*
    4598             :                          * This means especially, that it is not set at the
    4599             :                          * SCTP layer. So use the value from the IP layer.
    4600             :                          */
    4601             : #if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Panda__) || defined(__Windows__) || defined(__Userspace__)
    4602             : #if defined(__APPLE__) && (!defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) && !defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION))
    4603             :                         tos_value = (ntohl(inp->ip_inp.inp.inp_flow) >> 20) & 0xff;
    4604             : #else
    4605             :                         tos_value = (ntohl(((struct in6pcb *)inp)->in6p_flowinfo) >> 20) & 0xff;
    4606             : #endif
    4607             : #endif
    4608             :                 }
    4609             :                 tos_value &= 0xfc;
    4610             :                 if (ecn_ok) {
    4611             :                         tos_value |= sctp_get_ect(stcb);
    4612             :                 }
    4613             :                 flowinfo = 0x06;
    4614             :                 flowinfo <<= 8;
    4615             :                 flowinfo |= tos_value;
    4616             :                 flowinfo <<= 20;
    4617             :                 flowinfo |= flowlabel;
    4618             :                 ip6h->ip6_flow = htonl(flowinfo);
    4619             :                 if (port) {
    4620             :                         ip6h->ip6_nxt = IPPROTO_UDP;
    4621             :                 } else {
    4622             :                         ip6h->ip6_nxt = IPPROTO_SCTP;
    4623             :                 }
    4624             :                 ip6h->ip6_plen = (packet_length - sizeof(struct ip6_hdr));
    4625             :                 ip6h->ip6_dst = sin6->sin6_addr;
    4626             : 
    4627             :                 /*
    4628             :                  * Add SRC address selection here: we can only reuse to a
    4629             :                  * limited degree the kame src-addr-sel, since we can try
    4630             :                  * their selection but it may not be bound.
    4631             :                  */
    4632             :                 bzero(&lsa6_tmp, sizeof(lsa6_tmp));
    4633             :                 lsa6_tmp.sin6_family = AF_INET6;
    4634             : #ifdef HAVE_SIN6_LEN
    4635             :                 lsa6_tmp.sin6_len = sizeof(lsa6_tmp);
    4636             : #endif
    4637             :                 lsa6 = &lsa6_tmp;
    4638             :                 if (net && out_of_asoc_ok == 0) {
    4639             :                         if (net->ro._s_addr && (net->ro._s_addr->localifa_flags & (SCTP_BEING_DELETED|SCTP_ADDR_IFA_UNUSEABLE))) {
    4640             :                                 sctp_free_ifa(net->ro._s_addr);
    4641             :                                 net->ro._s_addr = NULL;
    4642             :                                 net->src_addr_selected = 0;
    4643             :                                 if (ro->ro_rt) {
    4644             :                                         RTFREE(ro->ro_rt);
    4645             :                                         ro->ro_rt = NULL;
    4646             :                                 }
    4647             :                         }
    4648             :                         if (net->src_addr_selected == 0) {
    4649             : #ifdef SCTP_EMBEDDED_V6_SCOPE
    4650             :                                 sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
    4651             :                                 /* KAME hack: embed scopeid */
    4652             : #if defined(__APPLE__)
    4653             : #if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD)
    4654             :                                 if (in6_embedscope(&sin6->sin6_addr, sin6, NULL, NULL) != 0)
    4655             : #else
    4656             :                                 if (in6_embedscope(&sin6->sin6_addr, sin6, NULL, NULL, NULL) != 0)
    4657             : #endif
    4658             : #elif defined(SCTP_KAME)
    4659             :                                 if (sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone)) != 0)
    4660             : #else
    4661             :                                 if (in6_embedscope(&sin6->sin6_addr, sin6) != 0)
    4662             : #endif
    4663             :                                 {
    4664             :                                         SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
    4665             :                                         return (EINVAL);
    4666             :                                 }
    4667             : #endif /* SCTP_EMBEDDED_V6_SCOPE */
    4668             :                                 /* Cache the source address */
    4669             :                                 net->ro._s_addr = sctp_source_address_selection(inp,
    4670             :                                                                                 stcb,
    4671             :                                                                                 ro,
    4672             :                                                                                 net,
    4673             :                                                                                 0,
    4674             :                                                                                 vrf_id);
    4675             : #ifdef SCTP_EMBEDDED_V6_SCOPE
    4676             : #ifdef SCTP_KAME
    4677             :                                 (void)sa6_recoverscope(sin6);
    4678             : #else
    4679             :                                 (void)in6_recoverscope(sin6, &sin6->sin6_addr, NULL);
    4680             : #endif  /* SCTP_KAME */
    4681             : #endif  /* SCTP_EMBEDDED_V6_SCOPE */
    4682             :                                 net->src_addr_selected = 1;
    4683             :                         }
    4684             :                         if (net->ro._s_addr == NULL) {
    4685             :                                 SCTPDBG(SCTP_DEBUG_OUTPUT3, "V6:No route to host\n");
    4686             :                                 net->src_addr_selected = 0;
    4687             :                                 sctp_handle_no_route(stcb, net, so_locked);
    4688             :                                 SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, EHOSTUNREACH);
    4689             :                                 sctp_m_freem(m);
    4690             :                                 return (EHOSTUNREACH);
    4691             :                         }
    4692             :                         lsa6->sin6_addr = net->ro._s_addr->address.sin6.sin6_addr;
    4693             :                 } else {
    4694             : #ifdef SCTP_EMBEDDED_V6_SCOPE
    4695             :                         sin6 = (struct sockaddr_in6 *)&ro->ro_dst;
    4696             :                         /* KAME hack: embed scopeid */
    4697             : #if defined(__APPLE__)
    4698             : #if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD)
    4699             :                         if (in6_embedscope(&sin6->sin6_addr, sin6, NULL, NULL) != 0)
    4700             : #else
    4701             :                         if (in6_embedscope(&sin6->sin6_addr, sin6, NULL, NULL, NULL) != 0)
    4702             : #endif
    4703             : #elif defined(SCTP_KAME)
    4704             :                         if (sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone)) != 0)
    4705             : #else
    4706             :                         if (in6_embedscope(&sin6->sin6_addr, sin6) != 0)
    4707             : #endif
    4708             :                           {
    4709             :                                 SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
    4710             :                                 return (EINVAL);
    4711             :                           }
    4712             : #endif /* SCTP_EMBEDDED_V6_SCOPE */
    4713             :                         if (over_addr == NULL) {
    4714             :                                 struct sctp_ifa *_lsrc;
    4715             : 
    4716             :                                 _lsrc = sctp_source_address_selection(inp, stcb, ro,
    4717             :                                                                       net,
    4718             :                                                                       out_of_asoc_ok,
    4719             :                                                                       vrf_id);
    4720             :                                 if (_lsrc == NULL) {
    4721             :                                         sctp_handle_no_route(stcb, net, so_locked);
    4722             :                                         SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, EHOSTUNREACH);
    4723             :                                         sctp_m_freem(m);
    4724             :                                         return (EHOSTUNREACH);
    4725             :                                 }
    4726             :                                 lsa6->sin6_addr = _lsrc->address.sin6.sin6_addr;
    4727             :                                 sctp_free_ifa(_lsrc);
    4728             :                         } else {
    4729             :                                 lsa6->sin6_addr = over_addr->sin6.sin6_addr;
    4730             :                                 SCTP_RTALLOC(ro, vrf_id);
    4731             :                         }
    4732             : #ifdef SCTP_EMBEDDED_V6_SCOPE
    4733             : #ifdef SCTP_KAME
    4734             :                         (void)sa6_recoverscope(sin6);
    4735             : #else
    4736             :                         (void)in6_recoverscope(sin6, &sin6->sin6_addr, NULL);
    4737             : #endif  /* SCTP_KAME */
    4738             : #endif  /* SCTP_EMBEDDED_V6_SCOPE */
    4739             :                 }
    4740             :                 lsa6->sin6_port = inp->sctp_lport;
    4741             : 
    4742             :                 if (ro->ro_rt == NULL) {
    4743             :                         /*
    4744             :                          * src addr selection failed to find a route (or
    4745             :                          * valid source addr), so we can't get there from
    4746             :                          * here!
    4747             :                          */
    4748             :                         sctp_handle_no_route(stcb, net, so_locked);
    4749             :                         SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, EHOSTUNREACH);
    4750             :                         sctp_m_freem(m);
    4751             :                         return (EHOSTUNREACH);
    4752             :                 }
    4753             : #ifndef SCOPEDROUTING
    4754             : #ifdef SCTP_EMBEDDED_V6_SCOPE
    4755             :                 /*
    4756             :                  * XXX: sa6 may not have a valid sin6_scope_id in the
    4757             :                  * non-SCOPEDROUTING case.
    4758             :                  */
    4759             :                 bzero(&lsa6_storage, sizeof(lsa6_storage));
    4760             :                 lsa6_storage.sin6_family = AF_INET6;
    4761             : #ifdef HAVE_SIN6_LEN
    4762             :                 lsa6_storage.sin6_len = sizeof(lsa6_storage);
    4763             : #endif
    4764             : #ifdef SCTP_KAME
    4765             :                 lsa6_storage.sin6_addr = lsa6->sin6_addr;
    4766             :                 if ((error = sa6_recoverscope(&lsa6_storage)) != 0) {
    4767             : #else
    4768             :                 if ((error = in6_recoverscope(&lsa6_storage, &lsa6->sin6_addr,
    4769             :                     NULL)) != 0) {
    4770             : #endif                          /* SCTP_KAME */
    4771             :                         SCTPDBG(SCTP_DEBUG_OUTPUT3, "recover scope fails error %d\n", error);
    4772             :                         sctp_m_freem(m);
    4773             :                         return (error);
    4774             :                 }
    4775             :                 /* XXX */
    4776             :                 lsa6_storage.sin6_addr = lsa6->sin6_addr;
    4777             :                 lsa6_storage.sin6_port = inp->sctp_lport;
    4778             :                 lsa6 = &lsa6_storage;
    4779             : #endif /* SCTP_EMBEDDED_V6_SCOPE */
    4780             : #endif /* SCOPEDROUTING */
    4781             :                 ip6h->ip6_src = lsa6->sin6_addr;
    4782             : 
    4783             :                 if (port) {
    4784             :                         if (htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)) == 0) {
    4785             :                                 sctp_handle_no_route(stcb, net, so_locked);
    4786             :                                 SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, EHOSTUNREACH);
    4787             :                                 sctp_m_freem(m);
    4788             :                                 return (EHOSTUNREACH);
    4789             :                         }
    4790             :                         udp = (struct udphdr *)((caddr_t)ip6h + sizeof(struct ip6_hdr));
    4791             :                         udp->uh_sport = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port));
    4792             :                         udp->uh_dport = port;
    4793             :                         udp->uh_ulen = htons(packet_length - sizeof(struct ip6_hdr));
    4794             :                         udp->uh_sum = 0;
    4795             :                         sctphdr = (struct sctphdr *)((caddr_t)udp + sizeof(struct udphdr));
    4796             :                 } else {
    4797             :                         sctphdr = (struct sctphdr *)((caddr_t)ip6h + sizeof(struct ip6_hdr));
    4798             :                 }
    4799             : 
    4800             :                 sctphdr->src_port = src_port;
    4801             :                 sctphdr->dest_port = dest_port;
    4802             :                 sctphdr->v_tag = v_tag;
    4803             :                 sctphdr->checksum = 0;
    4804             : 
    4805             :                 /*
    4806             :                  * We set the hop limit now since there is a good chance
    4807             :                  * that our ro pointer is now filled
    4808             :                  */
    4809             :                 ip6h->ip6_hlim = SCTP_GET_HLIM(inp, ro);
    4810             : #if !(defined(__Panda__) || defined(__Userspace__))
    4811             :                 ifp = SCTP_GET_IFN_VOID_FROM_ROUTE(ro);
    4812             : #endif
    4813             : 
    4814             : #ifdef SCTP_DEBUG
    4815             :                 /* Copy to be sure something bad is not happening */
    4816             :                 sin6->sin6_addr = ip6h->ip6_dst;
    4817             :                 lsa6->sin6_addr = ip6h->ip6_src;
    4818             : #endif
    4819             : 
    4820             :                 SCTPDBG(SCTP_DEBUG_OUTPUT3, "Calling ipv6 output routine from low level\n");
    4821             :                 SCTPDBG(SCTP_DEBUG_OUTPUT3, "src: ");
    4822             :                 SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT3, (struct sockaddr *)lsa6);
    4823             :                 SCTPDBG(SCTP_DEBUG_OUTPUT3, "dst: ");
    4824             :                 SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT3, (struct sockaddr *)sin6);
    4825             :                 if (net) {
    4826             :                         sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
    4827             :                         /* preserve the port and scope for link local send */
    4828             :                         prev_scope = sin6->sin6_scope_id;
    4829             :                         prev_port = sin6->sin6_port;
    4830             :                 }
    4831             : 
    4832             :                 if (SCTP_GET_HEADER_FOR_OUTPUT(o_pak)) {
    4833             :                         /* failed to prepend data, give up */
    4834             :                         sctp_m_freem(m);
    4835             :                         SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
    4836             :                         return (ENOMEM);
    4837             :                 }
    4838             :                 SCTP_ATTACH_CHAIN(o_pak, m, packet_length);
    4839             :                 if (port) {
    4840             : #if defined(SCTP_WITH_NO_CSUM)
    4841             :                         SCTP_STAT_INCR(sctps_sendnocrc);
    4842             : #else
    4843             :                         sctphdr->checksum = sctp_calculate_cksum(m, sizeof(struct ip6_hdr) + sizeof(struct udphdr));
    4844             :                         SCTP_STAT_INCR(sctps_sendswcrc);
    4845             : #endif
    4846             : #if defined(__Windows__)
    4847             :                         udp->uh_sum = 0;
    4848             : #elif !defined(__Userspace__)
    4849             :                         if ((udp->uh_sum = in6_cksum(o_pak, IPPROTO_UDP, sizeof(struct ip6_hdr), packet_length - sizeof(struct ip6_hdr))) == 0) {
    4850             :                                 udp->uh_sum = 0xffff;
    4851             :                         }
    4852             : #endif
    4853             :                 } else {
    4854             : #if defined(SCTP_WITH_NO_CSUM)
    4855             :                         SCTP_STAT_INCR(sctps_sendnocrc);
    4856             : #else
    4857             : #if defined(__FreeBSD__) && __FreeBSD_version >= 800000
    4858             : #if __FreeBSD_version < 900000
    4859             :                         sctphdr->checksum = sctp_calculate_cksum(m, sizeof(struct ip6_hdr));
    4860             :                         SCTP_STAT_INCR(sctps_sendswcrc);
    4861             : #else
    4862             : #if __FreeBSD_version > 901000
    4863             :                         m->m_pkthdr.csum_flags = CSUM_SCTP_IPV6;
    4864             : #else
    4865             :                         m->m_pkthdr.csum_flags = CSUM_SCTP;
    4866             : #endif
    4867             :                         m->m_pkthdr.csum_data = offsetof(struct sctphdr, checksum);
    4868             :                         SCTP_STAT_INCR(sctps_sendhwcrc);
    4869             : #endif
    4870             : #else
    4871             :                         if (!(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
    4872             :                               (stcb) && (stcb->asoc.scope.loopback_scope))) {
    4873             :                                 sctphdr->checksum = sctp_calculate_cksum(m, sizeof(struct ip6_hdr));
    4874             :                                 SCTP_STAT_INCR(sctps_sendswcrc);
    4875             :                         } else {
    4876             :                                 SCTP_STAT_INCR(sctps_sendnocrc);
    4877             :                         }
    4878             : #endif
    4879             : #endif
    4880             :                 }
    4881             :                 /* send it out. table id is taken from stcb */
    4882             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    4883             :                 if ((SCTP_BASE_SYSCTL(sctp_output_unlocked)) && (so_locked)) {
    4884             :                         so = SCTP_INP_SO(inp);
    4885             :                         SCTP_SOCKET_UNLOCK(so, 0);
    4886             :                 }
    4887             : #endif
    4888             : #ifdef SCTP_PACKET_LOGGING
    4889             :                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING)
    4890             :                         sctp_packet_log(o_pak);
    4891             : #endif
    4892             : #if !(defined(__Panda__) || defined(__Userspace__))
    4893             :                 SCTP_IP6_OUTPUT(ret, o_pak, (struct route_in6 *)ro, &ifp, stcb, vrf_id);
    4894             : #else
    4895             :                 SCTP_IP6_OUTPUT(ret, o_pak, (struct route_in6 *)ro, NULL, stcb, vrf_id);
    4896             : #endif
    4897             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    4898             :                 if ((SCTP_BASE_SYSCTL(sctp_output_unlocked)) && (so_locked)) {
    4899             :                         atomic_add_int(&stcb->asoc.refcnt, 1);
    4900             :                         SCTP_TCB_UNLOCK(stcb);
    4901             :                         SCTP_SOCKET_LOCK(so, 0);
    4902             :                         SCTP_TCB_LOCK(stcb);
    4903             :                         atomic_subtract_int(&stcb->asoc.refcnt, 1);
    4904             :                 }
    4905             : #endif
    4906             :                 if (net) {
    4907             :                         /* for link local this must be done */
    4908             :                         sin6->sin6_scope_id = prev_scope;
    4909             :                         sin6->sin6_port = prev_port;
    4910             :                 }
    4911             :                 SCTPDBG(SCTP_DEBUG_OUTPUT3, "return from send is %d\n", ret);
    4912             :                 SCTP_STAT_INCR(sctps_sendpackets);
    4913             :                 SCTP_STAT_INCR_COUNTER64(sctps_outpackets);
    4914             :                 if (ret) {
    4915             :                         SCTP_STAT_INCR(sctps_senderrors);
    4916             :                 }
    4917             :                 if (net == NULL) {
    4918             :                         /* Now if we had a temp route free it */
    4919             : #if defined(__FreeBSD__) && __FreeBSD_version > 901000
    4920             :                         RO_RTFREE(ro);
    4921             : #else
    4922             :                         if (ro->ro_rt) {
    4923             :                                 RTFREE(ro->ro_rt);
    4924             :                                 ro->ro_rt = NULL;
    4925             :                         }
    4926             : #endif
    4927             :                 } else {
    4928             :                         /* PMTU check versus smallest asoc MTU goes here */
    4929             :                         if (ro->ro_rt == NULL) {
    4930             :                                 /* Route was freed */
    4931             :                                 if (net->ro._s_addr &&
    4932             :                                     net->src_addr_selected) {
    4933             :                                         sctp_free_ifa(net->ro._s_addr);
    4934             :                                         net->ro._s_addr = NULL;
    4935             :                                 }
    4936             :                                 net->src_addr_selected = 0;
    4937             :                         }
    4938             :                         if ((ro->ro_rt != NULL) &&
    4939             :                             (net->ro._s_addr)) {
    4940             :                                 uint32_t mtu;
    4941             :                                 mtu = SCTP_GATHER_MTU_FROM_ROUTE(net->ro._s_addr, &net->ro._l_addr.sa, ro->ro_rt);
    4942             :                                 if (mtu &&
    4943             :                                     (stcb->asoc.smallest_mtu > mtu)) {
    4944             :                                         sctp_mtu_size_reset(inp, &stcb->asoc, mtu);
    4945             :                                         net->mtu = mtu;
    4946             :                                         if (net->port) {
    4947             :                                                 net->mtu -= sizeof(struct udphdr);
    4948             :                                         }
    4949             :                                 }
    4950             :                         }
    4951             : #if !defined(__Panda__) && !defined(__Userspace__)
    4952             :                         else if (ifp) {
    4953             : #if defined(__Windows__)
    4954             : #define ND_IFINFO(ifp)  (ifp)
    4955             : #define linkmtu         if_mtu
    4956             : #endif
    4957             :                                 if (ND_IFINFO(ifp)->linkmtu &&
    4958             :                                     (stcb->asoc.smallest_mtu > ND_IFINFO(ifp)->linkmtu)) {
    4959             :                                         sctp_mtu_size_reset(inp,
    4960             :                                             &stcb->asoc,
    4961             :                                             ND_IFINFO(ifp)->linkmtu);
    4962             :                                 }
    4963             :                         }
    4964             : #endif
    4965             :                 }
    4966             :                 return (ret);
    4967             :         }
    4968             : #endif
    4969             : #if defined(__Userspace__)
    4970             :         case AF_CONN:
    4971             :         {
    4972             :                 char *buffer;
    4973             :                 struct sockaddr_conn *sconn;
    4974             :                 int len;
    4975             : 
    4976           0 :                 sconn = (struct sockaddr_conn *)to;
    4977           0 :                 len = sizeof(struct sctphdr);
    4978           0 :                 newm = sctp_get_mbuf_for_msg(len, 1, M_NOWAIT, 1, MT_DATA);
    4979           0 :                 if (newm == NULL) {
    4980           0 :                         sctp_m_freem(m);
    4981             :                         SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
    4982           0 :                         return (ENOMEM);
    4983             :                 }
    4984           0 :                 SCTP_ALIGN_TO_END(newm, len);
    4985           0 :                 SCTP_BUF_LEN(newm) = len;
    4986           0 :                 SCTP_BUF_NEXT(newm) = m;
    4987           0 :                 m = newm;
    4988           0 :                 packet_length = sctp_calculate_len(m);
    4989           0 :                 sctphdr = mtod(m, struct sctphdr *);
    4990           0 :                 sctphdr->src_port = src_port;
    4991           0 :                 sctphdr->dest_port = dest_port;
    4992           0 :                 sctphdr->v_tag = v_tag;
    4993           0 :                 sctphdr->checksum = 0;
    4994             : #if defined(SCTP_WITH_NO_CSUM)
    4995             :                 SCTP_STAT_INCR(sctps_sendnocrc);
    4996             : #else
    4997           0 :                 sctphdr->checksum = sctp_calculate_cksum(m, 0);
    4998           0 :                 SCTP_STAT_INCR(sctps_sendswcrc);
    4999             : #endif
    5000           0 :                 if (tos_value == 0) {
    5001           0 :                         tos_value = inp->ip_inp.inp.inp_ip_tos;
    5002             :                 }
    5003           0 :                 tos_value &= 0xfc;
    5004           0 :                 if (ecn_ok) {
    5005           0 :                         tos_value |= sctp_get_ect(stcb);
    5006             :                 }
    5007             :                 /* Don't alloc/free for each packet */
    5008           0 :                 if ((buffer = malloc(packet_length)) != NULL) {
    5009           0 :                         m_copydata(m, 0, packet_length, buffer);
    5010           0 :                         ret = SCTP_BASE_VAR(conn_output)(sconn->sconn_addr, buffer, packet_length, tos_value, nofragment_flag);
    5011           0 :                         free(buffer);
    5012             :                 } else {
    5013           0 :                         ret = ENOMEM;
    5014             :                 }
    5015           0 :                 sctp_m_freem(m);
    5016           0 :                 return (ret);
    5017             :         }
    5018             : #endif
    5019             :         default:
    5020           0 :                 SCTPDBG(SCTP_DEBUG_OUTPUT1, "Unknown protocol (TSNH) type %d\n",
    5021             :                         ((struct sockaddr *)to)->sa_family);
    5022           0 :                 sctp_m_freem(m);
    5023             :                 SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EFAULT);
    5024           0 :                 return (EFAULT);
    5025             :         }
    5026             : }
    5027             : 
    5028             : 
    5029             : void
    5030           0 : sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked
    5031             : #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
    5032             :     SCTP_UNUSED
    5033             : #endif
    5034             :     )
    5035             : {
    5036             :         struct mbuf *m, *m_last;
    5037             :         struct sctp_nets *net;
    5038             :         struct sctp_init_chunk *init;
    5039             :         struct sctp_supported_addr_param *sup_addr;
    5040             :         struct sctp_adaptation_layer_indication *ali;
    5041             :         struct sctp_supported_chunk_types_param *pr_supported;
    5042             :         struct sctp_paramhdr *ph;
    5043           0 :         int cnt_inits_to = 0;
    5044             :         int ret;
    5045             :         uint16_t num_ext, chunk_len, padding_len, parameter_len;
    5046             : 
    5047             : #if defined(__APPLE__)
    5048             :         if (so_locked) {
    5049             :                 sctp_lock_assert(SCTP_INP_SO(inp));
    5050             :         } else {
    5051             :                 sctp_unlock_assert(SCTP_INP_SO(inp));
    5052             :         }
    5053             : #endif
    5054             :         /* INIT's always go to the primary (and usually ONLY address) */
    5055           0 :         net = stcb->asoc.primary_destination;
    5056           0 :         if (net == NULL) {
    5057           0 :                 net = TAILQ_FIRST(&stcb->asoc.nets);
    5058           0 :                 if (net == NULL) {
    5059             :                         /* TSNH */
    5060           0 :                         return;
    5061             :                 }
    5062             :                 /* we confirm any address we send an INIT to */
    5063           0 :                 net->dest_state &= ~SCTP_ADDR_UNCONFIRMED;
    5064           0 :                 (void)sctp_set_primary_addr(stcb, NULL, net);
    5065             :         } else {
    5066             :                 /* we confirm any address we send an INIT to */
    5067           0 :                 net->dest_state &= ~SCTP_ADDR_UNCONFIRMED;
    5068             :         }
    5069           0 :         SCTPDBG(SCTP_DEBUG_OUTPUT4, "Sending INIT\n");
    5070             : #ifdef INET6
    5071             :         if (net->ro._l_addr.sa.sa_family == AF_INET6) {
    5072             :                 /*
    5073             :                  * special hook, if we are sending to link local it will not
    5074             :                  * show up in our private address count.
    5075             :                  */
    5076             :                 if (IN6_IS_ADDR_LINKLOCAL(&net->ro._l_addr.sin6.sin6_addr))
    5077             :                         cnt_inits_to = 1;
    5078             :         }
    5079             : #endif
    5080           0 :         if (SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
    5081             :                 /* This case should not happen */
    5082           0 :                 SCTPDBG(SCTP_DEBUG_OUTPUT4, "Sending INIT - failed timer?\n");
    5083           0 :                 return;
    5084             :         }
    5085             :         /* start the INIT timer */
    5086           0 :         sctp_timer_start(SCTP_TIMER_TYPE_INIT, inp, stcb, net);
    5087             : 
    5088           0 :         m = sctp_get_mbuf_for_msg(MCLBYTES, 1, M_NOWAIT, 1, MT_DATA);
    5089           0 :         if (m == NULL) {
    5090             :                 /* No memory, INIT timer will re-attempt. */
    5091           0 :                 SCTPDBG(SCTP_DEBUG_OUTPUT4, "Sending INIT - mbuf?\n");
    5092           0 :                 return;
    5093             :         }
    5094           0 :         chunk_len = (uint16_t)sizeof(struct sctp_init_chunk);
    5095           0 :         padding_len = 0;
    5096             :         /* Now lets put the chunk header in place */
    5097           0 :         init = mtod(m, struct sctp_init_chunk *);
    5098             :         /* now the chunk header */
    5099           0 :         init->ch.chunk_type = SCTP_INITIATION;
    5100           0 :         init->ch.chunk_flags = 0;
    5101             :         /* fill in later from mbuf we build */
    5102           0 :         init->ch.chunk_length = 0;
    5103             :         /* place in my tag */
    5104           0 :         init->init.initiate_tag = htonl(stcb->asoc.my_vtag);
    5105             :         /* set up some of the credits. */
    5106           0 :         init->init.a_rwnd = htonl(max(inp->sctp_socket?SCTP_SB_LIMIT_RCV(inp->sctp_socket):0,
    5107             :                                       SCTP_MINIMAL_RWND));
    5108           0 :         init->init.num_outbound_streams = htons(stcb->asoc.pre_open_streams);
    5109           0 :         init->init.num_inbound_streams = htons(stcb->asoc.max_inbound_streams);
    5110           0 :         init->init.initial_tsn = htonl(stcb->asoc.init_seq_number);
    5111             : 
    5112             :         /* Adaptation layer indication parameter */
    5113           0 :         if (inp->sctp_ep.adaptation_layer_indicator_provided) {
    5114           0 :                 parameter_len = (uint16_t)sizeof(struct sctp_adaptation_layer_indication);
    5115           0 :                 ali = (struct sctp_adaptation_layer_indication *)(mtod(m, caddr_t) + chunk_len);
    5116           0 :                 ali->ph.param_type = htons(SCTP_ULP_ADAPTATION);
    5117           0 :                 ali->ph.param_length = htons(parameter_len);
    5118           0 :                 ali->indication = htonl(inp->sctp_ep.adaptation_layer_indicator);
    5119           0 :                 chunk_len += parameter_len;
    5120             :         }
    5121             : 
    5122             :         /* ECN parameter */
    5123           0 :         if (stcb->asoc.ecn_supported == 1) {
    5124           0 :                 parameter_len = (uint16_t)sizeof(struct sctp_paramhdr);
    5125           0 :                 ph = (struct sctp_paramhdr *)(mtod(m, caddr_t) + chunk_len);
    5126           0 :                 ph->param_type = htons(SCTP_ECN_CAPABLE);
    5127           0 :                 ph->param_length = htons(parameter_len);
    5128           0 :                 chunk_len += parameter_len;
    5129             :         }
    5130             : 
    5131             :         /* PR-SCTP supported parameter */
    5132           0 :         if (stcb->asoc.prsctp_supported == 1) {
    5133           0 :                 parameter_len = (uint16_t)sizeof(struct sctp_paramhdr);
    5134           0 :                 ph = (struct sctp_paramhdr *)(mtod(m, caddr_t) + chunk_len);
    5135           0 :                 ph->param_type = htons(SCTP_PRSCTP_SUPPORTED);
    5136           0 :                 ph->param_length = htons(parameter_len);
    5137           0 :                 chunk_len += parameter_len;
    5138             :         }
    5139             : 
    5140             :         /* Add NAT friendly parameter. */
    5141           0 :         if (SCTP_BASE_SYSCTL(sctp_inits_include_nat_friendly)) {
    5142           0 :                 parameter_len = (uint16_t)sizeof(struct sctp_paramhdr);
    5143           0 :                 ph = (struct sctp_paramhdr *)(mtod(m, caddr_t) + chunk_len);
    5144           0 :                 ph->param_type = htons(SCTP_HAS_NAT_SUPPORT);
    5145           0 :                 ph->param_length = htons(parameter_len);
    5146           0 :                 chunk_len += parameter_len;
    5147             :         }
    5148             : 
    5149             :         /* And now tell the peer which extensions we support */
    5150           0 :         num_ext = 0;
    5151           0 :         pr_supported = (struct sctp_supported_chunk_types_param *)(mtod(m, caddr_t) + chunk_len);
    5152           0 :         if (stcb->asoc.prsctp_supported == 1) {
    5153           0 :                 pr_supported->chunk_types[num_ext++] = SCTP_FORWARD_CUM_TSN;
    5154             :         }
    5155           0 :         if (stcb->asoc.auth_supported == 1) {
    5156           0 :                 pr_supported->chunk_types[num_ext++] = SCTP_AUTHENTICATION;
    5157             :         }
    5158           0 :         if (stcb->asoc.asconf_supported == 1) {
    5159           0 :                 pr_supported->chunk_types[num_ext++] = SCTP_ASCONF;
    5160           0 :                 pr_supported->chunk_types[num_ext++] = SCTP_ASCONF_ACK;
    5161             :         }
    5162           0 :         if (stcb->asoc.reconfig_supported == 1) {
    5163           0 :                 pr_supported->chunk_types[num_ext++] = SCTP_STREAM_RESET;
    5164             :         }
    5165           0 :         if (stcb->asoc.nrsack_supported == 1) {
    5166           0 :                 pr_supported->chunk_types[num_ext++] = SCTP_NR_SELECTIVE_ACK;
    5167             :         }
    5168           0 :         if (stcb->asoc.pktdrop_supported == 1) {
    5169           0 :                 pr_supported->chunk_types[num_ext++] = SCTP_PACKET_DROPPED;
    5170             :         }
    5171           0 :         if (num_ext > 0) {
    5172           0 :                 parameter_len = (uint16_t)sizeof(struct sctp_supported_chunk_types_param) + num_ext;
    5173           0 :                 pr_supported->ph.param_type = htons(SCTP_SUPPORTED_CHUNK_EXT);
    5174           0 :                 pr_supported->ph.param_length = htons(parameter_len);
    5175           0 :                 padding_len = SCTP_SIZE32(parameter_len) - parameter_len;
    5176           0 :                 chunk_len += parameter_len;
    5177             :         }
    5178             :         /* add authentication parameters */
    5179           0 :         if (stcb->asoc.auth_supported) {
    5180             :                 /* attach RANDOM parameter, if available */
    5181           0 :                 if (stcb->asoc.authinfo.random != NULL) {
    5182             :                         struct sctp_auth_random *randp;
    5183             : 
    5184           0 :                         if (padding_len > 0) {
    5185           0 :                                 memset(mtod(m, caddr_t) + chunk_len, 0, padding_len);
    5186           0 :                                 chunk_len += padding_len;
    5187           0 :                                 padding_len = 0;
    5188             :                         }
    5189           0 :                         randp = (struct sctp_auth_random *)(mtod(m, caddr_t) + chunk_len);
    5190           0 :                         parameter_len = (uint16_t)sizeof(struct sctp_auth_random) + stcb->asoc.authinfo.random_len;
    5191             :                         /* random key already contains the header */
    5192           0 :                         memcpy(randp, stcb->asoc.authinfo.random->key, parameter_len);
    5193           0 :                         padding_len = SCTP_SIZE32(parameter_len) - parameter_len;
    5194           0 :                         chunk_len += parameter_len;
    5195             :                 }
    5196             :                 /* add HMAC_ALGO parameter */
    5197           0 :                 if (stcb->asoc.local_hmacs != NULL) {
    5198             :                         struct sctp_auth_hmac_algo *hmacs;
    5199             : 
    5200           0 :                         if (padding_len > 0) {
    5201           0 :                                 memset(mtod(m, caddr_t) + chunk_len, 0, padding_len);
    5202           0 :                                 chunk_len += padding_len;
    5203           0 :                                 padding_len = 0;
    5204             :                         }
    5205           0 :                         hmacs = (struct sctp_auth_hmac_algo *)(mtod(m, caddr_t) + chunk_len);
    5206           0 :                         parameter_len = (uint16_t)(sizeof(struct sctp_auth_hmac_algo) +
    5207           0 :                                                    stcb->asoc.local_hmacs->num_algo * sizeof(uint16_t));
    5208           0 :                         hmacs->ph.param_type = htons(SCTP_HMAC_LIST);
    5209           0 :                         hmacs->ph.param_length = htons(parameter_len);
    5210           0 :                         sctp_serialize_hmaclist(stcb->asoc.local_hmacs, (uint8_t *)hmacs->hmac_ids);
    5211           0 :                         padding_len = SCTP_SIZE32(parameter_len) - parameter_len;
    5212           0 :                         chunk_len += parameter_len;
    5213             :                 }
    5214             :                 /* add CHUNKS parameter */
    5215           0 :                 if (stcb->asoc.local_auth_chunks != NULL) {
    5216             :                         struct sctp_auth_chunk_list *chunks;
    5217             : 
    5218           0 :                         if (padding_len > 0) {
    5219           0 :                                 memset(mtod(m, caddr_t) + chunk_len, 0, padding_len);
    5220           0 :                                 chunk_len += padding_len;
    5221           0 :                                 padding_len = 0;
    5222             :                         }
    5223           0 :                         chunks = (struct sctp_auth_chunk_list *)(mtod(m, caddr_t) + chunk_len);
    5224           0 :                         parameter_len = (uint16_t)(sizeof(struct sctp_auth_chunk_list) +
    5225           0 :                                                    sctp_auth_get_chklist_size(stcb->asoc.local_auth_chunks));
    5226           0 :                         chunks->ph.param_type = htons(SCTP_CHUNK_LIST);
    5227           0 :                         chunks->ph.param_length = htons(parameter_len);
    5228           0 :                         sctp_serialize_auth_chunks(stcb->asoc.local_auth_chunks, chunks->chunk_types);
    5229           0 :                         padding_len = SCTP_SIZE32(parameter_len) - parameter_len;
    5230           0 :                         chunk_len += parameter_len;
    5231             :                 }
    5232             :         }
    5233             : 
    5234             :         /* now any cookie time extensions */
    5235           0 :         if (stcb->asoc.cookie_preserve_req) {
    5236             :                 struct sctp_cookie_perserve_param *cookie_preserve;
    5237             : 
    5238           0 :                 if (padding_len > 0) {
    5239           0 :                         memset(mtod(m, caddr_t) + chunk_len, 0, padding_len);
    5240           0 :                         chunk_len += padding_len;
    5241           0 :                         padding_len = 0;
    5242             :                 }
    5243           0 :                 parameter_len = (uint16_t)sizeof(struct sctp_cookie_perserve_param);
    5244           0 :                 cookie_preserve = (struct sctp_cookie_perserve_param *)(mtod(m, caddr_t) + chunk_len);
    5245           0 :                 cookie_preserve->ph.param_type = htons(SCTP_COOKIE_PRESERVE);
    5246           0 :                 cookie_preserve->ph.param_length = htons(parameter_len);
    5247           0 :                 cookie_preserve->time = htonl(stcb->asoc.cookie_preserve_req);
    5248           0 :                 stcb->asoc.cookie_preserve_req = 0;
    5249           0 :                 chunk_len += parameter_len;
    5250             :         }
    5251             : 
    5252           0 :         if (stcb->asoc.scope.ipv4_addr_legal || stcb->asoc.scope.ipv6_addr_legal) {
    5253             :                 uint8_t i;
    5254             : 
    5255           0 :                 if (padding_len > 0) {
    5256           0 :                         memset(mtod(m, caddr_t) + chunk_len, 0, padding_len);
    5257           0 :                         chunk_len += padding_len;
    5258           0 :                         padding_len = 0;
    5259             :                 }
    5260           0 :                 parameter_len = (uint16_t)sizeof(struct sctp_paramhdr);
    5261           0 :                 if (stcb->asoc.scope.ipv4_addr_legal) {
    5262           0 :                         parameter_len += (uint16_t)sizeof(uint16_t);
    5263             :                 }
    5264           0 :                 if (stcb->asoc.scope.ipv6_addr_legal) {
    5265           0 :                         parameter_len += (uint16_t)sizeof(uint16_t);
    5266             :                 }
    5267           0 :                 sup_addr = (struct sctp_supported_addr_param *)(mtod(m, caddr_t) + chunk_len);
    5268           0 :                 sup_addr->ph.param_type = htons(SCTP_SUPPORTED_ADDRTYPE);
    5269           0 :                 sup_addr->ph.param_length = htons(parameter_len);
    5270           0 :                 i = 0;
    5271           0 :                 if (stcb->asoc.scope.ipv4_addr_legal) {
    5272           0 :                         sup_addr->addr_type[i++] = htons(SCTP_IPV4_ADDRESS);
    5273             :                 }
    5274           0 :                 if (stcb->asoc.scope.ipv6_addr_legal) {
    5275           0 :                         sup_addr->addr_type[i++] = htons(SCTP_IPV6_ADDRESS);
    5276             :                 }
    5277           0 :                 padding_len = 4 - 2 * i;
    5278           0 :                 chunk_len += parameter_len;
    5279             :         }
    5280             : 
    5281           0 :         SCTP_BUF_LEN(m) = chunk_len;
    5282             :         /* now the addresses */
    5283             :         /* To optimize this we could put the scoping stuff
    5284             :          * into a structure and remove the individual uint8's from
    5285             :          * the assoc structure. Then we could just sifa in the
    5286             :          * address within the stcb. But for now this is a quick
    5287             :          * hack to get the address stuff teased apart.
    5288             :          */
    5289           0 :         m_last = sctp_add_addresses_to_i_ia(inp, stcb, &stcb->asoc.scope,
    5290             :                                             m, cnt_inits_to,
    5291             :                                             &padding_len, &chunk_len);
    5292             : 
    5293           0 :         init->ch.chunk_length = htons(chunk_len);
    5294           0 :         if (padding_len > 0) {
    5295           0 :                 if (sctp_add_pad_tombuf(m_last, padding_len) == NULL) {
    5296           0 :                         sctp_m_freem(m);
    5297           0 :                         return;
    5298             :                 }
    5299             :         }
    5300           0 :         SCTPDBG(SCTP_DEBUG_OUTPUT4, "Sending INIT - calls lowlevel_output\n");
    5301           0 :         ret = sctp_lowlevel_chunk_output(inp, stcb, net,
    5302           0 :                                          (struct sockaddr *)&net->ro._l_addr,
    5303             :                                          m, 0, NULL, 0, 0, 0, 0,
    5304           0 :                                          inp->sctp_lport, stcb->rport, htonl(0),
    5305           0 :                                          net->port, NULL,
    5306             : #if defined(__FreeBSD__)
    5307             :                                          0, 0,
    5308             : #endif
    5309             :                                          so_locked);
    5310           0 :         SCTPDBG(SCTP_DEBUG_OUTPUT4, "lowlevel_output - %d\n", ret);
    5311           0 :         SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks);
    5312           0 :         (void)SCTP_GETTIME_TIMEVAL(&net->last_sent_time);
    5313             : }
    5314             : 
    5315             : struct mbuf *
    5316           0 : sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt,
    5317             :         int param_offset, int *abort_processing, struct sctp_chunkhdr *cp, int *nat_friendly)
    5318             : {
    5319             :         /*
    5320             :          * Given a mbuf containing an INIT or INIT-ACK with the param_offset
    5321             :          * being equal to the beginning of the params i.e. (iphlen +
    5322             :          * sizeof(struct sctp_init_msg) parse through the parameters to the
    5323             :          * end of the mbuf verifying that all parameters are known.
    5324             :          *
    5325             :          * For unknown parameters build and return a mbuf with
    5326             :          * UNRECOGNIZED_PARAMETER errors. If the flags indicate to stop
    5327             :          * processing this chunk stop, and set *abort_processing to 1.
    5328             :          *
    5329             :          * By having param_offset be pre-set to where parameters begin it is
    5330             :          * hoped that this routine may be reused in the future by new
    5331             :          * features.
    5332             :          */
    5333             :         struct sctp_paramhdr *phdr, params;
    5334             : 
    5335             :         struct mbuf *mat, *op_err;
    5336             :         char tempbuf[SCTP_PARAM_BUFFER_SIZE];
    5337             :         int at, limit, pad_needed;
    5338             :         uint16_t ptype, plen, padded_size;
    5339             :         int err_at;
    5340             : 
    5341           0 :         *abort_processing = 0;
    5342           0 :         mat = in_initpkt;
    5343           0 :         err_at = 0;
    5344           0 :         limit = ntohs(cp->chunk_length) - sizeof(struct sctp_init_chunk);
    5345           0 :         at = param_offset;
    5346           0 :         op_err = NULL;
    5347           0 :         SCTPDBG(SCTP_DEBUG_OUTPUT1, "Check for unrecognized param's\n");
    5348           0 :         phdr = sctp_get_next_param(mat, at, &params, sizeof(params));
    5349           0 :         while ((phdr != NULL) && ((size_t)limit >= sizeof(struct sctp_paramhdr))) {
    5350           0 :                 ptype = ntohs(phdr->param_type);
    5351           0 :                 plen = ntohs(phdr->param_length);
    5352           0 :                 if ((plen > limit) || (plen < sizeof(struct sctp_paramhdr))) {
    5353             :                         /* wacked parameter */
    5354           0 :                         SCTPDBG(SCTP_DEBUG_OUTPUT1, "Invalid size - error %d\n", plen);
    5355           0 :                         goto invalid_size;
    5356             :                 }
    5357           0 :                 limit -= SCTP_SIZE32(plen);
    5358             :                 /*-
    5359             :                  * All parameters for all chunks that we know/understand are
    5360             :                  * listed here. We process them other places and make
    5361             :                  * appropriate stop actions per the upper bits. However this
    5362             :                  * is the generic routine processor's can call to get back
    5363             :                  * an operr.. to either incorporate (init-ack) or send.
    5364             :                  */
    5365           0 :                 padded_size = SCTP_SIZE32(plen);
    5366           0 :                 switch (ptype) {
    5367             :                         /* Param's with variable size */
    5368             :                 case SCTP_HEARTBEAT_INFO:
    5369             :                 case SCTP_STATE_COOKIE:
    5370             :                 case SCTP_UNRECOG_PARAM:
    5371             :                 case SCTP_ERROR_CAUSE_IND:
    5372             :                         /* ok skip fwd */
    5373           0 :                         at += padded_size;
    5374           0 :                         break;
    5375             :                         /* Param's with variable size within a range */
    5376             :                 case SCTP_CHUNK_LIST:
    5377             :                 case SCTP_SUPPORTED_CHUNK_EXT:
    5378           0 :                         if (padded_size > (sizeof(struct sctp_supported_chunk_types_param) + (sizeof(uint8_t) * SCTP_MAX_SUPPORTED_EXT))) {
    5379           0 :                                 SCTPDBG(SCTP_DEBUG_OUTPUT1, "Invalid size - error chklist %d\n", plen);
    5380           0 :                                 goto invalid_size;
    5381             :                         }
    5382           0 :                         at += padded_size;
    5383           0 :                         break;
    5384             :                 case SCTP_SUPPORTED_ADDRTYPE:
    5385           0 :                         if (padded_size > SCTP_MAX_ADDR_PARAMS_SIZE) {
    5386           0 :                                 SCTPDBG(SCTP_DEBUG_OUTPUT1, "Invalid size - error supaddrtype %d\n", plen);
    5387           0 :                                 goto invalid_size;
    5388             :                         }
    5389           0 :                         at += padded_size;
    5390           0 :                         break;
    5391             :                 case SCTP_RANDOM:
    5392           0 :                         if (padded_size > (sizeof(struct sctp_auth_random) + SCTP_RANDOM_MAX_SIZE)) {
    5393           0 :                                 SCTPDBG(SCTP_DEBUG_OUTPUT1, "Invalid size - error random %d\n", plen);
    5394           0 :                                 goto invalid_size;
    5395             :                         }
    5396           0 :                         at += padded_size;
    5397           0 :                         break;
    5398             :                 case SCTP_SET_PRIM_ADDR:
    5399             :                 case SCTP_DEL_IP_ADDRESS:
    5400             :                 case SCTP_ADD_IP_ADDRESS:
    5401           0 :                         if ((padded_size != sizeof(struct sctp_asconf_addrv4_param)) &&
    5402             :                             (padded_size != sizeof(struct sctp_asconf_addr_param))) {
    5403           0 :                                 SCTPDBG(SCTP_DEBUG_OUTPUT1, "Invalid size - error setprim %d\n", plen);
    5404           0 :                                 goto invalid_size;
    5405             :                         }
    5406           0 :                         at += padded_size;
    5407           0 :                         break;
    5408             :                         /* Param's with a fixed size */
    5409             :                 case SCTP_IPV4_ADDRESS:
    5410           0 :                         if (padded_size != sizeof(struct sctp_ipv4addr_param)) {
    5411           0 :                                 SCTPDBG(SCTP_DEBUG_OUTPUT1, "Invalid size - error ipv4 addr %d\n", plen);
    5412           0 :                                 goto invalid_size;
    5413             :                         }
    5414           0 :                         at += padded_size;
    5415           0 :                         break;
    5416             :                 case SCTP_IPV6_ADDRESS:
    5417           0 :                         if (padded_size != sizeof(struct sctp_ipv6addr_param)) {
    5418           0 :                                 SCTPDBG(SCTP_DEBUG_OUTPUT1, "Invalid size - error ipv6 addr %d\n", plen);
    5419           0 :                                 goto invalid_size;
    5420             :                         }
    5421           0 :                         at += padded_size;
    5422           0 :                         break;
    5423             :                 case SCTP_COOKIE_PRESERVE:
    5424           0 :                         if (padded_size != sizeof(struct sctp_cookie_perserve_param)) {
    5425           0 :                                 SCTPDBG(SCTP_DEBUG_OUTPUT1, "Invalid size - error cookie-preserve %d\n", plen);
    5426           0 :                                 goto invalid_size;
    5427             :                         }
    5428           0 :                         at += padded_size;
    5429           0 :                         break;
    5430             :                 case SCTP_HAS_NAT_SUPPORT:
    5431           0 :                         *nat_friendly = 1;
    5432             :                         /* fall through */
    5433             :                 case SCTP_PRSCTP_SUPPORTED:
    5434           0 :                         if (padded_size != sizeof(struct sctp_paramhdr)) {
    5435           0 :                                 SCTPDBG(SCTP_DEBUG_OUTPUT1, "Invalid size - error prsctp/nat support %d\n", plen);
    5436           0 :                                 goto invalid_size;
    5437             :                         }
    5438           0 :                         at += padded_size;
    5439           0 :                         break;
    5440             :                 case SCTP_ECN_CAPABLE:
    5441           0 :                         if (padded_size != sizeof(struct sctp_paramhdr)) {
    5442           0 :                                 SCTPDBG(SCTP_DEBUG_OUTPUT1, "Invalid size - error ecn %d\n", plen);
    5443           0 :                                 goto invalid_size;
    5444             :                         }
    5445           0 :                         at += padded_size;
    5446           0 :                         break;
    5447             :                 case SCTP_ULP_ADAPTATION:
    5448           0 :                         if (padded_size != sizeof(struct sctp_adaptation_layer_indication)) {
    5449           0 :                                 SCTPDBG(SCTP_DEBUG_OUTPUT1, "Invalid size - error adapatation %d\n", plen);
    5450           0 :                                 goto invalid_size;
    5451             :                         }
    5452           0 :                         at += padded_size;
    5453           0 :                         break;
    5454             :                 case SCTP_SUCCESS_REPORT:
    5455           0 :                         if (padded_size != sizeof(struct sctp_asconf_paramhdr)) {
    5456           0 :                                 SCTPDBG(SCTP_DEBUG_OUTPUT1, "Invalid size - error success %d\n", plen);
    5457           0 :                                 goto invalid_size;
    5458             :                         }
    5459           0 :                         at += padded_size;
    5460           0 :                         break;
    5461             :                 case SCTP_HOSTNAME_ADDRESS:
    5462             :                 {
    5463             :                         /* We can NOT handle HOST NAME addresses!! */
    5464             :                         int l_len;
    5465             : 
    5466           0 :                         SCTPDBG(SCTP_DEBUG_OUTPUT1, "Can't handle hostname addresses.. abort processing\n");
    5467           0 :                         *abort_processing = 1;
    5468           0 :                         if (op_err == NULL) {
    5469             :                                 /* Ok need to try to get a mbuf */
    5470             : #ifdef INET6
    5471             :                                 l_len = sizeof(struct ip6_hdr) + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
    5472             : #else
    5473           0 :                                 l_len = sizeof(struct ip) + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
    5474             : #endif
    5475           0 :                                 l_len += plen;
    5476           0 :                                 l_len += sizeof(struct sctp_paramhdr);
    5477           0 :                                 op_err = sctp_get_mbuf_for_msg(l_len, 0, M_NOWAIT, 1, MT_DATA);
    5478           0 :                                 if (op_err) {
    5479           0 :                                         SCTP_BUF_LEN(op_err) = 0;
    5480             :                                         /*
    5481             :                                          * pre-reserve space for ip and sctp
    5482             :                                          * header  and chunk hdr
    5483             :                                          */
    5484             : #ifdef INET6
    5485             :                                         SCTP_BUF_RESV_UF(op_err, sizeof(struct ip6_hdr));
    5486             : #else
    5487           0 :                                         SCTP_BUF_RESV_UF(op_err, sizeof(struct ip));
    5488             : #endif
    5489           0 :                                         SCTP_BUF_RESV_UF(op_err, sizeof(struct sctphdr));
    5490           0 :                                         SCTP_BUF_RESV_UF(op_err, sizeof(struct sctp_chunkhdr));
    5491             :                                 }
    5492             :                         }
    5493           0 :                         if (op_err) {
    5494             :                                 /* If we have space */
    5495             :                                 struct sctp_paramhdr s;
    5496             : 
    5497           0 :                                 if (err_at % 4) {
    5498           0 :                                         uint32_t cpthis = 0;
    5499             : 
    5500           0 :                                         pad_needed = 4 - (err_at % 4);
    5501           0 :                                         m_copyback(op_err, err_at, pad_needed, (caddr_t)&cpthis);
    5502           0 :                                         err_at += pad_needed;
    5503             :                                 }
    5504           0 :                                 s.param_type = htons(SCTP_CAUSE_UNRESOLVABLE_ADDR);
    5505           0 :                                 s.param_length = htons(sizeof(s) + plen);
    5506           0 :                                 m_copyback(op_err, err_at, sizeof(s), (caddr_t)&s);
    5507           0 :                                 err_at += sizeof(s);
    5508           0 :                                 phdr = sctp_get_next_param(mat, at, (struct sctp_paramhdr *)tempbuf, min(sizeof(tempbuf),plen));
    5509           0 :                                 if (phdr == NULL) {
    5510           0 :                                         sctp_m_freem(op_err);
    5511             :                                         /*
    5512             :                                          * we are out of memory but we still
    5513             :                                          * need to have a look at what to do
    5514             :                                          * (the system is in trouble
    5515             :                                          * though).
    5516             :                                          */
    5517           0 :                                         return (NULL);
    5518             :                                 }
    5519           0 :                                 m_copyback(op_err, err_at, plen, (caddr_t)phdr);
    5520             :                         }
    5521           0 :                         return (op_err);
    5522             :                         break;
    5523             :                 }
    5524             :                 default:
    5525             :                         /*
    5526             :                          * we do not recognize the parameter figure out what
    5527             :                          * we do.
    5528             :                          */
    5529           0 :                         SCTPDBG(SCTP_DEBUG_OUTPUT1, "Hit default param %x\n", ptype);
    5530           0 :                         if ((ptype & 0x4000) == 0x4000) {
    5531             :                                 /* Report bit is set?? */
    5532           0 :                                 SCTPDBG(SCTP_DEBUG_OUTPUT1, "report op err\n");
    5533           0 :                                 if (op_err == NULL) {
    5534             :                                         int l_len;
    5535             :                                         /* Ok need to try to get an mbuf */
    5536             : #ifdef INET6
    5537             :                                         l_len = sizeof(struct ip6_hdr) + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
    5538             : #else
    5539           0 :                                         l_len = sizeof(struct ip) + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
    5540             : #endif
    5541           0 :                                         l_len += plen;
    5542           0 :                                         l_len += sizeof(struct sctp_paramhdr);
    5543           0 :                                         op_err = sctp_get_mbuf_for_msg(l_len, 0, M_NOWAIT, 1, MT_DATA);
    5544           0 :                                         if (op_err) {
    5545           0 :                                                 SCTP_BUF_LEN(op_err) = 0;
    5546             : #ifdef INET6
    5547             :                                                 SCTP_BUF_RESV_UF(op_err, sizeof(struct ip6_hdr));
    5548             : #else
    5549           0 :                                                 SCTP_BUF_RESV_UF(op_err, sizeof(struct ip));
    5550             : #endif
    5551           0 :                                                 SCTP_BUF_RESV_UF(op_err, sizeof(struct sctphdr));
    5552           0 :                                                 SCTP_BUF_RESV_UF(op_err, sizeof(struct sctp_chunkhdr));
    5553             :                                         }
    5554             :                                 }
    5555           0 :                                 if (op_err) {
    5556             :                                         /* If we have space */
    5557             :                                         struct sctp_paramhdr s;
    5558             : 
    5559           0 :                                         if (err_at % 4) {
    5560           0 :                                                 uint32_t cpthis = 0;
    5561             : 
    5562           0 :                                                 pad_needed = 4 - (err_at % 4);
    5563           0 :                                                 m_copyback(op_err, err_at, pad_needed, (caddr_t)&cpthis);
    5564           0 :                                                 err_at += pad_needed;
    5565             :                                         }
    5566           0 :                                         s.param_type = htons(SCTP_UNRECOG_PARAM);
    5567           0 :                                         s.param_length = htons(sizeof(s) + plen);
    5568           0 :                                         m_copyback(op_err, err_at, sizeof(s), (caddr_t)&s);
    5569           0 :                                         err_at += sizeof(s);
    5570           0 :                                         if (plen > sizeof(tempbuf)) {
    5571           0 :                                                 plen = sizeof(tempbuf);
    5572             :                                         }
    5573           0 :                                         phdr = sctp_get_next_param(mat, at, (struct sctp_paramhdr *)tempbuf, min(sizeof(tempbuf),plen));
    5574           0 :                                         if (phdr == NULL) {
    5575           0 :                                                 sctp_m_freem(op_err);
    5576             :                                                 /*
    5577             :                                                  * we are out of memory but
    5578             :                                                  * we still need to have a
    5579             :                                                  * look at what to do (the
    5580             :                                                  * system is in trouble
    5581             :                                                  * though).
    5582             :                                                  */
    5583           0 :                                                 op_err = NULL;
    5584           0 :                                                 goto more_processing;
    5585             :                                         }
    5586           0 :                                         m_copyback(op_err, err_at, plen, (caddr_t)phdr);
    5587           0 :                                         err_at += plen;
    5588             :                                 }
    5589             :                         }
    5590             :                 more_processing:
    5591           0 :                         if ((ptype & 0x8000) == 0x0000) {
    5592           0 :                                 SCTPDBG(SCTP_DEBUG_OUTPUT1, "stop proc\n");
    5593           0 :                                 return (op_err);
    5594             :                         } else {
    5595             :                                 /* skip this chunk and continue processing */
    5596           0 :                                 SCTPDBG(SCTP_DEBUG_OUTPUT1, "move on\n");
    5597           0 :                                 at += SCTP_SIZE32(plen);
    5598             :                         }
    5599           0 :                         break;
    5600             : 
    5601             :                 }
    5602           0 :                 phdr = sctp_get_next_param(mat, at, &params, sizeof(params));
    5603             :         }
    5604           0 :         return (op_err);
    5605             :  invalid_size:
    5606           0 :         SCTPDBG(SCTP_DEBUG_OUTPUT1, "abort flag set\n");
    5607           0 :         *abort_processing = 1;
    5608           0 :         if ((op_err == NULL) && phdr) {
    5609             :                 int l_len;
    5610             : #ifdef INET6
    5611             :                 l_len = sizeof(struct ip6_hdr) + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
    5612             : #else
    5613           0 :                 l_len = sizeof(struct ip) + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
    5614             : #endif
    5615           0 :                 l_len += (2 * sizeof(struct sctp_paramhdr));
    5616           0 :                 op_err = sctp_get_mbuf_for_msg(l_len, 0, M_NOWAIT, 1, MT_DATA);
    5617           0 :                 if (op_err) {
    5618           0 :                         SCTP_BUF_LEN(op_err) = 0;
    5619             : #ifdef INET6
    5620             :                         SCTP_BUF_RESV_UF(op_err, sizeof(struct ip6_hdr));
    5621             : #else
    5622           0 :                         SCTP_BUF_RESV_UF(op_err, sizeof(struct ip));
    5623             : #endif
    5624           0 :                         SCTP_BUF_RESV_UF(op_err, sizeof(struct sctphdr));
    5625           0 :                         SCTP_BUF_RESV_UF(op_err, sizeof(struct sctp_chunkhdr));
    5626             :                 }
    5627             :         }
    5628           0 :         if ((op_err) && phdr) {
    5629             :                 struct sctp_paramhdr s;
    5630             : 
    5631           0 :                 if (err_at % 4) {
    5632           0 :                         uint32_t cpthis = 0;
    5633             : 
    5634           0 :                         pad_needed = 4 - (err_at % 4);
    5635           0 :                         m_copyback(op_err, err_at, pad_needed, (caddr_t)&cpthis);
    5636           0 :                         err_at += pad_needed;
    5637             :                 }
    5638           0 :                 s.param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
    5639           0 :                 s.param_length = htons(sizeof(s) + sizeof(struct sctp_paramhdr));
    5640           0 :                 m_copyback(op_err, err_at, sizeof(s), (caddr_t)&s);
    5641           0 :                 err_at += sizeof(s);
    5642             :                 /* Only copy back the p-hdr that caused the issue */
    5643           0 :                 m_copyback(op_err, err_at, sizeof(struct sctp_paramhdr), (caddr_t)phdr);
    5644             :         }
    5645           0 :         return (op_err);
    5646             : }
    5647             : 
    5648             : static int
    5649           0 : sctp_are_there_new_addresses(struct sctp_association *asoc,
    5650             :     struct mbuf *in_initpkt, int offset, struct sockaddr *src)
    5651             : {
    5652             :         /*
    5653             :          * Given a INIT packet, look through the packet to verify that there
    5654             :          * are NO new addresses. As we go through the parameters add reports
    5655             :          * of any un-understood parameters that require an error.  Also we
    5656             :          * must return (1) to drop the packet if we see a un-understood
    5657             :          * parameter that tells us to drop the chunk.
    5658             :          */
    5659             :         struct sockaddr *sa_touse;
    5660             :         struct sockaddr *sa;
    5661             :         struct sctp_paramhdr *phdr, params;
    5662             :         uint16_t ptype, plen;
    5663             :         uint8_t fnd;
    5664             :         struct sctp_nets *net;
    5665             : #ifdef INET
    5666             :         struct sockaddr_in sin4, *sa4;
    5667             : #endif
    5668             : #ifdef INET6
    5669             :         struct sockaddr_in6 sin6, *sa6;
    5670             : #endif
    5671             : 
    5672             : #ifdef INET
    5673             :         memset(&sin4, 0, sizeof(sin4));
    5674             :         sin4.sin_family = AF_INET;
    5675             : #ifdef HAVE_SIN_LEN
    5676             :         sin4.sin_len = sizeof(sin4);
    5677             : #endif
    5678             : #endif
    5679             : #ifdef INET6
    5680             :         memset(&sin6, 0, sizeof(sin6));
    5681             :         sin6.sin6_family = AF_INET6;
    5682             : #ifdef HAVE_SIN6_LEN
    5683             :         sin6.sin6_len = sizeof(sin6);
    5684             : #endif
    5685             : #endif
    5686             :         /* First what about the src address of the pkt ? */
    5687           0 :         fnd = 0;
    5688           0 :         TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
    5689           0 :                 sa = (struct sockaddr *)&net->ro._l_addr;
    5690           0 :                 if (sa->sa_family == src->sa_family) {
    5691             : #ifdef INET
    5692             :                         if (sa->sa_family == AF_INET) {
    5693             :                                 struct sockaddr_in *src4;
    5694             : 
    5695             :                                 sa4 = (struct sockaddr_in *)sa;
    5696             :                                 src4 = (struct sockaddr_in *)src;
    5697             :                                 if (sa4->sin_addr.s_addr == src4->sin_addr.s_addr) {
    5698             :                                         fnd = 1;
    5699             :                                         break;
    5700             :                                 }
    5701             :                         }
    5702             : #endif
    5703             : #ifdef INET6
    5704             :                         if (sa->sa_family == AF_INET6) {
    5705             :                                 struct sockaddr_in6 *src6;
    5706             : 
    5707             :                                 sa6 = (struct sockaddr_in6 *)sa;
    5708             :                                 src6 = (struct sockaddr_in6 *)src;
    5709             :                                 if (SCTP6_ARE_ADDR_EQUAL(sa6, src6)) {
    5710             :                                         fnd = 1;
    5711             :                                         break;
    5712             :                                 }
    5713             :                         }
    5714             : #endif
    5715             :                 }
    5716             :         }
    5717           0 :         if (fnd == 0) {
    5718             :                 /* New address added! no need to look futher. */
    5719           0 :                 return (1);
    5720             :         }
    5721             :         /* Ok so far lets munge through the rest of the packet */
    5722           0 :         offset += sizeof(struct sctp_init_chunk);
    5723           0 :         phdr = sctp_get_next_param(in_initpkt, offset, &params, sizeof(params));
    5724           0 :         while (phdr) {
    5725           0 :                 sa_touse = NULL;
    5726           0 :                 ptype = ntohs(phdr->param_type);
    5727           0 :                 plen = ntohs(phdr->param_length);
    5728           0 :                 switch (ptype) {
    5729             : #ifdef INET
    5730             :                 case SCTP_IPV4_ADDRESS:
    5731             :                 {
    5732             :                         struct sctp_ipv4addr_param *p4, p4_buf;
    5733             : 
    5734             :                         phdr = sctp_get_next_param(in_initpkt, offset,
    5735             :                             (struct sctp_paramhdr *)&p4_buf, sizeof(p4_buf));
    5736             :                         if (plen != sizeof(struct sctp_ipv4addr_param) ||
    5737             :                             phdr == NULL) {
    5738             :                                 return (1);
    5739             :                         }
    5740             :                         p4 = (struct sctp_ipv4addr_param *)phdr;
    5741             :                         sin4.sin_addr.s_addr = p4->addr;
    5742             :                         sa_touse = (struct sockaddr *)&sin4;
    5743             :                         break;
    5744             :                 }
    5745             : #endif
    5746             : #ifdef INET6
    5747             :                 case SCTP_IPV6_ADDRESS:
    5748             :                 {
    5749             :                         struct sctp_ipv6addr_param *p6, p6_buf;
    5750             : 
    5751             :                         phdr = sctp_get_next_param(in_initpkt, offset,
    5752             :                             (struct sctp_paramhdr *)&p6_buf, sizeof(p6_buf));
    5753             :                         if (plen != sizeof(struct sctp_ipv6addr_param) ||
    5754             :                             phdr == NULL) {
    5755             :                                 return (1);
    5756             :                         }
    5757             :                         p6 = (struct sctp_ipv6addr_param *)phdr;
    5758             :                         memcpy((caddr_t)&sin6.sin6_addr, p6->addr,
    5759             :                             sizeof(p6->addr));
    5760             :                         sa_touse = (struct sockaddr *)&sin6;
    5761             :                         break;
    5762             :                 }
    5763             : #endif
    5764             :                 default:
    5765           0 :                         sa_touse = NULL;
    5766           0 :                         break;
    5767             :                 }
    5768           0 :                 if (sa_touse) {
    5769             :                         /* ok, sa_touse points to one to check */
    5770           0 :                         fnd = 0;
    5771           0 :                         TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
    5772           0 :                                 sa = (struct sockaddr *)&net->ro._l_addr;
    5773           0 :                                 if (sa->sa_family != sa_touse->sa_family) {
    5774           0 :                                         continue;
    5775             :                                 }
    5776             : #ifdef INET
    5777             :                                 if (sa->sa_family == AF_INET) {
    5778             :                                         sa4 = (struct sockaddr_in *)sa;
    5779             :                                         if (sa4->sin_addr.s_addr ==
    5780             :                                             sin4.sin_addr.s_addr) {
    5781             :                                                 fnd = 1;
    5782             :                                                 break;
    5783             :                                         }
    5784             :                                 }
    5785             : #endif
    5786             : #ifdef INET6
    5787             :                                 if (sa->sa_family == AF_INET6) {
    5788             :                                         sa6 = (struct sockaddr_in6 *)sa;
    5789             :                                         if (SCTP6_ARE_ADDR_EQUAL(
    5790             :                                             sa6, &sin6)) {
    5791             :                                                 fnd = 1;
    5792             :                                                 break;
    5793             :                                         }
    5794             :                                 }
    5795             : #endif
    5796             :                         }
    5797           0 :                         if (!fnd) {
    5798             :                                 /* New addr added! no need to look further */
    5799           0 :                                 return (1);
    5800             :                         }
    5801             :                 }
    5802           0 :                 offset += SCTP_SIZE32(plen);
    5803           0 :                 phdr = sctp_get_next_param(in_initpkt, offset, &params, sizeof(params));
    5804             :         }
    5805           0 :         return (0);
    5806             : }
    5807             : 
    5808             : /*
    5809             :  * Given a MBUF chain that was sent into us containing an INIT. Build a
    5810             :  * INIT-ACK with COOKIE and send back. We assume that the in_initpkt has done
    5811             :  * a pullup to include IPv6/4header, SCTP header and initial part of INIT
    5812             :  * message (i.e. the struct sctp_init_msg).
    5813             :  */
    5814             : void
    5815           0 : sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
    5816             :                        struct mbuf *init_pkt, int iphlen, int offset,
    5817             :                        struct sockaddr *src, struct sockaddr *dst,
    5818             :                        struct sctphdr *sh, struct sctp_init_chunk *init_chk,
    5819             : #if defined(__FreeBSD__)
    5820             :                        uint8_t mflowtype, uint32_t mflowid,
    5821             : #endif
    5822             :                        uint32_t vrf_id, uint16_t port, int hold_inp_lock)
    5823             : {
    5824             :         struct sctp_association *asoc;
    5825             :         struct mbuf *m, *m_tmp, *m_last, *m_cookie, *op_err;
    5826             :         struct sctp_init_ack_chunk *initack;
    5827             :         struct sctp_adaptation_layer_indication *ali;
    5828             :         struct sctp_supported_chunk_types_param *pr_supported;
    5829             :         struct sctp_paramhdr *ph;
    5830             :         union sctp_sockstore *over_addr;
    5831             :         struct sctp_scoping scp;
    5832             : #ifdef INET
    5833             :         struct sockaddr_in *dst4 = (struct sockaddr_in *)dst;
    5834             :         struct sockaddr_in *src4 = (struct sockaddr_in *)src;
    5835             :         struct sockaddr_in *sin;
    5836             : #endif
    5837             : #ifdef INET6
    5838             :         struct sockaddr_in6 *dst6 = (struct sockaddr_in6 *)dst;
    5839             :         struct sockaddr_in6 *src6 = (struct sockaddr_in6 *)src;
    5840             :         struct sockaddr_in6 *sin6;
    5841             : #endif
    5842             : #if defined(__Userspace__)
    5843           0 :         struct sockaddr_conn *dstconn = (struct sockaddr_conn *)dst;
    5844           0 :         struct sockaddr_conn *srcconn = (struct sockaddr_conn *)src;
    5845             :         struct sockaddr_conn *sconn;
    5846             : #endif
    5847             :         struct sockaddr *to;
    5848             :         struct sctp_state_cookie stc;
    5849           0 :         struct sctp_nets *net = NULL;
    5850           0 :         uint8_t *signature = NULL;
    5851           0 :         int cnt_inits_to = 0;
    5852             :         uint16_t his_limit, i_want;
    5853             :         int abort_flag;
    5854           0 :         int nat_friendly = 0;
    5855             :         struct socket *so;
    5856             :         uint16_t num_ext, chunk_len, padding_len, parameter_len;
    5857             : 
    5858           0 :         if (stcb) {
    5859           0 :                 asoc = &stcb->asoc;
    5860             :         } else {
    5861           0 :                 asoc = NULL;
    5862             :         }
    5863           0 :         if ((asoc != NULL) &&
    5864           0 :             (SCTP_GET_STATE(asoc) != SCTP_STATE_COOKIE_WAIT) &&
    5865           0 :             (sctp_are_there_new_addresses(asoc, init_pkt, offset, src))) {
    5866             :                 /* new addresses, out of here in non-cookie-wait states */
    5867             :                 /*
    5868             :                  * Send a ABORT, we don't add the new address error clause
    5869             :                  * though we even set the T bit and copy in the 0 tag.. this
    5870             :                  * looks no different than if no listener was present.
    5871             :                  */
    5872           0 :                 op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
    5873             :                                              "Address added");
    5874           0 :                 sctp_send_abort(init_pkt, iphlen, src, dst, sh, 0, op_err,
    5875             : #if defined(__FreeBSD__)
    5876             :                                 mflowtype, mflowid,
    5877             : #endif
    5878             :                                 vrf_id, port);
    5879           0 :                 return;
    5880             :         }
    5881           0 :         abort_flag = 0;
    5882           0 :         op_err = sctp_arethere_unrecognized_parameters(init_pkt,
    5883           0 :                                                        (offset + sizeof(struct sctp_init_chunk)),
    5884             :                                                        &abort_flag, (struct sctp_chunkhdr *)init_chk, &nat_friendly);
    5885           0 :         if (abort_flag) {
    5886             :         do_a_abort:
    5887           0 :                 if (op_err == NULL) {
    5888             :                         char msg[SCTP_DIAG_INFO_LEN];
    5889             : 
    5890           0 :                         snprintf(msg, sizeof(msg), "%s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__);
    5891           0 :                         op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
    5892             :                                                      msg);
    5893             :                 }
    5894           0 :                 sctp_send_abort(init_pkt, iphlen, src, dst, sh,
    5895             :                                 init_chk->init.initiate_tag, op_err,
    5896             : #if defined(__FreeBSD__)
    5897             :                                 mflowtype, mflowid,
    5898             : #endif
    5899             :                                 vrf_id, port);
    5900           0 :                 return;
    5901             :         }
    5902           0 :         m = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_NOWAIT, 1, MT_DATA);
    5903           0 :         if (m == NULL) {
    5904             :                 /* No memory, INIT timer will re-attempt. */
    5905           0 :                 if (op_err)
    5906           0 :                         sctp_m_freem(op_err);
    5907           0 :                 return;
    5908             :         }
    5909           0 :         chunk_len = (uint16_t)sizeof(struct sctp_init_ack_chunk);
    5910           0 :         padding_len = 0;
    5911             : 
    5912             :         /*
    5913             :          * We might not overwrite the identification[] completely and on
    5914             :          * some platforms time_entered will contain some padding.
    5915             :          * Therefore zero out the cookie to avoid putting
    5916             :          * uninitialized memory on the wire.
    5917             :          */
    5918           0 :         memset(&stc, 0, sizeof(struct sctp_state_cookie));
    5919             : 
    5920             :         /* the time I built cookie */
    5921           0 :         (void)SCTP_GETTIME_TIMEVAL(&stc.time_entered);
    5922             : 
    5923             :         /* populate any tie tags */
    5924           0 :         if (asoc != NULL) {
    5925             :                 /* unlock before tag selections */
    5926           0 :                 stc.tie_tag_my_vtag = asoc->my_vtag_nonce;
    5927           0 :                 stc.tie_tag_peer_vtag = asoc->peer_vtag_nonce;
    5928           0 :                 stc.cookie_life = asoc->cookie_life;
    5929           0 :                 net = asoc->primary_destination;
    5930             :         } else {
    5931           0 :                 stc.tie_tag_my_vtag = 0;
    5932           0 :                 stc.tie_tag_peer_vtag = 0;
    5933             :                 /* life I will award this cookie */
    5934           0 :                 stc.cookie_life = inp->sctp_ep.def_cookie_life;
    5935             :         }
    5936             : 
    5937             :         /* copy in the ports for later check */
    5938           0 :         stc.myport = sh->dest_port;
    5939           0 :         stc.peerport = sh->src_port;
    5940             : 
    5941             :         /*
    5942             :          * If we wanted to honor cookie life extentions, we would add to
    5943             :          * stc.cookie_life. For now we should NOT honor any extension
    5944             :          */
    5945           0 :         stc.site_scope = stc.local_scope = stc.loopback_scope = 0;
    5946           0 :         if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
    5947           0 :                 stc.ipv6_addr_legal = 1;
    5948           0 :                 if (SCTP_IPV6_V6ONLY(inp)) {
    5949           0 :                         stc.ipv4_addr_legal = 0;
    5950             :                 } else {
    5951           0 :                         stc.ipv4_addr_legal = 1;
    5952             :                 }
    5953             : #if defined(__Userspace__)
    5954           0 :                 stc.conn_addr_legal = 0;
    5955             : #endif
    5956             :         } else {
    5957           0 :                 stc.ipv6_addr_legal = 0;
    5958             : #if defined(__Userspace__)
    5959           0 :                 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) {
    5960           0 :                         stc.conn_addr_legal = 1;
    5961           0 :                         stc.ipv4_addr_legal = 0;
    5962             :                 } else {
    5963           0 :                         stc.conn_addr_legal = 0;
    5964           0 :                         stc.ipv4_addr_legal = 1;
    5965             :                 }
    5966             : #else
    5967             :                 stc.ipv4_addr_legal = 1;
    5968             : #endif
    5969             :         }
    5970             : #ifdef SCTP_DONT_DO_PRIVADDR_SCOPE
    5971             :         stc.ipv4_scope = 1;
    5972             : #else
    5973           0 :         stc.ipv4_scope = 0;
    5974             : #endif
    5975           0 :         if (net == NULL) {
    5976           0 :                 to = src;
    5977           0 :                 switch (dst->sa_family) {
    5978             : #ifdef INET
    5979             :                 case AF_INET:
    5980             :                 {
    5981             :                         /* lookup address */
    5982             :                         stc.address[0] = src4->sin_addr.s_addr;
    5983             :                         stc.address[1] = 0;
    5984             :                         stc.address[2] = 0;
    5985             :                         stc.address[3] = 0;
    5986             :                         stc.addr_type = SCTP_IPV4_ADDRESS;
    5987             :                         /* local from address */
    5988             :                         stc.laddress[0] = dst4->sin_addr.s_addr;
    5989             :                         stc.laddress[1] = 0;
    5990             :                         stc.laddress[2] = 0;
    5991             :                         stc.laddress[3] = 0;
    5992             :                         stc.laddr_type = SCTP_IPV4_ADDRESS;
    5993             :                         /* scope_id is only for v6 */
    5994             :                         stc.scope_id = 0;
    5995             : #ifndef SCTP_DONT_DO_PRIVADDR_SCOPE
    5996             :                         if (IN4_ISPRIVATE_ADDRESS(&src4->sin_addr)) {
    5997             :                                 stc.ipv4_scope = 1;
    5998             :                         }
    5999             : #else
    6000             :                         stc.ipv4_scope = 1;
    6001             : #endif                          /* SCTP_DONT_DO_PRIVADDR_SCOPE */
    6002             :                         /* Must use the address in this case */
    6003             :                         if (sctp_is_address_on_local_host(src, vrf_id)) {
    6004             :                                 stc.loopback_scope = 1;
    6005             :                                 stc.ipv4_scope = 1;
    6006             :                                 stc.site_scope = 1;
    6007             :                                 stc.local_scope = 0;
    6008             :                         }
    6009             :                         break;
    6010             :                 }
    6011             : #endif
    6012             : #ifdef INET6
    6013             :                 case AF_INET6:
    6014             :                 {
    6015             :                         stc.addr_type = SCTP_IPV6_ADDRESS;
    6016             :                         memcpy(&stc.address, &src6->sin6_addr, sizeof(struct in6_addr));
    6017             : #if defined(__FreeBSD__) && (((__FreeBSD_version < 900000) && (__FreeBSD_version >= 804000)) || (__FreeBSD_version > 900000))
    6018             :                         stc.scope_id = in6_getscope(&src6->sin6_addr);
    6019             : #else
    6020             :                         stc.scope_id = 0;
    6021             : #endif
    6022             :                         if (sctp_is_address_on_local_host(src, vrf_id)) {
    6023             :                                 stc.loopback_scope = 1;
    6024             :                                 stc.local_scope = 0;
    6025             :                                 stc.site_scope = 1;
    6026             :                                 stc.ipv4_scope = 1;
    6027             :                         } else if (IN6_IS_ADDR_LINKLOCAL(&src6->sin6_addr)) {
    6028             :                                 /*
    6029             :                                  * If the new destination is a LINK_LOCAL we
    6030             :                                  * must have common both site and local
    6031             :                                  * scope. Don't set local scope though since
    6032             :                                  * we must depend on the source to be added
    6033             :                                  * implicitly. We cannot assure just because
    6034             :                                  * we share one link that all links are
    6035             :                                  * common.
    6036             :                                  */
    6037             : #if defined(__APPLE__)
    6038             :                                 /* Mac OS X currently doesn't have in6_getscope() */
    6039             :                                 stc.scope_id = src6->sin6_addr.s6_addr16[1];
    6040             : #endif
    6041             :                                 stc.local_scope = 0;
    6042             :                                 stc.site_scope = 1;
    6043             :                                 stc.ipv4_scope = 1;
    6044             :                                 /*
    6045             :                                  * we start counting for the private address
    6046             :                                  * stuff at 1. since the link local we
    6047             :                                  * source from won't show up in our scoped
    6048             :                                  * count.
    6049             :                                  */
    6050             :                                 cnt_inits_to = 1;
    6051             :                                 /* pull out the scope_id from incoming pkt */
    6052             :                         } else if (IN6_IS_ADDR_SITELOCAL(&src6->sin6_addr)) {
    6053             :                                 /*
    6054             :                                  * If the new destination is SITE_LOCAL then
    6055             :                                  * we must have site scope in common.
    6056             :                                  */
    6057             :                                 stc.site_scope = 1;
    6058             :                         }
    6059             :                         memcpy(&stc.laddress, &dst6->sin6_addr, sizeof(struct in6_addr));
    6060             :                         stc.laddr_type = SCTP_IPV6_ADDRESS;
    6061             :                         break;
    6062             :                 }
    6063             : #endif
    6064             : #if defined(__Userspace__)
    6065             :                 case AF_CONN:
    6066             :                 {
    6067             :                         /* lookup address */
    6068           0 :                         stc.address[0] = 0;
    6069           0 :                         stc.address[1] = 0;
    6070           0 :                         stc.address[2] = 0;
    6071           0 :                         stc.address[3] = 0;
    6072           0 :                         memcpy(&stc.address, &srcconn->sconn_addr, sizeof(void *));
    6073           0 :                         stc.addr_type = SCTP_CONN_ADDRESS;
    6074             :                         /* local from address */
    6075           0 :                         stc.laddress[0] = 0;
    6076           0 :                         stc.laddress[1] = 0;
    6077           0 :                         stc.laddress[2] = 0;
    6078           0 :                         stc.laddress[3] = 0;
    6079           0 :                         memcpy(&stc.laddress, &dstconn->sconn_addr, sizeof(void *));
    6080           0 :                         stc.laddr_type = SCTP_CONN_ADDRESS;
    6081             :                         /* scope_id is only for v6 */
    6082           0 :                         stc.scope_id = 0;
    6083           0 :                         break;
    6084             :                 }
    6085             : #endif
    6086             :                 default:
    6087             :                         /* TSNH */
    6088           0 :                         goto do_a_abort;
    6089             :                         break;
    6090             :                 }
    6091             :         } else {
    6092             :                 /* set the scope per the existing tcb */
    6093             : 
    6094             : #ifdef INET6
    6095             :                 struct sctp_nets *lnet;
    6096             : #endif
    6097             : 
    6098           0 :                 stc.loopback_scope = asoc->scope.loopback_scope;
    6099           0 :                 stc.ipv4_scope = asoc->scope.ipv4_local_scope;
    6100           0 :                 stc.site_scope = asoc->scope.site_scope;
    6101           0 :                 stc.local_scope = asoc->scope.local_scope;
    6102             : #ifdef INET6
    6103             :                 /* Why do we not consider IPv4 LL addresses? */
    6104             :                 TAILQ_FOREACH(lnet, &asoc->nets, sctp_next) {
    6105             :                         if (lnet->ro._l_addr.sin6.sin6_family == AF_INET6) {
    6106             :                                 if (IN6_IS_ADDR_LINKLOCAL(&lnet->ro._l_addr.sin6.sin6_addr)) {
    6107             :                                         /*
    6108             :                                          * if we have a LL address, start
    6109             :                                          * counting at 1.
    6110             :                                          */
    6111             :                                         cnt_inits_to = 1;
    6112             :                                 }
    6113             :                         }
    6114             :                 }
    6115             : #endif
    6116             :                 /* use the net pointer */
    6117           0 :                 to = (struct sockaddr *)&net->ro._l_addr;
    6118           0 :                 switch (to->sa_family) {
    6119             : #ifdef INET
    6120             :                 case AF_INET:
    6121             :                         sin = (struct sockaddr_in *)to;
    6122             :                         stc.address[0] = sin->sin_addr.s_addr;
    6123             :                         stc.address[1] = 0;
    6124             :                         stc.address[2] = 0;
    6125             :                         stc.address[3] = 0;
    6126             :                         stc.addr_type = SCTP_IPV4_ADDRESS;
    6127             :                         if (net->src_addr_selected == 0) {
    6128             :                                 /*
    6129             :                                  * strange case here, the INIT should have
    6130             :                                  * did the selection.
    6131             :                                  */
    6132             :                                 net->ro._s_addr = sctp_source_address_selection(inp,
    6133             :                                                                                 stcb, (sctp_route_t *)&net->ro,
    6134             :                                                                                 net, 0, vrf_id);
    6135             :                                 if (net->ro._s_addr == NULL)
    6136             :                                         return;
    6137             : 
    6138             :                                 net->src_addr_selected = 1;
    6139             : 
    6140             :                         }
    6141             :                         stc.laddress[0] = net->ro._s_addr->address.sin.sin_addr.s_addr;
    6142             :                         stc.laddress[1] = 0;
    6143             :                         stc.laddress[2] = 0;
    6144             :                         stc.laddress[3] = 0;
    6145             :                         stc.laddr_type = SCTP_IPV4_ADDRESS;
    6146             :                         /* scope_id is only for v6 */
    6147             :                         stc.scope_id = 0;
    6148             :                         break;
    6149             : #endif
    6150             : #ifdef INET6
    6151             :                 case AF_INET6:
    6152             :                         sin6 = (struct sockaddr_in6 *)to;
    6153             :                         memcpy(&stc.address, &sin6->sin6_addr,
    6154             :                                sizeof(struct in6_addr));
    6155             :                         stc.addr_type = SCTP_IPV6_ADDRESS;
    6156             :                         stc.scope_id = sin6->sin6_scope_id;
    6157             :                         if (net->src_addr_selected == 0) {
    6158             :                                 /*
    6159             :                                  * strange case here, the INIT should have
    6160             :                                  * done the selection.
    6161             :                                  */
    6162             :                                 net->ro._s_addr = sctp_source_address_selection(inp,
    6163             :                                                                                 stcb, (sctp_route_t *)&net->ro,
    6164             :                                                                                 net, 0, vrf_id);
    6165             :                                 if (net->ro._s_addr == NULL)
    6166             :                                         return;
    6167             : 
    6168             :                                 net->src_addr_selected = 1;
    6169             :                         }
    6170             :                         memcpy(&stc.laddress, &net->ro._s_addr->address.sin6.sin6_addr,
    6171             :                                sizeof(struct in6_addr));
    6172             :                         stc.laddr_type = SCTP_IPV6_ADDRESS;
    6173             :                         break;
    6174             : #endif
    6175             : #if defined(__Userspace__)
    6176             :                 case AF_CONN:
    6177           0 :                         sconn = (struct sockaddr_conn *)to;
    6178           0 :                         stc.address[0] = 0;
    6179           0 :                         stc.address[1] = 0;
    6180           0 :                         stc.address[2] = 0;
    6181           0 :                         stc.address[3] = 0;
    6182           0 :                         memcpy(&stc.address, &sconn->sconn_addr, sizeof(void *));
    6183           0 :                         stc.addr_type = SCTP_CONN_ADDRESS;
    6184           0 :                         stc.laddress[0] = 0;
    6185           0 :                         stc.laddress[1] = 0;
    6186           0 :                         stc.laddress[2] = 0;
    6187           0 :                         stc.laddress[3] = 0;
    6188           0 :                         memcpy(&stc.laddress, &sconn->sconn_addr, sizeof(void *));
    6189           0 :                         stc.laddr_type = SCTP_CONN_ADDRESS;
    6190           0 :                         stc.scope_id = 0;
    6191           0 :                         break;
    6192             : #endif
    6193             :                 }
    6194             :         }
    6195             :         /* Now lets put the SCTP header in place */
    6196           0 :         initack = mtod(m, struct sctp_init_ack_chunk *);
    6197             :         /* Save it off for quick ref */
    6198           0 :         stc.peers_vtag = init_chk->init.initiate_tag;
    6199             :         /* who are we */
    6200           0 :         memcpy(stc.identification, SCTP_VERSION_STRING,
    6201             :                min(strlen(SCTP_VERSION_STRING), sizeof(stc.identification)));
    6202           0 :         memset(stc.reserved, 0, SCTP_RESERVE_SPACE);
    6203             :         /* now the chunk header */
    6204           0 :         initack->ch.chunk_type = SCTP_INITIATION_ACK;
    6205           0 :         initack->ch.chunk_flags = 0;
    6206             :         /* fill in later from mbuf we build */
    6207           0 :         initack->ch.chunk_length = 0;
    6208             :         /* place in my tag */
    6209           0 :         if ((asoc != NULL) &&
    6210           0 :             ((SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_WAIT) ||
    6211           0 :              (SCTP_GET_STATE(asoc) == SCTP_STATE_INUSE) ||
    6212           0 :              (SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_ECHOED))) {
    6213             :                 /* re-use the v-tags and init-seq here */
    6214           0 :                 initack->init.initiate_tag = htonl(asoc->my_vtag);
    6215           0 :                 initack->init.initial_tsn = htonl(asoc->init_seq_number);
    6216             :         } else {
    6217             :                 uint32_t vtag, itsn;
    6218           0 :                 if (hold_inp_lock) {
    6219           0 :                         SCTP_INP_INCR_REF(inp);
    6220           0 :                         SCTP_INP_RUNLOCK(inp);
    6221             :                 }
    6222           0 :                 if (asoc) {
    6223           0 :                         atomic_add_int(&asoc->refcnt, 1);
    6224           0 :                         SCTP_TCB_UNLOCK(stcb);
    6225             :                 new_tag:
    6226           0 :                         vtag = sctp_select_a_tag(inp, inp->sctp_lport, sh->src_port, 1);
    6227           0 :                         if ((asoc->peer_supports_nat)  && (vtag == asoc->my_vtag)) {
    6228             :                                 /* Got a duplicate vtag on some guy behind a nat
    6229             :                                  * make sure we don't use it.
    6230             :                                  */
    6231           0 :                                 goto new_tag;
    6232             :                         }
    6233           0 :                         initack->init.initiate_tag = htonl(vtag);
    6234             :                         /* get a TSN to use too */
    6235           0 :                         itsn = sctp_select_initial_TSN(&inp->sctp_ep);
    6236           0 :                         initack->init.initial_tsn = htonl(itsn);
    6237           0 :                         SCTP_TCB_LOCK(stcb);
    6238           0 :                         atomic_add_int(&asoc->refcnt, -1);
    6239             :                 } else {
    6240           0 :                         vtag = sctp_select_a_tag(inp, inp->sctp_lport, sh->src_port, 1);
    6241           0 :                         initack->init.initiate_tag = htonl(vtag);
    6242             :                         /* get a TSN to use too */
    6243           0 :                         initack->init.initial_tsn = htonl(sctp_select_initial_TSN(&inp->sctp_ep));
    6244             :                 }
    6245           0 :                 if (hold_inp_lock) {
    6246           0 :                         SCTP_INP_RLOCK(inp);
    6247           0 :                         SCTP_INP_DECR_REF(inp);
    6248             :                 }
    6249             :         }
    6250             :         /* save away my tag to */
    6251           0 :         stc.my_vtag = initack->init.initiate_tag;
    6252             : 
    6253             :         /* set up some of the credits. */
    6254           0 :         so = inp->sctp_socket;
    6255           0 :         if (so == NULL) {
    6256             :                 /* memory problem */
    6257           0 :                 sctp_m_freem(m);
    6258           0 :                 return;
    6259             :         } else {
    6260           0 :                 initack->init.a_rwnd = htonl(max(SCTP_SB_LIMIT_RCV(so), SCTP_MINIMAL_RWND));
    6261             :         }
    6262             :         /* set what I want */
    6263           0 :         his_limit = ntohs(init_chk->init.num_inbound_streams);
    6264             :         /* choose what I want */
    6265           0 :         if (asoc != NULL) {
    6266           0 :                 if (asoc->streamoutcnt > inp->sctp_ep.pre_open_stream_count) {
    6267           0 :                         i_want = asoc->streamoutcnt;
    6268             :                 } else {
    6269           0 :                         i_want = inp->sctp_ep.pre_open_stream_count;
    6270             :                 }
    6271             :         } else {
    6272           0 :                 i_want = inp->sctp_ep.pre_open_stream_count;
    6273             :         }
    6274           0 :         if (his_limit < i_want) {
    6275             :                 /* I Want more :< */
    6276           0 :                 initack->init.num_outbound_streams = init_chk->init.num_inbound_streams;
    6277             :         } else {
    6278             :                 /* I can have what I want :> */
    6279           0 :                 initack->init.num_outbound_streams = htons(i_want);
    6280             :         }
    6281             :         /* tell him his limit. */
    6282           0 :         initack->init.num_inbound_streams =
    6283           0 :                 htons(inp->sctp_ep.max_open_streams_intome);
    6284             : 
    6285             :         /* adaptation layer indication parameter */
    6286           0 :         if (inp->sctp_ep.adaptation_layer_indicator_provided) {
    6287           0 :                 parameter_len = (uint16_t)sizeof(struct sctp_adaptation_layer_indication);
    6288           0 :                 ali = (struct sctp_adaptation_layer_indication *)(mtod(m, caddr_t) + chunk_len);
    6289           0 :                 ali->ph.param_type = htons(SCTP_ULP_ADAPTATION);
    6290           0 :                 ali->ph.param_length = htons(parameter_len);
    6291           0 :                 ali->indication = htonl(inp->sctp_ep.adaptation_layer_indicator);
    6292           0 :                 chunk_len += parameter_len;
    6293             :         }
    6294             : 
    6295             :         /* ECN parameter */
    6296           0 :         if (((asoc != NULL) && (asoc->ecn_supported == 1)) ||
    6297           0 :             ((asoc == NULL) && (inp->ecn_supported == 1))) {
    6298           0 :                 parameter_len = (uint16_t)sizeof(struct sctp_paramhdr);
    6299           0 :                 ph = (struct sctp_paramhdr *)(mtod(m, caddr_t) + chunk_len);
    6300           0 :                 ph->param_type = htons(SCTP_ECN_CAPABLE);
    6301           0 :                 ph->param_length = htons(parameter_len);
    6302           0 :                 chunk_len += parameter_len;
    6303             :         }
    6304             : 
    6305             :         /* PR-SCTP supported parameter */
    6306           0 :         if (((asoc != NULL) && (asoc->prsctp_supported == 1)) ||
    6307           0 :             ((asoc == NULL) && (inp->prsctp_supported == 1))) {
    6308           0 :                 parameter_len = (uint16_t)sizeof(struct sctp_paramhdr);
    6309           0 :                 ph = (struct sctp_paramhdr *)(mtod(m, caddr_t) + chunk_len);
    6310           0 :                 ph->param_type = htons(SCTP_PRSCTP_SUPPORTED);
    6311           0 :                 ph->param_length = htons(parameter_len);
    6312           0 :                 chunk_len += parameter_len;
    6313             :         }
    6314             : 
    6315             :         /* Add NAT friendly parameter */
    6316           0 :         if (nat_friendly) {
    6317           0 :                 parameter_len = (uint16_t)sizeof(struct sctp_paramhdr);
    6318           0 :                 ph = (struct sctp_paramhdr *)(mtod(m, caddr_t) + chunk_len);
    6319           0 :                 ph->param_type = htons(SCTP_HAS_NAT_SUPPORT);
    6320           0 :                 ph->param_length = htons(parameter_len);
    6321           0 :                 chunk_len += parameter_len;
    6322             :         }
    6323             : 
    6324             :         /* And now tell the peer which extensions we support */
    6325           0 :         num_ext = 0;
    6326           0 :         pr_supported = (struct sctp_supported_chunk_types_param *)(mtod(m, caddr_t) + chunk_len);
    6327           0 :         if (((asoc != NULL) && (asoc->prsctp_supported == 1)) ||
    6328           0 :             ((asoc == NULL) && (inp->prsctp_supported == 1))) {
    6329           0 :                 pr_supported->chunk_types[num_ext++] = SCTP_FORWARD_CUM_TSN;
    6330             :         }
    6331           0 :         if (((asoc != NULL) && (asoc->auth_supported == 1)) ||
    6332           0 :             ((asoc == NULL) && (inp->auth_supported == 1))) {
    6333           0 :                 pr_supported->chunk_types[num_ext++] = SCTP_AUTHENTICATION;
    6334             :         }
    6335           0 :         if (((asoc != NULL) && (asoc->asconf_supported == 1)) ||
    6336           0 :             ((asoc == NULL) && (inp->asconf_supported == 1))) {
    6337           0 :                 pr_supported->chunk_types[num_ext++] = SCTP_ASCONF;
    6338           0 :                 pr_supported->chunk_types[num_ext++] = SCTP_ASCONF_ACK;
    6339             :         }
    6340           0 :         if (((asoc != NULL) && (asoc->reconfig_supported == 1)) ||
    6341           0 :             ((asoc == NULL) && (inp->reconfig_supported == 1))) {
    6342           0 :                 pr_supported->chunk_types[num_ext++] = SCTP_STREAM_RESET;
    6343             :         }
    6344           0 :         if (((asoc != NULL) && (asoc->nrsack_supported == 1)) ||
    6345           0 :             ((asoc == NULL) && (inp->nrsack_supported == 1))) {
    6346           0 :                 pr_supported->chunk_types[num_ext++] = SCTP_NR_SELECTIVE_ACK;
    6347             :         }
    6348           0 :         if (((asoc != NULL) && (asoc->pktdrop_supported == 1)) ||
    6349           0 :             ((asoc == NULL) && (inp->pktdrop_supported == 1))) {
    6350           0 :                 pr_supported->chunk_types[num_ext++] = SCTP_PACKET_DROPPED;
    6351             :         }
    6352           0 :         if (num_ext > 0) {
    6353           0 :                 parameter_len = (uint16_t)sizeof(struct sctp_supported_chunk_types_param) + num_ext;
    6354           0 :                 pr_supported->ph.param_type = htons(SCTP_SUPPORTED_CHUNK_EXT);
    6355           0 :                 pr_supported->ph.param_length = htons(parameter_len);
    6356           0 :                 padding_len = SCTP_SIZE32(parameter_len) - parameter_len;
    6357           0 :                 chunk_len += parameter_len;
    6358             :         }
    6359             :         
    6360             :         /* add authentication parameters */
    6361           0 :         if (((asoc != NULL) && (asoc->auth_supported == 1)) ||
    6362           0 :             ((asoc == NULL) && (inp->auth_supported == 1))) {
    6363             :                 struct sctp_auth_random *randp;
    6364             :                 struct sctp_auth_hmac_algo *hmacs;
    6365             :                 struct sctp_auth_chunk_list *chunks;
    6366             : 
    6367           0 :                 if (padding_len > 0) {
    6368           0 :                         memset(mtod(m, caddr_t) + chunk_len, 0, padding_len);
    6369           0 :                         chunk_len += padding_len;
    6370           0 :                         padding_len = 0;
    6371             :                 }
    6372             :                 /* generate and add RANDOM parameter */
    6373           0 :                 randp = (struct sctp_auth_random *)(mtod(m, caddr_t) + chunk_len);
    6374           0 :                 parameter_len = (uint16_t)sizeof(struct sctp_auth_random) +
    6375             :                                 SCTP_AUTH_RANDOM_SIZE_DEFAULT;
    6376           0 :                 randp->ph.param_type = htons(SCTP_RANDOM);
    6377           0 :                 randp->ph.param_length = htons(parameter_len);
    6378           0 :                 SCTP_READ_RANDOM(randp->random_data, SCTP_AUTH_RANDOM_SIZE_DEFAULT);
    6379           0 :                 padding_len = SCTP_SIZE32(parameter_len) - parameter_len;
    6380           0 :                 chunk_len += parameter_len;
    6381             : 
    6382           0 :                 if (padding_len > 0) {
    6383           0 :                         memset(mtod(m, caddr_t) + chunk_len, 0, padding_len);
    6384           0 :                         chunk_len += padding_len;
    6385           0 :                         padding_len = 0;
    6386             :                 }
    6387             :                 /* add HMAC_ALGO parameter */
    6388           0 :                 hmacs = (struct sctp_auth_hmac_algo *)(mtod(m, caddr_t) + chunk_len);
    6389           0 :                 parameter_len = (uint16_t)sizeof(struct sctp_auth_hmac_algo) +
    6390           0 :                                 sctp_serialize_hmaclist(inp->sctp_ep.local_hmacs,
    6391           0 :                                                         (uint8_t *)hmacs->hmac_ids);
    6392           0 :                 hmacs->ph.param_type = htons(SCTP_HMAC_LIST);
    6393           0 :                 hmacs->ph.param_length = htons(parameter_len);
    6394           0 :                 padding_len = SCTP_SIZE32(parameter_len) - parameter_len;
    6395           0 :                 chunk_len += parameter_len;
    6396             : 
    6397           0 :                 if (padding_len > 0) {
    6398           0 :                         memset(mtod(m, caddr_t) + chunk_len, 0, padding_len);
    6399           0 :                         chunk_len += padding_len;
    6400           0 :                         padding_len = 0;
    6401             :                 }
    6402             :                 /* add CHUNKS parameter */
    6403           0 :                 chunks = (struct sctp_auth_chunk_list *)(mtod(m, caddr_t) + chunk_len);
    6404           0 :                 parameter_len = (uint16_t)sizeof(struct sctp_auth_chunk_list) +
    6405           0 :                                 sctp_serialize_auth_chunks(inp->sctp_ep.local_auth_chunks,
    6406           0 :                                                            chunks->chunk_types);
    6407           0 :                 chunks->ph.param_type = htons(SCTP_CHUNK_LIST);
    6408           0 :                 chunks->ph.param_length = htons(parameter_len);
    6409           0 :                 padding_len = SCTP_SIZE32(parameter_len) - parameter_len;
    6410           0 :                 chunk_len += parameter_len;
    6411             :         }
    6412           0 :         SCTP_BUF_LEN(m) = chunk_len;
    6413           0 :         m_last = m;
    6414             :         /* now the addresses */
    6415             :         /* To optimize this we could put the scoping stuff
    6416             :          * into a structure and remove the individual uint8's from
    6417             :          * the stc structure. Then we could just sifa in the
    6418             :          * address within the stc.. but for now this is a quick
    6419             :          * hack to get the address stuff teased apart.
    6420             :          */
    6421           0 :         scp.ipv4_addr_legal = stc.ipv4_addr_legal;
    6422           0 :         scp.ipv6_addr_legal = stc.ipv6_addr_legal;
    6423             : #if defined(__Userspace__)
    6424           0 :         scp.conn_addr_legal = stc.conn_addr_legal;
    6425             : #endif
    6426           0 :         scp.loopback_scope = stc.loopback_scope;
    6427           0 :         scp.ipv4_local_scope = stc.ipv4_scope;
    6428           0 :         scp.local_scope = stc.local_scope;
    6429           0 :         scp.site_scope = stc.site_scope;
    6430           0 :         m_last = sctp_add_addresses_to_i_ia(inp, stcb, &scp, m_last,
    6431             :                                             cnt_inits_to,
    6432             :                                             &padding_len, &chunk_len);
    6433             :         /* padding_len can only be positive, if no addresses have been added */
    6434           0 :         if (padding_len > 0) {
    6435           0 :                 memset(mtod(m, caddr_t) + chunk_len, 0, padding_len);
    6436           0 :                 chunk_len += padding_len;
    6437           0 :                 SCTP_BUF_LEN(m) += padding_len;
    6438           0 :                 padding_len = 0;
    6439             :         }
    6440             : 
    6441             :         /* tack on the operational error if present */
    6442           0 :         if (op_err) {
    6443           0 :                 parameter_len = 0;
    6444           0 :                 for (m_tmp = op_err; m_tmp != NULL; m_tmp = SCTP_BUF_NEXT(m_tmp)) {
    6445           0 :                         parameter_len += SCTP_BUF_LEN(m_tmp);
    6446             :                 }
    6447           0 :                 padding_len = SCTP_SIZE32(parameter_len) - parameter_len;
    6448           0 :                 SCTP_BUF_NEXT(m_last) = op_err;
    6449           0 :                 while (SCTP_BUF_NEXT(m_last) != NULL) {
    6450           0 :                         m_last = SCTP_BUF_NEXT(m_last);
    6451             :                 }
    6452           0 :                 chunk_len += parameter_len;
    6453             :         }
    6454           0 :         if (padding_len > 0) {
    6455           0 :                 m_last = sctp_add_pad_tombuf(m_last, padding_len);
    6456           0 :                 if (m_last == NULL) {
    6457             :                         /* Houston we have a problem, no space */
    6458           0 :                         sctp_m_freem(m);
    6459           0 :                         return;
    6460             :                 }
    6461           0 :                 chunk_len += padding_len;
    6462           0 :                 padding_len = 0;
    6463             :         }
    6464             :         /* Now we must build a cookie */
    6465           0 :         m_cookie = sctp_add_cookie(init_pkt, offset, m, 0, &stc, &signature);
    6466           0 :         if (m_cookie == NULL) {
    6467             :                 /* memory problem */
    6468           0 :                 sctp_m_freem(m);
    6469           0 :                 return;
    6470             :         }
    6471             :         /* Now append the cookie to the end and update the space/size */
    6472           0 :         SCTP_BUF_NEXT(m_last) = m_cookie;
    6473           0 :         parameter_len = 0;
    6474           0 :         for (m_tmp = m_cookie; m_tmp != NULL; m_tmp = SCTP_BUF_NEXT(m_tmp)) {
    6475           0 :                 parameter_len += SCTP_BUF_LEN(m_tmp);
    6476           0 :                 if (SCTP_BUF_NEXT(m_tmp) == NULL) {
    6477           0 :                         m_last = m_tmp;
    6478             :                 }
    6479             :         }
    6480           0 :         padding_len = SCTP_SIZE32(parameter_len) - parameter_len;
    6481           0 :         chunk_len += parameter_len;
    6482             : 
    6483             :         /* Place in the size, but we don't include
    6484             :          * the last pad (if any) in the INIT-ACK.
    6485             :          */
    6486           0 :         initack->ch.chunk_length = htons(chunk_len);
    6487             : 
    6488             :         /* Time to sign the cookie, we don't sign over the cookie
    6489             :          * signature though thus we set trailer.
    6490             :          */
    6491           0 :         (void)sctp_hmac_m(SCTP_HMAC,
    6492           0 :                           (uint8_t *)inp->sctp_ep.secret_key[(int)(inp->sctp_ep.current_secret_number)],
    6493             :                           SCTP_SECRET_SIZE, m_cookie, sizeof(struct sctp_paramhdr),
    6494             :                           (uint8_t *)signature, SCTP_SIGNATURE_SIZE);
    6495             :         /*
    6496             :          * We sifa 0 here to NOT set IP_DF if its IPv4, we ignore the return
    6497             :          * here since the timer will drive a retranmission.
    6498             :          */
    6499           0 :         if (padding_len > 0) {
    6500           0 :                 if (sctp_add_pad_tombuf(m_last, padding_len) == NULL) {
    6501           0 :                         sctp_m_freem(m);
    6502           0 :                         return;
    6503             :                 }
    6504             :         }
    6505           0 :         if (stc.loopback_scope) {
    6506           0 :                 over_addr = (union sctp_sockstore *)dst;
    6507             :         } else {
    6508           0 :                 over_addr = NULL;
    6509             :         }
    6510             : 
    6511           0 :         (void)sctp_lowlevel_chunk_output(inp, NULL, NULL, to, m, 0, NULL, 0, 0,
    6512             :                                          0, 0,
    6513           0 :                                          inp->sctp_lport, sh->src_port, init_chk->init.initiate_tag,
    6514             :                                          port, over_addr,
    6515             : #if defined(__FreeBSD__)
    6516             :                                          mflowtype, mflowid,
    6517             : #endif
    6518             :                                          SCTP_SO_NOT_LOCKED);
    6519           0 :         SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks);
    6520             : }
    6521             : 
    6522             : 
    6523             : static void
    6524           0 : sctp_prune_prsctp(struct sctp_tcb *stcb,
    6525             :     struct sctp_association *asoc,
    6526             :     struct sctp_sndrcvinfo *srcv,
    6527             :     int dataout)
    6528             : {
    6529           0 :         int freed_spc = 0;
    6530             :         struct sctp_tmit_chunk *chk, *nchk;
    6531             : 
    6532             :         SCTP_TCB_LOCK_ASSERT(stcb);
    6533           0 :         if ((asoc->prsctp_supported) &&
    6534           0 :             (asoc->sent_queue_cnt_removeable > 0)) {
    6535           0 :                 TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) {
    6536             :                         /*
    6537             :                          * Look for chunks marked with the PR_SCTP flag AND
    6538             :                          * the buffer space flag. If the one being sent is
    6539             :                          * equal or greater priority then purge the old one
    6540             :                          * and free some space.
    6541             :                          */
    6542           0 :                         if (PR_SCTP_BUF_ENABLED(chk->flags)) {
    6543             :                                 /*
    6544             :                                  * This one is PR-SCTP AND buffer space
    6545             :                                  * limited type
    6546             :                                  */
    6547           0 :                                 if (chk->rec.data.timetodrop.tv_sec >= (long)srcv->sinfo_timetolive) {
    6548             :                                         /*
    6549             :                                          * Lower numbers equates to higher
    6550             :                                          * priority so if the one we are
    6551             :                                          * looking at has a larger or equal
    6552             :                                          * priority we want to drop the data
    6553             :                                          * and NOT retransmit it.
    6554             :                                          */
    6555           0 :                                         if (chk->data) {
    6556             :                                                 /*
    6557             :                                                  * We release the book_size
    6558             :                                                  * if the mbuf is here
    6559             :                                                  */
    6560             :                                                 int ret_spc;
    6561             :                                                 uint8_t sent;
    6562             : 
    6563           0 :                                                 if (chk->sent > SCTP_DATAGRAM_UNSENT)
    6564           0 :                                                         sent = 1;
    6565             :                                                 else
    6566           0 :                                                         sent = 0;
    6567           0 :                                                 ret_spc = sctp_release_pr_sctp_chunk(stcb, chk,
    6568             :                                                     sent,
    6569             :                                                     SCTP_SO_LOCKED);
    6570           0 :                                                 freed_spc += ret_spc;
    6571           0 :                                                 if (freed_spc >= dataout) {
    6572           0 :                                                         return;
    6573             :                                                 }
    6574             :                                         }       /* if chunk was present */
    6575             :                                 }       /* if of sufficent priority */
    6576             :                         }       /* if chunk has enabled */
    6577             :                 }               /* tailqforeach */
    6578             : 
    6579           0 :                 TAILQ_FOREACH_SAFE(chk, &asoc->send_queue, sctp_next, nchk) {
    6580             :                         /* Here we must move to the sent queue and mark */
    6581           0 :                         if (PR_SCTP_BUF_ENABLED(chk->flags)) {
    6582           0 :                                 if (chk->rec.data.timetodrop.tv_sec >= (long)srcv->sinfo_timetolive) {
    6583           0 :                                         if (chk->data) {
    6584             :                                                 /*
    6585             :                                                  * We release the book_size
    6586             :                                                  * if the mbuf is here
    6587             :                                                  */
    6588             :                                                 int ret_spc;
    6589             : 
    6590           0 :                                                 ret_spc = sctp_release_pr_sctp_chunk(stcb, chk,
    6591             :                                                     0, SCTP_SO_LOCKED);
    6592             : 
    6593           0 :                                                 freed_spc += ret_spc;
    6594           0 :                                                 if (freed_spc >= dataout) {
    6595           0 :                                                         return;
    6596             :                                                 }
    6597             :                                         }       /* end if chk->data */
    6598             :                                 }       /* end if right class */
    6599             :                         }       /* end if chk pr-sctp */
    6600             :                 }               /* tailqforeachsafe (chk) */
    6601             :         }                       /* if enabled in asoc */
    6602             : }
    6603             : 
    6604             : int
    6605           0 : sctp_get_frag_point(struct sctp_tcb *stcb,
    6606             :     struct sctp_association *asoc)
    6607             : {
    6608             :         int siz, ovh;
    6609             : 
    6610             :         /*
    6611             :          * For endpoints that have both v6 and v4 addresses we must reserve
    6612             :          * room for the ipv6 header, for those that are only dealing with V4
    6613             :          * we use a larger frag point.
    6614             :          */
    6615           0 :         if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
    6616           0 :                 ovh = SCTP_MED_OVERHEAD;
    6617             :         } else {
    6618           0 :                 ovh = SCTP_MED_V4_OVERHEAD;
    6619             :         }
    6620             : 
    6621           0 :         if (stcb->asoc.sctp_frag_point > asoc->smallest_mtu)
    6622           0 :                 siz = asoc->smallest_mtu - ovh;
    6623             :         else
    6624           0 :                 siz = (stcb->asoc.sctp_frag_point - ovh);
    6625             :         /*
    6626             :          * if (siz > (MCLBYTES-sizeof(struct sctp_data_chunk))) {
    6627             :          */
    6628             :         /* A data chunk MUST fit in a cluster */
    6629             :         /* siz = (MCLBYTES - sizeof(struct sctp_data_chunk)); */
    6630             :         /* } */
    6631             : 
    6632             :         /* adjust for an AUTH chunk if DATA requires auth */
    6633           0 :         if (sctp_auth_is_required_chunk(SCTP_DATA, stcb->asoc.peer_auth_chunks))
    6634           0 :                 siz -= sctp_get_auth_chunk_len(stcb->asoc.peer_hmac_id);
    6635             : 
    6636           0 :         if (siz % 4) {
    6637             :                 /* make it an even word boundary please */
    6638           0 :                 siz -= (siz % 4);
    6639             :         }
    6640           0 :         return (siz);
    6641             : }
    6642             : 
    6643             : static void
    6644           0 : sctp_set_prsctp_policy(struct sctp_stream_queue_pending *sp)
    6645             : {
    6646             :         /*
    6647             :          * We assume that the user wants PR_SCTP_TTL if the user
    6648             :          * provides a positive lifetime but does not specify any
    6649             :          * PR_SCTP policy.
    6650             :          */
    6651           0 :         if (PR_SCTP_ENABLED(sp->sinfo_flags)) {
    6652           0 :                 sp->act_flags |= PR_SCTP_POLICY(sp->sinfo_flags);
    6653           0 :         } else if (sp->timetolive > 0) {
    6654           0 :                 sp->sinfo_flags |= SCTP_PR_SCTP_TTL;
    6655           0 :                 sp->act_flags |= PR_SCTP_POLICY(sp->sinfo_flags);
    6656             :         } else {
    6657           0 :                 return;
    6658             :         }
    6659           0 :         switch (PR_SCTP_POLICY(sp->sinfo_flags)) {
    6660             :         case CHUNK_FLAGS_PR_SCTP_BUF:
    6661             :                 /*
    6662             :                  * Time to live is a priority stored in tv_sec when
    6663             :                  * doing the buffer drop thing.
    6664             :                  */
    6665           0 :                 sp->ts.tv_sec = sp->timetolive;
    6666           0 :                 sp->ts.tv_usec = 0;
    6667           0 :                 break;
    6668             :         case CHUNK_FLAGS_PR_SCTP_TTL:
    6669             :         {
    6670             :                 struct timeval tv;
    6671           0 :                 (void)SCTP_GETTIME_TIMEVAL(&sp->ts);
    6672           0 :                 tv.tv_sec = sp->timetolive / 1000;
    6673           0 :                 tv.tv_usec = (sp->timetolive * 1000) % 1000000;
    6674             :                 /* TODO sctp_constants.h needs alternative time macros when
    6675             :                  *  _KERNEL is undefined.
    6676             :                  */
    6677             : #ifndef __FreeBSD__
    6678           0 :                 timeradd(&sp->ts, &tv, &sp->ts);
    6679             : #else
    6680             :                 timevaladd(&sp->ts, &tv);
    6681             : #endif
    6682             :         }
    6683           0 :                 break;
    6684             :         case CHUNK_FLAGS_PR_SCTP_RTX:
    6685             :                 /*
    6686             :                  * Time to live is a the number or retransmissions
    6687             :                  * stored in tv_sec.
    6688             :                  */
    6689           0 :                 sp->ts.tv_sec = sp->timetolive;
    6690           0 :                 sp->ts.tv_usec = 0;
    6691           0 :                 break;
    6692             :         default:
    6693           0 :                 SCTPDBG(SCTP_DEBUG_USRREQ1,
    6694             :                         "Unknown PR_SCTP policy %u.\n",
    6695             :                         PR_SCTP_POLICY(sp->sinfo_flags));
    6696           0 :                 break;
    6697             :         }
    6698             : }
    6699             : 
    6700             : static int
    6701           0 : sctp_msg_append(struct sctp_tcb *stcb,
    6702             :                 struct sctp_nets *net,
    6703             :                 struct mbuf *m,
    6704             :                 struct sctp_sndrcvinfo *srcv, int hold_stcb_lock)
    6705             : {
    6706           0 :         int error = 0;
    6707             :         struct mbuf *at;
    6708           0 :         struct sctp_stream_queue_pending *sp = NULL;
    6709             :         struct sctp_stream_out *strm;
    6710             : 
    6711             :         /* Given an mbuf chain, put it
    6712             :          * into the association send queue and
    6713             :          * place it on the wheel
    6714             :          */
    6715           0 :         if (srcv->sinfo_stream >= stcb->asoc.streamoutcnt) {
    6716             :                 /* Invalid stream number */
    6717             :                 SCTP_LTRACE_ERR_RET_PKT(m, NULL, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
    6718           0 :                 error = EINVAL;
    6719           0 :                 goto out_now;
    6720             :         }
    6721           0 :         if ((stcb->asoc.stream_locked) &&
    6722           0 :             (stcb->asoc.stream_locked_on != srcv->sinfo_stream)) {
    6723             :                 SCTP_LTRACE_ERR_RET_PKT(m, NULL, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
    6724           0 :                 error = EINVAL;
    6725           0 :                 goto out_now;
    6726             :         }
    6727           0 :         strm = &stcb->asoc.strmout[srcv->sinfo_stream];
    6728             :         /* Now can we send this? */
    6729           0 :         if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_SENT) ||
    6730           0 :             (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_ACK_SENT) ||
    6731           0 :             (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED) ||
    6732           0 :             (stcb->asoc.state & SCTP_STATE_SHUTDOWN_PENDING)) {
    6733             :                 /* got data while shutting down */
    6734             :                 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ECONNRESET);
    6735           0 :                 error = ECONNRESET;
    6736           0 :                 goto out_now;
    6737             :         }
    6738           0 :         sctp_alloc_a_strmoq(stcb, sp);
    6739           0 :         if (sp == NULL) {
    6740             :                 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
    6741           0 :                 error = ENOMEM;
    6742           0 :                 goto out_now;
    6743             :         }
    6744           0 :         sp->sinfo_flags = srcv->sinfo_flags;
    6745           0 :         sp->timetolive = srcv->sinfo_timetolive;
    6746           0 :         sp->ppid = srcv->sinfo_ppid;
    6747           0 :         sp->context = srcv->sinfo_context;
    6748           0 :         if (sp->sinfo_flags & SCTP_ADDR_OVER) {
    6749           0 :                 sp->net = net;
    6750           0 :                 atomic_add_int(&sp->net->ref_count, 1);
    6751             :         } else {
    6752           0 :                 sp->net = NULL;
    6753             :         }
    6754           0 :         (void)SCTP_GETTIME_TIMEVAL(&sp->ts);
    6755           0 :         sp->stream = srcv->sinfo_stream;
    6756           0 :         sp->msg_is_complete = 1;
    6757           0 :         sp->sender_all_done = 1;
    6758           0 :         sp->some_taken = 0;
    6759           0 :         sp->data = m;
    6760           0 :         sp->tail_mbuf = NULL;
    6761           0 :         sctp_set_prsctp_policy(sp);
    6762             :         /* We could in theory (for sendall) sifa the length
    6763             :          * in, but we would still have to hunt through the
    6764             :          * chain since we need to setup the tail_mbuf
    6765             :          */
    6766           0 :         sp->length = 0;
    6767           0 :         for (at = m; at; at = SCTP_BUF_NEXT(at)) {
    6768           0 :                 if (SCTP_BUF_NEXT(at) == NULL)
    6769           0 :                         sp->tail_mbuf = at;
    6770           0 :                 sp->length += SCTP_BUF_LEN(at);
    6771             :         }
    6772           0 :         if (srcv->sinfo_keynumber_valid) {
    6773           0 :                 sp->auth_keyid = srcv->sinfo_keynumber;
    6774             :         } else {
    6775           0 :                 sp->auth_keyid = stcb->asoc.authinfo.active_keyid;
    6776             :         }
    6777           0 :         if (sctp_auth_is_required_chunk(SCTP_DATA, stcb->asoc.peer_auth_chunks)) {
    6778           0 :                 sctp_auth_key_acquire(stcb, sp->auth_keyid);
    6779           0 :                 sp->holds_key_ref = 1;
    6780             :         }
    6781           0 :         if (hold_stcb_lock == 0) {
    6782           0 :                 SCTP_TCB_SEND_LOCK(stcb);
    6783             :         }
    6784           0 :         sctp_snd_sb_alloc(stcb, sp->length);
    6785           0 :         atomic_add_int(&stcb->asoc.stream_queue_cnt, 1);
    6786           0 :         TAILQ_INSERT_TAIL(&strm->outqueue, sp, next);
    6787           0 :         stcb->asoc.ss_functions.sctp_ss_add_to_stream(stcb, &stcb->asoc, strm, sp, 1);
    6788           0 :         m = NULL;
    6789           0 :         if (hold_stcb_lock == 0) {
    6790           0 :                 SCTP_TCB_SEND_UNLOCK(stcb);
    6791             :         }
    6792             : out_now:
    6793           0 :         if (m) {
    6794           0 :                 sctp_m_freem(m);
    6795             :         }
    6796           0 :         return (error);
    6797             : }
    6798             : 
    6799             : 
    6800             : static struct mbuf *
    6801           0 : sctp_copy_mbufchain(struct mbuf *clonechain,
    6802             :                     struct mbuf *outchain,
    6803             :                     struct mbuf **endofchain,
    6804             :                     int can_take_mbuf,
    6805             :                     int sizeofcpy,
    6806             :                     uint8_t copy_by_ref)
    6807             : {
    6808             :         struct mbuf *m;
    6809             :         struct mbuf *appendchain;
    6810             :         caddr_t cp;
    6811             :         int len;
    6812             : 
    6813           0 :         if (endofchain == NULL) {
    6814             :                 /* error */
    6815             :         error_out:
    6816           0 :                 if (outchain)
    6817           0 :                         sctp_m_freem(outchain);
    6818           0 :                 return (NULL);
    6819             :         }
    6820           0 :         if (can_take_mbuf) {
    6821           0 :                 appendchain = clonechain;
    6822             :         } else {
    6823           0 :                 if (!copy_by_ref &&
    6824             : #if defined(__Panda__)
    6825             :                     0
    6826             : #else
    6827           0 :                     (sizeofcpy <= (int)((((SCTP_BASE_SYSCTL(sctp_mbuf_threshold_count) - 1) * MLEN) + MHLEN)))
    6828             : #endif
    6829             :                     ) {
    6830             :                         /* Its not in a cluster */
    6831           0 :                         if (*endofchain == NULL) {
    6832             :                                 /* lets get a mbuf cluster */
    6833           0 :                                 if (outchain == NULL) {
    6834             :                                         /* This is the general case */
    6835             :                                 new_mbuf:
    6836           0 :                                         outchain = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_NOWAIT, 1, MT_HEADER);
    6837           0 :                                         if (outchain == NULL) {
    6838           0 :                                                 goto error_out;
    6839             :                                         }
    6840           0 :                                         SCTP_BUF_LEN(outchain) = 0;
    6841           0 :                                         *endofchain = outchain;
    6842             :                                         /* get the prepend space */
    6843           0 :                                         SCTP_BUF_RESV_UF(outchain, (SCTP_FIRST_MBUF_RESV+4));
    6844             :                                 } else {
    6845             :                                         /* We really should not get a NULL in endofchain */
    6846             :                                         /* find end */
    6847           0 :                                         m = outchain;
    6848           0 :                                         while (m) {
    6849           0 :                                                 if (SCTP_BUF_NEXT(m) == NULL) {
    6850           0 :                                                         *endofchain = m;
    6851           0 :                                                         break;
    6852             :                                                 }
    6853           0 :                                                 m = SCTP_BUF_NEXT(m);
    6854             :                                         }
    6855             :                                         /* sanity */
    6856           0 :                                         if (*endofchain == NULL) {
    6857             :                                                 /* huh, TSNH XXX maybe we should panic */
    6858           0 :                                                 sctp_m_freem(outchain);
    6859           0 :                                                 goto new_mbuf;
    6860             :                                         }
    6861             :                                 }
    6862             :                                 /* get the new end of length */
    6863           0 :                                 len = M_TRAILINGSPACE(*endofchain);
    6864             :                         } else {
    6865             :                                 /* how much is left at the end? */
    6866           0 :                                 len = M_TRAILINGSPACE(*endofchain);
    6867             :                         }
    6868             :                         /* Find the end of the data, for appending */
    6869           0 :                         cp = (mtod((*endofchain), caddr_t) + SCTP_BUF_LEN((*endofchain)));
    6870             : 
    6871             :                         /* Now lets copy it out */
    6872           0 :                         if (len >= sizeofcpy) {
    6873             :                                 /* It all fits, copy it in */
    6874           0 :                                 m_copydata(clonechain, 0, sizeofcpy, cp);
    6875           0 :                                 SCTP_BUF_LEN((*endofchain)) += sizeofcpy;
    6876             :                         } else {
    6877             :                                 /* fill up the end of the chain */
    6878           0 :                                 if (len > 0) {
    6879           0 :                                         m_copydata(clonechain, 0, len, cp);
    6880           0 :                                         SCTP_BUF_LEN((*endofchain)) += len;
    6881             :                                         /* now we need another one */
    6882           0 :                                         sizeofcpy -= len;
    6883             :                                 }
    6884           0 :                                 m = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_NOWAIT, 1, MT_HEADER);
    6885           0 :                                 if (m == NULL) {
    6886             :                                         /* We failed */
    6887           0 :                                         goto error_out;
    6888             :                                 }
    6889           0 :                                 SCTP_BUF_NEXT((*endofchain)) = m;
    6890           0 :                                 *endofchain = m;
    6891           0 :                                 cp = mtod((*endofchain), caddr_t);
    6892           0 :                                 m_copydata(clonechain, len, sizeofcpy, cp);
    6893           0 :                                 SCTP_BUF_LEN((*endofchain)) += sizeofcpy;
    6894             :                         }
    6895           0 :                         return (outchain);
    6896             :                 } else {
    6897             :                         /* copy the old fashion way */
    6898           0 :                         appendchain = SCTP_M_COPYM(clonechain, 0, M_COPYALL, M_NOWAIT);
    6899             : #ifdef SCTP_MBUF_LOGGING
    6900             :                         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
    6901             :                                 sctp_log_mbc(appendchain, SCTP_MBUF_ICOPY);
    6902             :                         }
    6903             : #endif
    6904             :                 }
    6905             :         }
    6906           0 :         if (appendchain == NULL) {
    6907             :                 /* error */
    6908           0 :                 if (outchain)
    6909           0 :                         sctp_m_freem(outchain);
    6910           0 :                 return (NULL);
    6911             :         }
    6912           0 :         if (outchain) {
    6913             :                 /* tack on to the end */
    6914           0 :                 if (*endofchain != NULL) {
    6915           0 :                         SCTP_BUF_NEXT(((*endofchain))) = appendchain;
    6916             :                 } else {
    6917           0 :                         m = outchain;
    6918           0 :                         while (m) {
    6919           0 :                                 if (SCTP_BUF_NEXT(m) == NULL) {
    6920           0 :                                         SCTP_BUF_NEXT(m) = appendchain;
    6921           0 :                                         break;
    6922             :                                 }
    6923           0 :                                 m = SCTP_BUF_NEXT(m);
    6924             :                         }
    6925             :                 }
    6926             :                 /*
    6927             :                  * save off the end and update the end-chain
    6928             :                  * postion
    6929             :                  */
    6930           0 :                 m = appendchain;
    6931           0 :                 while (m) {
    6932           0 :                         if (SCTP_BUF_NEXT(m) == NULL) {
    6933           0 :                                 *endofchain = m;
    6934           0 :                                 break;
    6935             :                         }
    6936           0 :                         m = SCTP_BUF_NEXT(m);
    6937             :                 }
    6938           0 :                 return (outchain);
    6939             :         } else {
    6940             :                 /* save off the end and update the end-chain postion */
    6941           0 :                 m = appendchain;
    6942           0 :                 while (m) {
    6943           0 :                         if (SCTP_BUF_NEXT(m) == NULL) {
    6944           0 :                                 *endofchain = m;
    6945           0 :                                 break;
    6946             :                         }
    6947           0 :                         m = SCTP_BUF_NEXT(m);
    6948             :                 }
    6949           0 :                 return (appendchain);
    6950             :         }
    6951             : }
    6952             : 
    6953             : static int
    6954             : sctp_med_chunk_output(struct sctp_inpcb *inp,
    6955             :                       struct sctp_tcb *stcb,
    6956             :                       struct sctp_association *asoc,
    6957             :                       int *num_out,
    6958             :                       int *reason_code,
    6959             :                       int control_only, int from_where,
    6960             :                       struct timeval *now, int *now_filled, int frag_point, int so_locked
    6961             : #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
    6962             :                       SCTP_UNUSED
    6963             : #endif
    6964             :                       );
    6965             : 
    6966             : static void
    6967           0 : sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr,
    6968             :     uint32_t val SCTP_UNUSED)
    6969             : {
    6970             :         struct sctp_copy_all *ca;
    6971             :         struct mbuf *m;
    6972           0 :         int ret = 0;
    6973           0 :         int added_control = 0;
    6974           0 :         int un_sent, do_chunk_output = 1;
    6975             :         struct sctp_association *asoc;
    6976             :         struct sctp_nets *net;
    6977             : 
    6978           0 :         ca = (struct sctp_copy_all *)ptr;
    6979           0 :         if (ca->m == NULL) {
    6980           0 :                 return;
    6981             :         }
    6982           0 :         if (ca->inp != inp) {
    6983             :                 /* TSNH */
    6984           0 :                 return;
    6985             :         }
    6986           0 :         if (ca->sndlen > 0) {
    6987           0 :                 m = SCTP_M_COPYM(ca->m, 0, M_COPYALL, M_NOWAIT);
    6988           0 :                 if (m == NULL) {
    6989             :                         /* can't copy so we are done */
    6990           0 :                         ca->cnt_failed++;
    6991           0 :                         return;
    6992             :                 }
    6993             : #ifdef SCTP_MBUF_LOGGING
    6994             :                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
    6995             :                         sctp_log_mbc(m, SCTP_MBUF_ICOPY);
    6996             :                 }
    6997             : #endif
    6998             :         } else {
    6999           0 :                 m = NULL;
    7000             :         }
    7001             :         SCTP_TCB_LOCK_ASSERT(stcb);
    7002           0 :         if (stcb->asoc.alternate) {
    7003           0 :                 net = stcb->asoc.alternate;
    7004             :         } else {
    7005           0 :                 net = stcb->asoc.primary_destination;
    7006             :         }
    7007           0 :         if (ca->sndrcv.sinfo_flags & SCTP_ABORT) {
    7008             :                 /* Abort this assoc with m as the user defined reason */
    7009           0 :                 if (m != NULL) {
    7010           0 :                         SCTP_BUF_PREPEND(m, sizeof(struct sctp_paramhdr), M_NOWAIT);
    7011             :                 } else {
    7012           0 :                         m = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
    7013             :                                                   0, M_NOWAIT, 1, MT_DATA);
    7014           0 :                         SCTP_BUF_LEN(m) = sizeof(struct sctp_paramhdr);
    7015             :                 }
    7016           0 :                 if (m != NULL) {
    7017             :                         struct sctp_paramhdr *ph;
    7018             : 
    7019           0 :                         ph = mtod(m, struct sctp_paramhdr *);
    7020           0 :                         ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
    7021           0 :                         ph->param_length = htons(sizeof(struct sctp_paramhdr) + ca->sndlen);
    7022             :                 }
    7023             :                 /* We add one here to keep the assoc from
    7024             :                  * dis-appearing on us.
    7025             :                  */
    7026           0 :                 atomic_add_int(&stcb->asoc.refcnt, 1);
    7027           0 :                 sctp_abort_an_association(inp, stcb, m, SCTP_SO_NOT_LOCKED);
    7028             :                 /* sctp_abort_an_association calls sctp_free_asoc()
    7029             :                  * free association will NOT free it since we
    7030             :                  * incremented the refcnt .. we do this to prevent
    7031             :                  * it being freed and things getting tricky since
    7032             :                  * we could end up (from free_asoc) calling inpcb_free
    7033             :                  * which would get a recursive lock call to the
    7034             :                  * iterator lock.. But as a consequence of that the
    7035             :                  * stcb will return to us un-locked.. since free_asoc
    7036             :                  * returns with either no TCB or the TCB unlocked, we
    7037             :                  * must relock.. to unlock in the iterator timer :-0
    7038             :                  */
    7039           0 :                 SCTP_TCB_LOCK(stcb);
    7040           0 :                 atomic_add_int(&stcb->asoc.refcnt, -1);
    7041           0 :                 goto no_chunk_output;
    7042             :         } else {
    7043           0 :                 if (m) {
    7044           0 :                         ret = sctp_msg_append(stcb, net, m,
    7045             :                                               &ca->sndrcv, 1);
    7046             :                 }
    7047           0 :                 asoc = &stcb->asoc;
    7048           0 :                 if (ca->sndrcv.sinfo_flags & SCTP_EOF) {
    7049             :                         /* shutdown this assoc */
    7050             :                         int cnt;
    7051           0 :                         cnt = sctp_is_there_unsent_data(stcb, SCTP_SO_NOT_LOCKED);
    7052             : 
    7053           0 :                         if (TAILQ_EMPTY(&asoc->send_queue) &&
    7054           0 :                             TAILQ_EMPTY(&asoc->sent_queue) &&
    7055             :                             (cnt == 0)) {
    7056           0 :                                 if (asoc->locked_on_sending) {
    7057           0 :                                         goto abort_anyway;
    7058             :                                 }
    7059             :                                 /* there is nothing queued to send, so I'm done... */
    7060           0 :                                 if ((SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) &&
    7061           0 :                                     (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_RECEIVED) &&
    7062           0 :                                     (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT)) {
    7063             :                                         /* only send SHUTDOWN the first time through */
    7064           0 :                                         if (SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) {
    7065           0 :                                                 SCTP_STAT_DECR_GAUGE32(sctps_currestab);
    7066             :                                         }
    7067           0 :                                         SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_SENT);
    7068           0 :                                         SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
    7069           0 :                                         sctp_stop_timers_for_shutdown(stcb);
    7070           0 :                                         sctp_send_shutdown(stcb, net);
    7071           0 :                                         sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, stcb->sctp_ep, stcb,
    7072             :                                                          net);
    7073           0 :                                         sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, stcb->sctp_ep, stcb,
    7074             :                                                          asoc->primary_destination);
    7075           0 :                                         added_control = 1;
    7076           0 :                                         do_chunk_output = 0;
    7077             :                                 }
    7078             :                         } else {
    7079             :                                 /*
    7080             :                                  * we still got (or just got) data to send, so set
    7081             :                                  * SHUTDOWN_PENDING
    7082             :                                  */
    7083             :                                 /*
    7084             :                                  * XXX sockets draft says that SCTP_EOF should be
    7085             :                                  * sent with no data.  currently, we will allow user
    7086             :                                  * data to be sent first and move to
    7087             :                                  * SHUTDOWN-PENDING
    7088             :                                  */
    7089           0 :                                 if ((SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) &&
    7090           0 :                                     (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_RECEIVED) &&
    7091           0 :                                     (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT)) {
    7092           0 :                                         if (asoc->locked_on_sending) {
    7093             :                                                 /* Locked to send out the data */
    7094             :                                                 struct sctp_stream_queue_pending *sp;
    7095           0 :                                                 sp = TAILQ_LAST(&asoc->locked_on_sending->outqueue, sctp_streamhead);
    7096           0 :                                                 if (sp) {
    7097           0 :                                                         if ((sp->length == 0) && (sp->msg_is_complete == 0))
    7098           0 :                                                                 asoc->state |= SCTP_STATE_PARTIAL_MSG_LEFT;
    7099             :                                                 }
    7100             :                                         }
    7101           0 :                                         asoc->state |= SCTP_STATE_SHUTDOWN_PENDING;
    7102           0 :                                         if (TAILQ_EMPTY(&asoc->send_queue) &&
    7103           0 :                                             TAILQ_EMPTY(&asoc->sent_queue) &&
    7104           0 :                                             (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT)) {
    7105             :                                         abort_anyway:
    7106           0 :                                                 atomic_add_int(&stcb->asoc.refcnt, 1);
    7107           0 :                                                 sctp_abort_an_association(stcb->sctp_ep, stcb,
    7108             :                                                                           NULL, SCTP_SO_NOT_LOCKED);
    7109           0 :                                                 atomic_add_int(&stcb->asoc.refcnt, -1);
    7110           0 :                                                 goto no_chunk_output;
    7111             :                                         }
    7112           0 :                                         sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, stcb->sctp_ep, stcb,
    7113             :                                                          asoc->primary_destination);
    7114             :                                 }
    7115             :                         }
    7116             : 
    7117             :                 }
    7118             :         }
    7119           0 :         un_sent = ((stcb->asoc.total_output_queue_size - stcb->asoc.total_flight) +
    7120           0 :                    (stcb->asoc.stream_queue_cnt * sizeof(struct sctp_data_chunk)));
    7121             : 
    7122           0 :         if ((sctp_is_feature_off(inp, SCTP_PCB_FLAGS_NODELAY)) &&
    7123           0 :             (stcb->asoc.total_flight > 0) &&
    7124           0 :             (un_sent < (int)(stcb->asoc.smallest_mtu - SCTP_MIN_OVERHEAD))) {
    7125           0 :                 do_chunk_output = 0;
    7126             :         }
    7127           0 :         if (do_chunk_output)
    7128           0 :                 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_USR_SEND, SCTP_SO_NOT_LOCKED);
    7129           0 :         else if (added_control) {
    7130           0 :                 int num_out, reason, now_filled = 0;
    7131             :                 struct timeval now;
    7132             :                 int frag_point;
    7133             : 
    7134           0 :                 frag_point = sctp_get_frag_point(stcb, &stcb->asoc);
    7135           0 :                 (void)sctp_med_chunk_output(inp, stcb, &stcb->asoc, &num_out,
    7136             :                                       &reason, 1, 1, &now, &now_filled, frag_point, SCTP_SO_NOT_LOCKED);
    7137             :         }
    7138             :  no_chunk_output:
    7139           0 :         if (ret) {
    7140           0 :                 ca->cnt_failed++;
    7141             :         } else {
    7142           0 :                 ca->cnt_sent++;
    7143             :         }
    7144             : }
    7145             : 
    7146             : static void
    7147           0 : sctp_sendall_completes(void *ptr, uint32_t val SCTP_UNUSED)
    7148             : {
    7149             :         struct sctp_copy_all *ca;
    7150             : 
    7151           0 :         ca = (struct sctp_copy_all *)ptr;
    7152             :         /*
    7153             :          * Do a notify here? Kacheong suggests that the notify be done at
    7154             :          * the send time.. so you would push up a notification if any send
    7155             :          * failed. Don't know if this is feasable since the only failures we
    7156             :          * have is "memory" related and if you cannot get an mbuf to send
    7157             :          * the data you surely can't get an mbuf to send up to notify the
    7158             :          * user you can't send the data :->
    7159             :          */
    7160             : 
    7161             :         /* now free everything */
    7162           0 :         sctp_m_freem(ca->m);
    7163           0 :         SCTP_FREE(ca, SCTP_M_COPYAL);
    7164           0 : }
    7165             : 
    7166             : static struct mbuf *
    7167           0 : sctp_copy_out_all(struct uio *uio, int len)
    7168             : {
    7169             :         struct mbuf *ret, *at;
    7170             :         int left, willcpy, cancpy, error;
    7171             : 
    7172           0 :         ret = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_WAITOK, 1, MT_DATA);
    7173           0 :         if (ret == NULL) {
    7174             :                 /* TSNH */
    7175           0 :                 return (NULL);
    7176             :         }
    7177           0 :         left = len;
    7178           0 :         SCTP_BUF_LEN(ret) = 0;
    7179             :         /* save space for the data chunk header */
    7180           0 :         cancpy = M_TRAILINGSPACE(ret);
    7181           0 :         willcpy = min(cancpy, left);
    7182           0 :         at = ret;
    7183           0 :         while (left > 0) {
    7184             :                 /* Align data to the end */
    7185           0 :                 error = uiomove(mtod(at, caddr_t), willcpy, uio);
    7186           0 :                 if (error) {
    7187             :         err_out_now:
    7188           0 :                         sctp_m_freem(at);
    7189           0 :                         return (NULL);
    7190             :                 }
    7191           0 :                 SCTP_BUF_LEN(at) = willcpy;
    7192           0 :                 SCTP_BUF_NEXT_PKT(at) = SCTP_BUF_NEXT(at) = 0;
    7193           0 :                 left -= willcpy;
    7194           0 :                 if (left > 0) {
    7195           0 :                         SCTP_BUF_NEXT(at) = sctp_get_mbuf_for_msg(left, 0, M_WAITOK, 1, MT_DATA);
    7196           0 :                         if (SCTP_BUF_NEXT(at) == NULL) {
    7197           0 :                                 goto err_out_now;
    7198             :                         }
    7199           0 :                         at = SCTP_BUF_NEXT(at);
    7200           0 :                         SCTP_BUF_LEN(at) = 0;
    7201           0 :                         cancpy = M_TRAILINGSPACE(at);
    7202           0 :                         willcpy = min(cancpy, left);
    7203             :                 }
    7204             :         }
    7205           0 :         return (ret);
    7206             : }
    7207             : 
    7208             : static int
    7209           0 : sctp_sendall(struct sctp_inpcb *inp, struct uio *uio, struct mbuf *m,
    7210             :     struct sctp_sndrcvinfo *srcv)
    7211             : {
    7212             :         int ret;
    7213             :         struct sctp_copy_all *ca;
    7214             : 
    7215           0 :         SCTP_MALLOC(ca, struct sctp_copy_all *, sizeof(struct sctp_copy_all),
    7216             :                     SCTP_M_COPYAL);
    7217           0 :         if (ca == NULL) {
    7218           0 :                 sctp_m_freem(m);
    7219             :                 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
    7220           0 :                 return (ENOMEM);
    7221             :         }
    7222           0 :         memset(ca, 0, sizeof(struct sctp_copy_all));
    7223             : 
    7224           0 :         ca->inp = inp;
    7225           0 :         if (srcv) {
    7226           0 :                 memcpy(&ca->sndrcv, srcv, sizeof(struct sctp_nonpad_sndrcvinfo));
    7227             :         }
    7228             :         /*
    7229             :          * take off the sendall flag, it would be bad if we failed to do
    7230             :          * this :-0
    7231             :          */
    7232           0 :         ca->sndrcv.sinfo_flags &= ~SCTP_SENDALL;
    7233             :         /* get length and mbuf chain */
    7234           0 :         if (uio) {
    7235             : #if defined(__APPLE__)
    7236             : #if defined(APPLE_LEOPARD)
    7237             :                 ca->sndlen = uio->uio_resid;
    7238             : #else
    7239             :                 ca->sndlen = uio_resid(uio);
    7240             : #endif
    7241             : #else
    7242           0 :                 ca->sndlen = uio->uio_resid;
    7243             : #endif
    7244             : #if defined(__APPLE__)
    7245             :                 SCTP_SOCKET_UNLOCK(SCTP_INP_SO(inp), 0);
    7246             : #endif
    7247           0 :                 ca->m = sctp_copy_out_all(uio, ca->sndlen);
    7248             : #if defined(__APPLE__)
    7249             :                 SCTP_SOCKET_LOCK(SCTP_INP_SO(inp), 0);
    7250             : #endif
    7251           0 :                 if (ca->m == NULL) {
    7252           0 :                         SCTP_FREE(ca, SCTP_M_COPYAL);
    7253             :                         SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
    7254           0 :                         return (ENOMEM);
    7255             :                 }
    7256             :         } else {
    7257             :                 /* Gather the length of the send */
    7258             :                 struct mbuf *mat;
    7259             : 
    7260           0 :                 ca->sndlen = 0;
    7261           0 :                 for (mat = m; mat; mat = SCTP_BUF_NEXT(mat)) {
    7262           0 :                         ca->sndlen += SCTP_BUF_LEN(mat);
    7263             :                 }
    7264             :         }
    7265           0 :         ret = sctp_initiate_iterator(NULL, sctp_sendall_iterator, NULL,
    7266             :                                      SCTP_PCB_ANY_FLAGS, SCTP_PCB_ANY_FEATURES,
    7267             :                                      SCTP_ASOC_ANY_STATE,
    7268             :                                      (void *)ca, 0,
    7269             :                                      sctp_sendall_completes, inp, 1);
    7270           0 :         if (ret) {
    7271           0 :                 SCTP_PRINTF("Failed to initiate iterator for sendall\n");
    7272           0 :                 SCTP_FREE(ca, SCTP_M_COPYAL);
    7273             :                 SCTP_LTRACE_ERR_RET_PKT(m, inp, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, EFAULT);
    7274           0 :                 return (EFAULT);
    7275             :         }
    7276           0 :         return (0);
    7277             : }
    7278             : 
    7279             : 
    7280             : void
    7281           0 : sctp_toss_old_cookies(struct sctp_tcb *stcb, struct sctp_association *asoc)
    7282             : {
    7283             :         struct sctp_tmit_chunk *chk, *nchk;
    7284             : 
    7285           0 :         TAILQ_FOREACH_SAFE(chk, &asoc->control_send_queue, sctp_next, nchk) {
    7286           0 :                 if (chk->rec.chunk_id.id == SCTP_COOKIE_ECHO) {
    7287           0 :                         TAILQ_REMOVE(&asoc->control_send_queue, chk, sctp_next);
    7288           0 :                         if (chk->data) {
    7289           0 :                                 sctp_m_freem(chk->data);
    7290           0 :                                 chk->data = NULL;
    7291             :                         }
    7292           0 :                         asoc->ctrl_queue_cnt--;
    7293           0 :                         sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
    7294             :                 }
    7295             :         }
    7296           0 : }
    7297             : 
    7298             : void
    7299           0 : sctp_toss_old_asconf(struct sctp_tcb *stcb)
    7300             : {
    7301             :         struct sctp_association *asoc;
    7302             :         struct sctp_tmit_chunk *chk, *nchk;
    7303             :         struct sctp_asconf_chunk *acp;
    7304             : 
    7305           0 :         asoc = &stcb->asoc;
    7306           0 :         TAILQ_FOREACH_SAFE(chk, &asoc->asconf_send_queue, sctp_next, nchk) {
    7307             :                 /* find SCTP_ASCONF chunk in queue */
    7308           0 :                 if (chk->rec.chunk_id.id == SCTP_ASCONF) {
    7309           0 :                         if (chk->data) {
    7310           0 :                                 acp = mtod(chk->data, struct sctp_asconf_chunk *);
    7311           0 :                                 if (SCTP_TSN_GT(ntohl(acp->serial_number), asoc->asconf_seq_out_acked)) {
    7312             :                                         /* Not Acked yet */
    7313             :                                         break;
    7314             :                                 }
    7315             :                         }
    7316           0 :                         TAILQ_REMOVE(&asoc->asconf_send_queue, chk, sctp_next);
    7317           0 :                         if (chk->data) {
    7318           0 :                                 sctp_m_freem(chk->data);
    7319           0 :                                 chk->data = NULL;
    7320             :                         }
    7321           0 :                         asoc->ctrl_queue_cnt--;
    7322           0 :                         sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
    7323             :                 }
    7324             :         }
    7325           0 : }
    7326             : 
    7327             : 
    7328             : static void
    7329           0 : sctp_clean_up_datalist(struct sctp_tcb *stcb,
    7330             :     struct sctp_association *asoc,
    7331             :     struct sctp_tmit_chunk **data_list,
    7332             :     int bundle_at,
    7333             :     struct sctp_nets *net)
    7334             : {
    7335             :         int i;
    7336             :         struct sctp_tmit_chunk *tp1;
    7337             : 
    7338           0 :         for (i = 0; i < bundle_at; i++) {
    7339             :                 /* off of the send queue */
    7340           0 :                 TAILQ_REMOVE(&asoc->send_queue, data_list[i], sctp_next);
    7341           0 :                 asoc->send_queue_cnt--;
    7342           0 :                 if (i > 0) {
    7343             :                         /*
    7344             :                          * Any chunk NOT 0 you zap the time chunk 0 gets
    7345             :                          * zapped or set based on if a RTO measurment is
    7346             :                          * needed.
    7347             :                          */
    7348           0 :                         data_list[i]->do_rtt = 0;
    7349             :                 }
    7350             :                 /* record time */
    7351           0 :                 data_list[i]->sent_rcv_time = net->last_sent_time;
    7352           0 :                 data_list[i]->rec.data.cwnd_at_send = net->cwnd;
    7353           0 :                 data_list[i]->rec.data.fast_retran_tsn = data_list[i]->rec.data.TSN_seq;
    7354           0 :                 if (data_list[i]->whoTo == NULL) {
    7355           0 :                         data_list[i]->whoTo = net;
    7356           0 :                         atomic_add_int(&net->ref_count, 1);
    7357             :                 }
    7358             :                 /* on to the sent queue */
    7359           0 :                 tp1 = TAILQ_LAST(&asoc->sent_queue, sctpchunk_listhead);
    7360           0 :                 if ((tp1) && SCTP_TSN_GT(tp1->rec.data.TSN_seq, data_list[i]->rec.data.TSN_seq)) {
    7361             :                         struct sctp_tmit_chunk *tpp;
    7362             : 
    7363             :                         /* need to move back */
    7364             :                 back_up_more:
    7365           0 :                         tpp = TAILQ_PREV(tp1, sctpchunk_listhead, sctp_next);
    7366           0 :                         if (tpp == NULL) {
    7367           0 :                                 TAILQ_INSERT_BEFORE(tp1, data_list[i], sctp_next);
    7368           0 :                                 goto all_done;
    7369             :                         }
    7370           0 :                         tp1 = tpp;
    7371           0 :                         if (SCTP_TSN_GT(tp1->rec.data.TSN_seq, data_list[i]->rec.data.TSN_seq)) {
    7372             :                                 goto back_up_more;
    7373             :                         }
    7374           0 :                         TAILQ_INSERT_AFTER(&asoc->sent_queue, tp1, data_list[i], sctp_next);
    7375             :                 } else {
    7376           0 :                         TAILQ_INSERT_TAIL(&asoc->sent_queue,
    7377             :                                           data_list[i],
    7378             :                                           sctp_next);
    7379             :                 }
    7380             :         all_done:
    7381             :                 /* This does not lower until the cum-ack passes it */
    7382           0 :                 asoc->sent_queue_cnt++;
    7383           0 :                 if ((asoc->peers_rwnd <= 0) &&
    7384           0 :                     (asoc->total_flight == 0) &&
    7385             :                     (bundle_at == 1)) {
    7386             :                         /* Mark the chunk as being a window probe */
    7387           0 :                         SCTP_STAT_INCR(sctps_windowprobed);
    7388             :                 }
    7389             : #ifdef SCTP_AUDITING_ENABLED
    7390             :                 sctp_audit_log(0xC2, 3);
    7391             : #endif
    7392           0 :                 data_list[i]->sent = SCTP_DATAGRAM_SENT;
    7393           0 :                 data_list[i]->snd_count = 1;
    7394           0 :                 data_list[i]->rec.data.chunk_was_revoked = 0;
    7395           0 :                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FLIGHT_LOGGING_ENABLE) {
    7396           0 :                         sctp_misc_ints(SCTP_FLIGHT_LOG_UP,
    7397           0 :                                        data_list[i]->whoTo->flight_size,
    7398           0 :                                        data_list[i]->book_size,
    7399           0 :                                        (uintptr_t)data_list[i]->whoTo,
    7400           0 :                                        data_list[i]->rec.data.TSN_seq);
    7401             :                 }
    7402           0 :                 sctp_flight_size_increase(data_list[i]);
    7403           0 :                 sctp_total_flight_increase(stcb, data_list[i]);
    7404           0 :                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOG_RWND_ENABLE) {
    7405           0 :                         sctp_log_rwnd(SCTP_DECREASE_PEER_RWND,
    7406           0 :                               asoc->peers_rwnd, data_list[i]->send_size, SCTP_BASE_SYSCTL(sctp_peer_chunk_oh));
    7407             :                 }
    7408           0 :                 asoc->peers_rwnd = sctp_sbspace_sub(asoc->peers_rwnd,
    7409             :                                                     (uint32_t) (data_list[i]->send_size + SCTP_BASE_SYSCTL(sctp_peer_chunk_oh)));
    7410           0 :                 if (asoc->peers_rwnd < stcb->sctp_ep->sctp_ep.sctp_sws_sender) {
    7411             :                         /* SWS sender side engages */
    7412           0 :                         asoc->peers_rwnd = 0;
    7413             :                 }
    7414             :         }
    7415           0 :         if (asoc->cc_functions.sctp_cwnd_update_packet_transmitted) {
    7416           0 :                 (*asoc->cc_functions.sctp_cwnd_update_packet_transmitted)(stcb, net);
    7417             :         }
    7418           0 : }
    7419             : 
    7420             : static void
    7421           0 : sctp_clean_up_ctl(struct sctp_tcb *stcb, struct sctp_association *asoc, int so_locked
    7422             : #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
    7423             :         SCTP_UNUSED
    7424             : #endif
    7425             : )
    7426             : {
    7427             :         struct sctp_tmit_chunk *chk, *nchk;
    7428             : 
    7429           0 :         TAILQ_FOREACH_SAFE(chk, &asoc->control_send_queue, sctp_next, nchk) {
    7430           0 :                 if ((chk->rec.chunk_id.id == SCTP_SELECTIVE_ACK) ||
    7431           0 :                     (chk->rec.chunk_id.id == SCTP_NR_SELECTIVE_ACK) ||       /* EY */
    7432           0 :                     (chk->rec.chunk_id.id == SCTP_HEARTBEAT_REQUEST) ||
    7433           0 :                     (chk->rec.chunk_id.id == SCTP_HEARTBEAT_ACK) ||
    7434           0 :                     (chk->rec.chunk_id.id == SCTP_FORWARD_CUM_TSN) ||
    7435           0 :                     (chk->rec.chunk_id.id == SCTP_SHUTDOWN) ||
    7436           0 :                     (chk->rec.chunk_id.id == SCTP_SHUTDOWN_ACK) ||
    7437           0 :                     (chk->rec.chunk_id.id == SCTP_OPERATION_ERROR) ||
    7438           0 :                     (chk->rec.chunk_id.id == SCTP_PACKET_DROPPED) ||
    7439           0 :                     (chk->rec.chunk_id.id == SCTP_COOKIE_ACK) ||
    7440           0 :                     (chk->rec.chunk_id.id == SCTP_ECN_CWR) ||
    7441           0 :                     (chk->rec.chunk_id.id == SCTP_ASCONF_ACK)) {
    7442             :                         /* Stray chunks must be cleaned up */
    7443             :         clean_up_anyway:
    7444           0 :                         TAILQ_REMOVE(&asoc->control_send_queue, chk, sctp_next);
    7445           0 :                         if (chk->data) {
    7446           0 :                                 sctp_m_freem(chk->data);
    7447           0 :                                 chk->data = NULL;
    7448             :                         }
    7449           0 :                         asoc->ctrl_queue_cnt--;
    7450           0 :                         if (chk->rec.chunk_id.id == SCTP_FORWARD_CUM_TSN)
    7451           0 :                                 asoc->fwd_tsn_cnt--;
    7452           0 :                         sctp_free_a_chunk(stcb, chk, so_locked);
    7453           0 :                 } else if (chk->rec.chunk_id.id == SCTP_STREAM_RESET) {
    7454             :                         /* special handling, we must look into the param */
    7455           0 :                         if (chk != asoc->str_reset) {
    7456           0 :                                 goto clean_up_anyway;
    7457             :                         }
    7458             :                 }
    7459             :         }
    7460           0 : }
    7461             : 
    7462             : 
    7463             : static int
    7464           0 : sctp_can_we_split_this(struct sctp_tcb *stcb,
    7465             :                        uint32_t length,
    7466             :                        uint32_t goal_mtu, uint32_t frag_point, int eeor_on)
    7467             : {
    7468             :         /* Make a decision on if I should split a
    7469             :          * msg into multiple parts. This is only asked of
    7470             :          * incomplete messages.
    7471             :          */
    7472           0 :         if (eeor_on) {
    7473             :                 /* If we are doing EEOR we need to always send
    7474             :                  * it if its the entire thing, since it might
    7475             :                  * be all the guy is putting in the hopper.
    7476             :                  */
    7477           0 :                 if (goal_mtu >= length) {
    7478             :                         /*-
    7479             :                          * If we have data outstanding,
    7480             :                          * we get another chance when the sack
    7481             :                          * arrives to transmit - wait for more data
    7482             :                          */
    7483           0 :                         if (stcb->asoc.total_flight == 0) {
    7484             :                                 /* If nothing is in flight, we zero
    7485             :                                  * the packet counter.
    7486             :                                  */
    7487           0 :                                 return (length);
    7488             :                         }
    7489           0 :                         return (0);
    7490             : 
    7491             :                 } else {
    7492             :                         /* You can fill the rest */
    7493           0 :                         return (goal_mtu);
    7494             :                 }
    7495             :         }
    7496             :         /*-
    7497             :          * For those strange folk that make the send buffer
    7498             :          * smaller than our fragmentation point, we can't
    7499             :          * get a full msg in so we have to allow splitting.
    7500             :          */
    7501           0 :         if (SCTP_SB_LIMIT_SND(stcb->sctp_socket) < frag_point) {
    7502           0 :                 return (length);
    7503             :         }
    7504             : 
    7505           0 :         if ((length <= goal_mtu) ||
    7506           0 :             ((length - goal_mtu) < SCTP_BASE_SYSCTL(sctp_min_residual))) {
    7507             :                 /* Sub-optimial residual don't split in non-eeor mode. */
    7508           0 :                 return (0);
    7509             :         }
    7510             :         /* If we reach here length is larger
    7511             :          * than the goal_mtu. Do we wish to split
    7512             :          * it for the sake of packet putting together?
    7513             :          */
    7514           0 :         if (goal_mtu >= min(SCTP_BASE_SYSCTL(sctp_min_split_point), frag_point)) {
    7515             :                 /* Its ok to split it */
    7516           0 :                 return (min(goal_mtu, frag_point));
    7517             :         }
    7518             :         /* Nope, can't split */
    7519           0 :         return (0);
    7520             : 
    7521             : }
    7522             : 
    7523             : static uint32_t
    7524           0 : sctp_move_to_outqueue(struct sctp_tcb *stcb,
    7525             :                       struct sctp_stream_out *strq,
    7526             :                       uint32_t goal_mtu,
    7527             :                       uint32_t frag_point,
    7528             :                       int *locked,
    7529             :                       int *giveup,
    7530             :                       int eeor_mode,
    7531             :                       int *bail,
    7532             :                       int so_locked
    7533             : #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
    7534             :                       SCTP_UNUSED
    7535             : #endif
    7536             :         )
    7537             : {
    7538             :         /* Move from the stream to the send_queue keeping track of the total */
    7539             :         struct sctp_association *asoc;
    7540             :         struct sctp_stream_queue_pending *sp;
    7541             :         struct sctp_tmit_chunk *chk;
    7542             :         struct sctp_data_chunk *dchkh;
    7543             :         uint32_t to_move, length;
    7544           0 :         uint8_t rcv_flags = 0;
    7545             :         uint8_t some_taken;
    7546           0 :         uint8_t send_lock_up = 0;
    7547             : 
    7548             :         SCTP_TCB_LOCK_ASSERT(stcb);
    7549           0 :         asoc = &stcb->asoc;
    7550             : one_more_time:
    7551             :         /*sa_ignore FREED_MEMORY*/
    7552           0 :         sp = TAILQ_FIRST(&strq->outqueue);
    7553           0 :         if (sp == NULL) {
    7554           0 :                 *locked = 0;
    7555           0 :                 if (send_lock_up == 0) {
    7556           0 :                         SCTP_TCB_SEND_LOCK(stcb);
    7557           0 :                         send_lock_up = 1;
    7558             :                 }
    7559           0 :                 sp = TAILQ_FIRST(&strq->outqueue);
    7560           0 :                 if (sp) {
    7561           0 :                         goto one_more_time;
    7562             :                 }
    7563           0 :                 if (strq->last_msg_incomplete) {
    7564           0 :                         SCTP_PRINTF("Huh? Stream:%d lm_in_c=%d but queue is NULL\n",
    7565             :                                     strq->stream_no,
    7566             :                                     strq->last_msg_incomplete);
    7567           0 :                         strq->last_msg_incomplete = 0;
    7568             :                 }
    7569           0 :                 to_move = 0;
    7570           0 :                 if (send_lock_up) {
    7571           0 :                         SCTP_TCB_SEND_UNLOCK(stcb);
    7572           0 :                         send_lock_up = 0;
    7573             :                 }
    7574           0 :                 goto out_of;
    7575             :         }
    7576           0 :         if ((sp->msg_is_complete) && (sp->length == 0)) {
    7577           0 :                 if (sp->sender_all_done) {
    7578             :                         /* We are doing differed cleanup. Last
    7579             :                          * time through when we took all the data
    7580             :                          * the sender_all_done was not set.
    7581             :                          */
    7582           0 :                         if ((sp->put_last_out == 0) && (sp->discard_rest == 0)) {
    7583           0 :                                 SCTP_PRINTF("Gak, put out entire msg with NO end!-1\n");
    7584           0 :                                 SCTP_PRINTF("sender_done:%d len:%d msg_comp:%d put_last_out:%d send_lock:%d\n",
    7585             :                                             sp->sender_all_done,
    7586             :                                             sp->length,
    7587             :                                             sp->msg_is_complete,
    7588             :                                             sp->put_last_out,
    7589             :                                             send_lock_up);
    7590             :                         }
    7591           0 :                         if ((TAILQ_NEXT(sp, next) == NULL) && (send_lock_up  == 0)) {
    7592           0 :                                 SCTP_TCB_SEND_LOCK(stcb);
    7593           0 :                                 send_lock_up = 1;
    7594             :                         }
    7595           0 :                         atomic_subtract_int(&asoc->stream_queue_cnt, 1);
    7596           0 :                         TAILQ_REMOVE(&strq->outqueue, sp, next);
    7597           0 :                         stcb->asoc.ss_functions.sctp_ss_remove_from_stream(stcb, asoc, strq, sp, send_lock_up);
    7598           0 :                         if (sp->net) {
    7599           0 :                                 sctp_free_remote_addr(sp->net);
    7600           0 :                                 sp->net = NULL;
    7601             :                         }
    7602           0 :                         if (sp->data) {
    7603           0 :                                 sctp_m_freem(sp->data);
    7604           0 :                                 sp->data = NULL;
    7605             :                         }
    7606           0 :                         sctp_free_a_strmoq(stcb, sp, so_locked);
    7607             :                         /* we can't be locked to it */
    7608           0 :                         *locked = 0;
    7609           0 :                         stcb->asoc.locked_on_sending = NULL;
    7610           0 :                         if (send_lock_up) {
    7611           0 :                                 SCTP_TCB_SEND_UNLOCK(stcb);
    7612           0 :                                 send_lock_up = 0;
    7613             :                         }
    7614             :                         /* back to get the next msg */
    7615           0 :                         goto one_more_time;
    7616             :                 } else {
    7617             :                         /* sender just finished this but
    7618             :                          * still holds a reference
    7619             :                          */
    7620           0 :                         *locked = 1;
    7621           0 :                         *giveup = 1;
    7622           0 :                         to_move = 0;
    7623           0 :                         goto out_of;
    7624             :                 }
    7625             :         } else {
    7626             :                 /* is there some to get */
    7627           0 :                 if (sp->length == 0) {
    7628             :                         /* no */
    7629           0 :                         *locked = 1;
    7630           0 :                         *giveup = 1;
    7631           0 :                         to_move = 0;
    7632           0 :                         goto out_of;
    7633           0 :                 } else if (sp->discard_rest) {
    7634           0 :                         if (send_lock_up == 0) {
    7635           0 :                                 SCTP_TCB_SEND_LOCK(stcb);
    7636           0 :                                 send_lock_up = 1;
    7637             :                         }
    7638             :                         /* Whack down the size */
    7639           0 :                         atomic_subtract_int(&stcb->asoc.total_output_queue_size, sp->length);
    7640           0 :                         if ((stcb->sctp_socket != NULL) &&        \
    7641           0 :                             ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
    7642           0 :                              (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL))) {
    7643           0 :                                 atomic_subtract_int(&stcb->sctp_socket->so_snd.sb_cc, sp->length);
    7644             :                         }
    7645           0 :                         if (sp->data) {
    7646           0 :                                 sctp_m_freem(sp->data);
    7647           0 :                                 sp->data = NULL;
    7648           0 :                                 sp->tail_mbuf = NULL;
    7649             :                         }
    7650           0 :                         sp->length = 0;
    7651           0 :                         sp->some_taken = 1;
    7652           0 :                         *locked = 1;
    7653           0 :                         *giveup = 1;
    7654           0 :                         to_move = 0;
    7655           0 :                         goto out_of;
    7656             :                 }
    7657             :         }
    7658           0 :         some_taken = sp->some_taken;
    7659           0 :         if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
    7660           0 :                 sp->msg_is_complete = 1;
    7661             :         }
    7662             : re_look:
    7663           0 :         length = sp->length;
    7664           0 :         if (sp->msg_is_complete) {
    7665             :                 /* The message is complete */
    7666           0 :                 to_move = min(length, frag_point);
    7667           0 :                 if (to_move == length) {
    7668             :                         /* All of it fits in the MTU */
    7669           0 :                         if (sp->some_taken) {
    7670           0 :                                 rcv_flags |= SCTP_DATA_LAST_FRAG;
    7671           0 :                                 sp->put_last_out = 1;
    7672             :                         } else {
    7673           0 :                                 rcv_flags |= SCTP_DATA_NOT_FRAG;
    7674           0 :                                 sp->put_last_out = 1;
    7675             :                         }
    7676             :                 } else {
    7677             :                         /* Not all of it fits, we fragment */
    7678           0 :                         if (sp->some_taken == 0) {
    7679           0 :                                 rcv_flags |= SCTP_DATA_FIRST_FRAG;
    7680             :                         }
    7681           0 :                         sp->some_taken = 1;
    7682             :                 }
    7683             :         } else {
    7684           0 :                 to_move = sctp_can_we_split_this(stcb, length, goal_mtu, frag_point, eeor_mode);
    7685           0 :                 if (to_move) {
    7686             :                         /*-
    7687             :                          * We use a snapshot of length in case it
    7688             :                          * is expanding during the compare.
    7689             :                          */
    7690             :                         uint32_t llen;
    7691             : 
    7692           0 :                         llen = length;
    7693           0 :                         if (to_move >= llen) {
    7694           0 :                                 to_move = llen;
    7695           0 :                                 if (send_lock_up == 0) {
    7696             :                                         /*-
    7697             :                                          * We are taking all of an incomplete msg
    7698             :                                          * thus we need a send lock.
    7699             :                                          */
    7700           0 :                                         SCTP_TCB_SEND_LOCK(stcb);
    7701           0 :                                         send_lock_up = 1;
    7702           0 :                                         if (sp->msg_is_complete) {
    7703             :                                                 /* the sender finished the msg */
    7704           0 :                                                 goto re_look;
    7705             :                                         }
    7706             :                                 }
    7707             :                         }
    7708           0 :                         if (sp->some_taken == 0) {
    7709           0 :                                 rcv_flags |= SCTP_DATA_FIRST_FRAG;
    7710           0 :                                 sp->some_taken = 1;
    7711             :                         }
    7712             :                 } else {
    7713             :                         /* Nothing to take. */
    7714           0 :                         if (sp->some_taken) {
    7715           0 :                                 *locked = 1;
    7716             :                         }
    7717           0 :                         *giveup = 1;
    7718           0 :                         to_move = 0;
    7719           0 :                         goto out_of;
    7720             :                 }
    7721             :         }
    7722             : 
    7723             :         /* If we reach here, we can copy out a chunk */
    7724           0 :         sctp_alloc_a_chunk(stcb, chk);
    7725           0 :         if (chk == NULL) {
    7726             :                 /* No chunk memory */
    7727           0 :                 *giveup = 1;
    7728           0 :                 to_move = 0;
    7729           0 :                 goto out_of;
    7730             :         }
    7731             :         /* Setup for unordered if needed by looking
    7732             :          * at the user sent info flags.
    7733             :          */
    7734           0 :         if (sp->sinfo_flags & SCTP_UNORDERED) {
    7735           0 :                 rcv_flags |= SCTP_DATA_UNORDERED;
    7736             :         }
    7737           0 :         if ((SCTP_BASE_SYSCTL(sctp_enable_sack_immediately) && ((sp->sinfo_flags & SCTP_EOF) == SCTP_EOF)) ||
    7738           0 :             ((sp->sinfo_flags & SCTP_SACK_IMMEDIATELY) == SCTP_SACK_IMMEDIATELY)) {
    7739           0 :                 rcv_flags |= SCTP_DATA_SACK_IMMEDIATELY;
    7740             :         }
    7741             :         /* clear out the chunk before setting up */
    7742           0 :         memset(chk, 0, sizeof(*chk));
    7743           0 :         chk->rec.data.rcv_flags = rcv_flags;
    7744             : 
    7745           0 :         if (to_move >= length) {
    7746             :                 /* we think we can steal the whole thing */
    7747           0 :                 if ((sp->sender_all_done == 0) && (send_lock_up == 0)) {
    7748           0 :                         SCTP_TCB_SEND_LOCK(stcb);
    7749           0 :                         send_lock_up = 1;
    7750             :                 }
    7751           0 :                 if (to_move < sp->length) {
    7752             :                         /* bail, it changed */
    7753           0 :                         goto dont_do_it;
    7754             :                 }
    7755           0 :                 chk->data = sp->data;
    7756           0 :                 chk->last_mbuf = sp->tail_mbuf;
    7757             :                 /* register the stealing */
    7758           0 :                 sp->data = sp->tail_mbuf = NULL;
    7759             :         } else {
    7760             :                 struct mbuf *m;
    7761             :         dont_do_it:
    7762           0 :                 chk->data = SCTP_M_COPYM(sp->data, 0, to_move, M_NOWAIT);
    7763           0 :                 chk->last_mbuf = NULL;
    7764           0 :                 if (chk->data == NULL) {
    7765           0 :                         sp->some_taken = some_taken;
    7766           0 :                         sctp_free_a_chunk(stcb, chk, so_locked);
    7767           0 :                         *bail = 1;
    7768           0 :                         to_move = 0;
    7769           0 :                         goto out_of;
    7770             :                 }
    7771             : #ifdef SCTP_MBUF_LOGGING
    7772             :                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
    7773             :                         sctp_log_mbc(chk->data, SCTP_MBUF_ICOPY);
    7774             :                 }
    7775             : #endif
    7776             :                 /* Pull off the data */
    7777           0 :                 m_adj(sp->data, to_move);
    7778             :                 /* Now lets work our way down and compact it */
    7779           0 :                 m = sp->data;
    7780           0 :                 while (m && (SCTP_BUF_LEN(m) == 0)) {
    7781           0 :                         sp->data  = SCTP_BUF_NEXT(m);
    7782           0 :                         SCTP_BUF_NEXT(m) = NULL;
    7783           0 :                         if (sp->tail_mbuf == m) {
    7784             :                                 /*-
    7785             :                                  * Freeing tail? TSNH since
    7786             :                                  * we supposedly were taking less
    7787             :                                  * than the sp->length.
    7788             :                                  */
    7789             : #ifdef INVARIANTS
    7790             :                                 panic("Huh, freing tail? - TSNH");
    7791             : #else
    7792           0 :                                 SCTP_PRINTF("Huh, freeing tail? - TSNH\n");
    7793           0 :                                 sp->tail_mbuf = sp->data = NULL;
    7794           0 :                                 sp->length = 0;
    7795             : #endif
    7796             : 
    7797             :                         }
    7798           0 :                         sctp_m_free(m);
    7799           0 :                         m = sp->data;
    7800             :                 }
    7801             :         }
    7802           0 :         if (SCTP_BUF_IS_EXTENDED(chk->data)) {
    7803           0 :                 chk->copy_by_ref = 1;
    7804             :         } else {
    7805           0 :                 chk->copy_by_ref = 0;
    7806             :         }
    7807             :         /* get last_mbuf and counts of mb useage
    7808             :          * This is ugly but hopefully its only one mbuf.
    7809             :          */
    7810           0 :         if (chk->last_mbuf == NULL) {
    7811           0 :                 chk->last_mbuf = chk->data;
    7812           0 :                 while (SCTP_BUF_NEXT(chk->last_mbuf) != NULL) {
    7813           0 :                         chk->last_mbuf = SCTP_BUF_NEXT(chk->last_mbuf);
    7814             :                 }
    7815             :         }
    7816             : 
    7817           0 :         if (to_move > length) {
    7818             :                 /*- This should not happen either
    7819             :                  * since we always lower to_move to the size
    7820             :                  * of sp->length if its larger.
    7821             :                  */
    7822             : #ifdef INVARIANTS
    7823             :                 panic("Huh, how can to_move be larger?");
    7824             : #else
    7825           0 :                 SCTP_PRINTF("Huh, how can to_move be larger?\n");
    7826           0 :                 sp->length = 0;
    7827             : #endif
    7828             :         } else {
    7829           0 :                 atomic_subtract_int(&sp->length, to_move);
    7830             :         }
    7831           0 :         if (M_LEADINGSPACE(chk->data) < (int)sizeof(struct sctp_data_chunk)) {
    7832             :                 /* Not enough room for a chunk header, get some */
    7833             :                 struct mbuf *m;
    7834             : 
    7835           0 :                 m = sctp_get_mbuf_for_msg(1, 0, M_NOWAIT, 0, MT_DATA);
    7836           0 :                 if (m == NULL) {
    7837             :                         /*
    7838             :                          * we're in trouble here. _PREPEND below will free
    7839             :                          * all the data if there is no leading space, so we
    7840             :                          * must put the data back and restore.
    7841             :                          */
    7842           0 :                         if (send_lock_up == 0) {
    7843           0 :                                 SCTP_TCB_SEND_LOCK(stcb);
    7844           0 :                                 send_lock_up = 1;
    7845             :                         }
    7846           0 :                         if (sp->data == NULL) {
    7847             :                                 /* unsteal the data */
    7848           0 :                                 sp->data = chk->data;
    7849           0 :                                 sp->tail_mbuf = chk->last_mbuf;
    7850             :                         } else {
    7851             :                                 struct mbuf *m_tmp;
    7852             :                                 /* reassemble the data */
    7853           0 :                                 m_tmp = sp->data;
    7854           0 :                                 sp->data = chk->data;
    7855           0 :                                 SCTP_BUF_NEXT(chk->last_mbuf) = m_tmp;
    7856             :                         }
    7857           0 :                         sp->some_taken = some_taken;
    7858           0 :                         atomic_add_int(&sp->length, to_move);
    7859           0 :                         chk->data = NULL;
    7860           0 :                         *bail = 1;
    7861           0 :                         sctp_free_a_chunk(stcb, chk, so_locked);
    7862           0 :                         to_move = 0;
    7863           0 :                         goto out_of;
    7864             :                 } else {
    7865           0 :                         SCTP_BUF_LEN(m) = 0;
    7866           0 :                         SCTP_BUF_NEXT(m) = chk->data;
    7867           0 :                         chk->data = m;
    7868           0 :                         M_ALIGN(chk->data, 4);
    7869             :                 }
    7870             :         }
    7871           0 :         SCTP_BUF_PREPEND(chk->data, sizeof(struct sctp_data_chunk), M_NOWAIT);
    7872           0 :         if (chk->data == NULL) {
    7873             :                 /* HELP, TSNH since we assured it would not above? */
    7874             : #ifdef INVARIANTS
    7875             :                 panic("prepend failes HELP?");
    7876             : #else
    7877           0 :                 SCTP_PRINTF("prepend fails HELP?\n");
    7878           0 :                 sctp_free_a_chunk(stcb, chk, so_locked);
    7879             : #endif
    7880           0 :                 *bail = 1;
    7881           0 :                 to_move = 0;
    7882           0 :                 goto out_of;
    7883             :         }
    7884           0 :         sctp_snd_sb_alloc(stcb, sizeof(struct sctp_data_chunk));
    7885           0 :         chk->book_size = chk->send_size = (to_move + sizeof(struct sctp_data_chunk));
    7886           0 :         chk->book_size_scale = 0;
    7887           0 :         chk->sent = SCTP_DATAGRAM_UNSENT;
    7888             : 
    7889           0 :         chk->flags = 0;
    7890           0 :         chk->asoc = &stcb->asoc;
    7891           0 :         chk->pad_inplace = 0;
    7892           0 :         chk->no_fr_allowed = 0;
    7893           0 :         chk->rec.data.stream_seq = strq->next_sequence_send;
    7894           0 :         if ((rcv_flags & SCTP_DATA_LAST_FRAG) &&
    7895           0 :             !(rcv_flags & SCTP_DATA_UNORDERED)) {
    7896           0 :                 strq->next_sequence_send++;
    7897             :         }
    7898           0 :         chk->rec.data.stream_number = sp->stream;
    7899           0 :         chk->rec.data.payloadtype = sp->ppid;
    7900           0 :         chk->rec.data.context = sp->context;
    7901           0 :         chk->rec.data.doing_fast_retransmit = 0;
    7902             : 
    7903           0 :         chk->rec.data.timetodrop = sp->ts;
    7904           0 :         chk->flags = sp->act_flags;
    7905             : 
    7906           0 :         if (sp->net) {
    7907           0 :                 chk->whoTo = sp->net;
    7908           0 :                 atomic_add_int(&chk->whoTo->ref_count, 1);
    7909             :         } else
    7910           0 :                 chk->whoTo = NULL;
    7911             : 
    7912           0 :         if (sp->holds_key_ref) {
    7913           0 :                 chk->auth_keyid = sp->auth_keyid;
    7914           0 :                 sctp_auth_key_acquire(stcb, chk->auth_keyid);
    7915           0 :                 chk->holds_key_ref = 1;
    7916             :         }
    7917             : #if defined(__FreeBSD__) || defined(__Panda__)
    7918             :         chk->rec.data.TSN_seq = atomic_fetchadd_int(&asoc->sending_seq, 1);
    7919             : #else
    7920           0 :         chk->rec.data.TSN_seq = asoc->sending_seq++;
    7921             : #endif
    7922           0 :         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOG_AT_SEND_2_OUTQ) {
    7923           0 :                 sctp_misc_ints(SCTP_STRMOUT_LOG_SEND,
    7924             :                                (uintptr_t)stcb, sp->length,
    7925           0 :                                (uint32_t)((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq),
    7926             :                                chk->rec.data.TSN_seq);
    7927             :         }
    7928           0 :         dchkh = mtod(chk->data, struct sctp_data_chunk *);
    7929             :         /*
    7930             :          * Put the rest of the things in place now. Size was done
    7931             :          * earlier in previous loop prior to padding.
    7932             :          */
    7933             : 
    7934             : #ifdef SCTP_ASOCLOG_OF_TSNS
    7935             :         SCTP_TCB_LOCK_ASSERT(stcb);
    7936             :         if (asoc->tsn_out_at >= SCTP_TSN_LOG_SIZE) {
    7937             :                 asoc->tsn_out_at = 0;
    7938             :                 asoc->tsn_out_wrapped = 1;
    7939             :         }
    7940             :         asoc->out_tsnlog[asoc->tsn_out_at].tsn = chk->rec.data.TSN_seq;
    7941             :         asoc->out_tsnlog[asoc->tsn_out_at].strm = chk->rec.data.stream_number;
    7942             :         asoc->out_tsnlog[asoc->tsn_out_at].seq = chk->rec.data.stream_seq;
    7943             :         asoc->out_tsnlog[asoc->tsn_out_at].sz = chk->send_size;
    7944             :         asoc->out_tsnlog[asoc->tsn_out_at].flgs = chk->rec.data.rcv_flags;
    7945             :         asoc->out_tsnlog[asoc->tsn_out_at].stcb = (void *)stcb;
    7946             :         asoc->out_tsnlog[asoc->tsn_out_at].in_pos = asoc->tsn_out_at;
    7947             :         asoc->out_tsnlog[asoc->tsn_out_at].in_out = 2;
    7948             :         asoc->tsn_out_at++;
    7949             : #endif
    7950             : 
    7951           0 :         dchkh->ch.chunk_type = SCTP_DATA;
    7952           0 :         dchkh->ch.chunk_flags = chk->rec.data.rcv_flags;
    7953           0 :         dchkh->dp.tsn = htonl(chk->rec.data.TSN_seq);
    7954           0 :         dchkh->dp.stream_id = htons(strq->stream_no);
    7955           0 :         dchkh->dp.stream_sequence = htons(chk->rec.data.stream_seq);
    7956           0 :         dchkh->dp.protocol_id = chk->rec.data.payloadtype;
    7957           0 :         dchkh->ch.chunk_length = htons(chk->send_size);
    7958             :         /* Now advance the chk->send_size by the actual pad needed. */
    7959           0 :         if (chk->send_size < SCTP_SIZE32(chk->book_size)) {
    7960             :                 /* need a pad */
    7961             :                 struct mbuf *lm;
    7962             :                 int pads;
    7963             : 
    7964           0 :                 pads = SCTP_SIZE32(chk->book_size) - chk->send_size;
    7965           0 :                 lm = sctp_pad_lastmbuf(chk->data, pads, chk->last_mbuf);
    7966           0 :                 if (lm != NULL) {
    7967           0 :                         chk->last_mbuf = lm;
    7968           0 :                         chk->pad_inplace = 1;
    7969             :                 }
    7970           0 :                 chk->send_size += pads;
    7971             :         }
    7972           0 :         if (PR_SCTP_ENABLED(chk->flags)) {
    7973           0 :                 asoc->pr_sctp_cnt++;
    7974             :         }
    7975           0 :         if (sp->msg_is_complete && (sp->length == 0) && (sp->sender_all_done)) {
    7976             :                 /* All done pull and kill the message */
    7977           0 :                 atomic_subtract_int(&asoc->stream_queue_cnt, 1);
    7978           0 :                 if (sp->put_last_out == 0) {
    7979           0 :                         SCTP_PRINTF("Gak, put out entire msg with NO end!-2\n");
    7980           0 :                         SCTP_PRINTF("sender_done:%d len:%d msg_comp:%d put_last_out:%d send_lock:%d\n",
    7981             :                                     sp->sender_all_done,
    7982             :                                     sp->length,
    7983             :                                     sp->msg_is_complete,
    7984             :                                     sp->put_last_out,
    7985             :                                     send_lock_up);
    7986             :                 }
    7987           0 :                 if ((send_lock_up == 0) && (TAILQ_NEXT(sp, next) == NULL)) {
    7988           0 :                         SCTP_TCB_SEND_LOCK(stcb);
    7989           0 :                         send_lock_up = 1;
    7990             :                 }
    7991           0 :                 TAILQ_REMOVE(&strq->outqueue, sp, next);
    7992           0 :                 stcb->asoc.ss_functions.sctp_ss_remove_from_stream(stcb, asoc, strq, sp, send_lock_up);
    7993           0 :                 if (sp->net) {
    7994           0 :                         sctp_free_remote_addr(sp->net);
    7995           0 :                         sp->net = NULL;
    7996             :                 }
    7997           0 :                 if (sp->data) {
    7998           0 :                         sctp_m_freem(sp->data);
    7999           0 :                         sp->data = NULL;
    8000             :                 }
    8001           0 :                 sctp_free_a_strmoq(stcb, sp, so_locked);
    8002             : 
    8003             :                 /* we can't be locked to it */
    8004           0 :                 *locked = 0;
    8005           0 :                 stcb->asoc.locked_on_sending = NULL;
    8006             :         } else {
    8007             :                 /* more to go, we are locked */
    8008           0 :                 *locked = 1;
    8009             :         }
    8010           0 :         asoc->chunks_on_out_queue++;
    8011           0 :         strq->chunks_on_queues++;
    8012           0 :         TAILQ_INSERT_TAIL(&asoc->send_queue, chk, sctp_next);
    8013           0 :         asoc->send_queue_cnt++;
    8014             : out_of:
    8015           0 :         if (send_lock_up) {
    8016           0 :                 SCTP_TCB_SEND_UNLOCK(stcb);
    8017             :         }
    8018           0 :         return (to_move);
    8019             : }
    8020             : 
    8021             : 
    8022             : static void
    8023           0 : sctp_fill_outqueue(struct sctp_tcb *stcb,
    8024             :     struct sctp_nets *net, int frag_point, int eeor_mode, int *quit_now, int so_locked
    8025             : #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
    8026             :         SCTP_UNUSED
    8027             : #endif
    8028             : )
    8029             : {
    8030             :         struct sctp_association *asoc;
    8031             :         struct sctp_stream_out *strq;
    8032           0 :         int goal_mtu, moved_how_much, total_moved = 0, bail = 0;
    8033             :         int locked, giveup;
    8034             : 
    8035             :         SCTP_TCB_LOCK_ASSERT(stcb);
    8036           0 :         asoc = &stcb->asoc;
    8037           0 :         switch (net->ro._l_addr.sa.sa_family) {
    8038             : #ifdef INET
    8039             :                 case AF_INET:
    8040             :                         goal_mtu = net->mtu - SCTP_MIN_V4_OVERHEAD;
    8041             :                         break;
    8042             : #endif
    8043             : #ifdef INET6
    8044             :                 case AF_INET6:
    8045             :                         goal_mtu = net->mtu - SCTP_MIN_OVERHEAD;
    8046             :                         break;
    8047             : #endif
    8048             : #if defined(__Userspace__)
    8049             :                 case AF_CONN:
    8050           0 :                         goal_mtu = net->mtu - sizeof(struct sctphdr);
    8051           0 :                         break;
    8052             : #endif
    8053             :                 default:
    8054             :                         /* TSNH */
    8055           0 :                         goal_mtu = net->mtu;
    8056           0 :                         break;
    8057             :         }
    8058             :         /* Need an allowance for the data chunk header too */
    8059           0 :         goal_mtu -= sizeof(struct sctp_data_chunk);
    8060             : 
    8061             :         /* must make even word boundary */
    8062           0 :         goal_mtu &= 0xfffffffc;
    8063           0 :         if (asoc->locked_on_sending) {
    8064             :                 /* We are stuck on one stream until the message completes. */
    8065           0 :                 strq = asoc->locked_on_sending;
    8066           0 :                 locked = 1;
    8067             :         } else {
    8068           0 :                 strq = stcb->asoc.ss_functions.sctp_ss_select_stream(stcb, net, asoc);
    8069           0 :                 locked = 0;
    8070             :         }
    8071           0 :         while ((goal_mtu > 0) && strq) {
    8072           0 :                 giveup = 0;
    8073           0 :                 bail = 0;
    8074           0 :                 moved_how_much = sctp_move_to_outqueue(stcb, strq, goal_mtu, frag_point, &locked,
    8075             :                                                        &giveup, eeor_mode, &bail, so_locked);
    8076           0 :                 if (moved_how_much)
    8077           0 :                         stcb->asoc.ss_functions.sctp_ss_scheduled(stcb, net, asoc, strq, moved_how_much);
    8078             : 
    8079           0 :                 if (locked) {
    8080           0 :                         asoc->locked_on_sending = strq;
    8081           0 :                         if ((moved_how_much == 0) || (giveup) || bail)
    8082             :                                 /* no more to move for now */
    8083             :                                 break;
    8084             :                 } else {
    8085           0 :                         asoc->locked_on_sending = NULL;
    8086           0 :                         if ((giveup) || bail) {
    8087             :                                 break;
    8088             :                         }
    8089           0 :                         strq = stcb->asoc.ss_functions.sctp_ss_select_stream(stcb, net, asoc);
    8090           0 :                         if (strq == NULL) {
    8091           0 :                                 break;
    8092             :                         }
    8093             :                 }
    8094           0 :                 total_moved += moved_how_much;
    8095           0 :                 goal_mtu -= (moved_how_much + sizeof(struct sctp_data_chunk));
    8096           0 :                 goal_mtu &= 0xfffffffc;
    8097             :         }
    8098           0 :         if (bail)
    8099           0 :                 *quit_now = 1;
    8100             : 
    8101           0 :         stcb->asoc.ss_functions.sctp_ss_packet_done(stcb, net, asoc);
    8102             : 
    8103           0 :         if (total_moved == 0) {
    8104           0 :                 if ((stcb->asoc.sctp_cmt_on_off == 0) &&
    8105           0 :                     (net == stcb->asoc.primary_destination)) {
    8106             :                         /* ran dry for primary network net */
    8107           0 :                         SCTP_STAT_INCR(sctps_primary_randry);
    8108           0 :                 } else if (stcb->asoc.sctp_cmt_on_off > 0) {
    8109             :                         /* ran dry with CMT on */
    8110           0 :                         SCTP_STAT_INCR(sctps_cmt_randry);
    8111             :                 }
    8112             :         }
    8113           0 : }
    8114             : 
    8115             : void
    8116           0 : sctp_fix_ecn_echo(struct sctp_association *asoc)
    8117             : {
    8118             :         struct sctp_tmit_chunk *chk;
    8119             : 
    8120           0 :         TAILQ_FOREACH(chk, &asoc->control_send_queue, sctp_next) {
    8121           0 :                 if (chk->rec.chunk_id.id == SCTP_ECN_ECHO) {
    8122           0 :                         chk->sent = SCTP_DATAGRAM_UNSENT;
    8123             :                 }
    8124             :         }
    8125           0 : }
    8126             : 
    8127             : void
    8128           0 : sctp_move_chunks_from_net(struct sctp_tcb *stcb, struct sctp_nets *net)
    8129             : {
    8130             :         struct sctp_association *asoc;
    8131             :         struct sctp_tmit_chunk *chk;
    8132             :         struct sctp_stream_queue_pending *sp;
    8133             :         unsigned int i;
    8134             : 
    8135           0 :         if (net == NULL) {
    8136           0 :                 return;
    8137             :         }
    8138           0 :         asoc = &stcb->asoc;
    8139           0 :         for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
    8140           0 :                 TAILQ_FOREACH(sp, &stcb->asoc.strmout[i].outqueue, next) {
    8141           0 :                         if (sp->net == net) {
    8142           0 :                                 sctp_free_remote_addr(sp->net);
    8143           0 :                                 sp->net = NULL;
    8144             :                         }
    8145             :                 }
    8146             :         }
    8147           0 :         TAILQ_FOREACH(chk, &asoc->send_queue, sctp_next) {
    8148           0 :                 if (chk->whoTo == net) {
    8149           0 :                         sctp_free_remote_addr(chk->whoTo);
    8150           0 :                         chk->whoTo = NULL;
    8151             :                 }
    8152             :         }
    8153             : }
    8154             : 
    8155             : int
    8156           0 : sctp_med_chunk_output(struct sctp_inpcb *inp,
    8157             :                       struct sctp_tcb *stcb,
    8158             :                       struct sctp_association *asoc,
    8159             :                       int *num_out,
    8160             :                       int *reason_code,
    8161             :                       int control_only, int from_where,
    8162             :                       struct timeval *now, int *now_filled, int frag_point, int so_locked
    8163             : #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
    8164             :                       SCTP_UNUSED
    8165             : #endif
    8166             :         )
    8167             : {
    8168             :         /**
    8169             :          * Ok this is the generic chunk service queue. we must do the
    8170             :          * following: - Service the stream queue that is next, moving any
    8171             :          * message (note I must get a complete message i.e. FIRST/MIDDLE and
    8172             :          * LAST to the out queue in one pass) and assigning TSN's - Check to
    8173             :          * see if the cwnd/rwnd allows any output, if so we go ahead and
    8174             :          * fomulate and send the low level chunks. Making sure to combine
    8175             :          * any control in the control chunk queue also.
    8176             :          */
    8177           0 :         struct sctp_nets *net, *start_at, *sack_goes_to = NULL, *old_start_at = NULL;
    8178             :         struct mbuf *outchain, *endoutchain;
    8179             :         struct sctp_tmit_chunk *chk, *nchk;
    8180             : 
    8181             :         /* temp arrays for unlinking */
    8182             :         struct sctp_tmit_chunk *data_list[SCTP_MAX_DATA_BUNDLING];
    8183             :         int no_fragmentflg, error;
    8184             :         unsigned int max_rwnd_per_dest, max_send_per_dest;
    8185             :         int one_chunk, hbflag, skip_data_for_this_net;
    8186             :         int asconf, cookie, no_out_cnt;
    8187             :         int bundle_at, ctl_cnt, no_data_chunks, eeor_mode;
    8188             :         unsigned int mtu, r_mtu, omtu, mx_mtu, to_out;
    8189           0 :         int tsns_sent = 0;
    8190           0 :         uint32_t auth_offset = 0;
    8191           0 :         struct sctp_auth_chunk *auth = NULL;
    8192             :         uint16_t auth_keyid;
    8193           0 :         int override_ok = 1;
    8194           0 :         int skip_fill_up = 0;
    8195           0 :         int data_auth_reqd = 0;
    8196             :         /* JRS 5/14/07 - Add flag for whether a heartbeat is sent to
    8197             :            the destination. */
    8198           0 :         int quit_now = 0;
    8199             : 
    8200             : #if defined(__APPLE__)
    8201             :         if (so_locked) {
    8202             :                 sctp_lock_assert(SCTP_INP_SO(inp));
    8203             :         } else {
    8204             :                 sctp_unlock_assert(SCTP_INP_SO(inp));
    8205             :         }
    8206             : #endif
    8207           0 :         *num_out = 0;
    8208           0 :         *reason_code = 0;
    8209           0 :         auth_keyid = stcb->asoc.authinfo.active_keyid;
    8210           0 :         if ((asoc->state & SCTP_STATE_SHUTDOWN_PENDING) ||
    8211           0 :             (asoc->state & SCTP_STATE_SHUTDOWN_RECEIVED) ||
    8212           0 :             (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXPLICIT_EOR))) {
    8213           0 :                 eeor_mode = 1;
    8214             :         } else {
    8215           0 :                 eeor_mode = 0;
    8216             :         }
    8217           0 :         ctl_cnt = no_out_cnt = asconf = cookie = 0;
    8218             :         /*
    8219             :          * First lets prime the pump. For each destination, if there is room
    8220             :          * in the flight size, attempt to pull an MTU's worth out of the
    8221             :          * stream queues into the general send_queue
    8222             :          */
    8223             : #ifdef SCTP_AUDITING_ENABLED
    8224             :         sctp_audit_log(0xC2, 2);
    8225             : #endif
    8226             :         SCTP_TCB_LOCK_ASSERT(stcb);
    8227           0 :         hbflag = 0;
    8228           0 :         if ((control_only) || (asoc->stream_reset_outstanding))
    8229           0 :                 no_data_chunks = 1;
    8230             :         else
    8231           0 :                 no_data_chunks = 0;
    8232             : 
    8233             :         /* Nothing to possible to send? */
    8234           0 :         if ((TAILQ_EMPTY(&asoc->control_send_queue) ||
    8235           0 :              (asoc->ctrl_queue_cnt == stcb->asoc.ecn_echo_cnt_onq)) &&
    8236           0 :             TAILQ_EMPTY(&asoc->asconf_send_queue) &&
    8237           0 :             TAILQ_EMPTY(&asoc->send_queue) &&
    8238           0 :             stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, asoc)) {
    8239             :         nothing_to_send:
    8240           0 :                 *reason_code = 9;
    8241           0 :                 return (0);
    8242             :         }
    8243           0 :         if (asoc->peers_rwnd == 0) {
    8244             :                 /* No room in peers rwnd */
    8245           0 :                 *reason_code = 1;
    8246           0 :                 if (asoc->total_flight > 0) {
    8247             :                         /* we are allowed one chunk in flight */
    8248           0 :                         no_data_chunks = 1;
    8249             :                 }
    8250             :         }
    8251           0 :         if (stcb->asoc.ecn_echo_cnt_onq) {
    8252             :                 /* Record where a sack goes, if any */
    8253           0 :                 if (no_data_chunks &&
    8254           0 :                     (asoc->ctrl_queue_cnt == stcb->asoc.ecn_echo_cnt_onq)) {
    8255             :                         /* Nothing but ECNe to send - we don't do that */
    8256           0 :                         goto nothing_to_send;
    8257             :                 }
    8258           0 :                 TAILQ_FOREACH(chk, &asoc->control_send_queue, sctp_next) {
    8259           0 :                         if ((chk->rec.chunk_id.id == SCTP_SELECTIVE_ACK) ||
    8260           0 :                             (chk->rec.chunk_id.id == SCTP_NR_SELECTIVE_ACK)) {
    8261           0 :                                 sack_goes_to = chk->whoTo;
    8262           0 :                                 break;
    8263             :                         }
    8264             :                 }
    8265             :         }
    8266           0 :         max_rwnd_per_dest = ((asoc->peers_rwnd + asoc->total_flight) / asoc->numnets);
    8267           0 :         if (stcb->sctp_socket)
    8268           0 :                 max_send_per_dest = SCTP_SB_LIMIT_SND(stcb->sctp_socket) / asoc->numnets;
    8269             :         else
    8270           0 :                 max_send_per_dest = 0;
    8271           0 :         if (no_data_chunks == 0) {
    8272             :                 /* How many non-directed chunks are there? */
    8273           0 :                 TAILQ_FOREACH(chk, &asoc->send_queue, sctp_next) {
    8274           0 :                         if (chk->whoTo == NULL) {
    8275             :                                 /* We already have non-directed
    8276             :                                  * chunks on the queue, no need
    8277             :                                  * to do a fill-up.
    8278             :                                  */
    8279           0 :                                 skip_fill_up = 1;
    8280           0 :                                 break;
    8281             :                         }
    8282             :                 }
    8283             : 
    8284             :         }
    8285           0 :         if ((no_data_chunks == 0) &&
    8286           0 :             (skip_fill_up == 0) &&
    8287           0 :             (!stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, asoc))) {
    8288           0 :                 TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
    8289             :                         /*
    8290             :                          * This for loop we are in takes in
    8291             :                          * each net, if its's got space in cwnd and
    8292             :                          * has data sent to it (when CMT is off) then it
    8293             :                          * calls sctp_fill_outqueue for the net. This gets
    8294             :                          * data on the send queue for that network.
    8295             :                          *
    8296             :                          * In sctp_fill_outqueue TSN's are assigned and
    8297             :                          * data is copied out of the stream buffers. Note
    8298             :                          * mostly copy by reference (we hope).
    8299             :                          */
    8300           0 :                         net->window_probe = 0;
    8301           0 :                         if ((net != stcb->asoc.alternate) &&
    8302           0 :                             ((net->dest_state & SCTP_ADDR_PF) ||
    8303           0 :                              (!(net->dest_state & SCTP_ADDR_REACHABLE)) ||
    8304           0 :                              (net->dest_state & SCTP_ADDR_UNCONFIRMED))) {
    8305           0 :                                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) {
    8306           0 :                                         sctp_log_cwnd(stcb, net, 1,
    8307             :                                                       SCTP_CWND_LOG_FILL_OUTQ_CALLED);
    8308             :                                 }
    8309           0 :                                 continue;
    8310             :                         }
    8311           0 :                         if ((stcb->asoc.cc_functions.sctp_cwnd_new_transmission_begins) &&
    8312           0 :                             (net->flight_size == 0)) {
    8313           0 :                                 (*stcb->asoc.cc_functions.sctp_cwnd_new_transmission_begins)(stcb, net);
    8314             :                         }
    8315           0 :                         if (net->flight_size >= net->cwnd) {
    8316             :                                 /* skip this network, no room - can't fill */
    8317           0 :                                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) {
    8318           0 :                                         sctp_log_cwnd(stcb, net, 3,
    8319             :                                                       SCTP_CWND_LOG_FILL_OUTQ_CALLED);
    8320             :                                 }
    8321           0 :                                 continue;
    8322             :                         }
    8323           0 :                         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) {
    8324           0 :                                 sctp_log_cwnd(stcb, net, 4, SCTP_CWND_LOG_FILL_OUTQ_CALLED);
    8325             :                         }
    8326           0 :                         sctp_fill_outqueue(stcb, net, frag_point, eeor_mode, &quit_now, so_locked);
    8327           0 :                         if (quit_now) {
    8328             :                                 /* memory alloc failure */
    8329           0 :                                 no_data_chunks = 1;
    8330           0 :                                 break;
    8331             :                         }
    8332             :                 }
    8333             :         }
    8334             :         /* now service each destination and send out what we can for it */
    8335             :         /* Nothing to send? */
    8336           0 :         if (TAILQ_EMPTY(&asoc->control_send_queue) &&
    8337           0 :             TAILQ_EMPTY(&asoc->asconf_send_queue) &&
    8338           0 :             TAILQ_EMPTY(&asoc->send_queue)) {
    8339           0 :                 *reason_code = 8;
    8340           0 :                 return (0);
    8341             :         }
    8342             : 
    8343           0 :         if (asoc->sctp_cmt_on_off > 0) {
    8344             :                 /* get the last start point */
    8345           0 :                 start_at = asoc->last_net_cmt_send_started;
    8346           0 :                 if (start_at == NULL) {
    8347             :                         /* null so to beginning */
    8348           0 :                         start_at = TAILQ_FIRST(&asoc->nets);
    8349             :                 } else {
    8350           0 :                         start_at = TAILQ_NEXT(asoc->last_net_cmt_send_started, sctp_next);
    8351           0 :                         if (start_at == NULL) {
    8352           0 :                                 start_at = TAILQ_FIRST(&asoc->nets);
    8353             :                         }
    8354             :                 }
    8355           0 :                 asoc->last_net_cmt_send_started = start_at;
    8356             :         } else {
    8357           0 :                 start_at = TAILQ_FIRST(&asoc->nets);
    8358             :         }
    8359           0 :         TAILQ_FOREACH(chk, &asoc->control_send_queue, sctp_next) {
    8360           0 :                 if (chk->whoTo == NULL) {
    8361           0 :                         if (asoc->alternate) {
    8362           0 :                                 chk->whoTo = asoc->alternate;
    8363             :                         } else {
    8364           0 :                                 chk->whoTo = asoc->primary_destination;
    8365             :                         }
    8366           0 :                         atomic_add_int(&chk->whoTo->ref_count, 1);
    8367             :                 }
    8368             :         }
    8369           0 :         old_start_at = NULL;
    8370             : again_one_more_time:
    8371           0 :         for (net = start_at ; net != NULL; net = TAILQ_NEXT(net, sctp_next)) {
    8372             :                 /* how much can we send? */
    8373             :                 /* SCTPDBG("Examine for sending net:%x\n", (uint32_t)net); */
    8374           0 :                 if (old_start_at && (old_start_at == net)) {
    8375             :                         /* through list ocmpletely. */
    8376           0 :                         break;
    8377             :                 }
    8378           0 :                 tsns_sent = 0xa;
    8379           0 :                 if (TAILQ_EMPTY(&asoc->control_send_queue) &&
    8380           0 :                     TAILQ_EMPTY(&asoc->asconf_send_queue) &&
    8381           0 :                     (net->flight_size >= net->cwnd)) {
    8382             :                         /* Nothing on control or asconf and flight is full, we can skip
    8383             :                          * even in the CMT case.
    8384             :                          */
    8385           0 :                         continue;
    8386             :                 }
    8387           0 :                 bundle_at = 0;
    8388           0 :                 endoutchain = outchain = NULL;
    8389           0 :                 no_fragmentflg = 1;
    8390           0 :                 one_chunk = 0;
    8391           0 :                 if (net->dest_state & SCTP_ADDR_UNCONFIRMED) {
    8392           0 :                         skip_data_for_this_net = 1;
    8393             :                 } else {
    8394           0 :                         skip_data_for_this_net = 0;
    8395             :                 }
    8396           0 :                 switch (((struct sockaddr *)&net->ro._l_addr)->sa_family) {
    8397             : #ifdef INET
    8398             :                 case AF_INET:
    8399             :                         mtu = net->mtu - (sizeof(struct ip) + sizeof(struct sctphdr));
    8400             :                         break;
    8401             : #endif
    8402             : #ifdef INET6
    8403             :                 case AF_INET6:
    8404             :                         mtu = net->mtu - (sizeof(struct ip6_hdr) + sizeof(struct sctphdr));
    8405             :                         break;
    8406             : #endif
    8407             : #if defined(__Userspace__)
    8408             :                 case AF_CONN:
    8409           0 :                         mtu = net->mtu - sizeof(struct sctphdr);
    8410           0 :                         break;
    8411             : #endif
    8412             :                 default:
    8413             :                         /* TSNH */
    8414           0 :                         mtu = net->mtu;
    8415           0 :                         break;
    8416             :                 }
    8417           0 :                 mx_mtu = mtu;
    8418           0 :                 to_out = 0;
    8419           0 :                 if (mtu > asoc->peers_rwnd) {
    8420           0 :                         if (asoc->total_flight > 0) {
    8421             :                                 /* We have a packet in flight somewhere */
    8422           0 :                                 r_mtu = asoc->peers_rwnd;
    8423             :                         } else {
    8424             :                                 /* We are always allowed to send one MTU out */
    8425           0 :                                 one_chunk = 1;
    8426           0 :                                 r_mtu = mtu;
    8427             :                         }
    8428             :                 } else {
    8429           0 :                         r_mtu = mtu;
    8430             :                 }
    8431             :                 /************************/
    8432             :                 /* ASCONF transmission */
    8433             :                 /************************/
    8434             :                 /* Now first lets go through the asconf queue */
    8435           0 :                 TAILQ_FOREACH_SAFE(chk, &asoc->asconf_send_queue, sctp_next, nchk) {
    8436           0 :                         if (chk->rec.chunk_id.id != SCTP_ASCONF) {
    8437           0 :                                 continue;
    8438             :                         }
    8439           0 :                         if (chk->whoTo == NULL) {
    8440           0 :                                 if (asoc->alternate == NULL) {
    8441           0 :                                         if (asoc->primary_destination != net) {
    8442           0 :                                                 break;
    8443             :                                         }
    8444             :                                 } else {
    8445           0 :                                         if (asoc->alternate != net) {
    8446           0 :                                                 break;
    8447             :                                         }
    8448             :                                 }
    8449             :                         } else {
    8450           0 :                                 if (chk->whoTo != net) {
    8451           0 :                                         break;
    8452             :                                 }
    8453             :                         }
    8454           0 :                         if (chk->data == NULL) {
    8455           0 :                                 break;
    8456             :                         }
    8457           0 :                         if (chk->sent != SCTP_DATAGRAM_UNSENT &&
    8458           0 :                             chk->sent != SCTP_DATAGRAM_RESEND) {
    8459           0 :                                 break;
    8460             :                         }
    8461             :                         /*
    8462             :                          * if no AUTH is yet included and this chunk
    8463             :                          * requires it, make sure to account for it.  We
    8464             :                          * don't apply the size until the AUTH chunk is
    8465             :                          * actually added below in case there is no room for
    8466             :                          * this chunk. NOTE: we overload the use of "omtu"
    8467             :                          * here
    8468             :                          */
    8469           0 :                         if ((auth == NULL) &&
    8470           0 :                             sctp_auth_is_required_chunk(chk->rec.chunk_id.id,
    8471             :                                                         stcb->asoc.peer_auth_chunks)) {
    8472           0 :                                 omtu = sctp_get_auth_chunk_len(stcb->asoc.peer_hmac_id);
    8473             :                         } else
    8474           0 :                                 omtu = 0;
    8475             :                         /* Here we do NOT factor the r_mtu */
    8476           0 :                         if ((chk->send_size < (int)(mtu - omtu)) ||
    8477           0 :                             (chk->flags & CHUNK_FLAGS_FRAGMENT_OK)) {
    8478             :                                 /*
    8479             :                                  * We probably should glom the mbuf chain
    8480             :                                  * from the chk->data for control but the
    8481             :                                  * problem is it becomes yet one more level
    8482             :                                  * of tracking to do if for some reason
    8483             :                                  * output fails. Then I have got to
    8484             :                                  * reconstruct the merged control chain.. el
    8485             :                                  * yucko.. for now we take the easy way and
    8486             :                                  * do the copy
    8487             :                                  */
    8488             :                                 /*
    8489             :                                  * Add an AUTH chunk, if chunk requires it
    8490             :                                  * save the offset into the chain for AUTH
    8491             :                                  */
    8492           0 :                                 if ((auth == NULL) &&
    8493           0 :                                     (sctp_auth_is_required_chunk(chk->rec.chunk_id.id,
    8494             :                                                                  stcb->asoc.peer_auth_chunks))) {
    8495           0 :                                         outchain = sctp_add_auth_chunk(outchain,
    8496             :                                                                        &endoutchain,
    8497             :                                                                        &auth,
    8498             :                                                                        &auth_offset,
    8499             :                                                                        stcb,
    8500           0 :                                                                        chk->rec.chunk_id.id);
    8501           0 :                                         SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks);
    8502             :                                 }
    8503           0 :                                 outchain = sctp_copy_mbufchain(chk->data, outchain, &endoutchain,
    8504           0 :                                                                (int)chk->rec.chunk_id.can_take_data,
    8505           0 :                                                                chk->send_size, chk->copy_by_ref);
    8506           0 :                                 if (outchain == NULL) {
    8507           0 :                                         *reason_code = 8;
    8508             :                                         SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
    8509           0 :                                         return (ENOMEM);
    8510             :                                 }
    8511           0 :                                 SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks);
    8512             :                                 /* update our MTU size */
    8513           0 :                                 if (mtu > (chk->send_size + omtu))
    8514           0 :                                         mtu -= (chk->send_size + omtu);
    8515             :                                 else
    8516           0 :                                         mtu = 0;
    8517           0 :                                 to_out += (chk->send_size + omtu);
    8518             :                                 /* Do clear IP_DF ? */
    8519           0 :                                 if (chk->flags & CHUNK_FLAGS_FRAGMENT_OK) {
    8520           0 :                                         no_fragmentflg = 0;
    8521             :                                 }
    8522           0 :                                 if (chk->rec.chunk_id.can_take_data)
    8523           0 :                                         chk->data = NULL;
    8524             :                                 /*
    8525             :                                  * set hb flag since we can
    8526             :                                  * use these for RTO
    8527             :                                  */
    8528           0 :                                 hbflag = 1;
    8529           0 :                                 asconf = 1;
    8530             :                                 /*
    8531             :                                  * should sysctl this: don't
    8532             :                                  * bundle data with ASCONF
    8533             :                                  * since it requires AUTH
    8534             :                                  */
    8535           0 :                                 no_data_chunks = 1;
    8536           0 :                                 chk->sent = SCTP_DATAGRAM_SENT;
    8537           0 :                                 if (chk->whoTo == NULL) {
    8538           0 :                                         chk->whoTo = net;
    8539           0 :                                         atomic_add_int(&net->ref_count, 1);
    8540             :                                 }
    8541           0 :                                 chk->snd_count++;
    8542           0 :                                 if (mtu == 0) {
    8543             :                                         /*
    8544             :                                          * Ok we are out of room but we can
    8545             :                                          * output without effecting the
    8546             :                                          * flight size since this little guy
    8547             :                                          * is a control only packet.
    8548             :                                          */
    8549           0 :                                         sctp_timer_start(SCTP_TIMER_TYPE_ASCONF, inp, stcb, net);
    8550             :                                         /*
    8551             :                                          * do NOT clear the asconf
    8552             :                                          * flag as it is used to do
    8553             :                                          * appropriate source address
    8554             :                                          * selection.
    8555             :                                          */
    8556           0 :                                         if ((error = sctp_lowlevel_chunk_output(inp, stcb, net,
    8557           0 :                                                                                 (struct sockaddr *)&net->ro._l_addr,
    8558             :                                                                                 outchain, auth_offset, auth,
    8559           0 :                                                                                 stcb->asoc.authinfo.active_keyid,
    8560             :                                                                                 no_fragmentflg, 0, asconf,
    8561           0 :                                                                                 inp->sctp_lport, stcb->rport,
    8562             :                                                                                 htonl(stcb->asoc.peer_vtag),
    8563           0 :                                                                                 net->port, NULL,
    8564             : #if defined(__FreeBSD__)
    8565             :                                                                                 0, 0,
    8566             : #endif
    8567             :                                                                                 so_locked))) {
    8568           0 :                                                 if (error == ENOBUFS) {
    8569           0 :                                                         asoc->ifp_had_enobuf = 1;
    8570           0 :                                                         SCTP_STAT_INCR(sctps_lowlevelerr);
    8571             :                                                 }
    8572           0 :                                                 if (from_where == 0) {
    8573           0 :                                                         SCTP_STAT_INCR(sctps_lowlevelerrusr);
    8574             :                                                 }
    8575           0 :                                                 if (*now_filled == 0) {
    8576           0 :                                                         (void)SCTP_GETTIME_TIMEVAL(&net->last_sent_time);
    8577           0 :                                                         *now_filled = 1;
    8578           0 :                                                         *now = net->last_sent_time;
    8579             :                                                 } else {
    8580           0 :                                                         net->last_sent_time = *now;
    8581             :                                                 }
    8582           0 :                                                 hbflag = 0;
    8583             :                                                 /* error, could not output */
    8584           0 :                                                 if (error == EHOSTUNREACH) {
    8585             :                                                         /*
    8586             :                                                          * Destination went
    8587             :                                                          * unreachable
    8588             :                                                          * during this send
    8589             :                                                          */
    8590           0 :                                                         sctp_move_chunks_from_net(stcb, net);
    8591             :                                                 }
    8592           0 :                                                 *reason_code = 7;
    8593           0 :                                                 continue;
    8594             :                                         } else
    8595           0 :                                                 asoc->ifp_had_enobuf = 0;
    8596           0 :                                         if (*now_filled == 0) {
    8597           0 :                                                 (void)SCTP_GETTIME_TIMEVAL(&net->last_sent_time);
    8598           0 :                                                 *now_filled = 1;
    8599           0 :                                                 *now = net->last_sent_time;
    8600             :                                         } else {
    8601           0 :                                                 net->last_sent_time = *now;
    8602             :                                         }
    8603           0 :                                         hbflag = 0;
    8604             :                                         /*
    8605             :                                          * increase the number we sent, if a
    8606             :                                          * cookie is sent we don't tell them
    8607             :                                          * any was sent out.
    8608             :                                          */
    8609           0 :                                         outchain = endoutchain = NULL;
    8610           0 :                                         auth = NULL;
    8611           0 :                                         auth_offset = 0;
    8612           0 :                                         if (!no_out_cnt)
    8613           0 :                                                 *num_out += ctl_cnt;
    8614             :                                         /* recalc a clean slate and setup */
    8615           0 :                                         switch (net->ro._l_addr.sa.sa_family) {
    8616             : #ifdef INET
    8617             :                                                 case AF_INET:
    8618             :                                                         mtu = net->mtu - SCTP_MIN_V4_OVERHEAD;
    8619             :                                                         break;
    8620             : #endif
    8621             : #ifdef INET6
    8622             :                                                 case AF_INET6:
    8623             :                                                         mtu = net->mtu - SCTP_MIN_OVERHEAD;
    8624             :                                                         break;
    8625             : #endif
    8626             : #if defined(__Userspace__)
    8627             :                                                 case AF_CONN:
    8628           0 :                                                         mtu = net->mtu - sizeof(struct sctphdr);
    8629           0 :                                                         break;
    8630             : #endif
    8631             :                                                 default:
    8632             :                                                         /* TSNH */
    8633           0 :                                                         mtu = net->mtu;
    8634           0 :                                                         break;
    8635             :                                         }
    8636           0 :                                         to_out = 0;
    8637           0 :                                         no_fragmentflg = 1;
    8638             :                                 }
    8639             :                         }
    8640             :                 }
    8641             :                 /************************/
    8642             :                 /* Control transmission */
    8643             :                 /************************/
    8644             :                 /* Now first lets go through the control queue */
    8645           0 :                 TAILQ_FOREACH_SAFE(chk, &asoc->control_send_queue, sctp_next, nchk) {
    8646           0 :                         if ((sack_goes_to) &&
    8647           0 :                             (chk->rec.chunk_id.id == SCTP_ECN_ECHO) &&
    8648           0 :                             (chk->whoTo != sack_goes_to)) {
    8649             :                                 /*
    8650             :                                  * if we have a sack in queue, and we are looking at an
    8651             :                                  * ecn echo that is NOT queued to where the sack is going..
    8652             :                                  */
    8653           0 :                                 if (chk->whoTo == net) {
    8654             :                                         /* Don't transmit it to where its going (current net) */
    8655           0 :                                         continue;
    8656           0 :                                 } else if (sack_goes_to == net) {
    8657             :                                         /* But do transmit it to this address */
    8658           0 :                                         goto skip_net_check;
    8659             :                                 }
    8660             :                         }
    8661           0 :                         if (chk->whoTo == NULL) {
    8662           0 :                                 if (asoc->alternate == NULL) {
    8663           0 :                                         if (asoc->primary_destination != net) {
    8664           0 :                                                 continue;
    8665             :                                         }
    8666             :                                 } else {
    8667           0 :                                         if (asoc->alternate != net) {
    8668           0 :                                                 continue;
    8669             :                                         }
    8670             :                                 }
    8671             :                         } else {
    8672           0 :                                 if (chk->whoTo != net) {
    8673           0 :                                         continue;
    8674             :                                 }
    8675             :                         }
    8676             :                 skip_net_check:
    8677           0 :                         if (chk->data == NULL) {
    8678           0 :                                 continue;
    8679             :                         }
    8680           0 :                         if (chk->sent != SCTP_DATAGRAM_UNSENT) {
    8681             :                                 /*
    8682             :                                  * It must be unsent. Cookies and ASCONF's
    8683             :                                  * hang around but there timers will force
    8684             :                                  * when marked for resend.
    8685             :                                  */
    8686           0 :                                 continue;
    8687             :                         }
    8688             :                         /*
    8689             :                          * if no AUTH is yet included and this chunk
    8690             :                          * requires it, make sure to account for it.  We
    8691             :                          * don't apply the size until the AUTH chunk is
    8692             :                          * actually added below in case there is no room for
    8693             :                          * this chunk. NOTE: we overload the use of "omtu"
    8694             :                          * here
    8695             :                          */
    8696           0 :                         if ((auth == NULL) &&
    8697           0 :                             sctp_auth_is_required_chunk(chk->rec.chunk_id.id,
    8698             :                                                         stcb->asoc.peer_auth_chunks)) {
    8699           0 :                                 omtu = sctp_get_auth_chunk_len(stcb->asoc.peer_hmac_id);
    8700             :                         } else
    8701           0 :                                 omtu = 0;
    8702             :                         /* Here we do NOT factor the r_mtu */
    8703           0 :                         if ((chk->send_size <= (int)(mtu - omtu)) ||
    8704           0 :                             (chk->flags & CHUNK_FLAGS_FRAGMENT_OK)) {
    8705             :                                 /*
    8706             :                                  * We probably should glom the mbuf chain
    8707             :                                  * from the chk->data for control but the
    8708             :                                  * problem is it becomes yet one more level
    8709             :                                  * of tracking to do if for some reason
    8710             :                                  * output fails. Then I have got to
    8711             :                                  * reconstruct the merged control chain.. el
    8712             :                                  * yucko.. for now we take the easy way and
    8713             :                                  * do the copy
    8714             :                                  */
    8715             :                                 /*
    8716             :                                  * Add an AUTH chunk, if chunk requires it
    8717             :                                  * save the offset into the chain for AUTH
    8718             :                                  */
    8719           0 :                                 if ((auth == NULL) &&
    8720           0 :                                     (sctp_auth_is_required_chunk(chk->rec.chunk_id.id,
    8721             :                                                                  stcb->asoc.peer_auth_chunks))) {
    8722           0 :                                         outchain = sctp_add_auth_chunk(outchain,
    8723             :                                                                        &endoutchain,
    8724             :                                                                        &auth,
    8725             :                                                                        &auth_offset,
    8726             :                                                                        stcb,
    8727           0 :                                                                        chk->rec.chunk_id.id);
    8728           0 :                                         SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks);
    8729             :                                 }
    8730           0 :                                 outchain = sctp_copy_mbufchain(chk->data, outchain, &endoutchain,
    8731           0 :                                                                (int)chk->rec.chunk_id.can_take_data,
    8732           0 :                                                                chk->send_size, chk->copy_by_ref);
    8733           0 :                                 if (outchain == NULL) {
    8734           0 :                                         *reason_code = 8;
    8735             :                                         SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
    8736           0 :                                         return (ENOMEM);
    8737             :                                 }
    8738           0 :                                 SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks);
    8739             :                                 /* update our MTU size */
    8740           0 :                                 if (mtu > (chk->send_size + omtu))
    8741           0 :                                         mtu -= (chk->send_size + omtu);
    8742             :                                 else
    8743           0 :                                         mtu = 0;
    8744           0 :                                 to_out += (chk->send_size + omtu);
    8745             :                                 /* Do clear IP_DF ? */
    8746           0 :                                 if (chk->flags & CHUNK_FLAGS_FRAGMENT_OK) {
    8747           0 :                                         no_fragmentflg = 0;
    8748             :                                 }
    8749           0 :                                 if (chk->rec.chunk_id.can_take_data)
    8750           0 :                                         chk->data = NULL;
    8751             :                                 /* Mark things to be removed, if needed */
    8752           0 :                                 if ((chk->rec.chunk_id.id == SCTP_SELECTIVE_ACK) ||
    8753           0 :                                     (chk->rec.chunk_id.id == SCTP_NR_SELECTIVE_ACK) || /* EY */
    8754           0 :                                     (chk->rec.chunk_id.id == SCTP_HEARTBEAT_REQUEST) ||
    8755           0 :                                     (chk->rec.chunk_id.id == SCTP_HEARTBEAT_ACK) ||
    8756           0 :                                     (chk->rec.chunk_id.id == SCTP_SHUTDOWN) ||
    8757           0 :                                     (chk->rec.chunk_id.id == SCTP_SHUTDOWN_ACK) ||
    8758           0 :                                     (chk->rec.chunk_id.id == SCTP_OPERATION_ERROR) ||
    8759           0 :                                     (chk->rec.chunk_id.id == SCTP_COOKIE_ACK) ||
    8760           0 :                                     (chk->rec.chunk_id.id == SCTP_ECN_CWR) ||
    8761           0 :                                     (chk->rec.chunk_id.id == SCTP_PACKET_DROPPED) ||
    8762           0 :                                     (chk->rec.chunk_id.id == SCTP_ASCONF_ACK)) {
    8763           0 :                                         if (chk->rec.chunk_id.id == SCTP_HEARTBEAT_REQUEST) {
    8764           0 :                                                 hbflag = 1;
    8765             :                                         }
    8766             :                                         /* remove these chunks at the end */
    8767           0 :                                         if ((chk->rec.chunk_id.id == SCTP_SELECTIVE_ACK) ||
    8768           0 :                                             (chk->rec.chunk_id.id == SCTP_NR_SELECTIVE_ACK)) {
    8769             :                                                 /* turn off the timer */
    8770           0 :                                                 if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
    8771           0 :                                                         sctp_timer_stop(SCTP_TIMER_TYPE_RECV,
    8772             :                                                                         inp, stcb, net, SCTP_FROM_SCTP_OUTPUT+SCTP_LOC_1);
    8773             :                                                 }
    8774             :                                         }
    8775           0 :                                         ctl_cnt++;
    8776             :                                 } else {
    8777             :                                         /*
    8778             :                                          * Other chunks, since they have
    8779             :                                          * timers running (i.e. COOKIE)
    8780             :                                          * we just "trust" that it
    8781             :                                          * gets sent or retransmitted.
    8782             :                                          */
    8783           0 :                                         ctl_cnt++;
    8784           0 :                                         if (chk->rec.chunk_id.id == SCTP_COOKIE_ECHO) {
    8785           0 :                                                 cookie = 1;
    8786           0 :                                                 no_out_cnt = 1;
    8787           0 :                                         } else if (chk->rec.chunk_id.id == SCTP_ECN_ECHO) {
    8788             :                                                 /*
    8789             :                                                  * Increment ecne send count here
    8790             :                                                  * this means we may be over-zealous in
    8791             :                                                  * our counting if the send fails, but its
    8792             :                                                  * the best place to do it (we used to do
    8793             :                                                  * it in the queue of the chunk, but that did
    8794             :                                                  * not tell how many times it was sent.
    8795             :                                                  */
    8796           0 :                                                 SCTP_STAT_INCR(sctps_sendecne);
    8797             :                                         }
    8798           0 :                                         chk->sent = SCTP_DATAGRAM_SENT;
    8799           0 :                                         if (chk->whoTo == NULL) {
    8800           0 :                                                 chk->whoTo = net;
    8801           0 :                                                 atomic_add_int(&net->ref_count, 1);
    8802             :                                         }
    8803           0 :                                         chk->snd_count++;
    8804             :                                 }
    8805           0 :                                 if (mtu == 0) {
    8806             :                                         /*
    8807             :                                          * Ok we are out of room but we can
    8808             :                                          * output without effecting the
    8809             :                                          * flight size since this little guy
    8810             :                                          * is a control only packet.
    8811             :                                          */
    8812           0 :                                         if (asconf) {
    8813           0 :                                                 sctp_timer_start(SCTP_TIMER_TYPE_ASCONF, inp, stcb, net);
    8814             :                                                 /*
    8815             :                                                  * do NOT clear the asconf
    8816             :                                                  * flag as it is used to do
    8817             :                                                  * appropriate source address
    8818             :                                                  * selection.
    8819             :                                                  */
    8820             :                                         }
    8821           0 :                                         if (cookie) {
    8822           0 :                                                 sctp_timer_start(SCTP_TIMER_TYPE_COOKIE, inp, stcb, net);
    8823           0 :                                                 cookie = 0;
    8824             :                                         }
    8825           0 :                                         if ((error = sctp_lowlevel_chunk_output(inp, stcb, net,
    8826           0 :                                                                                 (struct sockaddr *)&net->ro._l_addr,
    8827             :                                                                                 outchain,
    8828             :                                                                                 auth_offset, auth,
    8829           0 :                                                                                 stcb->asoc.authinfo.active_keyid,
    8830             :                                                                                 no_fragmentflg, 0, asconf,
    8831           0 :                                                                                 inp->sctp_lport, stcb->rport,
    8832             :                                                                                 htonl(stcb->asoc.peer_vtag),
    8833           0 :                                                                                 net->port, NULL,
    8834             : #if defined(__FreeBSD__)
    8835             :                                                                                 0, 0,
    8836             : #endif
    8837             :                                                                                 so_locked))) {
    8838           0 :                                                 if (error == ENOBUFS) {
    8839           0 :                                                         asoc->ifp_had_enobuf = 1;
    8840           0 :                                                         SCTP_STAT_INCR(sctps_lowlevelerr);
    8841             :                                                 }
    8842           0 :                                                 if (from_where == 0) {
    8843           0 :                                                         SCTP_STAT_INCR(sctps_lowlevelerrusr);
    8844             :                                                 }
    8845             :                                                 /* error, could not output */
    8846           0 :                                                 if (hbflag) {
    8847           0 :                                                         if (*now_filled == 0) {
    8848           0 :                                                                 (void)SCTP_GETTIME_TIMEVAL(&net->last_sent_time);
    8849           0 :                                                                 *now_filled = 1;
    8850           0 :                                                                 *now = net->last_sent_time;
    8851             :                                                         } else {
    8852           0 :                                                                 net->last_sent_time = *now;
    8853             :                                                         }
    8854           0 :                                                         hbflag = 0;
    8855             :                                                 }
    8856           0 :                                                 if (error == EHOSTUNREACH) {
    8857             :                                                         /*
    8858             :                                                          * Destination went
    8859             :                                                          * unreachable
    8860             :                                                          * during this send
    8861             :                                                          */
    8862           0 :                                                         sctp_move_chunks_from_net(stcb, net);
    8863             :                                                 }
    8864           0 :                                                 *reason_code = 7;
    8865           0 :                                                 continue;
    8866             :                                         } else
    8867           0 :                                                 asoc->ifp_had_enobuf = 0;
    8868             :                                         /* Only HB or ASCONF advances time */
    8869           0 :                                         if (hbflag) {
    8870           0 :                                                 if (*now_filled == 0) {
    8871           0 :                                                         (void)SCTP_GETTIME_TIMEVAL(&net->last_sent_time);
    8872           0 :                                                         *now_filled = 1;
    8873           0 :                                                         *now = net->last_sent_time;
    8874             :                                                 } else {
    8875           0 :                                                         net->last_sent_time = *now;
    8876             :                                                 }
    8877           0 :                                                 hbflag = 0;
    8878             :                                         }
    8879             :                                         /*
    8880             :                                          * increase the number we sent, if a
    8881             :                                          * cookie is sent we don't tell them
    8882             :                                          * any was sent out.
    8883             :                                          */
    8884           0 :                                         outchain = endoutchain = NULL;
    8885           0 :                                         auth = NULL;
    8886           0 :                                         auth_offset = 0;
    8887           0 :                                         if (!no_out_cnt)
    8888           0 :                                                 *num_out += ctl_cnt;
    8889             :                                         /* recalc a clean slate and setup */
    8890           0 :                                         switch (net->ro._l_addr.sa.sa_family) {
    8891             : #ifdef INET
    8892             :                                                 case AF_INET:
    8893             :                                                         mtu = net->mtu - SCTP_MIN_V4_OVERHEAD;
    8894             :                                                         break;
    8895             : #endif
    8896             : #ifdef INET6
    8897             :                                                 case AF_INET6:
    8898             :                                                         mtu = net->mtu - SCTP_MIN_OVERHEAD;
    8899             :                                                         break;
    8900             : #endif
    8901             : #if defined(__Userspace__)
    8902             :                                                 case AF_CONN:
    8903           0 :                                                         mtu = net->mtu - sizeof(struct sctphdr);
    8904           0 :                                                         break;
    8905             : #endif
    8906             :                                                 default:
    8907             :                                                         /* TSNH */
    8908           0 :                                                         mtu = net->mtu;
    8909           0 :                                                         break;
    8910             :                                         }
    8911           0 :                                         to_out = 0;
    8912           0 :                                         no_fragmentflg = 1;
    8913             :                                 }
    8914             :                         }
    8915             :                 }
    8916             :                 /* JRI: if dest is in PF state, do not send data to it */
    8917           0 :                 if ((asoc->sctp_cmt_on_off > 0) &&
    8918           0 :                     (net != stcb->asoc.alternate) &&
    8919           0 :                     (net->dest_state & SCTP_ADDR_PF)) {
    8920           0 :                         goto no_data_fill;
    8921             :                 }
    8922           0 :                 if (net->flight_size >= net->cwnd) {
    8923           0 :                         goto no_data_fill;
    8924             :                 }
    8925           0 :                 if ((asoc->sctp_cmt_on_off > 0) &&
    8926           0 :                     (SCTP_BASE_SYSCTL(sctp_buffer_splitting) & SCTP_RECV_BUFFER_SPLITTING) &&
    8927           0 :                     (net->flight_size > max_rwnd_per_dest)) {
    8928           0 :                         goto no_data_fill;
    8929             :                 }
    8930             :                 /*
    8931             :                  * We need a specific accounting for the usage of the
    8932             :                  * send buffer. We also need to check the number of messages
    8933             :                  * per net. For now, this is better than nothing and it
    8934             :                  * disabled by default...
    8935             :                  */
    8936           0 :                 if ((asoc->sctp_cmt_on_off > 0) &&
    8937           0 :                     (SCTP_BASE_SYSCTL(sctp_buffer_splitting) & SCTP_SEND_BUFFER_SPLITTING) &&
    8938           0 :                     (max_send_per_dest > 0) &&
    8939           0 :                     (net->flight_size > max_send_per_dest)) {
    8940           0 :                         goto no_data_fill;
    8941             :                 }
    8942             :                 /*********************/
    8943             :                 /* Data transmission */
    8944             :                 /*********************/
    8945             :                 /*
    8946             :                  * if AUTH for DATA is required and no AUTH has been added
    8947             :                  * yet, account for this in the mtu now... if no data can be
    8948             :                  * bundled, this adjustment won't matter anyways since the
    8949             :                  * packet will be going out...
    8950             :                  */
    8951           0 :                 data_auth_reqd = sctp_auth_is_required_chunk(SCTP_DATA,
    8952             :                                                              stcb->asoc.peer_auth_chunks);
    8953           0 :                 if (data_auth_reqd && (auth == NULL)) {
    8954           0 :                         mtu -= sctp_get_auth_chunk_len(stcb->asoc.peer_hmac_id);
    8955             :                 }
    8956             :                 /* now lets add any data within the MTU constraints */
    8957           0 :                 switch (((struct sockaddr *)&net->ro._l_addr)->sa_family) {
    8958             : #ifdef INET
    8959             :                 case AF_INET:
    8960             :                         if (net->mtu > (sizeof(struct ip) + sizeof(struct sctphdr)))
    8961             :                                 omtu = net->mtu - (sizeof(struct ip) + sizeof(struct sctphdr));
    8962             :                         else
    8963             :                                 omtu = 0;
    8964             :                         break;
    8965             : #endif
    8966             : #ifdef INET6
    8967             :                 case AF_INET6:
    8968             :                         if (net->mtu > (sizeof(struct ip6_hdr) + sizeof(struct sctphdr)))
    8969             :                                 omtu = net->mtu - (sizeof(struct ip6_hdr) + sizeof(struct sctphdr));
    8970             :                         else
    8971             :                                 omtu = 0;
    8972             :                         break;
    8973             : #endif
    8974             : #if defined(__Userspace__)
    8975             :                 case AF_CONN:
    8976           0 :                         if (net->mtu > sizeof(struct sctphdr)) {
    8977           0 :                                 omtu = net->mtu - sizeof(struct sctphdr);
    8978             :                         } else {
    8979           0 :                                 omtu = 0;
    8980             :                         }
    8981           0 :                         break;
    8982             : #endif
    8983             :                 default:
    8984             :                         /* TSNH */
    8985           0 :                         omtu = 0;
    8986           0 :                         break;
    8987             :                 }
    8988           0 :                 if ((((asoc->state & SCTP_STATE_OPEN) == SCTP_STATE_OPEN) &&
    8989           0 :                      (skip_data_for_this_net == 0)) ||
    8990             :                     (cookie)) {
    8991           0 :                         TAILQ_FOREACH_SAFE(chk, &asoc->send_queue, sctp_next, nchk) {
    8992           0 :                                 if (no_data_chunks) {
    8993             :                                         /* let only control go out */
    8994           0 :                                         *reason_code = 1;
    8995           0 :                                         break;
    8996             :                                 }
    8997           0 :                                 if (net->flight_size >= net->cwnd) {
    8998             :                                         /* skip this net, no room for data */
    8999           0 :                                         *reason_code = 2;
    9000           0 :                                         break;
    9001             :                                 }
    9002           0 :                                 if ((chk->whoTo != NULL) &&
    9003           0 :                                     (chk->whoTo != net)) {
    9004             :                                         /* Don't send the chunk on this net */
    9005           0 :                                         continue;
    9006             :                                 }
    9007             : 
    9008           0 :                                 if (asoc->sctp_cmt_on_off == 0) {
    9009           0 :                                         if ((asoc->alternate) &&
    9010           0 :                                             (asoc->alternate != net) &&
    9011           0 :                                             (chk->whoTo == NULL)) {
    9012           0 :                                                 continue;
    9013           0 :                                         } else if ((net != asoc->primary_destination) &&
    9014           0 :                                                    (asoc->alternate == NULL) &&
    9015           0 :                                                    (chk->whoTo == NULL)) {
    9016           0 :                                                 continue;
    9017             :                                         }
    9018             :                                 }
    9019           0 :                                 if ((chk->send_size > omtu) && ((chk->flags & CHUNK_FLAGS_FRAGMENT_OK) == 0)) {
    9020             :                                         /*-
    9021             :                                          * strange, we have a chunk that is
    9022             :                                          * to big for its destination and
    9023             :                                          * yet no fragment ok flag.
    9024             :                                          * Something went wrong when the
    9025             :                                          * PMTU changed...we did not mark
    9026             :                                          * this chunk for some reason?? I
    9027             :                                          * will fix it here by letting IP
    9028             :                                          * fragment it for now and printing
    9029             :                                          * a warning. This really should not
    9030             :                                          * happen ...
    9031             :                                          */
    9032           0 :                                         SCTP_PRINTF("Warning chunk of %d bytes > mtu:%d and yet PMTU disc missed\n",
    9033             :                                                     chk->send_size, mtu);
    9034           0 :                                         chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
    9035             :                                 }
    9036           0 :                                 if (SCTP_BASE_SYSCTL(sctp_enable_sack_immediately) &&
    9037           0 :                                     ((asoc->state & SCTP_STATE_SHUTDOWN_PENDING) == SCTP_STATE_SHUTDOWN_PENDING)) {
    9038             :                                         struct sctp_data_chunk *dchkh;
    9039             : 
    9040           0 :                                         dchkh = mtod(chk->data, struct sctp_data_chunk *);
    9041           0 :                                         dchkh->ch.chunk_flags |= SCTP_DATA_SACK_IMMEDIATELY;
    9042             :                                 }
    9043           0 :                                 if (((chk->send_size <= mtu) && (chk->send_size <= r_mtu)) ||
    9044           0 :                                     ((chk->flags & CHUNK_FLAGS_FRAGMENT_OK) && (chk->send_size <= asoc->peers_rwnd))) {
    9045             :                                         /* ok we will add this one */
    9046             : 
    9047             :                                         /*
    9048             :                                          * Add an AUTH chunk, if chunk
    9049             :                                          * requires it, save the offset into
    9050             :                                          * the chain for AUTH
    9051             :                                          */
    9052           0 :                                         if (data_auth_reqd) {
    9053           0 :                                                 if (auth == NULL) {
    9054           0 :                                                         outchain = sctp_add_auth_chunk(outchain,
    9055             :                                                                                        &endoutchain,
    9056             :                                                                                        &auth,
    9057             :                                                                                        &auth_offset,
    9058             :                                                                                        stcb,
    9059             :                                                                                        SCTP_DATA);
    9060           0 :                                                         auth_keyid = chk->auth_keyid;
    9061           0 :                                                         override_ok = 0;
    9062           0 :                                                         SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks);
    9063           0 :                                                 } else if (override_ok) {
    9064             :                                                         /* use this data's keyid */
    9065           0 :                                                         auth_keyid = chk->auth_keyid;
    9066           0 :                                                         override_ok = 0;
    9067           0 :                                                 } else if (auth_keyid != chk->auth_keyid) {
    9068             :                                                         /* different keyid, so done bundling */
    9069           0 :                                                         break;
    9070             :                                                 }
    9071             :                                         }
    9072           0 :                                         outchain = sctp_copy_mbufchain(chk->data, outchain, &endoutchain, 0,
    9073           0 :                                                                        chk->send_size, chk->copy_by_ref);
    9074           0 :                                         if (outchain == NULL) {
    9075           0 :                                                 SCTPDBG(SCTP_DEBUG_OUTPUT3, "No memory?\n");
    9076           0 :                                                 if (!SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
    9077           0 :                                                         sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb, net);
    9078             :                                                 }
    9079           0 :                                                 *reason_code = 3;
    9080             :                                                 SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
    9081           0 :                                                 return (ENOMEM);
    9082             :                                         }
    9083             :                                         /* upate our MTU size */
    9084             :                                         /* Do clear IP_DF ? */
    9085           0 :                                         if (chk->flags & CHUNK_FLAGS_FRAGMENT_OK) {
    9086           0 :                                                 no_fragmentflg = 0;
    9087             :                                         }
    9088             :                                         /* unsigned subtraction of mtu */
    9089           0 :                                         if (mtu > chk->send_size)
    9090           0 :                                                 mtu -= chk->send_size;
    9091             :                                         else
    9092           0 :                                                 mtu = 0;
    9093             :                                         /* unsigned subtraction of r_mtu */
    9094           0 :                                         if (r_mtu > chk->send_size)
    9095           0 :                                                 r_mtu -= chk->send_size;
    9096             :                                         else
    9097           0 :                                                 r_mtu = 0;
    9098             : 
    9099           0 :                                         to_out += chk->send_size;
    9100           0 :                                         if ((to_out > mx_mtu) && no_fragmentflg) {
    9101             : #ifdef INVARIANTS
    9102             :                                                 panic("Exceeding mtu of %d out size is %d", mx_mtu, to_out);
    9103             : #else
    9104           0 :                                                 SCTP_PRINTF("Exceeding mtu of %d out size is %d\n",
    9105             :                                                             mx_mtu, to_out);
    9106             : #endif
    9107             :                                         }
    9108           0 :                                         chk->window_probe = 0;
    9109           0 :                                         data_list[bundle_at++] = chk;
    9110           0 :                                         if (bundle_at >= SCTP_MAX_DATA_BUNDLING) {
    9111           0 :                                                 break;
    9112             :                                         }
    9113           0 :                                         if (chk->sent == SCTP_DATAGRAM_UNSENT) {
    9114           0 :                                                 if ((chk->rec.data.rcv_flags & SCTP_DATA_UNORDERED) == 0) {
    9115           0 :                                                         SCTP_STAT_INCR_COUNTER64(sctps_outorderchunks);
    9116             :                                                 } else {
    9117           0 :                                                         SCTP_STAT_INCR_COUNTER64(sctps_outunorderchunks);
    9118             :                                                 }
    9119           0 :                                                 if (((chk->rec.data.rcv_flags & SCTP_DATA_LAST_FRAG) == SCTP_DATA_LAST_FRAG) &&
    9120           0 :                                                     ((chk->rec.data.rcv_flags & SCTP_DATA_FIRST_FRAG) == 0))
    9121             :                                                         /* Count number of user msg's that were fragmented
    9122             :                                                          * we do this by counting when we see a LAST fragment
    9123             :                                                          * only.
    9124             :                                                          */
    9125           0 :                                                         SCTP_STAT_INCR_COUNTER64(sctps_fragusrmsgs);
    9126             :                                         }
    9127           0 :                                         if ((mtu == 0) || (r_mtu == 0) || (one_chunk)) {
    9128           0 :                                                 if ((one_chunk) && (stcb->asoc.total_flight == 0)) {
    9129           0 :                                                         data_list[0]->window_probe = 1;
    9130           0 :                                                         net->window_probe = 1;
    9131             :                                                 }
    9132           0 :                                                 break;
    9133             :                                         }
    9134             :                                 } else {
    9135             :                                         /*
    9136             :                                          * Must be sent in order of the
    9137             :                                          * TSN's (on a network)
    9138             :                                          */
    9139             :                                         break;
    9140             :                                 }
    9141             :                         }       /* for (chunk gather loop for this net) */
    9142             :                 }               /* if asoc.state OPEN */
    9143             :         no_data_fill:
    9144             :                 /* Is there something to send for this destination? */
    9145           0 :                 if (outchain) {
    9146             :                         /* We may need to start a control timer or two */
    9147           0 :                         if (asconf) {
    9148           0 :                                 sctp_timer_start(SCTP_TIMER_TYPE_ASCONF, inp,
    9149             :                                                  stcb, net);
    9150             :                                 /*
    9151             :                                  * do NOT clear the asconf flag as it is used
    9152             :                                  * to do appropriate source address selection.
    9153             :                                  */
    9154             :                         }
    9155           0 :                         if (cookie) {
    9156           0 :                                 sctp_timer_start(SCTP_TIMER_TYPE_COOKIE, inp, stcb, net);
    9157           0 :                                 cookie = 0;
    9158             :                         }
    9159             :                         /* must start a send timer if data is being sent */
    9160           0 :                         if (bundle_at && (!SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer))) {
    9161             :                                 /*
    9162             :                                  * no timer running on this destination
    9163             :                                  * restart it.
    9164             :                                  */
    9165           0 :                                 sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb, net);
    9166             :                         }
    9167             :                         /* Now send it, if there is anything to send :> */
    9168           0 :                         if ((error = sctp_lowlevel_chunk_output(inp,
    9169             :                                                                 stcb,
    9170             :                                                                 net,
    9171           0 :                                                                 (struct sockaddr *)&net->ro._l_addr,
    9172             :                                                                 outchain,
    9173             :                                                                 auth_offset,
    9174             :                                                                 auth,
    9175             :                                                                 auth_keyid,
    9176             :                                                                 no_fragmentflg,
    9177             :                                                                 bundle_at,
    9178             :                                                                 asconf,
    9179           0 :                                                                 inp->sctp_lport, stcb->rport,
    9180             :                                                                 htonl(stcb->asoc.peer_vtag),
    9181           0 :                                                                 net->port, NULL,
    9182             : #if defined(__FreeBSD__)
    9183             :                                                                 0, 0,
    9184             : #endif
    9185             :                                                                 so_locked))) {
    9186             :                                 /* error, we could not output */
    9187           0 :                                 if (error == ENOBUFS) {
    9188           0 :                                         SCTP_STAT_INCR(sctps_lowlevelerr);
    9189           0 :                                         asoc->ifp_had_enobuf = 1;
    9190             :                                 }
    9191           0 :                                 if (from_where == 0) {
    9192           0 :                                         SCTP_STAT_INCR(sctps_lowlevelerrusr);
    9193             :                                 }
    9194           0 :                                 SCTPDBG(SCTP_DEBUG_OUTPUT3, "Gak send error %d\n", error);
    9195           0 :                                 if (hbflag) {
    9196           0 :                                         if (*now_filled == 0) {
    9197           0 :                                                 (void)SCTP_GETTIME_TIMEVAL(&net->last_sent_time);
    9198           0 :                                                 *now_filled = 1;
    9199           0 :                                                 *now = net->last_sent_time;
    9200             :                                         } else {
    9201           0 :                                                 net->last_sent_time = *now;
    9202             :                                         }
    9203           0 :                                         hbflag = 0;
    9204             :                                 }
    9205           0 :                                 if (error == EHOSTUNREACH) {
    9206             :                                         /*
    9207             :                                          * Destination went unreachable
    9208             :                                          * during this send
    9209             :                                          */
    9210           0 :                                         sctp_move_chunks_from_net(stcb, net);
    9211             :                                 }
    9212           0 :                                 *reason_code = 6;
    9213             :                                 /*-
    9214             :                                  * I add this line to be paranoid. As far as
    9215             :                                  * I can tell the continue, takes us back to
    9216             :                                  * the top of the for, but just to make sure
    9217             :                                  * I will reset these again here.
    9218             :                                  */
    9219           0 :                                 ctl_cnt = bundle_at = 0;
    9220           0 :                                 continue; /* This takes us back to the for() for the nets. */
    9221             :                         } else {
    9222           0 :                                 asoc->ifp_had_enobuf = 0;
    9223             :                         }
    9224           0 :                         endoutchain = NULL;
    9225           0 :                         auth = NULL;
    9226           0 :                         auth_offset = 0;
    9227           0 :                         if (bundle_at || hbflag) {
    9228             :                                 /* For data/asconf and hb set time */
    9229           0 :                                 if (*now_filled == 0) {
    9230           0 :                                         (void)SCTP_GETTIME_TIMEVAL(&net->last_sent_time);
    9231           0 :                                         *now_filled = 1;
    9232           0 :                                         *now = net->last_sent_time;
    9233             :                                 } else {
    9234           0 :                                         net->last_sent_time = *now;
    9235             :                                 }
    9236             :                         }
    9237           0 :                         if (!no_out_cnt) {
    9238           0 :                                 *num_out += (ctl_cnt + bundle_at);
    9239             :                         }
    9240           0 :                         if (bundle_at) {
    9241             :                                 /* setup for a RTO measurement */
    9242           0 :                                 tsns_sent = data_list[0]->rec.data.TSN_seq;
    9243             :                                 /* fill time if not already filled */
    9244           0 :                                 if (*now_filled == 0) {
    9245           0 :                                         (void)SCTP_GETTIME_TIMEVAL(&asoc->time_last_sent);
    9246           0 :                                         *now_filled = 1;
    9247           0 :                                         *now = asoc->time_last_sent;
    9248             :                                 } else {
    9249           0 :                                         asoc->time_last_sent = *now;
    9250             :                                 }
    9251           0 :                                 if (net->rto_needed) {
    9252           0 :                                         data_list[0]->do_rtt = 1;
    9253           0 :                                         net->rto_needed = 0;
    9254             :                                 }
    9255           0 :                                 SCTP_STAT_INCR_BY(sctps_senddata, bundle_at);
    9256           0 :                                 sctp_clean_up_datalist(stcb, asoc, data_list, bundle_at, net);
    9257             :                         }
    9258           0 :                         if (one_chunk) {
    9259           0 :                                 break;
    9260             :                         }
    9261             :                 }
    9262           0 :                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) {
    9263           0 :                         sctp_log_cwnd(stcb, net, tsns_sent, SCTP_CWND_LOG_FROM_SEND);
    9264             :                 }
    9265             :         }
    9266           0 :         if (old_start_at == NULL) {
    9267           0 :                 old_start_at = start_at;
    9268           0 :                 start_at = TAILQ_FIRST(&asoc->nets);
    9269           0 :                 if (old_start_at)
    9270           0 :                         goto again_one_more_time;
    9271             :         }
    9272             : 
    9273             :         /*
    9274             :          * At the end there should be no NON timed chunks hanging on this
    9275             :          * queue.
    9276             :          */
    9277           0 :         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) {
    9278           0 :                 sctp_log_cwnd(stcb, net, *num_out, SCTP_CWND_LOG_FROM_SEND);
    9279             :         }
    9280           0 :         if ((*num_out == 0) && (*reason_code == 0)) {
    9281           0 :                 *reason_code = 4;
    9282             :         } else {
    9283           0 :                 *reason_code = 5;
    9284             :         }
    9285           0 :         sctp_clean_up_ctl(stcb, asoc, so_locked);
    9286           0 :         return (0);
    9287             : }
    9288             : 
    9289             : void
    9290           0 : sctp_queue_op_err(struct sctp_tcb *stcb, struct mbuf *op_err)
    9291             : {
    9292             :         /*-
    9293             :          * Prepend a OPERATIONAL_ERROR chunk header and put on the end of
    9294             :          * the control chunk queue.
    9295             :          */
    9296             :         struct sctp_chunkhdr *hdr;
    9297             :         struct sctp_tmit_chunk *chk;
    9298             :         struct mbuf *mat;
    9299             : 
    9300             :         SCTP_TCB_LOCK_ASSERT(stcb);
    9301           0 :         sctp_alloc_a_chunk(stcb, chk);
    9302           0 :         if (chk == NULL) {
    9303             :                 /* no memory */
    9304           0 :                 sctp_m_freem(op_err);
    9305           0 :                 return;
    9306             :         }
    9307           0 :         chk->copy_by_ref = 0;
    9308           0 :         SCTP_BUF_PREPEND(op_err, sizeof(struct sctp_chunkhdr), M_NOWAIT);
    9309           0 :         if (op_err == NULL) {
    9310           0 :                 sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
    9311           0 :                 return;
    9312             :         }
    9313           0 :         chk->send_size = 0;
    9314           0 :         for (mat = op_err; mat != NULL; mat = SCTP_BUF_NEXT(mat)) {
    9315           0 :                 chk->send_size += SCTP_BUF_LEN(mat);
    9316             :         }
    9317           0 :         chk->sent = SCTP_DATAGRAM_UNSENT;
    9318           0 :         chk->snd_count = 0;
    9319           0 :         chk->asoc = &stcb->asoc;
    9320           0 :         chk->data = op_err;
    9321           0 :         chk->whoTo = NULL;
    9322           0 :         hdr = mtod(op_err, struct sctp_chunkhdr *);
    9323           0 :         hdr->chunk_type = SCTP_OPERATION_ERROR;
    9324           0 :         hdr->chunk_flags = 0;
    9325           0 :         hdr->chunk_length = htons(chk->send_size);
    9326           0 :         TAILQ_INSERT_TAIL(&chk->asoc->control_send_queue,
    9327             :             chk,
    9328             :             sctp_next);
    9329           0 :         chk->asoc->ctrl_queue_cnt++;
    9330             : }
    9331             : 
    9332             : int
    9333           0 : sctp_send_cookie_echo(struct mbuf *m,
    9334             :     int offset,
    9335             :     struct sctp_tcb *stcb,
    9336             :     struct sctp_nets *net)
    9337             : {
    9338             :         /*-
    9339             :          * pull out the cookie and put it at the front of the control chunk
    9340             :          * queue.
    9341             :          */
    9342             :         int at;
    9343             :         struct mbuf *cookie;
    9344             :         struct sctp_paramhdr parm, *phdr;
    9345             :         struct sctp_chunkhdr *hdr;
    9346             :         struct sctp_tmit_chunk *chk;
    9347             :         uint16_t ptype, plen;
    9348             : 
    9349             :         SCTP_TCB_LOCK_ASSERT(stcb);
    9350             :         /* First find the cookie in the param area */
    9351           0 :         cookie = NULL;
    9352           0 :         at = offset + sizeof(struct sctp_init_chunk);
    9353             :         for (;;) {
    9354           0 :                 phdr = sctp_get_next_param(m, at, &parm, sizeof(parm));
    9355           0 :                 if (phdr == NULL) {
    9356           0 :                         return (-3);
    9357             :                 }
    9358           0 :                 ptype = ntohs(phdr->param_type);
    9359           0 :                 plen = ntohs(phdr->param_length);
    9360           0 :                 if (ptype == SCTP_STATE_COOKIE) {
    9361             :                         int pad;
    9362             : 
    9363             :                         /* found the cookie */
    9364           0 :                         if ((pad = (plen % 4))) {
    9365           0 :                                 plen += 4 - pad;
    9366             :                         }
    9367           0 :                         cookie = SCTP_M_COPYM(m, at, plen, M_NOWAIT);
    9368           0 :                         if (cookie == NULL) {
    9369             :                                 /* No memory */
    9370           0 :                                 return (-2);
    9371             :                         }
    9372             : #ifdef SCTP_MBUF_LOGGING
    9373             :                         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
    9374             :                                 sctp_log_mbc(cookie, SCTP_MBUF_ICOPY);
    9375             :                         }
    9376             : #endif
    9377           0 :                         break;
    9378             :                 }
    9379           0 :                 at += SCTP_SIZE32(plen);
    9380             :         }
    9381             :         /* ok, we got the cookie lets change it into a cookie echo chunk */
    9382             :         /* first the change from param to cookie */
    9383           0 :         hdr = mtod(cookie, struct sctp_chunkhdr *);
    9384           0 :         hdr->chunk_type = SCTP_COOKIE_ECHO;
    9385           0 :         hdr->chunk_flags = 0;
    9386             :         /* get the chunk stuff now and place it in the FRONT of the queue */
    9387           0 :         sctp_alloc_a_chunk(stcb, chk);
    9388           0 :         if (chk == NULL) {
    9389             :                 /* no memory */
    9390           0 :                 sctp_m_freem(cookie);
    9391           0 :                 return (-5);
    9392             :         }
    9393           0 :         chk->copy_by_ref = 0;
    9394           0 :         chk->rec.chunk_id.id = SCTP_COOKIE_ECHO;
    9395           0 :         chk->rec.chunk_id.can_take_data = 0;
    9396           0 :         chk->flags = CHUNK_FLAGS_FRAGMENT_OK;
    9397           0 :         chk->send_size = plen;
    9398           0 :         chk->sent = SCTP_DATAGRAM_UNSENT;
    9399           0 :         chk->snd_count = 0;
    9400           0 :         chk->asoc = &stcb->asoc;
    9401           0 :         chk->data = cookie;
    9402           0 :         chk->whoTo = net;
    9403           0 :         atomic_add_int(&chk->whoTo->ref_count, 1);
    9404           0 :         TAILQ_INSERT_HEAD(&chk->asoc->control_send_queue, chk, sctp_next);
    9405           0 :         chk->asoc->ctrl_queue_cnt++;
    9406           0 :         return (0);
    9407             : }
    9408             : 
    9409             : void
    9410           0 : sctp_send_heartbeat_ack(struct sctp_tcb *stcb,
    9411             :     struct mbuf *m,
    9412             :     int offset,
    9413             :     int chk_length,
    9414             :     struct sctp_nets *net)
    9415             : {
    9416             :         /*
    9417             :          * take a HB request and make it into a HB ack and send it.
    9418             :          */
    9419             :         struct mbuf *outchain;
    9420             :         struct sctp_chunkhdr *chdr;
    9421             :         struct sctp_tmit_chunk *chk;
    9422             : 
    9423             : 
    9424           0 :         if (net == NULL)
    9425             :                 /* must have a net pointer */
    9426           0 :                 return;
    9427             : 
    9428           0 :         outchain = SCTP_M_COPYM(m, offset, chk_length, M_NOWAIT);
    9429           0 :         if (outchain == NULL) {
    9430             :                 /* gak out of memory */
    9431           0 :                 return;
    9432             :         }
    9433             : #ifdef SCTP_MBUF_LOGGING
    9434             :         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
    9435             :                 sctp_log_mbc(outchain, SCTP_MBUF_ICOPY);
    9436             :         }
    9437             : #endif
    9438           0 :         chdr = mtod(outchain, struct sctp_chunkhdr *);
    9439           0 :         chdr->chunk_type = SCTP_HEARTBEAT_ACK;
    9440           0 :         chdr->chunk_flags = 0;
    9441           0 :         if (chk_length % 4) {
    9442             :                 /* need pad */
    9443           0 :                 uint32_t cpthis = 0;
    9444             :                 int padlen;
    9445             : 
    9446           0 :                 padlen = 4 - (chk_length % 4);
    9447           0 :                 m_copyback(outchain, chk_length, padlen, (caddr_t)&cpthis);
    9448             :         }
    9449           0 :         sctp_alloc_a_chunk(stcb, chk);
    9450           0 :         if (chk == NULL) {
    9451             :                 /* no memory */
    9452           0 :                 sctp_m_freem(outchain);
    9453           0 :                 return;
    9454             :         }
    9455           0 :         chk->copy_by_ref = 0;
    9456           0 :         chk->rec.chunk_id.id = SCTP_HEARTBEAT_ACK;
    9457           0 :         chk->rec.chunk_id.can_take_data = 1;
    9458           0 :         chk->flags = 0;
    9459           0 :         chk->send_size = chk_length;
    9460           0 :         chk->sent = SCTP_DATAGRAM_UNSENT;
    9461           0 :         chk->snd_count = 0;
    9462           0 :         chk->asoc = &stcb->asoc;
    9463           0 :         chk->data = outchain;
    9464           0 :         chk->whoTo = net;
    9465           0 :         atomic_add_int(&chk->whoTo->ref_count, 1);
    9466           0 :         TAILQ_INSERT_TAIL(&chk->asoc->control_send_queue, chk, sctp_next);
    9467           0 :         chk->asoc->ctrl_queue_cnt++;
    9468             : }
    9469             : 
    9470             : void
    9471           0 : sctp_send_cookie_ack(struct sctp_tcb *stcb)
    9472             : {
    9473             :         /* formulate and queue a cookie-ack back to sender */
    9474             :         struct mbuf *cookie_ack;
    9475             :         struct sctp_chunkhdr *hdr;
    9476             :         struct sctp_tmit_chunk *chk;
    9477             : 
    9478             :         SCTP_TCB_LOCK_ASSERT(stcb);
    9479             : 
    9480           0 :         cookie_ack = sctp_get_mbuf_for_msg(sizeof(struct sctp_chunkhdr), 0, M_NOWAIT, 1, MT_HEADER);
    9481           0 :         if (cookie_ack == NULL) {
    9482             :                 /* no mbuf's */
    9483           0 :                 return;
    9484             :         }
    9485           0 :         SCTP_BUF_RESV_UF(cookie_ack, SCTP_MIN_OVERHEAD);
    9486           0 :         sctp_alloc_a_chunk(stcb, chk);
    9487           0 :         if (chk == NULL) {
    9488             :                 /* no memory */
    9489           0 :                 sctp_m_freem(cookie_ack);
    9490           0 :                 return;
    9491             :         }
    9492           0 :         chk->copy_by_ref = 0;
    9493           0 :         chk->rec.chunk_id.id = SCTP_COOKIE_ACK;
    9494           0 :         chk->rec.chunk_id.can_take_data = 1;
    9495           0 :         chk->flags = 0;
    9496           0 :         chk->send_size = sizeof(struct sctp_chunkhdr);
    9497           0 :         chk->sent = SCTP_DATAGRAM_UNSENT;
    9498           0 :         chk->snd_count = 0;
    9499           0 :         chk->asoc = &stcb->asoc;
    9500           0 :         chk->data = cookie_ack;
    9501           0 :         if (chk->asoc->last_control_chunk_from != NULL) {
    9502           0 :                 chk->whoTo = chk->asoc->last_control_chunk_from;
    9503           0 :                 atomic_add_int(&chk->whoTo->ref_count, 1);
    9504             :         } else {
    9505           0 :                 chk->whoTo = NULL;
    9506             :         }
    9507           0 :         hdr = mtod(cookie_ack, struct sctp_chunkhdr *);
    9508           0 :         hdr->chunk_type = SCTP_COOKIE_ACK;
    9509           0 :         hdr->chunk_flags = 0;
    9510           0 :         hdr->chunk_length = htons(chk->send_size);
    9511           0 :         SCTP_BUF_LEN(cookie_ack) = chk->send_size;
    9512           0 :         TAILQ_INSERT_TAIL(&chk->asoc->control_send_queue, chk, sctp_next);
    9513           0 :         chk->asoc->ctrl_queue_cnt++;
    9514           0 :         return;
    9515             : }
    9516             : 
    9517             : 
    9518             : void
    9519           0 : sctp_send_shutdown_ack(struct sctp_tcb *stcb, struct sctp_nets *net)
    9520             : {
    9521             :         /* formulate and queue a SHUTDOWN-ACK back to the sender */
    9522             :         struct mbuf *m_shutdown_ack;
    9523             :         struct sctp_shutdown_ack_chunk *ack_cp;
    9524             :         struct sctp_tmit_chunk *chk;
    9525             : 
    9526           0 :         m_shutdown_ack = sctp_get_mbuf_for_msg(sizeof(struct sctp_shutdown_ack_chunk), 0, M_NOWAIT, 1, MT_HEADER);
    9527           0 :         if (m_shutdown_ack == NULL) {
    9528             :                 /* no mbuf's */
    9529           0 :                 return;
    9530             :         }
    9531           0 :         SCTP_BUF_RESV_UF(m_shutdown_ack, SCTP_MIN_OVERHEAD);
    9532           0 :         sctp_alloc_a_chunk(stcb, chk);
    9533           0 :         if (chk == NULL) {
    9534             :                 /* no memory */
    9535           0 :                 sctp_m_freem(m_shutdown_ack);
    9536           0 :                 return;
    9537             :         }
    9538           0 :         chk->copy_by_ref = 0;
    9539           0 :         chk->rec.chunk_id.id = SCTP_SHUTDOWN_ACK;
    9540           0 :         chk->rec.chunk_id.can_take_data = 1;
    9541           0 :         chk->flags = 0;
    9542           0 :         chk->send_size = sizeof(struct sctp_chunkhdr);
    9543           0 :         chk->sent = SCTP_DATAGRAM_UNSENT;
    9544           0 :         chk->snd_count = 0;
    9545           0 :         chk->flags = 0;
    9546           0 :         chk->asoc = &stcb->asoc;
    9547           0 :         chk->data = m_shutdown_ack;
    9548           0 :         chk->whoTo = net;
    9549           0 :         if (chk->whoTo) {
    9550           0 :                 atomic_add_int(&chk->whoTo->ref_count, 1);
    9551             :         }
    9552           0 :         ack_cp = mtod(m_shutdown_ack, struct sctp_shutdown_ack_chunk *);
    9553           0 :         ack_cp->ch.chunk_type = SCTP_SHUTDOWN_ACK;
    9554           0 :         ack_cp->ch.chunk_flags = 0;
    9555           0 :         ack_cp->ch.chunk_length = htons(chk->send_size);
    9556           0 :         SCTP_BUF_LEN(m_shutdown_ack) = chk->send_size;
    9557           0 :         TAILQ_INSERT_TAIL(&chk->asoc->control_send_queue, chk, sctp_next);
    9558           0 :         chk->asoc->ctrl_queue_cnt++;
    9559           0 :         return;
    9560             : }
    9561             : 
    9562             : void
    9563           0 : sctp_send_shutdown(struct sctp_tcb *stcb, struct sctp_nets *net)
    9564             : {
    9565             :         /* formulate and queue a SHUTDOWN to the sender */
    9566             :         struct mbuf *m_shutdown;
    9567             :         struct sctp_shutdown_chunk *shutdown_cp;
    9568             :         struct sctp_tmit_chunk *chk;
    9569             : 
    9570           0 :         m_shutdown = sctp_get_mbuf_for_msg(sizeof(struct sctp_shutdown_chunk), 0, M_NOWAIT, 1, MT_HEADER);
    9571           0 :         if (m_shutdown == NULL) {
    9572             :                 /* no mbuf's */
    9573           0 :                 return;
    9574             :         }
    9575           0 :         SCTP_BUF_RESV_UF(m_shutdown, SCTP_MIN_OVERHEAD);
    9576           0 :         sctp_alloc_a_chunk(stcb, chk);
    9577           0 :         if (chk == NULL) {
    9578             :                 /* no memory */
    9579           0 :                 sctp_m_freem(m_shutdown);
    9580           0 :                 return;
    9581             :         }
    9582           0 :         chk->copy_by_ref = 0;
    9583           0 :         chk->rec.chunk_id.id = SCTP_SHUTDOWN;
    9584           0 :         chk->rec.chunk_id.can_take_data = 1;
    9585           0 :         chk->flags = 0;
    9586           0 :         chk->send_size = sizeof(struct sctp_shutdown_chunk);
    9587           0 :         chk->sent = SCTP_DATAGRAM_UNSENT;
    9588           0 :         chk->snd_count = 0;
    9589           0 :         chk->flags = 0;
    9590           0 :         chk->asoc = &stcb->asoc;
    9591           0 :         chk->data = m_shutdown;
    9592           0 :         chk->whoTo = net;
    9593           0 :         if (chk->whoTo) {
    9594           0 :                 atomic_add_int(&chk->whoTo->ref_count, 1);
    9595             :         }
    9596           0 :         shutdown_cp = mtod(m_shutdown, struct sctp_shutdown_chunk *);
    9597           0 :         shutdown_cp->ch.chunk_type = SCTP_SHUTDOWN;
    9598           0 :         shutdown_cp->ch.chunk_flags = 0;
    9599           0 :         shutdown_cp->ch.chunk_length = htons(chk->send_size);
    9600           0 :         shutdown_cp->cumulative_tsn_ack = htonl(stcb->asoc.cumulative_tsn);
    9601           0 :         SCTP_BUF_LEN(m_shutdown) = chk->send_size;
    9602           0 :         TAILQ_INSERT_TAIL(&chk->asoc->control_send_queue, chk, sctp_next);
    9603           0 :         chk->asoc->ctrl_queue_cnt++;
    9604           0 :         return;
    9605             : }
    9606             : 
    9607             : void
    9608           0 : sctp_send_asconf(struct sctp_tcb *stcb, struct sctp_nets *net, int addr_locked)
    9609             : {
    9610             :         /*
    9611             :          * formulate and queue an ASCONF to the peer.
    9612             :          * ASCONF parameters should be queued on the assoc queue.
    9613             :          */
    9614             :         struct sctp_tmit_chunk *chk;
    9615             :         struct mbuf *m_asconf;
    9616             :         int len;
    9617             : 
    9618             :         SCTP_TCB_LOCK_ASSERT(stcb);
    9619             : 
    9620           0 :         if ((!TAILQ_EMPTY(&stcb->asoc.asconf_send_queue)) &&
    9621           0 :             (!sctp_is_feature_on(stcb->sctp_ep, SCTP_PCB_FLAGS_MULTIPLE_ASCONFS))) {
    9622             :                 /* can't send a new one if there is one in flight already */
    9623           0 :                 return;
    9624             :         }
    9625             : 
    9626             :         /* compose an ASCONF chunk, maximum length is PMTU */
    9627           0 :         m_asconf = sctp_compose_asconf(stcb, &len, addr_locked);
    9628           0 :         if (m_asconf == NULL) {
    9629           0 :                 return;
    9630             :         }
    9631             : 
    9632           0 :         sctp_alloc_a_chunk(stcb, chk);
    9633           0 :         if (chk == NULL) {
    9634             :                 /* no memory */
    9635           0 :                 sctp_m_freem(m_asconf);
    9636           0 :                 return;
    9637             :         }
    9638             : 
    9639           0 :         chk->copy_by_ref = 0;
    9640           0 :         chk->rec.chunk_id.id = SCTP_ASCONF;
    9641           0 :         chk->rec.chunk_id.can_take_data = 0;
    9642           0 :         chk->flags = CHUNK_FLAGS_FRAGMENT_OK;
    9643           0 :         chk->data = m_asconf;
    9644           0 :         chk->send_size = len;
    9645           0 :         chk->sent = SCTP_DATAGRAM_UNSENT;
    9646           0 :         chk->snd_count = 0;
    9647           0 :         chk->asoc = &stcb->asoc;
    9648           0 :         chk->whoTo = net;
    9649           0 :         if (chk->whoTo) {
    9650           0 :                 atomic_add_int(&chk->whoTo->ref_count, 1);
    9651             :         }
    9652           0 :         TAILQ_INSERT_TAIL(&chk->asoc->asconf_send_queue, chk, sctp_next);
    9653           0 :         chk->asoc->ctrl_queue_cnt++;
    9654           0 :         return;
    9655             : }
    9656             : 
    9657             : void
    9658           0 : sctp_send_asconf_ack(struct sctp_tcb *stcb)
    9659             : {
    9660             :         /*
    9661             :          * formulate and queue a asconf-ack back to sender.
    9662             :          * the asconf-ack must be stored in the tcb.
    9663             :          */
    9664             :         struct sctp_tmit_chunk *chk;
    9665             :         struct sctp_asconf_ack *ack, *latest_ack;
    9666             :         struct mbuf *m_ack;
    9667           0 :         struct sctp_nets *net = NULL;
    9668             : 
    9669             :         SCTP_TCB_LOCK_ASSERT(stcb);
    9670             :         /* Get the latest ASCONF-ACK */
    9671           0 :         latest_ack = TAILQ_LAST(&stcb->asoc.asconf_ack_sent, sctp_asconf_ackhead);
    9672           0 :         if (latest_ack == NULL) {
    9673           0 :                 return;
    9674             :         }
    9675           0 :         if (latest_ack->last_sent_to != NULL &&
    9676           0 :             latest_ack->last_sent_to == stcb->asoc.last_control_chunk_from) {
    9677             :                 /* we're doing a retransmission */
    9678           0 :                 net = sctp_find_alternate_net(stcb, stcb->asoc.last_control_chunk_from, 0);
    9679           0 :                 if (net == NULL) {
    9680             :                         /* no alternate */
    9681           0 :                         if (stcb->asoc.last_control_chunk_from == NULL) {
    9682           0 :                                 if (stcb->asoc.alternate) {
    9683           0 :                                         net = stcb->asoc.alternate;
    9684             :                                 } else {
    9685           0 :                                         net = stcb->asoc.primary_destination;
    9686             :                                 }
    9687             :                         } else {
    9688           0 :                                 net = stcb->asoc.last_control_chunk_from;
    9689             :                         }
    9690             :                 }
    9691             :         } else {
    9692             :                 /* normal case */
    9693           0 :                 if (stcb->asoc.last_control_chunk_from == NULL) {
    9694           0 :                         if (stcb->asoc.alternate) {
    9695           0 :                                 net = stcb->asoc.alternate;
    9696             :                         } else {
    9697           0 :                                 net = stcb->asoc.primary_destination;
    9698             :                         }
    9699             :                 } else {
    9700           0 :                         net = stcb->asoc.last_control_chunk_from;
    9701             :                 }
    9702             :         }
    9703           0 :         latest_ack->last_sent_to = net;
    9704             : 
    9705           0 :         TAILQ_FOREACH(ack, &stcb->asoc.asconf_ack_sent, next) {
    9706           0 :                 if (ack->data == NULL) {
    9707           0 :                         continue;
    9708             :                 }
    9709             : 
    9710             :                 /* copy the asconf_ack */
    9711           0 :                 m_ack = SCTP_M_COPYM(ack->data, 0, M_COPYALL, M_NOWAIT);
    9712           0 :                 if (m_ack == NULL) {
    9713             :                         /* couldn't copy it */
    9714           0 :                         return;
    9715             :                 }
    9716             : #ifdef SCTP_MBUF_LOGGING
    9717             :                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
    9718             :                         sctp_log_mbc(m_ack, SCTP_MBUF_ICOPY);
    9719             :                 }
    9720             : #endif
    9721             : 
    9722           0 :                 sctp_alloc_a_chunk(stcb, chk);
    9723           0 :                 if (chk == NULL) {
    9724             :                         /* no memory */
    9725           0 :                         if (m_ack)
    9726           0 :                                 sctp_m_freem(m_ack);
    9727           0 :                         return;
    9728             :                 }
    9729           0 :                 chk->copy_by_ref = 0;
    9730           0 :                 chk->rec.chunk_id.id = SCTP_ASCONF_ACK;
    9731           0 :                 chk->rec.chunk_id.can_take_data = 1;
    9732           0 :                 chk->flags = CHUNK_FLAGS_FRAGMENT_OK;
    9733           0 :                 chk->whoTo = net;
    9734           0 :                 if (chk->whoTo) {
    9735           0 :                         atomic_add_int(&chk->whoTo->ref_count, 1);
    9736             :                 }
    9737           0 :                 chk->data = m_ack;
    9738           0 :                 chk->send_size = ack->len;
    9739           0 :                 chk->sent = SCTP_DATAGRAM_UNSENT;
    9740           0 :                 chk->snd_count = 0;
    9741           0 :                 chk->asoc = &stcb->asoc;
    9742             : 
    9743           0 :                 TAILQ_INSERT_TAIL(&chk->asoc->control_send_queue, chk, sctp_next);
    9744           0 :                 chk->asoc->ctrl_queue_cnt++;
    9745             :         }
    9746           0 :         return;
    9747             : }
    9748             : 
    9749             : 
    9750             : static int
    9751           0 : sctp_chunk_retransmission(struct sctp_inpcb *inp,
    9752             :     struct sctp_tcb *stcb,
    9753             :     struct sctp_association *asoc,
    9754             :     int *cnt_out, struct timeval *now, int *now_filled, int *fr_done, int so_locked
    9755             : #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
    9756             :     SCTP_UNUSED
    9757             : #endif
    9758             :     )
    9759             : {
    9760             :         /*-
    9761             :          * send out one MTU of retransmission. If fast_retransmit is
    9762             :          * happening we ignore the cwnd. Otherwise we obey the cwnd and
    9763             :          * rwnd. For a Cookie or Asconf in the control chunk queue we
    9764             :          * retransmit them by themselves.
    9765             :          *
    9766             :          * For data chunks we will pick out the lowest TSN's in the sent_queue
    9767             :          * marked for resend and bundle them all together (up to a MTU of
    9768             :          * destination). The address to send to should have been
    9769             :          * selected/changed where the retransmission was marked (i.e. in FR
    9770             :          * or t3-timeout routines).
    9771             :          */
    9772             :         struct sctp_tmit_chunk *data_list[SCTP_MAX_DATA_BUNDLING];
    9773             :         struct sctp_tmit_chunk *chk, *fwd;
    9774             :         struct mbuf *m, *endofchain;
    9775           0 :         struct sctp_nets *net = NULL;
    9776           0 :         uint32_t tsns_sent = 0;
    9777             :         int no_fragmentflg, bundle_at, cnt_thru;
    9778             :         unsigned int mtu;
    9779             :         int error, i, one_chunk, fwd_tsn, ctl_cnt, tmr_started;
    9780           0 :         struct sctp_auth_chunk *auth = NULL;
    9781           0 :         uint32_t auth_offset = 0;
    9782             :         uint16_t auth_keyid;
    9783           0 :         int override_ok = 1;
    9784           0 :         int data_auth_reqd = 0;
    9785           0 :         uint32_t dmtu = 0;
    9786             : 
    9787             : #if defined(__APPLE__)
    9788             :         if (so_locked) {
    9789             :                 sctp_lock_assert(SCTP_INP_SO(inp));
    9790             :         } else {
    9791             :                 sctp_unlock_assert(SCTP_INP_SO(inp));
    9792             :         }
    9793             : #endif
    9794             :         SCTP_TCB_LOCK_ASSERT(stcb);
    9795           0 :         tmr_started = ctl_cnt = bundle_at = error = 0;
    9796           0 :         no_fragmentflg = 1;
    9797           0 :         fwd_tsn = 0;
    9798           0 :         *cnt_out = 0;
    9799           0 :         fwd = NULL;
    9800           0 :         endofchain = m = NULL;
    9801           0 :         auth_keyid = stcb->asoc.authinfo.active_keyid;
    9802             : #ifdef SCTP_AUDITING_ENABLED
    9803             :         sctp_audit_log(0xC3, 1);
    9804             : #endif
    9805           0 :         if ((TAILQ_EMPTY(&asoc->sent_queue)) &&
    9806           0 :             (TAILQ_EMPTY(&asoc->control_send_queue))) {
    9807           0 :                 SCTPDBG(SCTP_DEBUG_OUTPUT1,"SCTP hits empty queue with cnt set to %d?\n",
    9808             :                         asoc->sent_queue_retran_cnt);
    9809           0 :                 asoc->sent_queue_cnt = 0;
    9810           0 :                 asoc->sent_queue_cnt_removeable = 0;
    9811             :                 /* send back 0/0 so we enter normal transmission */
    9812           0 :                 *cnt_out = 0;
    9813           0 :                 return (0);
    9814             :         }
    9815           0 :         TAILQ_FOREACH(chk, &asoc->control_send_queue, sctp_next) {
    9816           0 :                 if ((chk->rec.chunk_id.id == SCTP_COOKIE_ECHO) ||
    9817           0 :                     (chk->rec.chunk_id.id == SCTP_STREAM_RESET) ||
    9818           0 :                     (chk->rec.chunk_id.id == SCTP_FORWARD_CUM_TSN)) {
    9819           0 :                         if (chk->sent != SCTP_DATAGRAM_RESEND) {
    9820           0 :                                 continue;
    9821             :                         }
    9822           0 :                         if (chk->rec.chunk_id.id == SCTP_STREAM_RESET) {
    9823           0 :                                 if (chk != asoc->str_reset) {
    9824             :                                         /*
    9825             :                                          * not eligible for retran if its
    9826             :                                          * not ours
    9827             :                                          */
    9828           0 :                                         continue;
    9829             :                                 }
    9830             :                         }
    9831           0 :                         ctl_cnt++;
    9832           0 :                         if (chk->rec.chunk_id.id == SCTP_FORWARD_CUM_TSN) {
    9833           0 :                                 fwd_tsn = 1;
    9834             :                         }
    9835             :                         /*
    9836             :                          * Add an AUTH chunk, if chunk requires it save the
    9837             :                          * offset into the chain for AUTH
    9838             :                          */
    9839           0 :                         if ((auth == NULL) &&
    9840           0 :                             (sctp_auth_is_required_chunk(chk->rec.chunk_id.id,
    9841             :                                                          stcb->asoc.peer_auth_chunks))) {
    9842           0 :                                 m = sctp_add_auth_chunk(m, &endofchain,
    9843             :                                                         &auth, &auth_offset,
    9844             :                                                         stcb,
    9845           0 :                                                         chk->rec.chunk_id.id);
    9846           0 :                                 SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks);
    9847             :                         }
    9848           0 :                         m = sctp_copy_mbufchain(chk->data, m, &endofchain, 0, chk->send_size, chk->copy_by_ref);
    9849           0 :                         break;
    9850             :                 }
    9851             :         }
    9852           0 :         one_chunk = 0;
    9853           0 :         cnt_thru = 0;
    9854             :         /* do we have control chunks to retransmit? */
    9855           0 :         if (m != NULL) {
    9856             :                 /* Start a timer no matter if we suceed or fail */
    9857           0 :                 if (chk->rec.chunk_id.id == SCTP_COOKIE_ECHO) {
    9858           0 :                         sctp_timer_start(SCTP_TIMER_TYPE_COOKIE, inp, stcb, chk->whoTo);
    9859           0 :                 } else if (chk->rec.chunk_id.id == SCTP_ASCONF)
    9860           0 :                         sctp_timer_start(SCTP_TIMER_TYPE_ASCONF, inp, stcb, chk->whoTo);
    9861           0 :                 chk->snd_count++;    /* update our count */
    9862           0 :                 if ((error = sctp_lowlevel_chunk_output(inp, stcb, chk->whoTo,
    9863           0 :                                                         (struct sockaddr *)&chk->whoTo->ro._l_addr, m,
    9864           0 :                                                         auth_offset, auth, stcb->asoc.authinfo.active_keyid,
    9865             :                                                         no_fragmentflg, 0, 0,
    9866           0 :                                                         inp->sctp_lport, stcb->rport, htonl(stcb->asoc.peer_vtag),
    9867           0 :                                                         chk->whoTo->port, NULL,
    9868             : #if defined(__FreeBSD__)
    9869             :                                                         0, 0,
    9870             : #endif
    9871             :                                                         so_locked))) {
    9872           0 :                         SCTP_STAT_INCR(sctps_lowlevelerr);
    9873           0 :                         return (error);
    9874             :                 }
    9875           0 :                 endofchain = NULL;
    9876           0 :                 auth = NULL;
    9877           0 :                 auth_offset = 0;
    9878             :                 /*
    9879             :                  * We don't want to mark the net->sent time here since this
    9880             :                  * we use this for HB and retrans cannot measure RTT
    9881             :                  */
    9882             :                 /* (void)SCTP_GETTIME_TIMEVAL(&chk->whoTo->last_sent_time); */
    9883           0 :                 *cnt_out += 1;
    9884           0 :                 chk->sent = SCTP_DATAGRAM_SENT;
    9885           0 :                 sctp_ucount_decr(stcb->asoc.sent_queue_retran_cnt);
    9886           0 :                 if (fwd_tsn == 0) {
    9887           0 :                         return (0);
    9888             :                 } else {
    9889             :                         /* Clean up the fwd-tsn list */
    9890           0 :                         sctp_clean_up_ctl(stcb, asoc, so_locked);
    9891           0 :                         return (0);
    9892             :                 }
    9893             :         }
    9894             :         /*
    9895             :          * Ok, it is just data retransmission we need to do or that and a
    9896             :          * fwd-tsn with it all.
    9897             :          */
    9898           0 :         if (TAILQ_EMPTY(&asoc->sent_queue)) {
    9899           0 :                 return (SCTP_RETRAN_DONE);
    9900             :         }
    9901           0 :         if ((SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_ECHOED) ||
    9902           0 :             (SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_WAIT)) {
    9903             :                 /* not yet open, resend the cookie and that is it */
    9904           0 :                 return (1);
    9905             :         }
    9906             : #ifdef SCTP_AUDITING_ENABLED
    9907             :         sctp_auditing(20, inp, stcb, NULL);
    9908             : #endif
    9909           0 :         data_auth_reqd = sctp_auth_is_required_chunk(SCTP_DATA, stcb->asoc.peer_auth_chunks);
    9910           0 :         TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) {
    9911           0 :                 if (chk->sent != SCTP_DATAGRAM_RESEND) {
    9912             :                         /* No, not sent to this net or not ready for rtx */
    9913           0 :                         continue;
    9914             :                 }
    9915           0 :                 if (chk->data == NULL) {
    9916           0 :                         SCTP_PRINTF("TSN:%x chk->snd_count:%d chk->sent:%d can't retran - no data\n",
    9917             :                                     chk->rec.data.TSN_seq, chk->snd_count, chk->sent);
    9918           0 :                         continue;
    9919             :                 }
    9920           0 :                 if ((SCTP_BASE_SYSCTL(sctp_max_retran_chunk)) &&
    9921           0 :                     (chk->snd_count >= SCTP_BASE_SYSCTL(sctp_max_retran_chunk))) {
    9922             :                         /* Gak, we have exceeded max unlucky retran, abort! */
    9923           0 :                         SCTP_PRINTF("Gak, chk->snd_count:%d >= max:%d - send abort\n",
    9924             :                                     chk->snd_count,
    9925             :                                     SCTP_BASE_SYSCTL(sctp_max_retran_chunk));
    9926           0 :                         atomic_add_int(&stcb->asoc.refcnt, 1);
    9927           0 :                         sctp_abort_an_association(stcb->sctp_ep, stcb, NULL, so_locked);
    9928           0 :                         SCTP_TCB_LOCK(stcb);
    9929           0 :                         atomic_subtract_int(&stcb->asoc.refcnt, 1);
    9930           0 :                         return (SCTP_RETRAN_EXIT);
    9931             :                 }
    9932             :                 /* pick up the net */
    9933           0 :                 net = chk->whoTo;
    9934           0 :                 switch (net->ro._l_addr.sa.sa_family) {
    9935             : #ifdef INET
    9936             :                         case AF_INET:
    9937             :                                 mtu = net->mtu - SCTP_MIN_V4_OVERHEAD;
    9938             :                                 break;
    9939             : #endif
    9940             : #ifdef INET6
    9941             :                         case AF_INET6:
    9942             :                                 mtu = net->mtu - SCTP_MIN_OVERHEAD;
    9943             :                                 break;
    9944             : #endif
    9945             : #if defined(__Userspace__)
    9946             :                         case AF_CONN:
    9947           0 :                                 mtu = net->mtu - sizeof(struct sctphdr);
    9948           0 :                                 break;
    9949             : #endif
    9950             :                         default:
    9951             :                                 /* TSNH */
    9952           0 :                                 mtu = net->mtu;
    9953           0 :                                 break;
    9954             :                 }
    9955             : 
    9956           0 :                 if ((asoc->peers_rwnd < mtu) && (asoc->total_flight > 0)) {
    9957             :                         /* No room in peers rwnd */
    9958             :                         uint32_t tsn;
    9959             : 
    9960           0 :                         tsn = asoc->last_acked_seq + 1;
    9961           0 :                         if (tsn == chk->rec.data.TSN_seq) {
    9962             :                                 /*
    9963             :                                  * we make a special exception for this
    9964             :                                  * case. The peer has no rwnd but is missing
    9965             :                                  * the lowest chunk.. which is probably what
    9966             :                                  * is holding up the rwnd.
    9967             :                                  */
    9968           0 :                                 goto one_chunk_around;
    9969             :                         }
    9970           0 :                         return (1);
    9971             :                 }
    9972             :         one_chunk_around:
    9973           0 :                 if (asoc->peers_rwnd < mtu) {
    9974           0 :                         one_chunk = 1;
    9975           0 :                         if ((asoc->peers_rwnd == 0) &&
    9976           0 :                             (asoc->total_flight == 0)) {
    9977           0 :                                 chk->window_probe = 1;
    9978           0 :                                 chk->whoTo->window_probe = 1;
    9979             :                         }
    9980             :                 }
    9981             : #ifdef SCTP_AUDITING_ENABLED
    9982             :                 sctp_audit_log(0xC3, 2);
    9983             : #endif
    9984           0 :                 bundle_at = 0;
    9985           0 :                 m = NULL;
    9986           0 :                 net->fast_retran_ip = 0;
    9987           0 :                 if (chk->rec.data.doing_fast_retransmit == 0) {
    9988             :                         /*
    9989             :                          * if no FR in progress skip destination that have
    9990             :                          * flight_size > cwnd.
    9991             :                          */
    9992           0 :                         if (net->flight_size >= net->cwnd) {
    9993           0 :                                 continue;
    9994             :                         }
    9995             :                 } else {
    9996             :                         /*
    9997             :                          * Mark the destination net to have FR recovery
    9998             :                          * limits put on it.
    9999             :                          */
   10000           0 :                         *fr_done = 1;
   10001           0 :                         net->fast_retran_ip = 1;
   10002             :                 }
   10003             : 
   10004             :                 /*
   10005             :                  * if no AUTH is yet included and this chunk requires it,
   10006             :                  * make sure to account for it.  We don't apply the size
   10007             :                  * until the AUTH chunk is actually added below in case
   10008             :                  * there is no room for this chunk.
   10009             :                  */
   10010           0 :                 if (data_auth_reqd && (auth == NULL)) {
   10011           0 :                         dmtu = sctp_get_auth_chunk_len(stcb->asoc.peer_hmac_id);
   10012             :                 } else
   10013           0 :                         dmtu = 0;
   10014             : 
   10015           0 :                 if ((chk->send_size <= (mtu - dmtu)) ||
   10016           0 :                     (chk->flags & CHUNK_FLAGS_FRAGMENT_OK)) {
   10017             :                         /* ok we will add this one */
   10018           0 :                         if (data_auth_reqd) {
   10019           0 :                                 if (auth == NULL) {
   10020           0 :                                         m = sctp_add_auth_chunk(m,
   10021             :                                                                 &endofchain,
   10022             :                                                                 &auth,
   10023             :                                                                 &auth_offset,
   10024             :                                                                 stcb,
   10025             :                                                                 SCTP_DATA);
   10026           0 :                                         auth_keyid = chk->auth_keyid;
   10027           0 :                                         override_ok = 0;
   10028           0 :                                         SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks);
   10029           0 :                                 } else if (override_ok) {
   10030           0 :                                         auth_keyid = chk->auth_keyid;
   10031           0 :                                         override_ok = 0;
   10032           0 :                                 } else if (chk->auth_keyid != auth_keyid) {
   10033             :                                         /* different keyid, so done bundling */
   10034           0 :                                         break;
   10035             :                                 }
   10036             :                         }
   10037           0 :                         m = sctp_copy_mbufchain(chk->data, m, &endofchain, 0, chk->send_size, chk->copy_by_ref);
   10038           0 :                         if (m == NULL) {
   10039             :                                 SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
   10040           0 :                                 return (ENOMEM);
   10041             :                         }
   10042             :                         /* Do clear IP_DF ? */
   10043           0 :                         if (chk->flags & CHUNK_FLAGS_FRAGMENT_OK) {
   10044           0 :                                 no_fragmentflg = 0;
   10045             :                         }
   10046             :                         /* upate our MTU size */
   10047           0 :                         if (mtu > (chk->send_size + dmtu))
   10048           0 :                                 mtu -= (chk->send_size + dmtu);
   10049             :                         else
   10050           0 :                                 mtu = 0;
   10051           0 :                         data_list[bundle_at++] = chk;
   10052           0 :                         if (one_chunk && (asoc->total_flight <= 0)) {
   10053           0 :                                 SCTP_STAT_INCR(sctps_windowprobed);
   10054             :                         }
   10055             :                 }
   10056           0 :                 if (one_chunk == 0) {
   10057             :                         /*
   10058             :                          * now are there anymore forward from chk to pick
   10059             :                          * up?
   10060             :                          */
   10061           0 :                         for (fwd = TAILQ_NEXT(chk, sctp_next); fwd != NULL; fwd = TAILQ_NEXT(fwd, sctp_next)) {
   10062           0 :                                 if (fwd->sent != SCTP_DATAGRAM_RESEND) {
   10063             :                                         /* Nope, not for retran */
   10064           0 :                                         continue;
   10065             :                                 }
   10066           0 :                                 if (fwd->whoTo != net) {
   10067             :                                         /* Nope, not the net in question */
   10068           0 :                                         continue;
   10069             :                                 }
   10070           0 :                                 if (data_auth_reqd && (auth == NULL)) {
   10071           0 :                                         dmtu = sctp_get_auth_chunk_len(stcb->asoc.peer_hmac_id);
   10072             :                                 } else
   10073           0 :                                         dmtu = 0;
   10074           0 :                                 if (fwd->send_size <= (mtu - dmtu)) {
   10075           0 :                                         if (data_auth_reqd) {
   10076           0 :                                                 if (auth == NULL) {
   10077           0 :                                                         m = sctp_add_auth_chunk(m,
   10078             :                                                                                 &endofchain,
   10079             :                                                                                 &auth,
   10080             :                                                                                 &auth_offset,
   10081             :                                                                                 stcb,
   10082             :                                                                                 SCTP_DATA);
   10083           0 :                                                         auth_keyid = fwd->auth_keyid;
   10084           0 :                                                         override_ok = 0;
   10085           0 :                                                         SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks);
   10086           0 :                                                 } else if (override_ok) {
   10087           0 :                                                         auth_keyid = fwd->auth_keyid;
   10088           0 :                                                         override_ok = 0;
   10089           0 :                                                 } else if (fwd->auth_keyid != auth_keyid) {
   10090             :                                                         /* different keyid, so done bundling */
   10091           0 :                                                         break;
   10092             :                                                 }
   10093             :                                         }
   10094           0 :                                         m = sctp_copy_mbufchain(fwd->data, m, &endofchain, 0, fwd->send_size, fwd->copy_by_ref);
   10095           0 :                                         if (m == NULL) {
   10096             :                                                 SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
   10097           0 :                                                 return (ENOMEM);
   10098             :                                         }
   10099             :                                         /* Do clear IP_DF ? */
   10100           0 :                                         if (fwd->flags & CHUNK_FLAGS_FRAGMENT_OK) {
   10101           0 :                                                 no_fragmentflg = 0;
   10102             :                                         }
   10103             :                                         /* upate our MTU size */
   10104           0 :                                         if (mtu > (fwd->send_size + dmtu))
   10105           0 :                                                 mtu -= (fwd->send_size + dmtu);
   10106             :                                         else
   10107           0 :                                                 mtu = 0;
   10108           0 :                                         data_list[bundle_at++] = fwd;
   10109           0 :                                         if (bundle_at >= SCTP_MAX_DATA_BUNDLING) {
   10110           0 :                                                 break;
   10111             :                                         }
   10112             :                                 } else {
   10113             :                                         /* can't fit so we are done */
   10114           0 :                                         break;
   10115             :                                 }
   10116             :                         }
   10117             :                 }
   10118             :                 /* Is there something to send for this destination? */
   10119           0 :                 if (m) {
   10120             :                         /*
   10121             :                          * No matter if we fail/or suceed we should start a
   10122             :                          * timer. A failure is like a lost IP packet :-)
   10123             :                          */
   10124           0 :                         if (!SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
   10125             :                                 /*
   10126             :                                  * no timer running on this destination
   10127             :                                  * restart it.
   10128             :                                  */
   10129           0 :                                 sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb, net);
   10130           0 :                                 tmr_started = 1;
   10131             :                         }
   10132             :                         /* Now lets send it, if there is anything to send :> */
   10133           0 :                         if ((error = sctp_lowlevel_chunk_output(inp, stcb, net,
   10134           0 :                                                                 (struct sockaddr *)&net->ro._l_addr, m,
   10135             :                                                                 auth_offset, auth, auth_keyid,
   10136             :                                                                 no_fragmentflg, 0, 0,
   10137           0 :                                                                 inp->sctp_lport, stcb->rport, htonl(stcb->asoc.peer_vtag),
   10138           0 :                                                                 net->port, NULL,
   10139             : #if defined(__FreeBSD__)
   10140             :                                                                 0, 0,
   10141             : #endif
   10142             :                                                                 so_locked))) {
   10143             :                                 /* error, we could not output */
   10144           0 :                                 SCTP_STAT_INCR(sctps_lowlevelerr);
   10145           0 :                                 return (error);
   10146             :                         }
   10147           0 :                         endofchain = NULL;
   10148           0 :                         auth = NULL;
   10149           0 :                         auth_offset = 0;
   10150             :                         /* For HB's */
   10151             :                         /*
   10152             :                          * We don't want to mark the net->sent time here
   10153             :                          * since this we use this for HB and retrans cannot
   10154             :                          * measure RTT
   10155             :                          */
   10156             :                         /* (void)SCTP_GETTIME_TIMEVAL(&net->last_sent_time); */
   10157             : 
   10158             :                         /* For auto-close */
   10159           0 :                         cnt_thru++;
   10160           0 :                         if (*now_filled == 0) {
   10161           0 :                                 (void)SCTP_GETTIME_TIMEVAL(&asoc->time_last_sent);
   10162           0 :                                 *now = asoc->time_last_sent;
   10163           0 :                                 *now_filled = 1;
   10164             :                         } else {
   10165           0 :                                 asoc->time_last_sent = *now;
   10166             :                         }
   10167           0 :                         *cnt_out += bundle_at;
   10168             : #ifdef SCTP_AUDITING_ENABLED
   10169             :                         sctp_audit_log(0xC4, bundle_at);
   10170             : #endif
   10171           0 :                         if (bundle_at) {
   10172           0 :                                 tsns_sent = data_list[0]->rec.data.TSN_seq;
   10173             :                         }
   10174           0 :                         for (i = 0; i < bundle_at; i++) {
   10175           0 :                                 SCTP_STAT_INCR(sctps_sendretransdata);
   10176           0 :                                 data_list[i]->sent = SCTP_DATAGRAM_SENT;
   10177             :                                 /*
   10178             :                                  * When we have a revoked data, and we
   10179             :                                  * retransmit it, then we clear the revoked
   10180             :                                  * flag since this flag dictates if we
   10181             :                                  * subtracted from the fs
   10182             :                                  */
   10183           0 :                                 if (data_list[i]->rec.data.chunk_was_revoked) {
   10184             :                                         /* Deflate the cwnd */
   10185           0 :                                         data_list[i]->whoTo->cwnd -= data_list[i]->book_size;
   10186           0 :                                         data_list[i]->rec.data.chunk_was_revoked = 0;
   10187             :                                 }
   10188           0 :                                 data_list[i]->snd_count++;
   10189           0 :                                 sctp_ucount_decr(asoc->sent_queue_retran_cnt);
   10190             :                                 /* record the time */
   10191           0 :                                 data_list[i]->sent_rcv_time = asoc->time_last_sent;
   10192           0 :                                 if (data_list[i]->book_size_scale) {
   10193             :                                         /*
   10194             :                                          * need to double the book size on
   10195             :                                          * this one
   10196             :                                          */
   10197           0 :                                         data_list[i]->book_size_scale = 0;
   10198             :                                         /* Since we double the booksize, we must
   10199             :                                          * also double the output queue size, since this
   10200             :                                          * get shrunk when we free by this amount.
   10201             :                                          */
   10202           0 :                                         atomic_add_int(&((asoc)->total_output_queue_size),data_list[i]->book_size);
   10203           0 :                                         data_list[i]->book_size *= 2;
   10204             : 
   10205             : 
   10206             :                                 } else {
   10207           0 :                                         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOG_RWND_ENABLE) {
   10208           0 :                                                 sctp_log_rwnd(SCTP_DECREASE_PEER_RWND,
   10209           0 :                                                       asoc->peers_rwnd, data_list[i]->send_size, SCTP_BASE_SYSCTL(sctp_peer_chunk_oh));
   10210             :                                         }
   10211           0 :                                         asoc->peers_rwnd = sctp_sbspace_sub(asoc->peers_rwnd,
   10212             :                                                                             (uint32_t) (data_list[i]->send_size +
   10213             :                                                                                         SCTP_BASE_SYSCTL(sctp_peer_chunk_oh)));
   10214             :                                 }
   10215           0 :                                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FLIGHT_LOGGING_ENABLE) {
   10216           0 :                                         sctp_misc_ints(SCTP_FLIGHT_LOG_UP_RSND,
   10217           0 :                                                        data_list[i]->whoTo->flight_size,
   10218           0 :                                                        data_list[i]->book_size,
   10219           0 :                                                        (uintptr_t)data_list[i]->whoTo,
   10220           0 :                                                        data_list[i]->rec.data.TSN_seq);
   10221             :                                 }
   10222           0 :                                 sctp_flight_size_increase(data_list[i]);
   10223           0 :                                 sctp_total_flight_increase(stcb, data_list[i]);
   10224           0 :                                 if (asoc->peers_rwnd < stcb->sctp_ep->sctp_ep.sctp_sws_sender) {
   10225             :                                         /* SWS sender side engages */
   10226           0 :                                         asoc->peers_rwnd = 0;
   10227             :                                 }
   10228           0 :                                 if ((i == 0) &&
   10229           0 :                                     (data_list[i]->rec.data.doing_fast_retransmit)) {
   10230           0 :                                         SCTP_STAT_INCR(sctps_sendfastretrans);
   10231           0 :                                         if ((data_list[i] == TAILQ_FIRST(&asoc->sent_queue)) &&
   10232             :                                             (tmr_started == 0)) {
   10233             :                                                 /*-
   10234             :                                                  * ok we just fast-retrans'd
   10235             :                                                  * the lowest TSN, i.e the
   10236             :                                                  * first on the list. In
   10237             :                                                  * this case we want to give
   10238             :                                                  * some more time to get a
   10239             :                                                  * SACK back without a
   10240             :                                                  * t3-expiring.
   10241             :                                                  */
   10242           0 :                                                 sctp_timer_stop(SCTP_TIMER_TYPE_SEND, inp, stcb, net,
   10243             :                                                                 SCTP_FROM_SCTP_OUTPUT+SCTP_LOC_4);
   10244           0 :                                                 sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb, net);
   10245             :                                         }
   10246             :                                 }
   10247             :                         }
   10248           0 :                         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) {
   10249           0 :                                 sctp_log_cwnd(stcb, net, tsns_sent, SCTP_CWND_LOG_FROM_RESEND);
   10250             :                         }
   10251             : #ifdef SCTP_AUDITING_ENABLED
   10252             :                         sctp_auditing(21, inp, stcb, NULL);
   10253             : #endif
   10254             :                 } else {
   10255             :                         /* None will fit */
   10256           0 :                         return (1);
   10257             :                 }
   10258           0 :                 if (asoc->sent_queue_retran_cnt <= 0) {
   10259             :                         /* all done we have no more to retran */
   10260           0 :                         asoc->sent_queue_retran_cnt = 0;
   10261           0 :                         break;
   10262             :                 }
   10263           0 :                 if (one_chunk) {
   10264             :                         /* No more room in rwnd */
   10265           0 :                         return (1);
   10266             :                 }
   10267             :                 /* stop the for loop here. we sent out a packet */
   10268           0 :                 break;
   10269             :         }
   10270           0 :         return (0);
   10271             : }
   10272             : 
   10273             : static void
   10274           0 : sctp_timer_validation(struct sctp_inpcb *inp,
   10275             :     struct sctp_tcb *stcb,
   10276             :     struct sctp_association *asoc)
   10277             : {
   10278             :         struct sctp_nets *net;
   10279             : 
   10280             :         /* Validate that a timer is running somewhere */
   10281           0 :         TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
   10282           0 :                 if (SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
   10283             :                         /* Here is a timer */
   10284           0 :                         return;
   10285             :                 }
   10286             :         }
   10287             :         SCTP_TCB_LOCK_ASSERT(stcb);
   10288             :         /* Gak, we did not have a timer somewhere */
   10289           0 :         SCTPDBG(SCTP_DEBUG_OUTPUT3, "Deadlock avoided starting timer on a dest at retran\n");
   10290           0 :         if (asoc->alternate) {
   10291           0 :                 sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb, asoc->alternate);
   10292             :         } else {
   10293           0 :                 sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb, asoc->primary_destination);
   10294             :         }
   10295           0 :         return;
   10296             : }
   10297             : 
   10298             : void
   10299           0 : sctp_chunk_output (struct sctp_inpcb *inp,
   10300             :     struct sctp_tcb *stcb,
   10301             :     int from_where,
   10302             :     int so_locked
   10303             : #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
   10304             :     SCTP_UNUSED
   10305             : #endif
   10306             :     )
   10307             : {
   10308             :         /*-
   10309             :          * Ok this is the generic chunk service queue. we must do the
   10310             :          * following:
   10311             :          * - See if there are retransmits pending, if so we must
   10312             :          *   do these first.
   10313             :          * - Service the stream queue that is next, moving any
   10314             :          *   message (note I must get a complete message i.e.
   10315             :          *   FIRST/MIDDLE and LAST to the out queue in one pass) and assigning
   10316             :          *   TSN's
   10317             :          * - Check to see if the cwnd/rwnd allows any output, if so we
   10318             :          *   go ahead and fomulate and send the low level chunks. Making sure
   10319             :          *   to combine any control in the control chunk queue also.
   10320             :          */
   10321             :         struct sctp_association *asoc;
   10322             :         struct sctp_nets *net;
   10323           0 :         int error = 0, num_out, tot_out = 0, ret = 0, reason_code;
   10324           0 :         unsigned int burst_cnt = 0;
   10325             :         struct timeval now;
   10326           0 :         int now_filled = 0;
   10327             :         int nagle_on;
   10328           0 :         int frag_point = sctp_get_frag_point(stcb, &stcb->asoc);
   10329           0 :         int un_sent = 0;
   10330             :         int fr_done;
   10331           0 :         unsigned int tot_frs = 0;
   10332             : 
   10333             : #if defined(__APPLE__)
   10334             :         if (so_locked) {
   10335             :                 sctp_lock_assert(SCTP_INP_SO(inp));
   10336             :         } else {
   10337             :                 sctp_unlock_assert(SCTP_INP_SO(inp));
   10338             :         }
   10339             : #endif
   10340           0 :         asoc = &stcb->asoc;
   10341             :         /* The Nagle algorithm is only applied when handling a send call. */
   10342           0 :         if (from_where == SCTP_OUTPUT_FROM_USR_SEND) {
   10343           0 :                 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NODELAY)) {
   10344           0 :                         nagle_on = 0;
   10345             :                 } else {
   10346           0 :                         nagle_on = 1;
   10347             :                 }
   10348             :         } else {
   10349           0 :                 nagle_on = 0;
   10350             :         }
   10351             :         SCTP_TCB_LOCK_ASSERT(stcb);
   10352             : 
   10353           0 :         un_sent = (stcb->asoc.total_output_queue_size - stcb->asoc.total_flight);
   10354             : 
   10355           0 :         if ((un_sent <= 0) &&
   10356           0 :             (TAILQ_EMPTY(&asoc->control_send_queue)) &&
   10357           0 :             (TAILQ_EMPTY(&asoc->asconf_send_queue)) &&
   10358           0 :             (asoc->sent_queue_retran_cnt == 0)) {
   10359             :                 /* Nothing to do unless there is something to be sent left */
   10360           0 :                 return;
   10361             :         }
   10362             :         /* Do we have something to send, data or control AND
   10363             :          * a sack timer running, if so piggy-back the sack.
   10364             :          */
   10365           0 :         if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
   10366           0 :                 sctp_send_sack(stcb, so_locked);
   10367           0 :                 (void)SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer);
   10368             :         }
   10369           0 :         while (asoc->sent_queue_retran_cnt) {
   10370             :                 /*-
   10371             :                  * Ok, it is retransmission time only, we send out only ONE
   10372             :                  * packet with a single call off to the retran code.
   10373             :                  */
   10374           0 :                 if (from_where == SCTP_OUTPUT_FROM_COOKIE_ACK) {
   10375             :                         /*-
   10376             :                          * Special hook for handling cookiess discarded
   10377             :                          * by peer that carried data. Send cookie-ack only
   10378             :                          * and then the next call with get the retran's.
   10379             :                          */
   10380           0 :                         (void)sctp_med_chunk_output(inp, stcb, asoc, &num_out, &reason_code, 1,
   10381             :                                                     from_where,
   10382             :                                                     &now, &now_filled, frag_point, so_locked);
   10383           0 :                         return;
   10384           0 :                 } else if (from_where != SCTP_OUTPUT_FROM_HB_TMR) {
   10385             :                         /* if its not from a HB then do it */
   10386           0 :                         fr_done = 0;
   10387           0 :                         ret = sctp_chunk_retransmission(inp, stcb, asoc, &num_out, &now, &now_filled, &fr_done, so_locked);
   10388           0 :                         if (fr_done) {
   10389           0 :                                 tot_frs++;
   10390             :                         }
   10391             :                 } else {
   10392             :                         /*
   10393             :                          * its from any other place, we don't allow retran
   10394             :                          * output (only control)
   10395             :                          */
   10396           0 :                         ret = 1;
   10397             :                 }
   10398           0 :                 if (ret > 0) {
   10399             :                         /* Can't send anymore */
   10400             :                         /*-
   10401             :                          * now lets push out control by calling med-level
   10402             :                          * output once. this assures that we WILL send HB's
   10403             :                          * if queued too.
   10404             :                          */
   10405           0 :                         (void)sctp_med_chunk_output(inp, stcb, asoc, &num_out, &reason_code, 1,
   10406             :                                                     from_where,
   10407             :                                                     &now, &now_filled, frag_point, so_locked);
   10408             : #ifdef SCTP_AUDITING_ENABLED
   10409             :                         sctp_auditing(8, inp, stcb, NULL);
   10410             : #endif
   10411           0 :                         sctp_timer_validation(inp, stcb, asoc);
   10412           0 :                         return;
   10413             :                 }
   10414           0 :                 if (ret < 0) {
   10415             :                         /*-
   10416             :                          * The count was off.. retran is not happening so do
   10417             :                          * the normal retransmission.
   10418             :                          */
   10419             : #ifdef SCTP_AUDITING_ENABLED
   10420             :                         sctp_auditing(9, inp, stcb, NULL);
   10421             : #endif
   10422           0 :                         if (ret == SCTP_RETRAN_EXIT) {
   10423           0 :                                 return;
   10424             :                         }
   10425           0 :                         break;
   10426             :                 }
   10427           0 :                 if (from_where == SCTP_OUTPUT_FROM_T3) {
   10428             :                         /* Only one transmission allowed out of a timeout */
   10429             : #ifdef SCTP_AUDITING_ENABLED
   10430             :                         sctp_auditing(10, inp, stcb, NULL);
   10431             : #endif
   10432             :                         /* Push out any control */
   10433           0 :                         (void)sctp_med_chunk_output(inp, stcb, asoc, &num_out, &reason_code, 1, from_where,
   10434             :                                                     &now, &now_filled, frag_point, so_locked);
   10435           0 :                         return;
   10436             :                 }
   10437           0 :                 if ((asoc->fr_max_burst > 0) && (tot_frs >= asoc->fr_max_burst)) {
   10438             :                         /* Hit FR burst limit */
   10439           0 :                         return;
   10440             :                 }
   10441           0 :                 if ((num_out == 0) && (ret == 0)) {
   10442             :                         /* No more retrans to send */
   10443           0 :                         break;
   10444             :                 }
   10445             :         }
   10446             : #ifdef SCTP_AUDITING_ENABLED
   10447             :         sctp_auditing(12, inp, stcb, NULL);
   10448             : #endif
   10449             :         /* Check for bad destinations, if they exist move chunks around. */
   10450           0 :         TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
   10451           0 :                 if (!(net->dest_state & SCTP_ADDR_REACHABLE)) {
   10452             :                         /*-
   10453             :                          * if possible move things off of this address we
   10454             :                          * still may send below due to the dormant state but
   10455             :                          * we try to find an alternate address to send to
   10456             :                          * and if we have one we move all queued data on the
   10457             :                          * out wheel to this alternate address.
   10458             :                          */
   10459           0 :                         if (net->ref_count > 1)
   10460           0 :                                 sctp_move_chunks_from_net(stcb, net);
   10461             :                 } else {
   10462             :                         /*-
   10463             :                          * if ((asoc->sat_network) || (net->addr_is_local))
   10464             :                          * { burst_limit = asoc->max_burst *
   10465             :                          * SCTP_SAT_NETWORK_BURST_INCR; }
   10466             :                          */
   10467           0 :                         if (asoc->max_burst > 0) {
   10468           0 :                                 if (SCTP_BASE_SYSCTL(sctp_use_cwnd_based_maxburst)) {
   10469           0 :                                         if ((net->flight_size + (asoc->max_burst * net->mtu)) < net->cwnd) {
   10470             :                                                 /* JRS - Use the congestion control given in the congestion control module */
   10471           0 :                                                 asoc->cc_functions.sctp_cwnd_update_after_output(stcb, net, asoc->max_burst);
   10472           0 :                                                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOG_MAXBURST_ENABLE) {
   10473           0 :                                                         sctp_log_maxburst(stcb, net, 0, asoc->max_burst, SCTP_MAX_BURST_APPLIED);
   10474             :                                                 }
   10475           0 :                                                 SCTP_STAT_INCR(sctps_maxburstqueued);
   10476             :                                         }
   10477           0 :                                         net->fast_retran_ip = 0;
   10478             :                                 } else {
   10479           0 :                                         if (net->flight_size == 0) {
   10480             :                                                 /* Should be decaying the cwnd here */
   10481             :                                                 ;
   10482             :                                         }
   10483             :                                 }
   10484             :                         }
   10485             :                 }
   10486             : 
   10487             :         }
   10488           0 :         burst_cnt = 0;
   10489             :         do {
   10490           0 :                 error = sctp_med_chunk_output(inp, stcb, asoc, &num_out,
   10491             :                                               &reason_code, 0, from_where,
   10492             :                                               &now, &now_filled, frag_point, so_locked);
   10493           0 :                 if (error) {
   10494           0 :                         SCTPDBG(SCTP_DEBUG_OUTPUT1, "Error %d was returned from med-c-op\n", error);
   10495           0 :                         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOG_MAXBURST_ENABLE) {
   10496           0 :                                 sctp_log_maxburst(stcb, asoc->primary_destination, error, burst_cnt, SCTP_MAX_BURST_ERROR_STOP);
   10497             :                         }
   10498           0 :                         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) {
   10499           0 :                                 sctp_log_cwnd(stcb, NULL, error, SCTP_SEND_NOW_COMPLETES);
   10500           0 :                                 sctp_log_cwnd(stcb, NULL, 0xdeadbeef, SCTP_SEND_NOW_COMPLETES);
   10501             :                         }
   10502           0 :                         break;
   10503             :                 }
   10504           0 :                 SCTPDBG(SCTP_DEBUG_OUTPUT3, "m-c-o put out %d\n", num_out);
   10505             : 
   10506           0 :                 tot_out += num_out;
   10507           0 :                 burst_cnt++;
   10508           0 :                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) {
   10509           0 :                         sctp_log_cwnd(stcb, NULL, num_out, SCTP_SEND_NOW_COMPLETES);
   10510           0 :                         if (num_out == 0) {
   10511           0 :                                 sctp_log_cwnd(stcb, NULL, reason_code, SCTP_SEND_NOW_COMPLETES);
   10512             :                         }
   10513             :                 }
   10514           0 :                 if (nagle_on) {
   10515             :                         /*
   10516             :                          * When the Nagle algorithm is used, look at how much
   10517             :                          * is unsent, then if its smaller than an MTU and we
   10518             :                          * have data in flight we stop, except if we are
   10519             :                          * handling a fragmented user message.
   10520             :                          */
   10521           0 :                         un_sent = ((stcb->asoc.total_output_queue_size - stcb->asoc.total_flight) +
   10522           0 :                                    (stcb->asoc.stream_queue_cnt * sizeof(struct sctp_data_chunk)));
   10523           0 :                         if ((un_sent < (int)(stcb->asoc.smallest_mtu - SCTP_MIN_OVERHEAD)) &&
   10524           0 :                             (stcb->asoc.total_flight > 0) &&
   10525           0 :                             ((stcb->asoc.locked_on_sending == NULL) ||
   10526           0 :                              sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXPLICIT_EOR))) {
   10527             :                                 break;
   10528             :                         }
   10529             :                 }
   10530           0 :                 if (TAILQ_EMPTY(&asoc->control_send_queue) &&
   10531           0 :                     TAILQ_EMPTY(&asoc->send_queue) &&
   10532           0 :                     stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, asoc)) {
   10533             :                         /* Nothing left to send */
   10534           0 :                         break;
   10535             :                 }
   10536           0 :                 if ((stcb->asoc.total_output_queue_size - stcb->asoc.total_flight) <= 0) {
   10537             :                         /* Nothing left to send */
   10538           0 :                         break;
   10539             :                 }
   10540           0 :         } while (num_out &&
   10541           0 :                  ((asoc->max_burst == 0) ||
   10542           0 :                   SCTP_BASE_SYSCTL(sctp_use_cwnd_based_maxburst) ||
   10543           0 :                   (burst_cnt < asoc->max_burst)));
   10544             : 
   10545           0 :         if (SCTP_BASE_SYSCTL(sctp_use_cwnd_based_maxburst) == 0) {
   10546           0 :                 if ((asoc->max_burst > 0) && (burst_cnt >= asoc->max_burst)) {
   10547           0 :                         SCTP_STAT_INCR(sctps_maxburstqueued);
   10548           0 :                         asoc->burst_limit_applied = 1;
   10549           0 :                         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOG_MAXBURST_ENABLE) {
   10550           0 :                                 sctp_log_maxburst(stcb, asoc->primary_destination, 0, burst_cnt, SCTP_MAX_BURST_APPLIED);
   10551             :                         }
   10552             :                 } else {
   10553           0 :                         asoc->burst_limit_applied = 0;
   10554             :                 }
   10555             :         }
   10556           0 :         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) {
   10557           0 :                 sctp_log_cwnd(stcb, NULL, tot_out, SCTP_SEND_NOW_COMPLETES);
   10558             :         }
   10559           0 :         SCTPDBG(SCTP_DEBUG_OUTPUT1, "Ok, we have put out %d chunks\n",
   10560             :                 tot_out);
   10561             : 
   10562             :         /*-
   10563             :          * Now we need to clean up the control chunk chain if a ECNE is on
   10564             :          * it. It must be marked as UNSENT again so next call will continue
   10565             :          * to send it until such time that we get a CWR, to remove it.
   10566             :          */
   10567           0 :         if (stcb->asoc.ecn_echo_cnt_onq)
   10568           0 :                 sctp_fix_ecn_echo(asoc);
   10569           0 :         return;
   10570             : }
   10571             : 
   10572             : 
   10573             : int
   10574           0 : sctp_output(
   10575             :         struct sctp_inpcb *inp,
   10576             : #if defined(__Panda__)
   10577             :         pakhandle_type m,
   10578             : #else
   10579             :         struct mbuf *m,
   10580             : #endif
   10581             :         struct sockaddr *addr,
   10582             : #if defined(__Panda__)
   10583             :         pakhandle_type control,
   10584             : #else
   10585             :         struct mbuf *control,
   10586             : #endif
   10587             : #if defined(__FreeBSD__) && __FreeBSD_version >= 500000
   10588             :         struct thread *p,
   10589             : #elif defined(__Windows__)
   10590             :         PKTHREAD p,
   10591             : #else
   10592             : #if defined(__APPLE__)
   10593             :         struct proc *p SCTP_UNUSED,
   10594             : #else
   10595             :         struct proc *p,
   10596             : #endif
   10597             : #endif
   10598             :         int flags)
   10599             : {
   10600           0 :         if (inp == NULL) {
   10601             :                 SCTP_LTRACE_ERR_RET_PKT(m, inp, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, EINVAL);
   10602           0 :                 return (EINVAL);
   10603             :         }
   10604             : 
   10605           0 :         if (inp->sctp_socket == NULL) {
   10606             :                 SCTP_LTRACE_ERR_RET_PKT(m, inp, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, EINVAL);
   10607           0 :                 return (EINVAL);
   10608             :         }
   10609           0 :         return (sctp_sosend(inp->sctp_socket,
   10610             :                             addr,
   10611             :                             (struct uio *)NULL,
   10612             :                             m,
   10613             :                             control,
   10614             : #if defined(__APPLE__) || defined(__Panda__)
   10615             :                             flags
   10616             : #else
   10617             :                             flags, p
   10618             : #endif
   10619             :                         ));
   10620             : }
   10621             : 
   10622             : void
   10623           0 : send_forward_tsn(struct sctp_tcb *stcb,
   10624             :                  struct sctp_association *asoc)
   10625             : {
   10626             :         struct sctp_tmit_chunk *chk;
   10627             :         struct sctp_forward_tsn_chunk *fwdtsn;
   10628             :         uint32_t advance_peer_ack_point;
   10629             : 
   10630             :         SCTP_TCB_LOCK_ASSERT(stcb);
   10631           0 :         TAILQ_FOREACH(chk, &asoc->control_send_queue, sctp_next) {
   10632           0 :                 if (chk->rec.chunk_id.id == SCTP_FORWARD_CUM_TSN) {
   10633             :                         /* mark it to unsent */
   10634           0 :                         chk->sent = SCTP_DATAGRAM_UNSENT;
   10635           0 :                         chk->snd_count = 0;
   10636             :                         /* Do we correct its output location? */
   10637           0 :                         if (chk->whoTo) {
   10638           0 :                                 sctp_free_remote_addr(chk->whoTo);
   10639           0 :                                 chk->whoTo = NULL;
   10640             :                         }
   10641           0 :                         goto sctp_fill_in_rest;
   10642             :                 }
   10643             :         }
   10644             :         /* Ok if we reach here we must build one */
   10645           0 :         sctp_alloc_a_chunk(stcb, chk);
   10646           0 :         if (chk == NULL) {
   10647           0 :                 return;
   10648             :         }
   10649           0 :         asoc->fwd_tsn_cnt++;
   10650           0 :         chk->copy_by_ref = 0;
   10651           0 :         chk->rec.chunk_id.id = SCTP_FORWARD_CUM_TSN;
   10652           0 :         chk->rec.chunk_id.can_take_data = 0;
   10653           0 :         chk->flags = 0;
   10654           0 :         chk->asoc = asoc;
   10655           0 :         chk->whoTo = NULL;
   10656           0 :         chk->data = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_NOWAIT, 1, MT_DATA);
   10657           0 :         if (chk->data == NULL) {
   10658           0 :                 sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
   10659           0 :                 return;
   10660             :         }
   10661           0 :         SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD);
   10662           0 :         chk->sent = SCTP_DATAGRAM_UNSENT;
   10663           0 :         chk->snd_count = 0;
   10664           0 :         TAILQ_INSERT_TAIL(&asoc->control_send_queue, chk, sctp_next);
   10665           0 :         asoc->ctrl_queue_cnt++;
   10666             : sctp_fill_in_rest:
   10667             :         /*-
   10668             :          * Here we go through and fill out the part that deals with
   10669             :          * stream/seq of the ones we skip.
   10670             :          */
   10671           0 :         SCTP_BUF_LEN(chk->data) = 0;
   10672             :         {
   10673             :                 struct sctp_tmit_chunk *at, *tp1, *last;
   10674             :                 struct sctp_strseq *strseq;
   10675             :                 unsigned int cnt_of_space, i, ovh;
   10676             :                 unsigned int space_needed;
   10677           0 :                 unsigned int cnt_of_skipped = 0;
   10678             : 
   10679           0 :                 TAILQ_FOREACH(at, &asoc->sent_queue, sctp_next) {
   10680           0 :                         if ((at->sent != SCTP_FORWARD_TSN_SKIP) &&
   10681           0 :                             (at->sent != SCTP_DATAGRAM_NR_ACKED)) {
   10682             :                                 /* no more to look at */
   10683           0 :                                 break;
   10684             :                         }
   10685           0 :                         if (at->rec.data.rcv_flags & SCTP_DATA_UNORDERED) {
   10686             :                                 /* We don't report these */
   10687           0 :                                 continue;
   10688             :                         }
   10689           0 :                         cnt_of_skipped++;
   10690             :                 }
   10691           0 :                 space_needed = (sizeof(struct sctp_forward_tsn_chunk) +
   10692             :                     (cnt_of_skipped * sizeof(struct sctp_strseq)));
   10693             : 
   10694           0 :                 cnt_of_space = M_TRAILINGSPACE(chk->data);
   10695             : 
   10696           0 :                 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
   10697           0 :                         ovh = SCTP_MIN_OVERHEAD;
   10698             :                 } else {
   10699           0 :                         ovh = SCTP_MIN_V4_OVERHEAD;
   10700             :                 }
   10701           0 :                 if (cnt_of_space > (asoc->smallest_mtu - ovh)) {
   10702             :                         /* trim to a mtu size */
   10703           0 :                         cnt_of_space = asoc->smallest_mtu - ovh;
   10704             :                 }
   10705           0 :                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOG_TRY_ADVANCE) {
   10706           0 :                         sctp_misc_ints(SCTP_FWD_TSN_CHECK,
   10707             :                                        0xff, 0, cnt_of_skipped,
   10708             :                                        asoc->advanced_peer_ack_point);
   10709             : 
   10710             :                 }
   10711           0 :                 advance_peer_ack_point = asoc->advanced_peer_ack_point;
   10712           0 :                 if (cnt_of_space < space_needed) {
   10713             :                         /*-
   10714             :                          * ok we must trim down the chunk by lowering the
   10715             :                          * advance peer ack point.
   10716             :                          */
   10717           0 :                         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOG_TRY_ADVANCE) {
   10718           0 :                                 sctp_misc_ints(SCTP_FWD_TSN_CHECK,
   10719             :                                                0xff, 0xff, cnt_of_space,
   10720             :                                                space_needed);
   10721             :                         }
   10722           0 :                         cnt_of_skipped = cnt_of_space - sizeof(struct sctp_forward_tsn_chunk);
   10723           0 :                         cnt_of_skipped /= sizeof(struct sctp_strseq);
   10724             :                         /*-
   10725             :                          * Go through and find the TSN that will be the one
   10726             :                          * we report.
   10727             :                          */
   10728           0 :                         at = TAILQ_FIRST(&asoc->sent_queue);
   10729           0 :                         if (at != NULL) {
   10730           0 :                                 for (i = 0; i < cnt_of_skipped; i++) {
   10731           0 :                                         tp1 = TAILQ_NEXT(at, sctp_next);
   10732           0 :                                         if (tp1 == NULL) {
   10733           0 :                                                 break;
   10734             :                                         }
   10735           0 :                                         at = tp1;
   10736             :                                 }
   10737             :                         }
   10738           0 :                         if (at && SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOG_TRY_ADVANCE) {
   10739           0 :                                 sctp_misc_ints(SCTP_FWD_TSN_CHECK,
   10740             :                                                0xff, cnt_of_skipped, at->rec.data.TSN_seq,
   10741             :                                                asoc->advanced_peer_ack_point);
   10742             :                         }
   10743           0 :                         last = at;
   10744             :                         /*-
   10745             :                          * last now points to last one I can report, update
   10746             :                          * peer ack point
   10747             :                          */
   10748           0 :                         if (last)
   10749           0 :                                 advance_peer_ack_point = last->rec.data.TSN_seq;
   10750           0 :                         space_needed = sizeof(struct sctp_forward_tsn_chunk) +
   10751             :                                        cnt_of_skipped * sizeof(struct sctp_strseq);
   10752             :                 }
   10753           0 :                 chk->send_size = space_needed;
   10754             :                 /* Setup the chunk */
   10755           0 :                 fwdtsn = mtod(chk->data, struct sctp_forward_tsn_chunk *);
   10756           0 :                 fwdtsn->ch.chunk_length = htons(chk->send_size);
   10757           0 :                 fwdtsn->ch.chunk_flags = 0;
   10758           0 :                 fwdtsn->ch.chunk_type = SCTP_FORWARD_CUM_TSN;
   10759           0 :                 fwdtsn->new_cumulative_tsn = htonl(advance_peer_ack_point);
   10760           0 :                 SCTP_BUF_LEN(chk->data) = chk->send_size;
   10761           0 :                 fwdtsn++;
   10762             :                 /*-
   10763             :                  * Move pointer to after the fwdtsn and transfer to the
   10764             :                  * strseq pointer.
   10765             :                  */
   10766           0 :                 strseq = (struct sctp_strseq *)fwdtsn;
   10767             :                 /*-
   10768             :                  * Now populate the strseq list. This is done blindly
   10769             :                  * without pulling out duplicate stream info. This is
   10770             :                  * inefficent but won't harm the process since the peer will
   10771             :                  * look at these in sequence and will thus release anything.
   10772             :                  * It could mean we exceed the PMTU and chop off some that
   10773             :                  * we could have included.. but this is unlikely (aka 1432/4
   10774             :                  * would mean 300+ stream seq's would have to be reported in
   10775             :                  * one FWD-TSN. With a bit of work we can later FIX this to
   10776             :                  * optimize and pull out duplcates.. but it does add more
   10777             :                  * overhead. So for now... not!
   10778             :                  */
   10779           0 :                 at = TAILQ_FIRST(&asoc->sent_queue);
   10780           0 :                 for (i = 0; i < cnt_of_skipped; i++) {
   10781           0 :                         tp1 = TAILQ_NEXT(at, sctp_next);
   10782           0 :                         if (tp1 == NULL)
   10783           0 :                                 break;
   10784           0 :                         if (at->rec.data.rcv_flags & SCTP_DATA_UNORDERED) {
   10785             :                                 /* We don't report these */
   10786           0 :                                 i--;
   10787           0 :                                 at = tp1;
   10788           0 :                                 continue;
   10789             :                         }
   10790           0 :                         if (at->rec.data.TSN_seq == advance_peer_ack_point) {
   10791           0 :                                 at->rec.data.fwd_tsn_cnt = 0;
   10792             :                         }
   10793           0 :                         strseq->stream = ntohs(at->rec.data.stream_number);
   10794           0 :                         strseq->sequence = ntohs(at->rec.data.stream_seq);
   10795           0 :                         strseq++;
   10796           0 :                         at = tp1;
   10797             :                 }
   10798             :         }
   10799           0 :         return;
   10800             : }
   10801             : 
   10802             : void
   10803           0 : sctp_send_sack(struct sctp_tcb *stcb, int so_locked
   10804             : #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
   10805             :         SCTP_UNUSED
   10806             : #endif
   10807             : )
   10808             : {
   10809             :         /*-
   10810             :          * Queue up a SACK or NR-SACK in the control queue.
   10811             :          * We must first check to see if a SACK or NR-SACK is
   10812             :          * somehow on the control queue.
   10813             :          * If so, we will take and and remove the old one.
   10814             :          */
   10815             :         struct sctp_association *asoc;
   10816             :         struct sctp_tmit_chunk *chk, *a_chk;
   10817             :         struct sctp_sack_chunk *sack;
   10818             :         struct sctp_nr_sack_chunk *nr_sack;
   10819             :         struct sctp_gap_ack_block *gap_descriptor;
   10820             :         struct sack_track *selector;
   10821           0 :         int mergeable = 0;
   10822             :         int offset;
   10823             :         caddr_t limit;
   10824             :         uint32_t *dup;
   10825           0 :         int limit_reached = 0;
   10826             :         unsigned int i, siz, j;
   10827           0 :         unsigned int num_gap_blocks = 0, num_nr_gap_blocks = 0, space;
   10828           0 :         int num_dups = 0;
   10829             :         int space_req;
   10830             :         uint32_t highest_tsn;
   10831             :         uint8_t flags;
   10832             :         uint8_t type;
   10833             :         uint8_t tsn_map;
   10834             : 
   10835           0 :         if (stcb->asoc.nrsack_supported == 1) {
   10836           0 :                 type = SCTP_NR_SELECTIVE_ACK;
   10837             :         } else {
   10838           0 :                 type = SCTP_SELECTIVE_ACK;
   10839             :         }
   10840           0 :         a_chk = NULL;
   10841           0 :         asoc = &stcb->asoc;
   10842             :         SCTP_TCB_LOCK_ASSERT(stcb);
   10843           0 :         if (asoc->last_data_chunk_from == NULL) {
   10844             :                 /* Hmm we never received anything */
   10845           0 :                 return;
   10846             :         }
   10847           0 :         sctp_slide_mapping_arrays(stcb);
   10848           0 :         sctp_set_rwnd(stcb, asoc);
   10849           0 :         TAILQ_FOREACH(chk, &asoc->control_send_queue, sctp_next) {
   10850           0 :                 if (chk->rec.chunk_id.id == type) {
   10851             :                         /* Hmm, found a sack already on queue, remove it */
   10852           0 :                         TAILQ_REMOVE(&asoc->control_send_queue, chk, sctp_next);
   10853           0 :                         asoc->ctrl_queue_cnt--;
   10854           0 :                         a_chk = chk;
   10855           0 :                         if (a_chk->data) {
   10856           0 :                                 sctp_m_freem(a_chk->data);
   10857           0 :                                 a_chk->data = NULL;
   10858             :                         }
   10859           0 :                         if (a_chk->whoTo) {
   10860           0 :                                 sctp_free_remote_addr(a_chk->whoTo);
   10861           0 :                                 a_chk->whoTo = NULL;
   10862             :                         }
   10863           0 :                         break;
   10864             :                 }
   10865             :         }
   10866           0 :         if (a_chk == NULL) {
   10867           0 :                 sctp_alloc_a_chunk(stcb, a_chk);
   10868           0 :                 if (a_chk == NULL) {
   10869             :                         /* No memory so we drop the idea, and set a timer */
   10870           0 :                         if (stcb->asoc.delayed_ack) {
   10871           0 :                                 sctp_timer_stop(SCTP_TIMER_TYPE_RECV,
   10872             :                                     stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_5);
   10873           0 :                                 sctp_timer_start(SCTP_TIMER_TYPE_RECV,
   10874             :                                     stcb->sctp_ep, stcb, NULL);
   10875             :                         } else {
   10876           0 :                                 stcb->asoc.send_sack = 1;
   10877             :                         }
   10878           0 :                         return;
   10879             :                 }
   10880           0 :                 a_chk->copy_by_ref = 0;
   10881           0 :                 a_chk->rec.chunk_id.id = type;
   10882           0 :                 a_chk->rec.chunk_id.can_take_data = 1;
   10883             :         }
   10884             :         /* Clear our pkt counts */
   10885           0 :         asoc->data_pkts_seen = 0;
   10886             : 
   10887           0 :         a_chk->flags = 0;
   10888           0 :         a_chk->asoc = asoc;
   10889           0 :         a_chk->snd_count = 0;
   10890           0 :         a_chk->send_size = 0;        /* fill in later */
   10891           0 :         a_chk->sent = SCTP_DATAGRAM_UNSENT;
   10892           0 :         a_chk->whoTo = NULL;
   10893             : 
   10894           0 :         if ((asoc->numduptsns) ||
   10895           0 :             (!(asoc->last_data_chunk_from->dest_state & SCTP_ADDR_REACHABLE))) {
   10896             :                 /*-
   10897             :                  * Ok, we have some duplicates or the destination for the
   10898             :                  * sack is unreachable, lets see if we can select an
   10899             :                  * alternate than asoc->last_data_chunk_from
   10900             :                  */
   10901           0 :                 if ((asoc->last_data_chunk_from->dest_state & SCTP_ADDR_REACHABLE) &&
   10902           0 :                     (asoc->used_alt_onsack > asoc->numnets)) {
   10903             :                         /* We used an alt last time, don't this time */
   10904           0 :                         a_chk->whoTo = NULL;
   10905             :                 } else {
   10906           0 :                         asoc->used_alt_onsack++;
   10907           0 :                         a_chk->whoTo = sctp_find_alternate_net(stcb, asoc->last_data_chunk_from, 0);
   10908             :                 }
   10909           0 :                 if (a_chk->whoTo == NULL) {
   10910             :                         /* Nope, no alternate */
   10911           0 :                         a_chk->whoTo = asoc->last_data_chunk_from;
   10912           0 :                         asoc->used_alt_onsack = 0;
   10913             :                 }
   10914             :         } else {
   10915             :                 /*
   10916             :                  * No duplicates so we use the last place we received data
   10917             :                  * from.
   10918             :                  */
   10919           0 :                 asoc->used_alt_onsack = 0;
   10920           0 :                 a_chk->whoTo = asoc->last_data_chunk_from;
   10921             :         }
   10922           0 :         if (a_chk->whoTo) {
   10923           0 :                 atomic_add_int(&a_chk->whoTo->ref_count, 1);
   10924             :         }
   10925           0 :         if (SCTP_TSN_GT(asoc->highest_tsn_inside_map, asoc->highest_tsn_inside_nr_map)) {
   10926           0 :                 highest_tsn = asoc->highest_tsn_inside_map;
   10927             :         } else {
   10928           0 :                 highest_tsn = asoc->highest_tsn_inside_nr_map;
   10929             :         }
   10930           0 :         if (highest_tsn == asoc->cumulative_tsn) {
   10931             :                 /* no gaps */
   10932           0 :                 if (type == SCTP_SELECTIVE_ACK) {
   10933           0 :                         space_req = sizeof(struct sctp_sack_chunk);
   10934             :                 } else {
   10935           0 :                         space_req = sizeof(struct sctp_nr_sack_chunk);
   10936             :                 }
   10937             :         } else {
   10938             :                 /* gaps get a cluster */
   10939           0 :                 space_req = MCLBYTES;
   10940             :         }
   10941             :         /* Ok now lets formulate a MBUF with our sack */
   10942           0 :         a_chk->data = sctp_get_mbuf_for_msg(space_req, 0, M_NOWAIT, 1, MT_DATA);
   10943           0 :         if ((a_chk->data == NULL) ||
   10944           0 :             (a_chk->whoTo == NULL)) {
   10945             :                 /* rats, no mbuf memory */
   10946           0 :                 if (a_chk->data) {
   10947             :                         /* was a problem with the destination */
   10948           0 :                         sctp_m_freem(a_chk->data);
   10949           0 :                         a_chk->data = NULL;
   10950             :                 }
   10951           0 :                 sctp_free_a_chunk(stcb, a_chk, so_locked);
   10952             :                 /* sa_ignore NO_NULL_CHK */
   10953           0 :                 if (stcb->asoc.delayed_ack) {
   10954           0 :                         sctp_timer_stop(SCTP_TIMER_TYPE_RECV,
   10955             :                             stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_6);
   10956           0 :                         sctp_timer_start(SCTP_TIMER_TYPE_RECV,
   10957             :                             stcb->sctp_ep, stcb, NULL);
   10958             :                 } else {
   10959           0 :                         stcb->asoc.send_sack = 1;
   10960             :                 }
   10961           0 :                 return;
   10962             :         }
   10963             :         /* ok, lets go through and fill it in */
   10964           0 :         SCTP_BUF_RESV_UF(a_chk->data, SCTP_MIN_OVERHEAD);
   10965           0 :         space = M_TRAILINGSPACE(a_chk->data);
   10966           0 :         if (space > (a_chk->whoTo->mtu - SCTP_MIN_OVERHEAD)) {
   10967           0 :                 space = (a_chk->whoTo->mtu - SCTP_MIN_OVERHEAD);
   10968             :         }
   10969           0 :         limit = mtod(a_chk->data, caddr_t);
   10970           0 :         limit += space;
   10971             : 
   10972           0 :         flags = 0;
   10973             : 
   10974           0 :         if ((asoc->sctp_cmt_on_off > 0) &&
   10975           0 :             SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) {
   10976             :                 /*-
   10977             :                  * CMT DAC algorithm: If 2 (i.e., 0x10) packets have been
   10978             :                  * received, then set high bit to 1, else 0. Reset
   10979             :                  * pkts_rcvd.
   10980             :                  */
   10981           0 :                 flags |= (asoc->cmt_dac_pkts_rcvd << 6);
   10982           0 :                 asoc->cmt_dac_pkts_rcvd = 0;
   10983             :         }
   10984             : #ifdef SCTP_ASOCLOG_OF_TSNS
   10985             :         stcb->asoc.cumack_logsnt[stcb->asoc.cumack_log_atsnt] = asoc->cumulative_tsn;
   10986             :         stcb->asoc.cumack_log_atsnt++;
   10987             :         if (stcb->asoc.cumack_log_atsnt >= SCTP_TSN_LOG_SIZE) {
   10988             :                 stcb->asoc.cumack_log_atsnt = 0;
   10989             :         }
   10990             : #endif
   10991             :         /* reset the readers interpretation */
   10992           0 :         stcb->freed_by_sorcv_sincelast = 0;
   10993             : 
   10994           0 :         if (type == SCTP_SELECTIVE_ACK) {
   10995           0 :                 sack = mtod(a_chk->data, struct sctp_sack_chunk *);
   10996           0 :                 nr_sack = NULL;
   10997           0 :                 gap_descriptor = (struct sctp_gap_ack_block *)((caddr_t)sack + sizeof(struct sctp_sack_chunk));
   10998           0 :                 if (highest_tsn > asoc->mapping_array_base_tsn) {
   10999           0 :                         siz = (((highest_tsn - asoc->mapping_array_base_tsn) + 1) + 7) / 8;
   11000             :                 } else {
   11001           0 :                         siz = (((MAX_TSN - highest_tsn) + 1) + highest_tsn + 7) / 8;
   11002             :                 }
   11003             :         } else {
   11004           0 :                 sack = NULL;
   11005           0 :                 nr_sack = mtod(a_chk->data, struct sctp_nr_sack_chunk *);
   11006           0 :                 gap_descriptor = (struct sctp_gap_ack_block *)((caddr_t)nr_sack + sizeof(struct sctp_nr_sack_chunk));
   11007           0 :                 if (asoc->highest_tsn_inside_map > asoc->mapping_array_base_tsn) {
   11008           0 :                         siz = (((asoc->highest_tsn_inside_map - asoc->mapping_array_base_tsn) + 1) + 7) / 8;
   11009             :                 } else {
   11010           0 :                         siz = (((MAX_TSN - asoc->mapping_array_base_tsn) + 1) + asoc->highest_tsn_inside_map + 7) / 8;
   11011             :                 }
   11012             :         }
   11013             : 
   11014           0 :         if (SCTP_TSN_GT(asoc->mapping_array_base_tsn, asoc->cumulative_tsn)) {
   11015           0 :                 offset = 1;
   11016             :         } else {
   11017           0 :                 offset = asoc->mapping_array_base_tsn - asoc->cumulative_tsn;
   11018             :         }
   11019           0 :         if (((type == SCTP_SELECTIVE_ACK) &&
   11020           0 :              SCTP_TSN_GT(highest_tsn, asoc->cumulative_tsn)) ||
   11021           0 :             ((type == SCTP_NR_SELECTIVE_ACK) &&
   11022           0 :              SCTP_TSN_GT(asoc->highest_tsn_inside_map, asoc->cumulative_tsn))) {
   11023             :                 /* we have a gap .. maybe */
   11024           0 :                 for (i = 0; i < siz; i++) {
   11025           0 :                         tsn_map = asoc->mapping_array[i];
   11026           0 :                         if (type == SCTP_SELECTIVE_ACK) {
   11027           0 :                                 tsn_map |= asoc->nr_mapping_array[i];
   11028             :                         }
   11029           0 :                         if (i == 0) {
   11030             :                                 /*
   11031             :                                  * Clear all bits corresponding to TSNs
   11032             :                                  * smaller or equal to the cumulative TSN.
   11033             :                                  */
   11034           0 :                                 tsn_map &= (~0 << (1 - offset));
   11035             :                         }
   11036           0 :                         selector = &sack_array[tsn_map];
   11037           0 :                         if (mergeable && selector->right_edge) {
   11038             :                                 /*
   11039             :                                  * Backup, left and right edges were ok to
   11040             :                                  * merge.
   11041             :                                  */
   11042           0 :                                 num_gap_blocks--;
   11043           0 :                                 gap_descriptor--;
   11044             :                         }
   11045           0 :                         if (selector->num_entries == 0)
   11046           0 :                                 mergeable = 0;
   11047             :                         else {
   11048           0 :                                 for (j = 0; j < selector->num_entries; j++) {
   11049           0 :                                         if (mergeable && selector->right_edge) {
   11050             :                                                 /*
   11051             :                                                  * do a merge by NOT setting
   11052             :                                                  * the left side
   11053             :                                                  */
   11054           0 :                                                 mergeable = 0;
   11055             :                                         } else {
   11056             :                                                 /*
   11057             :                                                  * no merge, set the left
   11058             :                                                  * side
   11059             :                                                  */
   11060           0 :                                                 mergeable = 0;
   11061           0 :                                                 gap_descriptor->start = htons((selector->gaps[j].start + offset));
   11062             :                                         }
   11063           0 :                                         gap_descriptor->end = htons((selector->gaps[j].end + offset));
   11064           0 :                                         num_gap_blocks++;
   11065           0 :                                         gap_descriptor++;
   11066           0 :                                         if (((caddr_t)gap_descriptor + sizeof(struct sctp_gap_ack_block)) > limit) {
   11067             :                                                 /* no more room */
   11068           0 :                                                 limit_reached = 1;
   11069           0 :                                                 break;
   11070             :                                         }
   11071             :                                 }
   11072           0 :                                 if (selector->left_edge) {
   11073           0 :                                         mergeable = 1;
   11074             :                                 }
   11075             :                         }
   11076           0 :                         if (limit_reached) {
   11077             :                                 /* Reached the limit stop */
   11078           0 :                                 break;
   11079             :                         }
   11080           0 :                         offset += 8;
   11081             :                 }
   11082             :         }
   11083           0 :         if ((type == SCTP_NR_SELECTIVE_ACK) &&
   11084             :             (limit_reached == 0)) {
   11085             : 
   11086           0 :                 mergeable = 0;
   11087             : 
   11088           0 :                 if (asoc->highest_tsn_inside_nr_map > asoc->mapping_array_base_tsn) {
   11089           0 :                         siz = (((asoc->highest_tsn_inside_nr_map - asoc->mapping_array_base_tsn) + 1) + 7) / 8;
   11090             :                 } else {
   11091           0 :                         siz = (((MAX_TSN - asoc->mapping_array_base_tsn) + 1) + asoc->highest_tsn_inside_nr_map + 7) / 8;
   11092             :                 }
   11093             : 
   11094           0 :                 if (SCTP_TSN_GT(asoc->mapping_array_base_tsn, asoc->cumulative_tsn)) {
   11095           0 :                         offset = 1;
   11096             :                 } else {
   11097           0 :                         offset = asoc->mapping_array_base_tsn - asoc->cumulative_tsn;
   11098             :                 }
   11099           0 :                 if (SCTP_TSN_GT(asoc->highest_tsn_inside_nr_map, asoc->cumulative_tsn)) {
   11100             :                         /* we have a gap .. maybe */
   11101           0 :                         for (i = 0; i < siz; i++) {
   11102           0 :                                 tsn_map = asoc->nr_mapping_array[i];
   11103           0 :                                 if (i == 0) {
   11104             :                                         /*
   11105             :                                          * Clear all bits corresponding to TSNs
   11106             :                                          * smaller or equal to the cumulative TSN.
   11107             :                                          */
   11108           0 :                                         tsn_map &= (~0 << (1 - offset));
   11109             :                                 }
   11110           0 :                                 selector = &sack_array[tsn_map];
   11111           0 :                                 if (mergeable && selector->right_edge) {
   11112             :                                         /*
   11113             :                                         * Backup, left and right edges were ok to
   11114             :                                         * merge.
   11115             :                                         */
   11116           0 :                                         num_nr_gap_blocks--;
   11117           0 :                                         gap_descriptor--;
   11118             :                                 }
   11119           0 :                                 if (selector->num_entries == 0)
   11120           0 :                                         mergeable = 0;
   11121             :                                 else {
   11122           0 :                                         for (j = 0; j < selector->num_entries; j++) {
   11123           0 :                                                 if (mergeable && selector->right_edge) {
   11124             :                                                         /*
   11125             :                                                         * do a merge by NOT setting
   11126             :                                                         * the left side
   11127             :                                                         */
   11128           0 :                                                         mergeable = 0;
   11129             :                                                 } else {
   11130             :                                                         /*
   11131             :                                                         * no merge, set the left
   11132             :                                                         * side
   11133             :                                                         */
   11134           0 :                                                         mergeable = 0;
   11135           0 :                                                         gap_descriptor->start = htons((selector->gaps[j].start + offset));
   11136             :                                                 }
   11137           0 :                                                 gap_descriptor->end = htons((selector->gaps[j].end + offset));
   11138           0 :                                                 num_nr_gap_blocks++;
   11139           0 :                                                 gap_descriptor++;
   11140           0 :                                                 if (((caddr_t)gap_descriptor + sizeof(struct sctp_gap_ack_block)) > limit) {
   11141             :                                                         /* no more room */
   11142           0 :                                                         limit_reached = 1;
   11143           0 :                                                         break;
   11144             :                                                 }
   11145             :                                         }
   11146           0 :                                         if (selector->left_edge) {
   11147           0 :                                                 mergeable = 1;
   11148             :                                         }
   11149             :                                 }
   11150           0 :                                 if (limit_reached) {
   11151             :                                         /* Reached the limit stop */
   11152           0 :                                         break;
   11153             :                                 }
   11154           0 :                                 offset += 8;
   11155             :                         }
   11156             :                 }
   11157             :         }
   11158             :         /* now we must add any dups we are going to report. */
   11159           0 :         if ((limit_reached == 0) && (asoc->numduptsns)) {
   11160           0 :                 dup = (uint32_t *) gap_descriptor;
   11161           0 :                 for (i = 0; i < asoc->numduptsns; i++) {
   11162           0 :                         *dup = htonl(asoc->dup_tsns[i]);
   11163           0 :                         dup++;
   11164           0 :                         num_dups++;
   11165           0 :                         if (((caddr_t)dup + sizeof(uint32_t)) > limit) {
   11166             :                                 /* no more room */
   11167           0 :                                 break;
   11168             :                         }
   11169             :                 }
   11170           0 :                 asoc->numduptsns = 0;
   11171             :         }
   11172             :         /*
   11173             :          * now that the chunk is prepared queue it to the control chunk
   11174             :          * queue.
   11175             :          */
   11176           0 :         if (type == SCTP_SELECTIVE_ACK) {
   11177           0 :                 a_chk->send_size = sizeof(struct sctp_sack_chunk) +
   11178           0 :                                    (num_gap_blocks + num_nr_gap_blocks) * sizeof(struct sctp_gap_ack_block) +
   11179             :                                    num_dups * sizeof(int32_t);
   11180           0 :                 SCTP_BUF_LEN(a_chk->data) = a_chk->send_size;
   11181           0 :                 sack->sack.cum_tsn_ack = htonl(asoc->cumulative_tsn);
   11182           0 :                 sack->sack.a_rwnd = htonl(asoc->my_rwnd);
   11183           0 :                 sack->sack.num_gap_ack_blks = htons(num_gap_blocks);
   11184           0 :                 sack->sack.num_dup_tsns = htons(num_dups);
   11185           0 :                 sack->ch.chunk_type = type;
   11186           0 :                 sack->ch.chunk_flags = flags;
   11187           0 :                 sack->ch.chunk_length = htons(a_chk->send_size);
   11188             :         } else {
   11189           0 :                 a_chk->send_size = sizeof(struct sctp_nr_sack_chunk) +
   11190           0 :                                    (num_gap_blocks + num_nr_gap_blocks) * sizeof(struct sctp_gap_ack_block) +
   11191             :                                    num_dups * sizeof(int32_t);
   11192           0 :                 SCTP_BUF_LEN(a_chk->data) = a_chk->send_size;
   11193           0 :                 nr_sack->nr_sack.cum_tsn_ack = htonl(asoc->cumulative_tsn);
   11194           0 :                 nr_sack->nr_sack.a_rwnd = htonl(asoc->my_rwnd);
   11195           0 :                 nr_sack->nr_sack.num_gap_ack_blks = htons(num_gap_blocks);
   11196           0 :                 nr_sack->nr_sack.num_nr_gap_ack_blks = htons(num_nr_gap_blocks);
   11197           0 :                 nr_sack->nr_sack.num_dup_tsns = htons(num_dups);
   11198           0 :                 nr_sack->nr_sack.reserved = 0;
   11199           0 :                 nr_sack->ch.chunk_type = type;
   11200           0 :                 nr_sack->ch.chunk_flags = flags;
   11201           0 :                 nr_sack->ch.chunk_length = htons(a_chk->send_size);
   11202             :         }
   11203           0 :         TAILQ_INSERT_TAIL(&asoc->control_send_queue, a_chk, sctp_next);
   11204           0 :         asoc->my_last_reported_rwnd = asoc->my_rwnd;
   11205           0 :         asoc->ctrl_queue_cnt++;
   11206           0 :         asoc->send_sack = 0;
   11207           0 :         SCTP_STAT_INCR(sctps_sendsacks);
   11208           0 :         return;
   11209             : }
   11210             : 
   11211             : void
   11212           0 : sctp_send_abort_tcb(struct sctp_tcb *stcb, struct mbuf *operr, int so_locked
   11213             : #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
   11214             :     SCTP_UNUSED
   11215             : #endif
   11216             :     )
   11217             : {
   11218             :         struct mbuf *m_abort, *m, *m_last;
   11219           0 :         struct mbuf *m_out, *m_end = NULL;
   11220             :         struct sctp_abort_chunk *abort;
   11221           0 :         struct sctp_auth_chunk *auth = NULL;
   11222             :         struct sctp_nets *net;
   11223             :         uint32_t vtag;
   11224           0 :         uint32_t auth_offset = 0;
   11225             :         uint16_t cause_len, chunk_len, padding_len;
   11226             : 
   11227             : #if defined(__APPLE__)
   11228             :         if (so_locked) {
   11229             :                 sctp_lock_assert(SCTP_INP_SO(stcb->sctp_ep));
   11230             :         } else {
   11231             :                 sctp_unlock_assert(SCTP_INP_SO(stcb->sctp_ep));
   11232             :         }
   11233             : #endif
   11234             :         SCTP_TCB_LOCK_ASSERT(stcb);
   11235             :         /*-
   11236             :          * Add an AUTH chunk, if chunk requires it and save the offset into
   11237             :          * the chain for AUTH
   11238             :          */
   11239           0 :         if (sctp_auth_is_required_chunk(SCTP_ABORT_ASSOCIATION,
   11240             :                                         stcb->asoc.peer_auth_chunks)) {
   11241           0 :                 m_out = sctp_add_auth_chunk(NULL, &m_end, &auth, &auth_offset,
   11242             :                                             stcb, SCTP_ABORT_ASSOCIATION);
   11243           0 :                 SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks);
   11244             :         } else {
   11245           0 :                 m_out = NULL;
   11246             :         }
   11247           0 :         m_abort = sctp_get_mbuf_for_msg(sizeof(struct sctp_abort_chunk), 0, M_NOWAIT, 1, MT_HEADER);
   11248           0 :         if (m_abort == NULL) {
   11249           0 :                 if (m_out) {
   11250           0 :                         sctp_m_freem(m_out);
   11251             :                 }
   11252           0 :                 if (operr) {
   11253           0 :                         sctp_m_freem(operr);
   11254             :                 }
   11255           0 :                 return;
   11256             :         }
   11257             :         /* link in any error */
   11258           0 :         SCTP_BUF_NEXT(m_abort) = operr;
   11259           0 :         cause_len = 0;
   11260           0 :         m_last = NULL;
   11261           0 :         for (m = operr; m; m = SCTP_BUF_NEXT(m)) {
   11262           0 :                 cause_len += (uint16_t)SCTP_BUF_LEN(m);
   11263           0 :                 if (SCTP_BUF_NEXT(m) == NULL) {
   11264           0 :                         m_last = m;
   11265             :                 }
   11266             :         }
   11267           0 :         SCTP_BUF_LEN(m_abort) = sizeof(struct sctp_abort_chunk);
   11268           0 :         chunk_len = (uint16_t)sizeof(struct sctp_abort_chunk) + cause_len;
   11269           0 :         padding_len = SCTP_SIZE32(chunk_len) - chunk_len;
   11270           0 :         if (m_out == NULL) {
   11271             :                 /* NO Auth chunk prepended, so reserve space in front */
   11272           0 :                 SCTP_BUF_RESV_UF(m_abort, SCTP_MIN_OVERHEAD);
   11273           0 :                 m_out = m_abort;
   11274             :         } else {
   11275             :                 /* Put AUTH chunk at the front of the chain */
   11276           0 :                 SCTP_BUF_NEXT(m_end) = m_abort;
   11277             :         }
   11278           0 :         if (stcb->asoc.alternate) {
   11279           0 :                 net = stcb->asoc.alternate;
   11280             :         } else {
   11281           0 :                 net = stcb->asoc.primary_destination;
   11282             :         }
   11283             :         /* Fill in the ABORT chunk header. */
   11284           0 :         abort = mtod(m_abort, struct sctp_abort_chunk *);
   11285           0 :         abort->ch.chunk_type = SCTP_ABORT_ASSOCIATION;
   11286           0 :         if (stcb->asoc.peer_vtag == 0) {
   11287             :                 /* This happens iff the assoc is in COOKIE-WAIT state. */
   11288           0 :                 vtag = stcb->asoc.my_vtag;
   11289           0 :                 abort->ch.chunk_flags = SCTP_HAD_NO_TCB;
   11290             :         } else {
   11291           0 :                 vtag = stcb->asoc.peer_vtag;
   11292           0 :                 abort->ch.chunk_flags = 0;
   11293             :         }
   11294           0 :         abort->ch.chunk_length = htons(chunk_len);
   11295             :         /* Add padding, if necessary. */
   11296           0 :         if (padding_len > 0) {
   11297           0 :                 if ((m_last == NULL) ||
   11298           0 :                     (sctp_add_pad_tombuf(m_last, padding_len) == NULL)) {
   11299           0 :                         sctp_m_freem(m_out);
   11300           0 :                         return;
   11301             :                 }
   11302             :         }
   11303           0 :         (void)sctp_lowlevel_chunk_output(stcb->sctp_ep, stcb, net,
   11304           0 :                                          (struct sockaddr *)&net->ro._l_addr,
   11305           0 :                                          m_out, auth_offset, auth, stcb->asoc.authinfo.active_keyid, 1, 0, 0,
   11306           0 :                                          stcb->sctp_ep->sctp_lport, stcb->rport, htonl(vtag),
   11307           0 :                                          stcb->asoc.primary_destination->port, NULL,
   11308             : #if defined(__FreeBSD__)
   11309             :                                          0, 0,
   11310             : #endif
   11311             :                                          so_locked);
   11312           0 :         SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks);
   11313             : }
   11314             : 
   11315             : void
   11316           0 : sctp_send_shutdown_complete(struct sctp_tcb *stcb,
   11317             :                             struct sctp_nets *net,
   11318             :                             int reflect_vtag)
   11319             : {
   11320             :         /* formulate and SEND a SHUTDOWN-COMPLETE */
   11321             :         struct mbuf *m_shutdown_comp;
   11322             :         struct sctp_shutdown_complete_chunk *shutdown_complete;
   11323             :         uint32_t vtag;
   11324             :         uint8_t flags;
   11325             : 
   11326           0 :         m_shutdown_comp = sctp_get_mbuf_for_msg(sizeof(struct sctp_chunkhdr), 0, M_NOWAIT, 1, MT_HEADER);
   11327           0 :         if (m_shutdown_comp == NULL) {
   11328             :                 /* no mbuf's */
   11329           0 :                 return;
   11330             :         }
   11331           0 :         if (reflect_vtag) {
   11332           0 :                 flags = SCTP_HAD_NO_TCB;
   11333           0 :                 vtag = stcb->asoc.my_vtag;
   11334             :         } else {
   11335           0 :                 flags = 0;
   11336           0 :                 vtag = stcb->asoc.peer_vtag;
   11337             :         }
   11338           0 :         shutdown_complete = mtod(m_shutdown_comp, struct sctp_shutdown_complete_chunk *);
   11339           0 :         shutdown_complete->ch.chunk_type = SCTP_SHUTDOWN_COMPLETE;
   11340           0 :         shutdown_complete->ch.chunk_flags = flags;
   11341           0 :         shutdown_complete->ch.chunk_length = htons(sizeof(struct sctp_shutdown_complete_chunk));
   11342           0 :         SCTP_BUF_LEN(m_shutdown_comp) = sizeof(struct sctp_shutdown_complete_chunk);
   11343           0 :         (void)sctp_lowlevel_chunk_output(stcb->sctp_ep, stcb, net,
   11344           0 :                                          (struct sockaddr *)&net->ro._l_addr,
   11345             :                                          m_shutdown_comp, 0, NULL, 0, 1, 0, 0,
   11346           0 :                                          stcb->sctp_ep->sctp_lport, stcb->rport,
   11347             :                                          htonl(vtag),
   11348           0 :                                          net->port, NULL,
   11349             : #if defined(__FreeBSD__)
   11350             :                                          0, 0,
   11351             : #endif
   11352             :                                          SCTP_SO_NOT_LOCKED);
   11353           0 :         SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks);
   11354           0 :         return;
   11355             : }
   11356             : 
   11357             : #if defined(__FreeBSD__)
   11358             : static void
   11359             : sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst,
   11360             :                    struct sctphdr *sh, uint32_t vtag,
   11361             :                    uint8_t type, struct mbuf *cause,
   11362             :                    uint8_t mflowtype, uint32_t mflowid,
   11363             :                    uint32_t vrf_id, uint16_t port)
   11364             : #else
   11365             : static void
   11366           0 : sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst,
   11367             :                    struct sctphdr *sh, uint32_t vtag,
   11368             :                    uint8_t type, struct mbuf *cause,
   11369             :                    uint32_t vrf_id SCTP_UNUSED, uint16_t port)
   11370             : #endif
   11371             : {
   11372             : #ifdef __Panda__
   11373             :         pakhandle_type o_pak;
   11374             : #else
   11375             :         struct mbuf *o_pak;
   11376             : #endif
   11377             :         struct mbuf *mout;
   11378             :         struct sctphdr *shout;
   11379             :         struct sctp_chunkhdr *ch;
   11380             : #if defined(INET) || defined(INET6)
   11381             :         struct udphdr *udp;
   11382             :         int ret;
   11383             : #endif
   11384             :         int len, cause_len, padding_len;
   11385             : #ifdef INET
   11386             : #if defined(__APPLE__) || defined(__Panda__)
   11387             :         sctp_route_t ro;
   11388             : #endif
   11389             :         struct sockaddr_in *src_sin, *dst_sin;
   11390             :         struct ip *ip;
   11391             : #endif
   11392             : #ifdef INET6
   11393             :         struct sockaddr_in6 *src_sin6, *dst_sin6;
   11394             :         struct ip6_hdr *ip6;
   11395             : #endif
   11396             : 
   11397             :         /* Compute the length of the cause and add final padding. */
   11398           0 :         cause_len = 0;
   11399           0 :         if (cause != NULL) {
   11400           0 :                 struct mbuf *m_at, *m_last = NULL;
   11401             : 
   11402           0 :                 for (m_at = cause; m_at; m_at = SCTP_BUF_NEXT(m_at)) {
   11403           0 :                         if (SCTP_BUF_NEXT(m_at) == NULL)
   11404           0 :                                 m_last = m_at;
   11405           0 :                         cause_len += SCTP_BUF_LEN(m_at);
   11406             :                 }
   11407           0 :                 padding_len = cause_len % 4;
   11408           0 :                 if (padding_len != 0) {
   11409           0 :                         padding_len = 4 - padding_len;
   11410             :                 }
   11411           0 :                 if (padding_len != 0) {
   11412           0 :                         if (sctp_add_pad_tombuf(m_last, padding_len) == NULL) {
   11413           0 :                                 sctp_m_freem(cause);
   11414           0 :                                 return;
   11415             :                         }
   11416             :                 }
   11417             :         } else {
   11418           0 :                 padding_len = 0;
   11419             :         }
   11420             :         /* Get an mbuf for the header. */
   11421           0 :         len = sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
   11422           0 :         switch (dst->sa_family) {
   11423             : #ifdef INET
   11424             :         case AF_INET:
   11425             :                 len += sizeof(struct ip);
   11426             :                 break;
   11427             : #endif
   11428             : #ifdef INET6
   11429             :         case AF_INET6:
   11430             :                 len += sizeof(struct ip6_hdr);
   11431             :                 break;
   11432             : #endif
   11433             :         default:
   11434           0 :                 break;
   11435             :         }
   11436             : #if defined(INET) || defined(INET6)
   11437             :         if (port) {
   11438             :                 len += sizeof(struct udphdr);
   11439             :         }
   11440             : #endif
   11441             : #if defined(__APPLE__)
   11442             : #if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD)
   11443             :         mout = sctp_get_mbuf_for_msg(len + max_linkhdr, 1, M_NOWAIT, 1, MT_DATA);
   11444             : #else
   11445             :         mout = sctp_get_mbuf_for_msg(len + SCTP_MAX_LINKHDR, 1, M_NOWAIT, 1, MT_DATA);
   11446             : #endif
   11447             : #else
   11448           0 :         mout = sctp_get_mbuf_for_msg(len + max_linkhdr, 1, M_NOWAIT, 1, MT_DATA);
   11449             : #endif
   11450           0 :         if (mout == NULL) {
   11451           0 :                 if (cause) {
   11452           0 :                         sctp_m_freem(cause);
   11453             :                 }
   11454           0 :                 return;
   11455             :         }
   11456             : #if defined(__APPLE__)
   11457             : #if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD)
   11458             :         SCTP_BUF_RESV_UF(mout, max_linkhdr);
   11459             : #else
   11460             :         SCTP_BUF_RESV_UF(mout, SCTP_MAX_LINKHDR);
   11461             : #endif
   11462             : #else
   11463           0 :         SCTP_BUF_RESV_UF(mout, max_linkhdr);
   11464             : #endif
   11465           0 :         SCTP_BUF_LEN(mout) = len;
   11466           0 :         SCTP_BUF_NEXT(mout) = cause;
   11467             : #if defined(__FreeBSD__)
   11468             :         mout->m_pkthdr.flowid = mflowid;
   11469             :         M_HASHTYPE_SET(mout, mflowtype);
   11470             : #endif
   11471             : #ifdef INET
   11472             :         ip = NULL;
   11473             : #endif
   11474             : #ifdef INET6
   11475             :         ip6 = NULL;
   11476             : #endif
   11477           0 :         switch (dst->sa_family) {
   11478             : #ifdef INET
   11479             :         case AF_INET:
   11480             :                 src_sin = (struct sockaddr_in *)src;
   11481             :                 dst_sin = (struct sockaddr_in *)dst;
   11482             :                 ip = mtod(mout, struct ip *);
   11483             :                 ip->ip_v = IPVERSION;
   11484             :                 ip->ip_hl = (sizeof(struct ip) >> 2);
   11485             :                 ip->ip_tos = 0;
   11486             : #if defined(__FreeBSD__)
   11487             :                 ip->ip_id = ip_newid();
   11488             : #elif defined(__APPLE__)
   11489             : #if RANDOM_IP_ID
   11490             :                 ip->ip_id = ip_randomid();
   11491             : #else
   11492             :                 ip->ip_id = htons(ip_id++);
   11493             : #endif
   11494             : #else
   11495             :                 ip->ip_id = htons(ip_id++);
   11496             : #endif
   11497             :                 ip->ip_off = 0;
   11498             :                 ip->ip_ttl = MODULE_GLOBAL(ip_defttl);
   11499             :                 if (port) {
   11500             :                         ip->ip_p = IPPROTO_UDP;
   11501             :                 } else {
   11502             :                         ip->ip_p = IPPROTO_SCTP;
   11503             :                 }
   11504             :                 ip->ip_src.s_addr = dst_sin->sin_addr.s_addr;
   11505             :                 ip->ip_dst.s_addr = src_sin->sin_addr.s_addr;
   11506             :                 ip->ip_sum = 0;
   11507             :                 len = sizeof(struct ip);
   11508             :                 shout = (struct sctphdr *)((caddr_t)ip + len);
   11509             :                 break;
   11510             : #endif
   11511             : #ifdef INET6
   11512             :         case AF_INET6:
   11513             :                 src_sin6 = (struct sockaddr_in6 *)src;
   11514             :                 dst_sin6 = (struct sockaddr_in6 *)dst;
   11515             :                 ip6 = mtod(mout, struct ip6_hdr *);
   11516             :                 ip6->ip6_flow = htonl(0x60000000);
   11517             : #if defined(__FreeBSD__)
   11518             :                 if (V_ip6_auto_flowlabel) {
   11519             :                         ip6->ip6_flow |= (htonl(ip6_randomflowlabel()) & IPV6_FLOWLABEL_MASK);
   11520             :                 }
   11521             : #endif
   11522             : #if defined(__Userspace__)
   11523             :                 ip6->ip6_hlim = IPv6_HOP_LIMIT;
   11524             : #else
   11525             :                 ip6->ip6_hlim = MODULE_GLOBAL(ip6_defhlim);
   11526             : #endif
   11527             :                 if (port) {
   11528             :                         ip6->ip6_nxt = IPPROTO_UDP;
   11529             :                 } else {
   11530             :                         ip6->ip6_nxt = IPPROTO_SCTP;
   11531             :                 }
   11532             :                 ip6->ip6_src = dst_sin6->sin6_addr;
   11533             :                 ip6->ip6_dst = src_sin6->sin6_addr;
   11534             :                 len = sizeof(struct ip6_hdr);
   11535             :                 shout = (struct sctphdr *)((caddr_t)ip6 + len);
   11536             :                 break;
   11537             : #endif
   11538             :         default:
   11539           0 :                 len = 0;
   11540           0 :                 shout = mtod(mout, struct sctphdr *);
   11541           0 :                 break;
   11542             :         }
   11543             : #if defined(INET) || defined(INET6)
   11544             :         if (port) {
   11545             :                 if (htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)) == 0) {
   11546             :                         sctp_m_freem(mout);
   11547             :                         return;
   11548             :                 }
   11549             :                 udp = (struct udphdr *)shout;
   11550             :                 udp->uh_sport = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port));
   11551             :                 udp->uh_dport = port;
   11552             :                 udp->uh_sum = 0;
   11553             :                 udp->uh_ulen = htons(sizeof(struct udphdr) +
   11554             :                                      sizeof(struct sctphdr) +
   11555             :                                      sizeof(struct sctp_chunkhdr) +
   11556             :                                      cause_len + padding_len);
   11557             :                 len += sizeof(struct udphdr);
   11558             :                 shout = (struct sctphdr *)((caddr_t)shout + sizeof(struct udphdr));
   11559             :         } else {
   11560             :                 udp = NULL;
   11561             :         }
   11562             : #endif
   11563           0 :         shout->src_port = sh->dest_port;
   11564           0 :         shout->dest_port = sh->src_port;
   11565           0 :         shout->checksum = 0;
   11566           0 :         if (vtag) {
   11567           0 :                 shout->v_tag = htonl(vtag);
   11568             :         } else {
   11569           0 :                 shout->v_tag = sh->v_tag;
   11570             :         }
   11571           0 :         len += sizeof(struct sctphdr);
   11572           0 :         ch = (struct sctp_chunkhdr *)((caddr_t)shout + sizeof(struct sctphdr));
   11573           0 :         ch->chunk_type = type;
   11574           0 :         if (vtag) {
   11575           0 :                 ch->chunk_flags = 0;
   11576             :         } else {
   11577           0 :                 ch->chunk_flags = SCTP_HAD_NO_TCB;
   11578             :         }
   11579           0 :         ch->chunk_length = htons(sizeof(struct sctp_chunkhdr) + cause_len);
   11580           0 :         len += sizeof(struct sctp_chunkhdr);
   11581           0 :         len += cause_len + padding_len;
   11582             : 
   11583             :         if (SCTP_GET_HEADER_FOR_OUTPUT(o_pak)) {
   11584             :                 sctp_m_freem(mout);
   11585             :                 return;
   11586             :         }
   11587           0 :         SCTP_ATTACH_CHAIN(o_pak, mout, len);
   11588           0 :         switch (dst->sa_family) {
   11589             : #ifdef INET
   11590             :         case AF_INET:
   11591             : #if defined(__APPLE__) || defined(__Panda__)
   11592             :                 /* zap the stack pointer to the route */
   11593             :                 bzero(&ro, sizeof(sctp_route_t));
   11594             : #if defined(__Panda__)
   11595             :                 ro._l_addr.sa.sa_family = AF_INET;
   11596             : #endif
   11597             : #endif
   11598             :                 if (port) {
   11599             : #if !defined(__Windows__) && !defined(__Userspace__)
   11600             : #if defined(__FreeBSD__) && ((__FreeBSD_version > 803000 && __FreeBSD_version < 900000) || __FreeBSD_version > 900000)
   11601             :                         if (V_udp_cksum) {
   11602             :                                 udp->uh_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, udp->uh_ulen + htons(IPPROTO_UDP));
   11603             :                         } else {
   11604             :                                 udp->uh_sum = 0;
   11605             :                         }
   11606             : #else
   11607             :                         udp->uh_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, udp->uh_ulen + htons(IPPROTO_UDP));
   11608             : #endif
   11609             : #else
   11610             :                         udp->uh_sum = 0;
   11611             : #endif
   11612             :                 }
   11613             : #if defined(__FreeBSD__)
   11614             : #if __FreeBSD_version >= 1000000
   11615             :                 ip->ip_len = htons(len);
   11616             : #else
   11617             :                 ip->ip_len = len;
   11618             : #endif
   11619             : #elif defined(__APPLE__) || defined(__Userspace__)
   11620             :                 ip->ip_len = len;
   11621             : #else
   11622             :                 ip->ip_len = htons(len);
   11623             : #endif
   11624             :                 if (port) {
   11625             : #if defined(SCTP_WITH_NO_CSUM)
   11626             :                         SCTP_STAT_INCR(sctps_sendnocrc);
   11627             : #else
   11628             :                         shout->checksum = sctp_calculate_cksum(mout, sizeof(struct ip) + sizeof(struct udphdr));
   11629             :                         SCTP_STAT_INCR(sctps_sendswcrc);
   11630             : #endif
   11631             : #if defined(__FreeBSD__) && ((__FreeBSD_version > 803000 && __FreeBSD_version < 900000) || __FreeBSD_version > 900000)
   11632             :                         if (V_udp_cksum) {
   11633             :                                 SCTP_ENABLE_UDP_CSUM(o_pak);
   11634             :                         }
   11635             : #else
   11636             :                         SCTP_ENABLE_UDP_CSUM(o_pak);
   11637             : #endif
   11638             :                 } else {
   11639             : #if defined(SCTP_WITH_NO_CSUM)
   11640             :                         SCTP_STAT_INCR(sctps_sendnocrc);
   11641             : #else
   11642             : #if defined(__FreeBSD__) && __FreeBSD_version >= 800000
   11643             :                         mout->m_pkthdr.csum_flags = CSUM_SCTP;
   11644             :                         mout->m_pkthdr.csum_data = offsetof(struct sctphdr, checksum);
   11645             :                         SCTP_STAT_INCR(sctps_sendhwcrc);
   11646             : #else
   11647             :                         shout->checksum = sctp_calculate_cksum(mout, sizeof(struct ip));
   11648             :                         SCTP_STAT_INCR(sctps_sendswcrc);
   11649             : #endif
   11650             : #endif
   11651             :                 }
   11652             : #ifdef SCTP_PACKET_LOGGING
   11653             :                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING) {
   11654             :                         sctp_packet_log(o_pak);
   11655             :                 }
   11656             : #endif
   11657             : #if defined(__APPLE__) || defined(__Panda__)
   11658             :                 SCTP_IP_OUTPUT(ret, o_pak, &ro, NULL, vrf_id);
   11659             :                 /* Free the route if we got one back */
   11660             :                 if (ro.ro_rt) {
   11661             :                         RTFREE(ro.ro_rt);
   11662             :                         ro.ro_rt = NULL;
   11663             :                 }
   11664             : #else
   11665             :                 SCTP_IP_OUTPUT(ret, o_pak, NULL, NULL, vrf_id);
   11666             : #endif
   11667             :                 break;
   11668             : #endif
   11669             : #ifdef INET6
   11670             :         case AF_INET6:
   11671             :                 ip6->ip6_plen = len - sizeof(struct ip6_hdr);
   11672             :                 if (port) {
   11673             : #if defined(SCTP_WITH_NO_CSUM)
   11674             :                         SCTP_STAT_INCR(sctps_sendnocrc);
   11675             : #else
   11676             :                         shout->checksum = sctp_calculate_cksum(mout, sizeof(struct ip6_hdr) + sizeof(struct udphdr));
   11677             :                         SCTP_STAT_INCR(sctps_sendswcrc);
   11678             : #endif
   11679             : #if defined(__Windows__)
   11680             :                         udp->uh_sum = 0;
   11681             : #elif !defined(__Userspace__)
   11682             :                         if ((udp->uh_sum = in6_cksum(o_pak, IPPROTO_UDP, sizeof(struct ip6_hdr), len - sizeof(struct ip6_hdr))) == 0) {
   11683             :                                 udp->uh_sum = 0xffff;
   11684             :                         }
   11685             : #endif
   11686             :                 } else {
   11687             : #if defined(SCTP_WITH_NO_CSUM)
   11688             :                         SCTP_STAT_INCR(sctps_sendnocrc);
   11689             : #else
   11690             : #if defined(__FreeBSD__) && __FreeBSD_version >= 900000
   11691             : #if __FreeBSD_version > 901000
   11692             :                         mout->m_pkthdr.csum_flags = CSUM_SCTP_IPV6;
   11693             : #else
   11694             :                         mout->m_pkthdr.csum_flags = CSUM_SCTP;
   11695             : #endif
   11696             :                         mout->m_pkthdr.csum_data = offsetof(struct sctphdr, checksum);
   11697             :                         SCTP_STAT_INCR(sctps_sendhwcrc);
   11698             : #else
   11699             :                         shout->checksum = sctp_calculate_cksum(mout, sizeof(struct ip6_hdr));
   11700             :                         SCTP_STAT_INCR(sctps_sendswcrc);
   11701             : #endif
   11702             : #endif
   11703             :                 }
   11704             : #ifdef SCTP_PACKET_LOGGING
   11705             :                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING) {
   11706             :                         sctp_packet_log(o_pak);
   11707             :                 }
   11708             : #endif
   11709             :                 SCTP_IP6_OUTPUT(ret, o_pak, NULL, NULL, NULL, vrf_id);
   11710             :                 break;
   11711             : #endif
   11712             : #if defined(__Userspace__)
   11713             :         case AF_CONN:
   11714             :         {
   11715             :                 char *buffer;
   11716             :                 struct sockaddr_conn *sconn;
   11717             : 
   11718           0 :                 sconn = (struct sockaddr_conn *)src;
   11719             : #if defined(SCTP_WITH_NO_CSUM)
   11720             :                 SCTP_STAT_INCR(sctps_sendnocrc);
   11721             : #else
   11722           0 :                 shout->checksum = sctp_calculate_cksum(mout, 0);
   11723           0 :                 SCTP_STAT_INCR(sctps_sendswcrc);
   11724             : #endif
   11725             : #ifdef SCTP_PACKET_LOGGING
   11726             :                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING) {
   11727             :                         sctp_packet_log(mout);
   11728             :                 }
   11729             : #endif
   11730             :                 /* Don't alloc/free for each packet */
   11731           0 :                 if ((buffer = malloc(len)) != NULL) {
   11732           0 :                         m_copydata(mout, 0, len, buffer);
   11733           0 :                         SCTP_BASE_VAR(conn_output)(sconn->sconn_addr, buffer, len, 0, 0);
   11734           0 :                         free(buffer);
   11735             :                 }
   11736           0 :                 sctp_m_freem(mout);
   11737           0 :                 break;
   11738             :         }
   11739             : #endif
   11740             :         default:
   11741           0 :                 SCTPDBG(SCTP_DEBUG_OUTPUT1, "Unknown protocol (TSNH) type %d\n",
   11742             :                         dst->sa_family);
   11743           0 :                 sctp_m_freem(mout);
   11744             :                 SCTP_LTRACE_ERR_RET_PKT(mout, NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, EFAULT);
   11745           0 :                 return;
   11746             :         }
   11747           0 :         SCTP_STAT_INCR(sctps_sendpackets);
   11748           0 :         SCTP_STAT_INCR_COUNTER64(sctps_outpackets);
   11749           0 :         SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks);
   11750           0 :         return;
   11751             : }
   11752             : 
   11753             : void
   11754           0 : sctp_send_shutdown_complete2(struct sockaddr *src, struct sockaddr *dst,
   11755             :                              struct sctphdr *sh,
   11756             : #if defined(__FreeBSD__)
   11757             :                              uint8_t mflowtype, uint32_t mflowid,
   11758             : #endif
   11759             :                              uint32_t vrf_id, uint16_t port)
   11760             : {
   11761           0 :         sctp_send_resp_msg(src, dst, sh, 0, SCTP_SHUTDOWN_COMPLETE, NULL,
   11762             : #if defined(__FreeBSD__)
   11763             :                            mflowtype, mflowid,
   11764             : #endif
   11765             :                            vrf_id, port);
   11766           0 : }
   11767             : 
   11768             : void
   11769           0 : sctp_send_hb(struct sctp_tcb *stcb, struct sctp_nets *net,int so_locked
   11770             : #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
   11771             :         SCTP_UNUSED
   11772             : #endif
   11773             : )
   11774             : {
   11775             :         struct sctp_tmit_chunk *chk;
   11776             :         struct sctp_heartbeat_chunk *hb;
   11777             :         struct timeval now;
   11778             : 
   11779             :         SCTP_TCB_LOCK_ASSERT(stcb);
   11780           0 :         if (net == NULL) {
   11781           0 :                 return;
   11782             :         }
   11783           0 :         (void)SCTP_GETTIME_TIMEVAL(&now);
   11784           0 :         switch (net->ro._l_addr.sa.sa_family) {
   11785             : #ifdef INET
   11786             :         case AF_INET:
   11787             :                 break;
   11788             : #endif
   11789             : #ifdef INET6
   11790             :         case AF_INET6:
   11791             :                 break;
   11792             : #endif
   11793             : #if defined(__Userspace__)
   11794             :         case AF_CONN:
   11795           0 :                 break;
   11796             : #endif
   11797             :         default:
   11798           0 :                 return;
   11799             :         }
   11800           0 :         sctp_alloc_a_chunk(stcb, chk);
   11801           0 :         if (chk == NULL) {
   11802           0 :                 SCTPDBG(SCTP_DEBUG_OUTPUT4, "Gak, can't get a chunk for hb\n");
   11803           0 :                 return;
   11804             :         }
   11805             : 
   11806           0 :         chk->copy_by_ref = 0;
   11807           0 :         chk->rec.chunk_id.id = SCTP_HEARTBEAT_REQUEST;
   11808           0 :         chk->rec.chunk_id.can_take_data = 1;
   11809           0 :         chk->flags = 0;
   11810           0 :         chk->asoc = &stcb->asoc;
   11811           0 :         chk->send_size = sizeof(struct sctp_heartbeat_chunk);
   11812             : 
   11813           0 :         chk->data = sctp_get_mbuf_for_msg(chk->send_size, 0, M_NOWAIT, 1, MT_HEADER);
   11814           0 :         if (chk->data == NULL) {
   11815           0 :                 sctp_free_a_chunk(stcb, chk, so_locked);
   11816           0 :                 return;
   11817             :         }
   11818           0 :         SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD);
   11819           0 :         SCTP_BUF_LEN(chk->data) = chk->send_size;
   11820           0 :         chk->sent = SCTP_DATAGRAM_UNSENT;
   11821           0 :         chk->snd_count = 0;
   11822           0 :         chk->whoTo = net;
   11823           0 :         atomic_add_int(&chk->whoTo->ref_count, 1);
   11824             :         /* Now we have a mbuf that we can fill in with the details */
   11825           0 :         hb = mtod(chk->data, struct sctp_heartbeat_chunk *);
   11826           0 :         memset(hb, 0, sizeof(struct sctp_heartbeat_chunk));
   11827             :         /* fill out chunk header */
   11828           0 :         hb->ch.chunk_type = SCTP_HEARTBEAT_REQUEST;
   11829           0 :         hb->ch.chunk_flags = 0;
   11830           0 :         hb->ch.chunk_length = htons(chk->send_size);
   11831             :         /* Fill out hb parameter */
   11832           0 :         hb->heartbeat.hb_info.ph.param_type = htons(SCTP_HEARTBEAT_INFO);
   11833           0 :         hb->heartbeat.hb_info.ph.param_length = htons(sizeof(struct sctp_heartbeat_info_param));
   11834           0 :         hb->heartbeat.hb_info.time_value_1 = now.tv_sec;
   11835           0 :         hb->heartbeat.hb_info.time_value_2 = now.tv_usec;
   11836             :         /* Did our user request this one, put it in */
   11837           0 :         hb->heartbeat.hb_info.addr_family = (uint8_t)net->ro._l_addr.sa.sa_family;
   11838             : #ifdef HAVE_SA_LEN
   11839             :         hb->heartbeat.hb_info.addr_len = net->ro._l_addr.sa.sa_len;
   11840             : #else
   11841           0 :         switch (net->ro._l_addr.sa.sa_family) {
   11842             : #ifdef INET
   11843             :         case AF_INET:
   11844             :                 hb->heartbeat.hb_info.addr_len = sizeof(struct sockaddr_in);
   11845             :                 break;
   11846             : #endif
   11847             : #ifdef INET6
   11848             :         case AF_INET6:
   11849             :                 hb->heartbeat.hb_info.addr_len = sizeof(struct sockaddr_in6);
   11850             :                 break;
   11851             : #endif
   11852             : #if defined(__Userspace__)
   11853             :         case AF_CONN:
   11854           0 :                 hb->heartbeat.hb_info.addr_len = sizeof(struct sockaddr_conn);
   11855           0 :                 break;
   11856             : #endif
   11857             :         default:
   11858           0 :                 hb->heartbeat.hb_info.addr_len = 0;
   11859           0 :                 break;
   11860             :         }
   11861             : #endif
   11862           0 :         if (net->dest_state & SCTP_ADDR_UNCONFIRMED) {
   11863             :                 /*
   11864             :                  * we only take from the entropy pool if the address is not
   11865             :                  * confirmed.
   11866             :                  */
   11867           0 :                 net->heartbeat_random1 = hb->heartbeat.hb_info.random_value1 = sctp_select_initial_TSN(&stcb->sctp_ep->sctp_ep);
   11868           0 :                 net->heartbeat_random2 = hb->heartbeat.hb_info.random_value2 = sctp_select_initial_TSN(&stcb->sctp_ep->sctp_ep);
   11869             :         } else {
   11870           0 :                 net->heartbeat_random1 = hb->heartbeat.hb_info.random_value1 = 0;
   11871           0 :                 net->heartbeat_random2 = hb->heartbeat.hb_info.random_value2 = 0;
   11872             :         }
   11873           0 :         switch (net->ro._l_addr.sa.sa_family) {
   11874             : #ifdef INET
   11875             :         case AF_INET:
   11876             :                 memcpy(hb->heartbeat.hb_info.address,
   11877             :                        &net->ro._l_addr.sin.sin_addr,
   11878             :                        sizeof(net->ro._l_addr.sin.sin_addr));
   11879             :                 break;
   11880             : #endif
   11881             : #ifdef INET6
   11882             :         case AF_INET6:
   11883             :                 memcpy(hb->heartbeat.hb_info.address,
   11884             :                        &net->ro._l_addr.sin6.sin6_addr,
   11885             :                        sizeof(net->ro._l_addr.sin6.sin6_addr));
   11886             :                 break;
   11887             : #endif
   11888             : #if defined(__Userspace__)
   11889             :         case AF_CONN:
   11890           0 :                 memcpy(hb->heartbeat.hb_info.address,
   11891           0 :                        &net->ro._l_addr.sconn.sconn_addr,
   11892             :                        sizeof(net->ro._l_addr.sconn.sconn_addr));
   11893           0 :                 break;
   11894             : #endif
   11895             :         default:
   11896           0 :                 return;
   11897             :                 break;
   11898             :         }
   11899           0 :         net->hb_responded = 0;
   11900           0 :         TAILQ_INSERT_TAIL(&stcb->asoc.control_send_queue, chk, sctp_next);
   11901           0 :         stcb->asoc.ctrl_queue_cnt++;
   11902           0 :         SCTP_STAT_INCR(sctps_sendheartbeat);
   11903           0 :         return;
   11904             : }
   11905             : 
   11906             : void
   11907           0 : sctp_send_ecn_echo(struct sctp_tcb *stcb, struct sctp_nets *net,
   11908             :                    uint32_t high_tsn)
   11909             : {
   11910             :         struct sctp_association *asoc;
   11911             :         struct sctp_ecne_chunk *ecne;
   11912             :         struct sctp_tmit_chunk *chk;
   11913             : 
   11914           0 :         if (net == NULL) {
   11915           0 :                 return;
   11916             :         }
   11917           0 :         asoc = &stcb->asoc;
   11918             :         SCTP_TCB_LOCK_ASSERT(stcb);
   11919           0 :         TAILQ_FOREACH(chk, &asoc->control_send_queue, sctp_next) {
   11920           0 :                 if ((chk->rec.chunk_id.id == SCTP_ECN_ECHO) && (net == chk->whoTo)) {
   11921             :                         /* found a previous ECN_ECHO update it if needed */
   11922             :                         uint32_t cnt, ctsn;
   11923           0 :                         ecne = mtod(chk->data, struct sctp_ecne_chunk *);
   11924           0 :                         ctsn = ntohl(ecne->tsn);
   11925           0 :                         if (SCTP_TSN_GT(high_tsn, ctsn)) {
   11926           0 :                                 ecne->tsn = htonl(high_tsn);
   11927           0 :                                 SCTP_STAT_INCR(sctps_queue_upd_ecne);
   11928             :                         }
   11929           0 :                         cnt = ntohl(ecne->num_pkts_since_cwr);
   11930           0 :                         cnt++;
   11931           0 :                         ecne->num_pkts_since_cwr = htonl(cnt);
   11932           0 :                         return;
   11933             :                 }
   11934             :         }
   11935             :         /* nope could not find one to update so we must build one */
   11936           0 :         sctp_alloc_a_chunk(stcb, chk);
   11937           0 :         if (chk == NULL) {
   11938           0 :                 return;
   11939             :         }
   11940           0 :         SCTP_STAT_INCR(sctps_queue_upd_ecne);
   11941           0 :         chk->copy_by_ref = 0;
   11942           0 :         chk->rec.chunk_id.id = SCTP_ECN_ECHO;
   11943           0 :         chk->rec.chunk_id.can_take_data = 0;
   11944           0 :         chk->flags = 0;
   11945           0 :         chk->asoc = &stcb->asoc;
   11946           0 :         chk->send_size = sizeof(struct sctp_ecne_chunk);
   11947           0 :         chk->data = sctp_get_mbuf_for_msg(chk->send_size, 0, M_NOWAIT, 1, MT_HEADER);
   11948           0 :         if (chk->data == NULL) {
   11949           0 :                 sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
   11950           0 :                 return;
   11951             :         }
   11952           0 :         SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD);
   11953           0 :         SCTP_BUF_LEN(chk->data) = chk->send_size;
   11954           0 :         chk->sent = SCTP_DATAGRAM_UNSENT;
   11955           0 :         chk->snd_count = 0;
   11956           0 :         chk->whoTo = net;
   11957           0 :         atomic_add_int(&chk->whoTo->ref_count, 1);
   11958             : 
   11959           0 :         stcb->asoc.ecn_echo_cnt_onq++;
   11960           0 :         ecne = mtod(chk->data, struct sctp_ecne_chunk *);
   11961           0 :         ecne->ch.chunk_type = SCTP_ECN_ECHO;
   11962           0 :         ecne->ch.chunk_flags = 0;
   11963           0 :         ecne->ch.chunk_length = htons(sizeof(struct sctp_ecne_chunk));
   11964           0 :         ecne->tsn = htonl(high_tsn);
   11965           0 :         ecne->num_pkts_since_cwr = htonl(1);
   11966           0 :         TAILQ_INSERT_HEAD(&stcb->asoc.control_send_queue, chk, sctp_next);
   11967           0 :         asoc->ctrl_queue_cnt++;
   11968             : }
   11969             : 
   11970             : void
   11971           0 : sctp_send_packet_dropped(struct sctp_tcb *stcb, struct sctp_nets *net,
   11972             :     struct mbuf *m, int len, int iphlen, int bad_crc)
   11973             : {
   11974             :         struct sctp_association *asoc;
   11975             :         struct sctp_pktdrop_chunk *drp;
   11976             :         struct sctp_tmit_chunk *chk;
   11977             :         uint8_t *datap;
   11978           0 :         int was_trunc = 0;
   11979           0 :         int fullsz = 0;
   11980             :         long spc;
   11981             :         int offset;
   11982             :         struct sctp_chunkhdr *ch, chunk_buf;
   11983             :         unsigned int chk_length;
   11984             : 
   11985           0 :         if (!stcb) {
   11986           0 :             return;
   11987             :         }
   11988           0 :         asoc = &stcb->asoc;
   11989             :         SCTP_TCB_LOCK_ASSERT(stcb);
   11990           0 :         if (asoc->pktdrop_supported == 0) {
   11991             :                 /*-
   11992             :                  * peer must declare support before I send one.
   11993             :                  */
   11994           0 :                 return;
   11995             :         }
   11996           0 :         if (stcb->sctp_socket == NULL) {
   11997           0 :                 return;
   11998             :         }
   11999           0 :         sctp_alloc_a_chunk(stcb, chk);
   12000           0 :         if (chk == NULL) {
   12001           0 :                 return;
   12002             :         }
   12003           0 :         chk->copy_by_ref = 0;
   12004           0 :         chk->rec.chunk_id.id = SCTP_PACKET_DROPPED;
   12005           0 :         chk->rec.chunk_id.can_take_data = 1;
   12006           0 :         chk->flags = 0;
   12007           0 :         len -= iphlen;
   12008           0 :         chk->send_size = len;
   12009             :         /* Validate that we do not have an ABORT in here. */
   12010           0 :         offset = iphlen + sizeof(struct sctphdr);
   12011           0 :         ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset,
   12012             :                                                    sizeof(*ch), (uint8_t *) & chunk_buf);
   12013           0 :         while (ch != NULL) {
   12014           0 :                 chk_length = ntohs(ch->chunk_length);
   12015           0 :                 if (chk_length < sizeof(*ch)) {
   12016             :                         /* break to abort land */
   12017           0 :                         break;
   12018             :                 }
   12019           0 :                 switch (ch->chunk_type) {
   12020             :                 case SCTP_PACKET_DROPPED:
   12021             :                 case SCTP_ABORT_ASSOCIATION:
   12022             :                 case SCTP_INITIATION_ACK:
   12023             :                         /**
   12024             :                          * We don't respond with an PKT-DROP to an ABORT
   12025             :                          * or PKT-DROP. We also do not respond to an
   12026             :                          * INIT-ACK, because we can't know if the initiation
   12027             :                          * tag is correct or not.
   12028             :                          */
   12029           0 :                         sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
   12030           0 :                         return;
   12031             :                 default:
   12032           0 :                         break;
   12033             :                 }
   12034           0 :                 offset += SCTP_SIZE32(chk_length);
   12035           0 :                 ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset,
   12036             :                     sizeof(*ch), (uint8_t *) & chunk_buf);
   12037             :         }
   12038             : 
   12039           0 :         if ((len + SCTP_MAX_OVERHEAD + sizeof(struct sctp_pktdrop_chunk)) >
   12040           0 :             min(stcb->asoc.smallest_mtu, MCLBYTES)) {
   12041             :                 /* only send 1 mtu worth, trim off the
   12042             :                  * excess on the end.
   12043             :                  */
   12044           0 :                 fullsz = len;
   12045           0 :                 len = min(stcb->asoc.smallest_mtu, MCLBYTES) - SCTP_MAX_OVERHEAD;
   12046           0 :                 was_trunc = 1;
   12047             :         }
   12048           0 :         chk->asoc = &stcb->asoc;
   12049           0 :         chk->data = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_NOWAIT, 1, MT_DATA);
   12050           0 :         if (chk->data == NULL) {
   12051             : jump_out:
   12052           0 :                 sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
   12053           0 :                 return;
   12054             :         }
   12055           0 :         SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD);
   12056           0 :         drp = mtod(chk->data, struct sctp_pktdrop_chunk *);
   12057           0 :         if (drp == NULL) {
   12058           0 :                 sctp_m_freem(chk->data);
   12059           0 :                 chk->data = NULL;
   12060           0 :                 goto jump_out;
   12061             :         }
   12062           0 :         chk->book_size = SCTP_SIZE32((chk->send_size + sizeof(struct sctp_pktdrop_chunk) +
   12063             :             sizeof(struct sctphdr) + SCTP_MED_OVERHEAD));
   12064           0 :         chk->book_size_scale = 0;
   12065           0 :         if (was_trunc) {
   12066           0 :                 drp->ch.chunk_flags = SCTP_PACKET_TRUNCATED;
   12067           0 :                 drp->trunc_len = htons(fullsz);
   12068             :                 /* Len is already adjusted to size minus overhead above
   12069             :                  * take out the pkt_drop chunk itself from it.
   12070             :                  */
   12071           0 :                 chk->send_size = len - sizeof(struct sctp_pktdrop_chunk);
   12072           0 :                 len = chk->send_size;
   12073             :         } else {
   12074             :                 /* no truncation needed */
   12075           0 :                 drp->ch.chunk_flags = 0;
   12076           0 :                 drp->trunc_len = htons(0);
   12077             :         }
   12078           0 :         if (bad_crc) {
   12079           0 :                 drp->ch.chunk_flags |= SCTP_BADCRC;
   12080             :         }
   12081           0 :         chk->send_size += sizeof(struct sctp_pktdrop_chunk);
   12082           0 :         SCTP_BUF_LEN(chk->data) = chk->send_size;
   12083           0 :         chk->sent = SCTP_DATAGRAM_UNSENT;
   12084           0 :         chk->snd_count = 0;
   12085           0 :         if (net) {
   12086             :                 /* we should hit here */
   12087           0 :                 chk->whoTo = net;
   12088           0 :                 atomic_add_int(&chk->whoTo->ref_count, 1);
   12089             :         } else {
   12090           0 :                 chk->whoTo = NULL;
   12091             :         }
   12092           0 :         drp->ch.chunk_type = SCTP_PACKET_DROPPED;
   12093           0 :         drp->ch.chunk_length = htons(chk->send_size);
   12094           0 :         spc = SCTP_SB_LIMIT_RCV(stcb->sctp_socket);
   12095           0 :         if (spc < 0) {
   12096           0 :                 spc = 0;
   12097             :         }
   12098           0 :         drp->bottle_bw = htonl(spc);
   12099           0 :         if (asoc->my_rwnd) {
   12100           0 :                 drp->current_onq = htonl(asoc->size_on_reasm_queue +
   12101           0 :                     asoc->size_on_all_streams +
   12102           0 :                     asoc->my_rwnd_control_len +
   12103           0 :                     stcb->sctp_socket->so_rcv.sb_cc);
   12104             :         } else {
   12105             :                 /*-
   12106             :                  * If my rwnd is 0, possibly from mbuf depletion as well as
   12107             :                  * space used, tell the peer there is NO space aka onq == bw
   12108             :                  */
   12109           0 :                 drp->current_onq = htonl(spc);
   12110             :         }
   12111           0 :         drp->reserved = 0;
   12112           0 :         datap = drp->data;
   12113           0 :         m_copydata(m, iphlen, len, (caddr_t)datap);
   12114           0 :         TAILQ_INSERT_TAIL(&stcb->asoc.control_send_queue, chk, sctp_next);
   12115           0 :         asoc->ctrl_queue_cnt++;
   12116             : }
   12117             : 
   12118             : void
   12119           0 : sctp_send_cwr(struct sctp_tcb *stcb, struct sctp_nets *net, uint32_t high_tsn, uint8_t override)
   12120             : {
   12121             :         struct sctp_association *asoc;
   12122             :         struct sctp_cwr_chunk *cwr;
   12123             :         struct sctp_tmit_chunk *chk;
   12124             : 
   12125             :         SCTP_TCB_LOCK_ASSERT(stcb);
   12126           0 :         if (net == NULL) {
   12127           0 :                 return;
   12128             :         }
   12129           0 :         asoc = &stcb->asoc;
   12130           0 :         TAILQ_FOREACH(chk, &asoc->control_send_queue, sctp_next) {
   12131           0 :                 if ((chk->rec.chunk_id.id == SCTP_ECN_CWR) && (net == chk->whoTo)) {
   12132             :                         /* found a previous CWR queued to same destination update it if needed */
   12133             :                         uint32_t ctsn;
   12134           0 :                         cwr = mtod(chk->data, struct sctp_cwr_chunk *);
   12135           0 :                         ctsn = ntohl(cwr->tsn);
   12136           0 :                         if (SCTP_TSN_GT(high_tsn, ctsn)) {
   12137           0 :                                 cwr->tsn = htonl(high_tsn);
   12138             :                         }
   12139           0 :                         if (override & SCTP_CWR_REDUCE_OVERRIDE) {
   12140             :                                 /* Make sure override is carried */
   12141           0 :                                 cwr->ch.chunk_flags |= SCTP_CWR_REDUCE_OVERRIDE;
   12142             :                         }
   12143           0 :                         return;
   12144             :                 }
   12145             :         }
   12146           0 :         sctp_alloc_a_chunk(stcb, chk);
   12147           0 :         if (chk == NULL) {
   12148           0 :                 return;
   12149             :         }
   12150           0 :         chk->copy_by_ref = 0;
   12151           0 :         chk->rec.chunk_id.id = SCTP_ECN_CWR;
   12152           0 :         chk->rec.chunk_id.can_take_data = 1;
   12153           0 :         chk->flags = 0;
   12154           0 :         chk->asoc = &stcb->asoc;
   12155           0 :         chk->send_size = sizeof(struct sctp_cwr_chunk);
   12156           0 :         chk->data = sctp_get_mbuf_for_msg(chk->send_size, 0, M_NOWAIT, 1, MT_HEADER);
   12157           0 :         if (chk->data == NULL) {
   12158           0 :                 sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
   12159           0 :                 return;
   12160             :         }
   12161           0 :         SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD);
   12162           0 :         SCTP_BUF_LEN(chk->data) = chk->send_size;
   12163           0 :         chk->sent = SCTP_DATAGRAM_UNSENT;
   12164           0 :         chk->snd_count = 0;
   12165           0 :         chk->whoTo = net;
   12166           0 :         atomic_add_int(&chk->whoTo->ref_count, 1);
   12167           0 :         cwr = mtod(chk->data, struct sctp_cwr_chunk *);
   12168           0 :         cwr->ch.chunk_type = SCTP_ECN_CWR;
   12169           0 :         cwr->ch.chunk_flags = override;
   12170           0 :         cwr->ch.chunk_length = htons(sizeof(struct sctp_cwr_chunk));
   12171           0 :         cwr->tsn = htonl(high_tsn);
   12172           0 :         TAILQ_INSERT_TAIL(&stcb->asoc.control_send_queue, chk, sctp_next);
   12173           0 :         asoc->ctrl_queue_cnt++;
   12174             : }
   12175             : 
   12176             : void
   12177           0 : sctp_add_stream_reset_out(struct sctp_tmit_chunk *chk,
   12178             :                           int number_entries, uint16_t * list,
   12179             :                           uint32_t seq, uint32_t resp_seq, uint32_t last_sent)
   12180             : {
   12181             :         uint16_t len, old_len, i;
   12182             :         struct sctp_stream_reset_out_request *req_out;
   12183             :         struct sctp_chunkhdr *ch;
   12184             : 
   12185           0 :         ch = mtod(chk->data, struct sctp_chunkhdr *);
   12186           0 :         old_len = len = SCTP_SIZE32(ntohs(ch->chunk_length));
   12187             : 
   12188             :         /* get to new offset for the param. */
   12189           0 :         req_out = (struct sctp_stream_reset_out_request *)((caddr_t)ch + len);
   12190             :         /* now how long will this param be? */
   12191           0 :         len = (sizeof(struct sctp_stream_reset_out_request) + (sizeof(uint16_t) * number_entries));
   12192           0 :         req_out->ph.param_type = htons(SCTP_STR_RESET_OUT_REQUEST);
   12193           0 :         req_out->ph.param_length = htons(len);
   12194           0 :         req_out->request_seq = htonl(seq);
   12195           0 :         req_out->response_seq = htonl(resp_seq);
   12196           0 :         req_out->send_reset_at_tsn = htonl(last_sent);
   12197           0 :         if (number_entries) {
   12198           0 :                 for (i = 0; i < number_entries; i++) {
   12199           0 :                         req_out->list_of_streams[i] = htons(list[i]);
   12200             :                 }
   12201             :         }
   12202           0 :         if (SCTP_SIZE32(len) > len) {
   12203             :                 /*-
   12204             :                  * Need to worry about the pad we may end up adding to the
   12205             :                  * end. This is easy since the struct is either aligned to 4
   12206             :                  * bytes or 2 bytes off.
   12207             :                  */
   12208           0 :                 req_out->list_of_streams[number_entries] = 0;
   12209             :         }
   12210             :         /* now fix the chunk length */
   12211           0 :         ch->chunk_length = htons(len + old_len);
   12212           0 :         chk->book_size = len + old_len;
   12213           0 :         chk->book_size_scale = 0;
   12214           0 :         chk->send_size = SCTP_SIZE32(chk->book_size);
   12215           0 :         SCTP_BUF_LEN(chk->data) = chk->send_size;
   12216           0 :         return;
   12217             : }
   12218             : 
   12219             : static void
   12220           0 : sctp_add_stream_reset_in(struct sctp_tmit_chunk *chk,
   12221             :                          int number_entries, uint16_t *list,
   12222             :                          uint32_t seq)
   12223             : {
   12224             :         uint16_t len, old_len, i;
   12225             :         struct sctp_stream_reset_in_request *req_in;
   12226             :         struct sctp_chunkhdr *ch;
   12227             : 
   12228           0 :         ch = mtod(chk->data, struct sctp_chunkhdr *);
   12229           0 :         old_len = len = SCTP_SIZE32(ntohs(ch->chunk_length));
   12230             : 
   12231             :         /* get to new offset for the param. */
   12232           0 :         req_in = (struct sctp_stream_reset_in_request *)((caddr_t)ch + len);
   12233             :         /* now how long will this param be? */
   12234           0 :         len = (sizeof(struct sctp_stream_reset_in_request) + (sizeof(uint16_t) * number_entries));
   12235           0 :         req_in->ph.param_type = htons(SCTP_STR_RESET_IN_REQUEST);
   12236           0 :         req_in->ph.param_length = htons(len);
   12237           0 :         req_in->request_seq = htonl(seq);
   12238           0 :         if (number_entries) {
   12239           0 :                 for (i = 0; i < number_entries; i++) {
   12240           0 :                         req_in->list_of_streams[i] = htons(list[i]);
   12241             :                 }
   12242             :         }
   12243           0 :         if (SCTP_SIZE32(len) > len) {
   12244             :                 /*-
   12245             :                  * Need to worry about the pad we may end up adding to the
   12246             :                  * end. This is easy since the struct is either aligned to 4
   12247             :                  * bytes or 2 bytes off.
   12248             :                  */
   12249           0 :                 req_in->list_of_streams[number_entries] = 0;
   12250             :         }
   12251             :         /* now fix the chunk length */
   12252           0 :         ch->chunk_length = htons(len + old_len);
   12253           0 :         chk->book_size = len + old_len;
   12254           0 :         chk->book_size_scale = 0;
   12255           0 :         chk->send_size = SCTP_SIZE32(chk->book_size);
   12256           0 :         SCTP_BUF_LEN(chk->data) = chk->send_size;
   12257           0 :         return;
   12258             : }
   12259             : 
   12260             : static void
   12261           0 : sctp_add_stream_reset_tsn(struct sctp_tmit_chunk *chk,
   12262             :                           uint32_t seq)
   12263             : {
   12264             :         uint16_t len, old_len;
   12265             :         struct sctp_stream_reset_tsn_request *req_tsn;
   12266             :         struct sctp_chunkhdr *ch;
   12267             : 
   12268           0 :         ch = mtod(chk->data, struct sctp_chunkhdr *);
   12269           0 :         old_len = len = SCTP_SIZE32(ntohs(ch->chunk_length));
   12270             : 
   12271             :         /* get to new offset for the param. */
   12272           0 :         req_tsn = (struct sctp_stream_reset_tsn_request *)((caddr_t)ch + len);
   12273             :         /* now how long will this param be? */
   12274           0 :         len = sizeof(struct sctp_stream_reset_tsn_request);
   12275           0 :         req_tsn->ph.param_type = htons(SCTP_STR_RESET_TSN_REQUEST);
   12276           0 :         req_tsn->ph.param_length = htons(len);
   12277           0 :         req_tsn->request_seq = htonl(seq);
   12278             : 
   12279             :         /* now fix the chunk length */
   12280           0 :         ch->chunk_length = htons(len + old_len);
   12281           0 :         chk->send_size = len + old_len;
   12282           0 :         chk->book_size = SCTP_SIZE32(chk->send_size);
   12283           0 :         chk->book_size_scale = 0;
   12284           0 :         SCTP_BUF_LEN(chk->data) = SCTP_SIZE32(chk->send_size);
   12285           0 :         return;
   12286             : }
   12287             : 
   12288             : void
   12289           0 : sctp_add_stream_reset_result(struct sctp_tmit_chunk *chk,
   12290             :                              uint32_t resp_seq, uint32_t result)
   12291             : {
   12292             :         uint16_t len, old_len;
   12293             :         struct sctp_stream_reset_response *resp;
   12294             :         struct sctp_chunkhdr *ch;
   12295             : 
   12296           0 :         ch = mtod(chk->data, struct sctp_chunkhdr *);
   12297           0 :         old_len = len = SCTP_SIZE32(ntohs(ch->chunk_length));
   12298             : 
   12299             :         /* get to new offset for the param. */
   12300           0 :         resp = (struct sctp_stream_reset_response *)((caddr_t)ch + len);
   12301             :         /* now how long will this param be? */
   12302           0 :         len = sizeof(struct sctp_stream_reset_response);
   12303           0 :         resp->ph.param_type = htons(SCTP_STR_RESET_RESPONSE);
   12304           0 :         resp->ph.param_length = htons(len);
   12305           0 :         resp->response_seq = htonl(resp_seq);
   12306           0 :         resp->result = ntohl(result);
   12307             : 
   12308             :         /* now fix the chunk length */
   12309           0 :         ch->chunk_length = htons(len + old_len);
   12310           0 :         chk->book_size = len + old_len;
   12311           0 :         chk->book_size_scale = 0;
   12312           0 :         chk->send_size = SCTP_SIZE32(chk->book_size);
   12313           0 :         SCTP_BUF_LEN(chk->data) = chk->send_size;
   12314           0 :         return;
   12315             : }
   12316             : 
   12317             : void
   12318           0 : sctp_add_stream_reset_result_tsn(struct sctp_tmit_chunk *chk,
   12319             :                                  uint32_t resp_seq, uint32_t result,
   12320             :                                  uint32_t send_una, uint32_t recv_next)
   12321             : {
   12322             :         uint16_t len, old_len;
   12323             :         struct sctp_stream_reset_response_tsn *resp;
   12324             :         struct sctp_chunkhdr *ch;
   12325             : 
   12326           0 :         ch = mtod(chk->data, struct sctp_chunkhdr *);
   12327           0 :         old_len = len = SCTP_SIZE32(ntohs(ch->chunk_length));
   12328             : 
   12329             :         /* get to new offset for the param. */
   12330           0 :         resp = (struct sctp_stream_reset_response_tsn *)((caddr_t)ch + len);
   12331             :         /* now how long will this param be? */
   12332           0 :         len = sizeof(struct sctp_stream_reset_response_tsn);
   12333           0 :         resp->ph.param_type = htons(SCTP_STR_RESET_RESPONSE);
   12334           0 :         resp->ph.param_length = htons(len);
   12335           0 :         resp->response_seq = htonl(resp_seq);
   12336           0 :         resp->result = htonl(result);
   12337           0 :         resp->senders_next_tsn = htonl(send_una);
   12338           0 :         resp->receivers_next_tsn = htonl(recv_next);
   12339             : 
   12340             :         /* now fix the chunk length */
   12341           0 :         ch->chunk_length = htons(len + old_len);
   12342           0 :         chk->book_size = len + old_len;
   12343           0 :         chk->send_size = SCTP_SIZE32(chk->book_size);
   12344           0 :         chk->book_size_scale = 0;
   12345           0 :         SCTP_BUF_LEN(chk->data) = chk->send_size;
   12346           0 :         return;
   12347             : }
   12348             : 
   12349             : static void
   12350           0 : sctp_add_an_out_stream(struct sctp_tmit_chunk *chk,
   12351             :                        uint32_t seq,
   12352             :                        uint16_t adding)
   12353             : {
   12354             :         uint16_t len, old_len;
   12355             :         struct sctp_chunkhdr *ch;
   12356             :         struct sctp_stream_reset_add_strm *addstr;
   12357             : 
   12358           0 :         ch = mtod(chk->data, struct sctp_chunkhdr *);
   12359           0 :         old_len = len = SCTP_SIZE32(ntohs(ch->chunk_length));
   12360             : 
   12361             :         /* get to new offset for the param. */
   12362           0 :         addstr = (struct sctp_stream_reset_add_strm *)((caddr_t)ch + len);
   12363             :         /* now how long will this param be? */
   12364           0 :         len = sizeof(struct sctp_stream_reset_add_strm);
   12365             : 
   12366             :         /* Fill it out. */
   12367           0 :         addstr->ph.param_type = htons(SCTP_STR_RESET_ADD_OUT_STREAMS);
   12368           0 :         addstr->ph.param_length = htons(len);
   12369           0 :         addstr->request_seq = htonl(seq);
   12370           0 :         addstr->number_of_streams = htons(adding);
   12371           0 :         addstr->reserved = 0;
   12372             : 
   12373             :         /* now fix the chunk length */
   12374           0 :         ch->chunk_length = htons(len + old_len);
   12375           0 :         chk->send_size = len + old_len;
   12376           0 :         chk->book_size = SCTP_SIZE32(chk->send_size);
   12377           0 :         chk->book_size_scale = 0;
   12378           0 :         SCTP_BUF_LEN(chk->data) = SCTP_SIZE32(chk->send_size);
   12379           0 :         return;
   12380             : }
   12381             : 
   12382             : static void
   12383           0 : sctp_add_an_in_stream(struct sctp_tmit_chunk *chk,
   12384             :                       uint32_t seq,
   12385             :                       uint16_t adding)
   12386             : {
   12387             :         uint16_t len, old_len;
   12388             :         struct sctp_chunkhdr *ch;
   12389             :         struct sctp_stream_reset_add_strm *addstr;
   12390             : 
   12391           0 :         ch = mtod(chk->data, struct sctp_chunkhdr *);
   12392           0 :         old_len = len = SCTP_SIZE32(ntohs(ch->chunk_length));
   12393             : 
   12394             :         /* get to new offset for the param. */
   12395           0 :         addstr = (struct sctp_stream_reset_add_strm *)((caddr_t)ch + len);
   12396             :         /* now how long will this param be? */
   12397           0 :         len = sizeof(struct sctp_stream_reset_add_strm);
   12398             :         /* Fill it out. */
   12399           0 :         addstr->ph.param_type = htons(SCTP_STR_RESET_ADD_IN_STREAMS);
   12400           0 :         addstr->ph.param_length = htons(len);
   12401           0 :         addstr->request_seq = htonl(seq);
   12402           0 :         addstr->number_of_streams = htons(adding);
   12403           0 :         addstr->reserved = 0;
   12404             : 
   12405             :         /* now fix the chunk length */
   12406           0 :         ch->chunk_length = htons(len + old_len);
   12407           0 :         chk->send_size = len + old_len;
   12408           0 :         chk->book_size = SCTP_SIZE32(chk->send_size);
   12409           0 :         chk->book_size_scale = 0;
   12410           0 :         SCTP_BUF_LEN(chk->data) = SCTP_SIZE32(chk->send_size);
   12411           0 :         return;
   12412             : }
   12413             : 
   12414             : int
   12415           0 : sctp_send_str_reset_req(struct sctp_tcb *stcb,
   12416             :                         uint16_t number_entries, uint16_t *list,
   12417             :                         uint8_t send_out_req,
   12418             :                         uint8_t send_in_req,
   12419             :                         uint8_t send_tsn_req,
   12420             :                         uint8_t add_stream,
   12421             :                         uint16_t adding_o,
   12422             :                         uint16_t adding_i, uint8_t peer_asked)
   12423             : {
   12424             : 
   12425             :         struct sctp_association *asoc;
   12426             :         struct sctp_tmit_chunk *chk;
   12427             :         struct sctp_chunkhdr *ch;
   12428             :         uint32_t seq;
   12429             : 
   12430           0 :         asoc = &stcb->asoc;
   12431           0 :         if (asoc->stream_reset_outstanding) {
   12432             :                 /*-
   12433             :                  * Already one pending, must get ACK back to clear the flag.
   12434             :                  */
   12435             :                 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, EBUSY);
   12436           0 :                 return (EBUSY);
   12437             :         }
   12438           0 :         if ((send_out_req == 0) && (send_in_req == 0) && (send_tsn_req == 0) &&
   12439             :             (add_stream == 0)) {
   12440             :                 /* nothing to do */
   12441             :                 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, EINVAL);
   12442           0 :                 return (EINVAL);
   12443             :         }
   12444           0 :         if (send_tsn_req && (send_out_req || send_in_req)) {
   12445             :                 /* error, can't do that */
   12446             :                 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, EINVAL);
   12447           0 :                 return (EINVAL);
   12448             :         }
   12449           0 :         if (number_entries > (MCLBYTES -
   12450             :                               SCTP_MIN_OVERHEAD -
   12451             :                               sizeof(struct sctp_chunkhdr) -
   12452             :                               sizeof(struct sctp_stream_reset_out_request)) /
   12453             :                              sizeof(uint16_t)) {
   12454             :                 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
   12455           0 :                 return (ENOMEM);
   12456             :         }
   12457           0 :         sctp_alloc_a_chunk(stcb, chk);
   12458           0 :         if (chk == NULL) {
   12459             :                 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
   12460           0 :                 return (ENOMEM);
   12461             :         }
   12462           0 :         chk->copy_by_ref = 0;
   12463           0 :         chk->rec.chunk_id.id = SCTP_STREAM_RESET;
   12464           0 :         chk->rec.chunk_id.can_take_data = 0;
   12465           0 :         chk->flags = 0;
   12466           0 :         chk->asoc = &stcb->asoc;
   12467           0 :         chk->book_size = sizeof(struct sctp_chunkhdr);
   12468           0 :         chk->send_size = SCTP_SIZE32(chk->book_size);
   12469           0 :         chk->book_size_scale = 0;
   12470             : 
   12471           0 :         chk->data = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_NOWAIT, 1, MT_DATA);
   12472           0 :         if (chk->data == NULL) {
   12473           0 :                 sctp_free_a_chunk(stcb, chk, SCTP_SO_LOCKED);
   12474             :                 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
   12475           0 :                 return (ENOMEM);
   12476             :         }
   12477           0 :         SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD);
   12478             : 
   12479             :         /* setup chunk parameters */
   12480           0 :         chk->sent = SCTP_DATAGRAM_UNSENT;
   12481           0 :         chk->snd_count = 0;
   12482           0 :         if (stcb->asoc.alternate) {
   12483           0 :                 chk->whoTo = stcb->asoc.alternate;
   12484             :         } else {
   12485           0 :                 chk->whoTo = stcb->asoc.primary_destination;
   12486             :         }
   12487           0 :         atomic_add_int(&chk->whoTo->ref_count, 1);
   12488           0 :         ch = mtod(chk->data, struct sctp_chunkhdr *);
   12489           0 :         ch->chunk_type = SCTP_STREAM_RESET;
   12490           0 :         ch->chunk_flags = 0;
   12491           0 :         ch->chunk_length = htons(chk->book_size);
   12492           0 :         SCTP_BUF_LEN(chk->data) = chk->send_size;
   12493             : 
   12494           0 :         seq = stcb->asoc.str_reset_seq_out;
   12495           0 :         if (send_out_req) {
   12496           0 :                 sctp_add_stream_reset_out(chk, number_entries, list,
   12497           0 :                                           seq, (stcb->asoc.str_reset_seq_in - 1), (stcb->asoc.sending_seq - 1));
   12498           0 :                 asoc->stream_reset_out_is_outstanding = 1;
   12499           0 :                 seq++;
   12500           0 :                 asoc->stream_reset_outstanding++;
   12501             :         }
   12502           0 :         if ((add_stream & 1) &&
   12503           0 :             ((stcb->asoc.strm_realoutsize - stcb->asoc.streamoutcnt) < adding_o)) {
   12504             :                 /* Need to allocate more */
   12505             :                 struct sctp_stream_out *oldstream;
   12506             :                 struct sctp_stream_queue_pending *sp, *nsp;
   12507             :                 int i;
   12508             : #if defined(SCTP_DETAILED_STR_STATS)
   12509             :                 int j;
   12510             : #endif
   12511             : 
   12512           0 :                 oldstream = stcb->asoc.strmout;
   12513             :                 /* get some more */
   12514           0 :                 SCTP_MALLOC(stcb->asoc.strmout, struct sctp_stream_out *,
   12515             :                             ((stcb->asoc.streamoutcnt+adding_o) * sizeof(struct sctp_stream_out)),
   12516             :                             SCTP_M_STRMO);
   12517           0 :                 if (stcb->asoc.strmout == NULL) {
   12518             :                         uint8_t x;
   12519           0 :                         stcb->asoc.strmout = oldstream;
   12520             :                         /* Turn off the bit */
   12521           0 :                         x = add_stream & 0xfe;
   12522           0 :                         add_stream = x;
   12523           0 :                         goto skip_stuff;
   12524             :                 }
   12525             :                 /* Ok now we proceed with copying the old out stuff and
   12526             :                  * initializing the new stuff.
   12527             :                  */
   12528           0 :                 SCTP_TCB_SEND_LOCK(stcb);
   12529           0 :                 stcb->asoc.ss_functions.sctp_ss_clear(stcb, &stcb->asoc, 0, 1);
   12530           0 :                 for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
   12531           0 :                         TAILQ_INIT(&stcb->asoc.strmout[i].outqueue);
   12532           0 :                         stcb->asoc.strmout[i].chunks_on_queues = oldstream[i].chunks_on_queues;
   12533           0 :                         stcb->asoc.strmout[i].next_sequence_send = oldstream[i].next_sequence_send;
   12534           0 :                         stcb->asoc.strmout[i].last_msg_incomplete = oldstream[i].last_msg_incomplete;
   12535           0 :                         stcb->asoc.strmout[i].stream_no = i;
   12536           0 :                         stcb->asoc.ss_functions.sctp_ss_init_stream(&stcb->asoc.strmout[i], &oldstream[i]);
   12537             :                         /* now anything on those queues? */
   12538           0 :                         TAILQ_FOREACH_SAFE(sp, &oldstream[i].outqueue, next, nsp) {
   12539           0 :                                 TAILQ_REMOVE(&oldstream[i].outqueue, sp, next);
   12540           0 :                                 TAILQ_INSERT_TAIL(&stcb->asoc.strmout[i].outqueue, sp, next);
   12541             :                         }
   12542             :                         /* Now move assoc pointers too */
   12543           0 :                         if (stcb->asoc.last_out_stream == &oldstream[i]) {
   12544           0 :                                 stcb->asoc.last_out_stream = &stcb->asoc.strmout[i];
   12545             :                         }
   12546           0 :                         if (stcb->asoc.locked_on_sending == &oldstream[i]) {
   12547           0 :                                 stcb->asoc.locked_on_sending = &stcb->asoc.strmout[i];
   12548             :                         }
   12549             :                 }
   12550             :                 /* now the new streams */
   12551           0 :                 stcb->asoc.ss_functions.sctp_ss_init(stcb, &stcb->asoc, 1);
   12552           0 :                 for (i = stcb->asoc.streamoutcnt; i < (stcb->asoc.streamoutcnt + adding_o); i++) {
   12553           0 :                         TAILQ_INIT(&stcb->asoc.strmout[i].outqueue);
   12554           0 :                         stcb->asoc.strmout[i].chunks_on_queues = 0;
   12555             : #if defined(SCTP_DETAILED_STR_STATS)
   12556             :                         for (j = 0; j < SCTP_PR_SCTP_MAX + 1; j++) {
   12557             :                                 stcb->asoc.strmout[i].abandoned_sent[j] = 0;
   12558             :                                 stcb->asoc.strmout[i].abandoned_unsent[j] = 0;
   12559             :                         }
   12560             : #else
   12561           0 :                         stcb->asoc.strmout[i].abandoned_sent[0] = 0;
   12562           0 :                         stcb->asoc.strmout[i].abandoned_unsent[0] = 0;
   12563             : #endif
   12564           0 :                         stcb->asoc.strmout[i].next_sequence_send = 0x0;
   12565           0 :                         stcb->asoc.strmout[i].stream_no = i;
   12566           0 :                         stcb->asoc.strmout[i].last_msg_incomplete = 0;
   12567           0 :                         stcb->asoc.ss_functions.sctp_ss_init_stream(&stcb->asoc.strmout[i], NULL);
   12568             :                 }
   12569           0 :                 stcb->asoc.strm_realoutsize = stcb->asoc.streamoutcnt + adding_o;
   12570           0 :                 SCTP_FREE(oldstream, SCTP_M_STRMO);
   12571           0 :                 SCTP_TCB_SEND_UNLOCK(stcb);
   12572             :         }
   12573             : skip_stuff:
   12574           0 :         if ((add_stream & 1) && (adding_o > 0)) {
   12575           0 :                 asoc->strm_pending_add_size = adding_o;
   12576           0 :                 asoc->peer_req_out = peer_asked;
   12577           0 :                 sctp_add_an_out_stream(chk, seq, adding_o);
   12578           0 :                 seq++;
   12579           0 :                 asoc->stream_reset_outstanding++;
   12580             :         }
   12581           0 :         if ((add_stream & 2) && (adding_i > 0)) {
   12582           0 :                 sctp_add_an_in_stream(chk, seq, adding_i);
   12583           0 :                 seq++;
   12584           0 :                 asoc->stream_reset_outstanding++;
   12585             :         }
   12586           0 :         if (send_in_req) {
   12587           0 :                 sctp_add_stream_reset_in(chk, number_entries, list, seq);
   12588           0 :                 seq++;
   12589           0 :                 asoc->stream_reset_outstanding++;
   12590             :         }
   12591           0 :         if (send_tsn_req) {
   12592           0 :                 sctp_add_stream_reset_tsn(chk, seq);
   12593           0 :                 asoc->stream_reset_outstanding++;
   12594             :         }
   12595           0 :         asoc->str_reset = chk;
   12596             :         /* insert the chunk for sending */
   12597           0 :         TAILQ_INSERT_TAIL(&asoc->control_send_queue,
   12598             :                           chk,
   12599             :                           sctp_next);
   12600           0 :         asoc->ctrl_queue_cnt++;
   12601           0 :         sctp_timer_start(SCTP_TIMER_TYPE_STRRESET, stcb->sctp_ep, stcb, chk->whoTo);
   12602           0 :         return (0);
   12603             : }
   12604             : 
   12605             : void
   12606           0 : sctp_send_abort(struct mbuf *m, int iphlen, struct sockaddr *src, struct sockaddr *dst,
   12607             :                 struct sctphdr *sh, uint32_t vtag, struct mbuf *cause,
   12608             : #if defined(__FreeBSD__)
   12609             :                 uint8_t mflowtype, uint32_t mflowid,
   12610             : #endif
   12611             :                 uint32_t vrf_id, uint16_t port)
   12612             : {
   12613             :         /* Don't respond to an ABORT with an ABORT. */
   12614           0 :         if (sctp_is_there_an_abort_here(m, iphlen, &vtag)) {
   12615           0 :                 if (cause)
   12616           0 :                         sctp_m_freem(cause);
   12617           0 :                 return;
   12618             :         }
   12619           0 :         sctp_send_resp_msg(src, dst, sh, vtag, SCTP_ABORT_ASSOCIATION, cause,
   12620             : #if defined(__FreeBSD__)
   12621             :                            mflowtype, mflowid,
   12622             : #endif
   12623             :                            vrf_id, port);
   12624           0 :         return;
   12625             : }
   12626             : 
   12627             : void
   12628           0 : sctp_send_operr_to(struct sockaddr *src, struct sockaddr *dst,
   12629             :                    struct sctphdr *sh, uint32_t vtag, struct mbuf *cause,
   12630             : #if defined(__FreeBSD__)
   12631             :                    uint8_t mflowtype, uint32_t mflowid,
   12632             : #endif
   12633             :                    uint32_t vrf_id, uint16_t port)
   12634             : {
   12635           0 :         sctp_send_resp_msg(src, dst, sh, vtag, SCTP_OPERATION_ERROR, cause,
   12636             : #if defined(__FreeBSD__)
   12637             :                            mflowtype, mflowid,
   12638             : #endif
   12639             :                            vrf_id, port);
   12640           0 :         return;
   12641             : }
   12642             : 
   12643             : static struct mbuf *
   12644           0 : sctp_copy_resume(struct uio *uio,
   12645             :                  int max_send_len,
   12646             : #if defined(__FreeBSD__) && __FreeBSD_version > 602000
   12647             :                  int user_marks_eor,
   12648             : #endif
   12649             :                  int *error,
   12650             :                  uint32_t *sndout,
   12651             :                  struct mbuf **new_tail)
   12652             : {
   12653             : #if defined(__Panda__)
   12654             :         struct mbuf *m;
   12655             : 
   12656             :         m = m_uiotombuf(uio, M_WAITOK, max_send_len, 0,
   12657             :                         (user_marks_eor ? M_EOR : 0));
   12658             :         if (m == NULL) {
   12659             :                 SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOBUFS);
   12660             :                 *error = ENOBUFS;
   12661             :         } else {
   12662             :                 *sndout = m_length(m, NULL);
   12663             :                 *new_tail = m_last(m);
   12664             :         }
   12665             :         return (m);
   12666             : #elif defined(__FreeBSD__) && __FreeBSD_version > 602000
   12667             :         struct mbuf *m;
   12668             : 
   12669             :         m = m_uiotombuf(uio, M_WAITOK, max_send_len, 0,
   12670             :                 (M_PKTHDR | (user_marks_eor ? M_EOR : 0)));
   12671             :         if (m == NULL) {
   12672             :                 SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOBUFS);
   12673             :                 *error = ENOBUFS;
   12674             :         } else {
   12675             :                 *sndout = m_length(m, NULL);
   12676             :                 *new_tail = m_last(m);
   12677             :         }
   12678             :         return (m);
   12679             : #else
   12680             :         int left, cancpy, willcpy;
   12681             :         struct mbuf *m, *head;
   12682             : 
   12683             : #if defined(__APPLE__)
   12684             : #if defined(APPLE_LEOPARD)
   12685             :         left = min(uio->uio_resid, max_send_len);
   12686             : #else
   12687             :         left = min(uio_resid(uio), max_send_len);
   12688             : #endif
   12689             : #else
   12690           0 :         left = min(uio->uio_resid, max_send_len);
   12691             : #endif
   12692             :         /* Always get a header just in case */
   12693           0 :         head = sctp_get_mbuf_for_msg(left, 0, M_WAITOK, 0, MT_DATA);
   12694           0 :         if (head == NULL) {
   12695             :                 SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOBUFS);
   12696           0 :                 *error = ENOBUFS;
   12697           0 :                 return (NULL);
   12698             :         }
   12699           0 :         cancpy = M_TRAILINGSPACE(head);
   12700           0 :         willcpy = min(cancpy, left);
   12701           0 :         *error = uiomove(mtod(head, caddr_t), willcpy, uio);
   12702           0 :         if (*error) {
   12703           0 :                 sctp_m_freem(head);
   12704           0 :                 return (NULL);
   12705             :         }
   12706           0 :         *sndout += willcpy;
   12707           0 :         left -= willcpy;
   12708           0 :         SCTP_BUF_LEN(head) = willcpy;
   12709           0 :         m = head;
   12710           0 :         *new_tail = head;
   12711           0 :         while (left > 0) {
   12712             :                 /* move in user data */
   12713           0 :                 SCTP_BUF_NEXT(m) = sctp_get_mbuf_for_msg(left, 0, M_WAITOK, 0, MT_DATA);
   12714           0 :                 if (SCTP_BUF_NEXT(m) == NULL) {
   12715           0 :                         sctp_m_freem(head);
   12716           0 :                         *new_tail = NULL;
   12717             :                         SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOBUFS);
   12718           0 :                         *error = ENOBUFS;
   12719           0 :                         return (NULL);
   12720             :                 }
   12721           0 :                 m = SCTP_BUF_NEXT(m);
   12722           0 :                 cancpy = M_TRAILINGSPACE(m);
   12723           0 :                 willcpy = min(cancpy, left);
   12724           0 :                 *error = uiomove(mtod(m, caddr_t), willcpy, uio);
   12725           0 :                 if (*error) {
   12726           0 :                         sctp_m_freem(head);
   12727           0 :                         *new_tail = NULL;
   12728             :                         SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, EFAULT);
   12729           0 :                         *error = EFAULT;
   12730           0 :                         return (NULL);
   12731             :                 }
   12732           0 :                 SCTP_BUF_LEN(m) = willcpy;
   12733           0 :                 left -= willcpy;
   12734           0 :                 *sndout += willcpy;
   12735           0 :                 *new_tail = m;
   12736           0 :                 if (left == 0) {
   12737           0 :                         SCTP_BUF_NEXT(m) = NULL;
   12738             :                 }
   12739             :         }
   12740           0 :         return (head);
   12741             : #endif
   12742             : }
   12743             : 
   12744             : static int
   12745           0 : sctp_copy_one(struct sctp_stream_queue_pending *sp,
   12746             :               struct uio *uio,
   12747             :               int resv_upfront)
   12748             : {
   12749             :         int left;
   12750             : #if defined(__Panda__)
   12751             :         left = sp->length;
   12752             :         sp->data = m_uiotombuf(uio, M_WAITOK, sp->length,
   12753             :                                resv_upfront, 0);
   12754             :         if (sp->data == NULL) {
   12755             :                 SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOBUFS);
   12756             :                 return (ENOBUFS);
   12757             :         }
   12758             : 
   12759             :         sp->tail_mbuf = m_last(sp->data);
   12760             :         return (0);
   12761             : 
   12762             : #elif defined(__FreeBSD__) && __FreeBSD_version > 602000
   12763             :         left = sp->length;
   12764             :         sp->data = m_uiotombuf(uio, M_WAITOK, sp->length,
   12765             :                                resv_upfront, 0);
   12766             :         if (sp->data == NULL) {
   12767             :                 SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOBUFS);
   12768             :                 return (ENOBUFS);
   12769             :         }
   12770             : 
   12771             :         sp->tail_mbuf = m_last(sp->data);
   12772             :         return (0);
   12773             : #else
   12774             :         int cancpy, willcpy, error;
   12775             :         struct mbuf *m, *head;
   12776           0 :         int cpsz = 0;
   12777             : 
   12778             :         /* First one gets a header */
   12779           0 :         left = sp->length;
   12780           0 :         head = m = sctp_get_mbuf_for_msg((left + resv_upfront), 0, M_WAITOK, 0, MT_DATA);
   12781           0 :         if (m == NULL) {
   12782             :                 SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOBUFS);
   12783           0 :                 return (ENOBUFS);
   12784             :         }
   12785             :         /*-
   12786             :          * Add this one for m in now, that way if the alloc fails we won't
   12787             :          * have a bad cnt.
   12788             :          */
   12789           0 :         SCTP_BUF_RESV_UF(m, resv_upfront);
   12790           0 :         cancpy = M_TRAILINGSPACE(m);
   12791           0 :         willcpy = min(cancpy, left);
   12792           0 :         while (left > 0) {
   12793             :                 /* move in user data */
   12794           0 :                 error = uiomove(mtod(m, caddr_t), willcpy, uio);
   12795           0 :                 if (error) {
   12796           0 :                         sctp_m_freem(head);
   12797           0 :                         return (error);
   12798             :                 }
   12799           0 :                 SCTP_BUF_LEN(m) = willcpy;
   12800           0 :                 left -= willcpy;
   12801           0 :                 cpsz += willcpy;
   12802           0 :                 if (left > 0) {
   12803           0 :                         SCTP_BUF_NEXT(m) = sctp_get_mbuf_for_msg(left, 0, M_WAITOK, 0, MT_DATA);
   12804           0 :                         if (SCTP_BUF_NEXT(m) == NULL) {
   12805             :                                 /*
   12806             :                                  * the head goes back to caller, he can free
   12807             :                                  * the rest
   12808             :                                  */
   12809           0 :                                 sctp_m_freem(head);
   12810             :                                 SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOBUFS);
   12811           0 :                                 return (ENOBUFS);
   12812             :                         }
   12813           0 :                         m = SCTP_BUF_NEXT(m);
   12814           0 :                         cancpy = M_TRAILINGSPACE(m);
   12815           0 :                         willcpy = min(cancpy, left);
   12816             :                 } else {
   12817           0 :                         sp->tail_mbuf = m;
   12818           0 :                         SCTP_BUF_NEXT(m) = NULL;
   12819             :                 }
   12820             :         }
   12821           0 :         sp->data = head;
   12822           0 :         sp->length = cpsz;
   12823           0 :         return (0);
   12824             : #endif
   12825             : }
   12826             : 
   12827             : 
   12828             : 
   12829             : static struct sctp_stream_queue_pending *
   12830           0 : sctp_copy_it_in(struct sctp_tcb *stcb,
   12831             :     struct sctp_association *asoc,
   12832             :     struct sctp_sndrcvinfo *srcv,
   12833             :     struct uio *uio,
   12834             :     struct sctp_nets *net,
   12835             :     int max_send_len,
   12836             :     int user_marks_eor,
   12837             :     int *error)
   12838             : 
   12839             : {
   12840             :         /*-
   12841             :          * This routine must be very careful in its work. Protocol
   12842             :          * processing is up and running so care must be taken to spl...()
   12843             :          * when you need to do something that may effect the stcb/asoc. The
   12844             :          * sb is locked however. When data is copied the protocol processing
   12845             :          * should be enabled since this is a slower operation...
   12846             :          */
   12847           0 :         struct sctp_stream_queue_pending *sp = NULL;
   12848             :         int resv_in_first;
   12849             : 
   12850           0 :         *error = 0;
   12851             :         /* Now can we send this? */
   12852           0 :         if ((SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_SENT) ||
   12853           0 :             (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_ACK_SENT) ||
   12854           0 :             (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED) ||
   12855           0 :             (asoc->state & SCTP_STATE_SHUTDOWN_PENDING)) {
   12856             :                 /* got data while shutting down */
   12857             :                 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ECONNRESET);
   12858           0 :                 *error = ECONNRESET;
   12859           0 :                 goto out_now;
   12860             :         }
   12861           0 :         sctp_alloc_a_strmoq(stcb, sp);
   12862           0 :         if (sp == NULL) {
   12863             :                 SCTP_LTRACE_ERR_RET(NULL, stcb, net, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
   12864           0 :                 *error = ENOMEM;
   12865           0 :                 goto out_now;
   12866             :         }
   12867           0 :         sp->act_flags = 0;
   12868           0 :         sp->sender_all_done = 0;
   12869           0 :         sp->sinfo_flags = srcv->sinfo_flags;
   12870           0 :         sp->timetolive = srcv->sinfo_timetolive;
   12871           0 :         sp->ppid = srcv->sinfo_ppid;
   12872           0 :         sp->context = srcv->sinfo_context;
   12873           0 :         (void)SCTP_GETTIME_TIMEVAL(&sp->ts);
   12874             : 
   12875           0 :         sp->stream = srcv->sinfo_stream;
   12876             : #if defined(__APPLE__)
   12877             : #if defined(APPLE_LEOPARD)
   12878             :         sp->length = min(uio->uio_resid, max_send_len);
   12879             : #else
   12880             :         sp->length = min(uio_resid(uio), max_send_len);
   12881             : #endif
   12882             : #else
   12883           0 :         sp->length = min(uio->uio_resid, max_send_len);
   12884             : #endif
   12885             : #if defined(__APPLE__)
   12886             : #if defined(APPLE_LEOPARD)
   12887             :         if ((sp->length == (uint32_t)uio->uio_resid) &&
   12888             : #else
   12889             :         if ((sp->length == (uint32_t)uio_resid(uio)) &&
   12890             : #endif
   12891             : #else
   12892           0 :         if ((sp->length == (uint32_t)uio->uio_resid) &&
   12893             : #endif
   12894           0 :             ((user_marks_eor == 0) ||
   12895           0 :              (srcv->sinfo_flags & SCTP_EOF) ||
   12896           0 :              (user_marks_eor && (srcv->sinfo_flags & SCTP_EOR)))) {
   12897           0 :                 sp->msg_is_complete = 1;
   12898             :         } else {
   12899           0 :                 sp->msg_is_complete = 0;
   12900             :         }
   12901           0 :         sp->sender_all_done = 0;
   12902           0 :         sp->some_taken = 0;
   12903           0 :         sp->put_last_out = 0;
   12904           0 :         resv_in_first = sizeof(struct sctp_data_chunk);
   12905           0 :         sp->data = sp->tail_mbuf = NULL;
   12906           0 :         if (sp->length == 0) {
   12907           0 :                 *error = 0;
   12908           0 :                 goto skip_copy;
   12909             :         }
   12910           0 :         if (srcv->sinfo_keynumber_valid) {
   12911           0 :                 sp->auth_keyid = srcv->sinfo_keynumber;
   12912             :         } else {
   12913           0 :                 sp->auth_keyid = stcb->asoc.authinfo.active_keyid;
   12914             :         }
   12915           0 :         if (sctp_auth_is_required_chunk(SCTP_DATA, stcb->asoc.peer_auth_chunks)) {
   12916           0 :                 sctp_auth_key_acquire(stcb, sp->auth_keyid);
   12917           0 :                 sp->holds_key_ref = 1;
   12918             :         }
   12919             : #if defined(__APPLE__)
   12920             :         SCTP_SOCKET_UNLOCK(SCTP_INP_SO(stcb->sctp_ep), 0);
   12921             : #endif
   12922           0 :         *error = sctp_copy_one(sp, uio, resv_in_first);
   12923             : #if defined(__APPLE__)
   12924             :         SCTP_SOCKET_LOCK(SCTP_INP_SO(stcb->sctp_ep), 0);
   12925             : #endif
   12926             :  skip_copy:
   12927           0 :         if (*error) {
   12928           0 :                 sctp_free_a_strmoq(stcb, sp, SCTP_SO_LOCKED);
   12929           0 :                 sp = NULL;
   12930             :         } else {
   12931           0 :                 if (sp->sinfo_flags & SCTP_ADDR_OVER) {
   12932           0 :                         sp->net = net;
   12933           0 :                         atomic_add_int(&sp->net->ref_count, 1);
   12934             :                 } else {
   12935           0 :                         sp->net = NULL;
   12936             :                 }
   12937           0 :                 sctp_set_prsctp_policy(sp);
   12938             :         }
   12939             : out_now:
   12940           0 :         return (sp);
   12941             : }
   12942             : 
   12943             : 
   12944             : int
   12945           0 : sctp_sosend(struct socket *so,
   12946             :             struct sockaddr *addr,
   12947             :             struct uio *uio,
   12948             : #ifdef __Panda__
   12949             :             pakhandle_type top,
   12950             :             pakhandle_type icontrol,
   12951             : #else
   12952             :             struct mbuf *top,
   12953             :             struct mbuf *control,
   12954             : #endif
   12955             : #if defined(__APPLE__) || defined(__Panda__)
   12956             :             int flags
   12957             : #else
   12958             :             int flags,
   12959             : #if defined(__FreeBSD__) && __FreeBSD_version >= 500000
   12960             :             struct thread *p
   12961             : #elif defined(__Windows__)
   12962             :             PKTHREAD p
   12963             : #else
   12964             : #if defined(__Userspace__)
   12965             :             /*
   12966             :              * proc is a dummy in __Userspace__ and will not be passed
   12967             :              * to sctp_lower_sosend
   12968             :              */
   12969             : #endif
   12970             :             struct proc *p
   12971             : #endif
   12972             : #endif
   12973             : )
   12974             : {
   12975             : #ifdef __Panda__
   12976             :         struct mbuf *control = NULL;
   12977             : #endif
   12978             : #if defined(__APPLE__)
   12979             :         struct proc *p = current_proc();
   12980             : #endif
   12981           0 :         int error, use_sndinfo = 0;
   12982             :         struct sctp_sndrcvinfo sndrcvninfo;
   12983             :         struct sockaddr *addr_to_use;
   12984             : #if defined(INET) && defined(INET6)
   12985             :         struct sockaddr_in sin;
   12986             : #endif
   12987             : 
   12988             : #if defined(__APPLE__)
   12989             :         SCTP_SOCKET_LOCK(so, 1);
   12990             : #endif
   12991             : #ifdef __Panda__
   12992             :         control = SCTP_HEADER_TO_CHAIN(icontrol);
   12993             : #endif
   12994           0 :         if (control) {
   12995             :                 /* process cmsg snd/rcv info (maybe a assoc-id) */
   12996           0 :                 if (sctp_find_cmsg(SCTP_SNDRCV, (void *)&sndrcvninfo, control,
   12997             :                     sizeof(sndrcvninfo))) {
   12998             :                         /* got one */
   12999           0 :                         use_sndinfo = 1;
   13000             :                 }
   13001             :         }
   13002           0 :         addr_to_use = addr;
   13003             : #if defined(INET) && defined(INET6)
   13004             :         if ((addr) && (addr->sa_family == AF_INET6)) {
   13005             :                 struct sockaddr_in6 *sin6;
   13006             : 
   13007             :                 sin6 = (struct sockaddr_in6 *)addr;
   13008             :                 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
   13009             :                         in6_sin6_2_sin(&sin, sin6);
   13010             :                         addr_to_use = (struct sockaddr *)&sin;
   13011             :                 }
   13012             :         }
   13013             : #endif
   13014           0 :         error = sctp_lower_sosend(so, addr_to_use, uio, top,
   13015             : #ifdef __Panda__
   13016             :                                   icontrol,
   13017             : #else
   13018             :                                   control,
   13019             : #endif
   13020             :                                   flags,
   13021             :                                   use_sndinfo ? &sndrcvninfo: NULL
   13022             : #if !(defined(__Panda__) || defined(__Userspace__))
   13023             :                                   , p
   13024             : #endif
   13025             :                 );
   13026             : #if defined(__APPLE__)
   13027             :         SCTP_SOCKET_UNLOCK(so, 1);
   13028             : #endif
   13029           0 :         return (error);
   13030             : }
   13031             : 
   13032             : 
   13033             : int
   13034           0 : sctp_lower_sosend(struct socket *so,
   13035             :                   struct sockaddr *addr,
   13036             :                   struct uio *uio,
   13037             : #ifdef __Panda__
   13038             :                   pakhandle_type i_pak,
   13039             :                   pakhandle_type i_control,
   13040             : #else
   13041             :                   struct mbuf *i_pak,
   13042             :                   struct mbuf *control,
   13043             : #endif
   13044             :                   int flags,
   13045             :                   struct sctp_sndrcvinfo *srcv
   13046             : #if !(defined( __Panda__) || defined(__Userspace__))
   13047             :                   ,
   13048             : #if defined(__FreeBSD__) && __FreeBSD_version >= 500000
   13049             :                   struct thread *p
   13050             : #elif defined(__Windows__)
   13051             :                   PKTHREAD p
   13052             : #else
   13053             :                   struct proc *p
   13054             : #endif
   13055             : #endif
   13056             :         )
   13057             : {
   13058           0 :         unsigned int sndlen = 0, max_len;
   13059             :         int error, len;
   13060           0 :         struct mbuf *top = NULL;
   13061             : #ifdef __Panda__
   13062             :         struct mbuf *control = NULL;
   13063             : #endif
   13064           0 :         int queue_only = 0, queue_only_for_init = 0;
   13065           0 :         int free_cnt_applied = 0;
   13066             :         int un_sent;
   13067           0 :         int now_filled = 0;
   13068           0 :         unsigned int inqueue_bytes = 0;
   13069             :         struct sctp_block_entry be;
   13070             :         struct sctp_inpcb *inp;
   13071           0 :         struct sctp_tcb *stcb = NULL;
   13072             :         struct timeval now;
   13073             :         struct sctp_nets *net;
   13074             :         struct sctp_association *asoc;
   13075             :         struct sctp_inpcb *t_inp;
   13076             :         int user_marks_eor;
   13077           0 :         int create_lock_applied = 0;
   13078           0 :         int nagle_applies = 0;
   13079           0 :         int some_on_control = 0;
   13080           0 :         int got_all_of_the_send = 0;
   13081           0 :         int hold_tcblock = 0;
   13082           0 :         int non_blocking = 0;
   13083           0 :         uint32_t local_add_more, local_soresv = 0;
   13084             :         uint16_t port;
   13085             :         uint16_t sinfo_flags;
   13086             :         sctp_assoc_t sinfo_assoc_id;
   13087             : 
   13088           0 :         error = 0;
   13089           0 :         net = NULL;
   13090           0 :         stcb = NULL;
   13091           0 :         asoc = NULL;
   13092             : 
   13093             : #if defined(__APPLE__)
   13094             :         sctp_lock_assert(so);
   13095             : #endif
   13096           0 :         t_inp = inp = (struct sctp_inpcb *)so->so_pcb;
   13097           0 :         if (inp == NULL) {
   13098             :                 SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, EINVAL);
   13099           0 :                 error = EINVAL;
   13100           0 :                 if (i_pak) {
   13101           0 :                         SCTP_RELEASE_PKT(i_pak);
   13102             :                 }
   13103           0 :                 return (error);
   13104             :         }
   13105           0 :         if ((uio == NULL) && (i_pak == NULL)) {
   13106             :                 SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
   13107           0 :                 return (EINVAL);
   13108             :         }
   13109           0 :         user_marks_eor = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXPLICIT_EOR);
   13110           0 :         atomic_add_int(&inp->total_sends, 1);
   13111           0 :         if (uio) {
   13112             : #if defined(__APPLE__)
   13113             : #if defined(APPLE_LEOPARD)
   13114             :                 if (uio->uio_resid < 0) {
   13115             : #else
   13116             :                 if (uio_resid(uio) < 0) {
   13117             : #endif
   13118             : #else
   13119           0 :                 if (uio->uio_resid < 0) {
   13120             : #endif
   13121             :                         SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
   13122           0 :                         return (EINVAL);
   13123             :                 }
   13124             : #if defined(__APPLE__)
   13125             : #if defined(APPLE_LEOPARD)
   13126             :                 sndlen = uio->uio_resid;
   13127             : #else
   13128             :                 sndlen = uio_resid(uio);
   13129             : #endif
   13130             : #else
   13131           0 :                 sndlen = uio->uio_resid;
   13132             : #endif
   13133             :         } else {
   13134           0 :                 top = SCTP_HEADER_TO_CHAIN(i_pak);
   13135             : #ifdef __Panda__
   13136             :                 /*-
   13137             :                  * app len indicates the datalen, dgsize for cases
   13138             :                  * of SCTP_EOF/ABORT will not have the right len
   13139             :                  */
   13140             :                 sndlen = SCTP_APP_DATA_LEN(i_pak);
   13141             :                 /*-
   13142             :                  * Set the particle len also to zero to match
   13143             :                  * up with app len. We only have one particle
   13144             :                  * if app len is zero for Panda. This is ensured
   13145             :                  * in the socket lib
   13146             :                  */
   13147             :                 if (sndlen == 0) {
   13148             :                         SCTP_BUF_LEN(top)  = 0;
   13149             :                 }
   13150             :                 /*-
   13151             :                  * We delink the chain from header, but keep
   13152             :                  * the header around as we will need it in
   13153             :                  * EAGAIN case
   13154             :                  */
   13155             :                 SCTP_DETACH_HEADER_FROM_CHAIN(i_pak);
   13156             : #else
   13157           0 :                 sndlen = SCTP_HEADER_LEN(i_pak);
   13158             : #endif
   13159             :         }
   13160           0 :         SCTPDBG(SCTP_DEBUG_OUTPUT1, "Send called addr:%p send length %d\n",
   13161             :                 (void *)addr,
   13162             :                 sndlen);
   13163             : #ifdef __Panda__
   13164             :         if (i_control) {
   13165             :                 control = SCTP_HEADER_TO_CHAIN(i_control);
   13166             :         }
   13167             : #endif
   13168           0 :         if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
   13169           0 :             (inp->sctp_socket->so_qlimit)) {
   13170             :                 /* The listener can NOT send */
   13171             :                 SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOTCONN);
   13172           0 :                 error = ENOTCONN;
   13173           0 :                 goto out_unlocked;
   13174             :         }
   13175             :         /**
   13176             :          * Pre-screen address, if one is given the sin-len
   13177             :          * must be set correctly!
   13178             :          */
   13179           0 :         if (addr) {
   13180           0 :                 union sctp_sockstore *raddr = (union sctp_sockstore *)addr;
   13181           0 :                 switch (raddr->sa.sa_family) {
   13182             : #ifdef INET
   13183             :                 case AF_INET:
   13184             : #ifdef HAVE_SIN_LEN
   13185             :                         if (raddr->sin.sin_len != sizeof(struct sockaddr_in)) {
   13186             :                                 SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
   13187             :                                 error = EINVAL;
   13188             :                                 goto out_unlocked;
   13189             :                         }
   13190             : #endif
   13191             :                         port = raddr->sin.sin_port;
   13192             :                         break;
   13193             : #endif
   13194             : #ifdef INET6
   13195             :                 case AF_INET6:
   13196             : #ifdef HAVE_SIN6_LEN
   13197             :                         if (raddr->sin6.sin6_len != sizeof(struct sockaddr_in6)) {
   13198             :                                 SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
   13199             :                                 error = EINVAL;
   13200             :                                 goto out_unlocked;
   13201             :                         }
   13202             : #endif
   13203             :                         port = raddr->sin6.sin6_port;
   13204             :                         break;
   13205             : #endif
   13206             : #if defined(__Userspace__)
   13207             :                 case AF_CONN:
   13208             : #ifdef HAVE_SCONN_LEN
   13209             :                         if (raddr->sconn.sconn_len != sizeof(struct sockaddr_conn)) {
   13210             :                                 SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
   13211             :                                 error = EINVAL;
   13212             :                                 goto out_unlocked;
   13213             :                         }
   13214             : #endif
   13215           0 :                         port = raddr->sconn.sconn_port;
   13216           0 :                         break;
   13217             : #endif
   13218             :                 default:
   13219             :                         SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EAFNOSUPPORT);
   13220           0 :                         error = EAFNOSUPPORT;
   13221           0 :                         goto out_unlocked;
   13222             :                 }
   13223             :         } else
   13224           0 :                 port = 0;
   13225             : 
   13226           0 :         if (srcv) {
   13227           0 :                 sinfo_flags = srcv->sinfo_flags;
   13228           0 :                 sinfo_assoc_id = srcv->sinfo_assoc_id;
   13229           0 :                 if (INVALID_SINFO_FLAG(sinfo_flags) ||
   13230           0 :                     PR_SCTP_INVALID_POLICY(sinfo_flags)) {
   13231             :                         SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
   13232           0 :                         error = EINVAL;
   13233           0 :                         goto out_unlocked;
   13234             :                 }
   13235           0 :                 if (srcv->sinfo_flags)
   13236           0 :                         SCTP_STAT_INCR(sctps_sends_with_flags);
   13237             :         } else {
   13238           0 :                 sinfo_flags = inp->def_send.sinfo_flags;
   13239           0 :                 sinfo_assoc_id = inp->def_send.sinfo_assoc_id;
   13240             :         }
   13241           0 :         if (sinfo_flags & SCTP_SENDALL) {
   13242             :                 /* its a sendall */
   13243           0 :                 error = sctp_sendall(inp, uio, top, srcv);
   13244           0 :                 top = NULL;
   13245           0 :                 goto out_unlocked;
   13246             :         }
   13247           0 :         if ((sinfo_flags & SCTP_ADDR_OVER) && (addr == NULL)) {
   13248             :                 SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
   13249           0 :                 error = EINVAL;
   13250           0 :                 goto out_unlocked;
   13251             :         }
   13252             :         /* now we must find the assoc */
   13253           0 :         if ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) ||
   13254           0 :             (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
   13255           0 :                 SCTP_INP_RLOCK(inp);
   13256           0 :                 stcb = LIST_FIRST(&inp->sctp_asoc_list);
   13257           0 :                 if (stcb) {
   13258           0 :                         SCTP_TCB_LOCK(stcb);
   13259           0 :                         hold_tcblock = 1;
   13260             :                 }
   13261           0 :                 SCTP_INP_RUNLOCK(inp);
   13262           0 :         } else if (sinfo_assoc_id) {
   13263           0 :                 stcb = sctp_findassociation_ep_asocid(inp, sinfo_assoc_id, 0);
   13264           0 :         } else if (addr) {
   13265             :                 /*-
   13266             :                  * Since we did not use findep we must
   13267             :                  * increment it, and if we don't find a tcb
   13268             :                  * decrement it.
   13269             :                  */
   13270           0 :                 SCTP_INP_WLOCK(inp);
   13271           0 :                 SCTP_INP_INCR_REF(inp);
   13272           0 :                 SCTP_INP_WUNLOCK(inp);
   13273           0 :                 stcb = sctp_findassociation_ep_addr(&t_inp, addr, &net, NULL, NULL);
   13274           0 :                 if (stcb == NULL) {
   13275           0 :                         SCTP_INP_WLOCK(inp);
   13276           0 :                         SCTP_INP_DECR_REF(inp);
   13277           0 :                         SCTP_INP_WUNLOCK(inp);
   13278             :                 } else {
   13279           0 :                         hold_tcblock = 1;
   13280             :                 }
   13281             :         }
   13282           0 :         if ((stcb == NULL) && (addr)) {
   13283             :                 /* Possible implicit send? */
   13284           0 :                 SCTP_ASOC_CREATE_LOCK(inp);
   13285           0 :                 create_lock_applied = 1;
   13286           0 :                 if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
   13287           0 :                     (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE)) {
   13288             :                         /* Should I really unlock ? */
   13289             :                         SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, EINVAL);
   13290           0 :                         error = EINVAL;
   13291           0 :                         goto out_unlocked;
   13292             : 
   13293             :                 }
   13294           0 :                 if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) &&
   13295           0 :                     (addr->sa_family == AF_INET6)) {
   13296             :                         SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
   13297           0 :                         error = EINVAL;
   13298           0 :                         goto out_unlocked;
   13299             :                 }
   13300           0 :                 SCTP_INP_WLOCK(inp);
   13301           0 :                 SCTP_INP_INCR_REF(inp);
   13302           0 :                 SCTP_INP_WUNLOCK(inp);
   13303             :                 /* With the lock applied look again */
   13304           0 :                 stcb = sctp_findassociation_ep_addr(&t_inp, addr, &net, NULL, NULL);
   13305           0 :                 if ((stcb == NULL) && (control != NULL) && (port > 0)) {
   13306           0 :                         stcb = sctp_findassociation_cmsgs(&t_inp, port, control, &net, &error);
   13307             :                 }
   13308           0 :                 if (stcb == NULL) {
   13309           0 :                         SCTP_INP_WLOCK(inp);
   13310           0 :                         SCTP_INP_DECR_REF(inp);
   13311           0 :                         SCTP_INP_WUNLOCK(inp);
   13312             :                 } else {
   13313           0 :                         hold_tcblock = 1;
   13314             :                 }
   13315           0 :                 if (error) {
   13316           0 :                         goto out_unlocked;
   13317             :                 }
   13318           0 :                 if (t_inp != inp) {
   13319             :                         SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, ENOTCONN);
   13320           0 :                         error = ENOTCONN;
   13321           0 :                         goto out_unlocked;
   13322             :                 }
   13323             :         }
   13324           0 :         if (stcb == NULL) {
   13325           0 :                 if (addr == NULL) {
   13326             :                         SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, ENOENT);
   13327           0 :                         error = ENOENT;
   13328           0 :                         goto out_unlocked;
   13329             :                 } else {
   13330             :                         /* We must go ahead and start the INIT process */
   13331             :                         uint32_t vrf_id;
   13332             : 
   13333           0 :                         if ((sinfo_flags & SCTP_ABORT) ||
   13334           0 :                             ((sinfo_flags & SCTP_EOF) && (sndlen == 0))) {
   13335             :                                 /*-
   13336             :                                  * User asks to abort a non-existant assoc,
   13337             :                                  * or EOF a non-existant assoc with no data
   13338             :                                  */
   13339             :                                 SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, ENOENT);
   13340           0 :                                 error = ENOENT;
   13341           0 :                                 goto out_unlocked;
   13342             :                         }
   13343             :                         /* get an asoc/stcb struct */
   13344           0 :                         vrf_id = inp->def_vrf_id;
   13345             : #ifdef INVARIANTS
   13346             :                         if (create_lock_applied == 0) {
   13347             :                                 panic("Error, should hold create lock and I don't?");
   13348             :                         }
   13349             : #endif
   13350           0 :                         stcb = sctp_aloc_assoc(inp, addr, &error, 0, vrf_id,
   13351             : #if !(defined( __Panda__) || defined(__Userspace__))
   13352             :                                                p
   13353             : #else
   13354             :                                                (struct proc *)NULL
   13355             : #endif
   13356             :                                 );
   13357           0 :                         if (stcb == NULL) {
   13358             :                                 /* Error is setup for us in the call */
   13359           0 :                                 goto out_unlocked;
   13360             :                         }
   13361           0 :                         if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) {
   13362           0 :                                 stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED;
   13363             :                                 /* Set the connected flag so we can queue data */
   13364           0 :                                 soisconnecting(so);
   13365             :                         }
   13366           0 :                         hold_tcblock = 1;
   13367           0 :                         if (create_lock_applied) {
   13368           0 :                                 SCTP_ASOC_CREATE_UNLOCK(inp);
   13369           0 :                                 create_lock_applied = 0;
   13370             :                         } else {
   13371           0 :                                 SCTP_PRINTF("Huh-3? create lock should have been on??\n");
   13372             :                         }
   13373             :                         /* Turn on queue only flag to prevent data from being sent */
   13374           0 :                         queue_only = 1;
   13375           0 :                         asoc = &stcb->asoc;
   13376           0 :                         SCTP_SET_STATE(asoc, SCTP_STATE_COOKIE_WAIT);
   13377           0 :                         (void)SCTP_GETTIME_TIMEVAL(&asoc->time_entered);
   13378             : 
   13379             :                         /* initialize authentication params for the assoc */
   13380           0 :                         sctp_initialize_auth_params(inp, stcb);
   13381             : 
   13382           0 :                         if (control) {
   13383           0 :                                 if (sctp_process_cmsgs_for_init(stcb, control, &error)) {
   13384           0 :                                         sctp_free_assoc(inp, stcb, SCTP_PCBFREE_FORCE, SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_7);
   13385           0 :                                         hold_tcblock = 0;
   13386           0 :                                         stcb = NULL;
   13387           0 :                                         goto out_unlocked;
   13388             :                                 }
   13389             :                         }
   13390             :                         /* out with the INIT */
   13391           0 :                         queue_only_for_init = 1;
   13392             :                         /*-
   13393             :                          * we may want to dig in after this call and adjust the MTU
   13394             :                          * value. It defaulted to 1500 (constant) but the ro
   13395             :                          * structure may now have an update and thus we may need to
   13396             :                          * change it BEFORE we append the message.
   13397             :                          */
   13398             :                 }
   13399             :         } else
   13400           0 :                 asoc = &stcb->asoc;
   13401           0 :         if (srcv == NULL)
   13402           0 :                 srcv = (struct sctp_sndrcvinfo *)&asoc->def_send;
   13403           0 :         if (srcv->sinfo_flags & SCTP_ADDR_OVER) {
   13404           0 :                 if (addr)
   13405           0 :                         net = sctp_findnet(stcb, addr);
   13406             :                 else
   13407           0 :                         net = NULL;
   13408           0 :                 if ((net == NULL) ||
   13409           0 :                     ((port != 0) && (port != stcb->rport))) {
   13410             :                         SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
   13411           0 :                         error = EINVAL;
   13412           0 :                         goto out_unlocked;
   13413             :                 }
   13414             :         } else {
   13415           0 :                 if (stcb->asoc.alternate) {
   13416           0 :                         net = stcb->asoc.alternate;
   13417             :                 } else {
   13418           0 :                         net = stcb->asoc.primary_destination;
   13419             :                 }
   13420             :         }
   13421           0 :         atomic_add_int(&stcb->total_sends, 1);
   13422             :         /* Keep the stcb from being freed under our feet */
   13423           0 :         atomic_add_int(&asoc->refcnt, 1);
   13424           0 :         free_cnt_applied = 1;
   13425             : 
   13426           0 :         if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NO_FRAGMENT)) {
   13427           0 :                 if (sndlen > asoc->smallest_mtu) {
   13428             :                         SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EMSGSIZE);
   13429           0 :                         error = EMSGSIZE;
   13430           0 :                         goto out_unlocked;
   13431             :                 }
   13432             :         }
   13433             : #if defined(__Userspace__)
   13434           0 :         if (inp->recv_callback) {
   13435           0 :                 non_blocking = 1;
   13436             :         }
   13437             : #endif
   13438           0 :         if (SCTP_SO_IS_NBIO(so)
   13439             : #if defined(__FreeBSD__) && __FreeBSD_version >= 500000
   13440             :              || (flags & MSG_NBIO)
   13441             : #endif
   13442             :             ) {
   13443           0 :                 non_blocking = 1;
   13444             :         }
   13445             :         /* would we block? */
   13446           0 :         if (non_blocking) {
   13447           0 :                 if (hold_tcblock == 0) {
   13448           0 :                         SCTP_TCB_LOCK(stcb);
   13449           0 :                         hold_tcblock = 1;
   13450             :                 }
   13451           0 :                 inqueue_bytes = stcb->asoc.total_output_queue_size - (stcb->asoc.chunks_on_out_queue * sizeof(struct sctp_data_chunk));
   13452           0 :                 if ((SCTP_SB_LIMIT_SND(so) <  (sndlen + inqueue_bytes + stcb->asoc.sb_send_resv)) ||
   13453           0 :                     (stcb->asoc.chunks_on_out_queue >= SCTP_BASE_SYSCTL(sctp_max_chunks_on_queue))) {
   13454             :                         SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EWOULDBLOCK);
   13455           0 :                         if (sndlen > SCTP_SB_LIMIT_SND(so))
   13456           0 :                                 error = EMSGSIZE;
   13457             :                         else
   13458           0 :                                 error = EWOULDBLOCK;
   13459           0 :                         goto out_unlocked;
   13460             :                 }
   13461           0 :                 stcb->asoc.sb_send_resv += sndlen;
   13462           0 :                 SCTP_TCB_UNLOCK(stcb);
   13463           0 :                 hold_tcblock = 0;
   13464             :         } else {
   13465           0 :                 atomic_add_int(&stcb->asoc.sb_send_resv, sndlen);
   13466             :         }
   13467           0 :         local_soresv = sndlen;
   13468           0 :         if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
   13469             :                 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ECONNRESET);
   13470           0 :                 error = ECONNRESET;
   13471           0 :                 goto out_unlocked;
   13472             :         }
   13473           0 :         if (create_lock_applied) {
   13474           0 :                 SCTP_ASOC_CREATE_UNLOCK(inp);
   13475           0 :                 create_lock_applied = 0;
   13476             :         }
   13477           0 :         if (asoc->stream_reset_outstanding) {
   13478             :                 /*
   13479             :                  * Can't queue any data while stream reset is underway.
   13480             :                  */
   13481             :                 SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EAGAIN);
   13482           0 :                 error = EAGAIN;
   13483           0 :                 goto out_unlocked;
   13484             :         }
   13485           0 :         if ((SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_WAIT) ||
   13486           0 :             (SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_ECHOED)) {
   13487           0 :                 queue_only = 1;
   13488             :         }
   13489             :         /* we are now done with all control */
   13490           0 :         if (control) {
   13491           0 :                 sctp_m_freem(control);
   13492           0 :                 control = NULL;
   13493             :         }
   13494           0 :         if ((SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_SENT) ||
   13495           0 :             (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED) ||
   13496           0 :             (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_ACK_SENT) ||
   13497           0 :             (asoc->state & SCTP_STATE_SHUTDOWN_PENDING)) {
   13498           0 :                 if (srcv->sinfo_flags & SCTP_ABORT) {
   13499             :                         ;
   13500             :                 } else {
   13501             :                         SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ECONNRESET);
   13502           0 :                         error = ECONNRESET;
   13503           0 :                         goto out_unlocked;
   13504             :                 }
   13505             :         }
   13506             :         /* Ok, we will attempt a msgsnd :> */
   13507             : #if !(defined(__Panda__) || defined(__Windows__) || defined(__Userspace__))
   13508             :         if (p) {
   13509             : #if defined(__FreeBSD__) && __FreeBSD_version >= 603000
   13510             :                 p->td_ru.ru_msgsnd++;
   13511             : #elif defined(__FreeBSD__) && __FreeBSD_version >= 500000
   13512             :                 p->td_proc->p_stats->p_ru.ru_msgsnd++;
   13513             : #else
   13514             :                 p->p_stats->p_ru.ru_msgsnd++;
   13515             : #endif
   13516             :         }
   13517             : #endif
   13518             :         /* Are we aborting? */
   13519           0 :         if (srcv->sinfo_flags & SCTP_ABORT) {
   13520             :                 struct mbuf *mm;
   13521           0 :                 int tot_demand, tot_out = 0, max_out;
   13522             : 
   13523           0 :                 SCTP_STAT_INCR(sctps_sends_with_abort);
   13524           0 :                 if ((SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_WAIT) ||
   13525           0 :                     (SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_ECHOED)) {
   13526             :                         /* It has to be up before we abort */
   13527             :                         /* how big is the user initiated abort? */
   13528             :                         SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
   13529           0 :                         error = EINVAL;
   13530           0 :                         goto out;
   13531             :                 }
   13532           0 :                 if (hold_tcblock) {
   13533           0 :                         SCTP_TCB_UNLOCK(stcb);
   13534           0 :                         hold_tcblock = 0;
   13535             :                 }
   13536           0 :                 if (top) {
   13537           0 :                         struct mbuf *cntm = NULL;
   13538             : 
   13539           0 :                         mm = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr), 0, M_WAITOK, 1, MT_DATA);
   13540           0 :                         if (sndlen != 0) {
   13541           0 :                                 for (cntm = top; cntm; cntm = SCTP_BUF_NEXT(cntm)) {
   13542           0 :                                         tot_out += SCTP_BUF_LEN(cntm);
   13543             :                                 }
   13544             :                         }
   13545             :                 } else {
   13546             :                         /* Must fit in a MTU */
   13547           0 :                         tot_out = sndlen;
   13548           0 :                         tot_demand = (tot_out + sizeof(struct sctp_paramhdr));
   13549           0 :                         if (tot_demand > SCTP_DEFAULT_ADD_MORE) {
   13550             :                                 /* To big */
   13551             :                                 SCTP_LTRACE_ERR_RET(NULL, stcb, net, SCTP_FROM_SCTP_OUTPUT, EMSGSIZE);
   13552           0 :                                 error = EMSGSIZE;
   13553           0 :                                 goto out;
   13554             :                         }
   13555           0 :                         mm = sctp_get_mbuf_for_msg(tot_demand, 0, M_WAITOK, 1, MT_DATA);
   13556             :                 }
   13557           0 :                 if (mm == NULL) {
   13558             :                         SCTP_LTRACE_ERR_RET(NULL, stcb, net, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
   13559           0 :                         error = ENOMEM;
   13560           0 :                         goto out;
   13561             :                 }
   13562           0 :                 max_out = asoc->smallest_mtu - sizeof(struct sctp_paramhdr);
   13563           0 :                 max_out -= sizeof(struct sctp_abort_msg);
   13564           0 :                 if (tot_out > max_out) {
   13565           0 :                         tot_out = max_out;
   13566             :                 }
   13567           0 :                 if (mm) {
   13568             :                         struct sctp_paramhdr *ph;
   13569             : 
   13570             :                         /* now move forward the data pointer */
   13571           0 :                         ph = mtod(mm, struct sctp_paramhdr *);
   13572           0 :                         ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
   13573           0 :                         ph->param_length = htons(sizeof(struct sctp_paramhdr) + tot_out);
   13574           0 :                         ph++;
   13575           0 :                         SCTP_BUF_LEN(mm) = tot_out + sizeof(struct sctp_paramhdr);
   13576           0 :                         if (top == NULL) {
   13577             : #if defined(__APPLE__)
   13578             :                                 SCTP_SOCKET_UNLOCK(so, 0);
   13579             : #endif
   13580           0 :                                 error = uiomove((caddr_t)ph, (int)tot_out, uio);
   13581             : #if defined(__APPLE__)
   13582             :                                 SCTP_SOCKET_LOCK(so, 0);
   13583             : #endif
   13584           0 :                                 if (error) {
   13585             :                                         /*-
   13586             :                                          * Here if we can't get his data we
   13587             :                                          * still abort we just don't get to
   13588             :                                          * send the users note :-0
   13589             :                                          */
   13590           0 :                                         sctp_m_freem(mm);
   13591           0 :                                         mm = NULL;
   13592             :                                 }
   13593             :                         } else {
   13594           0 :                                 if (sndlen != 0) {
   13595           0 :                                         SCTP_BUF_NEXT(mm) = top;
   13596             :                                 }
   13597             :                         }
   13598             :                 }
   13599           0 :                 if (hold_tcblock == 0) {
   13600           0 :                         SCTP_TCB_LOCK(stcb);
   13601             :                 }
   13602           0 :                 atomic_add_int(&stcb->asoc.refcnt, -1);
   13603           0 :                 free_cnt_applied = 0;
   13604             :                 /* release this lock, otherwise we hang on ourselves */
   13605           0 :                 sctp_abort_an_association(stcb->sctp_ep, stcb, mm, SCTP_SO_LOCKED);
   13606             :                 /* now relock the stcb so everything is sane */
   13607           0 :                 hold_tcblock = 0;
   13608           0 :                 stcb = NULL;
   13609             :                 /* In this case top is already chained to mm
   13610             :                  * avoid double free, since we free it below if
   13611             :                  * top != NULL and driver would free it after sending
   13612             :                  * the packet out
   13613             :                  */
   13614           0 :                 if (sndlen != 0) {
   13615           0 :                         top = NULL;
   13616             :                 }
   13617           0 :                 goto out_unlocked;
   13618             :         }
   13619             :         /* Calculate the maximum we can send */
   13620           0 :         inqueue_bytes = stcb->asoc.total_output_queue_size - (stcb->asoc.chunks_on_out_queue * sizeof(struct sctp_data_chunk));
   13621           0 :         if (SCTP_SB_LIMIT_SND(so) > inqueue_bytes) {
   13622           0 :                 if (non_blocking) {
   13623             :                         /* we already checked for non-blocking above. */
   13624           0 :                         max_len = sndlen;
   13625             :                 } else {
   13626           0 :                         max_len = SCTP_SB_LIMIT_SND(so) - inqueue_bytes;
   13627             :                 }
   13628             :         } else {
   13629           0 :                 max_len = 0;
   13630             :         }
   13631           0 :         if (hold_tcblock) {
   13632           0 :                 SCTP_TCB_UNLOCK(stcb);
   13633           0 :                 hold_tcblock = 0;
   13634             :         }
   13635             :         /* Is the stream no. valid? */
   13636           0 :         if (srcv->sinfo_stream >= asoc->streamoutcnt) {
   13637             :                 /* Invalid stream number */
   13638             :                 SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
   13639           0 :                 error = EINVAL;
   13640           0 :                 goto out_unlocked;
   13641             :         }
   13642           0 :         if (asoc->strmout == NULL) {
   13643             :                 /* huh? software error */
   13644             :                 SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EFAULT);
   13645           0 :                 error = EFAULT;
   13646           0 :                 goto out_unlocked;
   13647             :         }
   13648             : 
   13649             :         /* Unless E_EOR mode is on, we must make a send FIT in one call. */
   13650           0 :         if ((user_marks_eor == 0) &&
   13651           0 :             (sndlen > SCTP_SB_LIMIT_SND(stcb->sctp_socket))) {
   13652             :                 /* It will NEVER fit */
   13653             :                 SCTP_LTRACE_ERR_RET(NULL, stcb, net, SCTP_FROM_SCTP_OUTPUT, EMSGSIZE);
   13654           0 :                 error = EMSGSIZE;
   13655           0 :                 goto out_unlocked;
   13656             :         }
   13657           0 :         if ((uio == NULL) && user_marks_eor) {
   13658             :                 /*-
   13659             :                  * We do not support eeor mode for
   13660             :                  * sending with mbuf chains (like sendfile).
   13661             :                  */
   13662             :                 SCTP_LTRACE_ERR_RET(NULL, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
   13663           0 :                 error = EINVAL;
   13664           0 :                 goto out_unlocked;
   13665             :         }
   13666             : 
   13667           0 :         if (user_marks_eor) {
   13668           0 :                 local_add_more = min(SCTP_SB_LIMIT_SND(so), SCTP_BASE_SYSCTL(sctp_add_more_threshold));
   13669             :         } else {
   13670             :                 /*-
   13671             :                  * For non-eeor the whole message must fit in
   13672             :                  * the socket send buffer.
   13673             :                  */
   13674           0 :                 local_add_more = sndlen;
   13675             :         }
   13676           0 :         len = 0;
   13677           0 :         if (non_blocking) {
   13678           0 :                 goto skip_preblock;
   13679             :         }
   13680           0 :         if (((max_len <= local_add_more) &&
   13681           0 :              (SCTP_SB_LIMIT_SND(so) >= local_add_more)) ||
   13682           0 :             (max_len == 0) ||
   13683           0 :             ((stcb->asoc.chunks_on_out_queue+stcb->asoc.stream_queue_cnt) >= SCTP_BASE_SYSCTL(sctp_max_chunks_on_queue))) {
   13684             :                 /* No room right now ! */
   13685           0 :                 SOCKBUF_LOCK(&so->so_snd);
   13686           0 :                 inqueue_bytes = stcb->asoc.total_output_queue_size - (stcb->asoc.chunks_on_out_queue * sizeof(struct sctp_data_chunk));
   13687           0 :                 while ((SCTP_SB_LIMIT_SND(so) < (inqueue_bytes + local_add_more)) ||
   13688           0 :                        ((stcb->asoc.stream_queue_cnt+stcb->asoc.chunks_on_out_queue) >= SCTP_BASE_SYSCTL(sctp_max_chunks_on_queue))) {
   13689           0 :                         SCTPDBG(SCTP_DEBUG_OUTPUT1,"pre_block limit:%u <(inq:%d + %d) || (%d+%d > %d)\n",
   13690             :                                 (unsigned int)SCTP_SB_LIMIT_SND(so),
   13691             :                                 inqueue_bytes,
   13692             :                                 local_add_more,
   13693             :                                 stcb->asoc.stream_queue_cnt,
   13694             :                                 stcb->asoc.chunks_on_out_queue,
   13695             :                                 SCTP_BASE_SYSCTL(sctp_max_chunks_on_queue));
   13696           0 :                         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_BLK_LOGGING_ENABLE) {
   13697           0 :                                 sctp_log_block(SCTP_BLOCK_LOG_INTO_BLKA, asoc, sndlen);
   13698             :                         }
   13699           0 :                         be.error = 0;
   13700             : #if !defined(__Panda__) && !defined(__Windows__)
   13701           0 :                         stcb->block_entry = &be;
   13702             : #endif
   13703           0 :                         error = sbwait(&so->so_snd);
   13704           0 :                         stcb->block_entry = NULL;
   13705           0 :                         if (error || so->so_error || be.error) {
   13706           0 :                                 if (error == 0) {
   13707           0 :                                         if (so->so_error)
   13708           0 :                                                 error = so->so_error;
   13709           0 :                                         if (be.error) {
   13710           0 :                                                 error = be.error;
   13711             :                                         }
   13712             :                                 }
   13713           0 :                                 SOCKBUF_UNLOCK(&so->so_snd);
   13714           0 :                                 goto out_unlocked;
   13715             :                         }
   13716           0 :                         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_BLK_LOGGING_ENABLE) {
   13717           0 :                                 sctp_log_block(SCTP_BLOCK_LOG_OUTOF_BLK,
   13718           0 :                                                asoc, stcb->asoc.total_output_queue_size);
   13719             :                         }
   13720           0 :                         if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
   13721           0 :                                 goto out_unlocked;
   13722             :                         }
   13723           0 :                         inqueue_bytes = stcb->asoc.total_output_queue_size - (stcb->asoc.chunks_on_out_queue * sizeof(struct sctp_data_chunk));
   13724             :                 }
   13725           0 :                 if (SCTP_SB_LIMIT_SND(so) > inqueue_bytes) {
   13726           0 :                         max_len = SCTP_SB_LIMIT_SND(so) -  inqueue_bytes;
   13727             :                 } else {
   13728           0 :                         max_len = 0;
   13729             :                 }
   13730           0 :                 SOCKBUF_UNLOCK(&so->so_snd);
   13731             :         }
   13732             : 
   13733             : skip_preblock:
   13734           0 :         if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
   13735           0 :                 goto out_unlocked;
   13736             :         }
   13737             : #if defined(__APPLE__)
   13738             :         error = sblock(&so->so_snd, SBLOCKWAIT(flags));
   13739             : #endif
   13740             :         /* sndlen covers for mbuf case
   13741             :          * uio_resid covers for the non-mbuf case
   13742             :          * NOTE: uio will be null when top/mbuf is passed
   13743             :          */
   13744           0 :         if (sndlen == 0) {
   13745           0 :                 if (srcv->sinfo_flags & SCTP_EOF) {
   13746           0 :                         got_all_of_the_send = 1;
   13747           0 :                         goto dataless_eof;
   13748             :                 } else {
   13749             :                         SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
   13750           0 :                         error = EINVAL;
   13751           0 :                         goto out;
   13752             :                 }
   13753             :         }
   13754           0 :         if (top == NULL) {
   13755             :                 struct sctp_stream_queue_pending *sp;
   13756             :                 struct sctp_stream_out *strm;
   13757             :                 uint32_t sndout;
   13758             : 
   13759           0 :                 SCTP_TCB_SEND_LOCK(stcb);
   13760           0 :                 if ((asoc->stream_locked) &&
   13761           0 :                     (asoc->stream_locked_on  != srcv->sinfo_stream)) {
   13762           0 :                         SCTP_TCB_SEND_UNLOCK(stcb);
   13763             :                         SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
   13764           0 :                         error = EINVAL;
   13765           0 :                         goto out;
   13766             :                 }
   13767           0 :                 SCTP_TCB_SEND_UNLOCK(stcb);
   13768             : 
   13769           0 :                 strm = &stcb->asoc.strmout[srcv->sinfo_stream];
   13770           0 :                 if (strm->last_msg_incomplete == 0) {
   13771             :                 do_a_copy_in:
   13772           0 :                         sp = sctp_copy_it_in(stcb, asoc, srcv, uio, net, max_len, user_marks_eor, &error);
   13773           0 :                         if ((sp == NULL) || (error)) {
   13774             :                                 goto out;
   13775             :                         }
   13776           0 :                         SCTP_TCB_SEND_LOCK(stcb);
   13777           0 :                         if (sp->msg_is_complete) {
   13778           0 :                                 strm->last_msg_incomplete = 0;
   13779           0 :                                 asoc->stream_locked = 0;
   13780             :                         } else {
   13781             :                                 /* Just got locked to this guy in
   13782             :                                  * case of an interrupt.
   13783             :                                  */
   13784           0 :                                 strm->last_msg_incomplete = 1;
   13785           0 :                                 asoc->stream_locked = 1;
   13786           0 :                                 asoc->stream_locked_on  = srcv->sinfo_stream;
   13787           0 :                                 sp->sender_all_done = 0;
   13788             :                         }
   13789           0 :                         sctp_snd_sb_alloc(stcb, sp->length);
   13790           0 :                         atomic_add_int(&asoc->stream_queue_cnt, 1);
   13791           0 :                         if (srcv->sinfo_flags & SCTP_UNORDERED) {
   13792           0 :                                 SCTP_STAT_INCR(sctps_sends_with_unord);
   13793             :                         }
   13794           0 :                         TAILQ_INSERT_TAIL(&strm->outqueue, sp, next);
   13795           0 :                         stcb->asoc.ss_functions.sctp_ss_add_to_stream(stcb, asoc, strm, sp, 1);
   13796           0 :                         SCTP_TCB_SEND_UNLOCK(stcb);
   13797             :                 } else {
   13798           0 :                         SCTP_TCB_SEND_LOCK(stcb);
   13799           0 :                         sp = TAILQ_LAST(&strm->outqueue, sctp_streamhead);
   13800           0 :                         SCTP_TCB_SEND_UNLOCK(stcb);
   13801           0 :                         if (sp == NULL) {
   13802             :                                 /* ???? Huh ??? last msg is gone */
   13803             : #ifdef INVARIANTS
   13804             :                                 panic("Warning: Last msg marked incomplete, yet nothing left?");
   13805             : #else
   13806           0 :                                 SCTP_PRINTF("Warning: Last msg marked incomplete, yet nothing left?\n");
   13807           0 :                                 strm->last_msg_incomplete = 0;
   13808             : #endif
   13809           0 :                                 goto do_a_copy_in;
   13810             : 
   13811             :                         }
   13812             :                 }
   13813             : #if defined(__APPLE__)
   13814             : #if defined(APPLE_LEOPARD)
   13815             :                 while (uio->uio_resid > 0) {
   13816             : #else
   13817             :                 while (uio_resid(uio) > 0) {
   13818             : #endif
   13819             : #else
   13820           0 :                 while (uio->uio_resid > 0) {
   13821             : #endif
   13822             :                         /* How much room do we have? */
   13823             :                         struct mbuf *new_tail, *mm;
   13824             : 
   13825           0 :                         if (SCTP_SB_LIMIT_SND(so) > stcb->asoc.total_output_queue_size)
   13826           0 :                                 max_len = SCTP_SB_LIMIT_SND(so) - stcb->asoc.total_output_queue_size;
   13827             :                         else
   13828           0 :                                 max_len = 0;
   13829             : 
   13830           0 :                         if ((max_len > SCTP_BASE_SYSCTL(sctp_add_more_threshold)) ||
   13831           0 :                             (max_len && (SCTP_SB_LIMIT_SND(so) < SCTP_BASE_SYSCTL(sctp_add_more_threshold))) ||
   13832             : #if defined(__APPLE__)
   13833             : #if defined(APPLE_LEOPARD)
   13834             :                             (uio->uio_resid && (uio->uio_resid <= (int)max_len))) {
   13835             : #else
   13836             :                             (uio_resid(uio) && (uio_resid(uio) <= (int)max_len))) {
   13837             : #endif
   13838             : #else
   13839           0 :                             (uio->uio_resid && (uio->uio_resid <= (int)max_len))) {
   13840             : #endif
   13841           0 :                                 sndout = 0;
   13842           0 :                                 new_tail = NULL;
   13843           0 :                                 if (hold_tcblock) {
   13844           0 :                                         SCTP_TCB_UNLOCK(stcb);
   13845           0 :                                         hold_tcblock = 0;
   13846             :                                 }
   13847             : #if defined(__APPLE__)
   13848             :                                 SCTP_SOCKET_UNLOCK(so, 0);
   13849             : #endif
   13850             : #if defined(__FreeBSD__) && __FreeBSD_version > 602000
   13851             :                                     mm = sctp_copy_resume(uio, max_len, user_marks_eor, &error, &sndout, &new_tail);
   13852             : #else
   13853           0 :                                     mm = sctp_copy_resume(uio, max_len, &error, &sndout, &new_tail);
   13854             : #endif
   13855             : #if defined(__APPLE__)
   13856             :                                 SCTP_SOCKET_LOCK(so, 0);
   13857             : #endif
   13858           0 :                                 if ((mm == NULL) || error) {
   13859           0 :                                         if (mm) {
   13860           0 :                                                 sctp_m_freem(mm);
   13861             :                                         }
   13862           0 :                                         goto out;
   13863             :                                 }
   13864             :                                 /* Update the mbuf and count */
   13865           0 :                                 SCTP_TCB_SEND_LOCK(stcb);
   13866           0 :                                 if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
   13867             :                                         /* we need to get out.
   13868             :                                          * Peer probably aborted.
   13869             :                                          */
   13870           0 :                                         sctp_m_freem(mm);
   13871           0 :                                         if (stcb->asoc.state & SCTP_PCB_FLAGS_WAS_ABORTED) {
   13872             :                                                 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ECONNRESET);
   13873           0 :                                                 error = ECONNRESET;
   13874             :                                         }
   13875           0 :                                         SCTP_TCB_SEND_UNLOCK(stcb);
   13876           0 :                                         goto out;
   13877             :                                 }
   13878           0 :                                 if (sp->tail_mbuf) {
   13879             :                                         /* tack it to the end */
   13880           0 :                                         SCTP_BUF_NEXT(sp->tail_mbuf) = mm;
   13881           0 :                                         sp->tail_mbuf = new_tail;
   13882             :                                 } else {
   13883             :                                         /* A stolen mbuf */
   13884           0 :                                         sp->data = mm;
   13885           0 :                                         sp->tail_mbuf = new_tail;
   13886             :                                 }
   13887           0 :                                 sctp_snd_sb_alloc(stcb, sndout);
   13888           0 :                                 atomic_add_int(&sp->length,sndout);
   13889           0 :                                 len += sndout;
   13890             : 
   13891             :                                 /* Did we reach EOR? */
   13892             : #if defined(__APPLE__)
   13893             : #if defined(APPLE_LEOPARD)
   13894             :                                 if ((uio->uio_resid == 0) &&
   13895             : #else
   13896             :                                 if ((uio_resid(uio) == 0) &&
   13897             : #endif
   13898             : #else
   13899           0 :                                 if ((uio->uio_resid == 0) &&
   13900             : #endif
   13901           0 :                                     ((user_marks_eor == 0) ||
   13902           0 :                                      (srcv->sinfo_flags & SCTP_EOF) ||
   13903           0 :                                      (user_marks_eor && (srcv->sinfo_flags & SCTP_EOR)))) {
   13904           0 :                                         sp->msg_is_complete = 1;
   13905             :                                 } else {
   13906           0 :                                         sp->msg_is_complete = 0;
   13907             :                                 }
   13908           0 :                                 SCTP_TCB_SEND_UNLOCK(stcb);
   13909             :                         }
   13910             : #if defined(__APPLE__)
   13911             : #if defined(APPLE_LEOPARD)
   13912             :                         if (uio->uio_resid == 0) {
   13913             : #else
   13914             :                         if (uio_resid(uio) == 0) {
   13915             : #endif
   13916             : #else
   13917           0 :                         if (uio->uio_resid == 0) {
   13918             : #endif
   13919             :                                 /* got it all? */
   13920           0 :                                 continue;
   13921             :                         }
   13922             :                         /* PR-SCTP? */
   13923           0 :                         if ((asoc->prsctp_supported) && (asoc->sent_queue_cnt_removeable > 0)) {
   13924             :                                 /* This is ugly but we must assure locking order */
   13925           0 :                                 if (hold_tcblock == 0) {
   13926           0 :                                         SCTP_TCB_LOCK(stcb);
   13927           0 :                                         hold_tcblock = 1;
   13928             :                                 }
   13929           0 :                                 sctp_prune_prsctp(stcb, asoc, srcv, sndlen);
   13930           0 :                                 inqueue_bytes = stcb->asoc.total_output_queue_size - (stcb->asoc.chunks_on_out_queue * sizeof(struct sctp_data_chunk));
   13931           0 :                                 if (SCTP_SB_LIMIT_SND(so) > stcb->asoc.total_output_queue_size)
   13932           0 :                                         max_len = SCTP_SB_LIMIT_SND(so) - inqueue_bytes;
   13933             :                                 else
   13934           0 :                                         max_len = 0;
   13935           0 :                                 if (max_len > 0) {
   13936           0 :                                         continue;
   13937             :                                 }
   13938           0 :                                 SCTP_TCB_UNLOCK(stcb);
   13939           0 :                                 hold_tcblock = 0;
   13940             :                         }
   13941             :                         /* wait for space now */
   13942           0 :                         if (non_blocking) {
   13943             :                                 /* Non-blocking io in place out */
   13944           0 :                                 goto skip_out_eof;
   13945             :                         }
   13946             :                         /* What about the INIT, send it maybe */
   13947           0 :                         if (queue_only_for_init) {
   13948           0 :                                 if (hold_tcblock == 0) {
   13949           0 :                                         SCTP_TCB_LOCK(stcb);
   13950           0 :                                         hold_tcblock = 1;
   13951             :                                 }
   13952           0 :                                 if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) {
   13953             :                                         /* a collision took us forward? */
   13954           0 :                                         queue_only = 0;
   13955             :                                 } else {
   13956           0 :                                         sctp_send_initiate(inp, stcb, SCTP_SO_LOCKED);
   13957           0 :                                         SCTP_SET_STATE(asoc, SCTP_STATE_COOKIE_WAIT);
   13958           0 :                                         queue_only = 1;
   13959             :                                 }
   13960             :                         }
   13961           0 :                         if ((net->flight_size > net->cwnd) &&
   13962           0 :                             (asoc->sctp_cmt_on_off == 0)) {
   13963           0 :                                 SCTP_STAT_INCR(sctps_send_cwnd_avoid);
   13964           0 :                                 queue_only = 1;
   13965           0 :                         } else if (asoc->ifp_had_enobuf) {
   13966           0 :                                 SCTP_STAT_INCR(sctps_ifnomemqueued);
   13967           0 :                                 if (net->flight_size > (2 * net->mtu)) {
   13968           0 :                                         queue_only = 1;
   13969             :                                 }
   13970           0 :                                 asoc->ifp_had_enobuf = 0;
   13971             :                         }
   13972           0 :                         un_sent = ((stcb->asoc.total_output_queue_size - stcb->asoc.total_flight) +
   13973           0 :                                    (stcb->asoc.stream_queue_cnt * sizeof(struct sctp_data_chunk)));
   13974           0 :                         if ((sctp_is_feature_off(inp, SCTP_PCB_FLAGS_NODELAY)) &&
   13975           0 :                             (stcb->asoc.total_flight > 0) &&
   13976           0 :                             (stcb->asoc.stream_queue_cnt < SCTP_MAX_DATA_BUNDLING) &&
   13977           0 :                             (un_sent < (int)(stcb->asoc.smallest_mtu - SCTP_MIN_OVERHEAD))) {
   13978             : 
   13979             :                                 /*-
   13980             :                                  * Ok, Nagle is set on and we have data outstanding.
   13981             :                                  * Don't send anything and let SACKs drive out the
   13982             :                                  * data unless wen have a "full" segment to send.
   13983             :                                  */
   13984           0 :                                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_NAGLE_LOGGING_ENABLE) {
   13985           0 :                                         sctp_log_nagle_event(stcb, SCTP_NAGLE_APPLIED);
   13986             :                                 }
   13987           0 :                                 SCTP_STAT_INCR(sctps_naglequeued);
   13988           0 :                                 nagle_applies = 1;
   13989             :                         } else {
   13990           0 :                                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_NAGLE_LOGGING_ENABLE) {
   13991           0 :                                         if (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_NODELAY))
   13992           0 :                                                 sctp_log_nagle_event(stcb, SCTP_NAGLE_SKIPPED);
   13993             :                                 }
   13994           0 :                                 SCTP_STAT_INCR(sctps_naglesent);
   13995           0 :                                 nagle_applies = 0;
   13996             :                         }
   13997           0 :                         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_BLK_LOGGING_ENABLE) {
   13998             : 
   13999           0 :                                 sctp_misc_ints(SCTP_CWNDLOG_PRESEND, queue_only_for_init, queue_only,
   14000             :                                                nagle_applies, un_sent);
   14001           0 :                                 sctp_misc_ints(SCTP_CWNDLOG_PRESEND, stcb->asoc.total_output_queue_size,
   14002             :                                                stcb->asoc.total_flight,
   14003             :                                                stcb->asoc.chunks_on_out_queue, stcb->asoc.total_flight_count);
   14004             :                         }
   14005           0 :                         if (queue_only_for_init)
   14006           0 :                                 queue_only_for_init = 0;
   14007           0 :                         if ((queue_only == 0) && (nagle_applies == 0)) {
   14008             :                                 /*-
   14009             :                                  * need to start chunk output
   14010             :                                  * before blocking.. note that if
   14011             :                                  * a lock is already applied, then
   14012             :                                  * the input via the net is happening
   14013             :                                  * and I don't need to start output :-D
   14014             :                                  */
   14015           0 :                                 if (hold_tcblock == 0) {
   14016           0 :                                         if (SCTP_TCB_TRYLOCK(stcb)) {
   14017           0 :                                                 hold_tcblock = 1;
   14018           0 :                                                 sctp_chunk_output(inp,
   14019             :                                                                   stcb,
   14020             :                                                                   SCTP_OUTPUT_FROM_USR_SEND, SCTP_SO_LOCKED);
   14021             :                                         }
   14022             :                                 } else {
   14023           0 :                                         sctp_chunk_output(inp,
   14024             :                                                           stcb,
   14025             :                                                           SCTP_OUTPUT_FROM_USR_SEND, SCTP_SO_LOCKED);
   14026             :                                 }
   14027           0 :                                 if (hold_tcblock == 1) {
   14028           0 :                                         SCTP_TCB_UNLOCK(stcb);
   14029           0 :                                         hold_tcblock = 0;
   14030             :                                 }
   14031             :                         }
   14032           0 :                         SOCKBUF_LOCK(&so->so_snd);
   14033             :                         /*-
   14034             :                          * This is a bit strange, but I think it will
   14035             :                          * work. The total_output_queue_size is locked and
   14036             :                          * protected by the TCB_LOCK, which we just released.
   14037             :                          * There is a race that can occur between releasing it
   14038             :                          * above, and me getting the socket lock, where sacks
   14039             :                          * come in but we have not put the SB_WAIT on the
   14040             :                          * so_snd buffer to get the wakeup. After the LOCK
   14041             :                          * is applied the sack_processing will also need to
   14042             :                          * LOCK the so->so_snd to do the actual sowwakeup(). So
   14043             :                          * once we have the socket buffer lock if we recheck the
   14044             :                          * size we KNOW we will get to sleep safely with the
   14045             :                          * wakeup flag in place.
   14046             :                          */
   14047           0 :                         if (SCTP_SB_LIMIT_SND(so) <= (stcb->asoc.total_output_queue_size +
   14048           0 :                                                       min(SCTP_BASE_SYSCTL(sctp_add_more_threshold), SCTP_SB_LIMIT_SND(so)))) {
   14049           0 :                                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_BLK_LOGGING_ENABLE) {
   14050             : #if defined(__APPLE__)
   14051             : #if defined(APPLE_LEOPARD)
   14052             :                                         sctp_log_block(SCTP_BLOCK_LOG_INTO_BLK,
   14053             :                                                        asoc, uio->uio_resid);
   14054             : #else
   14055             :                                         sctp_log_block(SCTP_BLOCK_LOG_INTO_BLK,
   14056             :                                                        asoc, uio_resid(uio));
   14057             : #endif
   14058             : #else
   14059           0 :                                         sctp_log_block(SCTP_BLOCK_LOG_INTO_BLK,
   14060             :                                                        asoc, uio->uio_resid);
   14061             : #endif
   14062             :                                 }
   14063           0 :                                 be.error = 0;
   14064             : #if !defined(__Panda__) && !defined(__Windows__)
   14065           0 :                                 stcb->block_entry = &be;
   14066             : #endif
   14067             : #if defined(__APPLE__)
   14068             :                                 sbunlock(&so->so_snd, 1);
   14069             : #endif
   14070           0 :                                 error = sbwait(&so->so_snd);
   14071           0 :                                 stcb->block_entry = NULL;
   14072             : 
   14073           0 :                                 if (error || so->so_error || be.error) {
   14074           0 :                                         if (error == 0) {
   14075           0 :                                                 if (so->so_error)
   14076           0 :                                                         error = so->so_error;
   14077           0 :                                                 if (be.error) {
   14078           0 :                                                         error = be.error;
   14079             :                                                 }
   14080             :                                         }
   14081           0 :                                         SOCKBUF_UNLOCK(&so->so_snd);
   14082           0 :                                         goto out_unlocked;
   14083             :                                 }
   14084             : 
   14085             : #if defined(__APPLE__)
   14086             :                                 error = sblock(&so->so_snd, SBLOCKWAIT(flags));
   14087             : #endif
   14088           0 :                                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_BLK_LOGGING_ENABLE) {
   14089           0 :                                         sctp_log_block(SCTP_BLOCK_LOG_OUTOF_BLK,
   14090           0 :                                                        asoc, stcb->asoc.total_output_queue_size);
   14091             :                                 }
   14092             :                         }
   14093           0 :                         SOCKBUF_UNLOCK(&so->so_snd);
   14094           0 :                         if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
   14095           0 :                                 goto out_unlocked;
   14096             :                         }
   14097             :                 }
   14098           0 :                 SCTP_TCB_SEND_LOCK(stcb);
   14099           0 :                 if (sp) {
   14100           0 :                         if (sp->msg_is_complete == 0) {
   14101           0 :                                 strm->last_msg_incomplete = 1;
   14102           0 :                                 asoc->stream_locked = 1;
   14103           0 :                                 asoc->stream_locked_on  = srcv->sinfo_stream;
   14104             :                         } else {
   14105           0 :                                 sp->sender_all_done = 1;
   14106           0 :                                 strm->last_msg_incomplete = 0;
   14107           0 :                                 asoc->stream_locked = 0;
   14108             :                         }
   14109             :                 } else {
   14110           0 :                         SCTP_PRINTF("Huh no sp TSNH?\n");
   14111           0 :                         strm->last_msg_incomplete = 0;
   14112           0 :                         asoc->stream_locked = 0;
   14113             :                 }
   14114           0 :                 SCTP_TCB_SEND_UNLOCK(stcb);
   14115             : #if defined(__APPLE__)
   14116             : #if defined(APPLE_LEOPARD)
   14117             :                 if (uio->uio_resid == 0) {
   14118             : #else
   14119             :                 if (uio_resid(uio) == 0) {
   14120             : #endif
   14121             : #else
   14122           0 :                 if (uio->uio_resid == 0) {
   14123             : #endif
   14124           0 :                         got_all_of_the_send = 1;
   14125             :                 }
   14126             :         } else {
   14127             :                 /* We send in a 0, since we do NOT have any locks */
   14128           0 :                 error = sctp_msg_append(stcb, net, top, srcv, 0);
   14129           0 :                 top = NULL;
   14130           0 :                 if (srcv->sinfo_flags & SCTP_EOF) {
   14131             :                         /*
   14132             :                          * This should only happen for Panda for the mbuf
   14133             :                          * send case, which does NOT yet support EEOR mode.
   14134             :                          * Thus, we can just set this flag to do the proper
   14135             :                          * EOF handling.
   14136             :                          */
   14137           0 :                         got_all_of_the_send = 1;
   14138             :                 }
   14139             :         }
   14140           0 :         if (error) {
   14141           0 :                 goto out;
   14142             :         }
   14143             : dataless_eof:
   14144             :         /* EOF thing ? */
   14145           0 :         if ((srcv->sinfo_flags & SCTP_EOF) &&
   14146             :             (got_all_of_the_send == 1)) {
   14147             :                 int cnt;
   14148           0 :                 SCTP_STAT_INCR(sctps_sends_with_eof);
   14149           0 :                 error = 0;
   14150           0 :                 if (hold_tcblock == 0) {
   14151           0 :                         SCTP_TCB_LOCK(stcb);
   14152           0 :                         hold_tcblock = 1;
   14153             :                 }
   14154           0 :                 cnt = sctp_is_there_unsent_data(stcb, SCTP_SO_LOCKED);
   14155           0 :                 if (TAILQ_EMPTY(&asoc->send_queue) &&
   14156           0 :                     TAILQ_EMPTY(&asoc->sent_queue) &&
   14157             :                     (cnt == 0)) {
   14158           0 :                         if (asoc->locked_on_sending) {
   14159           0 :                                 goto abort_anyway;
   14160             :                         }
   14161             :                         /* there is nothing queued to send, so I'm done... */
   14162           0 :                         if ((SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) &&
   14163           0 :                             (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_RECEIVED) &&
   14164           0 :                             (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT)) {
   14165             :                                 struct sctp_nets *netp;
   14166             : 
   14167             :                                 /* only send SHUTDOWN the first time through */
   14168           0 :                                 if (SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) {
   14169           0 :                                         SCTP_STAT_DECR_GAUGE32(sctps_currestab);
   14170             :                                 }
   14171           0 :                                 SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_SENT);
   14172           0 :                                 SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
   14173           0 :                                 sctp_stop_timers_for_shutdown(stcb);
   14174           0 :                                 if (stcb->asoc.alternate) {
   14175           0 :                                         netp = stcb->asoc.alternate;
   14176             :                                 } else {
   14177           0 :                                         netp = stcb->asoc.primary_destination;
   14178             :                                 }
   14179           0 :                                 sctp_send_shutdown(stcb, netp);
   14180           0 :                                 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, stcb->sctp_ep, stcb,
   14181             :                                                  netp);
   14182           0 :                                 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, stcb->sctp_ep, stcb,
   14183             :                                                  asoc->primary_destination);
   14184             :                         }
   14185             :                 } else {
   14186             :                         /*-
   14187             :                          * we still got (or just got) data to send, so set
   14188             :                          * SHUTDOWN_PENDING
   14189             :                          */
   14190             :                         /*-
   14191             :                          * XXX sockets draft says that SCTP_EOF should be
   14192             :                          * sent with no data.  currently, we will allow user
   14193             :                          * data to be sent first and move to
   14194             :                          * SHUTDOWN-PENDING
   14195             :                          */
   14196           0 :                         if ((SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) &&
   14197           0 :                             (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_RECEIVED) &&
   14198           0 :                             (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT)) {
   14199           0 :                                 if (hold_tcblock == 0) {
   14200           0 :                                         SCTP_TCB_LOCK(stcb);
   14201           0 :                                         hold_tcblock = 1;
   14202             :                                 }
   14203           0 :                                 if (asoc->locked_on_sending) {
   14204             :                                         /* Locked to send out the data */
   14205             :                                         struct sctp_stream_queue_pending *sp;
   14206           0 :                                         sp = TAILQ_LAST(&asoc->locked_on_sending->outqueue, sctp_streamhead);
   14207           0 :                                         if (sp) {
   14208           0 :                                                 if ((sp->length == 0) && (sp->msg_is_complete == 0))
   14209           0 :                                                         asoc->state |= SCTP_STATE_PARTIAL_MSG_LEFT;
   14210             :                                         }
   14211             :                                 }
   14212           0 :                                 asoc->state |= SCTP_STATE_SHUTDOWN_PENDING;
   14213           0 :                                 if (TAILQ_EMPTY(&asoc->send_queue) &&
   14214           0 :                                     TAILQ_EMPTY(&asoc->sent_queue) &&
   14215           0 :                                     (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT)) {
   14216             :                                 abort_anyway:
   14217           0 :                                         if (free_cnt_applied) {
   14218           0 :                                                 atomic_add_int(&stcb->asoc.refcnt, -1);
   14219           0 :                                                 free_cnt_applied = 0;
   14220             :                                         }
   14221           0 :                                         sctp_abort_an_association(stcb->sctp_ep, stcb,
   14222             :                                                                   NULL, SCTP_SO_LOCKED);
   14223             :                                         /* now relock the stcb so everything is sane */
   14224           0 :                                         hold_tcblock = 0;
   14225           0 :                                         stcb = NULL;
   14226           0 :                                         goto out;
   14227             :                                 }
   14228           0 :                                 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, stcb->sctp_ep, stcb,
   14229             :                                                  asoc->primary_destination);
   14230           0 :                                 sctp_feature_off(inp, SCTP_PCB_FLAGS_NODELAY);
   14231             :                         }
   14232             :                 }
   14233             :         }
   14234             : skip_out_eof:
   14235           0 :         if (!TAILQ_EMPTY(&stcb->asoc.control_send_queue)) {
   14236           0 :                 some_on_control = 1;
   14237             :         }
   14238           0 :         if (queue_only_for_init) {
   14239           0 :                 if (hold_tcblock == 0) {
   14240           0 :                         SCTP_TCB_LOCK(stcb);
   14241           0 :                         hold_tcblock = 1;
   14242             :                 }
   14243           0 :                 if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) {
   14244             :                         /* a collision took us forward? */
   14245           0 :                         queue_only = 0;
   14246             :                 } else {
   14247           0 :                         sctp_send_initiate(inp, stcb, SCTP_SO_LOCKED);
   14248           0 :                         SCTP_SET_STATE(&stcb->asoc, SCTP_STATE_COOKIE_WAIT);
   14249           0 :                         queue_only = 1;
   14250             :                 }
   14251             :         }
   14252           0 :         if ((net->flight_size > net->cwnd) &&
   14253           0 :             (stcb->asoc.sctp_cmt_on_off == 0)) {
   14254           0 :                 SCTP_STAT_INCR(sctps_send_cwnd_avoid);
   14255           0 :                 queue_only = 1;
   14256           0 :         } else if (asoc->ifp_had_enobuf) {
   14257           0 :                 SCTP_STAT_INCR(sctps_ifnomemqueued);
   14258           0 :                 if (net->flight_size > (2 * net->mtu)) {
   14259           0 :                         queue_only = 1;
   14260             :                 }
   14261           0 :                 asoc->ifp_had_enobuf = 0;
   14262             :         }
   14263           0 :         un_sent = ((stcb->asoc.total_output_queue_size - stcb->asoc.total_flight) +
   14264           0 :                    (stcb->asoc.stream_queue_cnt * sizeof(struct sctp_data_chunk)));
   14265           0 :         if ((sctp_is_feature_off(inp, SCTP_PCB_FLAGS_NODELAY)) &&
   14266           0 :             (stcb->asoc.total_flight > 0) &&
   14267           0 :             (stcb->asoc.stream_queue_cnt < SCTP_MAX_DATA_BUNDLING) &&
   14268           0 :             (un_sent < (int)(stcb->asoc.smallest_mtu - SCTP_MIN_OVERHEAD))) {
   14269             :                 /*-
   14270             :                  * Ok, Nagle is set on and we have data outstanding.
   14271             :                  * Don't send anything and let SACKs drive out the
   14272             :                  * data unless wen have a "full" segment to send.
   14273             :                  */
   14274           0 :                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_NAGLE_LOGGING_ENABLE) {
   14275           0 :                         sctp_log_nagle_event(stcb, SCTP_NAGLE_APPLIED);
   14276             :                 }
   14277           0 :                 SCTP_STAT_INCR(sctps_naglequeued);
   14278           0 :                 nagle_applies = 1;
   14279             :         } else {
   14280           0 :                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_NAGLE_LOGGING_ENABLE) {
   14281           0 :                         if (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_NODELAY))
   14282           0 :                                 sctp_log_nagle_event(stcb, SCTP_NAGLE_SKIPPED);
   14283             :                 }
   14284           0 :                 SCTP_STAT_INCR(sctps_naglesent);
   14285           0 :                 nagle_applies = 0;
   14286             :         }
   14287           0 :         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_BLK_LOGGING_ENABLE) {
   14288           0 :                 sctp_misc_ints(SCTP_CWNDLOG_PRESEND, queue_only_for_init, queue_only,
   14289             :                                nagle_applies, un_sent);
   14290           0 :                 sctp_misc_ints(SCTP_CWNDLOG_PRESEND, stcb->asoc.total_output_queue_size,
   14291             :                                stcb->asoc.total_flight,
   14292             :                                stcb->asoc.chunks_on_out_queue, stcb->asoc.total_flight_count);
   14293             :         }
   14294           0 :         if ((queue_only == 0) && (nagle_applies == 0) && (stcb->asoc.peers_rwnd && un_sent)) {
   14295             :                 /* we can attempt to send too. */
   14296           0 :                 if (hold_tcblock == 0) {
   14297             :                         /* If there is activity recv'ing sacks no need to send */
   14298           0 :                         if (SCTP_TCB_TRYLOCK(stcb)) {
   14299           0 :                                 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_USR_SEND, SCTP_SO_LOCKED);
   14300           0 :                                 hold_tcblock = 1;
   14301             :                         }
   14302             :                 } else {
   14303           0 :                         sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_USR_SEND, SCTP_SO_LOCKED);
   14304             :                 }
   14305           0 :         } else if ((queue_only == 0) &&
   14306           0 :                    (stcb->asoc.peers_rwnd == 0) &&
   14307           0 :                    (stcb->asoc.total_flight == 0)) {
   14308             :                 /* We get to have a probe outstanding */
   14309           0 :                 if (hold_tcblock == 0) {
   14310           0 :                         hold_tcblock = 1;
   14311           0 :                         SCTP_TCB_LOCK(stcb);
   14312             :                 }
   14313           0 :                 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_USR_SEND, SCTP_SO_LOCKED);
   14314           0 :         } else if (some_on_control) {
   14315             :                 int num_out, reason, frag_point;
   14316             : 
   14317             :                 /* Here we do control only */
   14318           0 :                 if (hold_tcblock == 0) {
   14319           0 :                         hold_tcblock = 1;
   14320           0 :                         SCTP_TCB_LOCK(stcb);
   14321             :                 }
   14322           0 :                 frag_point = sctp_get_frag_point(stcb, &stcb->asoc);
   14323           0 :                 (void)sctp_med_chunk_output(inp, stcb, &stcb->asoc, &num_out,
   14324             :                                             &reason, 1, 1, &now, &now_filled, frag_point, SCTP_SO_LOCKED);
   14325             :         }
   14326           0 :         SCTPDBG(SCTP_DEBUG_OUTPUT1, "USR Send complete qo:%d prw:%d unsent:%d tf:%d cooq:%d toqs:%d err:%d\n",
   14327             :                 queue_only, stcb->asoc.peers_rwnd, un_sent,
   14328             :                 stcb->asoc.total_flight, stcb->asoc.chunks_on_out_queue,
   14329             :                 stcb->asoc.total_output_queue_size, error);
   14330             : 
   14331             : out:
   14332             : #if defined(__APPLE__)
   14333             :         sbunlock(&so->so_snd, 1);
   14334             : #endif
   14335             : out_unlocked:
   14336             : 
   14337           0 :         if (local_soresv && stcb) {
   14338           0 :                 atomic_subtract_int(&stcb->asoc.sb_send_resv, sndlen);
   14339             :         }
   14340           0 :         if (create_lock_applied) {
   14341           0 :                 SCTP_ASOC_CREATE_UNLOCK(inp);
   14342             :         }
   14343           0 :         if ((stcb) && hold_tcblock) {
   14344           0 :                 SCTP_TCB_UNLOCK(stcb);
   14345             :         }
   14346           0 :         if (stcb && free_cnt_applied) {
   14347           0 :                 atomic_add_int(&stcb->asoc.refcnt, -1);
   14348             :         }
   14349             : #ifdef INVARIANTS
   14350             : #if !defined(__APPLE__)
   14351             :         if (stcb) {
   14352             :                 if (mtx_owned(&stcb->tcb_mtx)) {
   14353             :                         panic("Leaving with tcb mtx owned?");
   14354             :                 }
   14355             :                 if (mtx_owned(&stcb->tcb_send_mtx)) {
   14356             :                         panic("Leaving with tcb send mtx owned?");
   14357             :                 }
   14358             :         }
   14359             : #endif
   14360             : #endif
   14361             : #ifdef __Panda__
   14362             :         /*
   14363             :          * Handle the EAGAIN/ENOMEM cases to reattach the pak header
   14364             :          * to particle when pak is passed in, so that caller
   14365             :          * can try again with this pak
   14366             :          *
   14367             :          * NOTE: For other cases, including success case,
   14368             :          * we simply want to return the header back to free
   14369             :          * pool
   14370             :          */
   14371             :         if (top) {
   14372             :                 if ((error == EAGAIN) || (error == ENOMEM)) {
   14373             :                         SCTP_ATTACH_CHAIN(i_pak, top, sndlen);
   14374             :                         top = NULL;
   14375             :                 } else {
   14376             :                         (void)SCTP_RELEASE_HEADER(i_pak);
   14377             :                 }
   14378             :         } else {
   14379             :                 /* This is to handle cases when top has
   14380             :                  * been reset to NULL but pak might not
   14381             :                  * be freed
   14382             :                  */
   14383             :                 if (i_pak) {
   14384             :                         (void)SCTP_RELEASE_HEADER(i_pak);
   14385             :                 }
   14386             :         }
   14387             : #endif
   14388             : #ifdef INVARIANTS
   14389             :         if (inp) {
   14390             :                 sctp_validate_no_locks(inp);
   14391             :         } else {
   14392             :                 SCTP_PRINTF("Warning - inp is NULL so cant validate locks\n");
   14393             :         }
   14394             : #endif
   14395           0 :         if (top) {
   14396           0 :                 sctp_m_freem(top);
   14397             :         }
   14398           0 :         if (control) {
   14399           0 :                 sctp_m_freem(control);
   14400             :         }
   14401           0 :         return (error);
   14402             : }
   14403             : 
   14404             : 
   14405             : /*
   14406             :  * generate an AUTHentication chunk, if required
   14407             :  */
   14408             : struct mbuf *
   14409           0 : sctp_add_auth_chunk(struct mbuf *m, struct mbuf **m_end,
   14410             :     struct sctp_auth_chunk **auth_ret, uint32_t * offset,
   14411             :     struct sctp_tcb *stcb, uint8_t chunk)
   14412             : {
   14413             :         struct mbuf *m_auth;
   14414             :         struct sctp_auth_chunk *auth;
   14415             :         int chunk_len;
   14416             :         struct mbuf *cn;
   14417             : 
   14418           0 :         if ((m_end == NULL) || (auth_ret == NULL) || (offset == NULL) ||
   14419             :             (stcb == NULL))
   14420           0 :                 return (m);
   14421             : 
   14422           0 :         if (stcb->asoc.auth_supported == 0) {
   14423           0 :                 return (m);
   14424             :         }
   14425             :         /* does the requested chunk require auth? */
   14426           0 :         if (!sctp_auth_is_required_chunk(chunk, stcb->asoc.peer_auth_chunks)) {
   14427           0 :                 return (m);
   14428             :         }
   14429           0 :         m_auth = sctp_get_mbuf_for_msg(sizeof(*auth), 0, M_NOWAIT, 1, MT_HEADER);
   14430           0 :         if (m_auth == NULL) {
   14431             :                 /* no mbuf's */
   14432           0 :                 return (m);
   14433             :         }
   14434             :         /* reserve some space if this will be the first mbuf */
   14435           0 :         if (m == NULL)
   14436           0 :                 SCTP_BUF_RESV_UF(m_auth, SCTP_MIN_OVERHEAD);
   14437             :         /* fill in the AUTH chunk details */
   14438           0 :         auth = mtod(m_auth, struct sctp_auth_chunk *);
   14439           0 :         bzero(auth, sizeof(*auth));
   14440           0 :         auth->ch.chunk_type = SCTP_AUTHENTICATION;
   14441           0 :         auth->ch.chunk_flags = 0;
   14442           0 :         chunk_len = sizeof(*auth) +
   14443           0 :             sctp_get_hmac_digest_len(stcb->asoc.peer_hmac_id);
   14444           0 :         auth->ch.chunk_length = htons(chunk_len);
   14445           0 :         auth->hmac_id = htons(stcb->asoc.peer_hmac_id);
   14446             :         /* key id and hmac digest will be computed and filled in upon send */
   14447             : 
   14448             :         /* save the offset where the auth was inserted into the chain */
   14449           0 :         *offset = 0;
   14450           0 :         for (cn = m; cn; cn = SCTP_BUF_NEXT(cn)) {
   14451           0 :                 *offset += SCTP_BUF_LEN(cn);
   14452             :         }
   14453             : 
   14454             :         /* update length and return pointer to the auth chunk */
   14455           0 :         SCTP_BUF_LEN(m_auth) = chunk_len;
   14456           0 :         m = sctp_copy_mbufchain(m_auth, m, m_end, 1, chunk_len, 0);
   14457           0 :         if (auth_ret != NULL)
   14458           0 :                 *auth_ret = auth;
   14459             : 
   14460           0 :         return (m);
   14461             : }
   14462             : 
   14463             : #if defined(__FreeBSD__)  || defined(__APPLE__)
   14464             : #ifdef INET6
   14465             : int
   14466             : sctp_v6src_match_nexthop(struct sockaddr_in6 *src6, sctp_route_t *ro)
   14467             : {
   14468             :         struct nd_prefix *pfx = NULL;
   14469             :         struct nd_pfxrouter *pfxrtr = NULL;
   14470             :         struct sockaddr_in6 gw6;
   14471             : 
   14472             :         if (ro == NULL || ro->ro_rt == NULL || src6->sin6_family != AF_INET6)
   14473             :                 return (0);
   14474             : 
   14475             :         /* get prefix entry of address */
   14476             :         LIST_FOREACH(pfx, &MODULE_GLOBAL(nd_prefix), ndpr_entry) {
   14477             :                 if (pfx->ndpr_stateflags & NDPRF_DETACHED)
   14478             :                         continue;
   14479             :                 if (IN6_ARE_MASKED_ADDR_EQUAL(&pfx->ndpr_prefix.sin6_addr,
   14480             :                     &src6->sin6_addr, &pfx->ndpr_mask))
   14481             :                         break;
   14482             :         }
   14483             :         /* no prefix entry in the prefix list */
   14484             :         if (pfx == NULL) {
   14485             :                 SCTPDBG(SCTP_DEBUG_OUTPUT2, "No prefix entry for ");
   14486             :                 SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, (struct sockaddr *)src6);
   14487             :                 return (0);
   14488             :         }
   14489             : 
   14490             :         SCTPDBG(SCTP_DEBUG_OUTPUT2, "v6src_match_nexthop(), Prefix entry is ");
   14491             :         SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, (struct sockaddr *)src6);
   14492             : 
   14493             :         /* search installed gateway from prefix entry */
   14494             :         LIST_FOREACH(pfxrtr, &pfx->ndpr_advrtrs, pfr_entry) {
   14495             :                 memset(&gw6, 0, sizeof(struct sockaddr_in6));
   14496             :                 gw6.sin6_family = AF_INET6;
   14497             : #ifdef HAVE_SIN6_LEN
   14498             :                 gw6.sin6_len = sizeof(struct sockaddr_in6);
   14499             : #endif
   14500             :                 memcpy(&gw6.sin6_addr, &pfxrtr->router->rtaddr,
   14501             :                     sizeof(struct in6_addr));
   14502             :                 SCTPDBG(SCTP_DEBUG_OUTPUT2, "prefix router is ");
   14503             :                 SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, (struct sockaddr *)&gw6);
   14504             :                 SCTPDBG(SCTP_DEBUG_OUTPUT2, "installed router is ");
   14505             :                 SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, ro->ro_rt->rt_gateway);
   14506             :                 if (sctp_cmpaddr((struct sockaddr *)&gw6,
   14507             :                                 ro->ro_rt->rt_gateway)) {
   14508             :                         SCTPDBG(SCTP_DEBUG_OUTPUT2, "pfxrouter is installed\n");
   14509             :                         return (1);
   14510             :                 }
   14511             :         }
   14512             :         SCTPDBG(SCTP_DEBUG_OUTPUT2, "pfxrouter is not installed\n");
   14513             :         return (0);
   14514             : }
   14515             : #endif
   14516             : 
   14517             : int
   14518             : sctp_v4src_match_nexthop(struct sctp_ifa *sifa, sctp_route_t *ro)
   14519             : {
   14520             : #ifdef INET
   14521             :         struct sockaddr_in *sin, *mask;
   14522             :         struct ifaddr *ifa;
   14523             :         struct in_addr srcnetaddr, gwnetaddr;
   14524             : 
   14525             :         if (ro == NULL || ro->ro_rt == NULL ||
   14526             :             sifa->address.sa.sa_family != AF_INET) {
   14527             :                 return (0);
   14528             :         }
   14529             :         ifa = (struct ifaddr *)sifa->ifa;
   14530             :         mask = (struct sockaddr_in *)(ifa->ifa_netmask);
   14531             :         sin = &sifa->address.sin;
   14532             :         srcnetaddr.s_addr = (sin->sin_addr.s_addr & mask->sin_addr.s_addr);
   14533             :         SCTPDBG(SCTP_DEBUG_OUTPUT1, "match_nexthop4: src address is ");
   14534             :         SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, &sifa->address.sa);
   14535             :         SCTPDBG(SCTP_DEBUG_OUTPUT1, "network address is %x\n", srcnetaddr.s_addr);
   14536             : 
   14537             :         sin = (struct sockaddr_in *)ro->ro_rt->rt_gateway;
   14538             :         gwnetaddr.s_addr = (sin->sin_addr.s_addr & mask->sin_addr.s_addr);
   14539             :         SCTPDBG(SCTP_DEBUG_OUTPUT1, "match_nexthop4: nexthop is ");
   14540             :         SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, ro->ro_rt->rt_gateway);
   14541             :         SCTPDBG(SCTP_DEBUG_OUTPUT1, "network address is %x\n", gwnetaddr.s_addr);
   14542             :         if (srcnetaddr.s_addr == gwnetaddr.s_addr) {
   14543             :                 return (1);
   14544             :         }
   14545             : #endif
   14546             :         return (0);
   14547             : }
   14548             : #elif defined(__Userspace__)
   14549             : /* TODO __Userspace__ versions of sctp_vXsrc_match_nexthop(). */
   14550             : int
   14551           0 : sctp_v6src_match_nexthop(struct sockaddr_in6 *src6, sctp_route_t *ro)
   14552             : {
   14553           0 :     return (0);
   14554             : }
   14555             : int
   14556           0 : sctp_v4src_match_nexthop(struct sctp_ifa *sifa, sctp_route_t *ro)
   14557             : {
   14558           0 :     return (0);
   14559             : }
   14560             : 
   14561             : #endif

Generated by: LCOV version 1.13