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