Home | History | Annotate | Download | only in sctp
      1      0    stevel /*
      2      0    stevel  * CDDL HEADER START
      3      0    stevel  *
      4      0    stevel  * The contents of this file are subject to the terms of the
      5   1676       jpk  * Common Development and Distribution License (the "License").
      6   1676       jpk  * You may not use this file except in compliance with the License.
      7      0    stevel  *
      8      0    stevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9      0    stevel  * or http://www.opensolaris.org/os/licensing.
     10      0    stevel  * See the License for the specific language governing permissions
     11      0    stevel  * and limitations under the License.
     12      0    stevel  *
     13      0    stevel  * When distributing Covered Code, include this CDDL HEADER in each
     14      0    stevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15      0    stevel  * If applicable, add the following below this CDDL HEADER, with the
     16      0    stevel  * fields enclosed by brackets "[]" replaced with your own identifying
     17      0    stevel  * information: Portions Copyright [yyyy] [name of copyright owner]
     18      0    stevel  *
     19      0    stevel  * CDDL HEADER END
     20      0    stevel  */
     21   1735    kcpoon 
     22      0    stevel /*
     23  10212    George  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     24      0    stevel  * Use is subject to license terms.
     25      0    stevel  */
     26      0    stevel 
     27      0    stevel #include <sys/types.h>
     28      0    stevel #include <sys/systm.h>
     29      0    stevel #include <sys/stream.h>
     30      0    stevel #include <sys/cmn_err.h>
     31      0    stevel #include <sys/strsubr.h>
     32      0    stevel #include <sys/strsun.h>
     33      0    stevel 
     34      0    stevel #include <netinet/in.h>
     35      0    stevel #include <netinet/ip6.h>
     36      0    stevel 
     37      0    stevel #include <inet/common.h>
     38      0    stevel #include <inet/ip.h>
     39      0    stevel #include <inet/mib2.h>
     40      0    stevel #include <inet/ipclassifier.h>
     41      0    stevel #include "sctp_impl.h"
     42      0    stevel #include "sctp_asconf.h"
     43      0    stevel 
     44      0    stevel /* Timer block states. */
     45      0    stevel typedef enum {
     46      0    stevel 	SCTP_TB_RUNNING = 1,
     47      0    stevel 	SCTP_TB_IDLE,
     48      0    stevel /* Could not stop/free before mblk got queued */
     49      0    stevel 	SCTP_TB_RESCHED,	/* sctp_tb_time_left contains tick count */
     50      0    stevel 	SCTP_TB_CANCELLED,
     51      0    stevel 	SCTP_TB_TO_BE_FREED
     52      0    stevel } timer_block_state;
     53      0    stevel 
     54      0    stevel typedef struct sctp_tb_s {
     55      0    stevel 	timer_block_state	sctp_tb_state;
     56      0    stevel 	timeout_id_t		sctp_tb_tid;
     57      0    stevel 	mblk_t			*sctp_tb_mp;
     58      0    stevel 	clock_t			sctp_tb_time_left;
     59      0    stevel } sctp_tb_t;
     60      0    stevel 
     61      0    stevel static void sctp_timer_fire(sctp_tb_t *);
     62      0    stevel 
     63      0    stevel /*
     64      0    stevel  *		sctp_timer mechanism.
     65      0    stevel  *
     66      0    stevel  * Each timer is represented by a timer mblk. When the
     67      0    stevel  * timer fires, and the sctp_t is busy, the timer mblk will be put on
     68      0    stevel  * the associated sctp_t timer queue so that it can be executed when
     69      0    stevel  * the thread holding the lock on the sctp_t is done with its job.
     70      0    stevel  *
     71      0    stevel  * Note that there is no lock to protect the timer mblk state.  The reason
     72      0    stevel  * is that the timer state can only be changed by a thread holding the
     73      0    stevel  * lock on the sctp_t.
     74      0    stevel  *
     75      0    stevel  * The interface consists of 4 entry points:
     76      0    stevel  *	sctp_timer_alloc	- create a timer mblk
     77      0    stevel  *	sctp_timer_free		- free a timer mblk
     78      0    stevel  *	sctp_timer		- start, restart, stop the timer
     79      0    stevel  *	sctp_timer_valid	- called by sctp_process_recvq to verify that
     80      0    stevel  *				  the timer did indeed fire.
     81      0    stevel  */
     82      0    stevel 
     83      0    stevel 
     84      0    stevel /*
     85      0    stevel  * Start, restart, stop the timer.
     86      0    stevel  * If "tim" is -1 the timer is stopped.
     87      0    stevel  * Otherwise, the timer is stopped if it is already running, and
     88      0    stevel  * set to fire tim clock ticks from now.
     89      0    stevel  */
     90      0    stevel void
     91      0    stevel sctp_timer(sctp_t *sctp, mblk_t *mp, clock_t tim)
     92      0    stevel {
     93      0    stevel 	sctp_tb_t *sctp_tb;
     94      0    stevel 	int state;
     95      0    stevel 
     96      0    stevel 	ASSERT(sctp != NULL && mp != NULL);
     97      0    stevel 	ASSERT((mp->b_rptr - mp->b_datap->db_base) == sizeof (sctp_tb_t));
     98      0    stevel 	ASSERT(mp->b_datap->db_type == M_PCSIG);
     99      0    stevel 
    100      0    stevel 	sctp_tb = (sctp_tb_t *)mp->b_datap->db_base;
    101      0    stevel 	if (tim >= 0) {
    102      0    stevel 		state = sctp_tb->sctp_tb_state;
    103      0    stevel 		sctp_tb->sctp_tb_time_left = tim;
    104      0    stevel 		if (state == SCTP_TB_RUNNING) {
    105      0    stevel 			if (untimeout(sctp_tb->sctp_tb_tid) < 0) {
    106      0    stevel 				sctp_tb->sctp_tb_state = SCTP_TB_RESCHED;
    107      0    stevel 				/* sctp_timer_valid will start timer */
    108      0    stevel 				return;
    109      0    stevel 			}
    110      0    stevel 		} else if (state != SCTP_TB_IDLE) {
    111      0    stevel 			ASSERT(state != SCTP_TB_TO_BE_FREED);
    112      0    stevel 			if (state == SCTP_TB_CANCELLED) {
    113      0    stevel 				sctp_tb->sctp_tb_state = SCTP_TB_RESCHED;
    114      0    stevel 				/* sctp_timer_valid will start timer */
    115      0    stevel 				return;
    116      0    stevel 			}
    117      0    stevel 			if (state == SCTP_TB_RESCHED) {
    118      0    stevel 				/* sctp_timer_valid will start timer */
    119      0    stevel 				return;
    120      0    stevel 			}
    121      0    stevel 		} else {
    122      0    stevel 			SCTP_REFHOLD(sctp);
    123      0    stevel 		}
    124      0    stevel 		sctp_tb->sctp_tb_state = SCTP_TB_RUNNING;
    125      0    stevel 		sctp_tb->sctp_tb_tid =
    126      0    stevel 		    timeout((pfv_t)sctp_timer_fire, sctp_tb, tim);
    127      0    stevel 		return;
    128      0    stevel 	}
    129      0    stevel 	switch (tim) {
    130      0    stevel 	case -1:
    131      0    stevel 		sctp_timer_stop(mp);
    132      0    stevel 		break;
    133      0    stevel 	default:
    134      0    stevel 		ASSERT(0);
    135      0    stevel 		break;
    136      0    stevel 	}
    137      0    stevel }
    138      0    stevel 
    139      0    stevel /*
    140      0    stevel  * sctp_timer_alloc is called by sctp_init to allocate and initialize a
    141      0    stevel  * sctp timer.
    142      0    stevel  *
    143      0    stevel  * Allocate an M_PCSIG timer message. The space between db_base and
    144      0    stevel  * b_rptr is used by the sctp_timer mechanism, and after b_rptr there is
    145      0    stevel  * space for sctpt_t.
    146      0    stevel  */
    147      0    stevel mblk_t *
    148   4691    kcpoon sctp_timer_alloc(sctp_t *sctp, pfv_t func, int sleep)
    149      0    stevel {
    150      0    stevel 	mblk_t *mp;
    151      0    stevel 	sctp_tb_t *sctp_tb;
    152      0    stevel 	sctpt_t	*sctpt;
    153   3448  dh155122 	sctp_stack_t	*sctps = sctp->sctp_sctps;
    154      0    stevel 
    155   4691    kcpoon 	if (sleep == KM_SLEEP) {
    156   4691    kcpoon 		mp = allocb_wait(sizeof (sctp_t) + sizeof (sctp_tb_t), BPRI_HI,
    157   4691    kcpoon 		    STR_NOSIG, NULL);
    158   4691    kcpoon 	} else {
    159   4691    kcpoon 		mp = allocb(sizeof (sctp_t) + sizeof (sctp_tb_t), BPRI_HI);
    160   4691    kcpoon 	}
    161   4691    kcpoon 	if (mp != NULL) {
    162      0    stevel 		mp->b_datap->db_type = M_PCSIG;
    163      0    stevel 		sctp_tb = (sctp_tb_t *)mp->b_datap->db_base;
    164      0    stevel 		mp->b_rptr = (uchar_t *)&sctp_tb[1];
    165      0    stevel 		mp->b_wptr = mp->b_rptr + sizeof (sctpt_t);
    166      0    stevel 		sctp_tb->sctp_tb_state = SCTP_TB_IDLE;
    167      0    stevel 		sctp_tb->sctp_tb_mp = mp;
    168      0    stevel 
    169      0    stevel 		sctpt = (sctpt_t *)mp->b_rptr;
    170      0    stevel 		sctpt->sctpt_sctp = sctp;
    171      0    stevel 		sctpt->sctpt_faddr = NULL;	/* set when starting timer */
    172      0    stevel 		sctpt->sctpt_pfv = func;
    173      0    stevel 		return (mp);
    174      0    stevel 	}
    175   3448  dh155122 	SCTP_KSTAT(sctps, sctp_add_timer);
    176      0    stevel 	return (NULL);
    177      0    stevel }
    178      0    stevel 
    179      0    stevel /*
    180      0    stevel  * timeout() callback function.
    181      0    stevel  * Put the message on the process control block's queue.
    182      0    stevel  * If the timer is stopped or freed after
    183      0    stevel  * it has fired then sctp_timer() and sctp_timer_valid() will clean
    184      0    stevel  * things up.
    185      0    stevel  */
    186      0    stevel static void
    187      0    stevel sctp_timer_fire(sctp_tb_t *sctp_tb)
    188      0    stevel {
    189      0    stevel 	mblk_t *mp;
    190      0    stevel 	sctp_t *sctp;
    191      0    stevel 	sctpt_t *sctpt;
    192      0    stevel 
    193      0    stevel 	mp = sctp_tb->sctp_tb_mp;
    194      0    stevel 	ASSERT(sctp_tb == (sctp_tb_t *)mp->b_datap->db_base);
    195      0    stevel 	ASSERT(mp->b_datap->db_type == M_PCSIG);
    196      0    stevel 
    197      0    stevel 	sctpt = (sctpt_t *)mp->b_rptr;
    198      0    stevel 	sctp = sctpt->sctpt_sctp;
    199      0    stevel 	ASSERT(sctp != NULL);
    200      0    stevel 
    201      0    stevel 	mutex_enter(&sctp->sctp_lock);
    202      0    stevel 	if (sctp->sctp_running) {
    203      0    stevel 		/*
    204      0    stevel 		 * Put the timer mblk to the special sctp_timer_mp list.
    205      0    stevel 		 * This timer will be handled when the thread using this
    206      0    stevel 		 * SCTP is done with its job.
    207      0    stevel 		 */
    208      0    stevel 		if (sctp->sctp_timer_mp == NULL) {
    209      0    stevel 			SCTP_REFHOLD(sctp);
    210      0    stevel 			sctp->sctp_timer_mp = mp;
    211      0    stevel 		} else {
    212      0    stevel 			linkb(sctp->sctp_timer_mp, mp);
    213      0    stevel 		}
    214      0    stevel 		mp->b_cont = NULL;
    215      0    stevel 		mutex_exit(&sctp->sctp_lock);
    216      0    stevel 	} else {
    217      0    stevel 		sctp->sctp_running = B_TRUE;
    218      0    stevel 		mutex_exit(&sctp->sctp_lock);
    219      0    stevel 
    220      0    stevel 		sctp_timer_call(sctp, mp);
    221      0    stevel 		WAKE_SCTP(sctp);
    222      0    stevel 	}
    223      0    stevel 	SCTP_REFRELE(sctp);
    224      0    stevel }
    225      0    stevel 
    226      0    stevel /*
    227      0    stevel  * Logically free a timer mblk (that might have a pending timeout().)
    228      0    stevel  * If the timer has fired and the mblk has been put on the queue then
    229      0    stevel  * sctp_timer_valid will free the mblk.
    230      0    stevel  */
    231      0    stevel void
    232      0    stevel sctp_timer_free(mblk_t *mp)
    233      0    stevel {
    234      0    stevel 	sctp_tb_t *sctp_tb;
    235      0    stevel 	int state;
    236      0    stevel 	sctpt_t *sctpt;
    237      0    stevel 
    238      0    stevel 	ASSERT(mp != NULL);
    239      0    stevel 	ASSERT((mp->b_rptr - mp->b_datap->db_base) == sizeof (sctp_tb_t));
    240      0    stevel 	ASSERT(mp->b_datap->db_type == M_PCSIG);
    241      0    stevel 
    242      0    stevel 	sctp_tb = (sctp_tb_t *)mp->b_datap->db_base;
    243      0    stevel 	state = sctp_tb->sctp_tb_state;
    244      0    stevel 
    245   1676       jpk 	dprint(5, ("sctp_timer_free %p state %d\n", (void *)mp, state));
    246      0    stevel 
    247      0    stevel 	if (state == SCTP_TB_RUNNING) {
    248      0    stevel 		if (untimeout(sctp_tb->sctp_tb_tid) < 0) {
    249      0    stevel 			sctp_tb->sctp_tb_state = SCTP_TB_TO_BE_FREED;
    250      0    stevel 			/* sctp_timer_valid will free the mblk */
    251      0    stevel 			return;
    252      0    stevel 		}
    253      0    stevel 		sctpt = (sctpt_t *)mp->b_rptr;
    254      0    stevel 		SCTP_REFRELE(sctpt->sctpt_sctp);
    255      0    stevel 	} else if (state != SCTP_TB_IDLE) {
    256      0    stevel 		ASSERT(state != SCTP_TB_TO_BE_FREED);
    257      0    stevel 		sctp_tb->sctp_tb_state = SCTP_TB_TO_BE_FREED;
    258      0    stevel 		/* sctp_timer_valid will free the mblk */
    259      0    stevel 		return;
    260      0    stevel 	}
    261      0    stevel 	freeb(mp);
    262      0    stevel }
    263      0    stevel 
    264      0    stevel /*
    265      0    stevel  * Called from sctp_timer(,,-1)
    266      0    stevel  */
    267      0    stevel void
    268      0    stevel sctp_timer_stop(mblk_t *mp)
    269      0    stevel {
    270      0    stevel 	sctp_tb_t *sctp_tb;
    271      0    stevel 	int state;
    272      0    stevel 	sctpt_t *sctpt;
    273      0    stevel 
    274      0    stevel 	ASSERT(mp != NULL);
    275      0    stevel 	ASSERT(mp->b_datap->db_type == M_PCSIG);
    276      0    stevel 
    277      0    stevel 	sctp_tb = (sctp_tb_t *)mp->b_datap->db_base;
    278      0    stevel 	state = sctp_tb->sctp_tb_state;
    279      0    stevel 
    280   1676       jpk 	dprint(5, ("sctp_timer_stop %p %d\n", (void *)mp, state));
    281      0    stevel 
    282      0    stevel 	if (state == SCTP_TB_RUNNING) {
    283      0    stevel 		if (untimeout(sctp_tb->sctp_tb_tid) < 0) {
    284      0    stevel 			sctp_tb->sctp_tb_state = SCTP_TB_CANCELLED;
    285      0    stevel 		} else {
    286      0    stevel 			sctp_tb->sctp_tb_state = SCTP_TB_IDLE;
    287      0    stevel 			sctpt = (sctpt_t *)mp->b_rptr;
    288      0    stevel 			SCTP_REFRELE(sctpt->sctpt_sctp);
    289      0    stevel 		}
    290      0    stevel 	} else if (state == SCTP_TB_RESCHED) {
    291      0    stevel 		sctp_tb->sctp_tb_state = SCTP_TB_CANCELLED;
    292      0    stevel 	}
    293      0    stevel }
    294      0    stevel 
    295      0    stevel /*
    296      0    stevel  * The user of the sctp_timer mechanism is required to call
    297      0    stevel  * sctp_timer_valid() for each M_PCSIG message processed in the
    298      0    stevel  * service procedures.
    299      0    stevel  * sctp_timer_valid will return "true" if the timer actually did fire.
    300      0    stevel  */
    301      0    stevel 
    302      0    stevel static boolean_t
    303      0    stevel sctp_timer_valid(mblk_t *mp)
    304      0    stevel {
    305      0    stevel 	sctp_tb_t *sctp_tb;
    306      0    stevel 	int state;
    307      0    stevel 	sctpt_t *sctpt;
    308      0    stevel 
    309      0    stevel 	ASSERT(mp != NULL);
    310      0    stevel 	ASSERT(mp->b_datap->db_type == M_PCSIG);
    311      0    stevel 
    312      0    stevel 	sctp_tb = (sctp_tb_t *)DB_BASE(mp);
    313      0    stevel 	sctpt = (sctpt_t *)mp->b_rptr;
    314      0    stevel 	state = sctp_tb->sctp_tb_state;
    315      0    stevel 	if (state != SCTP_TB_RUNNING) {
    316      0    stevel 		ASSERT(state != SCTP_TB_IDLE);
    317      0    stevel 		if (state == SCTP_TB_TO_BE_FREED) {
    318      0    stevel 			/*
    319      0    stevel 			 * sctp_timer_free was called after the message
    320      0    stevel 			 * was putq'ed.
    321      0    stevel 			 */
    322      0    stevel 			freeb(mp);
    323      0    stevel 			return (B_FALSE);
    324      0    stevel 		}
    325      0    stevel 		if (state == SCTP_TB_CANCELLED) {
    326      0    stevel 			/* The timer was stopped after the mblk was putq'ed */
    327      0    stevel 			sctp_tb->sctp_tb_state = SCTP_TB_IDLE;
    328      0    stevel 			return (B_FALSE);
    329      0    stevel 		}
    330      0    stevel 		if (state == SCTP_TB_RESCHED) {
    331      0    stevel 			/*
    332      0    stevel 			 * The timer was stopped and then restarted after
    333      0    stevel 			 * the mblk was putq'ed.
    334      0    stevel 			 * sctp_tb_time_left contains the number of ticks that
    335      0    stevel 			 * the timer was restarted with.
    336      0    stevel 			 * The sctp will not be disapper between the time
    337      0    stevel 			 * the sctpt_t is marked SCTP_TB_RESCHED and when
    338      0    stevel 			 * we get here as sctp_add_recvq() does a refhold.
    339      0    stevel 			 */
    340      0    stevel 			sctp_tb->sctp_tb_state = SCTP_TB_RUNNING;
    341      0    stevel 			sctp_tb->sctp_tb_tid = timeout((pfv_t)sctp_timer_fire,
    342      0    stevel 			    sctp_tb, sctp_tb->sctp_tb_time_left);
    343      0    stevel 			SCTP_REFHOLD(sctpt->sctpt_sctp);
    344      0    stevel 			return (B_FALSE);
    345      0    stevel 		}
    346      0    stevel 	}
    347      0    stevel 	sctp_tb->sctp_tb_state = SCTP_TB_IDLE;
    348      0    stevel 	return (B_TRUE);
    349      0    stevel }
    350      0    stevel 
    351      0    stevel /*
    352      0    stevel  * The SCTP timer call. Calls sctp_timer_valid() to verify whether
    353      0    stevel  * timer was cancelled or not.
    354      0    stevel  */
    355      0    stevel void
    356      0    stevel sctp_timer_call(sctp_t *sctp, mblk_t *mp)
    357      0    stevel {
    358      0    stevel 	sctpt_t *sctpt = (sctpt_t *)mp->b_rptr;
    359      0    stevel 
    360      0    stevel 	if (sctp_timer_valid(mp)) {
    361      0    stevel 		(*sctpt->sctpt_pfv)(sctp, sctpt->sctpt_faddr);
    362      0    stevel 	}
    363      0    stevel }
    364      0    stevel 
    365      0    stevel /*
    366      0    stevel  * Delayed ack
    367      0    stevel  */
    368      0    stevel void
    369      0    stevel sctp_ack_timer(sctp_t *sctp)
    370      0    stevel {
    371   3448  dh155122 	sctp_stack_t	*sctps = sctp->sctp_sctps;
    372   3448  dh155122 
    373      0    stevel 	sctp->sctp_ack_timer_running = 0;
    374   3448  dh155122 	sctp->sctp_sack_toggle = sctps->sctps_deferred_acks_max;
    375   3448  dh155122 	BUMP_MIB(&sctps->sctps_mib, sctpOutAckDelayed);
    376   4964    kcpoon 	(void) sctp_sack(sctp, NULL);
    377      0    stevel }
    378      0    stevel 
    379      0    stevel /*
    380      0    stevel  * Peer address heartbeat timer handler
    381      0    stevel  */
    382      0    stevel void
    383      0    stevel sctp_heartbeat_timer(sctp_t *sctp)
    384      0    stevel {
    385      0    stevel 	sctp_faddr_t	*fp;
    386      0    stevel 	int64_t		now;
    387      0    stevel 	int64_t		earliest_expiry;
    388      0    stevel 	int		cnt;
    389   3448  dh155122 	sctp_stack_t	*sctps = sctp->sctp_sctps;
    390      0    stevel 
    391      0    stevel 	if (sctp->sctp_strikes >= sctp->sctp_pa_max_rxt) {
    392      0    stevel 		/*
    393      0    stevel 		 * If there is a peer address with no strikes,
    394      0    stevel 		 * don't give up yet. If enough other peer
    395      0    stevel 		 * address are down, we could otherwise fail
    396      0    stevel 		 * the association prematurely.  This is a
    397      0    stevel 		 * byproduct of our aggressive probe approach
    398      0    stevel 		 * when a heartbeat fails to connect. We may
    399      0    stevel 		 * wish to revisit this...
    400      0    stevel 		 */
    401      0    stevel 		if (!sctp_is_a_faddr_clean(sctp)) {
    402      0    stevel 			/* time to give up */
    403   3448  dh155122 			BUMP_MIB(&sctps->sctps_mib, sctpAborted);
    404   3448  dh155122 			BUMP_MIB(&sctps->sctps_mib, sctpTimHeartBeatDrop);
    405      0    stevel 			sctp_assoc_event(sctp, SCTP_COMM_LOST, 0, NULL);
    406      0    stevel 			sctp_clean_death(sctp, sctp->sctp_client_errno ?
    407      0    stevel 			    sctp->sctp_client_errno : ETIMEDOUT);
    408      0    stevel 			return;
    409      0    stevel 		}
    410      0    stevel 	}
    411      0    stevel 
    412      0    stevel 	/* Only send heartbeats in the established state */
    413      0    stevel 	if (sctp->sctp_state != SCTPS_ESTABLISHED) {
    414      0    stevel 		dprint(5, ("sctp_heartbeat_timer: not in ESTABLISHED\n"));
    415      0    stevel 		return;
    416      0    stevel 	}
    417      0    stevel 
    418  11066    rafael 	now = ddi_get_lbolt64();
    419      0    stevel 	earliest_expiry = 0;
    420   3448  dh155122 	cnt = sctps->sctps_maxburst;
    421      0    stevel 
    422      0    stevel 	/*
    423      0    stevel 	 * Walk through all faddrs.  Since the timer should run infrequently
    424      0    stevel 	 * and the number of peer addresses should not be big, this should
    425      0    stevel 	 * be OK.
    426      0    stevel 	 */
    427      0    stevel 	for (fp = sctp->sctp_faddrs; fp != NULL; fp = fp->next) {
    428      0    stevel 		/*
    429   4818    kcpoon 		 * If the peer is unreachable because there is no available
    430  11042      Erik 		 * source address, call sctp_get_dest() to see if it is
    431   4818    kcpoon 		 * reachable now.  If it is OK, the state will become
    432   4818    kcpoon 		 * unconfirmed.  And the following code to handle unconfirmed
    433   4818    kcpoon 		 * address will be executed.  If it is still not OK,
    434   4818    kcpoon 		 * re-schedule.  If heartbeat is enabled, only try this
    435   4818    kcpoon 		 * up to the normal heartbeat max times.  But if heartbeat
    436   4818    kcpoon 		 * is disable, this retry may go on forever.
    437      0    stevel 		 */
    438   4818    kcpoon 		if (fp->state == SCTP_FADDRS_UNREACH) {
    439  11042      Erik 			sctp_get_dest(sctp, fp);
    440   4818    kcpoon 			if (fp->state == SCTP_FADDRS_UNREACH) {
    441   4818    kcpoon 				if (fp->hb_enabled &&
    442   4818    kcpoon 				    ++fp->strikes > fp->max_retr &&
    443   4818    kcpoon 				    sctp_faddr_dead(sctp, fp,
    444   4818    kcpoon 				    SCTP_FADDRS_DOWN) == -1) {
    445   4818    kcpoon 					/* Assoc is dead */
    446   4818    kcpoon 					return;
    447   4818    kcpoon 				}
    448   4818    kcpoon 				fp->hb_expiry = now + SET_HB_INTVL(fp);
    449   4818    kcpoon 				goto set_expiry;
    450   4818    kcpoon 			} else {
    451   4818    kcpoon 				/* Send a heartbeat immediately. */
    452   4818    kcpoon 				fp->hb_expiry = now;
    453   4818    kcpoon 			}
    454   4818    kcpoon 		}
    455   4818    kcpoon 		/*
    456   4818    kcpoon 		 * Don't send heartbeat to this address if it is not
    457   4818    kcpoon 		 * hb_enabled and the address has been confirmed.
    458   4818    kcpoon 		 */
    459   4818    kcpoon 		if (!fp->hb_enabled && fp->state != SCTP_FADDRS_UNCONFIRMED) {
    460      0    stevel 			continue;
    461      0    stevel 		}
    462      0    stevel 
    463      0    stevel 		/*
    464      0    stevel 		 * The heartbeat timer is expired.  If the address is dead,
    465      0    stevel 		 * we still send heartbeat to it in case it becomes alive
    466   4818    kcpoon 		 * again.  But we will only send once in a while, calculated
    467   4818    kcpoon 		 * by SET_HB_INTVL().
    468      0    stevel 		 *
    469      0    stevel 		 * If the address is alive and there is a hearbeat pending,
    470      0    stevel 		 * resend the heartbeat and start exponential backoff on the
    471      0    stevel 		 * heartbeat timeout value.  If there is no heartbeat pending,
    472      0    stevel 		 * just send out one.
    473      0    stevel 		 */
    474      0    stevel 		if (now >= fp->hb_expiry) {
    475      0    stevel 			if (fp->hb_pending) {
    476      0    stevel 				/*
    477      0    stevel 				 * If an address is not confirmed, no need
    478      0    stevel 				 * to bump the overall counter as it doesn't
    479      0    stevel 				 * matter as we will not use it to send data
    480      0    stevel 				 * and it should not affect the association.
    481      0    stevel 				 */
    482      0    stevel 				switch (fp->state) {
    483      0    stevel 				case SCTP_FADDRS_ALIVE:
    484      0    stevel 					sctp->sctp_strikes++;
    485      0    stevel 					/* FALLTHRU */
    486      0    stevel 				case SCTP_FADDRS_UNCONFIRMED:
    487      0    stevel 					/*
    488      0    stevel 					 * Retransmission implies that RTO
    489      0    stevel 					 * is probably not correct.
    490      0    stevel 					 */
    491      0    stevel 					fp->rtt_updates = 0;
    492      0    stevel 					fp->strikes++;
    493      0    stevel 					if (fp->strikes > fp->max_retr) {
    494      0    stevel 						if (sctp_faddr_dead(sctp, fp,
    495      0    stevel 						    SCTP_FADDRS_DOWN) == -1) {
    496      0    stevel 							/* Assoc is dead */
    497      0    stevel 							return;
    498      0    stevel 						}
    499      0    stevel 						/*
    500      0    stevel 						 * Addr is down; keep initial
    501      0    stevel 						 * RTO
    502      0    stevel 						 */
    503      0    stevel 						fp->rto =
    504      0    stevel 						    sctp->sctp_rto_initial;
    505      0    stevel 						goto dead_addr;
    506      0    stevel 					} else {
    507  10212    George 						SCTP_CALC_RXT(sctp, fp);
    508      0    stevel 						fp->hb_expiry = now + fp->rto;
    509      0    stevel 					}
    510      0    stevel 					break;
    511      0    stevel 				case SCTP_FADDRS_DOWN:
    512      0    stevel dead_addr:
    513      0    stevel 					fp->hb_expiry = now + SET_HB_INTVL(fp);
    514      0    stevel 					break;
    515      0    stevel 				default:
    516      0    stevel 					continue;
    517      0    stevel 				}
    518      0    stevel 			} else {
    519   4818    kcpoon 				/*
    520   4818    kcpoon 				 * If there is unack'ed data, no need to
    521   4818    kcpoon 				 * send a heart beat.
    522   4818    kcpoon 				 */
    523   4818    kcpoon 				if (fp->suna > 0) {
    524   4818    kcpoon 					fp->hb_expiry = now + SET_HB_INTVL(fp);
    525   4818    kcpoon 					goto set_expiry;
    526   4818    kcpoon 				} else {
    527   4818    kcpoon 					fp->hb_expiry = now + fp->rto;
    528   4818    kcpoon 				}
    529      0    stevel 			}
    530      0    stevel 			/*
    531      0    stevel 			 * Note that the total number of heartbeat we can send
    532      0    stevel 			 * out simultaneously is limited by sctp_maxburst.  If
    533      0    stevel 			 * the limit is exceeded, we need to wait for the next
    534      0    stevel 			 * timeout to send them.  This should only happen if
    535      0    stevel 			 * there is unconfirmed address.  Note that hb_pending
    536      0    stevel 			 * is set in sctp_send_heartbeat().  So if a heartbeat
    537      0    stevel 			 * is not sent, it will not affect the state of the
    538      0    stevel 			 * peer address.
    539      0    stevel 			 */
    540      0    stevel 			if (fp->state != SCTP_FADDRS_UNCONFIRMED || cnt-- > 0)
    541      0    stevel 				sctp_send_heartbeat(sctp, fp);
    542      0    stevel 		}
    543   4818    kcpoon set_expiry:
    544      0    stevel 		if (fp->hb_expiry < earliest_expiry || earliest_expiry == 0)
    545      0    stevel 			earliest_expiry = fp->hb_expiry;
    546      0    stevel 	}
    547      0    stevel 	if (sctp->sctp_autoclose != 0) {
    548      0    stevel 		int64_t expire;
    549      0    stevel 
    550      0    stevel 		expire = sctp->sctp_active + sctp->sctp_autoclose;
    551      0    stevel 
    552      0    stevel 		if (expire <= now) {
    553      0    stevel 			dprint(3, ("sctp_heartbeat_timer: autoclosing\n"));
    554      0    stevel 			sctp_send_shutdown(sctp, 0);
    555      0    stevel 			return;
    556      0    stevel 		}
    557      0    stevel 		if (expire < earliest_expiry || earliest_expiry == 0)
    558      0    stevel 			earliest_expiry = expire;
    559      0    stevel 	}
    560      0    stevel 
    561      0    stevel 	earliest_expiry -= now;
    562      0    stevel 	if (earliest_expiry < 0)
    563      0    stevel 		earliest_expiry = 1;
    564      0    stevel 	sctp_timer(sctp, sctp->sctp_heartbeat_mp, earliest_expiry);
    565      0    stevel }
    566      0    stevel 
    567      0    stevel void
    568      0    stevel sctp_rexmit_timer(sctp_t *sctp, sctp_faddr_t *fp)
    569      0    stevel {
    570      0    stevel 	mblk_t 		*mp;
    571   3448  dh155122 	sctp_stack_t	*sctps = sctp->sctp_sctps;
    572      0    stevel 
    573      0    stevel 	ASSERT(fp != NULL);
    574      0    stevel 
    575      0    stevel 	dprint(3, ("sctp_timer: faddr=%x:%x:%x:%x\n",
    576      0    stevel 	    SCTP_PRINTADDR(fp->faddr)));
    577      0    stevel 
    578      0    stevel 	fp->timer_running = 0;
    579      0    stevel 
    580      0    stevel 	/* Check is we've reached the max for retries */
    581      0    stevel 	if (sctp->sctp_state < SCTPS_ESTABLISHED) {
    582      0    stevel 		if (fp->strikes >= sctp->sctp_max_init_rxt) {
    583      0    stevel 			/* time to give up */
    584   3448  dh155122 			BUMP_MIB(&sctps->sctps_mib, sctpAborted);
    585   3448  dh155122 			BUMP_MIB(&sctps->sctps_mib, sctpTimRetransDrop);
    586      0    stevel 			sctp_assoc_event(sctp, SCTP_CANT_STR_ASSOC, 0, NULL);
    587      0    stevel 			sctp_clean_death(sctp, sctp->sctp_client_errno ?
    588      0    stevel 			    sctp->sctp_client_errno : ETIMEDOUT);
    589      0    stevel 			return;
    590      0    stevel 		}
    591      0    stevel 	} else if (sctp->sctp_state >= SCTPS_ESTABLISHED) {
    592      0    stevel 		if (sctp->sctp_strikes >= sctp->sctp_pa_max_rxt) {
    593      0    stevel 			/* time to give up */
    594   3448  dh155122 			BUMP_MIB(&sctps->sctps_mib, sctpAborted);
    595   3448  dh155122 			BUMP_MIB(&sctps->sctps_mib, sctpTimRetransDrop);
    596      0    stevel 			sctp_assoc_event(sctp, SCTP_COMM_LOST, 0, NULL);
    597      0    stevel 			sctp_clean_death(sctp, sctp->sctp_client_errno ?
    598      0    stevel 			    sctp->sctp_client_errno : ETIMEDOUT);
    599      0    stevel 			return;
    600      0    stevel 		}
    601      0    stevel 	}
    602      0    stevel 
    603      0    stevel 	if (fp->strikes >= fp->max_retr) {
    604      0    stevel 		if (sctp_faddr_dead(sctp, fp, SCTP_FADDRS_DOWN) == -1) {
    605      0    stevel 			return;
    606      0    stevel 		}
    607      0    stevel 	}
    608      0    stevel 
    609      0    stevel 	switch (sctp->sctp_state) {
    610   4818    kcpoon 	case SCTPS_SHUTDOWN_RECEIVED:
    611   4818    kcpoon 		(void) sctp_shutdown_received(sctp, NULL, B_FALSE, B_TRUE,
    612   4818    kcpoon 		    NULL);
    613      0    stevel 
    614      0    stevel 		/* FALLTHRU */
    615   4818    kcpoon 	case SCTPS_ESTABLISHED:
    616      0    stevel 	case SCTPS_SHUTDOWN_PENDING:
    617      0    stevel 		if (sctp->sctp_xmit_head == NULL &&
    618      0    stevel 		    sctp->sctp_xmit_unsent == NULL) {
    619      0    stevel 			/* Nothing to retransmit */
    620      0    stevel 			if (sctp->sctp_state == SCTPS_SHUTDOWN_PENDING) {
    621      0    stevel 				sctp_send_shutdown(sctp, 1);
    622      0    stevel 			}
    623      0    stevel 			return;
    624      0    stevel 		}
    625      0    stevel 
    626   3448  dh155122 		BUMP_MIB(&sctps->sctps_mib, sctpTimRetrans);
    627      0    stevel 
    628      0    stevel 		sctp_rexmit(sctp, fp);
    629      0    stevel 		/*
    630      0    stevel 		 * sctp_rexmit() will increase the strikes and restart the
    631      0    stevel 		 * timer, so return here.
    632      0    stevel 		 */
    633      0    stevel 		return;
    634      0    stevel 	case SCTPS_COOKIE_WAIT:
    635      0    stevel 		BUMP_LOCAL(sctp->sctp_T1expire);
    636      0    stevel rxmit_init:
    637      0    stevel 		/* retransmit init */
    638    432  vi117747 		/*
    639    432  vi117747 		 * We don't take the conn hash lock here since the source
    640    432  vi117747 		 * address list won't be modified (it would have been done
    641    432  vi117747 		 * the first time around).
    642    432  vi117747 		 */
    643  11042      Erik 		mp = sctp_init_mp(sctp, fp);
    644      0    stevel 		if (mp != NULL) {
    645   3448  dh155122 			BUMP_MIB(&sctps->sctps_mib, sctpTimRetrans);
    646  11042      Erik 			(void) conn_ip_output(mp, fp->ixa);
    647  11042      Erik 			BUMP_LOCAL(sctp->sctp_opkts);
    648      0    stevel 		}
    649      0    stevel 		break;
    650  11042      Erik 	case SCTPS_COOKIE_ECHOED:
    651      0    stevel 		BUMP_LOCAL(sctp->sctp_T1expire);
    652      0    stevel 		if (sctp->sctp_cookie_mp == NULL) {
    653      0    stevel 			sctp->sctp_state = SCTPS_COOKIE_WAIT;
    654      0    stevel 			goto rxmit_init;
    655      0    stevel 		}
    656      0    stevel 		mp = dupmsg(sctp->sctp_cookie_mp);
    657      0    stevel 		if (mp == NULL)
    658      0    stevel 			break;
    659  11042      Erik 		(void) conn_ip_output(mp, fp->ixa);
    660  11042      Erik 		BUMP_LOCAL(sctp->sctp_opkts);
    661   3448  dh155122 		BUMP_MIB(&sctps->sctps_mib, sctpTimRetrans);
    662      0    stevel 		break;
    663      0    stevel 	case SCTPS_SHUTDOWN_SENT:
    664      0    stevel 		BUMP_LOCAL(sctp->sctp_T2expire);
    665      0    stevel 		sctp_send_shutdown(sctp, 1);
    666   3448  dh155122 		BUMP_MIB(&sctps->sctps_mib, sctpTimRetrans);
    667      0    stevel 		break;
    668      0    stevel 	case SCTPS_SHUTDOWN_ACK_SENT:
    669      0    stevel 		/* We shouldn't have any more outstanding data */
    670      0    stevel 		ASSERT(sctp->sctp_xmit_head == NULL);
    671      0    stevel 		ASSERT(sctp->sctp_xmit_unsent == NULL);
    672      0    stevel 
    673      0    stevel 		BUMP_LOCAL(sctp->sctp_T2expire);
    674   1735    kcpoon 		(void) sctp_shutdown_received(sctp, NULL, B_FALSE, B_TRUE,
    675   1735    kcpoon 		    NULL);
    676   3448  dh155122 		BUMP_MIB(&sctps->sctps_mib, sctpTimRetrans);
    677      0    stevel 		break;
    678      0    stevel 	default:
    679      0    stevel 		ASSERT(0);
    680      0    stevel 		break;
    681      0    stevel 	}
    682      0    stevel 
    683      0    stevel 	fp->strikes++;
    684      0    stevel 	sctp->sctp_strikes++;
    685  10212    George 	SCTP_CALC_RXT(sctp, fp);
    686      0    stevel 
    687      0    stevel 	SCTP_FADDR_TIMER_RESTART(sctp, fp, fp->rto);
    688      0    stevel }
    689      0    stevel 
    690      0    stevel /*
    691      0    stevel  * RTO calculation. timesent and now are both in ms.
    692      0    stevel  */
    693      0    stevel void
    694      0    stevel sctp_update_rtt(sctp_t *sctp, sctp_faddr_t *fp, clock_t delta)
    695      0    stevel {
    696      0    stevel 	int rtt;
    697      0    stevel 
    698      0    stevel 	/* Calculate the RTT in ms */
    699      0    stevel 	rtt = (int)delta;
    700      0    stevel 	rtt = rtt > 0 ? rtt : 1;
    701      0    stevel 
    702   1676       jpk 	dprint(5, ("sctp_update_rtt: fp = %p, rtt = %d\n", (void *)fp, rtt));
    703      0    stevel 
    704      0    stevel 	/* Is this the first RTT measurement? */
    705      0    stevel 	if (fp->srtt == -1) {
    706      0    stevel 		fp->srtt = rtt;
    707      0    stevel 		fp->rttvar = rtt / 2;
    708      0    stevel 		fp->rto = 3 * rtt; /* == rtt + 4 * rttvar ( == rtt / 2) */
    709      0    stevel 	} else {
    710      0    stevel 		int abs;
    711      0    stevel 		/*
    712      0    stevel 		 * Versions of the RTO equations that use fixed-point math.
    713      0    stevel 		 * alpha and beta are NOT tunable in this implementation,
    714      0    stevel 		 * and so are hard-coded in. alpha = 1/8, beta = 1/4.
    715      0    stevel 		 */
    716      0    stevel 		abs = fp->srtt - rtt;
    717      0    stevel 		abs = abs >= 0 ? abs : -abs;
    718      0    stevel 		fp->rttvar = (3 * fp->rttvar + abs) >> 2;
    719      0    stevel 		fp->rttvar = fp->rttvar != 0 ? fp->rttvar : 1;
    720      0    stevel 
    721      0    stevel 		fp->srtt = (7 * fp->srtt + rtt) >> 3;
    722      0    stevel 		fp->rto = fp->srtt + 4 * fp->rttvar;
    723      0    stevel 	}
    724      0    stevel 
    725      0    stevel 	dprint(5, ("sctp_update_rtt: srtt = %d, rttvar = %d, rto = %d\n",
    726      0    stevel 	    fp->srtt, fp->rttvar, fp->rto));
    727      0    stevel 
    728      0    stevel 	/* Bound the RTO by configured min and max values */
    729      0    stevel 	if (fp->rto < sctp->sctp_rto_min) {
    730      0    stevel 		fp->rto = sctp->sctp_rto_min;
    731      0    stevel 	}
    732      0    stevel 	if (fp->rto > sctp->sctp_rto_max) {
    733      0    stevel 		fp->rto = sctp->sctp_rto_max;
    734      0    stevel 	}
    735      0    stevel 
    736  10212    George 	SCTP_MAX_RTO(sctp, fp);
    737      0    stevel 	fp->rtt_updates++;
    738      0    stevel }
    739      0    stevel 
    740      0    stevel void
    741      0    stevel sctp_free_faddr_timers(sctp_t *sctp)
    742      0    stevel {
    743      0    stevel 	sctp_faddr_t *fp;
    744      0    stevel 
    745      0    stevel 	for (fp = sctp->sctp_faddrs; fp != NULL; fp = fp->next) {
    746      0    stevel 		if (fp->timer_mp != NULL) {
    747      0    stevel 			sctp_timer_free(fp->timer_mp);
    748      0    stevel 			fp->timer_mp = NULL;
    749      0    stevel 			fp->timer_running = 0;
    750      0    stevel 		}
    751      0    stevel 		if (fp->rc_timer_mp != NULL) {
    752      0    stevel 			sctp_timer_free(fp->rc_timer_mp);
    753      0    stevel 			fp->rc_timer_mp = NULL;
    754      0    stevel 			fp->rc_timer_running = 0;
    755      0    stevel 		}
    756      0    stevel 	}
    757      0    stevel }
    758      0    stevel 
    759      0    stevel void
    760      0    stevel sctp_stop_faddr_timers(sctp_t *sctp)
    761      0    stevel {
    762      0    stevel 	sctp_faddr_t *fp;
    763      0    stevel 
    764      0    stevel 	for (fp = sctp->sctp_faddrs; fp != NULL; fp = fp->next) {
    765      0    stevel 		SCTP_FADDR_TIMER_STOP(fp);
    766      0    stevel 		SCTP_FADDR_RC_TIMER_STOP(fp);
    767      0    stevel 	}
    768      0    stevel }
    769      0    stevel 
    770      0    stevel void
    771      0    stevel sctp_process_timer(sctp_t *sctp)
    772      0    stevel {
    773      0    stevel 	mblk_t *mp;
    774      0    stevel 
    775      0    stevel 	ASSERT(sctp->sctp_running);
    776      0    stevel 	ASSERT(MUTEX_HELD(&sctp->sctp_lock));
    777      0    stevel 	while ((mp = sctp->sctp_timer_mp) != NULL) {
    778      0    stevel 		ASSERT(DB_TYPE(mp) == M_PCSIG);
    779      0    stevel 		/*
    780      0    stevel 		 * Since the timer mblk can be freed in sctp_timer_call(),
    781      0    stevel 		 * we need to grab the b_cont before that.
    782      0    stevel 		 */
    783      0    stevel 		sctp->sctp_timer_mp = mp->b_cont;
    784      0    stevel 		mp->b_cont = NULL;
    785   7444    George 		/*
    786   7444    George 		 * We have a reference on the sctp, the lock must be
    787   7444    George 		 * dropped to avoid deadlocks with functions potentially
    788   7444    George 		 * called in this context which in turn call untimeout().
    789   7444    George 		 */
    790   7444    George 		mutex_exit(&sctp->sctp_lock);
    791      0    stevel 		sctp_timer_call(sctp, mp);
    792   7444    George 		mutex_enter(&sctp->sctp_lock);
    793      0    stevel 	}
    794      0    stevel 	SCTP_REFRELE(sctp);
    795      0    stevel }
    796