Home | History | Annotate | Line # | Download | only in netinet
sctp_timer.c revision 1.1.2.4
      1  1.1.2.2  skrll /*	$KAME: sctp_timer.c,v 1.30 2005/06/16 18:29:25 jinmei Exp $	*/
      2  1.1.2.4  skrll /*	$NetBSD: sctp_timer.c,v 1.1.2.4 2017/02/05 13:40:59 skrll Exp $	*/
      3  1.1.2.2  skrll 
      4  1.1.2.2  skrll /*
      5  1.1.2.2  skrll  * Copyright (C) 2002, 2003, 2004 Cisco Systems Inc,
      6  1.1.2.2  skrll  * All rights reserved.
      7  1.1.2.2  skrll  *
      8  1.1.2.2  skrll  * Redistribution and use in source and binary forms, with or without
      9  1.1.2.2  skrll  * modification, are permitted provided that the following conditions
     10  1.1.2.2  skrll  * are met:
     11  1.1.2.2  skrll  * 1. Redistributions of source code must retain the above copyright
     12  1.1.2.2  skrll  *    notice, this list of conditions and the following disclaimer.
     13  1.1.2.2  skrll  * 2. Redistributions in binary form must reproduce the above copyright
     14  1.1.2.2  skrll  *    notice, this list of conditions and the following disclaimer in the
     15  1.1.2.2  skrll  *    documentation and/or other materials provided with the distribution.
     16  1.1.2.2  skrll  * 3. Neither the name of the project nor the names of its contributors
     17  1.1.2.2  skrll  *    may be used to endorse or promote products derived from this software
     18  1.1.2.2  skrll  *    without specific prior written permission.
     19  1.1.2.2  skrll  *
     20  1.1.2.2  skrll  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
     21  1.1.2.2  skrll  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     22  1.1.2.2  skrll  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     23  1.1.2.2  skrll  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
     24  1.1.2.2  skrll  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     25  1.1.2.2  skrll  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     26  1.1.2.2  skrll  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     27  1.1.2.2  skrll  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     28  1.1.2.2  skrll  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     29  1.1.2.2  skrll  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     30  1.1.2.2  skrll  * SUCH DAMAGE.
     31  1.1.2.2  skrll  */
     32  1.1.2.2  skrll #include <sys/cdefs.h>
     33  1.1.2.4  skrll __KERNEL_RCSID(0, "$NetBSD: sctp_timer.c,v 1.1.2.4 2017/02/05 13:40:59 skrll Exp $");
     34  1.1.2.2  skrll 
     35  1.1.2.2  skrll #ifdef _KERNEL_OPT
     36  1.1.2.2  skrll #include "opt_inet.h"
     37  1.1.2.2  skrll #include "opt_sctp.h"
     38  1.1.2.2  skrll #endif /* _KERNEL_OPT */
     39  1.1.2.2  skrll 
     40  1.1.2.2  skrll #include <sys/param.h>
     41  1.1.2.2  skrll #include <sys/systm.h>
     42  1.1.2.2  skrll #include <sys/malloc.h>
     43  1.1.2.2  skrll #include <sys/mbuf.h>
     44  1.1.2.2  skrll #include <sys/domain.h>
     45  1.1.2.2  skrll #include <sys/protosw.h>
     46  1.1.2.2  skrll #include <sys/socket.h>
     47  1.1.2.2  skrll #include <sys/socketvar.h>
     48  1.1.2.2  skrll #include <sys/proc.h>
     49  1.1.2.2  skrll #include <sys/kernel.h>
     50  1.1.2.2  skrll #include <sys/sysctl.h>
     51  1.1.2.2  skrll #ifdef INET6
     52  1.1.2.2  skrll #include <sys/domain.h>
     53  1.1.2.2  skrll #endif
     54  1.1.2.2  skrll 
     55  1.1.2.2  skrll #include <machine/limits.h>
     56  1.1.2.2  skrll 
     57  1.1.2.2  skrll #include <net/if.h>
     58  1.1.2.2  skrll #include <net/if_types.h>
     59  1.1.2.2  skrll #include <net/route.h>
     60  1.1.2.2  skrll #include <netinet/in.h>
     61  1.1.2.2  skrll #include <netinet/in_systm.h>
     62  1.1.2.2  skrll #define _IP_VHL
     63  1.1.2.2  skrll #include <netinet/ip.h>
     64  1.1.2.2  skrll #include <netinet/in_pcb.h>
     65  1.1.2.2  skrll #include <netinet/in_var.h>
     66  1.1.2.2  skrll #include <netinet/ip_var.h>
     67  1.1.2.2  skrll 
     68  1.1.2.2  skrll #ifdef INET6
     69  1.1.2.2  skrll #include <netinet/ip6.h>
     70  1.1.2.2  skrll #include <netinet6/ip6_var.h>
     71  1.1.2.2  skrll #endif /* INET6 */
     72  1.1.2.2  skrll 
     73  1.1.2.2  skrll #include <netinet/sctp_pcb.h>
     74  1.1.2.2  skrll 
     75  1.1.2.2  skrll #ifdef IPSEC
     76  1.1.2.3  skrll #include <netipsec/ipsec.h>
     77  1.1.2.3  skrll #include <netipsec/key.h>
     78  1.1.2.2  skrll #endif /* IPSEC */
     79  1.1.2.2  skrll #ifdef INET6
     80  1.1.2.2  skrll #include <netinet6/sctp6_var.h>
     81  1.1.2.2  skrll #endif
     82  1.1.2.2  skrll #include <netinet/sctp_var.h>
     83  1.1.2.2  skrll #include <netinet/sctp_timer.h>
     84  1.1.2.2  skrll #include <netinet/sctputil.h>
     85  1.1.2.2  skrll #include <netinet/sctp_output.h>
     86  1.1.2.2  skrll #include <netinet/sctp_hashdriver.h>
     87  1.1.2.2  skrll #include <netinet/sctp_header.h>
     88  1.1.2.2  skrll #include <netinet/sctp_indata.h>
     89  1.1.2.2  skrll #include <netinet/sctp_asconf.h>
     90  1.1.2.2  skrll 
     91  1.1.2.2  skrll #include <netinet/sctp.h>
     92  1.1.2.2  skrll #include <netinet/sctp_uio.h>
     93  1.1.2.2  skrll 
     94  1.1.2.2  skrll #include <net/net_osdep.h>
     95  1.1.2.2  skrll 
     96  1.1.2.2  skrll #ifdef SCTP_DEBUG
     97  1.1.2.2  skrll extern u_int32_t sctp_debug_on;
     98  1.1.2.2  skrll #endif /* SCTP_DEBUG */
     99  1.1.2.2  skrll 
    100  1.1.2.2  skrll void
    101  1.1.2.2  skrll sctp_audit_retranmission_queue(struct sctp_association *asoc)
    102  1.1.2.2  skrll {
    103  1.1.2.2  skrll 	struct sctp_tmit_chunk *chk;
    104  1.1.2.2  skrll 
    105  1.1.2.2  skrll #ifdef SCTP_DEBUG
    106  1.1.2.2  skrll 	if (sctp_debug_on & SCTP_DEBUG_TIMER4) {
    107  1.1.2.2  skrll 		printf("Audit invoked on send queue cnt:%d onqueue:%d\n",
    108  1.1.2.2  skrll 		    asoc->sent_queue_retran_cnt,
    109  1.1.2.2  skrll 		    asoc->sent_queue_cnt);
    110  1.1.2.2  skrll 	}
    111  1.1.2.2  skrll #endif /* SCTP_DEBUG */
    112  1.1.2.2  skrll 	asoc->sent_queue_retran_cnt = 0;
    113  1.1.2.2  skrll 	asoc->sent_queue_cnt = 0;
    114  1.1.2.2  skrll 	TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) {
    115  1.1.2.2  skrll 		if (chk->sent == SCTP_DATAGRAM_RESEND) {
    116  1.1.2.2  skrll 			asoc->sent_queue_retran_cnt++;
    117  1.1.2.2  skrll 		}
    118  1.1.2.2  skrll 		asoc->sent_queue_cnt++;
    119  1.1.2.2  skrll 	}
    120  1.1.2.2  skrll 	TAILQ_FOREACH(chk, &asoc->control_send_queue, sctp_next) {
    121  1.1.2.2  skrll 		if (chk->sent == SCTP_DATAGRAM_RESEND) {
    122  1.1.2.2  skrll 			asoc->sent_queue_retran_cnt++;
    123  1.1.2.2  skrll 		}
    124  1.1.2.2  skrll 	}
    125  1.1.2.2  skrll #ifdef SCTP_DEBUG
    126  1.1.2.2  skrll 	if (sctp_debug_on & SCTP_DEBUG_TIMER4) {
    127  1.1.2.2  skrll 		printf("Audit completes retran:%d onqueue:%d\n",
    128  1.1.2.2  skrll 		    asoc->sent_queue_retran_cnt,
    129  1.1.2.2  skrll 		    asoc->sent_queue_cnt);
    130  1.1.2.2  skrll 	}
    131  1.1.2.2  skrll #endif /* SCTP_DEBUG */
    132  1.1.2.2  skrll }
    133  1.1.2.2  skrll 
    134  1.1.2.2  skrll int
    135  1.1.2.2  skrll sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
    136  1.1.2.2  skrll     struct sctp_nets *net, uint16_t threshold)
    137  1.1.2.2  skrll {
    138  1.1.2.2  skrll 	if (net) {
    139  1.1.2.2  skrll 		net->error_count++;
    140  1.1.2.2  skrll #ifdef SCTP_DEBUG
    141  1.1.2.2  skrll 		if (sctp_debug_on & SCTP_DEBUG_TIMER4) {
    142  1.1.2.2  skrll 			printf("Error count for %p now %d thresh:%d\n",
    143  1.1.2.2  skrll 			    net, net->error_count,
    144  1.1.2.2  skrll 			    net->failure_threshold);
    145  1.1.2.2  skrll 		}
    146  1.1.2.2  skrll #endif /* SCTP_DEBUG */
    147  1.1.2.2  skrll 		if (net->error_count >= net->failure_threshold) {
    148  1.1.2.2  skrll 			/* We had a threshold failure */
    149  1.1.2.2  skrll 			if (net->dest_state & SCTP_ADDR_REACHABLE) {
    150  1.1.2.2  skrll 				net->dest_state &= ~SCTP_ADDR_REACHABLE;
    151  1.1.2.2  skrll 				net->dest_state |= SCTP_ADDR_NOT_REACHABLE;
    152  1.1.2.2  skrll 				if (net == stcb->asoc.primary_destination) {
    153  1.1.2.2  skrll 					net->dest_state |= SCTP_ADDR_WAS_PRIMARY;
    154  1.1.2.2  skrll 				}
    155  1.1.2.2  skrll 				sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN,
    156  1.1.2.2  skrll 						stcb,
    157  1.1.2.2  skrll 						SCTP_FAILED_THRESHOLD,
    158  1.1.2.2  skrll 						(void *)net);
    159  1.1.2.2  skrll 			}
    160  1.1.2.2  skrll 		}
    161  1.1.2.2  skrll 		/*********HOLD THIS COMMENT FOR PATCH OF ALTERNATE
    162  1.1.2.2  skrll 		 *********ROUTING CODE
    163  1.1.2.2  skrll 		 */
    164  1.1.2.2  skrll 		/*********HOLD THIS COMMENT FOR END OF PATCH OF ALTERNATE
    165  1.1.2.2  skrll 		 *********ROUTING CODE
    166  1.1.2.2  skrll 		 */
    167  1.1.2.2  skrll 	}
    168  1.1.2.2  skrll 	if (stcb == NULL)
    169  1.1.2.2  skrll 		return (0);
    170  1.1.2.2  skrll 
    171  1.1.2.2  skrll 	if (net) {
    172  1.1.2.2  skrll 		if ((net->dest_state & SCTP_ADDR_UNCONFIRMED) == 0) {
    173  1.1.2.2  skrll 			stcb->asoc.overall_error_count++;
    174  1.1.2.2  skrll 		}
    175  1.1.2.2  skrll 	} else {
    176  1.1.2.2  skrll 		stcb->asoc.overall_error_count++;
    177  1.1.2.2  skrll 	}
    178  1.1.2.2  skrll #ifdef SCTP_DEBUG
    179  1.1.2.2  skrll 	if (sctp_debug_on & SCTP_DEBUG_TIMER4) {
    180  1.1.2.2  skrll 		printf("Overall error count for %p now %d thresh:%u state:%x\n",
    181  1.1.2.2  skrll 		       &stcb->asoc,
    182  1.1.2.2  skrll 		       stcb->asoc.overall_error_count,
    183  1.1.2.2  skrll 		       (u_int)threshold,
    184  1.1.2.2  skrll 		       ((net == NULL) ? (u_int)0 : (u_int)net->dest_state));
    185  1.1.2.2  skrll 	}
    186  1.1.2.2  skrll #endif /* SCTP_DEBUG */
    187  1.1.2.2  skrll 	/* We specifically do not do >= to give the assoc one more
    188  1.1.2.2  skrll 	 * change before we fail it.
    189  1.1.2.2  skrll 	 */
    190  1.1.2.2  skrll 	if (stcb->asoc.overall_error_count > threshold) {
    191  1.1.2.2  skrll 		/* Abort notification sends a ULP notify */
    192  1.1.2.2  skrll 		struct mbuf *oper;
    193  1.1.2.2  skrll 		MGET(oper, M_DONTWAIT, MT_DATA);
    194  1.1.2.2  skrll 		if (oper) {
    195  1.1.2.2  skrll 			struct sctp_paramhdr *ph;
    196  1.1.2.2  skrll 			u_int32_t *ippp;
    197  1.1.2.2  skrll 
    198  1.1.2.2  skrll 			oper->m_len = sizeof(struct sctp_paramhdr) +
    199  1.1.2.2  skrll 			    sizeof(*ippp);
    200  1.1.2.2  skrll 			ph = mtod(oper, struct sctp_paramhdr *);
    201  1.1.2.2  skrll 			ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
    202  1.1.2.2  skrll 			ph->param_length = htons(oper->m_len);
    203  1.1.2.2  skrll 			ippp = (u_int32_t *)(ph + 1);
    204  1.1.2.2  skrll 			*ippp = htonl(0x40000001);
    205  1.1.2.2  skrll 		}
    206  1.1.2.2  skrll 		sctp_abort_an_association(inp, stcb, SCTP_FAILED_THRESHOLD, oper);
    207  1.1.2.2  skrll 		return (1);
    208  1.1.2.2  skrll 	}
    209  1.1.2.2  skrll 	return (0);
    210  1.1.2.2  skrll }
    211  1.1.2.2  skrll 
    212  1.1.2.2  skrll struct sctp_nets *
    213  1.1.2.2  skrll sctp_find_alternate_net(struct sctp_tcb *stcb,
    214  1.1.2.2  skrll 			struct sctp_nets *net)
    215  1.1.2.2  skrll {
    216  1.1.2.2  skrll 	/* Find and return an alternate network if possible */
    217  1.1.2.2  skrll 	struct sctp_nets *alt, *mnet;
    218  1.1.2.2  skrll 	struct rtentry *rt;
    219  1.1.2.2  skrll 	int once;
    220  1.1.2.2  skrll 
    221  1.1.2.2  skrll 	if (stcb->asoc.numnets == 1) {
    222  1.1.2.2  skrll 		/* No others but net */
    223  1.1.2.2  skrll 		return (TAILQ_FIRST(&stcb->asoc.nets));
    224  1.1.2.2  skrll 	}
    225  1.1.2.2  skrll 	mnet = net;
    226  1.1.2.2  skrll 	once = 0;
    227  1.1.2.2  skrll 
    228  1.1.2.2  skrll 	if (mnet == NULL) {
    229  1.1.2.2  skrll 		mnet = TAILQ_FIRST(&stcb->asoc.nets);
    230  1.1.2.2  skrll 	}
    231  1.1.2.2  skrll 	do {
    232  1.1.2.2  skrll 		alt = TAILQ_NEXT(mnet, sctp_next);
    233  1.1.2.2  skrll 		if (alt == NULL) {
    234  1.1.2.2  skrll 			once++;
    235  1.1.2.2  skrll 			if (once > 1) {
    236  1.1.2.2  skrll 				break;
    237  1.1.2.2  skrll 			}
    238  1.1.2.2  skrll 			alt = TAILQ_FIRST(&stcb->asoc.nets);
    239  1.1.2.2  skrll 		}
    240  1.1.2.2  skrll 		rt = rtcache_validate(&alt->ro);
    241  1.1.2.2  skrll 		if (rt == NULL) {
    242  1.1.2.2  skrll 			alt->src_addr_selected = 0;
    243  1.1.2.2  skrll 		}
    244  1.1.2.2  skrll 		if (
    245  1.1.2.2  skrll 			((alt->dest_state & SCTP_ADDR_REACHABLE) == SCTP_ADDR_REACHABLE) &&
    246  1.1.2.2  skrll 			(rt != NULL) &&
    247  1.1.2.2  skrll 			(!(alt->dest_state & SCTP_ADDR_UNCONFIRMED))
    248  1.1.2.2  skrll 			) {
    249  1.1.2.2  skrll 			/* Found a reachable address */
    250  1.1.2.4  skrll 			rtcache_unref(rt, &alt->ro);
    251  1.1.2.2  skrll 			break;
    252  1.1.2.2  skrll 		}
    253  1.1.2.4  skrll 		rtcache_unref(rt, &alt->ro);
    254  1.1.2.2  skrll 		mnet = alt;
    255  1.1.2.2  skrll 	} while (alt != NULL);
    256  1.1.2.2  skrll 
    257  1.1.2.2  skrll 	if (alt == NULL) {
    258  1.1.2.2  skrll 		/* Case where NO insv network exists (dormant state) */
    259  1.1.2.2  skrll 		/* we rotate destinations */
    260  1.1.2.2  skrll 		once = 0;
    261  1.1.2.2  skrll 		mnet = net;
    262  1.1.2.2  skrll 		do {
    263  1.1.2.2  skrll 			alt = TAILQ_NEXT(mnet, sctp_next);
    264  1.1.2.2  skrll 			if (alt == NULL) {
    265  1.1.2.2  skrll 				once++;
    266  1.1.2.2  skrll 				if (once > 1) {
    267  1.1.2.2  skrll 					break;
    268  1.1.2.2  skrll 				}
    269  1.1.2.2  skrll 				alt = TAILQ_FIRST(&stcb->asoc.nets);
    270  1.1.2.2  skrll 			}
    271  1.1.2.2  skrll 			if ((!(alt->dest_state & SCTP_ADDR_UNCONFIRMED)) &&
    272  1.1.2.2  skrll 			    (alt != net)) {
    273  1.1.2.2  skrll 				/* Found an alternate address */
    274  1.1.2.2  skrll 				break;
    275  1.1.2.2  skrll 			}
    276  1.1.2.2  skrll 			mnet = alt;
    277  1.1.2.2  skrll 		} while (alt != NULL);
    278  1.1.2.2  skrll 	}
    279  1.1.2.2  skrll 	if (alt == NULL) {
    280  1.1.2.2  skrll 		return (net);
    281  1.1.2.2  skrll 	}
    282  1.1.2.2  skrll 	return (alt);
    283  1.1.2.2  skrll }
    284  1.1.2.2  skrll 
    285  1.1.2.2  skrll static void
    286  1.1.2.2  skrll sctp_backoff_on_timeout(struct sctp_tcb *stcb,
    287  1.1.2.2  skrll 			struct sctp_nets *net,
    288  1.1.2.2  skrll 			int win_probe,
    289  1.1.2.2  skrll 			int num_marked)
    290  1.1.2.2  skrll {
    291  1.1.2.2  skrll #ifdef SCTP_DEBUG
    292  1.1.2.2  skrll 	int oldRTO;
    293  1.1.2.2  skrll 
    294  1.1.2.2  skrll 	oldRTO = net->RTO;
    295  1.1.2.2  skrll #endif /* SCTP_DEBUG */
    296  1.1.2.2  skrll 	net->RTO <<= 1;
    297  1.1.2.2  skrll #ifdef SCTP_DEBUG
    298  1.1.2.2  skrll 	if (sctp_debug_on & SCTP_DEBUG_TIMER2) {
    299  1.1.2.2  skrll 		printf("Timer doubles from %d ms -to-> %d ms\n",
    300  1.1.2.2  skrll 		       oldRTO, net->RTO);
    301  1.1.2.2  skrll 	}
    302  1.1.2.2  skrll #endif /* SCTP_DEBUG */
    303  1.1.2.2  skrll 
    304  1.1.2.2  skrll 	if (net->RTO > stcb->asoc.maxrto) {
    305  1.1.2.2  skrll 		net->RTO = stcb->asoc.maxrto;
    306  1.1.2.2  skrll #ifdef SCTP_DEBUG
    307  1.1.2.2  skrll 		if (sctp_debug_on & SCTP_DEBUG_TIMER2) {
    308  1.1.2.2  skrll 			printf("Growth capped by maxrto %d\n",
    309  1.1.2.2  skrll 			       net->RTO);
    310  1.1.2.2  skrll 		}
    311  1.1.2.2  skrll #endif /* SCTP_DEBUG */
    312  1.1.2.2  skrll 	}
    313  1.1.2.2  skrll 
    314  1.1.2.2  skrll 
    315  1.1.2.2  skrll 	if ((win_probe == 0) && num_marked) {
    316  1.1.2.2  skrll 		/* We don't apply penalty to window probe scenarios */
    317  1.1.2.2  skrll #ifdef SCTP_CWND_LOGGING
    318  1.1.2.2  skrll 		int old_cwnd=net->cwnd;
    319  1.1.2.2  skrll #endif
    320  1.1.2.2  skrll 		net->ssthresh = net->cwnd >> 1;
    321  1.1.2.2  skrll 		if (net->ssthresh < (net->mtu << 1)) {
    322  1.1.2.2  skrll 			net->ssthresh = (net->mtu << 1);
    323  1.1.2.2  skrll 		}
    324  1.1.2.2  skrll 		net->cwnd = net->mtu;
    325  1.1.2.2  skrll 		/* floor of 1 mtu */
    326  1.1.2.2  skrll 		if (net->cwnd < net->mtu)
    327  1.1.2.2  skrll 			net->cwnd = net->mtu;
    328  1.1.2.2  skrll #ifdef SCTP_CWND_LOGGING
    329  1.1.2.2  skrll 		sctp_log_cwnd(net, net->cwnd-old_cwnd, SCTP_CWND_LOG_FROM_RTX);
    330  1.1.2.2  skrll #endif
    331  1.1.2.2  skrll 
    332  1.1.2.2  skrll 		net->partial_bytes_acked = 0;
    333  1.1.2.2  skrll #ifdef SCTP_DEBUG
    334  1.1.2.2  skrll 		if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
    335  1.1.2.2  skrll 			printf("collapse cwnd to 1MTU ssthresh to %d\n",
    336  1.1.2.2  skrll 			       net->ssthresh);
    337  1.1.2.2  skrll 		}
    338  1.1.2.2  skrll #endif
    339  1.1.2.2  skrll 
    340  1.1.2.2  skrll 	}
    341  1.1.2.2  skrll }
    342  1.1.2.2  skrll 
    343  1.1.2.2  skrll 
    344  1.1.2.2  skrll static int
    345  1.1.2.2  skrll sctp_mark_all_for_resend(struct sctp_tcb *stcb,
    346  1.1.2.2  skrll 			 struct sctp_nets *net,
    347  1.1.2.2  skrll 			 struct sctp_nets *alt,
    348  1.1.2.2  skrll 			 int *num_marked)
    349  1.1.2.2  skrll {
    350  1.1.2.2  skrll 
    351  1.1.2.2  skrll 	/*
    352  1.1.2.2  skrll 	 * Mark all chunks (well not all) that were sent to *net for retransmission.
    353  1.1.2.2  skrll 	 * Move them to alt for there destination as well... We only
    354  1.1.2.2  skrll 	 * mark chunks that have been outstanding long enough to have
    355  1.1.2.2  skrll 	 * received feed-back.
    356  1.1.2.2  skrll 	 */
    357  1.1.2.2  skrll 	struct sctp_tmit_chunk *chk, *tp2;
    358  1.1.2.2  skrll 	struct sctp_nets *lnets;
    359  1.1.2.2  skrll 	struct timeval now, min_wait, tv;
    360  1.1.2.2  skrll 	int cur_rto;
    361  1.1.2.2  skrll 	int win_probes, non_win_probes, orig_rwnd, audit_tf, num_mk, fir;
    362  1.1.2.2  skrll 	unsigned int cnt_mk;
    363  1.1.2.2  skrll 	u_int32_t orig_flight;
    364  1.1.2.2  skrll #ifdef SCTP_FR_LOGGING
    365  1.1.2.2  skrll 	u_int32_t tsnfirst, tsnlast;
    366  1.1.2.2  skrll #endif
    367  1.1.2.2  skrll 
    368  1.1.2.2  skrll 	/* none in flight now */
    369  1.1.2.2  skrll 	audit_tf = 0;
    370  1.1.2.2  skrll 	fir=0;
    371  1.1.2.2  skrll 	/* figure out how long a data chunk must be pending
    372  1.1.2.2  skrll 	 * before we can mark it ..
    373  1.1.2.2  skrll 	 */
    374  1.1.2.2  skrll 	SCTP_GETTIME_TIMEVAL(&now);
    375  1.1.2.2  skrll 	/* get cur rto in micro-seconds */
    376  1.1.2.2  skrll 	cur_rto = (((net->lastsa >> 2) + net->lastsv) >> 1);
    377  1.1.2.2  skrll #ifdef SCTP_FR_LOGGING
    378  1.1.2.2  skrll 	sctp_log_fr(cur_rto, 0, 0, SCTP_FR_T3_MARK_TIME);
    379  1.1.2.2  skrll #endif
    380  1.1.2.2  skrll 	cur_rto *= 1000;
    381  1.1.2.2  skrll #ifdef SCTP_FR_LOGGING
    382  1.1.2.2  skrll 	sctp_log_fr(cur_rto, 0, 0, SCTP_FR_T3_MARK_TIME);
    383  1.1.2.2  skrll #endif
    384  1.1.2.2  skrll 	tv.tv_sec = cur_rto / 1000000;
    385  1.1.2.2  skrll 	tv.tv_usec = cur_rto % 1000000;
    386  1.1.2.2  skrll #ifndef __FreeBSD__
    387  1.1.2.2  skrll 	timersub(&now, &tv, &min_wait);
    388  1.1.2.2  skrll #else
    389  1.1.2.2  skrll 	min_wait = now;
    390  1.1.2.2  skrll 	timevalsub(&min_wait, &tv);
    391  1.1.2.2  skrll #endif
    392  1.1.2.2  skrll 	if (min_wait.tv_sec < 0 || min_wait.tv_usec < 0) {
    393  1.1.2.2  skrll 		/*
    394  1.1.2.2  skrll 		 * if we hit here, we don't
    395  1.1.2.2  skrll 		 * have enough seconds on the clock to account
    396  1.1.2.2  skrll 		 * for the RTO. We just let the lower seconds
    397  1.1.2.2  skrll 		 * be the bounds and don't worry about it. This
    398  1.1.2.2  skrll 		 * may mean we will mark a lot more than we should.
    399  1.1.2.2  skrll 		 */
    400  1.1.2.2  skrll 		min_wait.tv_sec = min_wait.tv_usec = 0;
    401  1.1.2.2  skrll 	}
    402  1.1.2.2  skrll #ifdef SCTP_FR_LOGGING
    403  1.1.2.2  skrll 	sctp_log_fr(cur_rto, now.tv_sec, now.tv_usec, SCTP_FR_T3_MARK_TIME);
    404  1.1.2.2  skrll 	sctp_log_fr(0, min_wait.tv_sec, min_wait.tv_usec, SCTP_FR_T3_MARK_TIME);
    405  1.1.2.2  skrll #endif
    406  1.1.2.2  skrll 	if (stcb->asoc.total_flight >= net->flight_size) {
    407  1.1.2.2  skrll 		stcb->asoc.total_flight -= net->flight_size;
    408  1.1.2.2  skrll 	} else {
    409  1.1.2.2  skrll 		audit_tf = 1;
    410  1.1.2.2  skrll 		stcb->asoc.total_flight = 0;
    411  1.1.2.2  skrll 	}
    412  1.1.2.2  skrll         /* Our rwnd will be incorrect here since we are not adding
    413  1.1.2.2  skrll 	 * back the cnt * mbuf but we will fix that down below.
    414  1.1.2.2  skrll 	 */
    415  1.1.2.2  skrll 	orig_rwnd = stcb->asoc.peers_rwnd;
    416  1.1.2.2  skrll 	orig_flight = net->flight_size;
    417  1.1.2.2  skrll 	stcb->asoc.peers_rwnd += net->flight_size;
    418  1.1.2.2  skrll 	net->flight_size = 0;
    419  1.1.2.2  skrll 	net->rto_pending = 0;
    420  1.1.2.2  skrll 	net->fast_retran_ip= 0;
    421  1.1.2.2  skrll 	win_probes = non_win_probes = 0;
    422  1.1.2.2  skrll #ifdef SCTP_DEBUG
    423  1.1.2.2  skrll 	if (sctp_debug_on & SCTP_DEBUG_TIMER2) {
    424  1.1.2.2  skrll 		printf("Marking ALL un-acked for retransmission at t3-timeout\n");
    425  1.1.2.2  skrll 	}
    426  1.1.2.2  skrll #endif /* SCTP_DEBUG */
    427  1.1.2.2  skrll 	/* Now on to each chunk */
    428  1.1.2.2  skrll 	num_mk = cnt_mk = 0;
    429  1.1.2.2  skrll #ifdef SCTP_FR_LOGGING
    430  1.1.2.2  skrll 	tsnlast = tsnfirst = 0;
    431  1.1.2.2  skrll #endif
    432  1.1.2.2  skrll 	chk = TAILQ_FIRST(&stcb->asoc.sent_queue);
    433  1.1.2.2  skrll 	for (;chk != NULL; chk = tp2) {
    434  1.1.2.2  skrll 		tp2 = TAILQ_NEXT(chk, sctp_next);
    435  1.1.2.2  skrll 		if ((compare_with_wrap(stcb->asoc.last_acked_seq,
    436  1.1.2.2  skrll 				       chk->rec.data.TSN_seq,
    437  1.1.2.2  skrll 				       MAX_TSN)) ||
    438  1.1.2.2  skrll 		    (stcb->asoc.last_acked_seq == chk->rec.data.TSN_seq)) {
    439  1.1.2.2  skrll 			/* Strange case our list got out of order? */
    440  1.1.2.2  skrll 			printf("Our list is out of order?\n");
    441  1.1.2.2  skrll 			TAILQ_REMOVE(&stcb->asoc.sent_queue, chk, sctp_next);
    442  1.1.2.2  skrll 			if (chk->data) {
    443  1.1.2.2  skrll 				sctp_release_pr_sctp_chunk(stcb, chk, 0xffff,
    444  1.1.2.2  skrll 				    &stcb->asoc.sent_queue);
    445  1.1.2.2  skrll 				if (chk->flags & SCTP_PR_SCTP_BUFFER) {
    446  1.1.2.2  skrll 					stcb->asoc.sent_queue_cnt_removeable--;
    447  1.1.2.2  skrll 				}
    448  1.1.2.2  skrll 			}
    449  1.1.2.2  skrll 			stcb->asoc.sent_queue_cnt--;
    450  1.1.2.2  skrll 			sctp_free_remote_addr(chk->whoTo);
    451  1.1.2.2  skrll 			sctppcbinfo.ipi_count_chunk--;
    452  1.1.2.2  skrll 			if ((int)sctppcbinfo.ipi_count_chunk < 0) {
    453  1.1.2.2  skrll 				panic("Chunk count is going negative");
    454  1.1.2.2  skrll 			}
    455  1.1.2.2  skrll 			SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_chunk, chk);
    456  1.1.2.2  skrll 			sctppcbinfo.ipi_gencnt_chunk++;
    457  1.1.2.2  skrll 			continue;
    458  1.1.2.2  skrll 		}
    459  1.1.2.2  skrll 		if ((chk->whoTo == net) && (chk->sent < SCTP_DATAGRAM_ACKED)) {
    460  1.1.2.2  skrll 			/* found one to mark:
    461  1.1.2.2  skrll 			 * If it is less than DATAGRAM_ACKED it MUST
    462  1.1.2.2  skrll 			 * not be a skipped or marked TSN but instead
    463  1.1.2.2  skrll 			 * one that is either already set for retransmission OR
    464  1.1.2.2  skrll 			 * one that needs retransmission.
    465  1.1.2.2  skrll 			 */
    466  1.1.2.2  skrll 
    467  1.1.2.2  skrll 			/* validate its been outstanding long enough */
    468  1.1.2.2  skrll #ifdef SCTP_FR_LOGGING
    469  1.1.2.2  skrll 			sctp_log_fr(chk->rec.data.TSN_seq,
    470  1.1.2.2  skrll 				    chk->sent_rcv_time.tv_sec,
    471  1.1.2.2  skrll 				    chk->sent_rcv_time.tv_usec,
    472  1.1.2.2  skrll 				    SCTP_FR_T3_MARK_TIME);
    473  1.1.2.2  skrll #endif
    474  1.1.2.2  skrll 			if (chk->sent_rcv_time.tv_sec > min_wait.tv_sec) {
    475  1.1.2.2  skrll 				/* we have reached a chunk that was sent some
    476  1.1.2.2  skrll 				 * seconds past our min.. forget it we will
    477  1.1.2.2  skrll 				 * find no more to send.
    478  1.1.2.2  skrll 				 */
    479  1.1.2.2  skrll #ifdef SCTP_FR_LOGGING
    480  1.1.2.2  skrll 				sctp_log_fr(0,
    481  1.1.2.2  skrll 					    chk->sent_rcv_time.tv_sec,
    482  1.1.2.2  skrll 					    chk->sent_rcv_time.tv_usec,
    483  1.1.2.2  skrll 					    SCTP_FR_T3_STOPPED);
    484  1.1.2.2  skrll #endif
    485  1.1.2.2  skrll 				continue;
    486  1.1.2.2  skrll 			} else if (chk->sent_rcv_time.tv_sec == min_wait.tv_sec) {
    487  1.1.2.2  skrll 				/* we must look at the micro seconds to know.
    488  1.1.2.2  skrll 				 */
    489  1.1.2.2  skrll 				if (chk->sent_rcv_time.tv_usec >= min_wait.tv_usec) {
    490  1.1.2.2  skrll 					/* ok it was sent after our boundary time. */
    491  1.1.2.2  skrll #ifdef SCTP_FR_LOGGING
    492  1.1.2.2  skrll 					sctp_log_fr(0,
    493  1.1.2.2  skrll 						    chk->sent_rcv_time.tv_sec,
    494  1.1.2.2  skrll 						    chk->sent_rcv_time.tv_usec,
    495  1.1.2.2  skrll 						    SCTP_FR_T3_STOPPED);
    496  1.1.2.2  skrll #endif
    497  1.1.2.2  skrll 					continue;
    498  1.1.2.2  skrll 				}
    499  1.1.2.2  skrll 			}
    500  1.1.2.2  skrll 			if (stcb->asoc.total_flight_count > 0) {
    501  1.1.2.2  skrll 				stcb->asoc.total_flight_count--;
    502  1.1.2.2  skrll 			}
    503  1.1.2.2  skrll 			if ((chk->flags & (SCTP_PR_SCTP_ENABLED|SCTP_PR_SCTP_BUFFER)) == SCTP_PR_SCTP_ENABLED) {
    504  1.1.2.2  skrll 				/* Is it expired? */
    505  1.1.2.2  skrll 				if ((now.tv_sec > chk->rec.data.timetodrop.tv_sec) ||
    506  1.1.2.2  skrll 				    ((chk->rec.data.timetodrop.tv_sec == now.tv_sec) &&
    507  1.1.2.2  skrll 				     (now.tv_usec > chk->rec.data.timetodrop.tv_usec))) {
    508  1.1.2.2  skrll 					/* Yes so drop it */
    509  1.1.2.2  skrll 					if (chk->data) {
    510  1.1.2.2  skrll 						sctp_release_pr_sctp_chunk(stcb,
    511  1.1.2.2  skrll 						    chk,
    512  1.1.2.2  skrll 						    (SCTP_RESPONSE_TO_USER_REQ|SCTP_NOTIFY_DATAGRAM_SENT),
    513  1.1.2.2  skrll 						    &stcb->asoc.sent_queue);
    514  1.1.2.2  skrll 					}
    515  1.1.2.2  skrll 				}
    516  1.1.2.2  skrll 				continue;
    517  1.1.2.2  skrll 			}
    518  1.1.2.2  skrll 			if (chk->sent != SCTP_DATAGRAM_RESEND) {
    519  1.1.2.2  skrll  				stcb->asoc.sent_queue_retran_cnt++;
    520  1.1.2.2  skrll  				num_mk++;
    521  1.1.2.2  skrll 				if (fir == 0) {
    522  1.1.2.2  skrll 					fir = 1;
    523  1.1.2.2  skrll #ifdef SCTP_DEBUG
    524  1.1.2.2  skrll 					if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
    525  1.1.2.2  skrll 						printf("First TSN marked was %x\n",
    526  1.1.2.2  skrll 						       chk->rec.data.TSN_seq);
    527  1.1.2.2  skrll 					}
    528  1.1.2.2  skrll #endif
    529  1.1.2.2  skrll #ifdef SCTP_FR_LOGGING
    530  1.1.2.2  skrll 					tsnfirst = chk->rec.data.TSN_seq;
    531  1.1.2.2  skrll #endif
    532  1.1.2.2  skrll 				}
    533  1.1.2.2  skrll #ifdef SCTP_FR_LOGGING
    534  1.1.2.2  skrll 				tsnlast = chk->rec.data.TSN_seq;
    535  1.1.2.2  skrll 				sctp_log_fr(chk->rec.data.TSN_seq, chk->snd_count,
    536  1.1.2.2  skrll 					    0, SCTP_FR_T3_MARKED);
    537  1.1.2.2  skrll 
    538  1.1.2.2  skrll #endif
    539  1.1.2.2  skrll 			}
    540  1.1.2.2  skrll 			chk->sent = SCTP_DATAGRAM_RESEND;
    541  1.1.2.2  skrll 			/* reset the TSN for striking and other FR stuff */
    542  1.1.2.2  skrll 			chk->rec.data.doing_fast_retransmit = 0;
    543  1.1.2.2  skrll #ifdef SCTP_DEBUG
    544  1.1.2.2  skrll 			if (sctp_debug_on & SCTP_DEBUG_TIMER3) {
    545  1.1.2.2  skrll 				printf("mark TSN:%x for retransmission\n", chk->rec.data.TSN_seq);
    546  1.1.2.2  skrll 			}
    547  1.1.2.2  skrll #endif /* SCTP_DEBUG */
    548  1.1.2.2  skrll 			/* Clear any time so NO RTT is being done */
    549  1.1.2.2  skrll 			chk->do_rtt = 0;
    550  1.1.2.2  skrll 			/* Bump up the count */
    551  1.1.2.2  skrll 			if (compare_with_wrap(chk->rec.data.TSN_seq,
    552  1.1.2.2  skrll 					      stcb->asoc.t3timeout_highest_marked,
    553  1.1.2.2  skrll 					      MAX_TSN)) {
    554  1.1.2.2  skrll 				/* TSN_seq > than t3timeout so update */
    555  1.1.2.2  skrll 				stcb->asoc.t3timeout_highest_marked = chk->rec.data.TSN_seq;
    556  1.1.2.2  skrll 			}
    557  1.1.2.2  skrll 			if (alt != net) {
    558  1.1.2.2  skrll 				sctp_free_remote_addr(chk->whoTo);
    559  1.1.2.2  skrll 				chk->whoTo = alt;
    560  1.1.2.2  skrll 				alt->ref_count++;
    561  1.1.2.2  skrll 			}
    562  1.1.2.2  skrll 			if ((chk->rec.data.state_flags & SCTP_WINDOW_PROBE) !=
    563  1.1.2.2  skrll 			    SCTP_WINDOW_PROBE) {
    564  1.1.2.2  skrll 				non_win_probes++;
    565  1.1.2.2  skrll 			} else {
    566  1.1.2.2  skrll 				chk->rec.data.state_flags &= ~SCTP_WINDOW_PROBE;
    567  1.1.2.2  skrll 				win_probes++;
    568  1.1.2.2  skrll 			}
    569  1.1.2.2  skrll 		}
    570  1.1.2.2  skrll 		if (chk->sent == SCTP_DATAGRAM_RESEND) {
    571  1.1.2.2  skrll 			cnt_mk++;
    572  1.1.2.2  skrll 		}
    573  1.1.2.2  skrll 	}
    574  1.1.2.2  skrll 
    575  1.1.2.2  skrll #ifdef SCTP_FR_LOGGING
    576  1.1.2.2  skrll 	sctp_log_fr(tsnfirst, tsnlast, num_mk, SCTP_FR_T3_TIMEOUT);
    577  1.1.2.2  skrll #endif
    578  1.1.2.2  skrll 	/* compensate for the number we marked */
    579  1.1.2.2  skrll 	stcb->asoc.peers_rwnd += (num_mk /* * sizeof(struct mbuf)*/);
    580  1.1.2.2  skrll 
    581  1.1.2.2  skrll #ifdef SCTP_DEBUG
    582  1.1.2.2  skrll 	if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
    583  1.1.2.2  skrll 		if (num_mk) {
    584  1.1.2.2  skrll #ifdef SCTP_FR_LOGGING
    585  1.1.2.2  skrll 			printf("LAST TSN marked was %x\n", tsnlast);
    586  1.1.2.2  skrll #endif
    587  1.1.2.2  skrll 			printf("Num marked for retransmission was %d peer-rwd:%ld\n",
    588  1.1.2.2  skrll 			       num_mk, (u_long)stcb->asoc.peers_rwnd);
    589  1.1.2.2  skrll #ifdef SCTP_FR_LOGGING
    590  1.1.2.2  skrll 			printf("LAST TSN marked was %x\n", tsnlast);
    591  1.1.2.2  skrll #endif
    592  1.1.2.2  skrll 			printf("Num marked for retransmission was %d peer-rwd:%d\n",
    593  1.1.2.2  skrll 			       num_mk,
    594  1.1.2.2  skrll 			       (int)stcb->asoc.peers_rwnd
    595  1.1.2.2  skrll 				);
    596  1.1.2.2  skrll 		}
    597  1.1.2.2  skrll 	}
    598  1.1.2.2  skrll #endif
    599  1.1.2.2  skrll 	*num_marked = num_mk;
    600  1.1.2.2  skrll 	if (stcb->asoc.sent_queue_retran_cnt != cnt_mk) {
    601  1.1.2.2  skrll 		printf("Local Audit says there are %d for retran asoc cnt:%d\n",
    602  1.1.2.2  skrll 		       cnt_mk, stcb->asoc.sent_queue_retran_cnt);
    603  1.1.2.2  skrll #ifndef SCTP_AUDITING_ENABLED
    604  1.1.2.2  skrll 		stcb->asoc.sent_queue_retran_cnt = cnt_mk;
    605  1.1.2.2  skrll #endif
    606  1.1.2.2  skrll 	}
    607  1.1.2.2  skrll #ifdef SCTP_DEBUG
    608  1.1.2.2  skrll 	if (sctp_debug_on & SCTP_DEBUG_TIMER3) {
    609  1.1.2.2  skrll 		printf("**************************\n");
    610  1.1.2.2  skrll 	}
    611  1.1.2.2  skrll #endif /* SCTP_DEBUG */
    612  1.1.2.2  skrll 
    613  1.1.2.2  skrll 	/* Now check for a ECN Echo that may be stranded */
    614  1.1.2.2  skrll 	TAILQ_FOREACH(chk, &stcb->asoc.control_send_queue, sctp_next) {
    615  1.1.2.2  skrll 		if ((chk->whoTo == net) &&
    616  1.1.2.2  skrll 		    (chk->rec.chunk_id == SCTP_ECN_ECHO)) {
    617  1.1.2.2  skrll 			sctp_free_remote_addr(chk->whoTo);
    618  1.1.2.2  skrll 			chk->whoTo = alt;
    619  1.1.2.2  skrll 			if (chk->sent != SCTP_DATAGRAM_RESEND) {
    620  1.1.2.2  skrll 				chk->sent = SCTP_DATAGRAM_RESEND;
    621  1.1.2.2  skrll 				stcb->asoc.sent_queue_retran_cnt++;
    622  1.1.2.2  skrll 			}
    623  1.1.2.2  skrll 			alt->ref_count++;
    624  1.1.2.2  skrll 		}
    625  1.1.2.2  skrll 	}
    626  1.1.2.2  skrll 	if ((orig_rwnd == 0) && (stcb->asoc.total_flight == 0) &&
    627  1.1.2.2  skrll 	    (orig_flight <= net->mtu)) {
    628  1.1.2.2  skrll 		/*
    629  1.1.2.2  skrll 		 * If the LAST packet sent was not acked and our rwnd is 0
    630  1.1.2.2  skrll 		 * then we are in a win-probe state.
    631  1.1.2.2  skrll 		 */
    632  1.1.2.2  skrll 		win_probes = 1;
    633  1.1.2.2  skrll 		non_win_probes = 0;
    634  1.1.2.2  skrll #ifdef SCTP_DEBUG
    635  1.1.2.2  skrll 		if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
    636  1.1.2.2  skrll 			printf("WIN_PROBE set via o_rwnd=0 tf=0 and all:%d fit in mtu:%d\n",
    637  1.1.2.2  skrll 			       orig_flight, net->mtu);
    638  1.1.2.2  skrll 		}
    639  1.1.2.2  skrll #endif
    640  1.1.2.2  skrll 	}
    641  1.1.2.2  skrll 
    642  1.1.2.2  skrll 	if (audit_tf) {
    643  1.1.2.2  skrll #ifdef SCTP_DEBUG
    644  1.1.2.2  skrll 		if (sctp_debug_on & SCTP_DEBUG_TIMER4) {
    645  1.1.2.2  skrll 			printf("Audit total flight due to negative value net:%p\n",
    646  1.1.2.2  skrll 			    net);
    647  1.1.2.2  skrll 		}
    648  1.1.2.2  skrll #endif /* SCTP_DEBUG */
    649  1.1.2.2  skrll 		stcb->asoc.total_flight = 0;
    650  1.1.2.2  skrll 		stcb->asoc.total_flight_count = 0;
    651  1.1.2.2  skrll 		/* Clear all networks flight size */
    652  1.1.2.2  skrll 		TAILQ_FOREACH(lnets, &stcb->asoc.nets, sctp_next) {
    653  1.1.2.2  skrll 			lnets->flight_size = 0;
    654  1.1.2.2  skrll #ifdef SCTP_DEBUG
    655  1.1.2.2  skrll 			if (sctp_debug_on & SCTP_DEBUG_TIMER4) {
    656  1.1.2.2  skrll 				printf("Net:%p c-f cwnd:%d ssthresh:%d\n",
    657  1.1.2.2  skrll 				    lnets, lnets->cwnd, lnets->ssthresh);
    658  1.1.2.2  skrll 			}
    659  1.1.2.2  skrll #endif /* SCTP_DEBUG */
    660  1.1.2.2  skrll 		}
    661  1.1.2.2  skrll 		TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
    662  1.1.2.2  skrll 			if (chk->sent < SCTP_DATAGRAM_RESEND) {
    663  1.1.2.2  skrll 				stcb->asoc.total_flight += chk->book_size;
    664  1.1.2.2  skrll 				chk->whoTo->flight_size += chk->book_size;
    665  1.1.2.2  skrll 				stcb->asoc.total_flight_count++;
    666  1.1.2.2  skrll 			}
    667  1.1.2.2  skrll 		}
    668  1.1.2.2  skrll 	}
    669  1.1.2.2  skrll 	/* Setup the ecn nonce re-sync point. We
    670  1.1.2.2  skrll 	 * do this since retranmissions are NOT
    671  1.1.2.2  skrll 	 * setup for ECN. This means that do to
    672  1.1.2.2  skrll 	 * Karn's rule, we don't know the total
    673  1.1.2.2  skrll 	 * of the peers ecn bits.
    674  1.1.2.2  skrll 	 */
    675  1.1.2.2  skrll 	chk = TAILQ_FIRST(&stcb->asoc.send_queue);
    676  1.1.2.2  skrll 	if (chk == NULL) {
    677  1.1.2.2  skrll 		stcb->asoc.nonce_resync_tsn = stcb->asoc.sending_seq;
    678  1.1.2.2  skrll 	} else {
    679  1.1.2.2  skrll 		stcb->asoc.nonce_resync_tsn = chk->rec.data.TSN_seq;
    680  1.1.2.2  skrll 	}
    681  1.1.2.2  skrll 	stcb->asoc.nonce_wait_for_ecne = 0;
    682  1.1.2.2  skrll 	stcb->asoc.nonce_sum_check = 0;
    683  1.1.2.2  skrll 	/* We return 1 if we only have a window probe outstanding */
    684  1.1.2.2  skrll 	if (win_probes && (non_win_probes == 0)) {
    685  1.1.2.2  skrll 		return (1);
    686  1.1.2.2  skrll 	}
    687  1.1.2.2  skrll 	return (0);
    688  1.1.2.2  skrll }
    689  1.1.2.2  skrll 
    690  1.1.2.2  skrll static void
    691  1.1.2.2  skrll sctp_move_all_chunks_to_alt(struct sctp_tcb *stcb,
    692  1.1.2.2  skrll 			    struct sctp_nets *net,
    693  1.1.2.2  skrll 			    struct sctp_nets *alt)
    694  1.1.2.2  skrll {
    695  1.1.2.2  skrll 	struct sctp_association *asoc;
    696  1.1.2.2  skrll 	struct sctp_stream_out *outs;
    697  1.1.2.2  skrll 	struct sctp_tmit_chunk *chk;
    698  1.1.2.2  skrll 
    699  1.1.2.2  skrll 	if (net == alt)
    700  1.1.2.2  skrll 		/* nothing to do */
    701  1.1.2.2  skrll 		return;
    702  1.1.2.2  skrll 
    703  1.1.2.2  skrll 	asoc = &stcb->asoc;
    704  1.1.2.2  skrll 
    705  1.1.2.2  skrll 	/*
    706  1.1.2.2  skrll 	 * now through all the streams checking for chunks sent to our
    707  1.1.2.2  skrll 	 * bad network.
    708  1.1.2.2  skrll 	 */
    709  1.1.2.2  skrll 	TAILQ_FOREACH(outs, &asoc->out_wheel, next_spoke) {
    710  1.1.2.2  skrll 		/* now clean up any chunks here */
    711  1.1.2.2  skrll 		TAILQ_FOREACH(chk, &outs->outqueue, sctp_next) {
    712  1.1.2.2  skrll 			if (chk->whoTo == net) {
    713  1.1.2.2  skrll 				sctp_free_remote_addr(chk->whoTo);
    714  1.1.2.2  skrll 				chk->whoTo = alt;
    715  1.1.2.2  skrll 				alt->ref_count++;
    716  1.1.2.2  skrll 			}
    717  1.1.2.2  skrll 		}
    718  1.1.2.2  skrll 	}
    719  1.1.2.2  skrll 	/* Now check the pending queue */
    720  1.1.2.2  skrll 	TAILQ_FOREACH(chk, &asoc->send_queue, sctp_next) {
    721  1.1.2.2  skrll 		if (chk->whoTo == net) {
    722  1.1.2.2  skrll 			sctp_free_remote_addr(chk->whoTo);
    723  1.1.2.2  skrll 			chk->whoTo = alt;
    724  1.1.2.2  skrll 			alt->ref_count++;
    725  1.1.2.2  skrll 		}
    726  1.1.2.2  skrll 	}
    727  1.1.2.2  skrll 
    728  1.1.2.2  skrll }
    729  1.1.2.2  skrll 
    730  1.1.2.2  skrll int
    731  1.1.2.2  skrll sctp_t3rxt_timer(struct sctp_inpcb *inp,
    732  1.1.2.2  skrll 		 struct sctp_tcb *stcb,
    733  1.1.2.2  skrll 		 struct sctp_nets *net)
    734  1.1.2.2  skrll {
    735  1.1.2.2  skrll 	struct sctp_nets *alt;
    736  1.1.2.2  skrll 	int win_probe, num_mk;
    737  1.1.2.2  skrll 
    738  1.1.2.2  skrll 
    739  1.1.2.2  skrll #ifdef SCTP_FR_LOGGING
    740  1.1.2.2  skrll 	sctp_log_fr(0, 0, 0, SCTP_FR_T3_TIMEOUT);
    741  1.1.2.2  skrll #endif
    742  1.1.2.2  skrll 	/* Find an alternate and mark those for retransmission */
    743  1.1.2.2  skrll 	alt = sctp_find_alternate_net(stcb, net);
    744  1.1.2.2  skrll 	win_probe = sctp_mark_all_for_resend(stcb, net, alt, &num_mk);
    745  1.1.2.2  skrll 
    746  1.1.2.2  skrll 	/* FR Loss recovery just ended with the T3. */
    747  1.1.2.2  skrll 	stcb->asoc.fast_retran_loss_recovery = 0;
    748  1.1.2.2  skrll 
    749  1.1.2.2  skrll 	/* setup the sat loss recovery that prevents
    750  1.1.2.2  skrll 	 * satellite cwnd advance.
    751  1.1.2.2  skrll 	 */
    752  1.1.2.2  skrll  	stcb->asoc.sat_t3_loss_recovery = 1;
    753  1.1.2.2  skrll 	stcb->asoc.sat_t3_recovery_tsn = stcb->asoc.sending_seq;
    754  1.1.2.2  skrll 
    755  1.1.2.2  skrll 	/* Backoff the timer and cwnd */
    756  1.1.2.2  skrll 	sctp_backoff_on_timeout(stcb, net, win_probe, num_mk);
    757  1.1.2.2  skrll 	if (win_probe == 0) {
    758  1.1.2.2  skrll 		/* We don't do normal threshold management on window probes */
    759  1.1.2.2  skrll 		if (sctp_threshold_management(inp, stcb, net,
    760  1.1.2.2  skrll 					      stcb->asoc.max_send_times)) {
    761  1.1.2.2  skrll 			/* Association was destroyed */
    762  1.1.2.2  skrll 			return (1);
    763  1.1.2.2  skrll 		} else {
    764  1.1.2.2  skrll 			if (net != stcb->asoc.primary_destination) {
    765  1.1.2.2  skrll 				/* send a immediate HB if our RTO is stale */
    766  1.1.2.2  skrll 				struct  timeval now;
    767  1.1.2.2  skrll 				unsigned int ms_goneby;
    768  1.1.2.2  skrll 				SCTP_GETTIME_TIMEVAL(&now);
    769  1.1.2.2  skrll 				if (net->last_sent_time.tv_sec) {
    770  1.1.2.2  skrll 					ms_goneby = (now.tv_sec - net->last_sent_time.tv_sec) * 1000;
    771  1.1.2.2  skrll 				} else {
    772  1.1.2.2  skrll 					ms_goneby = 0;
    773  1.1.2.2  skrll 				}
    774  1.1.2.2  skrll 				if ((ms_goneby > net->RTO) || (net->RTO == 0)) {
    775  1.1.2.2  skrll 					/* no recent feed back in an RTO or more, request a RTT update */
    776  1.1.2.2  skrll 					sctp_send_hb(stcb, 1, net);
    777  1.1.2.2  skrll 				}
    778  1.1.2.2  skrll 			}
    779  1.1.2.2  skrll 		}
    780  1.1.2.2  skrll 	} else {
    781  1.1.2.2  skrll 		/*
    782  1.1.2.2  skrll 		 * For a window probe we don't penalize the net's but only
    783  1.1.2.2  skrll 		 * the association. This may fail it if SACKs are not coming
    784  1.1.2.2  skrll 		 * back. If sack's are coming with rwnd locked at 0, we will
    785  1.1.2.2  skrll 		 * continue to hold things waiting for rwnd to raise
    786  1.1.2.2  skrll 		 */
    787  1.1.2.2  skrll 		if (sctp_threshold_management(inp, stcb, NULL,
    788  1.1.2.2  skrll 					      stcb->asoc.max_send_times)) {
    789  1.1.2.2  skrll 			/* Association was destroyed */
    790  1.1.2.2  skrll 			return (1);
    791  1.1.2.2  skrll 		}
    792  1.1.2.2  skrll 	}
    793  1.1.2.2  skrll 	if (net->dest_state & SCTP_ADDR_NOT_REACHABLE) {
    794  1.1.2.2  skrll 		/* Move all pending over too */
    795  1.1.2.2  skrll 		sctp_move_all_chunks_to_alt(stcb, net, alt);
    796  1.1.2.2  skrll 		/* Was it our primary? */
    797  1.1.2.2  skrll 		if ((stcb->asoc.primary_destination == net) && (alt != net)) {
    798  1.1.2.2  skrll 			/*
    799  1.1.2.2  skrll 			 * Yes, note it as such and find an alternate
    800  1.1.2.2  skrll 			 * note: this means HB code must use this to resent
    801  1.1.2.2  skrll 			 * the primary if it goes active AND if someone does
    802  1.1.2.2  skrll 			 * a change-primary then this flag must be cleared
    803  1.1.2.2  skrll 			 * from any net structures.
    804  1.1.2.2  skrll 			 */
    805  1.1.2.2  skrll 			if (sctp_set_primary_addr(stcb,
    806  1.1.2.2  skrll 						 (struct sockaddr *)NULL,
    807  1.1.2.2  skrll 						 alt) == 0) {
    808  1.1.2.2  skrll 				net->dest_state |= SCTP_ADDR_WAS_PRIMARY;
    809  1.1.2.2  skrll 				net->src_addr_selected = 0;
    810  1.1.2.2  skrll 			}
    811  1.1.2.2  skrll 		}
    812  1.1.2.2  skrll 	}
    813  1.1.2.2  skrll 	/*
    814  1.1.2.2  skrll 	 * Special case for cookie-echo'ed case, we don't do output
    815  1.1.2.2  skrll 	 * but must await the COOKIE-ACK before retransmission
    816  1.1.2.2  skrll 	 */
    817  1.1.2.2  skrll 	if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED) {
    818  1.1.2.2  skrll 		/*
    819  1.1.2.2  skrll 		 * Here we just reset the timer and start again since we
    820  1.1.2.2  skrll 		 * have not established the asoc
    821  1.1.2.2  skrll 		 */
    822  1.1.2.2  skrll #ifdef SCTP_DEBUG
    823  1.1.2.2  skrll 		if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
    824  1.1.2.2  skrll 			printf("Special cookie case return\n");
    825  1.1.2.2  skrll 		}
    826  1.1.2.2  skrll #endif /* SCTP_DEBUG */
    827  1.1.2.2  skrll 		sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb, net);
    828  1.1.2.2  skrll 		return (0);
    829  1.1.2.2  skrll 	}
    830  1.1.2.2  skrll 	if (stcb->asoc.peer_supports_prsctp) {
    831  1.1.2.2  skrll 		struct sctp_tmit_chunk *lchk;
    832  1.1.2.2  skrll 		lchk = sctp_try_advance_peer_ack_point(stcb, &stcb->asoc);
    833  1.1.2.2  skrll 		/* C3. See if we need to send a Fwd-TSN */
    834  1.1.2.2  skrll 		if (compare_with_wrap(stcb->asoc.advanced_peer_ack_point,
    835  1.1.2.2  skrll 				      stcb->asoc.last_acked_seq, MAX_TSN)) {
    836  1.1.2.2  skrll 			/*
    837  1.1.2.2  skrll 			 * ISSUE with ECN, see FWD-TSN processing for notes
    838  1.1.2.2  skrll 			 * on issues that will occur when the ECN NONCE stuff
    839  1.1.2.2  skrll 			 * is put into SCTP for cross checking.
    840  1.1.2.2  skrll 			 */
    841  1.1.2.2  skrll #ifdef SCTP_DEBUG
    842  1.1.2.2  skrll 			if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
    843  1.1.2.2  skrll 				printf("Forward TSN time\n");
    844  1.1.2.2  skrll 			}
    845  1.1.2.2  skrll #endif /* SCTP_DEBUG */
    846  1.1.2.2  skrll 			send_forward_tsn(stcb, &stcb->asoc);
    847  1.1.2.2  skrll 			if (lchk) {
    848  1.1.2.2  skrll 				/* Assure a timer is up */
    849  1.1.2.2  skrll 				sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, lchk->whoTo);
    850  1.1.2.2  skrll 			}
    851  1.1.2.2  skrll 		}
    852  1.1.2.2  skrll 	}
    853  1.1.2.2  skrll 	return (0);
    854  1.1.2.2  skrll }
    855  1.1.2.2  skrll 
    856  1.1.2.2  skrll int
    857  1.1.2.2  skrll sctp_t1init_timer(struct sctp_inpcb *inp,
    858  1.1.2.2  skrll 		  struct sctp_tcb *stcb,
    859  1.1.2.2  skrll 		  struct sctp_nets *net)
    860  1.1.2.2  skrll {
    861  1.1.2.2  skrll 	/* bump the thresholds */
    862  1.1.2.2  skrll 	if (stcb->asoc.delayed_connection) {
    863  1.1.2.2  skrll 		/* special hook for delayed connection. The
    864  1.1.2.2  skrll 		 * library did NOT complete the rest of its
    865  1.1.2.2  skrll 		 * sends.
    866  1.1.2.2  skrll 		 */
    867  1.1.2.2  skrll 		stcb->asoc.delayed_connection = 0;
    868  1.1.2.2  skrll 		sctp_send_initiate(inp, stcb);
    869  1.1.2.2  skrll 		return (0);
    870  1.1.2.2  skrll 	}
    871  1.1.2.2  skrll 	if (sctp_threshold_management(inp, stcb, net,
    872  1.1.2.2  skrll 				      stcb->asoc.max_init_times)) {
    873  1.1.2.2  skrll 		/* Association was destroyed */
    874  1.1.2.2  skrll 		return (1);
    875  1.1.2.2  skrll 	}
    876  1.1.2.2  skrll 	stcb->asoc.dropped_special_cnt = 0;
    877  1.1.2.2  skrll 	sctp_backoff_on_timeout(stcb, stcb->asoc.primary_destination, 1, 0);
    878  1.1.2.2  skrll 	if (stcb->asoc.initial_init_rto_max < net->RTO) {
    879  1.1.2.2  skrll 		net->RTO = stcb->asoc.initial_init_rto_max;
    880  1.1.2.2  skrll 	}
    881  1.1.2.2  skrll 	if (stcb->asoc.numnets > 1) {
    882  1.1.2.2  skrll 		/* If we have more than one addr use it */
    883  1.1.2.2  skrll 		struct sctp_nets *alt;
    884  1.1.2.2  skrll 		alt = sctp_find_alternate_net(stcb, stcb->asoc.primary_destination);
    885  1.1.2.2  skrll 		if ((alt != NULL) && (alt != stcb->asoc.primary_destination)) {
    886  1.1.2.2  skrll 			sctp_move_all_chunks_to_alt(stcb, stcb->asoc.primary_destination, alt);
    887  1.1.2.2  skrll 			stcb->asoc.primary_destination = alt;
    888  1.1.2.2  skrll 		}
    889  1.1.2.2  skrll 	}
    890  1.1.2.2  skrll 	/* Send out a new init */
    891  1.1.2.2  skrll 	sctp_send_initiate(inp, stcb);
    892  1.1.2.2  skrll 	return (0);
    893  1.1.2.2  skrll }
    894  1.1.2.2  skrll 
    895  1.1.2.2  skrll /*
    896  1.1.2.2  skrll  * For cookie and asconf we actually need to find and mark for resend,
    897  1.1.2.2  skrll  * then increment the resend counter (after all the threshold management
    898  1.1.2.2  skrll  * stuff of course).
    899  1.1.2.2  skrll  */
    900  1.1.2.2  skrll int  sctp_cookie_timer(struct sctp_inpcb *inp,
    901  1.1.2.2  skrll 		       struct sctp_tcb *stcb,
    902  1.1.2.2  skrll 		       struct sctp_nets *net)
    903  1.1.2.2  skrll {
    904  1.1.2.2  skrll 	struct sctp_nets *alt;
    905  1.1.2.2  skrll 	struct sctp_tmit_chunk *cookie;
    906  1.1.2.2  skrll 	/* first before all else we must find the cookie */
    907  1.1.2.2  skrll 	TAILQ_FOREACH(cookie, &stcb->asoc.control_send_queue, sctp_next) {
    908  1.1.2.2  skrll 		if (cookie->rec.chunk_id == SCTP_COOKIE_ECHO) {
    909  1.1.2.2  skrll 			break;
    910  1.1.2.2  skrll 		}
    911  1.1.2.2  skrll 	}
    912  1.1.2.2  skrll 	if (cookie == NULL) {
    913  1.1.2.2  skrll 		if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED) {
    914  1.1.2.2  skrll 			/* FOOBAR! */
    915  1.1.2.2  skrll 			struct mbuf *oper;
    916  1.1.2.2  skrll 			MGET(oper, M_DONTWAIT, MT_DATA);
    917  1.1.2.2  skrll 			if (oper) {
    918  1.1.2.2  skrll 				struct sctp_paramhdr *ph;
    919  1.1.2.2  skrll 				u_int32_t *ippp;
    920  1.1.2.2  skrll 
    921  1.1.2.2  skrll 				oper->m_len = sizeof(struct sctp_paramhdr) +
    922  1.1.2.2  skrll 				    sizeof(*ippp);
    923  1.1.2.2  skrll 				ph = mtod(oper, struct sctp_paramhdr *);
    924  1.1.2.2  skrll 				ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
    925  1.1.2.2  skrll 				ph->param_length = htons(oper->m_len);
    926  1.1.2.2  skrll 				ippp = (u_int32_t *)(ph + 1);
    927  1.1.2.2  skrll 				*ippp = htonl(0x40000002);
    928  1.1.2.2  skrll 			}
    929  1.1.2.2  skrll 			sctp_abort_an_association(inp, stcb, SCTP_INTERNAL_ERROR,
    930  1.1.2.2  skrll 			    oper);
    931  1.1.2.2  skrll 		}
    932  1.1.2.2  skrll 		return (1);
    933  1.1.2.2  skrll 	}
    934  1.1.2.2  skrll 	/* Ok we found the cookie, threshold management next */
    935  1.1.2.2  skrll 	if (sctp_threshold_management(inp, stcb, cookie->whoTo,
    936  1.1.2.2  skrll 	    stcb->asoc.max_init_times)) {
    937  1.1.2.2  skrll 		/* Assoc is over */
    938  1.1.2.2  skrll 		return (1);
    939  1.1.2.2  skrll 	}
    940  1.1.2.2  skrll 	/*
    941  1.1.2.2  skrll 	 * cleared theshold management now lets backoff the address &
    942  1.1.2.2  skrll 	 * select an alternate
    943  1.1.2.2  skrll 	 */
    944  1.1.2.2  skrll 	stcb->asoc.dropped_special_cnt = 0;
    945  1.1.2.2  skrll 	sctp_backoff_on_timeout(stcb, cookie->whoTo, 1, 0);
    946  1.1.2.2  skrll 	alt = sctp_find_alternate_net(stcb, cookie->whoTo);
    947  1.1.2.2  skrll 	if (alt != cookie->whoTo) {
    948  1.1.2.2  skrll 		sctp_free_remote_addr(cookie->whoTo);
    949  1.1.2.2  skrll 		cookie->whoTo = alt;
    950  1.1.2.2  skrll 		alt->ref_count++;
    951  1.1.2.2  skrll 	}
    952  1.1.2.2  skrll 	/* Now mark the retran info */
    953  1.1.2.2  skrll 	if (cookie->sent != SCTP_DATAGRAM_RESEND) {
    954  1.1.2.2  skrll 		stcb->asoc.sent_queue_retran_cnt++;
    955  1.1.2.2  skrll 	}
    956  1.1.2.2  skrll 	cookie->sent = SCTP_DATAGRAM_RESEND;
    957  1.1.2.2  skrll 	/*
    958  1.1.2.2  skrll 	 * Now call the output routine to kick out the cookie again, Note we
    959  1.1.2.2  skrll 	 * don't mark any chunks for retran so that FR will need to kick in
    960  1.1.2.2  skrll 	 * to move these (or a send timer).
    961  1.1.2.2  skrll 	 */
    962  1.1.2.2  skrll 	return (0);
    963  1.1.2.2  skrll }
    964  1.1.2.2  skrll 
    965  1.1.2.2  skrll int sctp_strreset_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
    966  1.1.2.2  skrll     struct sctp_nets *net)
    967  1.1.2.2  skrll {
    968  1.1.2.2  skrll 	struct sctp_nets *alt;
    969  1.1.2.2  skrll 	struct sctp_tmit_chunk *strrst, *chk;
    970  1.1.2.2  skrll 	struct sctp_stream_reset_req *strreq;
    971  1.1.2.2  skrll 	/* find the existing STRRESET */
    972  1.1.2.2  skrll 	TAILQ_FOREACH(strrst, &stcb->asoc.control_send_queue,
    973  1.1.2.2  skrll 		      sctp_next) {
    974  1.1.2.2  skrll 		if (strrst->rec.chunk_id == SCTP_STREAM_RESET) {
    975  1.1.2.2  skrll 			/* is it what we want */
    976  1.1.2.2  skrll 			strreq = mtod(strrst->data, struct sctp_stream_reset_req *);
    977  1.1.2.2  skrll 			if (strreq->sr_req.ph.param_type == ntohs(SCTP_STR_RESET_REQUEST)) {
    978  1.1.2.2  skrll 				break;
    979  1.1.2.2  skrll 			}
    980  1.1.2.2  skrll 		}
    981  1.1.2.2  skrll 	}
    982  1.1.2.2  skrll 	if (strrst == NULL) {
    983  1.1.2.2  skrll #ifdef SCTP_DEBUG
    984  1.1.2.2  skrll 		if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
    985  1.1.2.2  skrll 			printf("Strange, strreset timer fires, but I can't find an str-reset?\n");
    986  1.1.2.2  skrll 		}
    987  1.1.2.2  skrll #endif /* SCTP_DEBUG */
    988  1.1.2.2  skrll 		return (0);
    989  1.1.2.2  skrll 	}
    990  1.1.2.2  skrll 	/* do threshold management */
    991  1.1.2.2  skrll 	if (sctp_threshold_management(inp, stcb, strrst->whoTo,
    992  1.1.2.2  skrll 				      stcb->asoc.max_send_times)) {
    993  1.1.2.2  skrll 		/* Assoc is over */
    994  1.1.2.2  skrll 		return (1);
    995  1.1.2.2  skrll 	}
    996  1.1.2.2  skrll 
    997  1.1.2.2  skrll 	/*
    998  1.1.2.2  skrll 	 * cleared theshold management
    999  1.1.2.2  skrll 	 * now lets backoff the address & select an alternate
   1000  1.1.2.2  skrll 	 */
   1001  1.1.2.2  skrll 	sctp_backoff_on_timeout(stcb, strrst->whoTo, 1, 0);
   1002  1.1.2.2  skrll 	alt = sctp_find_alternate_net(stcb, strrst->whoTo);
   1003  1.1.2.2  skrll 	sctp_free_remote_addr(strrst->whoTo);
   1004  1.1.2.2  skrll 	strrst->whoTo = alt;
   1005  1.1.2.2  skrll 	alt->ref_count++;
   1006  1.1.2.2  skrll 
   1007  1.1.2.2  skrll 	/* See if a ECN Echo is also stranded */
   1008  1.1.2.2  skrll 	TAILQ_FOREACH(chk, &stcb->asoc.control_send_queue, sctp_next) {
   1009  1.1.2.2  skrll 		if ((chk->whoTo == net) &&
   1010  1.1.2.2  skrll 		    (chk->rec.chunk_id == SCTP_ECN_ECHO)) {
   1011  1.1.2.2  skrll 			sctp_free_remote_addr(chk->whoTo);
   1012  1.1.2.2  skrll 			if (chk->sent != SCTP_DATAGRAM_RESEND) {
   1013  1.1.2.2  skrll 				chk->sent = SCTP_DATAGRAM_RESEND;
   1014  1.1.2.2  skrll 				stcb->asoc.sent_queue_retran_cnt++;
   1015  1.1.2.2  skrll 			}
   1016  1.1.2.2  skrll 			chk->whoTo = alt;
   1017  1.1.2.2  skrll 			alt->ref_count++;
   1018  1.1.2.2  skrll 		}
   1019  1.1.2.2  skrll 	}
   1020  1.1.2.2  skrll 	if (net->dest_state & SCTP_ADDR_NOT_REACHABLE) {
   1021  1.1.2.2  skrll 		/*
   1022  1.1.2.2  skrll 		 * If the address went un-reachable, we need to move
   1023  1.1.2.2  skrll 		 * to alternates for ALL chk's in queue
   1024  1.1.2.2  skrll 		 */
   1025  1.1.2.2  skrll 		sctp_move_all_chunks_to_alt(stcb, net, alt);
   1026  1.1.2.2  skrll 	}
   1027  1.1.2.2  skrll 	/* mark the retran info */
   1028  1.1.2.2  skrll 	if (strrst->sent != SCTP_DATAGRAM_RESEND)
   1029  1.1.2.2  skrll 		stcb->asoc.sent_queue_retran_cnt++;
   1030  1.1.2.2  skrll 	strrst->sent = SCTP_DATAGRAM_RESEND;
   1031  1.1.2.2  skrll 
   1032  1.1.2.2  skrll 	/* restart the timer */
   1033  1.1.2.2  skrll 	sctp_timer_start(SCTP_TIMER_TYPE_STRRESET, inp, stcb, strrst->whoTo);
   1034  1.1.2.2  skrll 	return (0);
   1035  1.1.2.2  skrll }
   1036  1.1.2.2  skrll 
   1037  1.1.2.2  skrll int sctp_asconf_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
   1038  1.1.2.2  skrll     struct sctp_nets *net)
   1039  1.1.2.2  skrll {
   1040  1.1.2.2  skrll 	struct sctp_nets *alt;
   1041  1.1.2.2  skrll 	struct sctp_tmit_chunk *asconf, *chk;
   1042  1.1.2.2  skrll 
   1043  1.1.2.2  skrll 	/* is this the first send, or a retransmission? */
   1044  1.1.2.2  skrll 	if (stcb->asoc.asconf_sent == 0) {
   1045  1.1.2.2  skrll 		/* compose a new ASCONF chunk and send it */
   1046  1.1.2.2  skrll 		sctp_send_asconf(stcb, net);
   1047  1.1.2.2  skrll 	} else {
   1048  1.1.2.2  skrll 		/* Retransmission of the existing ASCONF needed... */
   1049  1.1.2.2  skrll 
   1050  1.1.2.2  skrll 		/* find the existing ASCONF */
   1051  1.1.2.2  skrll 		TAILQ_FOREACH(asconf, &stcb->asoc.control_send_queue,
   1052  1.1.2.2  skrll 		    sctp_next) {
   1053  1.1.2.2  skrll 			if (asconf->rec.chunk_id == SCTP_ASCONF) {
   1054  1.1.2.2  skrll 				break;
   1055  1.1.2.2  skrll 			}
   1056  1.1.2.2  skrll 		}
   1057  1.1.2.2  skrll 		if (asconf == NULL) {
   1058  1.1.2.2  skrll #ifdef SCTP_DEBUG
   1059  1.1.2.2  skrll 			if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
   1060  1.1.2.2  skrll 				printf("Strange, asconf timer fires, but I can't find an asconf?\n");
   1061  1.1.2.2  skrll 			}
   1062  1.1.2.2  skrll #endif /* SCTP_DEBUG */
   1063  1.1.2.2  skrll 			return (0);
   1064  1.1.2.2  skrll 		}
   1065  1.1.2.2  skrll 		/* do threshold management */
   1066  1.1.2.2  skrll 		if (sctp_threshold_management(inp, stcb, asconf->whoTo,
   1067  1.1.2.2  skrll 		    stcb->asoc.max_send_times)) {
   1068  1.1.2.2  skrll 			/* Assoc is over */
   1069  1.1.2.2  skrll 			return (1);
   1070  1.1.2.2  skrll 		}
   1071  1.1.2.2  skrll 
   1072  1.1.2.2  skrll 		/* PETER? FIX? How will the following code ever run? If
   1073  1.1.2.2  skrll 		 * the max_send_times is hit, threshold managment will
   1074  1.1.2.2  skrll 		 * blow away the association?
   1075  1.1.2.2  skrll 		 */
   1076  1.1.2.2  skrll 		if (asconf->snd_count > stcb->asoc.max_send_times) {
   1077  1.1.2.2  skrll 			/*
   1078  1.1.2.2  skrll 			 * Something is rotten, peer is not responding to
   1079  1.1.2.2  skrll 			 * ASCONFs but maybe is to data etc.  e.g. it is not
   1080  1.1.2.2  skrll 			 * properly handling the chunk type upper bits
   1081  1.1.2.2  skrll 			 * Mark this peer as ASCONF incapable and cleanup
   1082  1.1.2.2  skrll 			 */
   1083  1.1.2.2  skrll #ifdef SCTP_DEBUG
   1084  1.1.2.2  skrll 			if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
   1085  1.1.2.2  skrll 				printf("asconf_timer: Peer has not responded to our repeated ASCONFs\n");
   1086  1.1.2.2  skrll 			}
   1087  1.1.2.2  skrll #endif /* SCTP_DEBUG */
   1088  1.1.2.2  skrll 			sctp_asconf_cleanup(stcb, net);
   1089  1.1.2.2  skrll 			return (0);
   1090  1.1.2.2  skrll 		}
   1091  1.1.2.2  skrll 		/*
   1092  1.1.2.2  skrll 		 * cleared theshold management
   1093  1.1.2.2  skrll 		 * now lets backoff the address & select an alternate
   1094  1.1.2.2  skrll 		 */
   1095  1.1.2.2  skrll 		sctp_backoff_on_timeout(stcb, asconf->whoTo, 1, 0);
   1096  1.1.2.2  skrll 		alt = sctp_find_alternate_net(stcb, asconf->whoTo);
   1097  1.1.2.2  skrll 		sctp_free_remote_addr(asconf->whoTo);
   1098  1.1.2.2  skrll 		asconf->whoTo = alt;
   1099  1.1.2.2  skrll 		alt->ref_count++;
   1100  1.1.2.2  skrll 
   1101  1.1.2.2  skrll 		/* See if a ECN Echo is also stranded */
   1102  1.1.2.2  skrll 		TAILQ_FOREACH(chk, &stcb->asoc.control_send_queue, sctp_next) {
   1103  1.1.2.2  skrll 			if ((chk->whoTo == net) &&
   1104  1.1.2.2  skrll 			    (chk->rec.chunk_id == SCTP_ECN_ECHO)) {
   1105  1.1.2.2  skrll 				sctp_free_remote_addr(chk->whoTo);
   1106  1.1.2.2  skrll 				chk->whoTo = alt;
   1107  1.1.2.2  skrll 				if (chk->sent != SCTP_DATAGRAM_RESEND) {
   1108  1.1.2.2  skrll 					chk->sent = SCTP_DATAGRAM_RESEND;
   1109  1.1.2.2  skrll 					stcb->asoc.sent_queue_retran_cnt++;
   1110  1.1.2.2  skrll 				}
   1111  1.1.2.2  skrll 				alt->ref_count++;
   1112  1.1.2.2  skrll 
   1113  1.1.2.2  skrll 			}
   1114  1.1.2.2  skrll 		}
   1115  1.1.2.2  skrll 		if (net->dest_state & SCTP_ADDR_NOT_REACHABLE) {
   1116  1.1.2.2  skrll 			/*
   1117  1.1.2.2  skrll 			 * If the address went un-reachable, we need to move
   1118  1.1.2.2  skrll 			 * to alternates for ALL chk's in queue
   1119  1.1.2.2  skrll 			 */
   1120  1.1.2.2  skrll 			sctp_move_all_chunks_to_alt(stcb, net, alt);
   1121  1.1.2.2  skrll 		}
   1122  1.1.2.2  skrll 		/* mark the retran info */
   1123  1.1.2.2  skrll 		if (asconf->sent != SCTP_DATAGRAM_RESEND)
   1124  1.1.2.2  skrll 			stcb->asoc.sent_queue_retran_cnt++;
   1125  1.1.2.2  skrll 		asconf->sent = SCTP_DATAGRAM_RESEND;
   1126  1.1.2.2  skrll 	}
   1127  1.1.2.2  skrll 	return (0);
   1128  1.1.2.2  skrll }
   1129  1.1.2.2  skrll 
   1130  1.1.2.2  skrll /*
   1131  1.1.2.2  skrll  * For the shutdown and shutdown-ack, we do not keep one around on the
   1132  1.1.2.2  skrll  * control queue. This means we must generate a new one and call the general
   1133  1.1.2.2  skrll  * chunk output routine, AFTER having done threshold
   1134  1.1.2.2  skrll  * management.
   1135  1.1.2.2  skrll  */
   1136  1.1.2.2  skrll int
   1137  1.1.2.2  skrll sctp_shutdown_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
   1138  1.1.2.2  skrll     struct sctp_nets *net)
   1139  1.1.2.2  skrll {
   1140  1.1.2.2  skrll 	struct sctp_nets *alt;
   1141  1.1.2.2  skrll 	/* first threshold managment */
   1142  1.1.2.2  skrll 	if (sctp_threshold_management(inp, stcb, net, stcb->asoc.max_send_times)) {
   1143  1.1.2.2  skrll 		/* Assoc is over */
   1144  1.1.2.2  skrll 		return (1);
   1145  1.1.2.2  skrll 	}
   1146  1.1.2.2  skrll 	/* second select an alternative */
   1147  1.1.2.2  skrll 	alt = sctp_find_alternate_net(stcb, net);
   1148  1.1.2.2  skrll 
   1149  1.1.2.2  skrll 	/* third generate a shutdown into the queue for out net */
   1150  1.1.2.2  skrll #ifdef SCTP_DEBUG
   1151  1.1.2.2  skrll 	if (sctp_debug_on & SCTP_DEBUG_OUTPUT4) {
   1152  1.1.2.2  skrll 		printf("%s:%d sends a shutdown\n",
   1153  1.1.2.2  skrll 		       __FILE__,
   1154  1.1.2.2  skrll 		       __LINE__
   1155  1.1.2.2  skrll 			);
   1156  1.1.2.2  skrll 	}
   1157  1.1.2.2  skrll #endif
   1158  1.1.2.2  skrll 	if (alt) {
   1159  1.1.2.2  skrll 		sctp_send_shutdown(stcb, alt);
   1160  1.1.2.2  skrll 	} else {
   1161  1.1.2.2  skrll 		/* if alt is NULL, there is no dest
   1162  1.1.2.2  skrll 		 * to send to??
   1163  1.1.2.2  skrll 		 */
   1164  1.1.2.2  skrll 		return (0);
   1165  1.1.2.2  skrll 	}
   1166  1.1.2.2  skrll 	/* fourth restart timer */
   1167  1.1.2.2  skrll 	sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, inp, stcb, alt);
   1168  1.1.2.2  skrll 	return (0);
   1169  1.1.2.2  skrll }
   1170  1.1.2.2  skrll 
   1171  1.1.2.2  skrll int sctp_shutdownack_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
   1172  1.1.2.2  skrll     struct sctp_nets *net)
   1173  1.1.2.2  skrll {
   1174  1.1.2.2  skrll 	struct sctp_nets *alt;
   1175  1.1.2.2  skrll 	/* first threshold managment */
   1176  1.1.2.2  skrll 	if (sctp_threshold_management(inp, stcb, net, stcb->asoc.max_send_times)) {
   1177  1.1.2.2  skrll 		/* Assoc is over */
   1178  1.1.2.2  skrll 		return (1);
   1179  1.1.2.2  skrll 	}
   1180  1.1.2.2  skrll 	/* second select an alternative */
   1181  1.1.2.2  skrll 	alt = sctp_find_alternate_net(stcb, net);
   1182  1.1.2.2  skrll 
   1183  1.1.2.2  skrll 	/* third generate a shutdown into the queue for out net */
   1184  1.1.2.2  skrll 	sctp_send_shutdown_ack(stcb, alt);
   1185  1.1.2.2  skrll 
   1186  1.1.2.2  skrll 	/* fourth restart timer */
   1187  1.1.2.2  skrll 	sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNACK, inp, stcb, alt);
   1188  1.1.2.2  skrll 	return (0);
   1189  1.1.2.2  skrll }
   1190  1.1.2.2  skrll 
   1191  1.1.2.2  skrll static void
   1192  1.1.2.2  skrll sctp_audit_stream_queues_for_size(struct sctp_inpcb *inp,
   1193  1.1.2.2  skrll 				  struct sctp_tcb *stcb)
   1194  1.1.2.2  skrll {
   1195  1.1.2.2  skrll 	struct sctp_stream_out *outs;
   1196  1.1.2.2  skrll 	struct sctp_tmit_chunk *chk;
   1197  1.1.2.2  skrll 	unsigned int chks_in_queue=0;
   1198  1.1.2.2  skrll 
   1199  1.1.2.2  skrll 	if ((stcb == NULL) || (inp == NULL))
   1200  1.1.2.2  skrll 		return;
   1201  1.1.2.2  skrll 	if (TAILQ_EMPTY(&stcb->asoc.out_wheel)) {
   1202  1.1.2.2  skrll 		printf("Strange, out_wheel empty nothing on sent/send and  tot=%lu?\n",
   1203  1.1.2.2  skrll 		    (u_long)stcb->asoc.total_output_queue_size);
   1204  1.1.2.2  skrll 		stcb->asoc.total_output_queue_size = 0;
   1205  1.1.2.2  skrll 		return;
   1206  1.1.2.2  skrll 	}
   1207  1.1.2.2  skrll 	if (stcb->asoc.sent_queue_retran_cnt) {
   1208  1.1.2.2  skrll 		printf("Hmm, sent_queue_retran_cnt is non-zero %d\n",
   1209  1.1.2.2  skrll 		    stcb->asoc.sent_queue_retran_cnt);
   1210  1.1.2.2  skrll 		stcb->asoc.sent_queue_retran_cnt = 0;
   1211  1.1.2.2  skrll 	}
   1212  1.1.2.2  skrll 	/* Check to see if some data queued, if so report it */
   1213  1.1.2.2  skrll 	TAILQ_FOREACH(outs, &stcb->asoc.out_wheel, next_spoke) {
   1214  1.1.2.2  skrll 		if (!TAILQ_EMPTY(&outs->outqueue)) {
   1215  1.1.2.2  skrll 			TAILQ_FOREACH(chk, &outs->outqueue, sctp_next) {
   1216  1.1.2.2  skrll 				chks_in_queue++;
   1217  1.1.2.2  skrll 			}
   1218  1.1.2.2  skrll 		}
   1219  1.1.2.2  skrll 	}
   1220  1.1.2.2  skrll 	if (chks_in_queue != stcb->asoc.stream_queue_cnt) {
   1221  1.1.2.2  skrll 		printf("Hmm, stream queue cnt at %d I counted %d in stream out wheel\n",
   1222  1.1.2.2  skrll 		       stcb->asoc.stream_queue_cnt, chks_in_queue);
   1223  1.1.2.2  skrll 	}
   1224  1.1.2.2  skrll 	if (chks_in_queue) {
   1225  1.1.2.2  skrll 		/* call the output queue function */
   1226  1.1.2.2  skrll 		sctp_chunk_output(inp, stcb, 1);
   1227  1.1.2.2  skrll 		if ((TAILQ_EMPTY(&stcb->asoc.send_queue)) &&
   1228  1.1.2.2  skrll 		    (TAILQ_EMPTY(&stcb->asoc.sent_queue))) {
   1229  1.1.2.2  skrll 			/* Probably should go in and make it go back through and add fragments allowed */
   1230  1.1.2.2  skrll 			printf("Still nothing moved %d chunks are stuck\n", chks_in_queue);
   1231  1.1.2.2  skrll 		}
   1232  1.1.2.2  skrll 	} else {
   1233  1.1.2.2  skrll 		printf("Found no chunks on any queue tot:%lu\n",
   1234  1.1.2.2  skrll 		    (u_long)stcb->asoc.total_output_queue_size);
   1235  1.1.2.2  skrll 		stcb->asoc.total_output_queue_size = 0;
   1236  1.1.2.2  skrll 	}
   1237  1.1.2.2  skrll }
   1238  1.1.2.2  skrll 
   1239  1.1.2.2  skrll int
   1240  1.1.2.2  skrll sctp_heartbeat_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
   1241  1.1.2.2  skrll     struct sctp_nets *net)
   1242  1.1.2.2  skrll {
   1243  1.1.2.2  skrll 	int cnt_of_unconf=0;
   1244  1.1.2.2  skrll 
   1245  1.1.2.2  skrll 	if (net) {
   1246  1.1.2.2  skrll 		if (net->hb_responded == 0) {
   1247  1.1.2.2  skrll 			sctp_backoff_on_timeout(stcb, net, 1, 0);
   1248  1.1.2.2  skrll 		}
   1249  1.1.2.2  skrll 		/* Zero PBA, if it needs it */
   1250  1.1.2.2  skrll 		if (net->partial_bytes_acked) {
   1251  1.1.2.2  skrll 			net->partial_bytes_acked = 0;
   1252  1.1.2.2  skrll 		}
   1253  1.1.2.2  skrll 	}
   1254  1.1.2.2  skrll 	TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
   1255  1.1.2.2  skrll 		if ((net->dest_state & SCTP_ADDR_UNCONFIRMED) &&
   1256  1.1.2.2  skrll 		    (net->dest_state & SCTP_ADDR_REACHABLE)) {
   1257  1.1.2.2  skrll 			cnt_of_unconf++;
   1258  1.1.2.2  skrll 		}
   1259  1.1.2.2  skrll 	}
   1260  1.1.2.2  skrll 	if ((stcb->asoc.total_output_queue_size > 0) &&
   1261  1.1.2.2  skrll 	    (TAILQ_EMPTY(&stcb->asoc.send_queue)) &&
   1262  1.1.2.2  skrll 	    (TAILQ_EMPTY(&stcb->asoc.sent_queue))) {
   1263  1.1.2.2  skrll 		sctp_audit_stream_queues_for_size(inp, stcb);
   1264  1.1.2.2  skrll 	}
   1265  1.1.2.2  skrll 	/* Send a new HB, this will do threshold managment, pick a new dest */
   1266  1.1.2.2  skrll 	if (sctp_send_hb(stcb, 0, NULL) < 0) {
   1267  1.1.2.2  skrll 		return (1);
   1268  1.1.2.2  skrll 	}
   1269  1.1.2.2  skrll 	if (cnt_of_unconf > 1) {
   1270  1.1.2.2  skrll 		/*
   1271  1.1.2.2  skrll 		 * this will send out extra hb's up to maxburst if
   1272  1.1.2.2  skrll 		 * there are any unconfirmed addresses.
   1273  1.1.2.2  skrll 		 */
   1274  1.1.2.2  skrll 		int cnt_sent = 1;
   1275  1.1.2.2  skrll 		while ((cnt_sent < stcb->asoc.max_burst) && (cnt_of_unconf > 1)) {
   1276  1.1.2.2  skrll 			if (sctp_send_hb(stcb, 0, NULL) == 0)
   1277  1.1.2.2  skrll 				break;
   1278  1.1.2.2  skrll 			cnt_of_unconf--;
   1279  1.1.2.2  skrll 			cnt_sent++;
   1280  1.1.2.2  skrll 		}
   1281  1.1.2.2  skrll 	}
   1282  1.1.2.2  skrll 	return (0);
   1283  1.1.2.2  skrll }
   1284  1.1.2.2  skrll 
   1285  1.1.2.2  skrll #define SCTP_NUMBER_OF_MTU_SIZES 18
   1286  1.1.2.2  skrll static u_int32_t mtu_sizes[]={
   1287  1.1.2.2  skrll 	68,
   1288  1.1.2.2  skrll 	296,
   1289  1.1.2.2  skrll 	508,
   1290  1.1.2.2  skrll 	512,
   1291  1.1.2.2  skrll 	544,
   1292  1.1.2.2  skrll 	576,
   1293  1.1.2.2  skrll 	1006,
   1294  1.1.2.2  skrll 	1492,
   1295  1.1.2.2  skrll 	1500,
   1296  1.1.2.2  skrll 	1536,
   1297  1.1.2.2  skrll 	2002,
   1298  1.1.2.2  skrll 	2048,
   1299  1.1.2.2  skrll 	4352,
   1300  1.1.2.2  skrll 	4464,
   1301  1.1.2.2  skrll 	8166,
   1302  1.1.2.2  skrll 	17914,
   1303  1.1.2.2  skrll 	32000,
   1304  1.1.2.2  skrll 	65535
   1305  1.1.2.2  skrll };
   1306  1.1.2.2  skrll 
   1307  1.1.2.2  skrll 
   1308  1.1.2.2  skrll static u_int32_t
   1309  1.1.2.2  skrll sctp_getnext_mtu(struct sctp_inpcb *inp, u_int32_t cur_mtu)
   1310  1.1.2.2  skrll {
   1311  1.1.2.2  skrll 	/* select another MTU that is just bigger than this one */
   1312  1.1.2.2  skrll 	int i;
   1313  1.1.2.2  skrll 
   1314  1.1.2.2  skrll 	for (i = 0; i < SCTP_NUMBER_OF_MTU_SIZES; i++) {
   1315  1.1.2.2  skrll 		if (cur_mtu < mtu_sizes[i]) {
   1316  1.1.2.2  skrll 		    /* no max_mtu is bigger than this one */
   1317  1.1.2.2  skrll 		    return (mtu_sizes[i]);
   1318  1.1.2.2  skrll 		}
   1319  1.1.2.2  skrll 	}
   1320  1.1.2.2  skrll 	/* here return the highest allowable */
   1321  1.1.2.2  skrll 	return (cur_mtu);
   1322  1.1.2.2  skrll }
   1323  1.1.2.2  skrll 
   1324  1.1.2.2  skrll 
   1325  1.1.2.2  skrll void sctp_pathmtu_timer(struct sctp_inpcb *inp,
   1326  1.1.2.2  skrll 			struct sctp_tcb *stcb,
   1327  1.1.2.2  skrll 			struct sctp_nets *net)
   1328  1.1.2.2  skrll {
   1329  1.1.2.2  skrll 	u_int32_t next_mtu;
   1330  1.1.2.2  skrll 	struct rtentry *rt;
   1331  1.1.2.2  skrll 
   1332  1.1.2.2  skrll 	/* restart the timer in any case */
   1333  1.1.2.2  skrll 	next_mtu = sctp_getnext_mtu(inp, net->mtu);
   1334  1.1.2.2  skrll 	if (next_mtu <= net->mtu) {
   1335  1.1.2.2  skrll 	    /* nothing to do */
   1336  1.1.2.2  skrll 	    return;
   1337  1.1.2.2  skrll 	}
   1338  1.1.2.2  skrll 	rt = rtcache_validate(&net->ro);
   1339  1.1.2.2  skrll 	if (rt != NULL) {
   1340  1.1.2.2  skrll 		/* only if we have a route and interface do we
   1341  1.1.2.2  skrll 		 * set anything. Note we always restart
   1342  1.1.2.2  skrll 		 * the timer though just in case it is updated
   1343  1.1.2.2  skrll 		 * (i.e. the ifp) or route/ifp is populated.
   1344  1.1.2.2  skrll 		 */
   1345  1.1.2.2  skrll 		if (rt->rt_ifp != NULL) {
   1346  1.1.2.2  skrll 			if (rt->rt_ifp->if_mtu > next_mtu) {
   1347  1.1.2.2  skrll 				/* ok it will fit out the door */
   1348  1.1.2.2  skrll 				net->mtu = next_mtu;
   1349  1.1.2.2  skrll 			}
   1350  1.1.2.2  skrll 		}
   1351  1.1.2.4  skrll 		rtcache_unref(rt, &net->ro);
   1352  1.1.2.2  skrll 	}
   1353  1.1.2.2  skrll 	/* restart the timer */
   1354  1.1.2.2  skrll 	sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net);
   1355  1.1.2.2  skrll }
   1356  1.1.2.2  skrll 
   1357  1.1.2.2  skrll void sctp_autoclose_timer(struct sctp_inpcb *inp,
   1358  1.1.2.2  skrll 			  struct sctp_tcb *stcb,
   1359  1.1.2.2  skrll 			  struct sctp_nets *net)
   1360  1.1.2.2  skrll {
   1361  1.1.2.2  skrll 	struct timeval tn, *tim_touse;
   1362  1.1.2.2  skrll 	struct sctp_association *asoc;
   1363  1.1.2.2  skrll 	int ticks_gone_by;
   1364  1.1.2.2  skrll 
   1365  1.1.2.2  skrll 	SCTP_GETTIME_TIMEVAL(&tn);
   1366  1.1.2.2  skrll 	if (stcb->asoc.sctp_autoclose_ticks &&
   1367  1.1.2.2  skrll 	    (inp->sctp_flags & SCTP_PCB_FLAGS_AUTOCLOSE)) {
   1368  1.1.2.2  skrll 		/* Auto close is on */
   1369  1.1.2.2  skrll 		asoc = &stcb->asoc;
   1370  1.1.2.2  skrll 		/* pick the time to use */
   1371  1.1.2.2  skrll 		if (asoc->time_last_rcvd.tv_sec >
   1372  1.1.2.2  skrll 		    asoc->time_last_sent.tv_sec) {
   1373  1.1.2.2  skrll 			tim_touse = &asoc->time_last_rcvd;
   1374  1.1.2.2  skrll 		} else {
   1375  1.1.2.2  skrll 			tim_touse = &asoc->time_last_sent;
   1376  1.1.2.2  skrll 		}
   1377  1.1.2.2  skrll 		/* Now has long enough transpired to autoclose? */
   1378  1.1.2.2  skrll 		ticks_gone_by = ((tn.tv_sec - tim_touse->tv_sec) * hz);
   1379  1.1.2.2  skrll 		if ((ticks_gone_by > 0) &&
   1380  1.1.2.2  skrll 		    (ticks_gone_by >= (int)asoc->sctp_autoclose_ticks)) {
   1381  1.1.2.2  skrll 			/*
   1382  1.1.2.2  skrll 			 * autoclose time has hit, call the output routine,
   1383  1.1.2.2  skrll 			 * which should do nothing just to be SURE we don't
   1384  1.1.2.2  skrll 			 * have hanging data. We can then safely check the
   1385  1.1.2.2  skrll 			 * queues and know that we are clear to send shutdown
   1386  1.1.2.2  skrll 			 */
   1387  1.1.2.2  skrll 			sctp_chunk_output(inp, stcb, 9);
   1388  1.1.2.2  skrll 			/* Are we clean? */
   1389  1.1.2.2  skrll 			if (TAILQ_EMPTY(&asoc->send_queue) &&
   1390  1.1.2.2  skrll 			    TAILQ_EMPTY(&asoc->sent_queue)) {
   1391  1.1.2.2  skrll 				/*
   1392  1.1.2.2  skrll 				 * there is nothing queued to send,
   1393  1.1.2.2  skrll 				 * so I'm done...
   1394  1.1.2.2  skrll 				 */
   1395  1.1.2.2  skrll 				if (SCTP_GET_STATE(asoc) !=
   1396  1.1.2.2  skrll 				    SCTP_STATE_SHUTDOWN_SENT) {
   1397  1.1.2.2  skrll 					/* only send SHUTDOWN 1st time thru */
   1398  1.1.2.2  skrll #ifdef SCTP_DEBUG
   1399  1.1.2.2  skrll 					if (sctp_debug_on & SCTP_DEBUG_OUTPUT4) {
   1400  1.1.2.2  skrll 						printf("%s:%d sends a shutdown\n",
   1401  1.1.2.2  skrll 						       __FILE__,
   1402  1.1.2.2  skrll 						       __LINE__
   1403  1.1.2.2  skrll 							);
   1404  1.1.2.2  skrll 					}
   1405  1.1.2.2  skrll #endif
   1406  1.1.2.2  skrll 					sctp_send_shutdown(stcb, stcb->asoc.primary_destination);
   1407  1.1.2.2  skrll 					asoc->state = SCTP_STATE_SHUTDOWN_SENT;
   1408  1.1.2.2  skrll 					sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
   1409  1.1.2.2  skrll 					    stcb->sctp_ep, stcb,
   1410  1.1.2.2  skrll 					    asoc->primary_destination);
   1411  1.1.2.2  skrll 					sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
   1412  1.1.2.2  skrll 					    stcb->sctp_ep, stcb,
   1413  1.1.2.2  skrll 					    asoc->primary_destination);
   1414  1.1.2.2  skrll 				}
   1415  1.1.2.2  skrll 			}
   1416  1.1.2.2  skrll 		} else {
   1417  1.1.2.2  skrll 			/*
   1418  1.1.2.2  skrll 			 * No auto close at this time, reset t-o to
   1419  1.1.2.2  skrll 			 * check later
   1420  1.1.2.2  skrll 			 */
   1421  1.1.2.2  skrll 			int tmp;
   1422  1.1.2.2  skrll 			/* fool the timer startup to use the time left */
   1423  1.1.2.2  skrll 			tmp = asoc->sctp_autoclose_ticks;
   1424  1.1.2.2  skrll 			asoc->sctp_autoclose_ticks -= ticks_gone_by;
   1425  1.1.2.2  skrll 			sctp_timer_start(SCTP_TIMER_TYPE_AUTOCLOSE, inp, stcb,
   1426  1.1.2.2  skrll 					 net);
   1427  1.1.2.2  skrll 			/* restore the real tick value */
   1428  1.1.2.2  skrll 			asoc->sctp_autoclose_ticks = tmp;
   1429  1.1.2.2  skrll 		}
   1430  1.1.2.2  skrll 	}
   1431  1.1.2.2  skrll }
   1432  1.1.2.2  skrll 
   1433  1.1.2.2  skrll void
   1434  1.1.2.2  skrll sctp_iterator_timer(struct sctp_iterator *it)
   1435  1.1.2.2  skrll {
   1436  1.1.2.2  skrll 	int cnt= 0;
   1437  1.1.2.2  skrll 	/* only one iterator can run at a
   1438  1.1.2.2  skrll 	 * time. This is the only way we
   1439  1.1.2.2  skrll 	 * can cleanly pull ep's from underneath
   1440  1.1.2.2  skrll 	 * all the running interators when a
   1441  1.1.2.2  skrll 	 * ep is freed.
   1442  1.1.2.2  skrll 	 */
   1443  1.1.2.2  skrll  	SCTP_ITERATOR_LOCK();
   1444  1.1.2.2  skrll 	if (it->inp == NULL) {
   1445  1.1.2.2  skrll 		/* iterator is complete */
   1446  1.1.2.2  skrll 	done_with_iterator:
   1447  1.1.2.2  skrll 		SCTP_ITERATOR_UNLOCK();
   1448  1.1.2.2  skrll 		SCTP_INP_INFO_WLOCK();
   1449  1.1.2.2  skrll 		LIST_REMOVE(it, sctp_nxt_itr);
   1450  1.1.2.2  skrll 		/* stopping the callout is not needed, in theory,
   1451  1.1.2.2  skrll 		 * but I am paranoid.
   1452  1.1.2.2  skrll 		 */
   1453  1.1.2.2  skrll 		SCTP_INP_INFO_WUNLOCK();
   1454  1.1.2.2  skrll 		callout_stop(&it->tmr.timer);
   1455  1.1.2.2  skrll 		if (it->function_atend != NULL) {
   1456  1.1.2.2  skrll 			(*it->function_atend)(it->pointer, it->val);
   1457  1.1.2.2  skrll 		}
   1458  1.1.2.2  skrll 		callout_destroy(&it->tmr.timer);
   1459  1.1.2.2  skrll 		free(it, M_PCB);
   1460  1.1.2.2  skrll 		return;
   1461  1.1.2.2  skrll 	}
   1462  1.1.2.2  skrll  select_a_new_ep:
   1463  1.1.2.2  skrll 	SCTP_INP_WLOCK(it->inp);
   1464  1.1.2.2  skrll 	while ((it->pcb_flags) && ((it->inp->sctp_flags & it->pcb_flags) != it->pcb_flags)) {
   1465  1.1.2.2  skrll 		/* we do not like this ep */
   1466  1.1.2.2  skrll 		if (it->iterator_flags & SCTP_ITERATOR_DO_SINGLE_INP) {
   1467  1.1.2.2  skrll 			SCTP_INP_WUNLOCK(it->inp);
   1468  1.1.2.2  skrll 			goto done_with_iterator;
   1469  1.1.2.2  skrll 		}
   1470  1.1.2.2  skrll 		SCTP_INP_WUNLOCK(it->inp);
   1471  1.1.2.2  skrll 		it->inp = LIST_NEXT(it->inp, sctp_list);
   1472  1.1.2.2  skrll 		if (it->inp == NULL) {
   1473  1.1.2.2  skrll 			goto done_with_iterator;
   1474  1.1.2.2  skrll 		}
   1475  1.1.2.2  skrll 		SCTP_INP_WLOCK(it->inp);
   1476  1.1.2.2  skrll 	}
   1477  1.1.2.2  skrll 	if ((it->inp->inp_starting_point_for_iterator != NULL) &&
   1478  1.1.2.2  skrll 	    (it->inp->inp_starting_point_for_iterator != it)) {
   1479  1.1.2.2  skrll 		printf("Iterator collision, we must wait for other iterator at %p\n",
   1480  1.1.2.2  skrll 		       it->inp);
   1481  1.1.2.2  skrll 		SCTP_INP_WUNLOCK(it->inp);
   1482  1.1.2.2  skrll 		goto start_timer_return;
   1483  1.1.2.2  skrll 	}
   1484  1.1.2.2  skrll 	/* now we do the actual write to this guy */
   1485  1.1.2.2  skrll 	it->inp->inp_starting_point_for_iterator = it;
   1486  1.1.2.2  skrll 	SCTP_INP_WUNLOCK(it->inp);
   1487  1.1.2.2  skrll 	SCTP_INP_RLOCK(it->inp);
   1488  1.1.2.2  skrll 	/* if we reach here we found a inp acceptable, now through each
   1489  1.1.2.2  skrll 	 * one that has the association in the right state
   1490  1.1.2.2  skrll 	 */
   1491  1.1.2.2  skrll 	if (it->stcb == NULL) {
   1492  1.1.2.2  skrll 		it->stcb = LIST_FIRST(&it->inp->sctp_asoc_list);
   1493  1.1.2.2  skrll 	}
   1494  1.1.2.2  skrll 	if (it->stcb->asoc.stcb_starting_point_for_iterator == it) {
   1495  1.1.2.2  skrll 		it->stcb->asoc.stcb_starting_point_for_iterator = NULL;
   1496  1.1.2.2  skrll 	}
   1497  1.1.2.2  skrll 	while (it->stcb) {
   1498  1.1.2.2  skrll 		SCTP_TCB_LOCK(it->stcb);
   1499  1.1.2.2  skrll 		if (it->asoc_state && ((it->stcb->asoc.state & it->asoc_state) != it->asoc_state)) {
   1500  1.1.2.2  skrll 			SCTP_TCB_UNLOCK(it->stcb);
   1501  1.1.2.2  skrll 			it->stcb = LIST_NEXT(it->stcb, sctp_tcblist);
   1502  1.1.2.2  skrll 			continue;
   1503  1.1.2.2  skrll 		}
   1504  1.1.2.2  skrll 		cnt++;
   1505  1.1.2.2  skrll 		/* run function on this one */
   1506  1.1.2.2  skrll 		SCTP_INP_RUNLOCK(it->inp);
   1507  1.1.2.2  skrll 		(*it->function_toapply)(it->inp, it->stcb, it->pointer, it->val);
   1508  1.1.2.2  skrll 		sctp_chunk_output(it->inp, it->stcb, 1);
   1509  1.1.2.2  skrll 		SCTP_TCB_UNLOCK(it->stcb);
   1510  1.1.2.2  skrll 		/* see if we have limited out */
   1511  1.1.2.2  skrll 		if (cnt > SCTP_MAX_ITERATOR_AT_ONCE) {
   1512  1.1.2.2  skrll 			it->stcb->asoc.stcb_starting_point_for_iterator = it;
   1513  1.1.2.2  skrll 		start_timer_return:
   1514  1.1.2.2  skrll 			SCTP_ITERATOR_UNLOCK();
   1515  1.1.2.2  skrll 			sctp_timer_start(SCTP_TIMER_TYPE_ITERATOR, (struct sctp_inpcb *)it, NULL, NULL);
   1516  1.1.2.2  skrll 			return;
   1517  1.1.2.2  skrll 		}
   1518  1.1.2.2  skrll 		SCTP_INP_RLOCK(it->inp);
   1519  1.1.2.2  skrll 		it->stcb = LIST_NEXT(it->stcb, sctp_tcblist);
   1520  1.1.2.2  skrll 	}
   1521  1.1.2.2  skrll 	/* if we reach here, we ran out of stcb's in the inp we are looking at */
   1522  1.1.2.2  skrll 	SCTP_INP_RUNLOCK(it->inp);
   1523  1.1.2.2  skrll 	SCTP_INP_WLOCK(it->inp);
   1524  1.1.2.2  skrll 	it->inp->inp_starting_point_for_iterator = NULL;
   1525  1.1.2.2  skrll 	SCTP_INP_WUNLOCK(it->inp);
   1526  1.1.2.2  skrll 	if (it->iterator_flags & SCTP_ITERATOR_DO_SINGLE_INP) {
   1527  1.1.2.2  skrll 		it->inp = NULL;
   1528  1.1.2.2  skrll 	} else {
   1529  1.1.2.2  skrll 		SCTP_INP_INFO_RLOCK();
   1530  1.1.2.2  skrll 		it->inp = LIST_NEXT(it->inp, sctp_list);
   1531  1.1.2.2  skrll 		SCTP_INP_INFO_RUNLOCK();
   1532  1.1.2.2  skrll 	}
   1533  1.1.2.2  skrll 	if (it->inp == NULL) {
   1534  1.1.2.2  skrll 		goto done_with_iterator;
   1535  1.1.2.2  skrll 	}
   1536  1.1.2.2  skrll 	goto select_a_new_ep;
   1537  1.1.2.2  skrll }
   1538