Mercurial > illumos > illumos-gate
changeset 4964:a9481fc76e88
6340684 SCTP does "packet amplification"
6596850 Processing malformed INIT chunk causes panic
author | kcpoon |
---|---|
date | Thu, 30 Aug 2007 08:00:29 -0700 |
parents | ce6338ba4a73 |
children | 4c42cf7a5c57 |
files | usr/src/cmd/mdb/common/modules/sctp/sctp.c usr/src/uts/common/inet/sctp/sctp.c usr/src/uts/common/inet/sctp/sctp_common.c usr/src/uts/common/inet/sctp/sctp_error.c usr/src/uts/common/inet/sctp/sctp_impl.h usr/src/uts/common/inet/sctp/sctp_input.c usr/src/uts/common/inet/sctp/sctp_timer.c |
diffstat | 7 files changed, 201 insertions(+), 73 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/cmd/mdb/common/modules/sctp/sctp.c Thu Aug 30 07:43:53 2007 -0700 +++ b/usr/src/cmd/mdb/common/modules/sctp/sctp.c Thu Aug 30 08:00:29 2007 -0700 @@ -785,7 +785,9 @@ sctp.sctp_recovery_tsn, sctp.sctp_adv_pap); mdb_printf("num_ostr\t%?hu\tostrcntrs\t%?p\n", sctp.sctp_num_ostr, sctp.sctp_ostrcntrs); - mdb_printf("pad_mp\t\t%?p\n", sctp.sctp_pad_mp); + mdb_printf("pad_mp\t\t%?p\terr_chunks\t%?p\n", + sctp.sctp_pad_mp, sctp.sctp_err_chunks); + mdb_printf("err_len\t\t%?u\n", sctp.sctp_err_len); mdb_printf("%<b>Default Send Parameters%</b>\n"); mdb_printf("def_stream\t%?u\tdef_flags\t%?x\n",
--- a/usr/src/uts/common/inet/sctp/sctp.c Thu Aug 30 07:43:53 2007 -0700 +++ b/usr/src/uts/common/inet/sctp/sctp.c Thu Aug 30 08:00:29 2007 -0700 @@ -753,6 +753,12 @@ sctp->sctp_shutdown_faddr = NULL; + if (sctp->sctp_err_chunks != NULL) { + freemsg(sctp->sctp_err_chunks); + sctp->sctp_err_chunks = NULL; + sctp->sctp_err_len = 0; + } + /* Clear all the bitfields. */ bzero(&sctp->sctp_bits, sizeof (sctp->sctp_bits));
--- a/usr/src/uts/common/inet/sctp/sctp_common.c Thu Aug 30 07:43:53 2007 -0700 +++ b/usr/src/uts/common/inet/sctp/sctp_common.c Thu Aug 30 08:00:29 2007 -0700 @@ -1554,7 +1554,7 @@ sctp_secure_restart_check(mblk_t *pkt, sctp_chunk_hdr_t *ich, uint32_t ports, int sleep, sctp_stack_t *sctps) { - sctp_faddr_t *fp, *fpa, *fphead = NULL; + sctp_faddr_t *fp, *fphead = NULL; sctp_parm_hdr_t *ph; ssize_t remaining; int isv4; @@ -1589,6 +1589,8 @@ ph = (sctp_parm_hdr_t *)(init + 1); while (ph != NULL) { + sctp_faddr_t *fpa = NULL; + /* params will have already been byteordered when validating */ if (ph->sph_type == htons(PARM_ADDR4)) { if (remaining >= PARM_ADDR4_LEN) { @@ -1597,7 +1599,7 @@ (ph + 1), &addr); fpa = kmem_cache_alloc(sctp_kmem_faddr_cache, sleep); - if (!fpa) { + if (fpa == NULL) { goto done; } bzero(fpa, sizeof (*fpa)); @@ -1608,7 +1610,7 @@ if (remaining >= PARM_ADDR6_LEN) { fpa = kmem_cache_alloc(sctp_kmem_faddr_cache, sleep); - if (!fpa) { + if (fpa == NULL) { goto done; } bzero(fpa, sizeof (*fpa)); @@ -1616,18 +1618,14 @@ sizeof (fpa->faddr)); fpa->next = NULL; } - } else { - /* else not addr param; skip */ - fpa = NULL; } /* link in the new addr, if it was an addr param */ - if (fpa) { - if (!fphead) { + if (fpa != NULL) { + if (fphead == NULL) { fphead = fpa; - fp = fphead; } else { - fp->next = fpa; - fp = fpa; + fpa->next = fphead; + fphead = fpa; } } @@ -1644,10 +1642,10 @@ * in the list */ fp = sctp_lookup_faddr_nosctp(fphead, hdraddr); - if (!fp) { + if (fp == NULL) { /* not included; add it now */ fp = kmem_cache_alloc(sctp_kmem_faddr_cache, sleep); - if (!fp) { + if (fp == NULL) { goto done; } bzero(fp, sizeof (*fp));
--- a/usr/src/uts/common/inet/sctp/sctp_error.c Thu Aug 30 07:43:53 2007 -0700 +++ b/usr/src/uts/common/inet/sctp/sctp_error.c Thu Aug 30 08:00:29 2007 -0700 @@ -130,7 +130,7 @@ len = 0; } if ((len = sctp_link_abort(mp, SCTP_ERR_USER_ABORT, cause, len, 0, - tbit)) < 0) { + tbit)) < 0) { freemsg(mp); return; } @@ -335,8 +335,8 @@ sctp_parm_hdr_t *eph; int pad; - if ((pad = len % 4) != 0) { - pad = 4 - pad; + if ((pad = len % SCTP_ALIGN) != 0) { + pad = SCTP_ALIGN - pad; } elen = sizeof (*ecp) + sizeof (*eph) + len; @@ -368,28 +368,88 @@ return (emp); } +/* + * Called from sctp_input_data() to add one error chunk to the error + * chunks list. The error chunks list will be processed at the end + * of sctp_input_data() by calling sctp_process_err(). + */ void -sctp_send_err(sctp_t *sctp, mblk_t *emp, sctp_faddr_t *dest) +sctp_add_err(sctp_t *sctp, uint16_t serror, void *details, size_t len, + sctp_faddr_t *dest) { - mblk_t *sendmp; - sctp_stack_t *sctps = sctp->sctp_sctps; + sctp_stack_t *sctps = sctp->sctp_sctps; + mblk_t *emp; + uint32_t emp_len; + uint32_t mss; + mblk_t *sendmp; + sctp_faddr_t *fp; - sendmp = sctp_make_sack(sctp, dest, NULL); - if (sendmp != NULL) { - linkb(sendmp, emp); + emp = sctp_make_err(sctp, serror, details, len); + if (emp == NULL) + return; + emp_len = MBLKL(emp); + if (sctp->sctp_err_chunks != NULL) { + fp = SCTP_CHUNK_DEST(sctp->sctp_err_chunks); } else { - sendmp = sctp_make_mp(sctp, dest, 0); - if (sendmp == NULL) { + fp = dest; + SCTP_SET_CHUNK_DEST(emp, dest); + } + mss = fp->sfa_pmss; + + /* + * If the current output packet cannot include the new error chunk, + * send out the current packet and then add the new error chunk + * to the new output packet. + */ + if (sctp->sctp_err_len + emp_len > mss) { + if ((sendmp = sctp_make_mp(sctp, fp, 0)) == NULL) { SCTP_KSTAT(sctps, sctp_send_err_failed); - freemsg(emp); + /* Just free the latest error chunk. */ + freeb(emp); return; } - sendmp->b_cont = emp; + sendmp->b_cont = sctp->sctp_err_chunks; + sctp_set_iplen(sctp, sendmp); + sctp_add_sendq(sctp, sendmp); + + sctp->sctp_err_chunks = emp; + sctp->sctp_err_len = emp_len; + SCTP_SET_CHUNK_DEST(emp, dest); + } else { + if (sctp->sctp_err_chunks != NULL) + linkb(sctp->sctp_err_chunks, emp); + else + sctp->sctp_err_chunks = emp; + sctp->sctp_err_len += emp_len; } + /* Assume that we will send it out... */ BUMP_LOCAL(sctp->sctp_obchunks); +} +/* + * Called from sctp_input_data() to send out error chunks created during + * the processing of all the chunks in an incoming packet. + */ +void +sctp_process_err(sctp_t *sctp) +{ + sctp_stack_t *sctps = sctp->sctp_sctps; + mblk_t *errmp; + mblk_t *sendmp; + + ASSERT(sctp->sctp_err_chunks != NULL); + errmp = sctp->sctp_err_chunks; + if ((sendmp = sctp_make_mp(sctp, SCTP_CHUNK_DEST(errmp), 0)) == NULL) { + SCTP_KSTAT(sctps, sctp_send_err_failed); + freemsg(errmp); + goto done; + } + sendmp->b_cont = errmp; sctp_set_iplen(sctp, sendmp); sctp_add_sendq(sctp, sendmp); +done: + sctp->sctp_err_chunks = NULL; + sctp->sctp_err_len = 0; } /*
--- a/usr/src/uts/common/inet/sctp/sctp_impl.h Thu Aug 30 07:43:53 2007 -0700 +++ b/usr/src/uts/common/inet/sctp/sctp_impl.h Thu Aug 30 08:00:29 2007 -0700 @@ -933,6 +933,8 @@ uint32_t sctp_rxt_maxtsn; /* Max TSN sent at time out */ int sctp_pd_point; /* Partial delivery point */ + mblk_t *sctp_err_chunks; /* Error chunks */ + uint32_t sctp_err_len; /* Total error chunks length */ } sctp_t; #endif /* (defined(_KERNEL) || defined(_KMEMUSER)) */ @@ -940,6 +942,8 @@ extern void sctp_ack_timer(sctp_t *); extern size_t sctp_adaption_code_param(sctp_t *, uchar_t *); extern void sctp_adaption_event(sctp_t *); +extern void sctp_add_err(sctp_t *, uint16_t, void *, size_t, + sctp_faddr_t *); extern int sctp_add_faddr(sctp_t *, in6_addr_t *, int, boolean_t); extern boolean_t sctp_add_ftsn_set(sctp_ftsn_set_t **, sctp_faddr_t *, mblk_t *, uint_t *, uint32_t *); @@ -1073,6 +1077,7 @@ extern void sctp_partial_delivery_event(sctp_t *); extern int sctp_process_cookie(sctp_t *, sctp_chunk_hdr_t *, mblk_t *, sctp_init_chunk_t **, sctp_hdr_t *, int *, in6_addr_t *); +extern void sctp_process_err(sctp_t *); extern void sctp_process_heartbeat(sctp_t *, sctp_chunk_hdr_t *); extern void sctp_process_sendq(sctp_t *); extern void sctp_process_timer(sctp_t *); @@ -1086,14 +1091,13 @@ extern void sctp_rexmit_timer(sctp_t *, sctp_faddr_t *); extern sctp_faddr_t *sctp_rotate_faddr(sctp_t *, sctp_faddr_t *); -extern void sctp_sack(sctp_t *, mblk_t *); +extern boolean_t sctp_sack(sctp_t *, mblk_t *); extern int sctp_secure_restart_check(mblk_t *, sctp_chunk_hdr_t *, uint32_t, int, sctp_stack_t *); extern void sctp_send_abort(sctp_t *, uint32_t, uint16_t, char *, size_t, mblk_t *, int, boolean_t); extern void sctp_send_cookie_ack(sctp_t *); extern void sctp_send_cookie_echo(sctp_t *, sctp_chunk_hdr_t *, mblk_t *); -extern void sctp_send_err(sctp_t *, mblk_t *, sctp_faddr_t *); extern void sctp_send_initack(sctp_t *, sctp_hdr_t *, sctp_chunk_hdr_t *, mblk_t *); extern void sctp_send_shutdown(sctp_t *, int);
--- a/usr/src/uts/common/inet/sctp/sctp_input.c Thu Aug 30 07:43:53 2007 -0700 +++ b/usr/src/uts/common/inet/sctp/sctp_input.c Thu Aug 30 08:00:29 2007 -0700 @@ -383,8 +383,8 @@ /* If app asked for hopbyhop headers and it has changed ... */ if ((sctp->sctp_ipv6_recvancillary & SCTP_IPV6_RECVHOPOPTS) && ip_cmpbuf(sctp->sctp_hopopts, sctp->sctp_hopoptslen, - (ipp->ipp_fields & IPPF_HOPOPTS), - ipp->ipp_hopopts, ipp->ipp_hopoptslen)) { + (ipp->ipp_fields & IPPF_HOPOPTS), + ipp->ipp_hopopts, ipp->ipp_hopoptslen)) { optlen += sizeof (*cmsg) + ipp->ipp_hopoptslen - sctp->sctp_v6label_len; if (hdrlen == 0) @@ -399,8 +399,8 @@ /* If app asked for dst headers before routing headers ... */ if ((sctp->sctp_ipv6_recvancillary & SCTP_IPV6_RECVRTDSTOPTS) && ip_cmpbuf(sctp->sctp_rtdstopts, sctp->sctp_rtdstoptslen, - (ipp->ipp_fields & IPPF_RTDSTOPTS), - ipp->ipp_rtdstopts, ipp->ipp_rtdstoptslen)) { + (ipp->ipp_fields & IPPF_RTDSTOPTS), + ipp->ipp_rtdstopts, ipp->ipp_rtdstoptslen)) { optlen += sizeof (*cmsg) + ipp->ipp_rtdstoptslen; if (hdrlen == 0) hdrlen = sizeof (struct T_unitdata_ind); @@ -430,8 +430,8 @@ /* If app asked for dest headers and it has changed ... */ if ((sctp->sctp_ipv6_recvancillary & SCTP_IPV6_RECVDSTOPTS) && ip_cmpbuf(sctp->sctp_dstopts, sctp->sctp_dstoptslen, - (ipp->ipp_fields & IPPF_DSTOPTS), - ipp->ipp_dstopts, ipp->ipp_dstoptslen)) { + (ipp->ipp_fields & IPPF_DSTOPTS), + ipp->ipp_dstopts, ipp->ipp_dstoptslen)) { optlen += sizeof (*cmsg) + ipp->ipp_dstoptslen; if (hdrlen == 0) hdrlen = sizeof (struct T_unitdata_ind); @@ -1181,7 +1181,6 @@ { sctp_data_hdr_t *dc; mblk_t *dmp, *pmp; - mblk_t *errmp; sctp_instr_t *instr; int ubit; int isfrag; @@ -1209,7 +1208,6 @@ sctp->sctp_force_sack = 1; \ } - errmp = NULL; dmp = NULL; dc = (sctp_data_hdr_t *)ch; @@ -1231,7 +1229,8 @@ for (sp = sctp->sctp_sack_info; sp; sp = sp->next) { if (SEQ_GEQ(tsn, sp->begin) && SEQ_LEQ(tsn, sp->end)) { dprint(4, - ("sctp_data_chunk: dropping dup > cumtsn\n")); + ("sctp_data_chunk: dropping dup > " + "cumtsn\n")); sctp->sctp_force_sack = 1; sctp_add_dup(dc->sdh_tsn, dups); return; @@ -1265,11 +1264,9 @@ /* RESERVED to be ignored at the receiving end */ inval_parm[1] = 0; /* ack and drop it */ - errmp = sctp_make_err(sctp, SCTP_ERR_BAD_SID, - (char *)inval_parm, sizeof (inval_parm)); + sctp_add_err(sctp, SCTP_ERR_BAD_SID, inval_parm, + sizeof (inval_parm), fp); SCTP_ACK_IT(sctp, tsn); - if (errmp != NULL) - sctp_send_err(sctp, errmp, NULL); return; } @@ -1364,7 +1361,7 @@ for (;;) { idc = (sctp_data_hdr_t *)imblk->b_rptr; if (SSN_GT(ntohs(idc->sdh_ssn), - ntohs(dc->sdh_ssn))) { + ntohs(dc->sdh_ssn))) { if (instr->istr_msgs == imblk) { instr->istr_msgs = dmp; dmp->b_next = imblk; @@ -1615,6 +1612,8 @@ sctp_sack_chunk_t *sc; int32_t acks_max; sctp_stack_t *sctps = sctp->sctp_sctps; + uint32_t dups_len; + sctp_faddr_t *fp; if (sctp->sctp_force_sack) { sctp->sctp_force_sack = 0; @@ -1642,8 +1641,36 @@ checks_done: dprint(2, ("sctp_make_sack: acking %x\n", sctp->sctp_ftsn - 1)); + if (dups != NULL) + dups_len = MBLKL(dups); + else + dups_len = 0; slen = sizeof (*sch) + sizeof (*sc) + (sizeof (sctp_sack_frag_t) * sctp->sctp_sack_gaps); + + /* + * If there are error chunks, check and see if we can send the + * SACK chunk and error chunks together in one packet. If not, + * send the error chunks out now. + */ + if (sctp->sctp_err_chunks != NULL) { + fp = SCTP_CHUNK_DEST(sctp->sctp_err_chunks); + if (sctp->sctp_err_len + slen + dups_len > fp->sfa_pmss) { + if ((smp = sctp_make_mp(sctp, fp, 0)) == NULL) { + SCTP_KSTAT(sctps, sctp_send_err_failed); + SCTP_KSTAT(sctps, sctp_send_sack_failed); + freemsg(sctp->sctp_err_chunks); + sctp->sctp_err_chunks = NULL; + sctp->sctp_err_len = 0; + return (NULL); + } + smp->b_cont = sctp->sctp_err_chunks; + sctp_set_iplen(sctp, smp); + sctp_add_sendq(sctp, smp); + sctp->sctp_err_chunks = NULL; + sctp->sctp_err_len = 0; + } + } smp = sctp_make_mp(sctp, sendto, slen); if (smp == NULL) { SCTP_KSTAT(sctps, sctp_send_sack_failed); @@ -1653,18 +1680,26 @@ sctp_fill_sack(sctp, smp->b_wptr, slen); smp->b_wptr += slen; - if (dups) { + if (dups != NULL) { sc = (sctp_sack_chunk_t *)(sch + 1); - sc->ssc_numdups = htons((dups->b_wptr - dups->b_rptr) - / sizeof (uint32_t)); - sch->sch_len = htons(slen + (dups->b_wptr - dups->b_rptr)); + sc->ssc_numdups = htons(MBLKL(dups) / sizeof (uint32_t)); + sch->sch_len = htons(slen + dups_len); smp->b_cont = dups; } + if (sctp->sctp_err_chunks != NULL) { + linkb(smp, sctp->sctp_err_chunks); + sctp->sctp_err_chunks = NULL; + sctp->sctp_err_len = 0; + } return (smp); } -void +/* + * Check and see if we need to send a SACK chunk. If it is needed, + * send it out. Return true if a SACK chunk is sent, false otherwise. + */ +boolean_t sctp_sack(sctp_t *sctp, mblk_t *dups) { mblk_t *smp; @@ -1681,9 +1716,8 @@ /* The caller of sctp_sack() will not free the dups mblk. */ if (dups != NULL) freeb(dups); - return; + return (B_FALSE); } - sctp_set_iplen(sctp, smp); dprint(2, ("sctp_sack: sending to %p %x:%x:%x:%x\n", @@ -1694,6 +1728,7 @@ BUMP_MIB(&sctps->sctps_mib, sctpOutAck); sctp_add_sendq(sctp, smp); + return (B_TRUE); } /* @@ -2061,15 +2096,12 @@ ftsn_entry->ftsn_ssn = ntohs(ftsn_entry->ftsn_ssn); if (ftsn_entry->ftsn_sid >= sctp->sctp_num_istr) { uint16_t inval_parm[2]; - mblk_t *errmp; inval_parm[0] = htons(ftsn_entry->ftsn_sid); /* RESERVED to be ignored at the receiving end */ inval_parm[1] = 0; - errmp = sctp_make_err(sctp, SCTP_ERR_BAD_SID, - (char *)inval_parm, sizeof (inval_parm)); - if (errmp != NULL) - sctp_send_err(sctp, errmp, NULL); + sctp_add_err(sctp, SCTP_ERR_BAD_SID, inval_parm, + sizeof (inval_parm), fp); ftsn_entry++; remaining -= sizeof (*ftsn_entry); continue; @@ -2905,16 +2937,14 @@ static int sctp_strange_chunk(sctp_t *sctp, sctp_chunk_hdr_t *ch, sctp_faddr_t *fp) { - mblk_t *errmp; size_t len; BUMP_LOCAL(sctp->sctp_ibchunks); /* check top two bits for action required */ if (ch->sch_id & 0x40) { /* also matches 0xc0 */ len = ntohs(ch->sch_len); - errmp = sctp_make_err(sctp, SCTP_ERR_UNREC_CHUNK, ch, len); - if (errmp != NULL) - sctp_send_err(sctp, errmp, fp); + sctp_add_err(sctp, SCTP_ERR_UNREC_CHUNK, ch, len, fp); + if ((ch->sch_id & 0xc0) == 0xc0) { /* skip and continue */ return (1); @@ -3473,6 +3503,7 @@ int64_t now; sctp_stack_t *sctps = sctp->sctp_sctps; ip_stack_t *ipst = sctps->sctps_netstack->netstack_ip; + boolean_t hb_already = B_FALSE; if (DB_TYPE(mp) != M_DATA) { ASSERT(DB_TYPE(mp) == M_CTL); @@ -3669,7 +3700,16 @@ } break; case CHUNK_HEARTBEAT: - sctp_return_heartbeat(sctp, ch, mp); + if (!hb_already) { + /* + * In any one packet, there should + * only be one heartbeat chunk. So + * we should not process more than + * once. + */ + sctp_return_heartbeat(sctp, ch, mp); + hb_already = B_TRUE; + } break; case CHUNK_HEARTBEAT_ACK: sctp_process_heartbeat(sctp, ch); @@ -3901,8 +3941,9 @@ sctp_send_cookie_ack(sctp); sctp_stop_faddr_timers(sctp); if (!SCTP_IS_DETACHED(sctp)) { - sctp->sctp_ulp_connected(sctp->sctp_ulpd); - sctp_set_ulp_prop(sctp); + sctp->sctp_ulp_connected( + sctp->sctp_ulpd); + sctp_set_ulp_prop(sctp); } sctp->sctp_state = SCTPS_ESTABLISHED; sctp->sctp_assoc_start_time = (uint32_t)lbolt; @@ -3936,8 +3977,9 @@ switch (ch->sch_id) { case CHUNK_COOKIE_ACK: if (!SCTP_IS_DETACHED(sctp)) { - sctp->sctp_ulp_connected(sctp->sctp_ulpd); - sctp_set_ulp_prop(sctp); + sctp->sctp_ulp_connected( + sctp->sctp_ulpd); + sctp_set_ulp_prop(sctp); } if (sctp->sctp_unacked == 0) sctp_stop_faddr_timers(sctp); @@ -3972,8 +4014,9 @@ sctp_send_cookie_ack(sctp); if (!SCTP_IS_DETACHED(sctp)) { - sctp->sctp_ulp_connected(sctp->sctp_ulpd); - sctp_set_ulp_prop(sctp); + sctp->sctp_ulp_connected( + sctp->sctp_ulpd); + sctp_set_ulp_prop(sctp); } if (sctp->sctp_unacked == 0) sctp_stop_faddr_timers(sctp); @@ -4024,7 +4067,10 @@ break; } case CHUNK_HEARTBEAT: - sctp_return_heartbeat(sctp, ch, mp); + if (!hb_already) { + sctp_return_heartbeat(sctp, ch, mp); + hb_already = B_TRUE; + } break; default: if (sctp_strange_chunk(sctp, ch, fp) == 0) { @@ -4064,7 +4110,10 @@ BUMP_LOCAL(sctp->sctp_ibchunks); break; case CHUNK_HEARTBEAT: - sctp_return_heartbeat(sctp, ch, mp); + if (!hb_already) { + sctp_return_heartbeat(sctp, ch, mp); + hb_already = B_TRUE; + } break; default: if (sctp_strange_chunk(sctp, ch, fp) == 0) { @@ -4096,7 +4145,10 @@ sctp_process_abort(sctp, ch, ECONNRESET); goto done; case CHUNK_HEARTBEAT: - sctp_return_heartbeat(sctp, ch, mp); + if (!hb_already) { + sctp_return_heartbeat(sctp, ch, mp); + hb_already = B_TRUE; + } break; default: if (sctp_strange_chunk(sctp, ch, fp) == 0) { @@ -4125,11 +4177,14 @@ nomorechunks: /* SACK if necessary */ if (gotdata) { + boolean_t sack_sent; + (sctp->sctp_sack_toggle)++; - sctp_sack(sctp, dups); + sack_sent = sctp_sack(sctp, dups); dups = NULL; - if (!sctp->sctp_ack_timer_running) { + /* If a SACK is sent, no need to restart the timer. */ + if (!sack_sent && !sctp->sctp_ack_timer_running) { sctp->sctp_ack_timer_running = B_TRUE; sctp_timer(sctp, sctp->sctp_ack_mp, MSEC_TO_TICK(sctps->sctps_deferred_ack_interval)); @@ -4154,6 +4209,9 @@ freeb(ipsec_mp); freemsg(mp); + if (sctp->sctp_err_chunks != NULL) + sctp_process_err(sctp); + if (wake_eager) { /* * sctp points to newly created control block, need to @@ -4199,7 +4257,7 @@ ((old <= new >> 1) || (old < sctp->sctp_mss))) { sctp->sctp_force_sack = 1; BUMP_MIB(&sctps->sctps_mib, sctpOutWinUpdate); - sctp_sack(sctp, NULL); + (void) sctp_sack(sctp, NULL); old = 1; } else { old = 0;
--- a/usr/src/uts/common/inet/sctp/sctp_timer.c Thu Aug 30 07:43:53 2007 -0700 +++ b/usr/src/uts/common/inet/sctp/sctp_timer.c Thu Aug 30 08:00:29 2007 -0700 @@ -376,7 +376,7 @@ sctp->sctp_ack_timer_running = 0; sctp->sctp_sack_toggle = sctps->sctps_deferred_acks_max; BUMP_MIB(&sctps->sctps_mib, sctpOutAckDelayed); - sctp_sack(sctp, NULL); + (void) sctp_sack(sctp, NULL); } /*