54#if defined(INET) || defined(INET6)
97 net->failure_threshold);
98 if (net->error_count > net->failure_threshold) {
101 net->dest_state &= ~SCTP_ADDR_REACHABLE;
102 net->dest_state &= ~SCTP_ADDR_REQ_PRIMARY;
103 net->dest_state &= ~SCTP_ADDR_PF;
108 }
else if ((net->pf_threshold < net->failure_threshold) &&
109 (net->error_count > net->pf_threshold)) {
158 "Association error counter exceeded");
176 struct sctp_nets *alt, *mnet, *min_errors_net = NULL, *max_cwnd_net = NULL;
185 return (TAILQ_FIRST(&stcb->
asoc.
nets));
196 TAILQ_FOREACH(mnet, &stcb->
asoc.
nets, sctp_next) {
223 if (min_errors == -1) {
225 min_errors_net = mnet;
228 min_errors_net = mnet;
231 min_errors_net = mnet;
236 if (min_errors == -1) {
238 min_errors_net = mnet;
241 min_errors_net = mnet;
244 min_errors_net = mnet;
258 if (max_cwnd < mnet->
cwnd) {
260 max_cwnd = mnet->
cwnd;
261 }
else if (max_cwnd == mnet->
cwnd) {
276 if (this_random % 2 == 1) {
278 max_cwnd = mnet->
cwnd;
282 if (max_cwnd_net == NULL) {
283 if (min_errors_net == NULL) {
286 return (min_errors_net);
288 return (max_cwnd_net);
292 else if (mode == 1) {
293 TAILQ_FOREACH(mnet, &stcb->
asoc.
nets, sctp_next) {
302 if (max_cwnd < mnet->
cwnd) {
304 max_cwnd = mnet->
cwnd;
305 }
else if (max_cwnd == mnet->
cwnd) {
321 if (this_random % 2) {
323 max_cwnd = mnet->
cwnd;
328 return (max_cwnd_net);
333 alt = TAILQ_NEXT(net, sctp_next);
335 alt = TAILQ_FIRST(&stcb->
asoc.
nets);
341 alt = TAILQ_FIRST(&stcb->
asoc.
nets);
363 alt = TAILQ_NEXT(alt, sctp_next);
372 alt = TAILQ_NEXT(net, sctp_next);
374 alt = TAILQ_FIRST(&stcb->
asoc.
nets);
380 alt = TAILQ_FIRST(&stcb->
asoc.
nets);
396 alt = TAILQ_NEXT(alt, sctp_next);
409 alt = TAILQ_FIRST(&stcb->
asoc.
nets);
419 int num_marked,
int num_abandoned)
432 if ((win_probe == 0) && (num_marked || num_abandoned)) {
447 TAILQ_FOREACH_SAFE(chk, &asoc->
sent_queue, sctp_next, nchk) {
449 SCTP_PRINTF(
"Found chk:%p tsn:%x <= last_acked_seq:%x\n",
461 TAILQ_REMOVE(&asoc->
sent_queue, chk, sctp_next);
479 SCTP_PRINTF(
"after recover order is as follows\n");
480 TAILQ_FOREACH(chk, &asoc->
sent_queue, sctp_next) {
503 struct timeval now, min_wait, tv;
506 int audit_tf, num_mk, fir;
510 int recovery_cnt = 0;
531 tv.tv_sec = cur_rto / 1000000;
532 tv.tv_usec = cur_rto % 1000000;
534 timevalsub(&min_wait, &tv);
535 if (min_wait.tv_sec < 0 || min_wait.tv_usec < 0) {
542 min_wait.tv_sec = min_wait.tv_usec = 0;
559 tsnfirst = tsnlast = 0;
563 TAILQ_FOREACH_SAFE(chk, &stcb->
asoc.
sent_queue, sctp_next, nchk) {
566 SCTP_PRINTF(
"Our list is out of order? last_acked:%x chk:%x\n",
570 panic(
"last acked >= chk on sent-Q");
572 SCTP_PRINTF(
"Recover attempts a restart cnt:%d\n", recovery_cnt);
574 if (recovery_cnt < 10) {
577 SCTP_PRINTF(
"Recovery fails %d times??\n", recovery_cnt);
597 if ((chk->
sent_rcv_time.tv_sec > min_wait.tv_sec) && (window_probe == 0)) {
611 (window_probe == 0)) {
716#ifdef THIS_SHOULD_NOT_BE_DONE
743 *num_marked = num_mk;
744 *num_abandoned = cnt_abandoned;
753 if ((chk->
whoTo == net) &&
766#ifdef THIS_SHOULD_NOT_BE_DONE
776 SCTP_PRINTF(
"Local Audit says there are %d for retran asoc cnt:%d we marked:%d this time\n",
779#ifndef SCTP_AUDITING_ENABLED
785 "Audit total flight due to negative value net:%p\n",
790 TAILQ_FOREACH(lnets, &stcb->
asoc.
nets, sctp_next) {
793 "Net:%p c-f cwnd:%d ssthresh:%d\n",
794 (
void *)lnets, lnets->
cwnd, lnets->ssthresh);
821 int win_probe, num_mk, num_abandoned;
829 TAILQ_FOREACH(lnet, &stcb->
asoc.
nets, sctp_next) {
846 if (win_probe == 0) {
865 if ((ms_goneby > net->
RTO) || (net->
RTO == 0)) {
915 &num_mk, &num_abandoned);
987 for (; lchk != NULL; lchk = TAILQ_NEXT(lchk, sctp_next)) {
988 if (lchk->
whoTo != NULL) {
1069 struct mbuf *op_err;
1072 "Cookie timer expired, but no cookie");
1077 panic(
"Cookie timer expires in wrong state?");
1098 if (alt !=
cookie->whoTo) {
1128 if (strrst == NULL) {
1131 net = strrst->
whoTo;
1143 strrst->
whoTo = alt;
1148 if ((chk->whoTo == net) &&
1198 if (asconf == NULL) {
1201 net = asconf->
whoTo;
1226 if (asconf->
whoTo != alt) {
1227 asconf->
whoTo = alt;
1233 if ((chk->
whoTo == net) &&
1246 if (chk->
whoTo != alt) {
1350 unsigned int i, chks_in_queue = 0;
1351 int being_filled = 0;
1353 KASSERT(inp != NULL, (
"inp is NULL"));
1354 KASSERT(stcb != NULL, (
"stcb is NULL"));
1357 KASSERT(TAILQ_EMPTY(&stcb->
asoc.
send_queue), (
"send_queue not empty"));
1358 KASSERT(TAILQ_EMPTY(&stcb->
asoc.
sent_queue), (
"sent_queue not empty"));
1361 SCTP_PRINTF(
"Hmm, sent_queue_retran_cnt is non-zero %d\n",
1370 SCTP_PRINTF(
"Found additional streams NOT managed by scheduler, corrected\n");
1387 SCTP_PRINTF(
"Hmm, stream queue cnt at %d I counted %d in stream out wheel\n",
1391 if (chks_in_queue) {
1400 if (being_filled == 0) {
1401 SCTP_PRINTF(
"Still nothing moved %d chunks are stuck\n",
1406 SCTP_PRINTF(
"Found no chunks on any queue tot:%lu\n",
1458 struct timeval diff;
1462 ms_gone_by = (
uint32_t)(diff.tv_sec * 1000) +
1465 ms_gone_by = 0xffffffff;
1484 if ((next_mtu > net->
mtu) && (net->
port == 0)) {
1493#if defined(INET6) && defined(SCTP_EMBEDDED_V6_SCOPE)
1495 struct sockaddr_in6 *sin6 = (
struct sockaddr_in6 *)&net->
ro.
_l_addr;
1506#if defined(INET6) && defined(SCTP_EMBEDDED_V6_SCOPE)
1508 struct sockaddr_in6 *sin6 = (
struct sockaddr_in6 *)&net->
ro.
_l_addr;
1510 (
void)sa6_recoverscope(sin6);
1519#if defined(INET) || defined(INET6)
1521 mtu -=
sizeof(
struct udphdr);
1524 if (mtu > next_mtu) {
1525 net->
mtu = next_mtu;
1538 struct timeval tn, *tim_touse;
const struct encaptab * cookie
#define SCTP_FLIGHT_LOGGING_ENABLE
#define SCTP_CWND_MONITOR_ENABLE
#define SCTP_THRESHOLD_LOGGING
#define SCTP_FR_LOGGING_ENABLE
#define SCTP_CWND_LOGGING_ENABLE
#define SCTP_MOBILITY_PRIM_DELETED
#define SCTP_PCB_FLAGS_AUTOCLOSE
void sctp_asconf_cleanup(struct sctp_tcb *stcb)
#define SCTP_TIMER_TYPE_SHUTDOWNACK
#define SCTP_THRESHOLD_INCR
#define SCTP_STATE_COOKIE_ECHOED
#define SCTP_DATAGRAM_NR_ACKED
#define SCTP_CWND_LOG_FROM_T3
#define SCTP_TSN_GT(a, b)
#define SCTP_OUTPUT_FROM_T3
#define SCTP_DATAGRAM_RESEND
#define SCTP_SO_NOT_LOCKED
#define SCTP_TIMER_TYPE_HEARTBEAT
#define SCTP_FR_T3_MARK_TIME
#define SCTP_ADDR_UNCONFIRMED
#define SCTP_FLIGHT_LOG_UP
#define SCTP_TIMER_TYPE_STRRESET
#define SCTP_TSN_GE(a, b)
#define SCTP_DEBUG_TIMER1
#define SCTP_TIMER_TYPE_SHUTDOWNGUARD
#define SCTP_GET_STATE(_stcb)
#define SCTP_GETTIME_TIMEVAL(x)
#define SCTP_CWND_LOG_FROM_RTX
#define SCTP_DATAGRAM_UNSENT
#define SCTP_TIMER_TYPE_PATHMTURAISE
#define SCTP_OUTPUT_FROM_AUTOCLOSE_TMR
#define SCTP_FR_T3_MARKED
#define SCTP_STATE_COOKIE_WAIT
#define SCTP_FR_CWND_REPORT
#define SCTP_TIMER_TYPE_SHUTDOWN
#define SCTP_DEBUG_ASCONF1
#define SCTP_STATE_SHUTDOWN_SENT
#define SCTP_STATE_SHUTDOWN_RECEIVED
#define SCTP_ADDR_REACHABLE
#define SCTP_NOTIFY_INTERFACE_DOWN
#define SCTP_SET_STATE(_stcb, _state)
#define SCTP_TIMER_TYPE_AUTOCLOSE
#define SCTP_ADDR_BEING_DELETED
#define SCTP_FR_T3_STOPPED
#define SCTP_DATAGRAM_ACKED
#define SCTP_FROM_SCTP_TIMER
#define SCTP_TIMER_TYPE_SEND
#define SCTP_FLIGHT_LOG_DOWN_RSND_TO
#define SCTP_ADDR_NOT_LOCKED
#define SCTP_DEBUG_TIMER4
#define SCTP_FR_T3_TIMEOUT
struct sctp_tmit_chunk * sctp_try_advance_peer_ack_point(struct sctp_tcb *stcb, struct sctp_association *asoc)
#define SCTP_TCB_SEND_UNLOCK(_tcb)
#define SCTP_TCB_SEND_LOCK(_tcb)
#define MODULE_GLOBAL(__SYMBOL)
struct route sctp_route_t
#define SCTP_PRINTF(params...)
#define SCTP_GATHER_MTU_FROM_ROUTE(sctp_ifa, sa, nh)
#define SCTPDBG(level, params...)
#define SCTP_BASE_SYSCTL(__m)
#define SCTPDBG_ADDR(level, addr)
#define sctp_get_tick_count()
void sctp_send_shutdown_ack(struct sctp_tcb *stcb, struct sctp_nets *net)
void send_forward_tsn(struct sctp_tcb *stcb, struct sctp_association *asoc)
struct sctp_ifa * sctp_source_address_selection(struct sctp_inpcb *inp, struct sctp_tcb *stcb, sctp_route_t *ro, struct sctp_nets *net, int non_asoc_addr_ok, uint32_t vrf_id)
void sctp_send_hb(struct sctp_tcb *stcb, struct sctp_nets *net, int so_locked)
void sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked)
void sctp_send_asconf(struct sctp_tcb *stcb, struct sctp_nets *net, int addr_locked)
void sctp_move_chunks_from_net(struct sctp_tcb *stcb, struct sctp_nets *net)
void sctp_send_shutdown(struct sctp_tcb *stcb, struct sctp_nets *net)
void sctp_chunk_output(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_where, int so_locked)
void sctp_free_ifa(struct sctp_ifa *sctp_ifap)
#define SCTP_BEING_DELETED
#define CHUNK_FLAGS_FRAGMENT_OK
#define SCTP_STREAM_RESET_PENDING
static void sctp_recover_sent_list(struct sctp_tcb *stcb)
void sctp_audit_retranmission_queue(struct sctp_association *asoc)
static void sctp_backoff_on_timeout(struct sctp_tcb *stcb, struct sctp_nets *net, int win_probe, int num_marked, int num_abandoned)
void sctp_delete_prim_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
int sctp_shutdown_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_nets *net)
static int sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_nets *net, uint16_t threshold)
int sctp_asconf_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_nets *net)
int sctp_strreset_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
int sctp_shutdownack_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_nets *net)
void sctp_autoclose_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
struct sctp_nets * sctp_find_alternate_net(struct sctp_tcb *stcb, struct sctp_nets *net, int mode)
static int sctp_mark_all_for_resend(struct sctp_tcb *stcb, struct sctp_nets *net, struct sctp_nets *alt, int window_probe, int *num_marked, int *num_abandoned)
int sctp_t1init_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_nets *net)
static void sctp_audit_stream_queues_for_size(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
int sctp_heartbeat_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_nets *net)
int sctp_cookie_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_nets *net SCTP_UNUSED)
int sctp_t3rxt_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_nets *net)
void sctp_pathmtu_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_nets *net)
#define PR_SCTP_ENABLED(x)
#define PR_SCTP_RTX_ENABLED(x)
#define PR_SCTP_BUF_ENABLED(x)
#define PR_SCTP_TTL_ENABLED(x)
#define SCTP_STAT_INCR(_x)
#define SCTP_STAT_DECR_GAUGE32(_x)
#define sctp_mobility_feature_off(inp, feature)
#define sctp_free_a_chunk(_stcb, _chk, _so_locked)
#define sctp_flight_size_decrease(tp1)
#define sctp_total_flight_decrease(stcb, tp1)
#define sctp_is_feature_on(inp, feature)
#define sctp_total_flight_increase(stcb, tp1)
#define sctp_free_remote_addr(__net)
#define sctp_ucount_incr(val)
#define sctp_flight_size_increase(tp1)
void sctp_misc_ints(uint8_t from, uint32_t a, uint32_t b, uint32_t c, uint32_t d)
void sctp_timer_stop(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_nets *net, uint32_t from)
void sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_nets *net)
struct mbuf * sctp_generate_cause(uint16_t code, char *info)
void sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb, uint32_t error, void *data, int so_locked)
void sctp_abort_an_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct mbuf *op_err, bool timedout, int so_locked)
uint32_t sctp_select_initial_TSN(struct sctp_pcb *inp)
uint32_t sctp_get_next_mtu(uint32_t val)
void sctp_log_cwnd(struct sctp_tcb *stcb, struct sctp_nets *net, int augment, uint8_t from)
void sctp_log_fr(uint32_t biggest_tsn, uint32_t biggest_new_tsn, uint32_t tsn, int from)
uint32_t sctp_secs_to_ticks(uint32_t secs)
int sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1, uint8_t sent, int so_locked)
void sctp_stop_timers_for_shutdown(struct sctp_tcb *stcb)
#define sctp_free_bufspace(stcb, asoc, tp1, chk_cnt)
uint32_t total_output_queue_size
unsigned int sent_queue_retran_cnt
unsigned int sent_queue_cnt_removeable
struct sctp_nets * alternate
uint32_t str_reset_seq_out
struct sctpchunk_listhead send_queue
struct sctp_stream_out * strmout
unsigned int total_flight_count
uint32_t sat_t3_recovery_tsn
uint32_t sctp_autoclose_ticks
struct sctpnetlisthead nets
uint8_t fast_retran_loss_recovery
struct sctp_nets * deleted_primary
struct timeval time_last_rcvd
uint8_t dropped_special_cnt
uint8_t delayed_connection
unsigned int total_flight
unsigned int stream_queue_cnt
uint8_t sat_t3_loss_recovery
struct sctpchunk_listhead asconf_send_queue
struct sctp_ss_functions ss_functions
struct sctpchunk_listhead control_send_queue
struct timeval time_last_sent
struct sctp_nets * primary_destination
uint8_t hb_random_values[4]
struct sctp_cc_functions cc_functions
unsigned int overall_error_count
struct sctpchunk_listhead sent_queue
uint8_t stream_reset_outstanding
uint32_t initial_init_rto_max
uint32_t advanced_peer_ack_point
unsigned int sent_queue_cnt
void(* sctp_cwnd_new_transmission_begins)(struct sctp_tcb *stcb, struct sctp_nets *net)
void(* sctp_cwnd_update_after_timeout)(struct sctp_tcb *stcb, struct sctp_nets *net)
struct timeval timetodrop
uint8_t doing_fast_retransmit
uint8_t chunk_was_revoked
struct nhop_object * ro_nh
union sctp_sockstore _l_addr
struct sctp_ifa * _s_addr
uint16_t failure_threshold
uint32_t partial_bytes_acked
uint8_t find_pseudo_cumack
uint32_t heart_beat_delay
struct timeval last_sent_time
uint8_t find_rtx_pseudo_cumack
uint8_t fast_retran_loss_recovery
uint8_t src_addr_selected
bool(* sctp_ss_is_empty)(struct sctp_tcb *stcb, struct sctp_association *asoc)
void(* sctp_ss_init)(struct sctp_tcb *stcb, struct sctp_association *asoc)
uint32_t chunks_on_queues
struct sctp_streamhead outqueue
struct sctp_association asoc
struct sctp_inpcb * sctp_ep
union sctp_tmit_chunk::@34 rec
struct sctp_data_chunkrec data
struct timeval sent_rcv_time
struct sctp_association * asoc