Home | History | Annotate | Line # | Download | only in netinet
      1   1.1       rjs /*	$KAME: sctputil.c,v 1.39 2005/06/16 20:54:06 jinmei Exp $	*/
      2  1.21    andvar /*	$NetBSD: sctputil.c,v 1.21 2025/07/11 22:19:54 andvar Exp $	*/
      3   1.1       rjs 
      4   1.1       rjs /*
      5   1.1       rjs  * Copyright (c) 2001, 2002, 2003, 2004 Cisco Systems, Inc.
      6   1.1       rjs  * All rights reserved.
      7   1.1       rjs  *
      8   1.1       rjs  * Redistribution and use in source and binary forms, with or without
      9   1.1       rjs  * modification, are permitted provided that the following conditions
     10   1.1       rjs  * are met:
     11   1.1       rjs  * 1. Redistributions of source code must retain the above copyright
     12   1.1       rjs  *    notice, this list of conditions and the following disclaimer.
     13   1.1       rjs  * 2. Redistributions in binary form must reproduce the above copyright
     14   1.1       rjs  *    notice, this list of conditions and the following disclaimer in the
     15   1.1       rjs  *    documentation and/or other materials provided with the distribution.
     16   1.1       rjs  * 3. All advertising materials mentioning features or use of this software
     17   1.1       rjs  *    must display the following acknowledgement:
     18   1.1       rjs  *      This product includes software developed by Cisco Systems, Inc.
     19   1.1       rjs  * 4. Neither the name of the project nor the names of its contributors
     20   1.1       rjs  *    may be used to endorse or promote products derived from this software
     21   1.1       rjs  *    without specific prior written permission.
     22   1.1       rjs  *
     23   1.1       rjs  * THIS SOFTWARE IS PROVIDED BY CISCO SYSTEMS AND CONTRIBUTORS ``AS IS'' AND
     24   1.1       rjs  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     25   1.1       rjs  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     26   1.1       rjs  * ARE DISCLAIMED.  IN NO EVENT SHALL CISCO SYSTEMS OR CONTRIBUTORS BE LIABLE
     27   1.1       rjs  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     28   1.1       rjs  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     29   1.1       rjs  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     30   1.1       rjs  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     31   1.1       rjs  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     32   1.1       rjs  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     33   1.1       rjs  * SUCH DAMAGE.
     34   1.1       rjs  */
     35   1.1       rjs 
     36   1.1       rjs #include <sys/cdefs.h>
     37  1.21    andvar __KERNEL_RCSID(0, "$NetBSD: sctputil.c,v 1.21 2025/07/11 22:19:54 andvar Exp $");
     38   1.1       rjs 
     39   1.1       rjs #ifdef _KERNEL_OPT
     40   1.1       rjs #include "opt_inet.h"
     41   1.1       rjs #include "opt_ipsec.h"
     42   1.1       rjs #include "opt_sctp.h"
     43   1.1       rjs #endif /* _KERNEL_OPT */
     44   1.1       rjs 
     45   1.1       rjs #include <sys/param.h>
     46   1.1       rjs #include <sys/systm.h>
     47   1.1       rjs #include <sys/malloc.h>
     48   1.1       rjs #include <sys/mbuf.h>
     49   1.1       rjs #include <sys/domain.h>
     50   1.1       rjs #include <sys/protosw.h>
     51   1.1       rjs #include <sys/socket.h>
     52   1.1       rjs #include <sys/socketvar.h>
     53   1.1       rjs #include <sys/mutex.h>
     54   1.1       rjs #include <sys/proc.h>
     55   1.1       rjs #include <sys/kernel.h>
     56   1.1       rjs #include <sys/sysctl.h>
     57  1.16  riastrad #include <sys/cprng.h>
     58   1.1       rjs 
     59   1.1       rjs #include <sys/callout.h>
     60   1.1       rjs 
     61   1.1       rjs #include <net/route.h>
     62   1.1       rjs 
     63   1.1       rjs #ifdef INET6
     64   1.1       rjs #include <sys/domain.h>
     65   1.1       rjs #endif
     66   1.1       rjs 
     67   1.1       rjs #include <machine/limits.h>
     68   1.1       rjs 
     69   1.1       rjs #include <net/if.h>
     70   1.1       rjs #include <net/if_types.h>
     71   1.1       rjs #include <net/route.h>
     72   1.1       rjs 
     73   1.1       rjs #include <netinet/in.h>
     74   1.1       rjs #include <netinet/in_systm.h>
     75   1.1       rjs #include <netinet/ip.h>
     76   1.1       rjs #include <netinet/in_pcb.h>
     77   1.1       rjs #include <netinet/in_var.h>
     78   1.1       rjs #include <netinet/ip_var.h>
     79   1.1       rjs 
     80   1.1       rjs #ifdef INET6
     81   1.1       rjs #include <netinet/ip6.h>
     82   1.1       rjs #include <netinet6/ip6_var.h>
     83   1.1       rjs #include <netinet6/scope6_var.h>
     84   1.1       rjs #include <netinet6/in6_pcb.h>
     85   1.1       rjs 
     86   1.1       rjs #endif /* INET6 */
     87   1.1       rjs 
     88   1.1       rjs #include <netinet/sctp_pcb.h>
     89   1.1       rjs 
     90   1.1       rjs #ifdef IPSEC
     91   1.6       rjs #include <netipsec/ipsec.h>
     92   1.6       rjs #include <netipsec/key.h>
     93   1.1       rjs #endif /* IPSEC */
     94   1.1       rjs 
     95   1.1       rjs #include <netinet/sctputil.h>
     96   1.1       rjs #include <netinet/sctp_var.h>
     97   1.1       rjs #ifdef INET6
     98   1.1       rjs #include <netinet6/sctp6_var.h>
     99   1.1       rjs #endif
    100   1.1       rjs #include <netinet/sctp_header.h>
    101   1.1       rjs #include <netinet/sctp_output.h>
    102   1.1       rjs #include <netinet/sctp_hashdriver.h>
    103   1.1       rjs #include <netinet/sctp_uio.h>
    104   1.1       rjs #include <netinet/sctp_timer.h>
    105   1.1       rjs #include <netinet/sctp_crc32.h>
    106   1.1       rjs #include <netinet/sctp_indata.h>	/* for sctp_deliver_data() */
    107   1.1       rjs #define NUMBER_OF_MTU_SIZES 18
    108   1.1       rjs 
    109   1.1       rjs #ifdef SCTP_DEBUG
    110   1.1       rjs extern u_int32_t sctp_debug_on;
    111   1.1       rjs #endif
    112   1.1       rjs 
    113   1.1       rjs #ifdef SCTP_STAT_LOGGING
    114   1.1       rjs int sctp_cwnd_log_at=0;
    115   1.1       rjs int sctp_cwnd_log_rolled=0;
    116   1.1       rjs struct sctp_cwnd_log sctp_clog[SCTP_STAT_LOG_SIZE];
    117   1.1       rjs 
    118   1.1       rjs void sctp_clr_stat_log(void)
    119   1.1       rjs {
    120   1.1       rjs 	sctp_cwnd_log_at=0;
    121   1.1       rjs 	sctp_cwnd_log_rolled=0;
    122   1.1       rjs }
    123   1.1       rjs 
    124   1.1       rjs void
    125   1.1       rjs sctp_log_strm_del_alt(u_int32_t tsn, u_int16_t sseq, int from)
    126   1.1       rjs {
    127   1.1       rjs 
    128   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
    129   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_STRM;
    130   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.strlog.n_tsn = tsn;
    131   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.strlog.n_sseq = sseq;
    132   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.strlog.e_tsn = 0;
    133   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.strlog.e_sseq = 0;
    134   1.1       rjs 	sctp_cwnd_log_at++;
    135   1.1       rjs 	if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
    136   1.1       rjs 		sctp_cwnd_log_at = 0;
    137   1.1       rjs 		sctp_cwnd_log_rolled = 1;
    138   1.1       rjs 	}
    139   1.1       rjs 
    140   1.1       rjs }
    141   1.1       rjs 
    142   1.1       rjs void
    143   1.1       rjs sctp_log_map(uint32_t map, uint32_t cum, uint32_t high, int from)
    144   1.1       rjs {
    145   1.1       rjs 
    146   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
    147   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_MAP;
    148   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.map.base = map;
    149   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.map.cum = cum;
    150   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.map.high = high;
    151   1.1       rjs 	sctp_cwnd_log_at++;
    152   1.1       rjs 	if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
    153   1.1       rjs 		sctp_cwnd_log_at = 0;
    154   1.1       rjs 		sctp_cwnd_log_rolled = 1;
    155   1.1       rjs 	}
    156   1.1       rjs }
    157   1.1       rjs 
    158   1.1       rjs void
    159   1.1       rjs sctp_log_fr(uint32_t biggest_tsn, uint32_t biggest_new_tsn, uint32_t tsn,
    160   1.1       rjs     int from)
    161   1.1       rjs {
    162   1.1       rjs 
    163   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
    164   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_FR;
    165   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.fr.largest_tsn = biggest_tsn;
    166   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.fr.largest_new_tsn = biggest_new_tsn;
    167   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.fr.tsn = tsn;
    168   1.1       rjs 	sctp_cwnd_log_at++;
    169   1.1       rjs 	if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
    170   1.1       rjs 		sctp_cwnd_log_at = 0;
    171   1.1       rjs 		sctp_cwnd_log_rolled = 1;
    172   1.1       rjs 	}
    173   1.1       rjs }
    174   1.1       rjs 
    175   1.1       rjs void
    176   1.1       rjs sctp_log_strm_del(struct sctp_tmit_chunk *chk, struct sctp_tmit_chunk *poschk,
    177   1.1       rjs     int from)
    178   1.1       rjs {
    179   1.1       rjs 
    180   1.1       rjs 	if (chk == NULL) {
    181   1.1       rjs 		printf("Gak log of NULL?\n");
    182   1.1       rjs 		return;
    183   1.1       rjs 	}
    184   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
    185   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_STRM;
    186   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.strlog.n_tsn = chk->rec.data.TSN_seq;
    187   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.strlog.n_sseq = chk->rec.data.stream_seq;
    188   1.1       rjs 	if (poschk != NULL) {
    189   1.1       rjs 		sctp_clog[sctp_cwnd_log_at].x.strlog.e_tsn =
    190   1.1       rjs 		    poschk->rec.data.TSN_seq;
    191   1.1       rjs 		sctp_clog[sctp_cwnd_log_at].x.strlog.e_sseq =
    192   1.1       rjs 		    poschk->rec.data.stream_seq;
    193   1.1       rjs 	} else {
    194   1.1       rjs 		sctp_clog[sctp_cwnd_log_at].x.strlog.e_tsn = 0;
    195   1.1       rjs 		sctp_clog[sctp_cwnd_log_at].x.strlog.e_sseq = 0;
    196   1.1       rjs 	}
    197   1.1       rjs 	sctp_cwnd_log_at++;
    198   1.1       rjs 	if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
    199   1.1       rjs 		sctp_cwnd_log_at = 0;
    200   1.1       rjs 		sctp_cwnd_log_rolled = 1;
    201   1.1       rjs 	}
    202   1.1       rjs }
    203   1.1       rjs 
    204   1.1       rjs void
    205   1.1       rjs sctp_log_cwnd(struct sctp_nets *net, int augment, uint8_t from)
    206   1.1       rjs {
    207   1.1       rjs 
    208   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
    209   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_CWND;
    210   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.cwnd.net = net;
    211   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.cwnd.cwnd_new_value = net->cwnd;
    212   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.cwnd.inflight = net->flight_size;
    213   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.cwnd.cwnd_augment = augment;
    214   1.1       rjs 	sctp_cwnd_log_at++;
    215   1.1       rjs 	if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
    216   1.1       rjs 		sctp_cwnd_log_at = 0;
    217   1.1       rjs 		sctp_cwnd_log_rolled = 1;
    218   1.1       rjs 	}
    219   1.1       rjs }
    220   1.1       rjs 
    221   1.1       rjs void
    222   1.1       rjs sctp_log_maxburst(struct sctp_nets *net, int error, int burst, uint8_t from)
    223   1.1       rjs {
    224   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
    225   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_MAXBURST;
    226   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.cwnd.net = net;
    227   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.cwnd.cwnd_new_value = error;
    228   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.cwnd.inflight = net->flight_size;
    229   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.cwnd.cwnd_augment = burst;
    230   1.1       rjs 	sctp_cwnd_log_at++;
    231   1.1       rjs 	if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
    232   1.1       rjs 		sctp_cwnd_log_at = 0;
    233   1.1       rjs 		sctp_cwnd_log_rolled = 1;
    234   1.1       rjs 	}
    235   1.1       rjs }
    236   1.1       rjs 
    237   1.1       rjs void
    238   1.1       rjs sctp_log_rwnd(uint8_t from, u_int32_t peers_rwnd , u_int32_t snd_size, u_int32_t overhead)
    239   1.1       rjs {
    240   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
    241   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_RWND;
    242   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.rwnd.rwnd = peers_rwnd;
    243   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.rwnd.send_size = snd_size;
    244   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.rwnd.overhead = overhead;
    245   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.rwnd.new_rwnd = 0;
    246   1.1       rjs 	sctp_cwnd_log_at++;
    247   1.1       rjs 	if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
    248   1.1       rjs 		sctp_cwnd_log_at = 0;
    249   1.1       rjs 		sctp_cwnd_log_rolled = 1;
    250   1.1       rjs 	}
    251   1.1       rjs }
    252   1.1       rjs 
    253   1.1       rjs void
    254   1.1       rjs sctp_log_rwnd_set(uint8_t from, u_int32_t peers_rwnd , u_int32_t flight_size, u_int32_t overhead, u_int32_t a_rwndval)
    255   1.1       rjs {
    256   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
    257   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_RWND;
    258   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.rwnd.rwnd = peers_rwnd;
    259   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.rwnd.send_size = flight_size;
    260   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.rwnd.overhead = overhead;
    261   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.rwnd.new_rwnd = a_rwndval;
    262   1.1       rjs 	sctp_cwnd_log_at++;
    263   1.1       rjs 	if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
    264   1.1       rjs 		sctp_cwnd_log_at = 0;
    265   1.1       rjs 		sctp_cwnd_log_rolled = 1;
    266   1.1       rjs 	}
    267   1.1       rjs }
    268   1.1       rjs 
    269   1.1       rjs void
    270   1.1       rjs sctp_log_mbcnt(uint8_t from, u_int32_t total_oq , u_int32_t book, u_int32_t total_mbcnt_q, u_int32_t mbcnt)
    271   1.1       rjs {
    272   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
    273   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_MBCNT;
    274   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.mbcnt.total_queue_size = total_oq;
    275   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.mbcnt.size_change  = book;
    276   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.mbcnt.total_queue_mb_size = total_mbcnt_q;
    277   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.mbcnt.mbcnt_change = mbcnt;
    278   1.1       rjs 	sctp_cwnd_log_at++;
    279   1.1       rjs 	if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
    280   1.1       rjs 		sctp_cwnd_log_at = 0;
    281   1.1       rjs 		sctp_cwnd_log_rolled = 1;
    282   1.1       rjs 	}
    283   1.1       rjs }
    284   1.1       rjs 
    285   1.1       rjs void
    286   1.1       rjs sctp_log_block(uint8_t from, struct socket *so, struct sctp_association *asoc)
    287   1.1       rjs {
    288   1.1       rjs 
    289   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
    290   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_BLOCK;
    291   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.blk.maxmb = (u_int16_t)(so->so_snd.sb_mbmax/1024);
    292   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.blk.onmb = asoc->total_output_mbuf_queue_size;
    293   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.blk.maxsb = (u_int16_t)(so->so_snd.sb_hiwat/1024);
    294   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.blk.onsb = asoc->total_output_queue_size;
    295   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.blk.send_sent_qcnt = (u_int16_t)(asoc->send_queue_cnt + asoc->sent_queue_cnt);
    296   1.1       rjs 	sctp_clog[sctp_cwnd_log_at].x.blk.stream_qcnt = (u_int16_t)asoc->stream_queue_cnt;
    297   1.1       rjs 	sctp_cwnd_log_at++;
    298   1.1       rjs 	if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
    299   1.1       rjs 		sctp_cwnd_log_at = 0;
    300   1.1       rjs 		sctp_cwnd_log_rolled = 1;
    301   1.1       rjs 	}
    302   1.1       rjs }
    303   1.1       rjs 
    304   1.1       rjs int
    305   1.1       rjs sctp_fill_stat_log(struct mbuf *m)
    306   1.1       rjs {
    307   1.1       rjs 	struct sctp_cwnd_log_req *req;
    308   1.1       rjs 	int size_limit, num, i, at, cnt_out=0;
    309   1.1       rjs 
    310   1.1       rjs 	if (m == NULL)
    311   1.1       rjs 		return (EINVAL);
    312   1.1       rjs 
    313   1.1       rjs 	size_limit = (m->m_len - sizeof(struct sctp_cwnd_log_req));
    314   1.1       rjs 	if (size_limit < sizeof(struct sctp_cwnd_log)) {
    315   1.1       rjs 		return (EINVAL);
    316   1.1       rjs 	}
    317   1.1       rjs 	req = mtod(m, struct sctp_cwnd_log_req *);
    318   1.1       rjs 	num = size_limit/sizeof(struct sctp_cwnd_log);
    319   1.1       rjs 	if (sctp_cwnd_log_rolled) {
    320   1.1       rjs 		req->num_in_log = SCTP_STAT_LOG_SIZE;
    321   1.1       rjs 	} else {
    322   1.1       rjs 		req->num_in_log = sctp_cwnd_log_at;
    323   1.1       rjs 		/* if the log has not rolled, we don't
    324   1.1       rjs 		 * let you have old data.
    325   1.1       rjs 		 */
    326   1.1       rjs  		if (req->end_at > sctp_cwnd_log_at) {
    327   1.1       rjs 			req->end_at = sctp_cwnd_log_at;
    328   1.1       rjs 		}
    329   1.1       rjs 	}
    330   1.1       rjs 	if ((num < SCTP_STAT_LOG_SIZE) &&
    331   1.1       rjs 	    ((sctp_cwnd_log_rolled) || (sctp_cwnd_log_at > num))) {
    332   1.1       rjs 		/* we can't return all of it */
    333   1.1       rjs 		if (((req->start_at == 0) && (req->end_at == 0)) ||
    334   1.1       rjs 		    (req->start_at >= SCTP_STAT_LOG_SIZE) ||
    335   1.1       rjs 		    (req->end_at >= SCTP_STAT_LOG_SIZE)) {
    336   1.1       rjs 			/* No user request or user is wacked. */
    337   1.1       rjs 			req->num_ret = num;
    338   1.1       rjs 			req->end_at = sctp_cwnd_log_at - 1;
    339   1.1       rjs 			if ((sctp_cwnd_log_at - num) < 0) {
    340   1.1       rjs 				int cc;
    341   1.1       rjs 				cc = num - sctp_cwnd_log_at;
    342   1.1       rjs 				req->start_at = SCTP_STAT_LOG_SIZE - cc;
    343   1.1       rjs 			} else {
    344   1.1       rjs 				req->start_at = sctp_cwnd_log_at - num;
    345   1.1       rjs 			}
    346   1.1       rjs 		} else {
    347   1.1       rjs 			/* a user request */
    348   1.1       rjs 			int cc;
    349   1.1       rjs 			if (req->start_at > req->end_at) {
    350   1.1       rjs 				cc = (SCTP_STAT_LOG_SIZE - req->start_at) +
    351   1.1       rjs 				    (req->end_at + 1);
    352   1.1       rjs 			} else {
    353   1.1       rjs 
    354   1.1       rjs 				cc = req->end_at - req->start_at;
    355   1.1       rjs 			}
    356   1.1       rjs 			if (cc < num) {
    357   1.1       rjs 				num = cc;
    358   1.1       rjs 			}
    359   1.1       rjs 			req->num_ret = num;
    360   1.1       rjs 		}
    361   1.1       rjs 	} else {
    362   1.1       rjs 		/* We can return all  of it */
    363   1.1       rjs 		req->start_at = 0;
    364   1.1       rjs 		req->end_at = sctp_cwnd_log_at - 1;
    365   1.1       rjs 		req->num_ret = sctp_cwnd_log_at;
    366   1.1       rjs 	}
    367   1.1       rjs 	for (i = 0, at = req->start_at; i < req->num_ret; i++) {
    368   1.1       rjs 		req->log[i] = sctp_clog[at];
    369   1.1       rjs 		cnt_out++;
    370   1.1       rjs 		at++;
    371   1.1       rjs 		if (at >= SCTP_STAT_LOG_SIZE)
    372   1.1       rjs 			at = 0;
    373   1.1       rjs 	}
    374   1.1       rjs 	m->m_len = (cnt_out * sizeof(struct sctp_cwnd_log_req)) + sizeof(struct sctp_cwnd_log_req);
    375   1.1       rjs 	return (0);
    376   1.1       rjs }
    377   1.1       rjs 
    378   1.1       rjs #endif
    379   1.1       rjs 
    380   1.1       rjs #ifdef SCTP_AUDITING_ENABLED
    381   1.1       rjs u_int8_t sctp_audit_data[SCTP_AUDIT_SIZE][2];
    382   1.1       rjs static int sctp_audit_indx = 0;
    383   1.1       rjs 
    384   1.1       rjs static
    385   1.1       rjs void sctp_print_audit_report(void)
    386   1.1       rjs {
    387   1.1       rjs 	int i;
    388   1.1       rjs 	int cnt;
    389   1.1       rjs 	cnt = 0;
    390   1.1       rjs 	for (i=sctp_audit_indx;i<SCTP_AUDIT_SIZE;i++) {
    391   1.1       rjs 		if ((sctp_audit_data[i][0] == 0xe0) &&
    392   1.1       rjs 		    (sctp_audit_data[i][1] == 0x01)) {
    393   1.1       rjs 			cnt = 0;
    394   1.1       rjs 			printf("\n");
    395   1.1       rjs 		} else if (sctp_audit_data[i][0] == 0xf0) {
    396   1.1       rjs 			cnt = 0;
    397   1.1       rjs 			printf("\n");
    398   1.1       rjs 		} else if ((sctp_audit_data[i][0] == 0xc0) &&
    399   1.1       rjs 		    (sctp_audit_data[i][1] == 0x01)) {
    400   1.1       rjs 			printf("\n");
    401   1.1       rjs 			cnt = 0;
    402   1.1       rjs 		}
    403   1.1       rjs 		printf("%2.2x%2.2x ", (uint32_t)sctp_audit_data[i][0],
    404   1.1       rjs 		    (uint32_t)sctp_audit_data[i][1]);
    405   1.1       rjs 		cnt++;
    406   1.1       rjs 		if ((cnt % 14) == 0)
    407   1.1       rjs 			printf("\n");
    408   1.1       rjs 	}
    409   1.1       rjs 	for (i=0;i<sctp_audit_indx;i++) {
    410   1.1       rjs 		if ((sctp_audit_data[i][0] == 0xe0) &&
    411   1.1       rjs 		    (sctp_audit_data[i][1] == 0x01)) {
    412   1.1       rjs 			cnt = 0;
    413   1.1       rjs 			printf("\n");
    414   1.1       rjs 		} else if (sctp_audit_data[i][0] == 0xf0) {
    415   1.1       rjs 			cnt = 0;
    416   1.1       rjs 			printf("\n");
    417   1.1       rjs 		} else if ((sctp_audit_data[i][0] == 0xc0) &&
    418   1.1       rjs 			 (sctp_audit_data[i][1] == 0x01)) {
    419   1.1       rjs 			printf("\n");
    420   1.1       rjs 			cnt = 0;
    421   1.1       rjs 		}
    422   1.1       rjs 		printf("%2.2x%2.2x ", (uint32_t)sctp_audit_data[i][0],
    423   1.1       rjs 		    (uint32_t)sctp_audit_data[i][1]);
    424   1.1       rjs 		cnt++;
    425   1.1       rjs 		if ((cnt % 14) == 0)
    426   1.1       rjs 			printf("\n");
    427   1.1       rjs 	}
    428   1.1       rjs 	printf("\n");
    429   1.1       rjs }
    430   1.1       rjs 
    431   1.1       rjs void sctp_auditing(int from, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
    432   1.1       rjs     struct sctp_nets *net)
    433   1.1       rjs {
    434   1.1       rjs 	int resend_cnt, tot_out, rep, tot_book_cnt;
    435   1.1       rjs 	struct sctp_nets *lnet;
    436   1.1       rjs 	struct sctp_tmit_chunk *chk;
    437   1.1       rjs 
    438   1.1       rjs 	sctp_audit_data[sctp_audit_indx][0] = 0xAA;
    439   1.1       rjs 	sctp_audit_data[sctp_audit_indx][1] = 0x000000ff & from;
    440   1.1       rjs 	sctp_audit_indx++;
    441   1.1       rjs 	if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
    442   1.1       rjs 		sctp_audit_indx = 0;
    443   1.1       rjs 	}
    444   1.1       rjs 	if (inp == NULL) {
    445   1.1       rjs 		sctp_audit_data[sctp_audit_indx][0] = 0xAF;
    446   1.1       rjs 		sctp_audit_data[sctp_audit_indx][1] = 0x01;
    447   1.1       rjs 		sctp_audit_indx++;
    448   1.1       rjs 		if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
    449   1.1       rjs 			sctp_audit_indx = 0;
    450   1.1       rjs 		}
    451   1.1       rjs 		return;
    452   1.1       rjs 	}
    453   1.1       rjs 	if (stcb == NULL) {
    454   1.1       rjs 		sctp_audit_data[sctp_audit_indx][0] = 0xAF;
    455   1.1       rjs 		sctp_audit_data[sctp_audit_indx][1] = 0x02;
    456   1.1       rjs 		sctp_audit_indx++;
    457   1.1       rjs 		if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
    458   1.1       rjs 			sctp_audit_indx = 0;
    459   1.1       rjs 		}
    460   1.1       rjs 		return;
    461   1.1       rjs 	}
    462   1.1       rjs 	sctp_audit_data[sctp_audit_indx][0] = 0xA1;
    463   1.1       rjs 	sctp_audit_data[sctp_audit_indx][1] =
    464   1.1       rjs 	    (0x000000ff & stcb->asoc.sent_queue_retran_cnt);
    465   1.1       rjs 	sctp_audit_indx++;
    466   1.1       rjs 	if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
    467   1.1       rjs 		sctp_audit_indx = 0;
    468   1.1       rjs 	}
    469   1.1       rjs 	rep = 0;
    470   1.1       rjs 	tot_book_cnt = 0;
    471   1.1       rjs 	resend_cnt = tot_out = 0;
    472   1.1       rjs 	TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
    473   1.1       rjs 		if (chk->sent == SCTP_DATAGRAM_RESEND) {
    474   1.1       rjs 			resend_cnt++;
    475   1.1       rjs 		} else if (chk->sent < SCTP_DATAGRAM_RESEND) {
    476   1.1       rjs 			tot_out += chk->book_size;
    477   1.1       rjs 			tot_book_cnt++;
    478   1.1       rjs 		}
    479   1.1       rjs 	}
    480   1.1       rjs 	if (resend_cnt != stcb->asoc.sent_queue_retran_cnt) {
    481   1.1       rjs 		sctp_audit_data[sctp_audit_indx][0] = 0xAF;
    482   1.1       rjs 		sctp_audit_data[sctp_audit_indx][1] = 0xA1;
    483   1.1       rjs 		sctp_audit_indx++;
    484   1.1       rjs 		if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
    485   1.1       rjs 			sctp_audit_indx = 0;
    486   1.1       rjs 		}
    487   1.1       rjs 		printf("resend_cnt:%d asoc-tot:%d\n",
    488   1.1       rjs 		    resend_cnt, stcb->asoc.sent_queue_retran_cnt);
    489   1.1       rjs 		rep = 1;
    490   1.1       rjs 		stcb->asoc.sent_queue_retran_cnt = resend_cnt;
    491   1.1       rjs 		sctp_audit_data[sctp_audit_indx][0] = 0xA2;
    492   1.1       rjs 		sctp_audit_data[sctp_audit_indx][1] =
    493   1.1       rjs 		    (0x000000ff & stcb->asoc.sent_queue_retran_cnt);
    494   1.1       rjs 		sctp_audit_indx++;
    495   1.1       rjs 		if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
    496   1.1       rjs 			sctp_audit_indx = 0;
    497   1.1       rjs 		}
    498   1.1       rjs 	}
    499   1.1       rjs 	if (tot_out != stcb->asoc.total_flight) {
    500   1.1       rjs 		sctp_audit_data[sctp_audit_indx][0] = 0xAF;
    501   1.1       rjs 		sctp_audit_data[sctp_audit_indx][1] = 0xA2;
    502   1.1       rjs 		sctp_audit_indx++;
    503   1.1       rjs 		if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
    504   1.1       rjs 			sctp_audit_indx = 0;
    505   1.1       rjs 		}
    506   1.1       rjs 		rep = 1;
    507   1.1       rjs 		printf("tot_flt:%d asoc_tot:%d\n", tot_out,
    508   1.1       rjs 		    (int)stcb->asoc.total_flight);
    509   1.1       rjs 		stcb->asoc.total_flight = tot_out;
    510   1.1       rjs 	}
    511   1.1       rjs 	if (tot_book_cnt != stcb->asoc.total_flight_count) {
    512   1.1       rjs 		sctp_audit_data[sctp_audit_indx][0] = 0xAF;
    513   1.1       rjs 		sctp_audit_data[sctp_audit_indx][1] = 0xA5;
    514   1.1       rjs 		sctp_audit_indx++;
    515   1.1       rjs 		if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
    516   1.1       rjs 			sctp_audit_indx = 0;
    517   1.1       rjs 		}
    518   1.1       rjs 		rep = 1;
    519   1.1       rjs 		printf("tot_flt_book:%d\n", tot_book);
    520   1.1       rjs 
    521   1.1       rjs 		stcb->asoc.total_flight_count = tot_book_cnt;
    522   1.1       rjs 	}
    523   1.1       rjs 	tot_out = 0;
    524   1.1       rjs 	TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) {
    525   1.1       rjs 		tot_out += lnet->flight_size;
    526   1.1       rjs 	}
    527   1.1       rjs 	if (tot_out != stcb->asoc.total_flight) {
    528   1.1       rjs 		sctp_audit_data[sctp_audit_indx][0] = 0xAF;
    529   1.1       rjs 		sctp_audit_data[sctp_audit_indx][1] = 0xA3;
    530   1.1       rjs 		sctp_audit_indx++;
    531   1.1       rjs 		if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
    532   1.1       rjs 			sctp_audit_indx = 0;
    533   1.1       rjs 		}
    534   1.1       rjs 		rep = 1;
    535   1.1       rjs 		printf("real flight:%d net total was %d\n",
    536   1.1       rjs 		    stcb->asoc.total_flight, tot_out);
    537   1.1       rjs 		/* now corrective action */
    538   1.1       rjs 		TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) {
    539   1.1       rjs 			tot_out = 0;
    540   1.1       rjs 			TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
    541   1.1       rjs 				if ((chk->whoTo == lnet) &&
    542   1.1       rjs 				    (chk->sent < SCTP_DATAGRAM_RESEND)) {
    543   1.1       rjs 					tot_out += chk->book_size;
    544   1.1       rjs 				}
    545   1.1       rjs 			}
    546   1.1       rjs 			if (lnet->flight_size != tot_out) {
    547   1.1       rjs 				printf("net:%x flight was %d corrected to %d\n",
    548   1.1       rjs 				    (uint32_t)lnet, lnet->flight_size, tot_out);
    549   1.1       rjs 				lnet->flight_size = tot_out;
    550   1.1       rjs 			}
    551   1.1       rjs 
    552   1.1       rjs 		}
    553   1.1       rjs 	}
    554   1.1       rjs 
    555   1.1       rjs 	if (rep) {
    556   1.1       rjs 		sctp_print_audit_report();
    557   1.1       rjs 	}
    558   1.1       rjs }
    559   1.1       rjs 
    560   1.1       rjs void
    561   1.1       rjs sctp_audit_log(u_int8_t ev, u_int8_t fd)
    562   1.1       rjs {
    563   1.1       rjs 	sctp_audit_data[sctp_audit_indx][0] = ev;
    564   1.1       rjs 	sctp_audit_data[sctp_audit_indx][1] = fd;
    565   1.1       rjs 	sctp_audit_indx++;
    566   1.1       rjs 	if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
    567   1.1       rjs 		sctp_audit_indx = 0;
    568   1.1       rjs 	}
    569   1.1       rjs }
    570   1.1       rjs 
    571   1.1       rjs #endif
    572   1.1       rjs 
    573   1.1       rjs /*
    574   1.1       rjs  * a list of sizes based on typical mtu's, used only if next hop
    575   1.1       rjs  * size not returned.
    576   1.1       rjs  */
    577   1.1       rjs static int sctp_mtu_sizes[] = {
    578   1.1       rjs 	68,
    579   1.1       rjs 	296,
    580   1.1       rjs 	508,
    581   1.1       rjs 	512,
    582   1.1       rjs 	544,
    583   1.1       rjs 	576,
    584   1.1       rjs 	1006,
    585   1.1       rjs 	1492,
    586   1.1       rjs 	1500,
    587   1.1       rjs 	1536,
    588   1.1       rjs 	2002,
    589   1.1       rjs 	2048,
    590   1.1       rjs 	4352,
    591   1.1       rjs 	4464,
    592   1.1       rjs 	8166,
    593   1.1       rjs 	17914,
    594   1.1       rjs 	32000,
    595   1.1       rjs 	65535
    596   1.1       rjs };
    597   1.1       rjs 
    598   1.1       rjs int
    599   1.1       rjs find_next_best_mtu(int totsz)
    600   1.1       rjs {
    601   1.1       rjs 	int i, perfer;
    602   1.1       rjs 	/*
    603   1.1       rjs 	 * if we are in here we must find the next best fit based on the
    604   1.1       rjs 	 * size of the dg that failed to be sent.
    605   1.1       rjs 	 */
    606   1.1       rjs 	perfer = 0;
    607   1.1       rjs 	for (i = 0; i < NUMBER_OF_MTU_SIZES; i++) {
    608   1.1       rjs 		if (totsz < sctp_mtu_sizes[i]) {
    609   1.1       rjs 			perfer = i - 1;
    610   1.1       rjs 			if (perfer < 0)
    611   1.1       rjs 				perfer = 0;
    612   1.1       rjs 			break;
    613   1.1       rjs 		}
    614   1.1       rjs 	}
    615   1.1       rjs 	return (sctp_mtu_sizes[perfer]);
    616   1.1       rjs }
    617   1.1       rjs 
    618   1.1       rjs uint32_t
    619   1.1       rjs sctp_select_initial_TSN(struct sctp_pcb *m)
    620   1.1       rjs {
    621  1.16  riastrad 	return cprng_strong32();
    622   1.1       rjs }
    623   1.1       rjs 
    624   1.1       rjs u_int32_t sctp_select_a_tag(struct sctp_inpcb *m)
    625   1.1       rjs {
    626   1.1       rjs 	u_long x, not_done;
    627   1.1       rjs 	struct timeval now;
    628   1.1       rjs 
    629   1.1       rjs 	SCTP_GETTIME_TIMEVAL(&now);
    630   1.1       rjs 	not_done = 1;
    631   1.1       rjs 	while (not_done) {
    632   1.1       rjs 		x = sctp_select_initial_TSN(&m->sctp_ep);
    633   1.1       rjs 		if (x == 0) {
    634   1.1       rjs 			/* we never use 0 */
    635   1.1       rjs 			continue;
    636   1.1       rjs 		}
    637   1.1       rjs 		if (sctp_is_vtag_good(m, x, &now)) {
    638   1.1       rjs 			not_done = 0;
    639   1.1       rjs 		}
    640   1.1       rjs 	}
    641   1.1       rjs 	return (x);
    642   1.1       rjs }
    643   1.1       rjs 
    644   1.1       rjs 
    645   1.1       rjs int
    646   1.1       rjs sctp_init_asoc(struct sctp_inpcb *m, struct sctp_association *asoc,
    647   1.1       rjs 	       int for_a_init, uint32_t override_tag )
    648   1.1       rjs {
    649   1.1       rjs 	/*
    650   1.1       rjs 	 * Anything set to zero is taken care of by the allocation
    651   1.1       rjs 	 * routine's bzero
    652   1.1       rjs 	 */
    653   1.1       rjs 
    654   1.1       rjs 	/*
    655   1.1       rjs 	 * Up front select what scoping to apply on addresses I tell my peer
    656   1.1       rjs 	 * Not sure what to do with these right now, we will need to come up
    657   1.1       rjs 	 * with a way to set them. We may need to pass them through from the
    658   1.1       rjs 	 * caller in the sctp_aloc_assoc() function.
    659   1.1       rjs 	 */
    660   1.1       rjs 	int i;
    661   1.1       rjs 	/* init all variables to a known value.*/
    662   1.1       rjs 	asoc->state = SCTP_STATE_INUSE;
    663   1.1       rjs 	asoc->max_burst = m->sctp_ep.max_burst;
    664   1.1       rjs 	asoc->heart_beat_delay = m->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT];
    665   1.1       rjs 	asoc->cookie_life = m->sctp_ep.def_cookie_life;
    666   1.1       rjs 
    667   1.1       rjs 	if (override_tag) {
    668   1.1       rjs 		asoc->my_vtag = override_tag;
    669   1.1       rjs 	} else {
    670   1.1       rjs 		asoc->my_vtag = sctp_select_a_tag(m);
    671   1.1       rjs 	}
    672   1.1       rjs 	asoc->asconf_seq_out = asoc->str_reset_seq_out = asoc->init_seq_number = asoc->sending_seq =
    673   1.1       rjs 		sctp_select_initial_TSN(&m->sctp_ep);
    674   1.1       rjs 	asoc->t3timeout_highest_marked = asoc->asconf_seq_out;
    675   1.1       rjs 	/* we are opptimisitic here */
    676   1.1       rjs 	asoc->peer_supports_asconf = 1;
    677   1.1       rjs 	asoc->peer_supports_asconf_setprim = 1;
    678   1.1       rjs 	asoc->peer_supports_pktdrop = 1;
    679   1.1       rjs 
    680   1.1       rjs 	asoc->sent_queue_retran_cnt = 0;
    681   1.1       rjs 	/* This will need to be adjusted */
    682   1.1       rjs 	asoc->last_cwr_tsn = asoc->init_seq_number - 1;
    683   1.1       rjs 	asoc->last_acked_seq = asoc->init_seq_number - 1;
    684   1.1       rjs 	asoc->advanced_peer_ack_point = asoc->last_acked_seq;
    685   1.1       rjs 	asoc->asconf_seq_in = asoc->last_acked_seq;
    686   1.1       rjs 
    687   1.1       rjs 	/* here we are different, we hold the next one we expect */
    688   1.1       rjs 	asoc->str_reset_seq_in = asoc->last_acked_seq + 1;
    689   1.1       rjs 
    690   1.1       rjs 	asoc->initial_init_rto_max = m->sctp_ep.initial_init_rto_max;
    691   1.1       rjs 	asoc->initial_rto = m->sctp_ep.initial_rto;
    692   1.1       rjs 
    693   1.1       rjs 	asoc->max_init_times = m->sctp_ep.max_init_times;
    694   1.1       rjs 	asoc->max_send_times = m->sctp_ep.max_send_times;
    695   1.1       rjs 	asoc->def_net_failure = m->sctp_ep.def_net_failure;
    696   1.1       rjs 
    697   1.1       rjs 	/* ECN Nonce initialization */
    698   1.1       rjs 	asoc->ecn_nonce_allowed = 0;
    699   1.1       rjs 	asoc->receiver_nonce_sum = 1;
    700   1.1       rjs 	asoc->nonce_sum_expect_base = 1;
    701   1.1       rjs 	asoc->nonce_sum_check = 1;
    702   1.1       rjs 	asoc->nonce_resync_tsn = 0;
    703   1.1       rjs 	asoc->nonce_wait_for_ecne = 0;
    704   1.1       rjs 	asoc->nonce_wait_tsn = 0;
    705   1.1       rjs 
    706   1.1       rjs 	if (m->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
    707   1.1       rjs 		struct in6pcb *inp6;
    708   1.1       rjs 
    709   1.1       rjs 
    710   1.1       rjs 		/* Its a V6 socket */
    711   1.1       rjs 		inp6 = (struct in6pcb *)m;
    712   1.1       rjs 		asoc->ipv6_addr_legal = 1;
    713   1.1       rjs 		/* Now look at the binding flag to see if V4 will be legal */
    714   1.1       rjs 	if (
    715   1.1       rjs #if defined(__OpenBSD__)
    716   1.1       rjs 		(0) /* we always do dual bind */
    717   1.1       rjs #elif defined (__NetBSD__)
    718   1.1       rjs 		(inp6->in6p_flags & IN6P_IPV6_V6ONLY)
    719   1.1       rjs #else
    720   1.1       rjs 		(inp6->inp_flags & IN6P_IPV6_V6ONLY)
    721   1.1       rjs #endif
    722   1.1       rjs 	     == 0) {
    723   1.1       rjs 			asoc->ipv4_addr_legal = 1;
    724   1.1       rjs 		} else {
    725   1.1       rjs 			/* V4 addresses are NOT legal on the association */
    726   1.1       rjs 			asoc->ipv4_addr_legal = 0;
    727   1.1       rjs 		}
    728   1.1       rjs 	} else {
    729   1.1       rjs 		/* Its a V4 socket, no - V6 */
    730   1.1       rjs 		asoc->ipv4_addr_legal = 1;
    731   1.1       rjs 		asoc->ipv6_addr_legal = 0;
    732   1.1       rjs 	}
    733   1.1       rjs 
    734   1.1       rjs 
    735  1.13  riastrad 	asoc->my_rwnd = uimax(m->sctp_socket->so_rcv.sb_hiwat, SCTP_MINIMAL_RWND);
    736   1.1       rjs 	asoc->peers_rwnd = m->sctp_socket->so_rcv.sb_hiwat;
    737   1.1       rjs 
    738   1.1       rjs 	asoc->smallest_mtu = m->sctp_frag_point;
    739   1.1       rjs 	asoc->minrto = m->sctp_ep.sctp_minrto;
    740   1.1       rjs 	asoc->maxrto = m->sctp_ep.sctp_maxrto;
    741   1.1       rjs 
    742   1.1       rjs 	LIST_INIT(&asoc->sctp_local_addr_list);
    743   1.1       rjs 	TAILQ_INIT(&asoc->nets);
    744   1.1       rjs 	TAILQ_INIT(&asoc->pending_reply_queue);
    745   1.1       rjs 	asoc->last_asconf_ack_sent = NULL;
    746   1.1       rjs 	/* Setup to fill the hb random cache at first HB */
    747   1.1       rjs 	asoc->hb_random_idx = 4;
    748   1.1       rjs 
    749   1.1       rjs 	asoc->sctp_autoclose_ticks = m->sctp_ep.auto_close_time;
    750   1.1       rjs 
    751   1.1       rjs 	/*
    752   1.1       rjs 	 * Now the stream parameters, here we allocate space for all
    753   1.1       rjs 	 * streams that we request by default.
    754   1.1       rjs 	 */
    755   1.1       rjs 	asoc->streamoutcnt = asoc->pre_open_streams =
    756   1.1       rjs 	    m->sctp_ep.pre_open_stream_count;
    757   1.1       rjs 	asoc->strmout = malloc(asoc->streamoutcnt *
    758   1.1       rjs 	    sizeof(struct sctp_stream_out), M_PCB, M_NOWAIT);
    759   1.1       rjs 	if (asoc->strmout == NULL) {
    760   1.1       rjs 		/* big trouble no memory */
    761   1.1       rjs 		return (ENOMEM);
    762   1.1       rjs 	}
    763   1.1       rjs 	for (i = 0; i < asoc->streamoutcnt; i++) {
    764   1.1       rjs 		/*
    765   1.1       rjs 		 * inbound side must be set to 0xffff,
    766   1.1       rjs 		 * also NOTE when we get the INIT-ACK back (for INIT sender)
    767   1.1       rjs 		 * we MUST reduce the count (streamoutcnt) but first check
    768   1.1       rjs 		 * if we sent to any of the upper streams that were dropped
    769   1.1       rjs 		 * (if some were). Those that were dropped must be notified
    770   1.1       rjs 		 * to the upper layer as failed to send.
    771   1.1       rjs 		 */
    772   1.1       rjs 		asoc->strmout[i].next_sequence_sent = 0x0;
    773   1.1       rjs 		TAILQ_INIT(&asoc->strmout[i].outqueue);
    774   1.1       rjs 		asoc->strmout[i].stream_no = i;
    775   1.1       rjs 		asoc->strmout[i].next_spoke.tqe_next = 0;
    776   1.1       rjs 		asoc->strmout[i].next_spoke.tqe_prev = 0;
    777   1.1       rjs 	}
    778   1.1       rjs 	/* Now the mapping array */
    779   1.1       rjs 	asoc->mapping_array_size = SCTP_INITIAL_MAPPING_ARRAY;
    780   1.1       rjs 	asoc->mapping_array = malloc(asoc->mapping_array_size,
    781   1.1       rjs 	       M_PCB, M_NOWAIT);
    782   1.1       rjs 	if (asoc->mapping_array == NULL) {
    783   1.1       rjs 		free(asoc->strmout, M_PCB);
    784   1.1       rjs 		return (ENOMEM);
    785   1.1       rjs 	}
    786   1.1       rjs 	memset(asoc->mapping_array, 0, asoc->mapping_array_size);
    787   1.1       rjs 	/* Now the init of the other outqueues */
    788   1.1       rjs 	TAILQ_INIT(&asoc->out_wheel);
    789   1.1       rjs 	TAILQ_INIT(&asoc->control_send_queue);
    790   1.1       rjs 	TAILQ_INIT(&asoc->send_queue);
    791   1.1       rjs 	TAILQ_INIT(&asoc->sent_queue);
    792   1.1       rjs 	TAILQ_INIT(&asoc->reasmqueue);
    793   1.1       rjs 	TAILQ_INIT(&asoc->delivery_queue);
    794   1.1       rjs 	asoc->max_inbound_streams = m->sctp_ep.max_open_streams_intome;
    795   1.1       rjs 
    796   1.1       rjs 	TAILQ_INIT(&asoc->asconf_queue);
    797   1.1       rjs 	return (0);
    798   1.1       rjs }
    799   1.1       rjs 
    800   1.1       rjs int
    801   1.1       rjs sctp_expand_mapping_array(struct sctp_association *asoc)
    802   1.1       rjs {
    803   1.1       rjs 	/* mapping array needs to grow */
    804   1.1       rjs 	u_int8_t *new_array;
    805   1.3  christos 	uint16_t new_size, old_size;
    806   1.1       rjs 
    807   1.3  christos 	old_size = asoc->mapping_array_size;
    808   1.3  christos 	new_size = old_size + SCTP_MAPPING_ARRAY_INCR;
    809   1.1       rjs 	new_array = malloc(new_size, M_PCB, M_NOWAIT);
    810   1.1       rjs 	if (new_array == NULL) {
    811   1.1       rjs 		/* can't get more, forget it */
    812   1.1       rjs 		printf("No memory for expansion of SCTP mapping array %d\n",
    813   1.1       rjs 		       new_size);
    814   1.1       rjs 		return (-1);
    815   1.1       rjs 	}
    816   1.3  christos 	memcpy(new_array, asoc->mapping_array, old_size);
    817   1.3  christos 	memset(new_array + old_size, 0, SCTP_MAPPING_ARRAY_INCR);
    818   1.1       rjs 	free(asoc->mapping_array, M_PCB);
    819   1.1       rjs 	asoc->mapping_array = new_array;
    820   1.1       rjs 	asoc->mapping_array_size = new_size;
    821   1.1       rjs 	return (0);
    822   1.1       rjs }
    823   1.1       rjs 
    824   1.1       rjs static void
    825   1.1       rjs sctp_timeout_handler(void *t)
    826   1.1       rjs {
    827   1.1       rjs 	struct sctp_inpcb *inp;
    828   1.1       rjs 	struct sctp_tcb *stcb;
    829   1.1       rjs 	struct sctp_nets *net;
    830   1.1       rjs 	struct sctp_timer *tmr;
    831   1.1       rjs 	int did_output;
    832   1.1       rjs 
    833   1.1       rjs 	mutex_enter(softnet_lock);
    834   1.1       rjs 	tmr = (struct sctp_timer *)t;
    835   1.1       rjs 	inp = (struct sctp_inpcb *)tmr->ep;
    836   1.1       rjs 	stcb = (struct sctp_tcb *)tmr->tcb;
    837   1.1       rjs 	net = (struct sctp_nets *)tmr->net;
    838   1.1       rjs 	did_output = 1;
    839   1.1       rjs 
    840   1.1       rjs #ifdef SCTP_AUDITING_ENABLED
    841   1.1       rjs 	sctp_audit_log(0xF0, (u_int8_t)tmr->type);
    842   1.1       rjs 	sctp_auditing(3, inp, stcb, net);
    843   1.1       rjs #endif
    844   1.1       rjs 	sctp_pegs[SCTP_TIMERS_EXP]++;
    845   1.1       rjs 
    846   1.1       rjs 	if (inp == NULL) {
    847   1.1       rjs 		return;
    848   1.1       rjs 	}
    849   1.1       rjs 
    850   1.1       rjs 	SCTP_INP_WLOCK(inp);
    851   1.1       rjs 	if (inp->sctp_socket == 0) {
    852   1.1       rjs 		mutex_exit(softnet_lock);
    853   1.1       rjs 		SCTP_INP_WUNLOCK(inp);
    854   1.1       rjs 		return;
    855   1.1       rjs 	}
    856   1.1       rjs 	if (stcb) {
    857   1.1       rjs 		if (stcb->asoc.state == 0) {
    858   1.1       rjs 			mutex_exit(softnet_lock);
    859   1.1       rjs 			SCTP_INP_WUNLOCK(inp);
    860   1.1       rjs 			return;
    861   1.1       rjs 		}
    862   1.1       rjs 	}
    863   1.1       rjs #ifdef SCTP_DEBUG
    864   1.1       rjs 	if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
    865   1.1       rjs 		printf("Timer type %d goes off\n", tmr->type);
    866   1.1       rjs 	}
    867   1.1       rjs #endif /* SCTP_DEBUG */
    868   1.1       rjs #ifndef __NetBSD__
    869   1.1       rjs 	if (!callout_active(&tmr->timer)) {
    870   1.1       rjs 		SCTP_INP_WUNLOCK(inp);
    871   1.1       rjs 		return;
    872   1.1       rjs 	}
    873   1.1       rjs #endif
    874   1.1       rjs 	if (stcb) {
    875   1.1       rjs 		SCTP_TCB_LOCK(stcb);
    876   1.1       rjs 	}
    877   1.1       rjs 	SCTP_INP_INCR_REF(inp);
    878   1.1       rjs 	SCTP_INP_WUNLOCK(inp);
    879   1.1       rjs 
    880   1.1       rjs 	switch (tmr->type) {
    881   1.1       rjs 	case SCTP_TIMER_TYPE_ITERATOR:
    882   1.1       rjs 	{
    883   1.1       rjs 		struct sctp_iterator *it;
    884   1.1       rjs 		it = (struct sctp_iterator *)inp;
    885   1.1       rjs 		sctp_iterator_timer(it);
    886   1.1       rjs 	}
    887   1.1       rjs 	break;
    888   1.1       rjs 	/* call the handler for the appropriate timer type */
    889   1.1       rjs 	case SCTP_TIMER_TYPE_SEND:
    890   1.1       rjs 		sctp_pegs[SCTP_TMIT_TIMER]++;
    891   1.1       rjs 		stcb->asoc.num_send_timers_up--;
    892   1.1       rjs 		if (stcb->asoc.num_send_timers_up < 0) {
    893   1.1       rjs 			stcb->asoc.num_send_timers_up = 0;
    894   1.1       rjs 		}
    895   1.1       rjs 		if (sctp_t3rxt_timer(inp, stcb, net)) {
    896   1.1       rjs 			/* no need to unlock on tcb its gone */
    897   1.1       rjs 
    898   1.1       rjs 			goto out_decr;
    899   1.1       rjs 		}
    900   1.1       rjs #ifdef SCTP_AUDITING_ENABLED
    901   1.1       rjs 		sctp_auditing(4, inp, stcb, net);
    902   1.1       rjs #endif
    903   1.1       rjs 		sctp_chunk_output(inp, stcb, 1);
    904   1.1       rjs 		if ((stcb->asoc.num_send_timers_up == 0) &&
    905   1.1       rjs 		    (stcb->asoc.sent_queue_cnt > 0)
    906   1.1       rjs 			) {
    907   1.1       rjs 			struct sctp_tmit_chunk *chk;
    908   1.1       rjs 			/*
    909   1.1       rjs 			 * safeguard. If there on some on the sent queue
    910   1.1       rjs 			 * somewhere but no timers running something is
    911   1.1       rjs 			 * wrong... so we start a timer on the first chunk
    912   1.1       rjs 			 * on the send queue on whatever net it is sent to.
    913   1.1       rjs 			 */
    914   1.1       rjs 			sctp_pegs[SCTP_T3_SAFEGRD]++;
    915   1.1       rjs 			chk = TAILQ_FIRST(&stcb->asoc.sent_queue);
    916   1.1       rjs 			sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb,
    917   1.1       rjs 					 chk->whoTo);
    918   1.1       rjs 		}
    919   1.1       rjs 		break;
    920   1.1       rjs 	case SCTP_TIMER_TYPE_INIT:
    921   1.1       rjs 		if (sctp_t1init_timer(inp, stcb, net)) {
    922   1.1       rjs 			/* no need to unlock on tcb its gone */
    923   1.1       rjs 			goto out_decr;
    924   1.1       rjs 		}
    925   1.1       rjs 		/* We do output but not here */
    926   1.1       rjs 		did_output = 0;
    927   1.1       rjs 		break;
    928   1.1       rjs 	case SCTP_TIMER_TYPE_RECV:
    929   1.1       rjs 		sctp_pegs[SCTP_RECV_TIMER]++;
    930   1.1       rjs 		sctp_send_sack(stcb);
    931   1.1       rjs #ifdef SCTP_AUDITING_ENABLED
    932   1.1       rjs 		sctp_auditing(4, inp, stcb, net);
    933   1.1       rjs #endif
    934   1.1       rjs 		sctp_chunk_output(inp, stcb, 4);
    935   1.1       rjs 		break;
    936   1.1       rjs 	case SCTP_TIMER_TYPE_SHUTDOWN:
    937   1.1       rjs 		if (sctp_shutdown_timer(inp, stcb, net) ) {
    938   1.1       rjs 			/* no need to unlock on tcb its gone */
    939   1.1       rjs 			goto out_decr;
    940   1.1       rjs 		}
    941   1.1       rjs #ifdef SCTP_AUDITING_ENABLED
    942   1.1       rjs 		sctp_auditing(4, inp, stcb, net);
    943   1.1       rjs #endif
    944   1.1       rjs 		sctp_chunk_output(inp, stcb, 5);
    945   1.1       rjs 		break;
    946   1.1       rjs 	case SCTP_TIMER_TYPE_HEARTBEAT:
    947   1.1       rjs 		if (sctp_heartbeat_timer(inp, stcb, net)) {
    948   1.1       rjs 			/* no need to unlock on tcb its gone */
    949   1.1       rjs 			goto out_decr;
    950   1.1       rjs 		}
    951   1.1       rjs #ifdef SCTP_AUDITING_ENABLED
    952   1.1       rjs 		sctp_auditing(4, inp, stcb, net);
    953   1.1       rjs #endif
    954   1.1       rjs 		sctp_chunk_output(inp, stcb, 6);
    955   1.1       rjs 		break;
    956   1.1       rjs 	case SCTP_TIMER_TYPE_COOKIE:
    957   1.1       rjs 		if (sctp_cookie_timer(inp, stcb, net)) {
    958   1.1       rjs 			/* no need to unlock on tcb its gone */
    959   1.1       rjs 			goto out_decr;
    960   1.1       rjs 		}
    961   1.1       rjs #ifdef SCTP_AUDITING_ENABLED
    962   1.1       rjs 		sctp_auditing(4, inp, stcb, net);
    963   1.1       rjs #endif
    964   1.1       rjs 		sctp_chunk_output(inp, stcb, 1);
    965   1.1       rjs 		break;
    966   1.1       rjs 	case SCTP_TIMER_TYPE_NEWCOOKIE:
    967   1.1       rjs 	{
    968   1.1       rjs 		struct timeval tv;
    969   1.1       rjs 		int i, secret;
    970   1.1       rjs 		SCTP_GETTIME_TIMEVAL(&tv);
    971   1.1       rjs 		SCTP_INP_WLOCK(inp);
    972   1.1       rjs 		inp->sctp_ep.time_of_secret_change = tv.tv_sec;
    973   1.1       rjs 		inp->sctp_ep.last_secret_number =
    974   1.1       rjs 			inp->sctp_ep.current_secret_number;
    975   1.1       rjs 		inp->sctp_ep.current_secret_number++;
    976   1.1       rjs 		if (inp->sctp_ep.current_secret_number >=
    977   1.1       rjs 		    SCTP_HOW_MANY_SECRETS) {
    978   1.1       rjs 			inp->sctp_ep.current_secret_number = 0;
    979   1.1       rjs 		}
    980   1.1       rjs 		secret = (int)inp->sctp_ep.current_secret_number;
    981   1.1       rjs 		for (i = 0; i < SCTP_NUMBER_OF_SECRETS; i++) {
    982   1.1       rjs 			inp->sctp_ep.secret_key[secret][i] =
    983   1.1       rjs 				sctp_select_initial_TSN(&inp->sctp_ep);
    984   1.1       rjs 		}
    985   1.1       rjs 		SCTP_INP_WUNLOCK(inp);
    986   1.1       rjs 		sctp_timer_start(SCTP_TIMER_TYPE_NEWCOOKIE, inp, stcb, net);
    987   1.1       rjs 	}
    988   1.1       rjs 	did_output = 0;
    989   1.1       rjs 	break;
    990   1.1       rjs 	case SCTP_TIMER_TYPE_PATHMTURAISE:
    991   1.1       rjs 		sctp_pathmtu_timer(inp, stcb, net);
    992   1.1       rjs 		did_output = 0;
    993   1.1       rjs 		break;
    994   1.1       rjs 	case SCTP_TIMER_TYPE_SHUTDOWNACK:
    995   1.1       rjs 		if (sctp_shutdownack_timer(inp, stcb, net)) {
    996   1.1       rjs 			/* no need to unlock on tcb its gone */
    997   1.1       rjs 			goto out_decr;
    998   1.1       rjs 		}
    999   1.1       rjs #ifdef SCTP_AUDITING_ENABLED
   1000   1.1       rjs 		sctp_auditing(4, inp, stcb, net);
   1001   1.1       rjs #endif
   1002   1.1       rjs 		sctp_chunk_output(inp, stcb, 7);
   1003   1.1       rjs 		break;
   1004   1.1       rjs 	case SCTP_TIMER_TYPE_SHUTDOWNGUARD:
   1005   1.1       rjs 		sctp_abort_an_association(inp, stcb,
   1006   1.1       rjs 					  SCTP_SHUTDOWN_GUARD_EXPIRES, NULL);
   1007   1.1       rjs 		/* no need to unlock on tcb its gone */
   1008   1.1       rjs 		goto out_decr;
   1009   1.1       rjs 		break;
   1010   1.1       rjs 
   1011   1.1       rjs 	case SCTP_TIMER_TYPE_STRRESET:
   1012   1.1       rjs 		if (sctp_strreset_timer(inp, stcb, net)) {
   1013   1.1       rjs 			/* no need to unlock on tcb its gone */
   1014   1.1       rjs 			goto out_decr;
   1015   1.1       rjs 		}
   1016   1.1       rjs 		sctp_chunk_output(inp, stcb, 9);
   1017   1.1       rjs 		break;
   1018   1.1       rjs 
   1019   1.1       rjs 	case SCTP_TIMER_TYPE_ASCONF:
   1020   1.1       rjs 		if (sctp_asconf_timer(inp, stcb, net)) {
   1021   1.1       rjs 			/* no need to unlock on tcb its gone */
   1022   1.1       rjs 			goto out_decr;
   1023   1.1       rjs 		}
   1024   1.1       rjs #ifdef SCTP_AUDITING_ENABLED
   1025   1.1       rjs 		sctp_auditing(4, inp, stcb, net);
   1026   1.1       rjs #endif
   1027   1.1       rjs 		sctp_chunk_output(inp, stcb, 8);
   1028   1.1       rjs 		break;
   1029   1.1       rjs 
   1030   1.1       rjs 	case SCTP_TIMER_TYPE_AUTOCLOSE:
   1031   1.1       rjs 		sctp_autoclose_timer(inp, stcb, net);
   1032   1.1       rjs 		sctp_chunk_output(inp, stcb, 10);
   1033   1.1       rjs 		did_output = 0;
   1034   1.1       rjs 		break;
   1035   1.1       rjs 	case SCTP_TIMER_TYPE_INPKILL:
   1036   1.1       rjs 		/* special case, take away our
   1037   1.1       rjs 		 * increment since WE are the killer
   1038   1.1       rjs 		 */
   1039   1.1       rjs 		SCTP_INP_WLOCK(inp);
   1040   1.1       rjs 		SCTP_INP_DECR_REF(inp);
   1041   1.1       rjs 		SCTP_INP_WUNLOCK(inp);
   1042   1.1       rjs 		sctp_timer_stop(SCTP_TIMER_TYPE_INPKILL, inp, NULL, NULL);
   1043   1.1       rjs 		sctp_inpcb_free(inp, 1);
   1044   1.1       rjs 		goto out_no_decr;
   1045   1.1       rjs 		break;
   1046   1.1       rjs 	default:
   1047   1.1       rjs #ifdef SCTP_DEBUG
   1048   1.1       rjs 		if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
   1049   1.1       rjs 			printf("sctp_timeout_handler:unknown timer %d\n",
   1050   1.1       rjs 			       tmr->type);
   1051   1.1       rjs 		}
   1052   1.1       rjs #endif /* SCTP_DEBUG */
   1053   1.1       rjs 		break;
   1054   1.1       rjs 	};
   1055   1.1       rjs #ifdef SCTP_AUDITING_ENABLED
   1056   1.1       rjs 	sctp_audit_log(0xF1, (u_int8_t)tmr->type);
   1057   1.1       rjs 	sctp_auditing(5, inp, stcb, net);
   1058   1.1       rjs #endif
   1059   1.1       rjs 	if (did_output) {
   1060   1.1       rjs 		/*
   1061   1.1       rjs 		 * Now we need to clean up the control chunk chain if an
   1062   1.1       rjs 		 * ECNE is on it. It must be marked as UNSENT again so next
   1063   1.1       rjs 		 * call will continue to send it until such time that we get
   1064   1.1       rjs 		 * a CWR, to remove it. It is, however, less likely that we
   1065   1.1       rjs 		 * will find a ecn echo on the chain though.
   1066   1.1       rjs 		 */
   1067   1.1       rjs 		sctp_fix_ecn_echo(&stcb->asoc);
   1068   1.1       rjs 	}
   1069   1.1       rjs 	if (stcb) {
   1070   1.1       rjs 		SCTP_TCB_UNLOCK(stcb);
   1071   1.1       rjs 	}
   1072   1.1       rjs  out_decr:
   1073   1.1       rjs 	SCTP_INP_WLOCK(inp);
   1074   1.1       rjs 	SCTP_INP_DECR_REF(inp);
   1075   1.1       rjs 	SCTP_INP_WUNLOCK(inp);
   1076   1.1       rjs 
   1077   1.1       rjs  out_no_decr:
   1078   1.1       rjs 
   1079   1.1       rjs 	mutex_exit(softnet_lock);
   1080   1.1       rjs }
   1081   1.1       rjs 
   1082   1.1       rjs int
   1083   1.1       rjs sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
   1084   1.1       rjs     struct sctp_nets *net)
   1085   1.1       rjs {
   1086   1.1       rjs 	int to_ticks;
   1087   1.1       rjs 	struct sctp_timer *tmr;
   1088   1.1       rjs 
   1089   1.1       rjs 	if (inp == NULL)
   1090   1.1       rjs 		return (EFAULT);
   1091   1.1       rjs 
   1092   1.1       rjs 	to_ticks = 0;
   1093   1.1       rjs 
   1094   1.1       rjs 	tmr = NULL;
   1095   1.1       rjs 	switch (t_type) {
   1096   1.1       rjs 	case SCTP_TIMER_TYPE_ITERATOR:
   1097   1.1       rjs 	{
   1098   1.1       rjs 		struct sctp_iterator *it;
   1099   1.1       rjs 		it = (struct sctp_iterator *)inp;
   1100   1.1       rjs 		tmr = &it->tmr;
   1101   1.1       rjs 		to_ticks = SCTP_ITERATOR_TICKS;
   1102   1.1       rjs 	}
   1103   1.1       rjs 	break;
   1104   1.1       rjs 	case SCTP_TIMER_TYPE_SEND:
   1105   1.1       rjs 		/* Here we use the RTO timer */
   1106   1.1       rjs 	{
   1107   1.1       rjs 		int rto_val;
   1108   1.1       rjs 		if ((stcb == NULL) || (net == NULL)) {
   1109   1.1       rjs 			return (EFAULT);
   1110   1.1       rjs 		}
   1111   1.1       rjs 		tmr = &net->rxt_timer;
   1112   1.1       rjs 		if (net->RTO == 0) {
   1113   1.1       rjs 			rto_val = stcb->asoc.initial_rto;
   1114   1.1       rjs 		} else {
   1115   1.1       rjs 			rto_val = net->RTO;
   1116   1.1       rjs 		}
   1117   1.1       rjs 		to_ticks = MSEC_TO_TICKS(rto_val);
   1118   1.1       rjs 	}
   1119   1.1       rjs 	break;
   1120   1.1       rjs 	case SCTP_TIMER_TYPE_INIT:
   1121   1.1       rjs 		/*
   1122   1.1       rjs 		 * Here we use the INIT timer default
   1123   1.1       rjs 		 * usually about 1 minute.
   1124   1.1       rjs 		 */
   1125   1.1       rjs 		if ((stcb == NULL) || (net == NULL)) {
   1126   1.1       rjs 			return (EFAULT);
   1127   1.1       rjs 		}
   1128   1.1       rjs 		tmr = &net->rxt_timer;
   1129   1.1       rjs 		if (net->RTO == 0) {
   1130   1.1       rjs 			to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
   1131   1.1       rjs 		} else {
   1132   1.1       rjs 			to_ticks = MSEC_TO_TICKS(net->RTO);
   1133   1.1       rjs 		}
   1134   1.1       rjs 		break;
   1135   1.1       rjs 	case SCTP_TIMER_TYPE_RECV:
   1136   1.1       rjs 		/*
   1137   1.1       rjs 		 * Here we use the Delayed-Ack timer value from the inp
   1138   1.1       rjs 		 * ususually about 200ms.
   1139   1.1       rjs 		 */
   1140   1.1       rjs 		if (stcb == NULL) {
   1141   1.1       rjs 			return (EFAULT);
   1142   1.1       rjs 		}
   1143   1.1       rjs 		tmr = &stcb->asoc.dack_timer;
   1144   1.1       rjs 		to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV];
   1145   1.1       rjs 		break;
   1146   1.1       rjs 	case SCTP_TIMER_TYPE_SHUTDOWN:
   1147   1.1       rjs 		/* Here we use the RTO of the destination. */
   1148   1.1       rjs 		if ((stcb == NULL) || (net == NULL)) {
   1149   1.1       rjs 			return (EFAULT);
   1150   1.1       rjs 		}
   1151   1.1       rjs 
   1152   1.1       rjs 		if (net->RTO == 0) {
   1153   1.1       rjs 			to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
   1154   1.1       rjs 		} else {
   1155   1.1       rjs 			to_ticks = MSEC_TO_TICKS(net->RTO);
   1156   1.1       rjs 		}
   1157   1.1       rjs 		tmr = &net->rxt_timer;
   1158   1.1       rjs 		break;
   1159   1.1       rjs 	case SCTP_TIMER_TYPE_HEARTBEAT:
   1160   1.1       rjs 		/*
   1161   1.1       rjs 		 * the net is used here so that we can add in the RTO.
   1162   1.1       rjs 		 * Even though we use a different timer. We also add the
   1163   1.1       rjs 		 * HB timer PLUS a random jitter.
   1164   1.1       rjs 		 */
   1165   1.1       rjs 		if (stcb == NULL) {
   1166   1.1       rjs 			return (EFAULT);
   1167   1.1       rjs 		}
   1168   1.1       rjs 		{
   1169   1.1       rjs 			uint32_t rndval;
   1170   1.1       rjs 			uint8_t this_random;
   1171   1.1       rjs 			int cnt_of_unconf=0;
   1172   1.1       rjs 			struct sctp_nets *lnet;
   1173   1.1       rjs 
   1174   1.1       rjs 			TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) {
   1175   1.1       rjs 				if (lnet->dest_state & SCTP_ADDR_UNCONFIRMED) {
   1176   1.1       rjs 					cnt_of_unconf++;
   1177   1.1       rjs 				}
   1178   1.1       rjs 			}
   1179   1.1       rjs #ifdef SCTP_DEBUG
   1180   1.1       rjs 			if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
   1181   1.1       rjs 				printf("HB timer to start unconfirmed:%d hb_delay:%d\n",
   1182   1.1       rjs 				       cnt_of_unconf, stcb->asoc.heart_beat_delay);
   1183   1.1       rjs 			}
   1184   1.1       rjs #endif
   1185   1.1       rjs 			if (stcb->asoc.hb_random_idx > 3) {
   1186   1.1       rjs 				rndval = sctp_select_initial_TSN(&inp->sctp_ep);
   1187   1.1       rjs 				memcpy(stcb->asoc.hb_random_values, &rndval,
   1188   1.1       rjs 				       sizeof(stcb->asoc.hb_random_values));
   1189   1.1       rjs 				this_random = stcb->asoc.hb_random_values[0];
   1190   1.1       rjs 				stcb->asoc.hb_random_idx = 0;
   1191   1.1       rjs 				stcb->asoc.hb_ect_randombit = 0;
   1192   1.1       rjs 			} else {
   1193   1.1       rjs 				this_random = stcb->asoc.hb_random_values[stcb->asoc.hb_random_idx];
   1194   1.1       rjs 				stcb->asoc.hb_random_idx++;
   1195   1.1       rjs 				stcb->asoc.hb_ect_randombit = 0;
   1196   1.1       rjs 			}
   1197   1.1       rjs 			/*
   1198   1.1       rjs 			 * this_random will be 0 - 256 ms
   1199   1.1       rjs 			 * RTO is in ms.
   1200   1.1       rjs 			 */
   1201   1.1       rjs 			if ((stcb->asoc.heart_beat_delay == 0) &&
   1202   1.1       rjs 			    (cnt_of_unconf == 0)) {
   1203   1.1       rjs 				/* no HB on this inp after confirmations */
   1204   1.1       rjs 				return (0);
   1205   1.1       rjs 			}
   1206   1.1       rjs 			if (net) {
   1207   1.1       rjs 				int delay;
   1208   1.1       rjs 				delay = stcb->asoc.heart_beat_delay;
   1209   1.1       rjs 				TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) {
   1210   1.1       rjs 					if ((lnet->dest_state & SCTP_ADDR_UNCONFIRMED) &&
   1211   1.1       rjs 					    ((lnet->dest_state & SCTP_ADDR_OUT_OF_SCOPE) == 0) &&
   1212   1.1       rjs 					    (lnet->dest_state & SCTP_ADDR_REACHABLE)) {
   1213   1.1       rjs 					    delay = 0;
   1214   1.1       rjs 					}
   1215   1.1       rjs 				}
   1216   1.1       rjs 				if (net->RTO == 0) {
   1217   1.1       rjs 					/* Never been checked */
   1218   1.1       rjs 					to_ticks = this_random + stcb->asoc.initial_rto + delay;
   1219   1.1       rjs 				} else {
   1220   1.1       rjs 					/* set rto_val to the ms */
   1221   1.1       rjs 					to_ticks = delay + net->RTO + this_random;
   1222   1.1       rjs 				}
   1223   1.1       rjs 			} else {
   1224   1.1       rjs 				if (cnt_of_unconf) {
   1225   1.1       rjs 					to_ticks = this_random + stcb->asoc.initial_rto;
   1226   1.1       rjs 				} else {
   1227   1.1       rjs 					to_ticks = stcb->asoc.heart_beat_delay + this_random + stcb->asoc.initial_rto;
   1228   1.1       rjs 				}
   1229   1.1       rjs 			}
   1230   1.1       rjs 			/*
   1231   1.1       rjs 			 * Now we must convert the to_ticks that are now in
   1232   1.1       rjs 			 * ms to ticks.
   1233   1.1       rjs 			 */
   1234   1.1       rjs 			to_ticks *= hz;
   1235   1.1       rjs 			to_ticks /= 1000;
   1236   1.1       rjs #ifdef SCTP_DEBUG
   1237   1.1       rjs 			if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
   1238   1.1       rjs 				printf("Timer to expire in %d ticks\n", to_ticks);
   1239   1.1       rjs 			}
   1240   1.1       rjs #endif
   1241   1.1       rjs 			tmr = &stcb->asoc.hb_timer;
   1242   1.1       rjs 		}
   1243   1.1       rjs 		break;
   1244   1.1       rjs 	case SCTP_TIMER_TYPE_COOKIE:
   1245   1.1       rjs 		/*
   1246   1.1       rjs 		 * Here we can use the RTO timer from the network since
   1247  1.21    andvar 		 * one RTT was complete. If a retran happened then we will
   1248   1.1       rjs 		 * be using the RTO initial value.
   1249   1.1       rjs 		 */
   1250   1.1       rjs 		if ((stcb == NULL) || (net == NULL)) {
   1251   1.1       rjs 			return (EFAULT);
   1252   1.1       rjs 		}
   1253   1.1       rjs 		if (net->RTO == 0) {
   1254   1.1       rjs 			to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
   1255   1.1       rjs 		} else {
   1256   1.1       rjs 			to_ticks = MSEC_TO_TICKS(net->RTO);
   1257   1.1       rjs 		}
   1258   1.1       rjs 		tmr = &net->rxt_timer;
   1259   1.1       rjs 		break;
   1260   1.1       rjs 	case SCTP_TIMER_TYPE_NEWCOOKIE:
   1261   1.1       rjs 		/*
   1262   1.1       rjs 		 * nothing needed but the endpoint here
   1263   1.1       rjs 		 * ususually about 60 minutes.
   1264   1.1       rjs 		 */
   1265   1.1       rjs 		tmr = &inp->sctp_ep.signature_change;
   1266   1.1       rjs 		to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_SIGNATURE];
   1267   1.1       rjs 		break;
   1268   1.1       rjs 	case SCTP_TIMER_TYPE_INPKILL:
   1269   1.1       rjs 		/*
   1270   1.1       rjs 		 * The inp is setup to die. We re-use the
   1271  1.17    andvar 		 * signature_change timer since that has
   1272   1.1       rjs 		 * stopped and we are in the GONE state.
   1273   1.1       rjs 		 */
   1274   1.1       rjs 		tmr = &inp->sctp_ep.signature_change;
   1275   1.1       rjs 		to_ticks = (SCTP_INP_KILL_TIMEOUT * hz) / 1000;
   1276   1.1       rjs 		break;
   1277   1.1       rjs 	case SCTP_TIMER_TYPE_PATHMTURAISE:
   1278   1.1       rjs 		/*
   1279   1.1       rjs 		 * Here we use the value found in the EP for PMTU
   1280   1.1       rjs 		 * ususually about 10 minutes.
   1281   1.1       rjs 		 */
   1282   1.1       rjs 		if (stcb == NULL) {
   1283   1.1       rjs 			return (EFAULT);
   1284   1.1       rjs 		}
   1285   1.1       rjs 		if (net == NULL) {
   1286   1.1       rjs 			return (EFAULT);
   1287   1.1       rjs 		}
   1288   1.1       rjs 		to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_PMTU];
   1289   1.1       rjs 		tmr = &net->pmtu_timer;
   1290   1.1       rjs 		break;
   1291   1.1       rjs 	case SCTP_TIMER_TYPE_SHUTDOWNACK:
   1292   1.1       rjs 		/* Here we use the RTO of the destination */
   1293   1.1       rjs 		if ((stcb == NULL) || (net == NULL)) {
   1294   1.1       rjs 			return (EFAULT);
   1295   1.1       rjs 		}
   1296   1.1       rjs 		if (net->RTO == 0) {
   1297   1.1       rjs 			to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
   1298   1.1       rjs 		} else {
   1299   1.1       rjs 			to_ticks = MSEC_TO_TICKS(net->RTO);
   1300   1.1       rjs 		}
   1301   1.1       rjs 		tmr = &net->rxt_timer;
   1302   1.1       rjs 		break;
   1303   1.1       rjs 	case SCTP_TIMER_TYPE_SHUTDOWNGUARD:
   1304   1.1       rjs 		/*
   1305   1.1       rjs 		 * Here we use the endpoints shutdown guard timer
   1306   1.1       rjs 		 * usually about 3 minutes.
   1307   1.1       rjs 		 */
   1308   1.1       rjs 		if (stcb == NULL) {
   1309   1.1       rjs 			return (EFAULT);
   1310   1.1       rjs 		}
   1311   1.1       rjs 		to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_MAXSHUTDOWN];
   1312   1.1       rjs 		tmr = &stcb->asoc.shut_guard_timer;
   1313   1.1       rjs 		break;
   1314   1.1       rjs 	case SCTP_TIMER_TYPE_STRRESET:
   1315   1.1       rjs 		/*
   1316   1.1       rjs 		 * Here the timer comes from the inp
   1317   1.1       rjs 		 * but its value is from the RTO.
   1318   1.1       rjs 		 */
   1319   1.1       rjs 		if ((stcb == NULL) || (net == NULL)) {
   1320   1.1       rjs 			return (EFAULT);
   1321   1.1       rjs 		}
   1322   1.1       rjs 		if (net->RTO == 0) {
   1323   1.1       rjs 			to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
   1324   1.1       rjs 		} else {
   1325   1.1       rjs 			to_ticks = MSEC_TO_TICKS(net->RTO);
   1326   1.1       rjs 		}
   1327   1.1       rjs 		tmr = &stcb->asoc.strreset_timer;
   1328   1.1       rjs 		break;
   1329   1.1       rjs 
   1330   1.1       rjs 	case SCTP_TIMER_TYPE_ASCONF:
   1331   1.1       rjs 		/*
   1332   1.1       rjs 		 * Here the timer comes from the inp
   1333   1.1       rjs 		 * but its value is from the RTO.
   1334   1.1       rjs 		 */
   1335   1.1       rjs 		if ((stcb == NULL) || (net == NULL)) {
   1336   1.1       rjs 			return (EFAULT);
   1337   1.1       rjs 		}
   1338   1.1       rjs 		if (net->RTO == 0) {
   1339   1.1       rjs 			to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
   1340   1.1       rjs 		} else {
   1341   1.1       rjs 			to_ticks = MSEC_TO_TICKS(net->RTO);
   1342   1.1       rjs 		}
   1343   1.1       rjs 		tmr = &stcb->asoc.asconf_timer;
   1344   1.1       rjs 		break;
   1345   1.1       rjs 	case SCTP_TIMER_TYPE_AUTOCLOSE:
   1346   1.1       rjs 		if (stcb == NULL) {
   1347   1.1       rjs 			return (EFAULT);
   1348   1.1       rjs 		}
   1349   1.1       rjs 		if (stcb->asoc.sctp_autoclose_ticks == 0) {
   1350   1.1       rjs 			/* Really an error since stcb is NOT set to autoclose */
   1351   1.1       rjs 			return (0);
   1352   1.1       rjs 		}
   1353   1.1       rjs 		to_ticks = stcb->asoc.sctp_autoclose_ticks;
   1354   1.1       rjs 		tmr = &stcb->asoc.autoclose_timer;
   1355   1.1       rjs 		break;
   1356   1.1       rjs 	default:
   1357   1.1       rjs #ifdef SCTP_DEBUG
   1358   1.1       rjs 		if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
   1359   1.1       rjs 			printf("sctp_timer_start:Unknown timer type %d\n",
   1360   1.1       rjs 			       t_type);
   1361   1.1       rjs 		}
   1362   1.1       rjs #endif /* SCTP_DEBUG */
   1363   1.1       rjs 		return (EFAULT);
   1364   1.1       rjs 		break;
   1365   1.1       rjs 	};
   1366   1.1       rjs 	if ((to_ticks <= 0) || (tmr == NULL)) {
   1367   1.1       rjs #ifdef SCTP_DEBUG
   1368   1.1       rjs 		if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
   1369   1.1       rjs 			printf("sctp_timer_start:%d:software error to_ticks:%d tmr:%p not set ??\n",
   1370   1.1       rjs 			       t_type, to_ticks, tmr);
   1371   1.1       rjs 		}
   1372   1.1       rjs #endif /* SCTP_DEBUG */
   1373   1.1       rjs 		return (EFAULT);
   1374   1.1       rjs 	}
   1375   1.1       rjs 	if (callout_pending(&tmr->timer)) {
   1376   1.1       rjs 		/*
   1377   1.1       rjs 		 * we do NOT allow you to have it already running.
   1378   1.1       rjs 		 * if it is we leave the current one up unchanged
   1379   1.1       rjs 		 */
   1380   1.1       rjs 		return (EALREADY);
   1381   1.1       rjs 	}
   1382   1.1       rjs 	/* At this point we can proceed */
   1383   1.1       rjs 	if (t_type == SCTP_TIMER_TYPE_SEND) {
   1384   1.1       rjs 		stcb->asoc.num_send_timers_up++;
   1385   1.1       rjs 	}
   1386   1.1       rjs 	tmr->type = t_type;
   1387   1.1       rjs 	tmr->ep = (void *)inp;
   1388   1.1       rjs 	tmr->tcb = (void *)stcb;
   1389   1.1       rjs 	tmr->net = (void *)net;
   1390   1.1       rjs 	callout_reset(&tmr->timer, to_ticks, sctp_timeout_handler, tmr);
   1391   1.1       rjs 	return (0);
   1392   1.1       rjs }
   1393   1.1       rjs 
   1394   1.1       rjs int
   1395   1.1       rjs sctp_timer_stop(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
   1396   1.1       rjs 		struct sctp_nets *net)
   1397   1.1       rjs {
   1398   1.1       rjs 	struct sctp_timer *tmr;
   1399   1.1       rjs 
   1400   1.1       rjs 	if (inp == NULL)
   1401   1.1       rjs 		return (EFAULT);
   1402   1.1       rjs 
   1403   1.1       rjs 	tmr = NULL;
   1404   1.1       rjs 	switch (t_type) {
   1405   1.1       rjs 	case SCTP_TIMER_TYPE_ITERATOR:
   1406   1.1       rjs 	{
   1407   1.1       rjs 		struct sctp_iterator *it;
   1408   1.1       rjs 		it = (struct sctp_iterator *)inp;
   1409   1.1       rjs 		tmr = &it->tmr;
   1410   1.1       rjs 	}
   1411   1.1       rjs 	break;
   1412   1.1       rjs 	case SCTP_TIMER_TYPE_SEND:
   1413   1.1       rjs 		if ((stcb == NULL) || (net == NULL)) {
   1414   1.1       rjs 			return (EFAULT);
   1415   1.1       rjs 		}
   1416   1.1       rjs 		tmr = &net->rxt_timer;
   1417   1.1       rjs 		break;
   1418   1.1       rjs 	case SCTP_TIMER_TYPE_INIT:
   1419   1.1       rjs 		if ((stcb == NULL) || (net == NULL)) {
   1420   1.1       rjs 			return (EFAULT);
   1421   1.1       rjs 		}
   1422   1.1       rjs 		tmr = &net->rxt_timer;
   1423   1.1       rjs 		break;
   1424   1.1       rjs 	case SCTP_TIMER_TYPE_RECV:
   1425   1.1       rjs 		if (stcb == NULL) {
   1426   1.1       rjs 			return (EFAULT);
   1427   1.1       rjs 		}
   1428   1.1       rjs 		tmr = &stcb->asoc.dack_timer;
   1429   1.1       rjs 		break;
   1430   1.1       rjs 	case SCTP_TIMER_TYPE_SHUTDOWN:
   1431   1.1       rjs 		if ((stcb == NULL) || (net == NULL)) {
   1432   1.1       rjs 			return (EFAULT);
   1433   1.1       rjs 		}
   1434   1.1       rjs 		tmr = &net->rxt_timer;
   1435   1.1       rjs 		break;
   1436   1.1       rjs 	case SCTP_TIMER_TYPE_HEARTBEAT:
   1437   1.1       rjs 		if (stcb == NULL) {
   1438   1.1       rjs 			return (EFAULT);
   1439   1.1       rjs 		}
   1440   1.1       rjs 		tmr = &stcb->asoc.hb_timer;
   1441   1.1       rjs 		break;
   1442   1.1       rjs 	case SCTP_TIMER_TYPE_COOKIE:
   1443   1.1       rjs 		if ((stcb == NULL) || (net == NULL)) {
   1444   1.1       rjs 			return (EFAULT);
   1445   1.1       rjs 		}
   1446   1.1       rjs 		tmr = &net->rxt_timer;
   1447   1.1       rjs 		break;
   1448   1.1       rjs 	case SCTP_TIMER_TYPE_NEWCOOKIE:
   1449   1.1       rjs 		/* nothing needed but the endpoint here */
   1450   1.1       rjs 		tmr = &inp->sctp_ep.signature_change;
   1451   1.1       rjs 		/* We re-use the newcookie timer for
   1452   1.1       rjs 		 * the INP kill timer. We must assure
   1453   1.1       rjs 		 * that we do not kill it by accident.
   1454   1.1       rjs 		 */
   1455   1.1       rjs 		break;
   1456   1.1       rjs 	case SCTP_TIMER_TYPE_INPKILL:
   1457   1.1       rjs 		/*
   1458   1.1       rjs 		 * The inp is setup to die. We re-use the
   1459  1.17    andvar 		 * signature_change timer since that has
   1460   1.1       rjs 		 * stopped and we are in the GONE state.
   1461   1.1       rjs 		 */
   1462   1.1       rjs 		tmr = &inp->sctp_ep.signature_change;
   1463   1.1       rjs 		break;
   1464   1.1       rjs 	case SCTP_TIMER_TYPE_PATHMTURAISE:
   1465   1.1       rjs 		if (stcb == NULL) {
   1466   1.1       rjs 			return (EFAULT);
   1467   1.1       rjs 		}
   1468   1.1       rjs 		if (net == NULL) {
   1469   1.1       rjs 			return (EFAULT);
   1470   1.1       rjs 		}
   1471   1.1       rjs 		tmr = &net->pmtu_timer;
   1472   1.1       rjs 		break;
   1473   1.1       rjs 	case SCTP_TIMER_TYPE_SHUTDOWNACK:
   1474   1.1       rjs 		if ((stcb == NULL) || (net == NULL)) {
   1475   1.1       rjs 			return (EFAULT);
   1476   1.1       rjs 		}
   1477   1.1       rjs 		tmr = &net->rxt_timer;
   1478   1.1       rjs 		break;
   1479   1.1       rjs 	case SCTP_TIMER_TYPE_SHUTDOWNGUARD:
   1480   1.1       rjs 		if (stcb == NULL) {
   1481   1.1       rjs 			return (EFAULT);
   1482   1.1       rjs 		}
   1483   1.1       rjs 		tmr = &stcb->asoc.shut_guard_timer;
   1484   1.1       rjs 		break;
   1485   1.1       rjs 	case SCTP_TIMER_TYPE_STRRESET:
   1486   1.1       rjs 		if (stcb == NULL) {
   1487   1.1       rjs 			return (EFAULT);
   1488   1.1       rjs 		}
   1489   1.1       rjs 		tmr = &stcb->asoc.strreset_timer;
   1490   1.1       rjs 		break;
   1491   1.1       rjs 	case SCTP_TIMER_TYPE_ASCONF:
   1492   1.1       rjs 		if (stcb == NULL) {
   1493   1.1       rjs 			return (EFAULT);
   1494   1.1       rjs 		}
   1495   1.1       rjs 		tmr = &stcb->asoc.asconf_timer;
   1496   1.1       rjs 		break;
   1497   1.1       rjs 	case SCTP_TIMER_TYPE_AUTOCLOSE:
   1498   1.1       rjs 		if (stcb == NULL) {
   1499   1.1       rjs 			return (EFAULT);
   1500   1.1       rjs 		}
   1501   1.1       rjs 		tmr = &stcb->asoc.autoclose_timer;
   1502   1.1       rjs 		break;
   1503   1.1       rjs 	default:
   1504   1.1       rjs #ifdef SCTP_DEBUG
   1505   1.1       rjs 		if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
   1506   1.1       rjs 			printf("sctp_timer_stop:Unknown timer type %d\n",
   1507   1.1       rjs 			       t_type);
   1508   1.1       rjs 		}
   1509   1.1       rjs #endif /* SCTP_DEBUG */
   1510   1.1       rjs 		break;
   1511   1.1       rjs 	};
   1512   1.1       rjs 	if (tmr == NULL)
   1513   1.1       rjs 		return (EFAULT);
   1514   1.1       rjs 
   1515   1.1       rjs 	if ((tmr->type != t_type) && tmr->type) {
   1516   1.1       rjs 		/*
   1517   1.1       rjs 		 * Ok we have a timer that is under joint use. Cookie timer
   1518   1.1       rjs 		 * per chance with the SEND timer. We therefore are NOT
   1519   1.1       rjs 		 * running the timer that the caller wants stopped.  So just
   1520   1.1       rjs 		 * return.
   1521   1.1       rjs 		 */
   1522   1.1       rjs 		return (0);
   1523   1.1       rjs 	}
   1524   1.1       rjs 	if (t_type == SCTP_TIMER_TYPE_SEND) {
   1525   1.1       rjs 		stcb->asoc.num_send_timers_up--;
   1526   1.1       rjs 		if (stcb->asoc.num_send_timers_up < 0) {
   1527   1.1       rjs 			stcb->asoc.num_send_timers_up = 0;
   1528   1.1       rjs 		}
   1529   1.1       rjs 	}
   1530   1.1       rjs 	callout_stop(&tmr->timer);
   1531   1.1       rjs 	return (0);
   1532   1.1       rjs }
   1533   1.1       rjs 
   1534   1.1       rjs u_int32_t
   1535   1.1       rjs sctp_calculate_len(struct mbuf *m)
   1536   1.1       rjs {
   1537   1.1       rjs 	u_int32_t tlen=0;
   1538   1.1       rjs 	struct mbuf *at;
   1539   1.1       rjs 	at = m;
   1540   1.1       rjs 	while (at) {
   1541   1.1       rjs 		tlen += at->m_len;
   1542   1.1       rjs 		at = at->m_next;
   1543   1.1       rjs 	}
   1544   1.1       rjs 	return (tlen);
   1545   1.1       rjs }
   1546   1.1       rjs 
   1547   1.1       rjs uint32_t
   1548   1.1       rjs sctp_calculate_sum(struct mbuf *m, int32_t *pktlen, uint32_t offset)
   1549   1.1       rjs {
   1550   1.1       rjs 	/*
   1551   1.1       rjs 	 * given a mbuf chain with a packetheader offset by 'offset'
   1552   1.1       rjs 	 * pointing at a sctphdr (with csum set to 0) go through
   1553   1.1       rjs 	 * the chain of m_next's and calculate the SCTP checksum.
   1554  1.15       rjs 	 * This is CRC32c.
   1555  1.15       rjs 	 * Also has a side bonus calculate the total length
   1556   1.1       rjs 	 * of the mbuf chain.
   1557   1.1       rjs 	 * Note: if offset is greater than the total mbuf length,
   1558   1.1       rjs 	 * checksum=1, pktlen=0 is returned (ie. no real error code)
   1559   1.1       rjs 	 */
   1560   1.1       rjs 	int32_t tlen=0;
   1561   1.1       rjs 	uint32_t base = 0xffffffff;
   1562   1.1       rjs 	struct mbuf *at;
   1563   1.1       rjs 	at = m;
   1564   1.1       rjs 	/* find the correct mbuf and offset into mbuf */
   1565   1.1       rjs 	while ((at != NULL) && (offset > (uint32_t)at->m_len)) {
   1566   1.1       rjs 		offset -= at->m_len;	/* update remaining offset left */
   1567   1.1       rjs 		at = at->m_next;
   1568   1.1       rjs 	}
   1569   1.1       rjs 
   1570   1.1       rjs 	while (at != NULL) {
   1571   1.1       rjs 		base = update_crc32(base, at->m_data + offset,
   1572   1.1       rjs 		    at->m_len - offset);
   1573   1.1       rjs 		tlen += at->m_len - offset;
   1574   1.1       rjs 		/* we only offset once into the first mbuf */
   1575   1.1       rjs 		if (offset) {
   1576   1.1       rjs 			offset = 0;
   1577   1.1       rjs 		}
   1578   1.1       rjs 		at = at->m_next;
   1579   1.1       rjs 	}
   1580   1.1       rjs 	if (pktlen != NULL) {
   1581   1.1       rjs 		*pktlen = tlen;
   1582   1.1       rjs 	}
   1583   1.1       rjs 	/* CRC-32c */
   1584   1.1       rjs 	base = sctp_csum_finalize(base);
   1585   1.1       rjs 	return (base);
   1586   1.1       rjs }
   1587   1.1       rjs 
   1588   1.1       rjs void
   1589   1.1       rjs sctp_mtu_size_reset(struct sctp_inpcb *inp,
   1590   1.1       rjs 		    struct sctp_association *asoc, u_long mtu)
   1591   1.1       rjs {
   1592   1.1       rjs 	/*
   1593   1.1       rjs 	 * Reset the P-MTU size on this association, this involves changing
   1594   1.1       rjs 	 * the asoc MTU, going through ANY chunk+overhead larger than mtu
   1595   1.1       rjs 	 * to allow the DF flag to be cleared.
   1596   1.1       rjs 	 */
   1597   1.1       rjs 	struct sctp_tmit_chunk *chk;
   1598   1.1       rjs 	struct sctp_stream_out *strm;
   1599   1.1       rjs 	unsigned int eff_mtu, ovh;
   1600   1.1       rjs 	asoc->smallest_mtu = mtu;
   1601   1.1       rjs 	if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
   1602   1.1       rjs 		ovh = SCTP_MIN_OVERHEAD;
   1603   1.1       rjs 	} else {
   1604   1.1       rjs 		ovh = SCTP_MIN_V4_OVERHEAD;
   1605   1.1       rjs 	}
   1606   1.1       rjs 	eff_mtu = mtu - ovh;
   1607   1.1       rjs 	/* Now mark any chunks that need to let IP fragment */
   1608   1.1       rjs 	TAILQ_FOREACH(strm, &asoc->out_wheel, next_spoke) {
   1609   1.1       rjs 		TAILQ_FOREACH(chk, &strm->outqueue, sctp_next) {
   1610   1.1       rjs 			if (chk->send_size > eff_mtu) {
   1611   1.1       rjs 				chk->flags &= SCTP_DONT_FRAGMENT;
   1612   1.1       rjs 				chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
   1613   1.1       rjs 			}
   1614   1.1       rjs 		}
   1615   1.1       rjs 	}
   1616   1.1       rjs 	TAILQ_FOREACH(chk, &asoc->send_queue, sctp_next) {
   1617   1.1       rjs 		if (chk->send_size > eff_mtu) {
   1618   1.1       rjs 			chk->flags &= SCTP_DONT_FRAGMENT;
   1619   1.1       rjs 			chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
   1620   1.1       rjs 		}
   1621   1.1       rjs 	}
   1622   1.1       rjs 	TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) {
   1623   1.1       rjs 		if (chk->send_size > eff_mtu) {
   1624   1.1       rjs 			chk->flags &= SCTP_DONT_FRAGMENT;
   1625   1.1       rjs 			chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
   1626   1.1       rjs 		}
   1627   1.1       rjs 	}
   1628   1.1       rjs }
   1629   1.1       rjs 
   1630   1.1       rjs 
   1631   1.1       rjs /*
   1632   1.1       rjs  * given an association and starting time of the current RTT period
   1633   1.1       rjs  * return RTO in number of usecs
   1634   1.1       rjs  * net should point to the current network
   1635   1.1       rjs  */
   1636   1.1       rjs u_int32_t
   1637   1.1       rjs sctp_calculate_rto(struct sctp_tcb *stcb,
   1638   1.1       rjs 		   struct sctp_association *asoc,
   1639   1.1       rjs 		   struct sctp_nets *net,
   1640   1.1       rjs 		   struct timeval *old)
   1641   1.1       rjs {
   1642   1.1       rjs 	/*
   1643   1.1       rjs 	 * given an association and the starting time of the current RTT
   1644   1.1       rjs 	 * period (in value1/value2) return RTO in number of usecs.
   1645   1.1       rjs 	 */
   1646   1.1       rjs 	int calc_time = 0;
   1647   1.1       rjs 	unsigned int new_rto = 0;
   1648   1.1       rjs 	int first_measure = 0;
   1649   1.1       rjs 	struct timeval now;
   1650   1.1       rjs 
   1651   1.1       rjs 	/************************/
   1652   1.1       rjs 	/* 1. calculate new RTT */
   1653   1.1       rjs 	/************************/
   1654   1.1       rjs 	/* get the current time */
   1655   1.1       rjs 	SCTP_GETTIME_TIMEVAL(&now);
   1656   1.1       rjs 	/* compute the RTT value */
   1657   1.1       rjs 	if ((u_long)now.tv_sec > (u_long)old->tv_sec) {
   1658   1.1       rjs 		calc_time = ((u_long)now.tv_sec - (u_long)old->tv_sec) * 1000;
   1659   1.1       rjs 		if ((u_long)now.tv_usec > (u_long)old->tv_usec) {
   1660   1.1       rjs 			calc_time += (((u_long)now.tv_usec -
   1661   1.1       rjs 				       (u_long)old->tv_usec)/1000);
   1662   1.1       rjs 		} else if ((u_long)now.tv_usec < (u_long)old->tv_usec) {
   1663   1.1       rjs 			/* Borrow 1,000ms from current calculation */
   1664   1.1       rjs 			calc_time -= 1000;
   1665   1.1       rjs 			/* Add in the slop over */
   1666   1.1       rjs 			calc_time += ((int)now.tv_usec/1000);
   1667   1.1       rjs 			/* Add in the pre-second ms's */
   1668   1.1       rjs 			calc_time += (((int)1000000 - (int)old->tv_usec)/1000);
   1669   1.1       rjs 		}
   1670   1.1       rjs 	} else if ((u_long)now.tv_sec == (u_long)old->tv_sec) {
   1671   1.1       rjs 		if ((u_long)now.tv_usec > (u_long)old->tv_usec) {
   1672   1.1       rjs 			calc_time = ((u_long)now.tv_usec -
   1673   1.1       rjs 				     (u_long)old->tv_usec)/1000;
   1674   1.1       rjs 		} else if ((u_long)now.tv_usec < (u_long)old->tv_usec) {
   1675   1.1       rjs 			/* impossible .. garbage in nothing out */
   1676   1.1       rjs 			return (((net->lastsa >> 2) + net->lastsv) >> 1);
   1677   1.1       rjs 		} else {
   1678   1.1       rjs 			/* impossible .. garbage in nothing out */
   1679   1.1       rjs 			return (((net->lastsa >> 2) + net->lastsv) >> 1);
   1680   1.1       rjs 		}
   1681   1.1       rjs 	} else {
   1682   1.1       rjs 		/* Clock wrapped? */
   1683   1.1       rjs 		return (((net->lastsa >> 2) + net->lastsv) >> 1);
   1684   1.1       rjs 	}
   1685   1.1       rjs 	/***************************/
   1686   1.1       rjs 	/* 2. update RTTVAR & SRTT */
   1687   1.1       rjs 	/***************************/
   1688   1.1       rjs #if 0
   1689   1.1       rjs 	/*	if (net->lastsv || net->lastsa) {*/
   1690   1.1       rjs 	/* per Section 5.3.1 C3 in SCTP */
   1691   1.1       rjs 	/*		net->lastsv = (int) 	*//* RTTVAR */
   1692   1.1       rjs 	/*			(((double)(1.0 - 0.25) * (double)net->lastsv) +
   1693   1.1       rjs 				(double)(0.25 * (double)abs(net->lastsa - calc_time)));
   1694   1.1       rjs 				net->lastsa = (int) */	/* SRTT */
   1695   1.1       rjs 	/*(((double)(1.0 - 0.125) * (double)net->lastsa) +
   1696   1.1       rjs 	  (double)(0.125 * (double)calc_time));
   1697   1.1       rjs 	  } else {
   1698   1.1       rjs 	*//* the first RTT calculation, per C2 Section 5.3.1 */
   1699   1.1       rjs 	/*		net->lastsa = calc_time;	*//* SRTT */
   1700   1.1       rjs 	/*		net->lastsv = calc_time / 2;	*//* RTTVAR */
   1701   1.1       rjs 	/*	}*/
   1702   1.1       rjs 	/* if RTTVAR goes to 0 you set to clock grainularity */
   1703   1.1       rjs 	/*	if (net->lastsv == 0) {
   1704   1.1       rjs 		net->lastsv = SCTP_CLOCK_GRANULARITY;
   1705   1.1       rjs 		}
   1706   1.1       rjs 		new_rto = net->lastsa + 4 * net->lastsv;
   1707   1.1       rjs 	*/
   1708   1.1       rjs #endif
   1709   1.1       rjs 	/* this is Van Jacobson's integer version */
   1710   1.1       rjs 	if (net->RTO) {
   1711   1.1       rjs 		calc_time -= (net->lastsa >> 3);
   1712   1.1       rjs 		net->lastsa += calc_time;
   1713   1.1       rjs 		if (calc_time < 0) {
   1714   1.1       rjs 			calc_time = -calc_time;
   1715   1.1       rjs 		}
   1716   1.1       rjs 		calc_time -= (net->lastsv >> 2);
   1717   1.1       rjs 		net->lastsv += calc_time;
   1718   1.1       rjs 		if (net->lastsv == 0) {
   1719   1.1       rjs 			net->lastsv = SCTP_CLOCK_GRANULARITY;
   1720   1.1       rjs 		}
   1721   1.1       rjs 	} else {
   1722  1.18   msaitoh 		/* First RTO measurement */
   1723   1.1       rjs 		net->lastsa = calc_time;
   1724   1.1       rjs 		net->lastsv = calc_time >> 1;
   1725   1.1       rjs 		first_measure = 1;
   1726   1.1       rjs 	}
   1727   1.1       rjs 	new_rto = ((net->lastsa >> 2) + net->lastsv) >> 1;
   1728   1.1       rjs 	if ((new_rto > SCTP_SAT_NETWORK_MIN) &&
   1729   1.1       rjs 	    (stcb->asoc.sat_network_lockout == 0)) {
   1730   1.1       rjs 		stcb->asoc.sat_network = 1;
   1731   1.1       rjs 	} else 	if ((!first_measure) && stcb->asoc.sat_network) {
   1732   1.1       rjs 		stcb->asoc.sat_network = 0;
   1733   1.1       rjs 		stcb->asoc.sat_network_lockout = 1;
   1734   1.1       rjs 	}
   1735   1.1       rjs 	/* bound it, per C6/C7 in Section 5.3.1 */
   1736   1.1       rjs 	if (new_rto < stcb->asoc.minrto) {
   1737   1.1       rjs 		new_rto = stcb->asoc.minrto;
   1738   1.1       rjs 	}
   1739   1.1       rjs 	if (new_rto > stcb->asoc.maxrto) {
   1740   1.1       rjs 		new_rto = stcb->asoc.maxrto;
   1741   1.1       rjs 	}
   1742   1.1       rjs 	/* we are now returning the RTT Smoothed */
   1743   1.1       rjs 	return ((u_int32_t)new_rto);
   1744   1.1       rjs }
   1745   1.1       rjs 
   1746   1.1       rjs 
   1747   1.1       rjs /*
   1748   1.1       rjs  * return a pointer to a contiguous piece of data from the given
   1749   1.1       rjs  * mbuf chain starting at 'off' for 'len' bytes.  If the desired
   1750   1.1       rjs  * piece spans more than one mbuf, a copy is made at 'ptr'.
   1751   1.1       rjs  * caller must ensure that the buffer size is >= 'len'
   1752   1.1       rjs  * returns NULL if there there isn't 'len' bytes in the chain.
   1753   1.1       rjs  */
   1754   1.1       rjs void *
   1755   1.1       rjs sctp_m_getptr(struct mbuf *m, int off, int len, u_int8_t *in_ptr)
   1756   1.1       rjs {
   1757   1.1       rjs 	uint32_t count;
   1758   1.1       rjs 	uint8_t *ptr;
   1759   1.1       rjs 	ptr = in_ptr;
   1760   1.1       rjs 	if ((off < 0) || (len <= 0))
   1761   1.1       rjs 		return (NULL);
   1762   1.1       rjs 
   1763   1.1       rjs 	/* find the desired start location */
   1764   1.1       rjs 	while ((m != NULL) && (off > 0)) {
   1765   1.1       rjs 		if (off < m->m_len)
   1766   1.1       rjs 			break;
   1767   1.1       rjs 		off -= m->m_len;
   1768   1.1       rjs 		m = m->m_next;
   1769   1.1       rjs 	}
   1770   1.1       rjs 	if (m == NULL)
   1771   1.1       rjs 		return (NULL);
   1772   1.1       rjs 
   1773   1.1       rjs 	/* is the current mbuf large enough (eg. contiguous)? */
   1774   1.1       rjs 	if ((m->m_len - off) >= len) {
   1775   1.1       rjs 		return ((void *)(mtod(m, vaddr_t) + off));
   1776   1.1       rjs 	} else {
   1777   1.1       rjs 		/* else, it spans more than one mbuf, so save a temp copy... */
   1778   1.1       rjs 		while ((m != NULL) && (len > 0)) {
   1779  1.13  riastrad 			count = uimin(m->m_len - off, len);
   1780   1.1       rjs 			memcpy(ptr, (void *)(mtod(m, vaddr_t) + off), count);
   1781   1.1       rjs 			len -= count;
   1782   1.1       rjs 			ptr += count;
   1783   1.1       rjs 			off = 0;
   1784   1.1       rjs 			m = m->m_next;
   1785   1.1       rjs 		}
   1786   1.1       rjs 		if ((m == NULL) && (len > 0))
   1787   1.1       rjs 			return (NULL);
   1788   1.1       rjs 		else
   1789   1.1       rjs 			return ((void *)in_ptr);
   1790   1.1       rjs 	}
   1791   1.1       rjs }
   1792   1.1       rjs 
   1793   1.1       rjs 
   1794   1.1       rjs struct sctp_paramhdr *
   1795   1.1       rjs sctp_get_next_param(struct mbuf *m,
   1796   1.1       rjs 		    int offset,
   1797   1.1       rjs 		    struct sctp_paramhdr *pull,
   1798   1.1       rjs 		    int pull_limit)
   1799   1.1       rjs {
   1800   1.1       rjs 	/* This just provides a typed signature to Peter's Pull routine */
   1801   1.1       rjs 	return ((struct sctp_paramhdr *)sctp_m_getptr(m, offset, pull_limit,
   1802   1.1       rjs     	    (u_int8_t *)pull));
   1803   1.1       rjs }
   1804   1.1       rjs 
   1805   1.1       rjs 
   1806   1.1       rjs int
   1807   1.1       rjs sctp_add_pad_tombuf(struct mbuf *m, int padlen)
   1808   1.1       rjs {
   1809   1.1       rjs 	/*
   1810   1.1       rjs 	 * add padlen bytes of 0 filled padding to the end of the mbuf.
   1811   1.1       rjs 	 * If padlen is > 3 this routine will fail.
   1812   1.1       rjs 	 */
   1813   1.1       rjs 	u_int8_t *dp;
   1814   1.1       rjs 	int i;
   1815   1.1       rjs 	if (padlen > 3) {
   1816   1.1       rjs 		return (ENOBUFS);
   1817   1.1       rjs 	}
   1818   1.1       rjs 	if (M_TRAILINGSPACE(m)) {
   1819   1.1       rjs 		/*
   1820   1.1       rjs 		 * The easy way.
   1821   1.1       rjs 		 * We hope the majority of the time we hit here :)
   1822   1.1       rjs 		 */
   1823   1.1       rjs 		dp = (u_int8_t *)(mtod(m, vaddr_t) + m->m_len);
   1824   1.1       rjs 		m->m_len += padlen;
   1825   1.1       rjs 	} else {
   1826   1.1       rjs 		/* Hard way we must grow the mbuf */
   1827   1.1       rjs 		struct mbuf *tmp;
   1828   1.1       rjs 		MGET(tmp, M_DONTWAIT, MT_DATA);
   1829   1.1       rjs 		if (tmp == NULL) {
   1830   1.1       rjs 			/* Out of space GAK! we are in big trouble. */
   1831   1.1       rjs 			return (ENOSPC);
   1832   1.1       rjs 		}
   1833   1.1       rjs 		/* setup and insert in middle */
   1834   1.1       rjs 		tmp->m_next = m->m_next;
   1835   1.1       rjs 		tmp->m_len = padlen;
   1836   1.1       rjs 		m->m_next = tmp;
   1837   1.1       rjs 		dp = mtod(tmp, u_int8_t *);
   1838   1.1       rjs 	}
   1839   1.1       rjs 	/* zero out the pad */
   1840   1.1       rjs 	for (i=  0; i < padlen; i++) {
   1841   1.1       rjs 		*dp = 0;
   1842   1.1       rjs 		dp++;
   1843   1.1       rjs 	}
   1844   1.1       rjs 	return (0);
   1845   1.1       rjs }
   1846   1.1       rjs 
   1847   1.1       rjs int
   1848   1.1       rjs sctp_pad_lastmbuf(struct mbuf *m, int padval)
   1849   1.1       rjs {
   1850   1.1       rjs 	/* find the last mbuf in chain and pad it */
   1851   1.1       rjs 	struct mbuf *m_at;
   1852   1.1       rjs 	m_at = m;
   1853   1.1       rjs 	while (m_at) {
   1854   1.1       rjs 		if (m_at->m_next == NULL) {
   1855   1.1       rjs 			return (sctp_add_pad_tombuf(m_at, padval));
   1856   1.1       rjs 		}
   1857   1.1       rjs 		m_at = m_at->m_next;
   1858   1.1       rjs 	}
   1859   1.1       rjs 	return (EFAULT);
   1860   1.1       rjs }
   1861   1.1       rjs 
   1862   1.1       rjs static void
   1863   1.1       rjs sctp_notify_assoc_change(u_int32_t event, struct sctp_tcb *stcb,
   1864   1.1       rjs     u_int32_t error)
   1865   1.1       rjs {
   1866   1.1       rjs 	struct mbuf *m_notify;
   1867   1.1       rjs 	struct sctp_assoc_change *sac;
   1868   1.1       rjs 	const struct sockaddr *to;
   1869   1.1       rjs 	struct sockaddr_in6 sin6, lsa6;
   1870   1.1       rjs 
   1871   1.1       rjs #ifdef SCTP_DEBUG
   1872   1.1       rjs 	printf("notify: %d\n", event);
   1873   1.1       rjs #endif
   1874   1.1       rjs 	/*
   1875  1.14   msaitoh 	 * First if we are going down dump everything we
   1876   1.1       rjs 	 * can to the socket rcv queue.
   1877   1.1       rjs 	 */
   1878   1.1       rjs 	if ((event == SCTP_SHUTDOWN_COMP) || (event == SCTP_COMM_LOST)) {
   1879   1.1       rjs 		sctp_deliver_data(stcb, &stcb->asoc, NULL, 0);
   1880   1.1       rjs 	}
   1881   1.1       rjs 
   1882   1.1       rjs 	/*
   1883   1.1       rjs 	 * For TCP model AND UDP connected sockets we will send
   1884   1.1       rjs 	 * an error up when an ABORT comes in.
   1885   1.1       rjs 	 */
   1886   1.1       rjs 	if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   1887   1.1       rjs 	     (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) &&
   1888   1.1       rjs 	    (event == SCTP_COMM_LOST)) {
   1889   1.1       rjs 		stcb->sctp_socket->so_error = ECONNRESET;
   1890   1.1       rjs 		/* Wake ANY sleepers */
   1891   1.1       rjs 		sowwakeup(stcb->sctp_socket);
   1892   1.1       rjs 		sorwakeup(stcb->sctp_socket);
   1893   1.1       rjs 	}
   1894   1.1       rjs #if 0
   1895   1.1       rjs 	if ((event == SCTP_COMM_UP) &&
   1896   1.1       rjs 	    (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
   1897   1.1       rjs  	    (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) {
   1898   1.1       rjs 		 soisconnected(stcb->sctp_socket);
   1899   1.1       rjs 	}
   1900   1.1       rjs #endif
   1901   1.1       rjs 	if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_RECVASSOCEVNT)) {
   1902   1.1       rjs 		/* event not enabled */
   1903   1.1       rjs 		return;
   1904   1.1       rjs 	}
   1905   1.1       rjs 	MGETHDR(m_notify, M_DONTWAIT, MT_DATA);
   1906   1.1       rjs 	if (m_notify == NULL)
   1907   1.1       rjs 		/* no space left */
   1908   1.1       rjs 		return;
   1909   1.1       rjs 	m_notify->m_len = 0;
   1910   1.1       rjs 
   1911   1.1       rjs 	sac = mtod(m_notify, struct sctp_assoc_change *);
   1912   1.1       rjs 	sac->sac_type = SCTP_ASSOC_CHANGE;
   1913   1.1       rjs 	sac->sac_flags = 0;
   1914   1.1       rjs 	sac->sac_length = sizeof(struct sctp_assoc_change);
   1915   1.1       rjs 	sac->sac_state = event;
   1916   1.1       rjs 	sac->sac_error = error;
   1917   1.1       rjs 	/* XXX verify these stream counts */
   1918   1.1       rjs 	sac->sac_outbound_streams = stcb->asoc.streamoutcnt;
   1919   1.1       rjs 	sac->sac_inbound_streams = stcb->asoc.streamincnt;
   1920   1.1       rjs 	sac->sac_assoc_id = sctp_get_associd(stcb);
   1921   1.1       rjs 
   1922   1.1       rjs 	m_notify->m_flags |= M_EOR | M_NOTIFICATION;
   1923   1.1       rjs 	m_notify->m_pkthdr.len = sizeof(struct sctp_assoc_change);
   1924   1.9     ozaki 	m_reset_rcvif(m_notify);
   1925   1.1       rjs 	m_notify->m_len = sizeof(struct sctp_assoc_change);
   1926   1.1       rjs 	m_notify->m_next = NULL;
   1927   1.1       rjs 
   1928   1.1       rjs 	/* append to socket */
   1929   1.1       rjs 	to = rtcache_getdst(&stcb->asoc.primary_destination->ro);
   1930   1.1       rjs 	if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
   1931   1.1       rjs 	    to->sa_family == AF_INET) {
   1932   1.1       rjs 		const struct sockaddr_in *sin;
   1933   1.1       rjs 
   1934   1.1       rjs 		sin = (const struct sockaddr_in *)to;
   1935   1.2       rtr 		in6_sin_2_v4mapsin6(sin, &sin6);
   1936   1.1       rjs 		to = (struct sockaddr *)&sin6;
   1937   1.1       rjs 	}
   1938   1.1       rjs 	/* check and strip embedded scope junk */
   1939   1.1       rjs 	to = (const struct sockaddr *)sctp_recover_scope((const struct sockaddr_in6 *)to,
   1940   1.1       rjs 						   &lsa6);
   1941   1.1       rjs 	/*
   1942   1.1       rjs 	 * We need to always notify comm changes.
   1943   1.1       rjs 	 * if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
   1944   1.1       rjs 	 * 	sctp_m_freem(m_notify);
   1945   1.1       rjs 	 *	return;
   1946   1.1       rjs 	 * }
   1947   1.1       rjs 	*/
   1948   1.1       rjs 	SCTP_TCB_UNLOCK(stcb);
   1949   1.1       rjs 	SCTP_INP_WLOCK(stcb->sctp_ep);
   1950   1.1       rjs 	SCTP_TCB_LOCK(stcb);
   1951   1.1       rjs 	if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv,
   1952   1.1       rjs 	    to, m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) {
   1953   1.1       rjs 		/* not enough room */
   1954   1.1       rjs 		sctp_m_freem(m_notify);
   1955   1.1       rjs 		SCTP_INP_WUNLOCK(stcb->sctp_ep);
   1956   1.1       rjs 		return;
   1957   1.1       rjs 	}
   1958   1.1       rjs 	if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) &&
   1959   1.1       rjs 	   ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){
   1960   1.1       rjs 		if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) {
   1961   1.1       rjs 			stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
   1962   1.1       rjs 		}
   1963   1.1       rjs 	} else {
   1964   1.1       rjs 		stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
   1965   1.1       rjs 	}
   1966   1.1       rjs 	SCTP_INP_WUNLOCK(stcb->sctp_ep);
   1967   1.1       rjs 	/* Wake up any sleeper */
   1968   1.1       rjs 	sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
   1969   1.1       rjs 	sctp_sowwakeup(stcb->sctp_ep, stcb->sctp_socket);
   1970   1.1       rjs }
   1971   1.1       rjs 
   1972   1.1       rjs static void
   1973   1.1       rjs sctp_notify_peer_addr_change(struct sctp_tcb *stcb, uint32_t state,
   1974   1.1       rjs     const struct sockaddr *sa, uint32_t error)
   1975   1.1       rjs {
   1976   1.1       rjs 	struct mbuf *m_notify;
   1977   1.1       rjs 	struct sctp_paddr_change *spc;
   1978   1.1       rjs 	const struct sockaddr *to;
   1979   1.1       rjs 	struct sockaddr_in6 sin6, lsa6;
   1980   1.1       rjs 
   1981   1.1       rjs 	if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_RECVPADDREVNT))
   1982   1.1       rjs 		/* event not enabled */
   1983   1.1       rjs 		return;
   1984   1.1       rjs 
   1985   1.1       rjs 	MGETHDR(m_notify, M_DONTWAIT, MT_DATA);
   1986   1.1       rjs 	if (m_notify == NULL)
   1987   1.1       rjs 		return;
   1988   1.1       rjs 	m_notify->m_len = 0;
   1989   1.1       rjs 
   1990   1.1       rjs 	MCLGET(m_notify, M_DONTWAIT);
   1991   1.1       rjs 	if ((m_notify->m_flags & M_EXT) != M_EXT) {
   1992   1.1       rjs 		sctp_m_freem(m_notify);
   1993   1.1       rjs 		return;
   1994   1.1       rjs 	}
   1995   1.1       rjs 
   1996   1.1       rjs 	spc = mtod(m_notify, struct sctp_paddr_change *);
   1997   1.1       rjs 	spc->spc_type = SCTP_PEER_ADDR_CHANGE;
   1998   1.1       rjs 	spc->spc_flags = 0;
   1999   1.1       rjs 	spc->spc_length = sizeof(struct sctp_paddr_change);
   2000   1.1       rjs 	if (sa->sa_family == AF_INET) {
   2001   1.1       rjs 		memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_in));
   2002   1.1       rjs 	} else {
   2003   1.1       rjs 		memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_in6));
   2004   1.1       rjs 	}
   2005   1.1       rjs 	spc->spc_state = state;
   2006   1.1       rjs 	spc->spc_error = error;
   2007   1.1       rjs 	spc->spc_assoc_id = sctp_get_associd(stcb);
   2008   1.1       rjs 
   2009   1.1       rjs 	m_notify->m_flags |= M_EOR | M_NOTIFICATION;
   2010   1.1       rjs 	m_notify->m_pkthdr.len = sizeof(struct sctp_paddr_change);
   2011   1.9     ozaki 	m_reset_rcvif(m_notify);
   2012   1.1       rjs 	m_notify->m_len = sizeof(struct sctp_paddr_change);
   2013   1.1       rjs 	m_notify->m_next = NULL;
   2014   1.1       rjs 
   2015   1.1       rjs 	to = rtcache_getdst(&stcb->asoc.primary_destination->ro);
   2016   1.1       rjs 	if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
   2017   1.1       rjs 	    to->sa_family == AF_INET) {
   2018   1.1       rjs 		const struct sockaddr_in *sin;
   2019   1.1       rjs 
   2020   1.1       rjs 		sin = (const struct sockaddr_in *)to;
   2021   1.2       rtr 		in6_sin_2_v4mapsin6(sin, &sin6);
   2022   1.1       rjs 		to = (struct sockaddr *)&sin6;
   2023   1.1       rjs 	}
   2024   1.1       rjs 	/* check and strip embedded scope junk */
   2025   1.1       rjs 	to = (const struct sockaddr *)sctp_recover_scope((const struct sockaddr_in6 *)to,
   2026   1.1       rjs 	    &lsa6);
   2027   1.1       rjs 
   2028   1.1       rjs 	if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
   2029   1.1       rjs 		sctp_m_freem(m_notify);
   2030   1.1       rjs 		return;
   2031   1.1       rjs 	}
   2032   1.1       rjs 	/* append to socket */
   2033   1.1       rjs 	SCTP_TCB_UNLOCK(stcb);
   2034   1.1       rjs 	SCTP_INP_WLOCK(stcb->sctp_ep);
   2035   1.1       rjs 	SCTP_TCB_LOCK(stcb);
   2036   1.1       rjs 	if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, to,
   2037   1.1       rjs 	    m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) {
   2038   1.1       rjs 		/* not enough room */
   2039   1.1       rjs 		sctp_m_freem(m_notify);
   2040   1.1       rjs 		SCTP_INP_WUNLOCK(stcb->sctp_ep);
   2041   1.1       rjs 		return;
   2042   1.1       rjs 	}
   2043   1.1       rjs 	if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) &&
   2044   1.1       rjs 	   ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){
   2045   1.1       rjs 		if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) {
   2046   1.1       rjs 			stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
   2047   1.1       rjs 		}
   2048   1.1       rjs 	} else {
   2049   1.1       rjs 		stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
   2050   1.1       rjs 	}
   2051   1.1       rjs 	SCTP_INP_WUNLOCK(stcb->sctp_ep);
   2052   1.1       rjs 	sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
   2053   1.1       rjs }
   2054   1.1       rjs 
   2055   1.1       rjs 
   2056   1.1       rjs static void
   2057   1.1       rjs sctp_notify_send_failed(struct sctp_tcb *stcb, u_int32_t error,
   2058   1.1       rjs 			struct sctp_tmit_chunk *chk)
   2059   1.1       rjs {
   2060   1.1       rjs 	struct mbuf *m_notify;
   2061   1.1       rjs 	struct sctp_send_failed *ssf;
   2062   1.1       rjs 	struct sockaddr_in6 sin6, lsa6;
   2063   1.1       rjs 	const struct sockaddr *to;
   2064   1.1       rjs 	int length;
   2065   1.1       rjs 
   2066   1.1       rjs 	if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_RECVSENDFAILEVNT))
   2067   1.1       rjs 		/* event not enabled */
   2068   1.1       rjs 		return;
   2069   1.1       rjs 
   2070   1.1       rjs 	length = sizeof(struct sctp_send_failed) + chk->send_size;
   2071   1.1       rjs 	MGETHDR(m_notify, M_DONTWAIT, MT_DATA);
   2072   1.1       rjs 	if (m_notify == NULL)
   2073   1.1       rjs 		/* no space left */
   2074   1.1       rjs 		return;
   2075   1.1       rjs 	m_notify->m_len = 0;
   2076   1.1       rjs 	ssf = mtod(m_notify, struct sctp_send_failed *);
   2077   1.1       rjs 	ssf->ssf_type = SCTP_SEND_FAILED;
   2078   1.1       rjs 	if (error == SCTP_NOTIFY_DATAGRAM_UNSENT)
   2079   1.1       rjs 		ssf->ssf_flags = SCTP_DATA_UNSENT;
   2080   1.1       rjs 	else
   2081   1.1       rjs 		ssf->ssf_flags = SCTP_DATA_SENT;
   2082   1.1       rjs 	ssf->ssf_length = length;
   2083   1.1       rjs 	ssf->ssf_error = error;
   2084   1.1       rjs 	/* not exactly what the user sent in, but should be close :) */
   2085   1.1       rjs 	ssf->ssf_info.sinfo_stream = chk->rec.data.stream_number;
   2086   1.1       rjs 	ssf->ssf_info.sinfo_ssn = chk->rec.data.stream_seq;
   2087   1.1       rjs 	ssf->ssf_info.sinfo_flags = chk->rec.data.rcv_flags;
   2088   1.1       rjs 	ssf->ssf_info.sinfo_ppid = chk->rec.data.payloadtype;
   2089   1.1       rjs 	ssf->ssf_info.sinfo_context = chk->rec.data.context;
   2090   1.1       rjs 	ssf->ssf_info.sinfo_assoc_id = sctp_get_associd(stcb);
   2091   1.1       rjs 	ssf->ssf_assoc_id = sctp_get_associd(stcb);
   2092   1.1       rjs 	m_notify->m_next = chk->data;
   2093   1.1       rjs 	if (m_notify->m_next == NULL)
   2094   1.1       rjs 		m_notify->m_flags |= M_EOR | M_NOTIFICATION;
   2095   1.1       rjs 	else {
   2096   1.1       rjs 		struct mbuf *m;
   2097   1.1       rjs 		m_notify->m_flags |= M_NOTIFICATION;
   2098   1.1       rjs 		m = m_notify;
   2099   1.1       rjs 		while (m->m_next != NULL)
   2100   1.1       rjs 			m = m->m_next;
   2101   1.1       rjs 		m->m_flags |= M_EOR;
   2102   1.1       rjs 	}
   2103   1.1       rjs 	m_notify->m_pkthdr.len = length;
   2104   1.9     ozaki 	m_reset_rcvif(m_notify);
   2105   1.1       rjs 	m_notify->m_len = sizeof(struct sctp_send_failed);
   2106   1.1       rjs 
   2107   1.1       rjs 	/* Steal off the mbuf */
   2108   1.1       rjs 	chk->data = NULL;
   2109   1.1       rjs 	to = rtcache_getdst(&stcb->asoc.primary_destination->ro);
   2110   1.1       rjs 	if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
   2111   1.1       rjs 	    to->sa_family == AF_INET) {
   2112   1.1       rjs 		const struct sockaddr_in *sin;
   2113   1.1       rjs 
   2114   1.1       rjs 		sin = satocsin(to);
   2115   1.2       rtr 		in6_sin_2_v4mapsin6(sin, &sin6);
   2116   1.1       rjs 		to = (struct sockaddr *)&sin6;
   2117   1.1       rjs 	}
   2118   1.1       rjs 	/* check and strip embedded scope junk */
   2119   1.1       rjs 	to = (const struct sockaddr *)sctp_recover_scope((const struct sockaddr_in6 *)to,
   2120   1.1       rjs 						   &lsa6);
   2121   1.1       rjs 
   2122   1.1       rjs 	if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
   2123   1.1       rjs 		sctp_m_freem(m_notify);
   2124   1.1       rjs 		return;
   2125   1.1       rjs 	}
   2126   1.1       rjs 
   2127   1.1       rjs 	/* append to socket */
   2128   1.1       rjs 	SCTP_TCB_UNLOCK(stcb);
   2129   1.1       rjs 	SCTP_INP_WLOCK(stcb->sctp_ep);
   2130   1.1       rjs 	SCTP_TCB_LOCK(stcb);
   2131   1.1       rjs 	if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, to,
   2132   1.1       rjs 	    m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) {
   2133   1.1       rjs 		/* not enough room */
   2134   1.1       rjs 		sctp_m_freem(m_notify);
   2135   1.1       rjs 		SCTP_INP_WUNLOCK(stcb->sctp_ep);
   2136   1.1       rjs 		return;
   2137   1.1       rjs 	}
   2138   1.1       rjs 	if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) &&
   2139   1.1       rjs 	   ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){
   2140   1.1       rjs 		if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) {
   2141   1.1       rjs 			stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
   2142   1.1       rjs 		}
   2143   1.1       rjs 	} else {
   2144   1.1       rjs 		stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
   2145   1.1       rjs 	}
   2146   1.1       rjs 	SCTP_INP_WUNLOCK(stcb->sctp_ep);
   2147   1.1       rjs 	sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
   2148   1.1       rjs }
   2149   1.1       rjs 
   2150   1.1       rjs static void
   2151   1.1       rjs sctp_notify_adaption_layer(struct sctp_tcb *stcb,
   2152   1.1       rjs 			   u_int32_t error)
   2153   1.1       rjs {
   2154   1.1       rjs 	struct mbuf *m_notify;
   2155   1.1       rjs 	struct sctp_adaption_event *sai;
   2156   1.1       rjs 	struct sockaddr_in6 sin6, lsa6;
   2157   1.1       rjs 	const struct sockaddr *to;
   2158   1.1       rjs 
   2159   1.1       rjs 	if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_ADAPTIONEVNT))
   2160   1.1       rjs 		/* event not enabled */
   2161   1.1       rjs 		return;
   2162   1.1       rjs 
   2163   1.1       rjs 	MGETHDR(m_notify, M_DONTWAIT, MT_DATA);
   2164   1.1       rjs 	if (m_notify == NULL)
   2165   1.1       rjs 		/* no space left */
   2166   1.1       rjs 		return;
   2167   1.1       rjs 	m_notify->m_len = 0;
   2168   1.1       rjs 	sai = mtod(m_notify, struct sctp_adaption_event *);
   2169   1.1       rjs 	sai->sai_type = SCTP_ADAPTION_INDICATION;
   2170   1.1       rjs 	sai->sai_flags = 0;
   2171   1.1       rjs 	sai->sai_length = sizeof(struct sctp_adaption_event);
   2172   1.1       rjs 	sai->sai_adaption_ind = error;
   2173   1.1       rjs 	sai->sai_assoc_id = sctp_get_associd(stcb);
   2174   1.1       rjs 
   2175   1.1       rjs 	m_notify->m_flags |= M_EOR | M_NOTIFICATION;
   2176   1.1       rjs 	m_notify->m_pkthdr.len = sizeof(struct sctp_adaption_event);
   2177   1.9     ozaki 	m_reset_rcvif(m_notify);
   2178   1.1       rjs 	m_notify->m_len = sizeof(struct sctp_adaption_event);
   2179   1.1       rjs 	m_notify->m_next = NULL;
   2180   1.1       rjs 
   2181   1.1       rjs 	to = rtcache_getdst(&stcb->asoc.primary_destination->ro);
   2182   1.1       rjs 	if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
   2183   1.1       rjs 	    (to->sa_family == AF_INET)) {
   2184   1.1       rjs 		const struct sockaddr_in *sin;
   2185   1.1       rjs 
   2186   1.1       rjs 		sin = satocsin(to);
   2187   1.2       rtr 		in6_sin_2_v4mapsin6(sin, &sin6);
   2188   1.1       rjs 		to = (struct sockaddr *)&sin6;
   2189   1.1       rjs 	}
   2190   1.1       rjs 	/* check and strip embedded scope junk */
   2191   1.1       rjs 	to = (const struct sockaddr *)sctp_recover_scope((const struct sockaddr_in6 *)to,
   2192   1.1       rjs 						   &lsa6);
   2193   1.1       rjs 	if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
   2194   1.1       rjs 		sctp_m_freem(m_notify);
   2195   1.1       rjs 		return;
   2196   1.1       rjs 	}
   2197   1.1       rjs 	/* append to socket */
   2198   1.1       rjs 	SCTP_TCB_UNLOCK(stcb);
   2199   1.1       rjs 	SCTP_INP_WLOCK(stcb->sctp_ep);
   2200   1.1       rjs 	SCTP_TCB_LOCK(stcb);
   2201   1.1       rjs 	if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, to,
   2202   1.1       rjs 	    m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) {
   2203   1.1       rjs 		/* not enough room */
   2204   1.1       rjs 		sctp_m_freem(m_notify);
   2205   1.1       rjs 		SCTP_INP_WUNLOCK(stcb->sctp_ep);
   2206   1.1       rjs 		return;
   2207   1.1       rjs 	}
   2208   1.1       rjs 	if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) &&
   2209   1.1       rjs 	   ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){
   2210   1.1       rjs 		if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) {
   2211   1.1       rjs 			stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
   2212   1.1       rjs 		}
   2213   1.1       rjs 	} else {
   2214   1.1       rjs 		stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
   2215   1.1       rjs 	}
   2216   1.1       rjs 	SCTP_INP_WUNLOCK(stcb->sctp_ep);
   2217   1.1       rjs 	sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
   2218   1.1       rjs }
   2219   1.1       rjs 
   2220   1.1       rjs static void
   2221   1.1       rjs sctp_notify_partial_delivery_indication(struct sctp_tcb *stcb,
   2222   1.1       rjs 					u_int32_t error)
   2223   1.1       rjs {
   2224   1.1       rjs 	struct mbuf *m_notify;
   2225   1.1       rjs 	struct sctp_pdapi_event *pdapi;
   2226   1.1       rjs 	struct sockaddr_in6 sin6, lsa6;
   2227   1.1       rjs 	const struct sockaddr *to;
   2228   1.1       rjs 
   2229   1.1       rjs 	if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_PDAPIEVNT))
   2230   1.1       rjs 		/* event not enabled */
   2231   1.1       rjs 		return;
   2232   1.1       rjs 
   2233   1.1       rjs 	MGETHDR(m_notify, M_DONTWAIT, MT_DATA);
   2234   1.1       rjs 	if (m_notify == NULL)
   2235   1.1       rjs 		/* no space left */
   2236   1.1       rjs 		return;
   2237   1.1       rjs 	m_notify->m_len = 0;
   2238   1.1       rjs 	pdapi = mtod(m_notify, struct sctp_pdapi_event *);
   2239   1.1       rjs 	pdapi->pdapi_type = SCTP_PARTIAL_DELIVERY_EVENT;
   2240   1.1       rjs 	pdapi->pdapi_flags = 0;
   2241   1.1       rjs 	pdapi->pdapi_length = sizeof(struct sctp_pdapi_event);
   2242   1.1       rjs 	pdapi->pdapi_indication = error;
   2243   1.1       rjs 	pdapi->pdapi_assoc_id = sctp_get_associd(stcb);
   2244   1.1       rjs 
   2245   1.1       rjs 	m_notify->m_flags |= M_EOR | M_NOTIFICATION;
   2246   1.1       rjs 	m_notify->m_pkthdr.len = sizeof(struct sctp_pdapi_event);
   2247   1.9     ozaki 	m_reset_rcvif(m_notify);
   2248   1.1       rjs 	m_notify->m_len = sizeof(struct sctp_pdapi_event);
   2249   1.1       rjs 	m_notify->m_next = NULL;
   2250   1.1       rjs 
   2251   1.1       rjs 	to = rtcache_getdst(&stcb->asoc.primary_destination->ro);
   2252   1.1       rjs 	if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
   2253   1.1       rjs 	    (to->sa_family == AF_INET)) {
   2254   1.1       rjs 		const struct sockaddr_in *sin;
   2255   1.1       rjs 
   2256   1.1       rjs 		sin = satocsin(to);
   2257   1.2       rtr 		in6_sin_2_v4mapsin6(sin, &sin6);
   2258   1.1       rjs 		to = (struct sockaddr *)&sin6;
   2259   1.1       rjs 	}
   2260   1.1       rjs 	/* check and strip embedded scope junk */
   2261   1.1       rjs 	to = (const struct sockaddr *)sctp_recover_scope((const struct sockaddr_in6 *)to,
   2262   1.1       rjs 						   &lsa6);
   2263   1.1       rjs 	if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
   2264   1.1       rjs 		sctp_m_freem(m_notify);
   2265   1.1       rjs 		return;
   2266   1.1       rjs 	}
   2267   1.1       rjs 	/* append to socket */
   2268   1.1       rjs 	SCTP_TCB_UNLOCK(stcb);
   2269   1.1       rjs 	SCTP_INP_WLOCK(stcb->sctp_ep);
   2270   1.1       rjs 	SCTP_TCB_LOCK(stcb);
   2271   1.1       rjs 	if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, to,
   2272   1.1       rjs 	    m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) {
   2273   1.1       rjs 		/* not enough room */
   2274   1.1       rjs 		sctp_m_freem(m_notify);
   2275   1.1       rjs 		SCTP_INP_WUNLOCK(stcb->sctp_ep);
   2276   1.1       rjs 		return;
   2277   1.1       rjs 	}
   2278   1.1       rjs 	if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) &&
   2279   1.1       rjs 	   ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){
   2280   1.1       rjs 		if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) {
   2281   1.1       rjs 			stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
   2282   1.1       rjs 		}
   2283   1.1       rjs 	} else {
   2284   1.1       rjs 		stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
   2285   1.1       rjs 	}
   2286   1.1       rjs 	SCTP_INP_WUNLOCK(stcb->sctp_ep);
   2287   1.1       rjs 	sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
   2288   1.1       rjs }
   2289   1.1       rjs 
   2290   1.1       rjs static void
   2291   1.1       rjs sctp_notify_shutdown_event(struct sctp_tcb *stcb)
   2292   1.1       rjs {
   2293   1.1       rjs 	struct mbuf *m_notify;
   2294   1.1       rjs 	struct sctp_shutdown_event *sse;
   2295   1.1       rjs 	struct sockaddr_in6 sin6, lsa6;
   2296   1.1       rjs 	const struct sockaddr *to;
   2297   1.1       rjs 
   2298   1.1       rjs 	/*
   2299   1.1       rjs 	 * For TCP model AND UDP connected sockets we will send
   2300   1.1       rjs 	 * an error up when an SHUTDOWN completes
   2301   1.1       rjs 	 */
   2302   1.1       rjs 	if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   2303   1.1       rjs 	    (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
   2304   1.1       rjs 		/* mark socket closed for read/write and wakeup! */
   2305   1.1       rjs 		socantrcvmore(stcb->sctp_socket);
   2306   1.1       rjs 		socantsendmore(stcb->sctp_socket);
   2307   1.1       rjs 	}
   2308   1.1       rjs 
   2309   1.1       rjs 	if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT))
   2310   1.1       rjs 		/* event not enabled */
   2311   1.1       rjs 		return;
   2312   1.1       rjs 
   2313   1.1       rjs 	MGETHDR(m_notify, M_DONTWAIT, MT_DATA);
   2314   1.1       rjs 	if (m_notify == NULL)
   2315   1.1       rjs 		/* no space left */
   2316   1.1       rjs 		return;
   2317   1.1       rjs 	m_notify->m_len = 0;
   2318   1.1       rjs 	sse = mtod(m_notify, struct sctp_shutdown_event *);
   2319   1.1       rjs 	sse->sse_type = SCTP_SHUTDOWN_EVENT;
   2320   1.1       rjs 	sse->sse_flags = 0;
   2321   1.1       rjs 	sse->sse_length = sizeof(struct sctp_shutdown_event);
   2322   1.1       rjs 	sse->sse_assoc_id = sctp_get_associd(stcb);
   2323   1.1       rjs 
   2324   1.1       rjs 	m_notify->m_flags |= M_EOR | M_NOTIFICATION;
   2325   1.1       rjs 	m_notify->m_pkthdr.len = sizeof(struct sctp_shutdown_event);
   2326   1.9     ozaki 	m_reset_rcvif(m_notify);
   2327   1.1       rjs 	m_notify->m_len = sizeof(struct sctp_shutdown_event);
   2328   1.1       rjs 	m_notify->m_next = NULL;
   2329   1.1       rjs 
   2330   1.1       rjs 	to = rtcache_getdst(&stcb->asoc.primary_destination->ro);
   2331   1.1       rjs 	if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
   2332   1.1       rjs 	    to->sa_family == AF_INET) {
   2333   1.1       rjs 		const struct sockaddr_in *sin;
   2334   1.1       rjs 
   2335   1.1       rjs 		sin = satocsin(to);
   2336   1.2       rtr 		in6_sin_2_v4mapsin6(sin, &sin6);
   2337   1.1       rjs 		to = (struct sockaddr *)&sin6;
   2338   1.1       rjs 	}
   2339   1.1       rjs 	/* check and strip embedded scope junk */
   2340   1.1       rjs 	to = (const struct sockaddr *)sctp_recover_scope((const struct sockaddr_in6 *)to,
   2341   1.1       rjs 	    &lsa6);
   2342   1.1       rjs 	if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
   2343   1.1       rjs 		sctp_m_freem(m_notify);
   2344   1.1       rjs 		return;
   2345   1.1       rjs 	}
   2346   1.1       rjs 	/* append to socket */
   2347   1.1       rjs 	SCTP_TCB_UNLOCK(stcb);
   2348   1.1       rjs 	SCTP_INP_WLOCK(stcb->sctp_ep);
   2349   1.1       rjs 	SCTP_TCB_LOCK(stcb);
   2350   1.1       rjs 	if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, to,
   2351   1.1       rjs 	    m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) {
   2352   1.1       rjs 		/* not enough room */
   2353   1.1       rjs 		sctp_m_freem(m_notify);
   2354   1.1       rjs 		SCTP_INP_WUNLOCK(stcb->sctp_ep);
   2355   1.1       rjs 		return;
   2356   1.1       rjs 	}
   2357   1.1       rjs 	if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) &&
   2358   1.1       rjs 	   ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){
   2359   1.1       rjs 		if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) {
   2360   1.1       rjs 			stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
   2361   1.1       rjs 		}
   2362   1.1       rjs 	} else {
   2363   1.1       rjs 		stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
   2364   1.1       rjs 	}
   2365   1.1       rjs 	SCTP_INP_WUNLOCK(stcb->sctp_ep);
   2366   1.1       rjs 	sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
   2367   1.1       rjs }
   2368   1.1       rjs 
   2369   1.1       rjs static void
   2370   1.1       rjs sctp_notify_stream_reset(struct sctp_tcb *stcb,
   2371   1.1       rjs     int number_entries, uint16_t *list, int flag)
   2372   1.1       rjs {
   2373   1.1       rjs 	struct mbuf *m_notify;
   2374   1.1       rjs 	struct sctp_stream_reset_event *strreset;
   2375   1.1       rjs 	struct sockaddr_in6 sin6, lsa6;
   2376   1.1       rjs 	const struct sockaddr *to;
   2377   1.1       rjs 	int len;
   2378   1.1       rjs 
   2379   1.1       rjs 	if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_STREAM_RESETEVNT))
   2380   1.1       rjs 		/* event not enabled */
   2381   1.1       rjs 		return;
   2382   1.1       rjs 
   2383   1.1       rjs 	MGETHDR(m_notify, M_DONTWAIT, MT_DATA);
   2384   1.1       rjs 	if (m_notify == NULL)
   2385   1.1       rjs 		/* no space left */
   2386   1.1       rjs 		return;
   2387   1.1       rjs 	m_notify->m_len = 0;
   2388   1.1       rjs 	len = sizeof(struct sctp_stream_reset_event) + (number_entries * sizeof(uint16_t));
   2389   1.1       rjs 	if (len > M_TRAILINGSPACE(m_notify)) {
   2390   1.1       rjs 		MCLGET(m_notify, M_WAIT);
   2391   1.1       rjs 	}
   2392   1.1       rjs 	if (m_notify == NULL)
   2393   1.1       rjs 		/* no clusters */
   2394   1.1       rjs 		return;
   2395   1.1       rjs 
   2396   1.1       rjs 	if (len > M_TRAILINGSPACE(m_notify)) {
   2397   1.1       rjs 		/* never enough room */
   2398   1.1       rjs 		m_freem(m_notify);
   2399   1.1       rjs 		return;
   2400   1.1       rjs 	}
   2401   1.1       rjs 	strreset = mtod(m_notify, struct sctp_stream_reset_event *);
   2402   1.1       rjs 	strreset->strreset_type = SCTP_STREAM_RESET_EVENT;
   2403   1.1       rjs 	if (number_entries == 0) {
   2404   1.1       rjs 		strreset->strreset_flags = flag | SCTP_STRRESET_ALL_STREAMS;
   2405   1.1       rjs 	} else {
   2406   1.1       rjs 		strreset->strreset_flags = flag | SCTP_STRRESET_STREAM_LIST;
   2407   1.1       rjs 	}
   2408   1.1       rjs 	strreset->strreset_length = len;
   2409   1.1       rjs 	strreset->strreset_assoc_id = sctp_get_associd(stcb);
   2410   1.1       rjs 	if (number_entries) {
   2411   1.1       rjs 		int i;
   2412   1.1       rjs 		for (i=0; i<number_entries; i++) {
   2413   1.1       rjs 			strreset->strreset_list[i] = list[i];
   2414   1.1       rjs 		}
   2415   1.1       rjs 	}
   2416   1.1       rjs 	m_notify->m_flags |= M_EOR | M_NOTIFICATION;
   2417   1.1       rjs 	m_notify->m_pkthdr.len = len;
   2418   1.9     ozaki 	m_reset_rcvif(m_notify);
   2419   1.1       rjs 	m_notify->m_len = len;
   2420   1.1       rjs 	m_notify->m_next = NULL;
   2421   1.1       rjs 	if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
   2422   1.1       rjs 		/* no space */
   2423   1.1       rjs 		sctp_m_freem(m_notify);
   2424   1.1       rjs 		return;
   2425   1.1       rjs 	}
   2426   1.1       rjs 	to = rtcache_getdst(&stcb->asoc.primary_destination->ro);
   2427   1.1       rjs 	if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
   2428   1.1       rjs 	    to->sa_family == AF_INET) {
   2429   1.1       rjs 		const struct sockaddr_in *sin;
   2430   1.1       rjs 
   2431   1.1       rjs 		sin = satocsin(to);
   2432   1.2       rtr 		in6_sin_2_v4mapsin6(sin, &sin6);
   2433   1.1       rjs 		to = (struct sockaddr *)&sin6;
   2434   1.1       rjs 	}
   2435   1.1       rjs 	/* check and strip embedded scope junk */
   2436   1.1       rjs 	to = (const struct sockaddr *) sctp_recover_scope((const struct sockaddr_in6 *)to,
   2437   1.1       rjs 	    &lsa6);
   2438   1.1       rjs 	/* append to socket */
   2439   1.1       rjs 	SCTP_TCB_UNLOCK(stcb);
   2440   1.1       rjs 	SCTP_INP_WLOCK(stcb->sctp_ep);
   2441   1.1       rjs 	SCTP_TCB_LOCK(stcb);
   2442   1.1       rjs 	if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, to,
   2443   1.1       rjs 	    m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) {
   2444   1.1       rjs 		/* not enough room */
   2445   1.1       rjs 		sctp_m_freem(m_notify);
   2446   1.1       rjs 		SCTP_INP_WUNLOCK(stcb->sctp_ep);
   2447   1.1       rjs 		return;
   2448   1.1       rjs 	}
   2449   1.1       rjs 	if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) &&
   2450   1.1       rjs 	   ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){
   2451   1.1       rjs 		if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) {
   2452   1.1       rjs 			stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
   2453   1.1       rjs 		}
   2454   1.1       rjs 	} else {
   2455   1.1       rjs 		stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
   2456   1.1       rjs 	}
   2457   1.1       rjs 	SCTP_INP_WUNLOCK(stcb->sctp_ep);
   2458   1.1       rjs 	sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
   2459   1.1       rjs }
   2460   1.1       rjs 
   2461   1.1       rjs 
   2462   1.1       rjs void
   2463   1.1       rjs sctp_ulp_notify(u_int32_t notification, struct sctp_tcb *stcb,
   2464   1.1       rjs 		u_int32_t error, void *data)
   2465   1.1       rjs {
   2466   1.1       rjs 	if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
   2467   1.1       rjs 		/* No notifications up when we are in a no socket state */
   2468   1.1       rjs 		return;
   2469   1.1       rjs 	}
   2470   1.1       rjs 	if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
   2471   1.1       rjs 		/* Can't send up to a closed socket any notifications */
   2472   1.1       rjs 		return;
   2473   1.1       rjs 	}
   2474   1.1       rjs 	switch (notification) {
   2475   1.1       rjs 	case SCTP_NOTIFY_ASSOC_UP:
   2476   1.1       rjs 		sctp_notify_assoc_change(SCTP_COMM_UP, stcb, error);
   2477   1.1       rjs 		break;
   2478   1.1       rjs 	case SCTP_NOTIFY_ASSOC_DOWN:
   2479   1.1       rjs 		sctp_notify_assoc_change(SCTP_SHUTDOWN_COMP, stcb, error);
   2480   1.1       rjs 		break;
   2481   1.1       rjs 	case SCTP_NOTIFY_INTERFACE_DOWN:
   2482   1.1       rjs 	{
   2483   1.1       rjs 		struct sctp_nets *net;
   2484   1.1       rjs 		net = (struct sctp_nets *)data;
   2485   1.1       rjs 		sctp_notify_peer_addr_change(stcb, SCTP_ADDR_UNREACHABLE,
   2486   1.1       rjs 		    rtcache_getdst(&net->ro), error);
   2487   1.1       rjs 		break;
   2488   1.1       rjs 	}
   2489   1.1       rjs 	case SCTP_NOTIFY_INTERFACE_UP:
   2490   1.1       rjs 	{
   2491   1.1       rjs 		struct sctp_nets *net;
   2492   1.1       rjs 		net = (struct sctp_nets *)data;
   2493   1.1       rjs 		sctp_notify_peer_addr_change(stcb, SCTP_ADDR_AVAILABLE,
   2494   1.1       rjs 		    rtcache_getdst(&net->ro), error);
   2495   1.1       rjs 		break;
   2496   1.1       rjs 	}
   2497   1.1       rjs 	case SCTP_NOTIFY_INTERFACE_CONFIRMED:
   2498   1.1       rjs 	{
   2499   1.1       rjs 		struct sctp_nets *net;
   2500   1.1       rjs 		net = (struct sctp_nets *)data;
   2501   1.1       rjs 		sctp_notify_peer_addr_change(stcb, SCTP_ADDR_CONFIRMED,
   2502   1.1       rjs 		    rtcache_getdst(&net->ro), error);
   2503   1.1       rjs 		break;
   2504   1.1       rjs 	}
   2505   1.1       rjs 	case SCTP_NOTIFY_DG_FAIL:
   2506   1.1       rjs 		sctp_notify_send_failed(stcb, error,
   2507   1.1       rjs 		    (struct sctp_tmit_chunk *)data);
   2508   1.1       rjs 		break;
   2509   1.1       rjs 	case SCTP_NOTIFY_ADAPTION_INDICATION:
   2510   1.1       rjs 		/* Here the error is the adaption indication */
   2511   1.1       rjs 		sctp_notify_adaption_layer(stcb, error);
   2512   1.1       rjs 		break;
   2513   1.1       rjs 	case SCTP_NOTIFY_PARTIAL_DELVIERY_INDICATION:
   2514   1.1       rjs 		sctp_notify_partial_delivery_indication(stcb, error);
   2515   1.1       rjs 		break;
   2516   1.1       rjs 	case SCTP_NOTIFY_STRDATA_ERR:
   2517   1.1       rjs 		break;
   2518   1.1       rjs 	case SCTP_NOTIFY_ASSOC_ABORTED:
   2519   1.1       rjs 		sctp_notify_assoc_change(SCTP_COMM_LOST, stcb, error);
   2520   1.1       rjs 		break;
   2521   1.1       rjs 	case SCTP_NOTIFY_PEER_OPENED_STREAM:
   2522   1.1       rjs 		break;
   2523   1.1       rjs 	case SCTP_NOTIFY_STREAM_OPENED_OK:
   2524   1.1       rjs 		break;
   2525   1.1       rjs 	case SCTP_NOTIFY_ASSOC_RESTART:
   2526   1.1       rjs 		sctp_notify_assoc_change(SCTP_RESTART, stcb, error);
   2527   1.1       rjs 		break;
   2528   1.1       rjs 	case SCTP_NOTIFY_HB_RESP:
   2529   1.1       rjs 		break;
   2530   1.1       rjs 	case SCTP_NOTIFY_STR_RESET_SEND:
   2531   1.1       rjs 		sctp_notify_stream_reset(stcb, error, ((uint16_t *)data), SCTP_STRRESET_OUTBOUND_STR);
   2532   1.1       rjs 		break;
   2533   1.1       rjs 	case SCTP_NOTIFY_STR_RESET_RECV:
   2534   1.1       rjs 		sctp_notify_stream_reset(stcb, error, ((uint16_t *)data), SCTP_STRRESET_INBOUND_STR);
   2535   1.1       rjs 		break;
   2536   1.1       rjs 	case SCTP_NOTIFY_ASCONF_ADD_IP:
   2537   1.1       rjs 		sctp_notify_peer_addr_change(stcb, SCTP_ADDR_ADDED, data,
   2538   1.1       rjs 		    error);
   2539   1.1       rjs 		break;
   2540   1.1       rjs 	case SCTP_NOTIFY_ASCONF_DELETE_IP:
   2541   1.1       rjs 		sctp_notify_peer_addr_change(stcb, SCTP_ADDR_REMOVED, data,
   2542   1.1       rjs 		    error);
   2543   1.1       rjs 		break;
   2544   1.1       rjs 	case SCTP_NOTIFY_ASCONF_SET_PRIMARY:
   2545   1.1       rjs 		sctp_notify_peer_addr_change(stcb, SCTP_ADDR_MADE_PRIM, data,
   2546   1.1       rjs 		    error);
   2547   1.1       rjs 		break;
   2548   1.1       rjs 	case SCTP_NOTIFY_ASCONF_SUCCESS:
   2549   1.1       rjs 		break;
   2550   1.1       rjs 	case SCTP_NOTIFY_ASCONF_FAILED:
   2551   1.1       rjs 		break;
   2552   1.1       rjs 	case SCTP_NOTIFY_PEER_SHUTDOWN:
   2553   1.1       rjs 		sctp_notify_shutdown_event(stcb);
   2554   1.1       rjs 		break;
   2555   1.1       rjs 	default:
   2556   1.1       rjs #ifdef SCTP_DEBUG
   2557   1.1       rjs 		if (sctp_debug_on & SCTP_DEBUG_UTIL1) {
   2558   1.1       rjs 			printf("NOTIFY: unknown notification %xh (%u)\n",
   2559   1.1       rjs 			    notification, notification);
   2560   1.1       rjs 		}
   2561   1.1       rjs #endif /* SCTP_DEBUG */
   2562   1.1       rjs 		break;
   2563   1.1       rjs 	} /* end switch */
   2564   1.1       rjs }
   2565   1.1       rjs 
   2566   1.1       rjs void
   2567   1.1       rjs sctp_report_all_outbound(struct sctp_tcb *stcb)
   2568   1.1       rjs {
   2569   1.1       rjs 	struct sctp_association *asoc;
   2570   1.1       rjs 	struct sctp_stream_out *outs;
   2571   1.1       rjs 	struct sctp_tmit_chunk *chk;
   2572   1.1       rjs 
   2573   1.1       rjs 	asoc = &stcb->asoc;
   2574   1.1       rjs 
   2575   1.1       rjs 	if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
   2576   1.1       rjs 		return;
   2577   1.1       rjs 	}
   2578   1.1       rjs 	/* now through all the gunk freeing chunks */
   2579   1.1       rjs 	TAILQ_FOREACH(outs, &asoc->out_wheel, next_spoke) {
   2580   1.1       rjs 		/* now clean up any chunks here */
   2581   1.1       rjs 		chk = TAILQ_FIRST(&outs->outqueue);
   2582   1.1       rjs 		while (chk) {
   2583   1.1       rjs 			stcb->asoc.stream_queue_cnt--;
   2584   1.1       rjs 			TAILQ_REMOVE(&outs->outqueue, chk, sctp_next);
   2585   1.1       rjs 			sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb,
   2586   1.1       rjs 			    SCTP_NOTIFY_DATAGRAM_UNSENT, chk);
   2587  1.20       rin 			sctp_m_freem(chk->data);
   2588  1.20       rin 			chk->data = NULL;
   2589   1.1       rjs 			if (chk->whoTo)
   2590   1.1       rjs 				sctp_free_remote_addr(chk->whoTo);
   2591   1.1       rjs 			chk->whoTo = NULL;
   2592   1.1       rjs 			chk->asoc = NULL;
   2593   1.1       rjs 			/* Free the chunk */
   2594   1.1       rjs 			SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_chunk, chk);
   2595   1.1       rjs 			sctppcbinfo.ipi_count_chunk--;
   2596   1.1       rjs 			if ((int)sctppcbinfo.ipi_count_chunk < 0) {
   2597   1.1       rjs 				panic("Chunk count is negative");
   2598   1.1       rjs 			}
   2599   1.1       rjs 			sctppcbinfo.ipi_gencnt_chunk++;
   2600   1.1       rjs 			chk = TAILQ_FIRST(&outs->outqueue);
   2601   1.1       rjs 		}
   2602   1.1       rjs 	}
   2603   1.1       rjs 	/* pending send queue SHOULD be empty */
   2604   1.1       rjs 	if (!TAILQ_EMPTY(&asoc->send_queue)) {
   2605   1.1       rjs 		chk = TAILQ_FIRST(&asoc->send_queue);
   2606   1.1       rjs 		while (chk) {
   2607   1.1       rjs 			TAILQ_REMOVE(&asoc->send_queue, chk, sctp_next);
   2608   1.1       rjs 			sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb, SCTP_NOTIFY_DATAGRAM_UNSENT, chk);
   2609  1.20       rin 			sctp_m_freem(chk->data);
   2610  1.20       rin 			chk->data = NULL;
   2611   1.1       rjs 			if (chk->whoTo)
   2612   1.1       rjs 				sctp_free_remote_addr(chk->whoTo);
   2613   1.1       rjs 			chk->whoTo = NULL;
   2614   1.1       rjs 			SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_chunk, chk);
   2615   1.1       rjs 			sctppcbinfo.ipi_count_chunk--;
   2616   1.1       rjs 			if ((int)sctppcbinfo.ipi_count_chunk < 0) {
   2617   1.1       rjs 				panic("Chunk count is negative");
   2618   1.1       rjs 			}
   2619   1.1       rjs 			sctppcbinfo.ipi_gencnt_chunk++;
   2620   1.1       rjs 			chk = TAILQ_FIRST(&asoc->send_queue);
   2621   1.1       rjs 		}
   2622   1.1       rjs 	}
   2623   1.1       rjs 	/* sent queue SHOULD be empty */
   2624   1.1       rjs 	if (!TAILQ_EMPTY(&asoc->sent_queue)) {
   2625   1.1       rjs 		chk = TAILQ_FIRST(&asoc->sent_queue);
   2626   1.1       rjs 		while (chk) {
   2627   1.1       rjs 			TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next);
   2628   1.1       rjs 			sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb,
   2629   1.1       rjs 			    SCTP_NOTIFY_DATAGRAM_SENT, chk);
   2630  1.20       rin 			sctp_m_freem(chk->data);
   2631  1.20       rin 			chk->data = NULL;
   2632   1.1       rjs 			if (chk->whoTo)
   2633   1.1       rjs 				sctp_free_remote_addr(chk->whoTo);
   2634   1.1       rjs 			chk->whoTo = NULL;
   2635   1.1       rjs 			SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_chunk, chk);
   2636   1.1       rjs 			sctppcbinfo.ipi_count_chunk--;
   2637   1.1       rjs 			if ((int)sctppcbinfo.ipi_count_chunk < 0) {
   2638   1.1       rjs 				panic("Chunk count is negative");
   2639   1.1       rjs 			}
   2640   1.1       rjs 			sctppcbinfo.ipi_gencnt_chunk++;
   2641   1.1       rjs 			chk = TAILQ_FIRST(&asoc->sent_queue);
   2642   1.1       rjs 		}
   2643   1.1       rjs 	}
   2644   1.1       rjs }
   2645   1.1       rjs 
   2646   1.1       rjs void
   2647   1.1       rjs sctp_abort_notification(struct sctp_tcb *stcb, int error)
   2648   1.1       rjs {
   2649   1.1       rjs 
   2650   1.1       rjs 	if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
   2651   1.1       rjs 		return;
   2652   1.1       rjs 	}
   2653   1.1       rjs 	/* Tell them we lost the asoc */
   2654   1.1       rjs 	sctp_report_all_outbound(stcb);
   2655   1.1       rjs 	sctp_ulp_notify(SCTP_NOTIFY_ASSOC_ABORTED, stcb, error, NULL);
   2656   1.1       rjs }
   2657   1.1       rjs 
   2658   1.1       rjs void
   2659   1.1       rjs sctp_abort_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
   2660   1.1       rjs     struct mbuf *m, int iphlen, struct sctphdr *sh, struct mbuf *op_err)
   2661   1.1       rjs {
   2662   1.1       rjs 	u_int32_t vtag;
   2663   1.1       rjs 
   2664   1.1       rjs 	vtag = 0;
   2665   1.1       rjs 	if (stcb != NULL) {
   2666   1.1       rjs 		/* We have a TCB to abort, send notification too */
   2667   1.1       rjs 		vtag = stcb->asoc.peer_vtag;
   2668   1.1       rjs 		sctp_abort_notification(stcb, 0);
   2669   1.1       rjs 	}
   2670   1.1       rjs 	sctp_send_abort(m, iphlen, sh, vtag, op_err);
   2671   1.1       rjs 	if (stcb != NULL) {
   2672   1.1       rjs 		/* Ok, now lets free it */
   2673   1.1       rjs 		sctp_free_assoc(inp, stcb);
   2674   1.1       rjs 	} else {
   2675   1.1       rjs 		if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
   2676   1.1       rjs 			if (LIST_FIRST(&inp->sctp_asoc_list) == NULL) {
   2677   1.1       rjs 				sctp_inpcb_free(inp, 1);
   2678   1.1       rjs 			}
   2679   1.1       rjs 		}
   2680   1.1       rjs 	}
   2681   1.1       rjs }
   2682   1.1       rjs 
   2683   1.1       rjs void
   2684   1.1       rjs sctp_abort_an_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
   2685   1.1       rjs     int error, struct mbuf *op_err)
   2686   1.1       rjs {
   2687   1.1       rjs 
   2688   1.1       rjs 	if (stcb == NULL) {
   2689   1.1       rjs 		/* Got to have a TCB */
   2690   1.1       rjs 		if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
   2691   1.1       rjs 			if (LIST_FIRST(&inp->sctp_asoc_list) == NULL) {
   2692   1.1       rjs 				sctp_inpcb_free(inp, 1);
   2693   1.1       rjs 			}
   2694   1.1       rjs 		}
   2695   1.1       rjs 		return;
   2696   1.1       rjs 	}
   2697   1.1       rjs 	/* notify the ulp */
   2698   1.1       rjs 	if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0)
   2699   1.1       rjs 		sctp_abort_notification(stcb, error);
   2700   1.1       rjs 	/* notify the peer */
   2701   1.1       rjs 	sctp_send_abort_tcb(stcb, op_err);
   2702   1.1       rjs 	/* now free the asoc */
   2703   1.1       rjs 	sctp_free_assoc(inp, stcb);
   2704   1.1       rjs }
   2705   1.1       rjs 
   2706   1.1       rjs void
   2707   1.1       rjs sctp_handle_ootb(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
   2708   1.1       rjs     struct sctp_inpcb *inp, struct mbuf *op_err)
   2709   1.1       rjs {
   2710   1.1       rjs 	struct sctp_chunkhdr *ch, chunk_buf;
   2711   1.1       rjs 	unsigned int chk_length;
   2712   1.1       rjs 
   2713   1.1       rjs 	/* Generate a TO address for future reference */
   2714   1.1       rjs 	if (inp && (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) {
   2715   1.1       rjs 		if (LIST_FIRST(&inp->sctp_asoc_list) == NULL) {
   2716   1.1       rjs 			sctp_inpcb_free(inp, 1);
   2717   1.1       rjs 		}
   2718   1.1       rjs 	}
   2719   1.1       rjs 	ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset,
   2720   1.1       rjs 	    sizeof(*ch), (u_int8_t *)&chunk_buf);
   2721   1.1       rjs 	while (ch != NULL) {
   2722   1.1       rjs 		chk_length = ntohs(ch->chunk_length);
   2723   1.1       rjs 		if (chk_length < sizeof(*ch)) {
   2724   1.1       rjs 			/* break to abort land */
   2725   1.1       rjs 			break;
   2726   1.1       rjs 		}
   2727   1.1       rjs 		switch (ch->chunk_type) {
   2728   1.1       rjs 		case SCTP_PACKET_DROPPED:
   2729   1.1       rjs 			/* we don't respond to pkt-dropped */
   2730   1.1       rjs 			return;
   2731   1.1       rjs 		case SCTP_ABORT_ASSOCIATION:
   2732   1.1       rjs 			/* we don't respond with an ABORT to an ABORT */
   2733   1.1       rjs 			return;
   2734   1.1       rjs 		case SCTP_SHUTDOWN_COMPLETE:
   2735   1.1       rjs 			/*
   2736   1.1       rjs 			 * we ignore it since we are not waiting for it
   2737   1.1       rjs 			 * and peer is gone
   2738   1.1       rjs 			 */
   2739   1.1       rjs 			return;
   2740   1.1       rjs 		case SCTP_SHUTDOWN_ACK:
   2741   1.1       rjs 			sctp_send_shutdown_complete2(m, iphlen, sh);
   2742   1.1       rjs 			return;
   2743   1.1       rjs 		default:
   2744   1.1       rjs 			break;
   2745   1.1       rjs 		}
   2746   1.1       rjs 		offset += SCTP_SIZE32(chk_length);
   2747   1.1       rjs 		ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset,
   2748   1.1       rjs 		    sizeof(*ch), (u_int8_t *)&chunk_buf);
   2749   1.1       rjs 	}
   2750   1.1       rjs 	sctp_send_abort(m, iphlen, sh, 0, op_err);
   2751   1.1       rjs }
   2752   1.1       rjs 
   2753   1.1       rjs /*
   2754   1.1       rjs  * check the inbound datagram to make sure there is not an abort
   2755   1.1       rjs  * inside it, if there is return 1, else return 0.
   2756   1.1       rjs  */
   2757   1.1       rjs int
   2758   1.1       rjs sctp_is_there_an_abort_here(struct mbuf *m, int iphlen, int *vtagfill)
   2759   1.1       rjs {
   2760   1.1       rjs 	struct sctp_chunkhdr *ch;
   2761   1.1       rjs 	struct sctp_init_chunk *init_chk, chunk_buf;
   2762   1.1       rjs 	int offset;
   2763   1.1       rjs 	unsigned int chk_length;
   2764   1.1       rjs 
   2765   1.1       rjs 	offset = iphlen + sizeof(struct sctphdr);
   2766   1.1       rjs 	ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset, sizeof(*ch),
   2767   1.1       rjs 	    (u_int8_t *)&chunk_buf);
   2768   1.1       rjs 	while (ch != NULL) {
   2769   1.1       rjs 		chk_length = ntohs(ch->chunk_length);
   2770   1.1       rjs 		if (chk_length < sizeof(*ch)) {
   2771   1.1       rjs 			/* packet is probably corrupt */
   2772   1.1       rjs 			break;
   2773   1.1       rjs 		}
   2774   1.1       rjs 		/* we seem to be ok, is it an abort? */
   2775   1.1       rjs 		if (ch->chunk_type == SCTP_ABORT_ASSOCIATION) {
   2776   1.1       rjs 			/* yep, tell them */
   2777   1.1       rjs 			return (1);
   2778   1.1       rjs 		}
   2779   1.1       rjs 		if (ch->chunk_type == SCTP_INITIATION) {
   2780   1.1       rjs 			/* need to update the Vtag */
   2781   1.1       rjs 			init_chk = (struct sctp_init_chunk *)sctp_m_getptr(m,
   2782   1.1       rjs 			    offset, sizeof(*init_chk), (u_int8_t *)&chunk_buf);
   2783   1.1       rjs 			if (init_chk != NULL) {
   2784   1.1       rjs 				*vtagfill = ntohl(init_chk->init.initiate_tag);
   2785   1.1       rjs 			}
   2786   1.1       rjs 		}
   2787   1.1       rjs 		/* Nope, move to the next chunk */
   2788   1.1       rjs 		offset += SCTP_SIZE32(chk_length);
   2789   1.1       rjs 		ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset,
   2790   1.1       rjs 		    sizeof(*ch), (u_int8_t *)&chunk_buf);
   2791   1.1       rjs 	}
   2792   1.1       rjs 	return (0);
   2793   1.1       rjs }
   2794   1.1       rjs 
   2795   1.1       rjs /*
   2796   1.1       rjs  * currently (2/02), ifa_addr embeds scope_id's and don't
   2797   1.1       rjs  * have sin6_scope_id set (i.e. it's 0)
   2798   1.1       rjs  * so, create this function to compare link local scopes
   2799   1.1       rjs  */
   2800   1.1       rjs uint32_t
   2801   1.8       rjs sctp_is_same_scope(const struct sockaddr_in6 *addr1, const struct sockaddr_in6 *addr2)
   2802   1.1       rjs {
   2803   1.1       rjs 	struct sockaddr_in6 a, b;
   2804   1.1       rjs 
   2805   1.1       rjs 	/* save copies */
   2806   1.1       rjs 	a = *addr1;
   2807   1.1       rjs 	b = *addr2;
   2808   1.1       rjs 
   2809   1.1       rjs 	if (a.sin6_scope_id == 0)
   2810   1.1       rjs 		if (sa6_recoverscope(&a)) {
   2811   1.1       rjs 			/* can't get scope, so can't match */
   2812   1.1       rjs 			return (0);
   2813   1.1       rjs 		}
   2814   1.1       rjs 	if (b.sin6_scope_id == 0)
   2815   1.1       rjs 		if (sa6_recoverscope(&b)) {
   2816   1.1       rjs 			/* can't get scope, so can't match */
   2817   1.1       rjs 			return (0);
   2818   1.1       rjs 		}
   2819   1.1       rjs 	if (a.sin6_scope_id != b.sin6_scope_id)
   2820   1.1       rjs 		return (0);
   2821   1.1       rjs 
   2822   1.1       rjs 	return (1);
   2823   1.1       rjs }
   2824   1.1       rjs 
   2825   1.1       rjs /*
   2826   1.1       rjs  * returns a sockaddr_in6 with embedded scope recovered and removed
   2827   1.1       rjs  */
   2828   1.1       rjs const struct sockaddr_in6 *
   2829   1.1       rjs sctp_recover_scope(const struct sockaddr_in6 *addr, struct sockaddr_in6 *store)
   2830   1.1       rjs {
   2831   1.1       rjs 	const struct sockaddr_in6 *newaddr;
   2832   1.1       rjs 
   2833   1.1       rjs 	newaddr = addr;
   2834   1.1       rjs 	/* check and strip embedded scope junk */
   2835   1.1       rjs 	if (addr->sin6_family == AF_INET6) {
   2836   1.1       rjs 		if (IN6_IS_SCOPE_LINKLOCAL(&addr->sin6_addr)) {
   2837   1.1       rjs 			if (addr->sin6_scope_id == 0) {
   2838   1.1       rjs 				*store = *addr;
   2839   1.1       rjs 				if (sa6_recoverscope(store) == 0) {
   2840   1.1       rjs 					/* use the recovered scope */
   2841   1.1       rjs 					newaddr = store;
   2842   1.1       rjs 				}
   2843   1.1       rjs 				/* else, return the original "to" addr */
   2844   1.1       rjs 			}
   2845   1.1       rjs 		}
   2846   1.1       rjs 	}
   2847   1.1       rjs 	return (newaddr);
   2848   1.1       rjs }
   2849   1.1       rjs 
   2850   1.1       rjs /*
   2851   1.1       rjs  * are the two addresses the same?  currently a "scopeless" check
   2852   1.1       rjs  * returns: 1 if same, 0 if not
   2853   1.1       rjs  */
   2854   1.1       rjs int
   2855   1.1       rjs sctp_cmpaddr(const struct sockaddr *sa1, const struct sockaddr *sa2)
   2856   1.1       rjs {
   2857   1.1       rjs 
   2858   1.1       rjs 	/* must be valid */
   2859   1.1       rjs 	if (sa1 == NULL || sa2 == NULL)
   2860   1.1       rjs 		return (0);
   2861   1.1       rjs 
   2862   1.1       rjs 	/* must be the same family */
   2863   1.1       rjs 	if (sa1->sa_family != sa2->sa_family)
   2864   1.1       rjs 		return (0);
   2865   1.1       rjs 
   2866   1.1       rjs 	if (sa1->sa_family == AF_INET6) {
   2867   1.1       rjs 		/* IPv6 addresses */
   2868   1.1       rjs 		const struct sockaddr_in6 *sin6_1, *sin6_2;
   2869   1.1       rjs 
   2870   1.1       rjs 		sin6_1 = (const struct sockaddr_in6 *)sa1;
   2871   1.1       rjs 		sin6_2 = (const struct sockaddr_in6 *)sa2;
   2872   1.1       rjs 		return (SCTP6_ARE_ADDR_EQUAL(&sin6_1->sin6_addr,
   2873   1.1       rjs 		    &sin6_2->sin6_addr));
   2874   1.1       rjs 	} else if (sa1->sa_family == AF_INET) {
   2875   1.1       rjs 		/* IPv4 addresses */
   2876   1.1       rjs 		const struct sockaddr_in *sin_1, *sin_2;
   2877   1.1       rjs 
   2878   1.1       rjs 		sin_1 = (const struct sockaddr_in *)sa1;
   2879   1.1       rjs 		sin_2 = (const struct sockaddr_in *)sa2;
   2880   1.1       rjs 		return (sin_1->sin_addr.s_addr == sin_2->sin_addr.s_addr);
   2881   1.1       rjs 	} else {
   2882   1.1       rjs 		/* we don't do these... */
   2883   1.1       rjs 		return (0);
   2884   1.1       rjs 	}
   2885   1.1       rjs }
   2886   1.1       rjs 
   2887   1.1       rjs void
   2888   1.1       rjs sctp_print_address(const struct sockaddr *sa)
   2889   1.1       rjs {
   2890  1.11       ryo 	char ip6buf[INET6_ADDRSTRLEN];
   2891   1.1       rjs 
   2892   1.1       rjs 	if (sa->sa_family == AF_INET6) {
   2893   1.1       rjs 		const struct sockaddr_in6 *sin6;
   2894   1.1       rjs 		sin6 = (const struct sockaddr_in6 *)sa;
   2895   1.1       rjs 		printf("IPv6 address: %s:%d scope:%u\n",
   2896  1.12  christos 		    IN6_PRINT(ip6buf, &sin6->sin6_addr), ntohs(sin6->sin6_port),
   2897   1.1       rjs 		    sin6->sin6_scope_id);
   2898   1.1       rjs 	} else if (sa->sa_family == AF_INET) {
   2899   1.1       rjs 		const struct sockaddr_in *sin;
   2900   1.1       rjs 		sin = (const struct sockaddr_in *)sa;
   2901   1.1       rjs 		printf("IPv4 address: %s:%d\n", inet_ntoa(sin->sin_addr),
   2902   1.1       rjs 		    ntohs(sin->sin_port));
   2903   1.1       rjs 	} else {
   2904   1.1       rjs 		printf("?\n");
   2905   1.1       rjs 	}
   2906   1.1       rjs }
   2907   1.1       rjs 
   2908   1.1       rjs void
   2909   1.1       rjs sctp_print_address_pkt(struct ip *iph, struct sctphdr *sh)
   2910   1.1       rjs {
   2911   1.1       rjs 	if (iph->ip_v == IPVERSION) {
   2912   1.1       rjs 		struct sockaddr_in lsa, fsa;
   2913   1.1       rjs 
   2914   1.1       rjs 		memset(&lsa, 0, sizeof(lsa));
   2915   1.1       rjs 		lsa.sin_len = sizeof(lsa);
   2916   1.1       rjs 		lsa.sin_family = AF_INET;
   2917   1.1       rjs 		lsa.sin_addr = iph->ip_src;
   2918   1.1       rjs 		lsa.sin_port = sh->src_port;
   2919   1.1       rjs 		memset(&fsa, 0, sizeof(fsa));
   2920   1.1       rjs 		fsa.sin_len = sizeof(fsa);
   2921   1.1       rjs 		fsa.sin_family = AF_INET;
   2922   1.1       rjs 		fsa.sin_addr = iph->ip_dst;
   2923   1.1       rjs 		fsa.sin_port = sh->dest_port;
   2924   1.1       rjs 		printf("src: ");
   2925   1.1       rjs 		sctp_print_address((struct sockaddr *)&lsa);
   2926   1.1       rjs 		printf("dest: ");
   2927   1.1       rjs 		sctp_print_address((struct sockaddr *)&fsa);
   2928   1.1       rjs 	} else if (iph->ip_v == (IPV6_VERSION >> 4)) {
   2929   1.1       rjs 		struct ip6_hdr *ip6;
   2930   1.1       rjs 		struct sockaddr_in6 lsa6, fsa6;
   2931   1.1       rjs 
   2932   1.1       rjs 		ip6 = (struct ip6_hdr *)iph;
   2933   1.1       rjs 		memset(&lsa6, 0, sizeof(lsa6));
   2934   1.1       rjs 		lsa6.sin6_len = sizeof(lsa6);
   2935   1.1       rjs 		lsa6.sin6_family = AF_INET6;
   2936   1.1       rjs 		lsa6.sin6_addr = ip6->ip6_src;
   2937   1.1       rjs 		lsa6.sin6_port = sh->src_port;
   2938   1.1       rjs 		memset(&fsa6, 0, sizeof(fsa6));
   2939   1.1       rjs 		fsa6.sin6_len = sizeof(fsa6);
   2940   1.1       rjs 		fsa6.sin6_family = AF_INET6;
   2941   1.1       rjs 		fsa6.sin6_addr = ip6->ip6_dst;
   2942   1.1       rjs 		fsa6.sin6_port = sh->dest_port;
   2943   1.1       rjs 		printf("src: ");
   2944   1.1       rjs 		sctp_print_address((struct sockaddr *)&lsa6);
   2945   1.1       rjs 		printf("dest: ");
   2946   1.1       rjs 		sctp_print_address((struct sockaddr *)&fsa6);
   2947   1.1       rjs 	}
   2948   1.1       rjs }
   2949   1.1       rjs 
   2950   1.1       rjs #if defined(__FreeBSD__) || defined(__APPLE__)
   2951   1.1       rjs 
   2952   1.1       rjs /* cloned from uipc_socket.c */
   2953   1.1       rjs 
   2954   1.1       rjs #define SCTP_SBLINKRECORD(sb, m0) do {					\
   2955   1.1       rjs 	if ((sb)->sb_lastrecord != NULL)				\
   2956   1.1       rjs 		(sb)->sb_lastrecord->m_nextpkt = (m0);			\
   2957   1.1       rjs 	else								\
   2958   1.1       rjs 		(sb)->sb_mb = (m0);					\
   2959   1.1       rjs 	(sb)->sb_lastrecord = (m0);					\
   2960   1.1       rjs } while (/*CONSTCOND*/0)
   2961   1.1       rjs #endif
   2962   1.1       rjs 
   2963   1.1       rjs 
   2964   1.1       rjs int
   2965   1.1       rjs sbappendaddr_nocheck(struct sockbuf *sb, const struct sockaddr *asa,
   2966   1.1       rjs 	struct mbuf *m0, struct mbuf *control,
   2967   1.1       rjs 	u_int32_t tag, struct sctp_inpcb *inp)
   2968   1.1       rjs {
   2969   1.1       rjs #ifdef __NetBSD__
   2970   1.1       rjs 	struct mbuf *m, *n;
   2971   1.1       rjs 
   2972   1.1       rjs 	if (m0 && (m0->m_flags & M_PKTHDR) == 0)
   2973   1.1       rjs 		panic("sbappendaddr_nocheck");
   2974   1.1       rjs 
   2975   1.1       rjs 	m0->m_pkthdr.csum_data = (int)tag;
   2976   1.1       rjs 
   2977   1.1       rjs 	for (n = control; n; n = n->m_next) {
   2978   1.1       rjs 		if (n->m_next == 0)	/* keep pointer to last control buf */
   2979   1.1       rjs 			break;
   2980   1.1       rjs 	}
   2981   1.1       rjs 	if (((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) == 0) ||
   2982   1.1       rjs 	    ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)== 0)) {
   2983   1.1       rjs 		MGETHDR(m, M_DONTWAIT, MT_SONAME);
   2984   1.1       rjs 		if (m == 0)
   2985   1.1       rjs 			return (0);
   2986   1.1       rjs 
   2987   1.1       rjs 		m->m_len = asa->sa_len;
   2988   1.1       rjs 		memcpy(mtod(m, void *), (const void *)asa, asa->sa_len);
   2989   1.1       rjs 	} else {
   2990   1.1       rjs 		m = NULL;
   2991   1.1       rjs 	}
   2992   1.1       rjs 	if (n) {
   2993   1.1       rjs 		n->m_next = m0;		/* concatenate data to control */
   2994   1.1       rjs 	}else {
   2995   1.1       rjs 		control = m0;
   2996   1.1       rjs 	}
   2997   1.1       rjs 	if (m)
   2998   1.1       rjs 		m->m_next = control;
   2999   1.1       rjs 	else
   3000   1.1       rjs 		m = control;
   3001   1.1       rjs 	m->m_pkthdr.csum_data = tag;
   3002   1.1       rjs 
   3003   1.1       rjs 	for (n = m; n; n = n->m_next)
   3004   1.1       rjs 		sballoc(sb, n);
   3005   1.1       rjs 	if ((n = sb->sb_mb) != NULL) {
   3006   1.1       rjs 		if ((n->m_nextpkt != inp->sb_last_mpkt) && (n->m_nextpkt == NULL)) {
   3007   1.1       rjs 			inp->sb_last_mpkt = NULL;
   3008   1.1       rjs 		}
   3009   1.1       rjs 		if (inp->sb_last_mpkt)
   3010   1.1       rjs 			inp->sb_last_mpkt->m_nextpkt = m;
   3011   1.1       rjs  		else {
   3012   1.1       rjs 			while (n->m_nextpkt) {
   3013   1.1       rjs 				n = n->m_nextpkt;
   3014   1.1       rjs 			}
   3015   1.1       rjs 			n->m_nextpkt = m;
   3016   1.1       rjs 		}
   3017   1.1       rjs 		inp->sb_last_mpkt = m;
   3018   1.1       rjs 	} else {
   3019   1.1       rjs 		inp->sb_last_mpkt = sb->sb_mb = m;
   3020   1.1       rjs 		inp->sctp_vtag_first = tag;
   3021   1.1       rjs 	}
   3022   1.1       rjs 	return (1);
   3023   1.1       rjs #endif
   3024   1.1       rjs #if defined(__FreeBSD__) || defined(__APPLE__)
   3025   1.1       rjs 	struct mbuf *m, *n, *nlast;
   3026   1.1       rjs 	int cnt=0;
   3027   1.1       rjs 
   3028   1.1       rjs 	if (m0 && (m0->m_flags & M_PKTHDR) == 0)
   3029   1.1       rjs 		panic("sbappendaddr_nocheck");
   3030   1.1       rjs 
   3031   1.1       rjs 	for (n = control; n; n = n->m_next) {
   3032   1.1       rjs 		if (n->m_next == 0)	/* get pointer to last control buf */
   3033   1.1       rjs 			break;
   3034   1.1       rjs 	}
   3035   1.1       rjs 	if (((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) == 0) ||
   3036   1.1       rjs 	    ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)== 0)) {
   3037   1.1       rjs 		if (asa->sa_len > MHLEN)
   3038   1.1       rjs 			return (0);
   3039   1.1       rjs  try_again:
   3040   1.1       rjs 		MGETHDR(m, M_DONTWAIT, MT_SONAME);
   3041   1.1       rjs 		if (m == 0)
   3042   1.1       rjs 			return (0);
   3043   1.1       rjs 		m->m_len = 0;
   3044   1.1       rjs 		/* safety */
   3045   1.1       rjs 		if (m == m0) {
   3046   1.1       rjs 			printf("Duplicate mbuf allocated %p in and mget returned %p?\n",
   3047   1.1       rjs 			       m0, m);
   3048   1.1       rjs 			if (cnt) {
   3049   1.1       rjs 				panic("more than once");
   3050   1.1       rjs 			}
   3051   1.1       rjs 			cnt++;
   3052   1.1       rjs 			goto try_again;
   3053   1.1       rjs 		}
   3054   1.1       rjs 		m->m_len = asa->sa_len;
   3055   1.1       rjs 		bcopy((void *)asa, mtod(m, void *), asa->sa_len);
   3056   1.1       rjs 	}
   3057   1.1       rjs 	else {
   3058   1.1       rjs 		m = NULL;
   3059   1.1       rjs 	}
   3060   1.1       rjs 	if (n)
   3061   1.1       rjs 		n->m_next = m0;		/* concatenate data to control */
   3062   1.1       rjs 	else
   3063   1.1       rjs 		control = m0;
   3064   1.1       rjs 	if (m)
   3065   1.1       rjs 		m->m_next = control;
   3066   1.1       rjs 	else
   3067   1.1       rjs 		m = control;
   3068   1.1       rjs 	m->m_pkthdr.csum_data = (int)tag;
   3069   1.1       rjs 
   3070   1.1       rjs 	for (n = m; n; n = n->m_next)
   3071   1.1       rjs 		sballoc(sb, n);
   3072   1.1       rjs 	nlast = n;
   3073   1.1       rjs 	if (sb->sb_mb == NULL) {
   3074   1.1       rjs 		inp->sctp_vtag_first = tag;
   3075   1.1       rjs 	}
   3076   1.1       rjs 
   3077   1.1       rjs #ifdef __FREEBSD__
   3078   1.1       rjs 	if (sb->sb_mb == NULL)
   3079   1.1       rjs 		inp->sctp_vtag_first = tag;
   3080   1.1       rjs 	SCTP_SBLINKRECORD(sb, m);
   3081   1.1       rjs 	sb->sb_mbtail = nlast;
   3082   1.1       rjs #else
   3083   1.1       rjs 	if ((n = sb->sb_mb) != NULL) {
   3084   1.1       rjs 		if ((n->m_nextpkt != inp->sb_last_mpkt) && (n->m_nextpkt == NULL)) {
   3085   1.1       rjs 			inp->sb_last_mpkt = NULL;
   3086   1.1       rjs 		}
   3087   1.1       rjs 		if (inp->sb_last_mpkt)
   3088   1.1       rjs 			inp->sb_last_mpkt->m_nextpkt = m;
   3089   1.1       rjs  		else {
   3090   1.1       rjs 			while (n->m_nextpkt) {
   3091   1.1       rjs 				n = n->m_nextpkt;
   3092   1.1       rjs 			}
   3093   1.1       rjs 			n->m_nextpkt = m;
   3094   1.1       rjs 		}
   3095   1.1       rjs 		inp->sb_last_mpkt = m;
   3096   1.1       rjs 	} else {
   3097   1.1       rjs 		inp->sb_last_mpkt = sb->sb_mb = m;
   3098   1.1       rjs 		inp->sctp_vtag_first = tag;
   3099   1.1       rjs 	}
   3100   1.1       rjs #endif
   3101   1.1       rjs 	return (1);
   3102   1.1       rjs #endif
   3103   1.1       rjs #ifdef __OpenBSD__
   3104   1.1       rjs 	struct mbuf *m, *n;
   3105   1.1       rjs 
   3106   1.1       rjs 	if (m0 && (m0->m_flags & M_PKTHDR) == 0)
   3107   1.1       rjs 		panic("sbappendaddr_nocheck");
   3108   1.1       rjs 	m0->m_pkthdr.csum = (int)tag;
   3109   1.1       rjs 	for (n = control; n; n = n->m_next) {
   3110   1.1       rjs 		if (n->m_next == 0)	/* keep pointer to last control buf */
   3111   1.1       rjs 			break;
   3112   1.1       rjs 	}
   3113   1.1       rjs 	if (((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) == 0) ||
   3114   1.1       rjs 	    ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)== 0)) {
   3115   1.1       rjs 		if (asa->sa_len > MHLEN)
   3116   1.1       rjs 			return (0);
   3117   1.1       rjs 		MGETHDR(m, M_DONTWAIT, MT_SONAME);
   3118   1.1       rjs 		if (m == 0)
   3119   1.1       rjs 			return (0);
   3120   1.1       rjs 		m->m_len = asa->sa_len;
   3121   1.1       rjs 		bcopy((void *)asa, mtod(m, void *), asa->sa_len);
   3122   1.1       rjs 	} else {
   3123   1.1       rjs 		m = NULL;
   3124   1.1       rjs 	}
   3125   1.1       rjs 	if (n)
   3126   1.1       rjs 		n->m_next = m0;		/* concatenate data to control */
   3127   1.1       rjs 	else
   3128   1.1       rjs 		control = m0;
   3129   1.1       rjs 
   3130   1.1       rjs 	m->m_pkthdr.csum = (int)tag;
   3131   1.1       rjs 	m->m_next = control;
   3132   1.1       rjs 	for (n = m; n; n = n->m_next)
   3133   1.1       rjs 		sballoc(sb, n);
   3134   1.1       rjs 	if ((n = sb->sb_mb) != NULL) {
   3135   1.1       rjs 		if ((n->m_nextpkt != inp->sb_last_mpkt) && (n->m_nextpkt == NULL)) {
   3136   1.1       rjs 			inp->sb_last_mpkt = NULL;
   3137   1.1       rjs 		}
   3138   1.1       rjs 		if (inp->sb_last_mpkt)
   3139   1.1       rjs 			inp->sb_last_mpkt->m_nextpkt = m;
   3140   1.1       rjs  		else {
   3141   1.1       rjs 			while (n->m_nextpkt) {
   3142   1.1       rjs 				n = n->m_nextpkt;
   3143   1.1       rjs 			}
   3144   1.1       rjs 			n->m_nextpkt = m;
   3145   1.1       rjs 		}
   3146   1.1       rjs 		inp->sb_last_mpkt = m;
   3147   1.1       rjs 	} else {
   3148   1.1       rjs 		inp->sb_last_mpkt = sb->sb_mb = m;
   3149   1.1       rjs 		inp->sctp_vtag_first = tag;
   3150   1.1       rjs 	}
   3151   1.1       rjs 	return (1);
   3152   1.1       rjs #endif
   3153   1.1       rjs }
   3154   1.1       rjs 
   3155   1.1       rjs /*************HOLD THIS COMMENT FOR PATCH FILE OF
   3156   1.1       rjs  *************ALTERNATE ROUTING CODE
   3157   1.1       rjs  */
   3158   1.1       rjs 
   3159   1.1       rjs /*************HOLD THIS COMMENT FOR END OF PATCH FILE OF
   3160   1.1       rjs  *************ALTERNATE ROUTING CODE
   3161   1.1       rjs  */
   3162   1.1       rjs 
   3163   1.1       rjs struct mbuf *
   3164   1.1       rjs sctp_generate_invmanparam(int err)
   3165   1.1       rjs {
   3166   1.1       rjs 	/* Return a MBUF with a invalid mandatory parameter */
   3167   1.1       rjs 	struct mbuf *m;
   3168   1.1       rjs 
   3169   1.1       rjs 	MGET(m, M_DONTWAIT, MT_DATA);
   3170   1.1       rjs 	if (m) {
   3171   1.1       rjs 		struct sctp_paramhdr *ph;
   3172   1.1       rjs 		m->m_len = sizeof(struct sctp_paramhdr);
   3173   1.1       rjs 		ph = mtod(m, struct sctp_paramhdr *);
   3174   1.1       rjs 		ph->param_length = htons(sizeof(struct sctp_paramhdr));
   3175   1.1       rjs 		ph->param_type = htons(err);
   3176   1.1       rjs 	}
   3177   1.1       rjs 	return (m);
   3178   1.1       rjs }
   3179   1.1       rjs 
   3180   1.1       rjs static int
   3181   1.1       rjs sctp_should_be_moved(struct mbuf *this, struct sctp_association *asoc)
   3182   1.1       rjs {
   3183   1.1       rjs 	struct mbuf *m;
   3184   1.1       rjs 	/*
   3185   1.1       rjs 	 * given a mbuf chain, look through it finding
   3186   1.1       rjs 	 * the M_PKTHDR and return 1 if it belongs to
   3187   1.1       rjs 	 * the association given. We tell this by
   3188   1.1       rjs 	 * a kludge where we stuff the my_vtag of the asoc
   3189   1.1       rjs 	 * into the m->m_pkthdr.csum_data/csum field.
   3190   1.1       rjs 	 */
   3191   1.1       rjs 	m = this;
   3192   1.1       rjs 	while (m) {
   3193   1.1       rjs 		if (m->m_flags & M_PKTHDR) {
   3194   1.1       rjs 			/* check it */
   3195   1.1       rjs #if defined(__OpenBSD__)
   3196   1.1       rjs 			if ((u_int32_t)m->m_pkthdr.csum == asoc->my_vtag)
   3197   1.1       rjs #else
   3198   1.1       rjs 			if ((u_int32_t)m->m_pkthdr.csum_data == asoc->my_vtag)
   3199   1.1       rjs #endif
   3200   1.1       rjs 			{
   3201   1.1       rjs 				/* Yep */
   3202   1.1       rjs 				return (1);
   3203   1.1       rjs 			}
   3204   1.1       rjs 		}
   3205   1.1       rjs 		m = m->m_next;
   3206   1.1       rjs 	}
   3207   1.1       rjs 	return (0);
   3208   1.1       rjs }
   3209   1.1       rjs 
   3210   1.1       rjs u_int32_t
   3211   1.1       rjs sctp_get_first_vtag_from_sb(struct socket *so)
   3212   1.1       rjs {
   3213   1.1       rjs 	struct mbuf *this, *at;
   3214   1.1       rjs 	u_int32_t retval;
   3215   1.1       rjs 
   3216   1.1       rjs 	retval = 0;
   3217   1.1       rjs 	if (so->so_rcv.sb_mb) {
   3218   1.1       rjs 		/* grubbing time */
   3219   1.1       rjs 		this = so->so_rcv.sb_mb;
   3220   1.1       rjs 		while (this) {
   3221   1.1       rjs 			at = this;
   3222   1.1       rjs 			/* get to the m_pkthdr */
   3223   1.1       rjs 			while (at) {
   3224   1.1       rjs 				if (at->m_flags & M_PKTHDR)
   3225   1.1       rjs 					break;
   3226   1.1       rjs 				else {
   3227   1.1       rjs 					at = at->m_next;
   3228   1.1       rjs 				}
   3229   1.1       rjs 			}
   3230   1.1       rjs 			/* now do we have a m_pkthdr */
   3231   1.1       rjs 			if (at && (at->m_flags & M_PKTHDR)) {
   3232   1.1       rjs 				/* check it */
   3233   1.1       rjs #if defined(__OpenBSD__)
   3234   1.1       rjs 				if ((u_int32_t)at->m_pkthdr.csum != 0)
   3235   1.1       rjs #else
   3236   1.1       rjs 				if ((u_int32_t)at->m_pkthdr.csum_data != 0)
   3237   1.1       rjs #endif
   3238   1.1       rjs 				{
   3239   1.1       rjs 					/* its the one */
   3240   1.1       rjs #if defined(__OpenBSD__)
   3241   1.1       rjs 					retval = (u_int32_t)at->m_pkthdr.csum;
   3242   1.1       rjs #else
   3243   1.1       rjs 					retval =
   3244   1.1       rjs 					    (u_int32_t)at->m_pkthdr.csum_data;
   3245   1.1       rjs #endif
   3246   1.1       rjs 					break;
   3247   1.1       rjs 				}
   3248   1.1       rjs 			}
   3249   1.1       rjs 			this = this->m_nextpkt;
   3250   1.1       rjs 		}
   3251   1.1       rjs 
   3252   1.1       rjs 	}
   3253   1.1       rjs 	return (retval);
   3254   1.1       rjs 
   3255   1.1       rjs }
   3256   1.1       rjs void
   3257   1.1       rjs sctp_grub_through_socket_buffer(struct sctp_inpcb *inp, struct socket *old,
   3258   1.1       rjs     struct socket *new, struct sctp_tcb *stcb)
   3259   1.1       rjs {
   3260   1.1       rjs 	struct mbuf **put, **take, *next, *this;
   3261   1.1       rjs 	struct sockbuf *old_sb, *new_sb;
   3262   1.1       rjs 	struct sctp_association *asoc;
   3263   1.1       rjs 	int moved_top = 0;
   3264   1.1       rjs 
   3265   1.1       rjs 	asoc = &stcb->asoc;
   3266   1.1       rjs 	old_sb = &old->so_rcv;
   3267   1.1       rjs 	new_sb = &new->so_rcv;
   3268   1.1       rjs 	if (old_sb->sb_mb == NULL) {
   3269   1.1       rjs 		/* Nothing to move */
   3270   1.1       rjs 		return;
   3271   1.1       rjs 	}
   3272   1.1       rjs 
   3273   1.1       rjs 	if (inp->sctp_vtag_first == asoc->my_vtag) {
   3274   1.1       rjs 		/* First one must be moved */
   3275   1.1       rjs 		struct mbuf *mm;
   3276   1.1       rjs 		for (mm = old_sb->sb_mb; mm; mm = mm->m_next) {
   3277   1.1       rjs 			/*
   3278   1.1       rjs 			 * Go down the chain and fix
   3279   1.1       rjs 			 * the space allocation of the
   3280   1.1       rjs 			 * two sockets.
   3281   1.1       rjs 			 */
   3282   1.1       rjs 			sbfree(old_sb, mm);
   3283   1.1       rjs 			sballoc(new_sb, mm);
   3284   1.1       rjs 		}
   3285   1.1       rjs 		new_sb->sb_mb = old_sb->sb_mb;
   3286   1.1       rjs 		old_sb->sb_mb = new_sb->sb_mb->m_nextpkt;
   3287   1.1       rjs 		new_sb->sb_mb->m_nextpkt = NULL;
   3288   1.1       rjs 		put = &new_sb->sb_mb->m_nextpkt;
   3289   1.1       rjs 		moved_top = 1;
   3290   1.1       rjs 	} else {
   3291   1.1       rjs 		put = &new_sb->sb_mb;
   3292   1.1       rjs 	}
   3293   1.1       rjs 
   3294   1.1       rjs 	take = &old_sb->sb_mb;
   3295   1.1       rjs 	next = old_sb->sb_mb;
   3296   1.1       rjs 	while (next) {
   3297   1.1       rjs 		this = next;
   3298  1.19    andvar 		/* position for next one */
   3299   1.1       rjs 		next = this->m_nextpkt;
   3300   1.1       rjs 		/* check the tag of this packet */
   3301   1.1       rjs 		if (sctp_should_be_moved(this, asoc)) {
   3302   1.1       rjs 			/* yes this needs to be moved */
   3303   1.1       rjs 			struct mbuf *mm;
   3304   1.1       rjs 			*take = this->m_nextpkt;
   3305   1.1       rjs 			this->m_nextpkt = NULL;
   3306   1.1       rjs 			*put = this;
   3307   1.1       rjs 			for (mm = this; mm; mm = mm->m_next) {
   3308   1.1       rjs 				/*
   3309   1.1       rjs 				 * Go down the chain and fix
   3310   1.1       rjs 				 * the space allocation of the
   3311   1.1       rjs 				 * two sockets.
   3312   1.1       rjs 				 */
   3313   1.1       rjs 				sbfree(old_sb, mm);
   3314   1.1       rjs 				sballoc(new_sb, mm);
   3315   1.1       rjs 			}
   3316   1.1       rjs 			put = &this->m_nextpkt;
   3317   1.1       rjs 
   3318   1.1       rjs 		} else {
   3319   1.1       rjs 			/* no advance our take point. */
   3320   1.1       rjs 			take = &this->m_nextpkt;
   3321   1.1       rjs 		}
   3322   1.1       rjs 	}
   3323   1.1       rjs 	if (moved_top) {
   3324   1.1       rjs 		/*
   3325  1.19    andvar 		 * Ok so now we must re-position vtag_first to
   3326   1.1       rjs 		 * match the new first one since we moved the
   3327   1.1       rjs 		 * mbuf at the top.
   3328   1.1       rjs 		 */
   3329   1.1       rjs 		inp->sctp_vtag_first = sctp_get_first_vtag_from_sb(old);
   3330   1.1       rjs 	}
   3331   1.1       rjs }
   3332   1.1       rjs 
   3333   1.1       rjs void
   3334   1.1       rjs sctp_free_bufspace(struct sctp_tcb *stcb, struct sctp_association *asoc,
   3335   1.1       rjs     struct sctp_tmit_chunk *tp1)
   3336   1.1       rjs {
   3337   1.1       rjs 	if (tp1->data == NULL) {
   3338   1.1       rjs 		return;
   3339   1.1       rjs 	}
   3340   1.1       rjs #ifdef SCTP_MBCNT_LOGGING
   3341   1.1       rjs 	sctp_log_mbcnt(SCTP_LOG_MBCNT_DECREASE,
   3342   1.1       rjs 		       asoc->total_output_queue_size,
   3343   1.1       rjs 		       tp1->book_size,
   3344   1.1       rjs 		       asoc->total_output_mbuf_queue_size,
   3345   1.1       rjs 		       tp1->mbcnt);
   3346   1.1       rjs #endif
   3347   1.1       rjs 	if (asoc->total_output_queue_size >= tp1->book_size) {
   3348   1.1       rjs 		asoc->total_output_queue_size -= tp1->book_size;
   3349   1.1       rjs 	} else {
   3350   1.1       rjs 		asoc->total_output_queue_size = 0;
   3351   1.1       rjs 	}
   3352   1.1       rjs 
   3353   1.1       rjs 	/* Now free the mbuf */
   3354   1.1       rjs 	if (asoc->total_output_mbuf_queue_size >= tp1->mbcnt) {
   3355   1.1       rjs 		asoc->total_output_mbuf_queue_size -= tp1->mbcnt;
   3356   1.1       rjs 	} else {
   3357   1.1       rjs 		asoc->total_output_mbuf_queue_size = 0;
   3358   1.1       rjs 	}
   3359   1.1       rjs 	if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   3360   1.1       rjs 	    (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
   3361   1.1       rjs 		if (stcb->sctp_socket->so_snd.sb_cc >= tp1->book_size) {
   3362   1.1       rjs 			stcb->sctp_socket->so_snd.sb_cc -= tp1->book_size;
   3363   1.1       rjs 		} else {
   3364   1.1       rjs 			stcb->sctp_socket->so_snd.sb_cc = 0;
   3365   1.1       rjs 
   3366   1.1       rjs 		}
   3367   1.1       rjs 		if (stcb->sctp_socket->so_snd.sb_mbcnt >= tp1->mbcnt) {
   3368   1.1       rjs 			stcb->sctp_socket->so_snd.sb_mbcnt -= tp1->mbcnt;
   3369   1.1       rjs 		} else {
   3370   1.1       rjs 			stcb->sctp_socket->so_snd.sb_mbcnt = 0;
   3371   1.1       rjs 		}
   3372   1.1       rjs 	}
   3373   1.1       rjs }
   3374   1.1       rjs 
   3375   1.1       rjs int
   3376   1.1       rjs sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1,
   3377   1.1       rjs     int reason, struct sctpchunk_listhead *queue)
   3378   1.1       rjs {
   3379   1.1       rjs 	int ret_sz = 0;
   3380   1.1       rjs 	int notdone;
   3381   1.1       rjs 	uint8_t foundeom = 0;
   3382   1.1       rjs 
   3383   1.1       rjs 	do {
   3384   1.1       rjs 		ret_sz += tp1->book_size;
   3385   1.1       rjs 		tp1->sent = SCTP_FORWARD_TSN_SKIP;
   3386   1.1       rjs 		if (tp1->data) {
   3387   1.1       rjs 			sctp_free_bufspace(stcb, &stcb->asoc, tp1);
   3388   1.1       rjs 			sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb, reason, tp1);
   3389   1.1       rjs 			sctp_m_freem(tp1->data);
   3390   1.1       rjs 			tp1->data = NULL;
   3391   1.1       rjs 			sctp_sowwakeup(stcb->sctp_ep, stcb->sctp_socket);
   3392   1.1       rjs 		}
   3393   1.1       rjs 		if (tp1->flags & SCTP_PR_SCTP_BUFFER) {
   3394   1.1       rjs 			stcb->asoc.sent_queue_cnt_removeable--;
   3395   1.1       rjs 		}
   3396   1.1       rjs 		if (queue == &stcb->asoc.send_queue) {
   3397   1.1       rjs 			TAILQ_REMOVE(&stcb->asoc.send_queue, tp1, sctp_next);
   3398   1.1       rjs 			/* on to the sent queue */
   3399   1.1       rjs 			TAILQ_INSERT_TAIL(&stcb->asoc.sent_queue, tp1,
   3400   1.1       rjs 			    sctp_next);
   3401   1.1       rjs 			stcb->asoc.sent_queue_cnt++;
   3402   1.1       rjs 		}
   3403   1.1       rjs 		if ((tp1->rec.data.rcv_flags & SCTP_DATA_NOT_FRAG) ==
   3404   1.1       rjs 		    SCTP_DATA_NOT_FRAG) {
   3405   1.1       rjs 			/* not frag'ed we ae done   */
   3406   1.1       rjs 			notdone = 0;
   3407   1.1       rjs 			foundeom = 1;
   3408   1.1       rjs 		} else if (tp1->rec.data.rcv_flags & SCTP_DATA_LAST_FRAG) {
   3409   1.1       rjs 			/* end of frag, we are done */
   3410   1.1       rjs 			notdone = 0;
   3411   1.1       rjs 			foundeom = 1;
   3412   1.1       rjs 		} else {
   3413   1.1       rjs 			/* Its a begin or middle piece, we must mark all of it */
   3414   1.1       rjs 			notdone = 1;
   3415   1.1       rjs 			tp1 = TAILQ_NEXT(tp1, sctp_next);
   3416   1.1       rjs 		}
   3417   1.1       rjs 	} while (tp1 && notdone);
   3418   1.1       rjs 	if ((foundeom == 0) && (queue == &stcb->asoc.sent_queue)) {
   3419   1.1       rjs 		/*
   3420   1.1       rjs 		 * The multi-part message was scattered
   3421   1.1       rjs 		 * across the send and sent queue.
   3422   1.1       rjs 		 */
   3423   1.1       rjs 		tp1 = TAILQ_FIRST(&stcb->asoc.send_queue);
   3424   1.1       rjs 		/*
   3425   1.1       rjs 		 * recurse throught the send_queue too, starting at the
   3426   1.1       rjs 		 * beginning.
   3427   1.1       rjs 		 */
   3428   1.1       rjs 		if (tp1) {
   3429   1.1       rjs 			ret_sz += sctp_release_pr_sctp_chunk(stcb, tp1, reason,
   3430   1.1       rjs 			    &stcb->asoc.send_queue);
   3431   1.1       rjs 		} else {
   3432   1.1       rjs 			printf("hmm, nothing on the send queue and no EOM?\n");
   3433   1.1       rjs 		}
   3434   1.1       rjs 	}
   3435   1.1       rjs 	return (ret_sz);
   3436   1.1       rjs }
   3437   1.1       rjs 
   3438   1.1       rjs /*
   3439   1.1       rjs  * checks to see if the given address, sa, is one that is currently
   3440   1.1       rjs  * known by the kernel
   3441   1.1       rjs  * note: can't distinguish the same address on multiple interfaces and
   3442   1.1       rjs  *       doesn't handle multiple addresses with different zone/scope id's
   3443   1.1       rjs  * note: ifa_ifwithaddr() compares the entire sockaddr struct
   3444   1.1       rjs  */
   3445   1.1       rjs struct ifaddr *
   3446   1.1       rjs sctp_find_ifa_by_addr(struct sockaddr *sa)
   3447   1.1       rjs {
   3448   1.1       rjs 	struct ifnet *ifn;
   3449   1.1       rjs 	struct ifaddr *ifa;
   3450   1.7     ozaki 	int s;
   3451   1.1       rjs 
   3452   1.1       rjs 	/* go through all our known interfaces */
   3453   1.7     ozaki 	s = pserialize_read_enter();
   3454   1.7     ozaki 	IFNET_READER_FOREACH(ifn) {
   3455   1.1       rjs 		/* go through each interface addresses */
   3456  1.10     ozaki 		IFADDR_READER_FOREACH(ifa, ifn) {
   3457   1.1       rjs 			/* correct family? */
   3458   1.1       rjs 			if (ifa->ifa_addr->sa_family != sa->sa_family)
   3459   1.1       rjs 				continue;
   3460   1.1       rjs 
   3461   1.1       rjs #ifdef INET6
   3462   1.1       rjs 			if (ifa->ifa_addr->sa_family == AF_INET6) {
   3463   1.1       rjs 				/* IPv6 address */
   3464   1.1       rjs 				struct sockaddr_in6 *sin1, *sin2, sin6_tmp;
   3465   1.1       rjs 				sin1 = (struct sockaddr_in6 *)ifa->ifa_addr;
   3466   1.1       rjs 				if (IN6_IS_SCOPE_LINKLOCAL(&sin1->sin6_addr)) {
   3467   1.1       rjs 					/* create a copy and clear scope */
   3468   1.1       rjs 					memcpy(&sin6_tmp, sin1,
   3469   1.1       rjs 					    sizeof(struct sockaddr_in6));
   3470   1.1       rjs 					sin1 = &sin6_tmp;
   3471   1.1       rjs 					in6_clearscope(&sin1->sin6_addr);
   3472   1.1       rjs 				}
   3473   1.1       rjs 				sin2 = (struct sockaddr_in6 *)sa;
   3474   1.1       rjs 				if (memcmp(&sin1->sin6_addr, &sin2->sin6_addr,
   3475   1.1       rjs 					   sizeof(struct in6_addr)) == 0) {
   3476   1.1       rjs 					/* found it */
   3477   1.7     ozaki 					pserialize_read_exit(s);
   3478   1.1       rjs 					return (ifa);
   3479   1.1       rjs 				}
   3480   1.1       rjs 			} else
   3481   1.1       rjs #endif
   3482   1.1       rjs 			if (ifa->ifa_addr->sa_family == AF_INET) {
   3483   1.1       rjs 				/* IPv4 address */
   3484   1.1       rjs 				struct sockaddr_in *sin1, *sin2;
   3485   1.1       rjs 				sin1 = (struct sockaddr_in *)ifa->ifa_addr;
   3486   1.1       rjs 				sin2 = (struct sockaddr_in *)sa;
   3487   1.1       rjs 				if (sin1->sin_addr.s_addr ==
   3488   1.1       rjs 				    sin2->sin_addr.s_addr) {
   3489   1.1       rjs 					/* found it */
   3490   1.7     ozaki 					pserialize_read_exit(s);
   3491   1.1       rjs 					return (ifa);
   3492   1.1       rjs 				}
   3493   1.1       rjs 			}
   3494   1.1       rjs 			/* else, not AF_INET or AF_INET6, so skip */
   3495   1.1       rjs 		} /* end foreach ifa */
   3496   1.1       rjs 	} /* end foreach ifn */
   3497   1.7     ozaki 	pserialize_read_exit(s);
   3498   1.7     ozaki 
   3499   1.1       rjs 	/* not found! */
   3500   1.1       rjs 	return (NULL);
   3501   1.1       rjs }
   3502   1.1       rjs 
   3503   1.1       rjs 
   3504   1.1       rjs #ifdef __APPLE__
   3505   1.1       rjs /*
   3506   1.1       rjs  * here we hack in a fix for Apple's m_copym for the case where the first mbuf
   3507   1.1       rjs  * in the chain is a M_PKTHDR and the length is zero
   3508   1.1       rjs  */
   3509   1.1       rjs static void
   3510   1.1       rjs sctp_pkthdr_fix(struct mbuf *m)
   3511   1.1       rjs {
   3512   1.1       rjs 	struct mbuf *m_nxt;
   3513   1.1       rjs 
   3514   1.1       rjs 	if ((m->m_flags & M_PKTHDR) == 0) {
   3515   1.1       rjs 		/* not a PKTHDR */
   3516   1.1       rjs 		return;
   3517   1.1       rjs 	}
   3518   1.1       rjs 
   3519   1.1       rjs 	if (m->m_len != 0) {
   3520   1.1       rjs 		/* not a zero length PKTHDR mbuf */
   3521   1.1       rjs 		return;
   3522   1.1       rjs 	}
   3523   1.1       rjs 
   3524   1.1       rjs 	/* let's move in a word into the first mbuf... yes, ugly! */
   3525   1.1       rjs 	m_nxt = m->m_next;
   3526   1.1       rjs 	if (m_nxt == NULL) {
   3527   1.1       rjs 		/* umm... not a very useful mbuf chain... */
   3528   1.1       rjs 		return;
   3529   1.1       rjs 	}
   3530   1.1       rjs 	if ((size_t)m_nxt->m_len > sizeof(long)) {
   3531   1.1       rjs 		/* move over a long */
   3532   1.1       rjs 		bcopy(mtod(m_nxt, void *), mtod(m, void *), sizeof(long));
   3533   1.1       rjs 		/* update mbuf data pointers and lengths */
   3534   1.1       rjs 		m->m_len += sizeof(long);
   3535   1.1       rjs 		m_nxt->m_data += sizeof(long);
   3536   1.1       rjs 		m_nxt->m_len -= sizeof(long);
   3537   1.1       rjs 	}
   3538   1.1       rjs }
   3539   1.1       rjs 
   3540   1.1       rjs inline struct mbuf *
   3541   1.1       rjs sctp_m_copym(struct mbuf *m, int off, int len, int wait)
   3542   1.1       rjs {
   3543   1.1       rjs 	sctp_pkthdr_fix(m);
   3544   1.1       rjs 	return (m_copym(m, off, len, wait));
   3545   1.1       rjs }
   3546   1.1       rjs #endif /* __APPLE__ */
   3547