- Bug fix managing congestion parameter on immediate
retransmittion by handover event (fast mobility code) - Fixed problem of mobility code which is caused by remaining parameters in the deleted primary destination. - Add a missing lock. When a peer sends an INIT, and while we are processing it to send an INIT-ACK the socket is closed, we did not hold a lock to keep the socket from going away. Add protection for this case. - Fix so that arwnd is alway uses the minimal rwnd if the user has set the socket buffer smaller. Found this when the test org decided to see what happens when you set in a rwnd of 10 bytes (which is not allowed per RFC .. 4k is minimum). - Fixes so a cookie-echo ootb will NOT cause an abort to be sent. This was happening in a MPI collision case. - Examined all panics and unless there was no recovery, moved any that were not already to INVARANTS. Approved by: re@freebsd.org (gnn)
This commit is contained in:
parent
55aaf894e8
commit
d55b0b1b09
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=172396
@ -1018,7 +1018,6 @@ sctp_move_chunks_from_deleted_prim(struct sctp_tcb *stcb, struct sctp_nets *dst)
|
||||
|
||||
}
|
||||
|
||||
extern int cur_oerr;
|
||||
|
||||
void
|
||||
sctp_assoc_immediate_retrans(struct sctp_tcb *stcb, struct sctp_nets *dstnet)
|
||||
@ -1044,7 +1043,6 @@ sctp_assoc_immediate_retrans(struct sctp_tcb *stcb, struct sctp_nets *dstnet)
|
||||
stcb->asoc.num_send_timers_up = 0;
|
||||
}
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
cur_oerr = stcb->asoc.overall_error_count;
|
||||
error = sctp_t3rxt_timer(stcb->sctp_ep, stcb,
|
||||
stcb->asoc.deleted_primary);
|
||||
if (error) {
|
||||
@ -1086,9 +1084,16 @@ sctp_net_immediate_retrans(struct sctp_tcb *stcb, struct sctp_nets *net)
|
||||
if (chk->sent < SCTP_DATAGRAM_RESEND) {
|
||||
chk->sent = SCTP_DATAGRAM_RESEND;
|
||||
sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
|
||||
sctp_flight_size_decrease(chk);
|
||||
sctp_total_flight_decrease(stcb, chk);
|
||||
net->marked_retrans++;
|
||||
stcb->asoc.marked_retrans++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (net->marked_retrans) {
|
||||
sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_NOT_LOCKED);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1205,7 +1210,9 @@ sctp_asconf_addr_mgmt_ack(struct sctp_tcb *stcb, struct sctp_ifa *addr,
|
||||
sctp_del_local_addr_restricted(stcb, addr);
|
||||
|
||||
if (sctp_is_mobility_feature_on(stcb->sctp_ep,
|
||||
SCTP_MOBILITY_BASE)) {
|
||||
SCTP_MOBILITY_BASE) ||
|
||||
sctp_is_mobility_feature_on(stcb->sctp_ep,
|
||||
SCTP_MOBILITY_FASTHANDOFF)) {
|
||||
sctp_path_check_and_react(stcb, addr);
|
||||
return;
|
||||
}
|
||||
|
@ -1034,6 +1034,9 @@ __FBSDID("$FreeBSD$");
|
||||
#define SCTP_SO_NOT_LOCKED 0
|
||||
|
||||
|
||||
#define SCTP_HOLDS_LOCK 1
|
||||
#define SCTP_NOT_LOCKED 0
|
||||
|
||||
/*-
|
||||
* For address locks, do we hold the lock?
|
||||
*/
|
||||
|
@ -1571,8 +1571,8 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
asoc->highest_tsn_inside_map, MAX_TSN)) {
|
||||
|
||||
/* Nope not in the valid range dump it */
|
||||
SCTPDBG(SCTP_DEBUG_INDATA1, "My rwnd overrun1:tsn:%lx rwnd %lu sbspace:%ld\n",
|
||||
(u_long)tsn, (u_long)asoc->my_rwnd,
|
||||
SCTPDBG(SCTP_DEBUG_INDATA1, "My rwnd overrun1:tsn:%x rwnd %x sbspace:%x\n",
|
||||
tsn, asoc->my_rwnd,
|
||||
sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv));
|
||||
sctp_set_rwnd(stcb, asoc);
|
||||
if ((asoc->cnt_on_all_streams +
|
||||
@ -2325,7 +2325,12 @@ sctp_sack_check(struct sctp_tcb *stcb, int ok_to_sack, int was_a_gap, int *abort
|
||||
}
|
||||
slide_end = lgap >> 3;
|
||||
if (slide_end < slide_from) {
|
||||
#ifdef INVARIANTS
|
||||
panic("impossible slide");
|
||||
#else
|
||||
printf("impossible slide?\n");
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
distance = (slide_end - slide_from) + 1;
|
||||
if (sctp_logging_level & SCTP_MAP_LOGGING_ENABLE) {
|
||||
|
@ -87,6 +87,12 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
|
||||
|
||||
SCTPDBG(SCTP_DEBUG_INPUT2, "sctp_handle_init: handling INIT tcb:%p\n",
|
||||
stcb);
|
||||
if (stcb == NULL) {
|
||||
SCTP_INP_RLOCK(inp);
|
||||
if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
|
||||
goto outnow;
|
||||
}
|
||||
}
|
||||
op_err = NULL;
|
||||
init = &cp->init;
|
||||
/* First are we accepting? */
|
||||
@ -102,7 +108,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
|
||||
vrf_id);
|
||||
if (stcb)
|
||||
*abort_no_unlock = 1;
|
||||
return;
|
||||
goto outnow;
|
||||
}
|
||||
if (ntohs(cp->ch.chunk_length) < sizeof(struct sctp_init_chunk)) {
|
||||
/* Invalid length */
|
||||
@ -111,7 +117,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
|
||||
vrf_id);
|
||||
if (stcb)
|
||||
*abort_no_unlock = 1;
|
||||
return;
|
||||
goto outnow;
|
||||
}
|
||||
/* validate parameters */
|
||||
if (init->initiate_tag == 0) {
|
||||
@ -121,7 +127,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
|
||||
vrf_id);
|
||||
if (stcb)
|
||||
*abort_no_unlock = 1;
|
||||
return;
|
||||
goto outnow;
|
||||
}
|
||||
if (ntohl(init->a_rwnd) < SCTP_MIN_RWND) {
|
||||
/* invalid parameter... send abort */
|
||||
@ -130,7 +136,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
|
||||
vrf_id);
|
||||
if (stcb)
|
||||
*abort_no_unlock = 1;
|
||||
return;
|
||||
goto outnow;
|
||||
}
|
||||
if (init->num_inbound_streams == 0) {
|
||||
/* protocol error... send abort */
|
||||
@ -139,7 +145,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
|
||||
vrf_id);
|
||||
if (stcb)
|
||||
*abort_no_unlock = 1;
|
||||
return;
|
||||
goto outnow;
|
||||
}
|
||||
if (init->num_outbound_streams == 0) {
|
||||
/* protocol error... send abort */
|
||||
@ -148,7 +154,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
|
||||
vrf_id);
|
||||
if (stcb)
|
||||
*abort_no_unlock = 1;
|
||||
return;
|
||||
goto outnow;
|
||||
}
|
||||
init_limit = offset + ntohs(cp->ch.chunk_length);
|
||||
if (sctp_validate_init_auth_params(m, offset + sizeof(*cp),
|
||||
@ -157,11 +163,16 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
|
||||
sctp_abort_association(inp, stcb, m, iphlen, sh, NULL, vrf_id);
|
||||
if (stcb)
|
||||
*abort_no_unlock = 1;
|
||||
return;
|
||||
goto outnow;
|
||||
}
|
||||
/* send an INIT-ACK w/cookie */
|
||||
SCTPDBG(SCTP_DEBUG_INPUT3, "sctp_handle_init: sending INIT-ACK\n");
|
||||
sctp_send_initiate_ack(inp, stcb, m, iphlen, offset, sh, cp, vrf_id);
|
||||
sctp_send_initiate_ack(inp, stcb, m, iphlen, offset, sh, cp, vrf_id,
|
||||
SCTP_HOLDS_LOCK);
|
||||
outnow:
|
||||
if (stcb == NULL) {
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -495,6 +506,7 @@ sctp_handle_heartbeat_ack(struct sctp_heartbeat_chunk *cp,
|
||||
struct sockaddr_in6 *sin6;
|
||||
struct sctp_nets *r_net;
|
||||
struct timeval tv;
|
||||
int req_prim = 0;
|
||||
|
||||
if (ntohs(cp->ch.chunk_length) != sizeof(struct sctp_heartbeat_chunk)) {
|
||||
/* Invalid length */
|
||||
@ -549,28 +561,7 @@ sctp_handle_heartbeat_ack(struct sctp_heartbeat_chunk *cp,
|
||||
TAILQ_REMOVE(&stcb->asoc.nets, stcb->asoc.primary_destination, sctp_next);
|
||||
TAILQ_INSERT_HEAD(&stcb->asoc.nets, stcb->asoc.primary_destination, sctp_next);
|
||||
}
|
||||
/* Mobility adaptation */
|
||||
if ((sctp_is_mobility_feature_on(stcb->sctp_ep,
|
||||
SCTP_MOBILITY_BASE) ||
|
||||
sctp_is_mobility_feature_on(stcb->sctp_ep,
|
||||
SCTP_MOBILITY_FASTHANDOFF)) &&
|
||||
sctp_is_mobility_feature_on(stcb->sctp_ep,
|
||||
SCTP_MOBILITY_PRIM_DELETED)) {
|
||||
|
||||
sctp_timer_stop(SCTP_TIMER_TYPE_PRIM_DELETED, stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_TIMER + SCTP_LOC_7);
|
||||
if (sctp_is_mobility_feature_on(stcb->sctp_ep,
|
||||
SCTP_MOBILITY_FASTHANDOFF)) {
|
||||
sctp_assoc_immediate_retrans(stcb,
|
||||
stcb->asoc.primary_destination);
|
||||
}
|
||||
if (sctp_is_mobility_feature_on(stcb->sctp_ep,
|
||||
SCTP_MOBILITY_BASE)) {
|
||||
sctp_move_chunks_from_deleted_prim(stcb,
|
||||
stcb->asoc.primary_destination);
|
||||
}
|
||||
sctp_delete_prim_timer(stcb->sctp_ep, stcb,
|
||||
stcb->asoc.deleted_primary);
|
||||
}
|
||||
req_prim = 1;
|
||||
}
|
||||
sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_CONFIRMED,
|
||||
stcb, 0, (void *)r_net, SCTP_SO_NOT_LOCKED);
|
||||
@ -610,6 +601,30 @@ sctp_handle_heartbeat_ack(struct sctp_heartbeat_chunk *cp,
|
||||
}
|
||||
/* Now lets do a RTO with this */
|
||||
r_net->RTO = sctp_calculate_rto(stcb, &stcb->asoc, r_net, &tv, sctp_align_safe_nocopy);
|
||||
/* Mobility adaptation */
|
||||
if (req_prim) {
|
||||
if ((sctp_is_mobility_feature_on(stcb->sctp_ep,
|
||||
SCTP_MOBILITY_BASE) ||
|
||||
sctp_is_mobility_feature_on(stcb->sctp_ep,
|
||||
SCTP_MOBILITY_FASTHANDOFF)) &&
|
||||
sctp_is_mobility_feature_on(stcb->sctp_ep,
|
||||
SCTP_MOBILITY_PRIM_DELETED)) {
|
||||
|
||||
sctp_timer_stop(SCTP_TIMER_TYPE_PRIM_DELETED, stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_TIMER + SCTP_LOC_7);
|
||||
if (sctp_is_mobility_feature_on(stcb->sctp_ep,
|
||||
SCTP_MOBILITY_FASTHANDOFF)) {
|
||||
sctp_assoc_immediate_retrans(stcb,
|
||||
stcb->asoc.primary_destination);
|
||||
}
|
||||
if (sctp_is_mobility_feature_on(stcb->sctp_ep,
|
||||
SCTP_MOBILITY_BASE)) {
|
||||
sctp_move_chunks_from_deleted_prim(stcb,
|
||||
stcb->asoc.primary_destination);
|
||||
}
|
||||
sctp_delete_prim_timer(stcb->sctp_ep, stcb,
|
||||
stcb->asoc.deleted_primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -630,6 +645,15 @@ sctp_handle_abort(struct sctp_abort_chunk *cp,
|
||||
/* notify user of the abort and clean up... */
|
||||
sctp_abort_notification(stcb, 0, SCTP_SO_NOT_LOCKED);
|
||||
/* free the tcb */
|
||||
#if defined(SCTP_PANIC_ON_ABORT)
|
||||
printf("stcb:%p state:%d rport:%d net:%p\n",
|
||||
stcb, stcb->asoc.state, stcb->rport, net);
|
||||
if (!(stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET)) {
|
||||
panic("Received an ABORT");
|
||||
} else {
|
||||
printf("No panic its in state %x closed\n", stcb->asoc.state);
|
||||
}
|
||||
#endif
|
||||
SCTP_STAT_INCR_COUNTER32(sctps_aborted);
|
||||
if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) ||
|
||||
(SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
|
||||
@ -1537,7 +1561,6 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
|
||||
SCTP_STAT_INCR_COUNTER32(sctps_activeestab);
|
||||
else
|
||||
SCTP_STAT_INCR_COUNTER32(sctps_collisionestab);
|
||||
SCTP_STAT_INCR_COUNTER32(sctps_activeestab);
|
||||
SCTP_STAT_INCR_GAUGE32(sctps_currestab);
|
||||
} else if (SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) {
|
||||
SCTP_STAT_INCR_COUNTER32(sctps_restartestab);
|
||||
@ -1548,7 +1571,6 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
|
||||
if (asoc->state & SCTP_STATE_SHUTDOWN_PENDING) {
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
|
||||
stcb->sctp_ep, stcb, asoc->primary_destination);
|
||||
|
||||
}
|
||||
sctp_stop_all_cookie_timers(stcb);
|
||||
sctp_toss_old_cookies(stcb, asoc);
|
||||
|
@ -4612,7 +4612,7 @@ sctp_are_there_new_addresses(struct sctp_association *asoc,
|
||||
void
|
||||
sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
struct mbuf *init_pkt, int iphlen, int offset, struct sctphdr *sh,
|
||||
struct sctp_init_chunk *init_chk, uint32_t vrf_id)
|
||||
struct sctp_init_chunk *init_chk, uint32_t vrf_id, int hold_inp_lock)
|
||||
{
|
||||
struct sctp_association *asoc;
|
||||
struct mbuf *m, *m_at, *m_tmp, *m_cookie, *op_err, *mp_last;
|
||||
@ -4636,6 +4636,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
int abort_flag, padval;
|
||||
int num_ext;
|
||||
int p_len;
|
||||
struct socket *so;
|
||||
|
||||
if (stcb)
|
||||
asoc = &stcb->asoc;
|
||||
@ -4947,6 +4948,9 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
} else {
|
||||
uint32_t vtag, itsn;
|
||||
|
||||
if (hold_inp_lock) {
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
}
|
||||
if (asoc) {
|
||||
atomic_add_int(&asoc->refcnt, 1);
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
@ -4963,12 +4967,22 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
/* get a TSN to use too */
|
||||
initackm_out->msg.init.initial_tsn = htonl(sctp_select_initial_TSN(&inp->sctp_ep));
|
||||
}
|
||||
if (hold_inp_lock) {
|
||||
SCTP_INP_RLOCK(inp);
|
||||
}
|
||||
}
|
||||
/* save away my tag to */
|
||||
stc.my_vtag = initackm_out->msg.init.initiate_tag;
|
||||
|
||||
/* set up some of the credits. */
|
||||
initackm_out->msg.init.a_rwnd = htonl(max(SCTP_SB_LIMIT_RCV(inp->sctp_socket), SCTP_MINIMAL_RWND));
|
||||
so = inp->sctp_socket;
|
||||
if (so == NULL) {
|
||||
/* memory problem */
|
||||
sctp_m_freem(m);
|
||||
return;
|
||||
} else {
|
||||
initackm_out->msg.init.a_rwnd = htonl(max(SCTP_SB_LIMIT_RCV(so), SCTP_MINIMAL_RWND));
|
||||
}
|
||||
/* set what I want */
|
||||
his_limit = ntohs(init_chk->init.num_inbound_streams);
|
||||
/* choose what I want */
|
||||
@ -10962,7 +10976,10 @@ sctp_lower_sosend(struct socket *so,
|
||||
if (inp == NULL) {
|
||||
SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, EFAULT);
|
||||
error = EFAULT;
|
||||
goto out_unlocked;
|
||||
if (i_pak) {
|
||||
SCTP_RELEASE_PKT(i_pak);
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
if ((uio == NULL) && (i_pak == NULL)) {
|
||||
SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
|
||||
@ -11193,6 +11210,11 @@ sctp_lower_sosend(struct socket *so,
|
||||
}
|
||||
/* get an asoc/stcb struct */
|
||||
vrf_id = inp->def_vrf_id;
|
||||
#ifdef INVARIANTS
|
||||
if (create_lock_applied == 0) {
|
||||
panic("Error, should hold create lock and I don't?");
|
||||
}
|
||||
#endif
|
||||
stcb = sctp_aloc_assoc(inp, addr, 1, &error, 0, vrf_id,
|
||||
p
|
||||
);
|
||||
@ -11342,11 +11364,16 @@ sctp_lower_sosend(struct socket *so,
|
||||
}
|
||||
}
|
||||
/* Keep the stcb from being freed under our feet */
|
||||
if (free_cnt_applied)
|
||||
if (free_cnt_applied) {
|
||||
#ifdef INVARIANTS
|
||||
panic("refcnt already incremented");
|
||||
atomic_add_int(&stcb->asoc.refcnt, 1);
|
||||
free_cnt_applied = 1;
|
||||
|
||||
#else
|
||||
printf("refcnt:1 already incremented?\n");
|
||||
#endif
|
||||
} else {
|
||||
atomic_add_int(&stcb->asoc.refcnt, 1);
|
||||
free_cnt_applied = 1;
|
||||
}
|
||||
if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
|
||||
SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ECONNRESET);
|
||||
error = ECONNRESET;
|
||||
|
@ -84,7 +84,7 @@ sctp_send_initiate(struct sctp_inpcb *, struct sctp_tcb *, int
|
||||
void
|
||||
sctp_send_initiate_ack(struct sctp_inpcb *, struct sctp_tcb *,
|
||||
struct mbuf *, int, int, struct sctphdr *, struct sctp_init_chunk *,
|
||||
uint32_t);
|
||||
uint32_t, int);
|
||||
|
||||
struct mbuf *
|
||||
sctp_arethere_unrecognized_parameters(struct mbuf *, int, int *,
|
||||
|
@ -2908,6 +2908,9 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
|
||||
*ippp = htonl(SCTP_FROM_SCTP_PCB + SCTP_LOC_3);
|
||||
}
|
||||
asoc->sctp_ep->last_abort_code = SCTP_FROM_SCTP_PCB + SCTP_LOC_3;
|
||||
#if defined(SCTP_PANIC_ON_ABORT)
|
||||
panic("inpcb_free does an abort");
|
||||
#endif
|
||||
sctp_send_abort_tcb(asoc, op_err, SCTP_SO_LOCKED);
|
||||
SCTP_STAT_INCR_COUNTER32(sctps_aborted);
|
||||
if ((SCTP_GET_STATE(&asoc->asoc) == SCTP_STATE_OPEN) ||
|
||||
@ -2991,6 +2994,10 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
|
||||
*ippp = htonl(SCTP_FROM_SCTP_PCB + SCTP_LOC_5);
|
||||
}
|
||||
asoc->sctp_ep->last_abort_code = SCTP_FROM_SCTP_PCB + SCTP_LOC_5;
|
||||
#if defined(SCTP_PANIC_ON_ABORT)
|
||||
panic("inpcb_free does an abort");
|
||||
#endif
|
||||
|
||||
sctp_send_abort_tcb(asoc, op_err, SCTP_SO_LOCKED);
|
||||
SCTP_STAT_INCR_COUNTER32(sctps_aborted);
|
||||
if ((SCTP_GET_STATE(&asoc->asoc) == SCTP_STATE_OPEN) ||
|
||||
@ -3822,6 +3829,8 @@ sctp_remove_net(struct sctp_tcb *stcb, struct sctp_nets *net)
|
||||
}
|
||||
asoc->deleted_primary = net;
|
||||
atomic_add_int(&net->ref_count, 1);
|
||||
memset(&net->lastsa, 0, sizeof(net->lastsa));
|
||||
memset(&net->lastsv, 0, sizeof(net->lastsv));
|
||||
sctp_mobility_feature_on(stcb->sctp_ep,
|
||||
SCTP_MOBILITY_PRIM_DELETED);
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_PRIM_DELETED,
|
||||
|
@ -280,6 +280,9 @@ sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
*ippp = htonl(SCTP_FROM_SCTP_TIMER + SCTP_LOC_1);
|
||||
}
|
||||
inp->last_abort_code = SCTP_FROM_SCTP_TIMER + SCTP_LOC_1;
|
||||
printf("Aborting association threshold:%d overall error count:%d\n",
|
||||
threshold,
|
||||
stcb->asoc.overall_error_count);
|
||||
sctp_abort_an_association(inp, stcb, SCTP_FAILED_THRESHOLD, oper, SCTP_SO_NOT_LOCKED);
|
||||
return (1);
|
||||
}
|
||||
|
@ -792,6 +792,9 @@ sctp_disconnect(struct socket *so)
|
||||
ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
|
||||
ph->param_length = htons(SCTP_BUF_LEN(err));
|
||||
}
|
||||
#if defined(SCTP_PANIC_ON_ABORT)
|
||||
panic("disconnect does an abort");
|
||||
#endif
|
||||
sctp_send_abort_tcb(stcb, err, SCTP_SO_LOCKED);
|
||||
SCTP_STAT_INCR_COUNTER32(sctps_aborted);
|
||||
}
|
||||
@ -883,6 +886,10 @@ sctp_disconnect(struct socket *so)
|
||||
ippp = (uint32_t *) (ph + 1);
|
||||
*ippp = htonl(SCTP_FROM_SCTP_USRREQ + SCTP_LOC_4);
|
||||
}
|
||||
#if defined(SCTP_PANIC_ON_ABORT)
|
||||
panic("disconnect does an abort");
|
||||
#endif
|
||||
|
||||
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_USRREQ + SCTP_LOC_4;
|
||||
sctp_send_abort_tcb(stcb, op_err, SCTP_SO_LOCKED);
|
||||
SCTP_STAT_INCR_COUNTER32(sctps_aborted);
|
||||
@ -1023,6 +1030,9 @@ sctp_shutdown(struct socket *so)
|
||||
ippp = (uint32_t *) (ph + 1);
|
||||
*ippp = htonl(SCTP_FROM_SCTP_USRREQ + SCTP_LOC_6);
|
||||
}
|
||||
#if defined(SCTP_PANIC_ON_ABORT)
|
||||
panic("shutdown does an abort");
|
||||
#endif
|
||||
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_USRREQ + SCTP_LOC_6;
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb,
|
||||
SCTP_RESPONSE_TO_USER_REQ,
|
||||
|
@ -54,9 +54,11 @@ extern struct pr_usrreqs sctp_usrreqs;
|
||||
#define sctp_is_mobility_feature_on(inp, feature) (inp->sctp_mobility_features & feature)
|
||||
#define sctp_is_mobility_feature_off(inp, feature) ((inp->sctp_mobility_features & feature) == 0)
|
||||
|
||||
#define sctp_sbspace(asoc, sb) ((long) (((sb)->sb_hiwat > (asoc)->sb_cc) ? ((sb)->sb_hiwat - (asoc)->sb_cc) : 0))
|
||||
#define sctp_maxspace(sb) (max((sb)->sb_hiwat,SCTP_MINIMAL_RWND))
|
||||
|
||||
#define sctp_sbspace_failedmsgs(sb) ((long) (((sb)->sb_hiwat > (sb)->sb_cc) ? ((sb)->sb_hiwat - (sb)->sb_cc) : 0))
|
||||
#define sctp_sbspace(asoc, sb) ((long) (sctp_maxspace(sb) > (asoc)->sb_cc) ? (sctp_maxspace(sb) - (asoc)->sb_cc) : 0)
|
||||
|
||||
#define sctp_sbspace_failedmsgs(sb) ((long) ((sctp_maxspace(sb) > (sb)->sb_cc) ? (sctp_maxspace(sb) - (sb)->sb_cc) : 0))
|
||||
|
||||
#define sctp_sbspace_sub(a,b) ((a > b) ? (a - b) : 0)
|
||||
|
||||
|
@ -3962,6 +3962,9 @@ sctp_handle_ootb(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
|
||||
break;
|
||||
}
|
||||
switch (ch->chunk_type) {
|
||||
case SCTP_COOKIE_ECHO:
|
||||
/* We hit here only if the assoc is being freed */
|
||||
return;
|
||||
case SCTP_PACKET_DROPPED:
|
||||
/* we don't respond to pkt-dropped */
|
||||
return;
|
||||
@ -5265,10 +5268,16 @@ sctp_sorecvmsg(struct socket *so,
|
||||
* to increment, we need to use the atomic add to
|
||||
* the refcnt
|
||||
*/
|
||||
if (freecnt_applied)
|
||||
if (freecnt_applied) {
|
||||
#ifdef INVARIANTS
|
||||
panic("refcnt already incremented");
|
||||
atomic_add_int(&stcb->asoc.refcnt, 1);
|
||||
freecnt_applied = 1;
|
||||
#else
|
||||
printf("refcnt already incremented?\n");
|
||||
#endif
|
||||
} else {
|
||||
atomic_add_int(&stcb->asoc.refcnt, 1);
|
||||
freecnt_applied = 1;
|
||||
}
|
||||
/*
|
||||
* Setup to remember how much we have not yet told
|
||||
* the peer our rwnd has opened up. Note we grab the
|
||||
|
Loading…
Reference in New Issue
Block a user