aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/sctp/sctp.h21
-rw-r--r--net/sctp/sysctl.c5
-rw-r--r--net/sctp/transport.c17
3 files changed, 12 insertions, 31 deletions
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index 8e4de46c052e..c2035c96a2ee 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -388,27 +388,6 @@ static inline int sctp_list_single_entry(struct list_head *head)
388 return (head->next != head) && (head->next == head->prev); 388 return (head->next != head) && (head->next == head->prev);
389} 389}
390 390
391/* Generate a random jitter in the range of -50% ~ +50% of input RTO. */
392static inline __s32 sctp_jitter(__u32 rto)
393{
394 static __u32 sctp_rand;
395 __s32 ret;
396
397 /* Avoid divide by zero. */
398 if (!rto)
399 rto = 1;
400
401 sctp_rand += jiffies;
402 sctp_rand ^= (sctp_rand << 12);
403 sctp_rand ^= (sctp_rand >> 20);
404
405 /* Choose random number from 0 to rto, then move to -50% ~ +50%
406 * of rto.
407 */
408 ret = sctp_rand % rto - (rto >> 1);
409 return ret;
410}
411
412/* Break down data chunks at this point. */ 391/* Break down data chunks at this point. */
413static inline int sctp_frag_point(const struct sctp_association *asoc, int pmtu) 392static inline int sctp_frag_point(const struct sctp_association *asoc, int pmtu)
414{ 393{
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
index 12c7e01c2677..2e9ada10fd84 100644
--- a/net/sctp/sysctl.c
+++ b/net/sctp/sysctl.c
@@ -424,8 +424,9 @@ static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write,
424 void __user *buffer, size_t *lenp, 424 void __user *buffer, size_t *lenp,
425 loff_t *ppos) 425 loff_t *ppos)
426{ 426{
427 pr_warn_once("Changing rto_alpha or rto_beta may lead to " 427 if (write)
428 "suboptimal rtt/srtt estimations!\n"); 428 pr_warn_once("Changing rto_alpha or rto_beta may lead to "
429 "suboptimal rtt/srtt estimations!\n");
429 430
430 return proc_dointvec_minmax(ctl, write, buffer, lenp, ppos); 431 return proc_dointvec_minmax(ctl, write, buffer, lenp, ppos);
431} 432}
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index 7dd672fa651f..b10e047bbd15 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -594,15 +594,16 @@ void sctp_transport_burst_reset(struct sctp_transport *t)
594} 594}
595 595
596/* What is the next timeout value for this transport? */ 596/* What is the next timeout value for this transport? */
597unsigned long sctp_transport_timeout(struct sctp_transport *t) 597unsigned long sctp_transport_timeout(struct sctp_transport *trans)
598{ 598{
599 unsigned long timeout; 599 /* RTO + timer slack +/- 50% of RTO */
600 timeout = t->rto + sctp_jitter(t->rto); 600 unsigned long timeout = (trans->rto >> 1) + prandom_u32_max(trans->rto);
601 if ((t->state != SCTP_UNCONFIRMED) && 601
602 (t->state != SCTP_PF)) 602 if (trans->state != SCTP_UNCONFIRMED &&
603 timeout += t->hbinterval; 603 trans->state != SCTP_PF)
604 timeout += jiffies; 604 timeout += trans->hbinterval;
605 return timeout; 605
606 return timeout + jiffies;
606} 607}
607 608
608/* Reset transport variables to their initial values */ 609/* Reset transport variables to their initial values */