Handle integer overflows correctly when converting msecs and secs to
ticks and vice versa. These issues were caught by recently added panic() calls on INVARIANTS systems. Reported by: syzbot+b44787b4be7096cd1590@syzkaller.appspotmail.com Reported by: syzbot+35f82d22805c1e899685@syzkaller.appspotmail.com MFC after: 1 week
This commit is contained in:
parent
fb1bc03eee
commit
25ec355353
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=359405
@ -1914,7 +1914,7 @@ measure_rtt(struct sctp_nets *net)
|
|||||||
if (net->fast_retran_ip == 0 && net->ssthresh < 0xFFFF && htcp_ccount(&net->cc_mod.htcp_ca) > 3) {
|
if (net->fast_retran_ip == 0 && net->ssthresh < 0xFFFF && htcp_ccount(&net->cc_mod.htcp_ca) > 3) {
|
||||||
if (net->cc_mod.htcp_ca.maxRTT < net->cc_mod.htcp_ca.minRTT)
|
if (net->cc_mod.htcp_ca.maxRTT < net->cc_mod.htcp_ca.minRTT)
|
||||||
net->cc_mod.htcp_ca.maxRTT = net->cc_mod.htcp_ca.minRTT;
|
net->cc_mod.htcp_ca.maxRTT = net->cc_mod.htcp_ca.minRTT;
|
||||||
if (net->cc_mod.htcp_ca.maxRTT < srtt && srtt <= net->cc_mod.htcp_ca.maxRTT + MSEC_TO_TICKS(20))
|
if (net->cc_mod.htcp_ca.maxRTT < srtt && srtt <= net->cc_mod.htcp_ca.maxRTT + sctp_msecs_to_ticks(20))
|
||||||
net->cc_mod.htcp_ca.maxRTT = srtt;
|
net->cc_mod.htcp_ca.maxRTT = srtt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1975,7 +1975,7 @@ htcp_beta_update(struct htcp *ca, uint32_t minRTT, uint32_t maxRTT)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ca->modeswitch && minRTT > (uint32_t)MSEC_TO_TICKS(10) && maxRTT) {
|
if (ca->modeswitch && minRTT > sctp_msecs_to_ticks(10) && maxRTT) {
|
||||||
ca->beta = (minRTT << 7) / maxRTT;
|
ca->beta = (minRTT << 7) / maxRTT;
|
||||||
if (ca->beta < BETA_MIN)
|
if (ca->beta < BETA_MIN)
|
||||||
ca->beta = BETA_MIN;
|
ca->beta = BETA_MIN;
|
||||||
|
@ -577,16 +577,6 @@ __FBSDID("$FreeBSD$");
|
|||||||
#define SCTP_ASOC_MAX_CHUNKS_ON_QUEUE 512
|
#define SCTP_ASOC_MAX_CHUNKS_ON_QUEUE 512
|
||||||
|
|
||||||
|
|
||||||
/* The conversion from time to ticks and vice versa is done by rounding
|
|
||||||
* upwards. This way we can test in the code the time to be positive and
|
|
||||||
* know that this corresponds to a positive number of ticks.
|
|
||||||
*/
|
|
||||||
#define MSEC_TO_TICKS(x) ((hz == 1000) ? x : ((((x) * hz) + 999) / 1000))
|
|
||||||
#define TICKS_TO_MSEC(x) ((hz == 1000) ? x : ((((x) * 1000) + (hz - 1)) / hz))
|
|
||||||
|
|
||||||
#define SEC_TO_TICKS(x) ((x) * hz)
|
|
||||||
#define TICKS_TO_SEC(x) (((x) + (hz - 1)) / hz)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Basically the minimum amount of time before I do a early FR. Making this
|
* Basically the minimum amount of time before I do a early FR. Making this
|
||||||
* value to low will cause duplicate retransmissions.
|
* value to low will cause duplicate retransmissions.
|
||||||
|
@ -2600,7 +2600,7 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
|
|||||||
*/
|
*/
|
||||||
(void)SCTP_GETTIME_TIMEVAL(&now);
|
(void)SCTP_GETTIME_TIMEVAL(&now);
|
||||||
/* Expire time is in Ticks, so we convert to seconds */
|
/* Expire time is in Ticks, so we convert to seconds */
|
||||||
time_expires.tv_sec = cookie->time_entered.tv_sec + TICKS_TO_SEC(cookie->cookie_life);
|
time_expires.tv_sec = cookie->time_entered.tv_sec + sctp_ticks_to_secs(cookie->cookie_life);
|
||||||
time_expires.tv_usec = cookie->time_entered.tv_usec;
|
time_expires.tv_usec = cookie->time_entered.tv_usec;
|
||||||
if (timevalcmp(&now, &time_expires, >)) {
|
if (timevalcmp(&now, &time_expires, >)) {
|
||||||
/* cookie is stale! */
|
/* cookie is stale! */
|
||||||
|
@ -2556,13 +2556,13 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
|
|||||||
m = &inp->sctp_ep;
|
m = &inp->sctp_ep;
|
||||||
|
|
||||||
/* setup the base timeout information */
|
/* setup the base timeout information */
|
||||||
m->sctp_timeoutticks[SCTP_TIMER_SEND] = SEC_TO_TICKS(SCTP_SEND_SEC); /* needed ? */
|
m->sctp_timeoutticks[SCTP_TIMER_SEND] = sctp_secs_to_ticks(SCTP_SEND_SEC); /* needed ? */
|
||||||
m->sctp_timeoutticks[SCTP_TIMER_INIT] = SEC_TO_TICKS(SCTP_INIT_SEC); /* needed ? */
|
m->sctp_timeoutticks[SCTP_TIMER_INIT] = sctp_secs_to_ticks(SCTP_INIT_SEC); /* needed ? */
|
||||||
m->sctp_timeoutticks[SCTP_TIMER_RECV] = MSEC_TO_TICKS(SCTP_BASE_SYSCTL(sctp_delayed_sack_time_default));
|
m->sctp_timeoutticks[SCTP_TIMER_RECV] = sctp_msecs_to_ticks(SCTP_BASE_SYSCTL(sctp_delayed_sack_time_default));
|
||||||
m->sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = MSEC_TO_TICKS(SCTP_BASE_SYSCTL(sctp_heartbeat_interval_default));
|
m->sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = sctp_msecs_to_ticks(SCTP_BASE_SYSCTL(sctp_heartbeat_interval_default));
|
||||||
m->sctp_timeoutticks[SCTP_TIMER_PMTU] = SEC_TO_TICKS(SCTP_BASE_SYSCTL(sctp_pmtu_raise_time_default));
|
m->sctp_timeoutticks[SCTP_TIMER_PMTU] = sctp_secs_to_ticks(SCTP_BASE_SYSCTL(sctp_pmtu_raise_time_default));
|
||||||
m->sctp_timeoutticks[SCTP_TIMER_MAXSHUTDOWN] = SEC_TO_TICKS(SCTP_BASE_SYSCTL(sctp_shutdown_guard_time_default));
|
m->sctp_timeoutticks[SCTP_TIMER_MAXSHUTDOWN] = sctp_secs_to_ticks(SCTP_BASE_SYSCTL(sctp_shutdown_guard_time_default));
|
||||||
m->sctp_timeoutticks[SCTP_TIMER_SIGNATURE] = SEC_TO_TICKS(SCTP_BASE_SYSCTL(sctp_secret_lifetime_default));
|
m->sctp_timeoutticks[SCTP_TIMER_SIGNATURE] = sctp_secs_to_ticks(SCTP_BASE_SYSCTL(sctp_secret_lifetime_default));
|
||||||
/* all max/min max are in ms */
|
/* all max/min max are in ms */
|
||||||
m->sctp_maxrto = SCTP_BASE_SYSCTL(sctp_rto_max_default);
|
m->sctp_maxrto = SCTP_BASE_SYSCTL(sctp_rto_max_default);
|
||||||
m->sctp_minrto = SCTP_BASE_SYSCTL(sctp_rto_min_default);
|
m->sctp_minrto = SCTP_BASE_SYSCTL(sctp_rto_min_default);
|
||||||
@ -2610,7 +2610,7 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
|
|||||||
sctp_timer_start(SCTP_TIMER_TYPE_NEWCOOKIE, inp, NULL, NULL);
|
sctp_timer_start(SCTP_TIMER_TYPE_NEWCOOKIE, inp, NULL, NULL);
|
||||||
|
|
||||||
/* How long is a cookie good for ? */
|
/* How long is a cookie good for ? */
|
||||||
m->def_cookie_life = MSEC_TO_TICKS(SCTP_BASE_SYSCTL(sctp_valid_cookie_life_default));
|
m->def_cookie_life = sctp_msecs_to_ticks(SCTP_BASE_SYSCTL(sctp_valid_cookie_life_default));
|
||||||
/*
|
/*
|
||||||
* Initialize authentication parameters
|
* Initialize authentication parameters
|
||||||
*/
|
*/
|
||||||
|
@ -1539,7 +1539,7 @@ sctp_autoclose_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
|
|||||||
tim_touse = &asoc->time_last_sent;
|
tim_touse = &asoc->time_last_sent;
|
||||||
}
|
}
|
||||||
/* Now has long enough transpired to autoclose? */
|
/* Now has long enough transpired to autoclose? */
|
||||||
ticks_gone_by = SEC_TO_TICKS((uint32_t)(tn.tv_sec - tim_touse->tv_sec));
|
ticks_gone_by = sctp_secs_to_ticks((uint32_t)(tn.tv_sec - tim_touse->tv_sec));
|
||||||
if (ticks_gone_by >= asoc->sctp_autoclose_ticks) {
|
if (ticks_gone_by >= asoc->sctp_autoclose_ticks) {
|
||||||
/*
|
/*
|
||||||
* autoclose time has hit, call the output routine,
|
* autoclose time has hit, call the output routine,
|
||||||
|
@ -1600,7 +1600,7 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
|
|||||||
break;
|
break;
|
||||||
case SCTP_AUTOCLOSE:
|
case SCTP_AUTOCLOSE:
|
||||||
if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTOCLOSE))
|
if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTOCLOSE))
|
||||||
val = TICKS_TO_SEC(inp->sctp_ep.auto_close_time);
|
val = sctp_ticks_to_secs(inp->sctp_ep.auto_close_time);
|
||||||
else
|
else
|
||||||
val = 0;
|
val = 0;
|
||||||
break;
|
break;
|
||||||
@ -2012,7 +2012,7 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
|
|||||||
((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
|
((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
|
||||||
(sack->sack_assoc_id == SCTP_FUTURE_ASSOC))) {
|
(sack->sack_assoc_id == SCTP_FUTURE_ASSOC))) {
|
||||||
SCTP_INP_RLOCK(inp);
|
SCTP_INP_RLOCK(inp);
|
||||||
sack->sack_delay = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV]);
|
sack->sack_delay = sctp_ticks_to_msecs(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV]);
|
||||||
sack->sack_freq = inp->sctp_ep.sctp_sack_freq;
|
sack->sack_freq = inp->sctp_ep.sctp_sack_freq;
|
||||||
SCTP_INP_RUNLOCK(inp);
|
SCTP_INP_RUNLOCK(inp);
|
||||||
} else {
|
} else {
|
||||||
@ -2493,7 +2493,7 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
|
|||||||
/* Use endpoint defaults */
|
/* Use endpoint defaults */
|
||||||
SCTP_INP_RLOCK(inp);
|
SCTP_INP_RLOCK(inp);
|
||||||
paddrp->spp_pathmaxrxt = inp->sctp_ep.def_net_failure;
|
paddrp->spp_pathmaxrxt = inp->sctp_ep.def_net_failure;
|
||||||
paddrp->spp_hbinterval = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]);
|
paddrp->spp_hbinterval = sctp_ticks_to_msecs(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]);
|
||||||
paddrp->spp_assoc_id = SCTP_FUTURE_ASSOC;
|
paddrp->spp_assoc_id = SCTP_FUTURE_ASSOC;
|
||||||
/* get inp's default */
|
/* get inp's default */
|
||||||
if (inp->sctp_ep.default_dscp & 0x01) {
|
if (inp->sctp_ep.default_dscp & 0x01) {
|
||||||
@ -2765,7 +2765,7 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
|
|||||||
SCTP_FIND_STCB(inp, stcb, sasoc->sasoc_assoc_id);
|
SCTP_FIND_STCB(inp, stcb, sasoc->sasoc_assoc_id);
|
||||||
|
|
||||||
if (stcb) {
|
if (stcb) {
|
||||||
sasoc->sasoc_cookie_life = TICKS_TO_MSEC(stcb->asoc.cookie_life);
|
sasoc->sasoc_cookie_life = sctp_ticks_to_msecs(stcb->asoc.cookie_life);
|
||||||
sasoc->sasoc_asocmaxrxt = stcb->asoc.max_send_times;
|
sasoc->sasoc_asocmaxrxt = stcb->asoc.max_send_times;
|
||||||
sasoc->sasoc_number_peer_destinations = stcb->asoc.numnets;
|
sasoc->sasoc_number_peer_destinations = stcb->asoc.numnets;
|
||||||
sasoc->sasoc_peer_rwnd = stcb->asoc.peers_rwnd;
|
sasoc->sasoc_peer_rwnd = stcb->asoc.peers_rwnd;
|
||||||
@ -2777,7 +2777,7 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
|
|||||||
((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
|
((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
|
||||||
(sasoc->sasoc_assoc_id == SCTP_FUTURE_ASSOC))) {
|
(sasoc->sasoc_assoc_id == SCTP_FUTURE_ASSOC))) {
|
||||||
SCTP_INP_RLOCK(inp);
|
SCTP_INP_RLOCK(inp);
|
||||||
sasoc->sasoc_cookie_life = TICKS_TO_MSEC(inp->sctp_ep.def_cookie_life);
|
sasoc->sasoc_cookie_life = sctp_ticks_to_msecs(inp->sctp_ep.def_cookie_life);
|
||||||
sasoc->sasoc_asocmaxrxt = inp->sctp_ep.max_send_times;
|
sasoc->sasoc_asocmaxrxt = inp->sctp_ep.max_send_times;
|
||||||
sasoc->sasoc_number_peer_destinations = 0;
|
sasoc->sasoc_number_peer_destinations = 0;
|
||||||
sasoc->sasoc_peer_rwnd = 0;
|
sasoc->sasoc_peer_rwnd = 0;
|
||||||
@ -3855,7 +3855,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
|
|||||||
* The value is in ticks. Note this does not effect
|
* The value is in ticks. Note this does not effect
|
||||||
* old associations, only new ones.
|
* old associations, only new ones.
|
||||||
*/
|
*/
|
||||||
inp->sctp_ep.auto_close_time = SEC_TO_TICKS(*mopt);
|
inp->sctp_ep.auto_close_time = sctp_secs_to_ticks(*mopt);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
SCTP_INP_WLOCK(inp);
|
SCTP_INP_WLOCK(inp);
|
||||||
@ -4252,10 +4252,12 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
|
|||||||
SCTP_CHECK_AND_CAST(sack, optval, struct sctp_sack_info, optsize);
|
SCTP_CHECK_AND_CAST(sack, optval, struct sctp_sack_info, optsize);
|
||||||
SCTP_FIND_STCB(inp, stcb, sack->sack_assoc_id);
|
SCTP_FIND_STCB(inp, stcb, sack->sack_assoc_id);
|
||||||
if (sack->sack_delay) {
|
if (sack->sack_delay) {
|
||||||
if (sack->sack_delay > SCTP_MAX_SACK_DELAY)
|
if (sack->sack_delay > SCTP_MAX_SACK_DELAY) {
|
||||||
sack->sack_delay = SCTP_MAX_SACK_DELAY;
|
error = EINVAL;
|
||||||
if (MSEC_TO_TICKS(sack->sack_delay) < 1) {
|
if (stcb != NULL) {
|
||||||
sack->sack_delay = TICKS_TO_MSEC(1);
|
SCTP_TCB_UNLOCK(stcb);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (stcb) {
|
if (stcb) {
|
||||||
@ -4274,7 +4276,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
|
|||||||
(sack->sack_assoc_id == SCTP_ALL_ASSOC)))) {
|
(sack->sack_assoc_id == SCTP_ALL_ASSOC)))) {
|
||||||
SCTP_INP_WLOCK(inp);
|
SCTP_INP_WLOCK(inp);
|
||||||
if (sack->sack_delay) {
|
if (sack->sack_delay) {
|
||||||
inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV] = MSEC_TO_TICKS(sack->sack_delay);
|
inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV] = sctp_msecs_to_ticks(sack->sack_delay);
|
||||||
}
|
}
|
||||||
if (sack->sack_freq) {
|
if (sack->sack_freq) {
|
||||||
inp->sctp_ep.sctp_sack_freq = sack->sack_freq;
|
inp->sctp_ep.sctp_sack_freq = sack->sack_freq;
|
||||||
@ -5637,14 +5639,14 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
|
|||||||
else if (paddrp->spp_hbinterval != 0) {
|
else if (paddrp->spp_hbinterval != 0) {
|
||||||
if (paddrp->spp_hbinterval > SCTP_MAX_HB_INTERVAL)
|
if (paddrp->spp_hbinterval > SCTP_MAX_HB_INTERVAL)
|
||||||
paddrp->spp_hbinterval = SCTP_MAX_HB_INTERVAL;
|
paddrp->spp_hbinterval = SCTP_MAX_HB_INTERVAL;
|
||||||
inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = MSEC_TO_TICKS(paddrp->spp_hbinterval);
|
inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = sctp_msecs_to_ticks(paddrp->spp_hbinterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (paddrp->spp_flags & SPP_HB_ENABLE) {
|
if (paddrp->spp_flags & SPP_HB_ENABLE) {
|
||||||
if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO) {
|
if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO) {
|
||||||
inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = 0;
|
inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = 0;
|
||||||
} else if (paddrp->spp_hbinterval) {
|
} else if (paddrp->spp_hbinterval) {
|
||||||
inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = MSEC_TO_TICKS(paddrp->spp_hbinterval);
|
inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = sctp_msecs_to_ticks(paddrp->spp_hbinterval);
|
||||||
}
|
}
|
||||||
sctp_feature_off(inp, SCTP_PCB_FLAGS_DONOT_HEARTBEAT);
|
sctp_feature_off(inp, SCTP_PCB_FLAGS_DONOT_HEARTBEAT);
|
||||||
} else if (paddrp->spp_flags & SPP_HB_DISABLE) {
|
} else if (paddrp->spp_flags & SPP_HB_DISABLE) {
|
||||||
@ -5759,7 +5761,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
|
|||||||
if (sasoc->sasoc_asocmaxrxt)
|
if (sasoc->sasoc_asocmaxrxt)
|
||||||
stcb->asoc.max_send_times = sasoc->sasoc_asocmaxrxt;
|
stcb->asoc.max_send_times = sasoc->sasoc_asocmaxrxt;
|
||||||
if (sasoc->sasoc_cookie_life) {
|
if (sasoc->sasoc_cookie_life) {
|
||||||
stcb->asoc.cookie_life = MSEC_TO_TICKS(sasoc->sasoc_cookie_life);
|
stcb->asoc.cookie_life = sctp_msecs_to_ticks(sasoc->sasoc_cookie_life);
|
||||||
}
|
}
|
||||||
SCTP_TCB_UNLOCK(stcb);
|
SCTP_TCB_UNLOCK(stcb);
|
||||||
} else {
|
} else {
|
||||||
@ -5771,7 +5773,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
|
|||||||
if (sasoc->sasoc_asocmaxrxt)
|
if (sasoc->sasoc_asocmaxrxt)
|
||||||
inp->sctp_ep.max_send_times = sasoc->sasoc_asocmaxrxt;
|
inp->sctp_ep.max_send_times = sasoc->sasoc_asocmaxrxt;
|
||||||
if (sasoc->sasoc_cookie_life) {
|
if (sasoc->sasoc_cookie_life) {
|
||||||
inp->sctp_ep.def_cookie_life = MSEC_TO_TICKS(sasoc->sasoc_cookie_life);
|
inp->sctp_ep.def_cookie_life = sctp_msecs_to_ticks(sasoc->sasoc_cookie_life);
|
||||||
}
|
}
|
||||||
SCTP_INP_WUNLOCK(inp);
|
SCTP_INP_WUNLOCK(inp);
|
||||||
} else {
|
} else {
|
||||||
|
@ -772,6 +772,80 @@ sctp_audit_log(uint8_t ev, uint8_t fd)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The conversion from time to ticks and vice versa is done by rounding
|
||||||
|
* upwards. This way we can test in the code the time to be positive and
|
||||||
|
* know that this corresponds to a positive number of ticks.
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
sctp_msecs_to_ticks(uint32_t msecs)
|
||||||
|
{
|
||||||
|
uint64_t temp;
|
||||||
|
uint32_t ticks;
|
||||||
|
|
||||||
|
if (hz == 1000) {
|
||||||
|
ticks = msecs;
|
||||||
|
} else {
|
||||||
|
temp = (((uint64_t)msecs * hz) + 999) / 1000;
|
||||||
|
if (temp > UINT32_MAX) {
|
||||||
|
ticks = UINT32_MAX;
|
||||||
|
} else {
|
||||||
|
ticks = (uint32_t)temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (ticks);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
sctp_ticks_to_msecs(uint32_t ticks)
|
||||||
|
{
|
||||||
|
uint64_t temp;
|
||||||
|
uint32_t msecs;
|
||||||
|
|
||||||
|
if (hz == 1000) {
|
||||||
|
msecs = ticks;
|
||||||
|
} else {
|
||||||
|
temp = (((uint64_t)ticks * 1000) + (hz - 1)) / hz;
|
||||||
|
if (temp > UINT32_MAX) {
|
||||||
|
msecs = UINT32_MAX;
|
||||||
|
} else {
|
||||||
|
msecs = (uint32_t)temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (msecs);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
sctp_secs_to_ticks(uint32_t secs)
|
||||||
|
{
|
||||||
|
uint64_t temp;
|
||||||
|
uint32_t ticks;
|
||||||
|
|
||||||
|
temp = (uint64_t)secs * hz;
|
||||||
|
if (temp > UINT32_MAX) {
|
||||||
|
ticks = UINT32_MAX;
|
||||||
|
} else {
|
||||||
|
ticks = (uint32_t)temp;
|
||||||
|
}
|
||||||
|
return (ticks);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
sctp_ticks_to_secs(uint32_t ticks)
|
||||||
|
{
|
||||||
|
uint64_t temp;
|
||||||
|
uint32_t secs;
|
||||||
|
|
||||||
|
temp = ((uint64_t)ticks + (hz - 1)) / hz;
|
||||||
|
if (temp > UINT32_MAX) {
|
||||||
|
secs = UINT32_MAX;
|
||||||
|
} else {
|
||||||
|
secs = (uint32_t)temp;
|
||||||
|
}
|
||||||
|
return (secs);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* sctp_stop_timers_for_shutdown() should be called
|
* sctp_stop_timers_for_shutdown() should be called
|
||||||
* when entering the SHUTDOWN_SENT or SHUTDOWN_ACK_SENT
|
* when entering the SHUTDOWN_SENT or SHUTDOWN_ACK_SENT
|
||||||
@ -1065,7 +1139,7 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
|||||||
SCTP_SET_STATE(stcb, SCTP_STATE_INUSE);
|
SCTP_SET_STATE(stcb, SCTP_STATE_INUSE);
|
||||||
asoc->max_burst = inp->sctp_ep.max_burst;
|
asoc->max_burst = inp->sctp_ep.max_burst;
|
||||||
asoc->fr_max_burst = inp->sctp_ep.fr_max_burst;
|
asoc->fr_max_burst = inp->sctp_ep.fr_max_burst;
|
||||||
asoc->heart_beat_delay = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]);
|
asoc->heart_beat_delay = sctp_ticks_to_msecs(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]);
|
||||||
asoc->cookie_life = inp->sctp_ep.def_cookie_life;
|
asoc->cookie_life = inp->sctp_ep.def_cookie_life;
|
||||||
asoc->sctp_cmt_on_off = inp->sctp_cmt_on_off;
|
asoc->sctp_cmt_on_off = inp->sctp_cmt_on_off;
|
||||||
asoc->ecn_supported = inp->ecn_supported;
|
asoc->ecn_supported = inp->ecn_supported;
|
||||||
@ -1151,7 +1225,7 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
|||||||
asoc->context = inp->sctp_context;
|
asoc->context = inp->sctp_context;
|
||||||
asoc->local_strreset_support = inp->local_strreset_support;
|
asoc->local_strreset_support = inp->local_strreset_support;
|
||||||
asoc->def_send = inp->def_send;
|
asoc->def_send = inp->def_send;
|
||||||
asoc->delayed_ack = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV]);
|
asoc->delayed_ack = sctp_ticks_to_msecs(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV]);
|
||||||
asoc->sack_freq = inp->sctp_ep.sctp_sack_freq;
|
asoc->sack_freq = inp->sctp_ep.sctp_sack_freq;
|
||||||
asoc->pr_sctp_cnt = 0;
|
asoc->pr_sctp_cnt = 0;
|
||||||
asoc->total_output_queue_size = 0;
|
asoc->total_output_queue_size = 0;
|
||||||
@ -2115,9 +2189,9 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
|||||||
}
|
}
|
||||||
tmr = &net->rxt_timer;
|
tmr = &net->rxt_timer;
|
||||||
if (net->RTO == 0) {
|
if (net->RTO == 0) {
|
||||||
to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
|
to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
|
||||||
} else {
|
} else {
|
||||||
to_ticks = MSEC_TO_TICKS(net->RTO);
|
to_ticks = sctp_msecs_to_ticks(net->RTO);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SCTP_TIMER_TYPE_INIT:
|
case SCTP_TIMER_TYPE_INIT:
|
||||||
@ -2135,9 +2209,9 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
|||||||
}
|
}
|
||||||
tmr = &net->rxt_timer;
|
tmr = &net->rxt_timer;
|
||||||
if (net->RTO == 0) {
|
if (net->RTO == 0) {
|
||||||
to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
|
to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
|
||||||
} else {
|
} else {
|
||||||
to_ticks = MSEC_TO_TICKS(net->RTO);
|
to_ticks = sctp_msecs_to_ticks(net->RTO);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SCTP_TIMER_TYPE_RECV:
|
case SCTP_TIMER_TYPE_RECV:
|
||||||
@ -2154,7 +2228,7 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
tmr = &stcb->asoc.dack_timer;
|
tmr = &stcb->asoc.dack_timer;
|
||||||
to_ticks = MSEC_TO_TICKS(stcb->asoc.delayed_ack);
|
to_ticks = sctp_msecs_to_ticks(stcb->asoc.delayed_ack);
|
||||||
break;
|
break;
|
||||||
case SCTP_TIMER_TYPE_SHUTDOWN:
|
case SCTP_TIMER_TYPE_SHUTDOWN:
|
||||||
/* Here we use the RTO of the destination. */
|
/* Here we use the RTO of the destination. */
|
||||||
@ -2168,9 +2242,9 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
|||||||
}
|
}
|
||||||
tmr = &net->rxt_timer;
|
tmr = &net->rxt_timer;
|
||||||
if (net->RTO == 0) {
|
if (net->RTO == 0) {
|
||||||
to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
|
to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
|
||||||
} else {
|
} else {
|
||||||
to_ticks = MSEC_TO_TICKS(net->RTO);
|
to_ticks = sctp_msecs_to_ticks(net->RTO);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SCTP_TIMER_TYPE_HEARTBEAT:
|
case SCTP_TIMER_TYPE_HEARTBEAT:
|
||||||
@ -2215,7 +2289,7 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
|||||||
* Now we must convert the to_ticks that are now in ms to
|
* Now we must convert the to_ticks that are now in ms to
|
||||||
* ticks.
|
* ticks.
|
||||||
*/
|
*/
|
||||||
to_ticks = MSEC_TO_TICKS(to_ticks);
|
to_ticks = sctp_msecs_to_ticks(to_ticks);
|
||||||
break;
|
break;
|
||||||
case SCTP_TIMER_TYPE_COOKIE:
|
case SCTP_TIMER_TYPE_COOKIE:
|
||||||
/*
|
/*
|
||||||
@ -2233,9 +2307,9 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
|||||||
}
|
}
|
||||||
tmr = &net->rxt_timer;
|
tmr = &net->rxt_timer;
|
||||||
if (net->RTO == 0) {
|
if (net->RTO == 0) {
|
||||||
to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
|
to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
|
||||||
} else {
|
} else {
|
||||||
to_ticks = MSEC_TO_TICKS(net->RTO);
|
to_ticks = sctp_msecs_to_ticks(net->RTO);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SCTP_TIMER_TYPE_NEWCOOKIE:
|
case SCTP_TIMER_TYPE_NEWCOOKIE:
|
||||||
@ -2288,9 +2362,9 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
|||||||
}
|
}
|
||||||
tmr = &net->rxt_timer;
|
tmr = &net->rxt_timer;
|
||||||
if (net->RTO == 0) {
|
if (net->RTO == 0) {
|
||||||
to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
|
to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
|
||||||
} else {
|
} else {
|
||||||
to_ticks = MSEC_TO_TICKS(net->RTO);
|
to_ticks = sctp_msecs_to_ticks(net->RTO);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SCTP_TIMER_TYPE_ASCONF:
|
case SCTP_TIMER_TYPE_ASCONF:
|
||||||
@ -2308,9 +2382,9 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
|||||||
}
|
}
|
||||||
tmr = &stcb->asoc.asconf_timer;
|
tmr = &stcb->asoc.asconf_timer;
|
||||||
if (net->RTO == 0) {
|
if (net->RTO == 0) {
|
||||||
to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
|
to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
|
||||||
} else {
|
} else {
|
||||||
to_ticks = MSEC_TO_TICKS(net->RTO);
|
to_ticks = sctp_msecs_to_ticks(net->RTO);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SCTP_TIMER_TYPE_SHUTDOWNGUARD:
|
case SCTP_TIMER_TYPE_SHUTDOWNGUARD:
|
||||||
@ -2328,7 +2402,11 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
|||||||
}
|
}
|
||||||
tmr = &stcb->asoc.shut_guard_timer;
|
tmr = &stcb->asoc.shut_guard_timer;
|
||||||
if (inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_MAXSHUTDOWN] == 0) {
|
if (inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_MAXSHUTDOWN] == 0) {
|
||||||
to_ticks = 5 * MSEC_TO_TICKS(stcb->asoc.maxrto);
|
if (stcb->asoc.maxrto < UINT32_MAX / 5) {
|
||||||
|
to_ticks = sctp_msecs_to_ticks(5 * stcb->asoc.maxrto);
|
||||||
|
} else {
|
||||||
|
to_ticks = sctp_msecs_to_ticks(UINT32_MAX);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_MAXSHUTDOWN];
|
to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_MAXSHUTDOWN];
|
||||||
}
|
}
|
||||||
@ -2360,9 +2438,9 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
|||||||
}
|
}
|
||||||
tmr = &stcb->asoc.strreset_timer;
|
tmr = &stcb->asoc.strreset_timer;
|
||||||
if (net->RTO == 0) {
|
if (net->RTO == 0) {
|
||||||
to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
|
to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
|
||||||
} else {
|
} else {
|
||||||
to_ticks = MSEC_TO_TICKS(net->RTO);
|
to_ticks = sctp_msecs_to_ticks(net->RTO);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SCTP_TIMER_TYPE_INPKILL:
|
case SCTP_TIMER_TYPE_INPKILL:
|
||||||
@ -2380,7 +2458,7 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
tmr = &inp->sctp_ep.signature_change;
|
tmr = &inp->sctp_ep.signature_change;
|
||||||
to_ticks = MSEC_TO_TICKS(SCTP_INP_KILL_TIMEOUT);
|
to_ticks = sctp_msecs_to_ticks(SCTP_INP_KILL_TIMEOUT);
|
||||||
break;
|
break;
|
||||||
case SCTP_TIMER_TYPE_ASOCKILL:
|
case SCTP_TIMER_TYPE_ASOCKILL:
|
||||||
if ((inp == NULL) || (stcb == NULL) || (net != NULL)) {
|
if ((inp == NULL) || (stcb == NULL) || (net != NULL)) {
|
||||||
@ -2392,7 +2470,7 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
tmr = &stcb->asoc.strreset_timer;
|
tmr = &stcb->asoc.strreset_timer;
|
||||||
to_ticks = MSEC_TO_TICKS(SCTP_ASOC_KILL_TIMEOUT);
|
to_ticks = sctp_msecs_to_ticks(SCTP_ASOC_KILL_TIMEOUT);
|
||||||
break;
|
break;
|
||||||
case SCTP_TIMER_TYPE_ADDR_WQ:
|
case SCTP_TIMER_TYPE_ADDR_WQ:
|
||||||
if ((inp != NULL) || (stcb != NULL) || (net != NULL)) {
|
if ((inp != NULL) || (stcb != NULL) || (net != NULL)) {
|
||||||
@ -2417,7 +2495,7 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
tmr = &stcb->asoc.delete_prim_timer;
|
tmr = &stcb->asoc.delete_prim_timer;
|
||||||
to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
|
to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#ifdef INVARIANTS
|
#ifdef INVARIANTS
|
||||||
|
@ -392,5 +392,10 @@ void sctp_hc_set_mtu(union sctp_sockstore *, uint16_t, uint32_t);
|
|||||||
uint32_t sctp_hc_get_mtu(union sctp_sockstore *, uint16_t);
|
uint32_t sctp_hc_get_mtu(union sctp_sockstore *, uint16_t);
|
||||||
void sctp_set_state(struct sctp_tcb *, int);
|
void sctp_set_state(struct sctp_tcb *, int);
|
||||||
void sctp_add_substate(struct sctp_tcb *, int);
|
void sctp_add_substate(struct sctp_tcb *, int);
|
||||||
|
uint32_t sctp_ticks_to_msecs(uint32_t);
|
||||||
|
uint32_t sctp_msecs_to_ticks(uint32_t);
|
||||||
|
uint32_t sctp_ticks_to_secs(uint32_t);
|
||||||
|
uint32_t sctp_secs_to_ticks(uint32_t);
|
||||||
|
|
||||||
#endif /* _KERNEL */
|
#endif /* _KERNEL */
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user