Пример #1
0
/*
 * Reset any state related to transmitted chunks.
 */
void
sctp_congest_reset(sctp_t *sctp)
{
	sctp_faddr_t	*fp;
	sctp_stack_t	*sctps = sctp->sctp_sctps;
	mblk_t		*mp;

	for (fp = sctp->sctp_faddrs; fp != NULL; fp = fp->next) {
		fp->ssthresh = sctps->sctps_initial_mtu;
		SET_CWND(fp, fp->sfa_pmss, sctps->sctps_slow_start_initial);
		fp->suna = 0;
		fp->pba = 0;
	}
	/*
	 * Clean up the transmit list as well since we have reset accounting
	 * on all the fps. Send event upstream, if required.
	 */
	while ((mp = sctp->sctp_xmit_head) != NULL) {
		sctp->sctp_xmit_head = mp->b_next;
		mp->b_next = NULL;
		if (sctp->sctp_xmit_head != NULL)
			sctp->sctp_xmit_head->b_prev = NULL;
		sctp_sendfail_event(sctp, mp, 0, B_TRUE);
	}
	sctp->sctp_xmit_head = NULL;
	sctp->sctp_xmit_tail = NULL;
	sctp->sctp_xmit_unacked = NULL;

	sctp->sctp_unacked = 0;
	/*
	 * Any control message as well. We will clean-up this list as well.
	 * This contains any pending ASCONF request that we have queued/sent.
	 * If we do get an ACK we will just drop it. However, given that
	 * we are restarting chances are we aren't going to get any.
	 */
	if (sctp->sctp_cxmit_list != NULL)
		sctp_asconf_free_cxmit(sctp, NULL);
	sctp->sctp_cxmit_list = NULL;
	sctp->sctp_cchunk_pend = 0;

	sctp->sctp_rexmitting = B_FALSE;
	sctp->sctp_rxt_nxttsn = 0;
	sctp->sctp_rxt_maxtsn = 0;

	sctp->sctp_zero_win_probe = B_FALSE;
}
Пример #2
0
/*
 * Returns 0 on non-fatal error, otherwise a system error on fatal
 * error.
 */
int
sctp_handle_error(sctp_t *sctp, sctp_hdr_t *sctph, sctp_chunk_hdr_t *ch,
    mblk_t *mp, ip_recv_attr_t *ira)
{
	sctp_parm_hdr_t *errh;
	sctp_chunk_hdr_t *uch;

	if (ch->sch_len == htons(sizeof (*ch))) {
		/* no error cause given */
		return (0);
	}
	errh = (sctp_parm_hdr_t *)(ch + 1);
	sctp_error_event(sctp, ch, B_FALSE);

	switch (errh->sph_type) {
	/*
	 * Both BAD_SID and NO_USR_DATA errors
	 * indicate a serious bug in our stack,
	 * so complain and abort the association.
	 */
	case SCTP_ERR_BAD_SID:
		cmn_err(CE_WARN, "BUG! send to invalid SID");
		sctp_send_abort(sctp, sctph->sh_verf, 0, NULL, 0, mp, 0, 0,
		    ira);
		return (ECONNABORTED);
	case SCTP_ERR_NO_USR_DATA:
		cmn_err(CE_WARN, "BUG! no usr data");
		sctp_send_abort(sctp, sctph->sh_verf, 0, NULL, 0, mp, 0, 0,
		    ira);
		return (ECONNABORTED);
	case SCTP_ERR_UNREC_CHUNK:
		/* Pull out the unrecognized chunk type */
		if (ntohs(errh->sph_len) < (sizeof (*errh) + sizeof (*uch))) {
			/* Not enough to process */
			return (0);
		}
		uch = (sctp_chunk_hdr_t *)(errh + 1);
		if (uch->sch_id == CHUNK_ASCONF) {
			/* Turn on ASCONF sending */
			sctp->sctp_understands_asconf = B_FALSE;
			/*
			 * Hand off to asconf to clear out the unacked
			 * asconf chunk.
			 */
			if (ntohs(uch->sch_len) !=
			    (ntohs(errh->sph_len) - sizeof (*errh))) {
				/* malformed */
				dprint(0, ("Malformed Unrec Chunk error\n"));
				return (0);
			}
			sctp_asconf_free_cxmit(sctp, uch);
			return (0);
		}
		/* Else drop it */
		break;
	default:
		break;
	}

	return (0);
}