0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0030
0031 #include <linux/slab.h>
0032 #include <linux/types.h>
0033 #include <linux/random.h>
0034 #include <net/sctp/sctp.h>
0035 #include <net/sctp/sm.h>
0036
0037
0038
0039
0040 static struct sctp_transport *sctp_transport_init(struct net *net,
0041 struct sctp_transport *peer,
0042 const union sctp_addr *addr,
0043 gfp_t gfp)
0044 {
0045
0046 peer->af_specific = sctp_get_af_specific(addr->sa.sa_family);
0047 memcpy(&peer->ipaddr, addr, peer->af_specific->sockaddr_len);
0048 memset(&peer->saddr, 0, sizeof(union sctp_addr));
0049
0050 peer->sack_generation = 0;
0051
0052
0053
0054
0055
0056
0057
0058 peer->rto = msecs_to_jiffies(net->sctp.rto_initial);
0059
0060 peer->last_time_heard = 0;
0061 peer->last_time_ecne_reduced = jiffies;
0062
0063 peer->param_flags = SPP_HB_DISABLE |
0064 SPP_PMTUD_ENABLE |
0065 SPP_SACKDELAY_ENABLE;
0066
0067
0068 peer->pathmaxrxt = net->sctp.max_retrans_path;
0069 peer->pf_retrans = net->sctp.pf_retrans;
0070
0071 INIT_LIST_HEAD(&peer->transmitted);
0072 INIT_LIST_HEAD(&peer->send_ready);
0073 INIT_LIST_HEAD(&peer->transports);
0074
0075 timer_setup(&peer->T3_rtx_timer, sctp_generate_t3_rtx_event, 0);
0076 timer_setup(&peer->hb_timer, sctp_generate_heartbeat_event, 0);
0077 timer_setup(&peer->reconf_timer, sctp_generate_reconf_event, 0);
0078 timer_setup(&peer->probe_timer, sctp_generate_probe_event, 0);
0079 timer_setup(&peer->proto_unreach_timer,
0080 sctp_generate_proto_unreach_event, 0);
0081
0082
0083 get_random_bytes(&peer->hb_nonce, sizeof(peer->hb_nonce));
0084
0085 refcount_set(&peer->refcnt, 1);
0086
0087 return peer;
0088 }
0089
0090
0091 struct sctp_transport *sctp_transport_new(struct net *net,
0092 const union sctp_addr *addr,
0093 gfp_t gfp)
0094 {
0095 struct sctp_transport *transport;
0096
0097 transport = kzalloc(sizeof(*transport), gfp);
0098 if (!transport)
0099 goto fail;
0100
0101 if (!sctp_transport_init(net, transport, addr, gfp))
0102 goto fail_init;
0103
0104 SCTP_DBG_OBJCNT_INC(transport);
0105
0106 return transport;
0107
0108 fail_init:
0109 kfree(transport);
0110
0111 fail:
0112 return NULL;
0113 }
0114
0115
0116
0117
0118 void sctp_transport_free(struct sctp_transport *transport)
0119 {
0120
0121 if (del_timer(&transport->hb_timer))
0122 sctp_transport_put(transport);
0123
0124
0125
0126
0127
0128
0129 if (del_timer(&transport->T3_rtx_timer))
0130 sctp_transport_put(transport);
0131
0132 if (del_timer(&transport->reconf_timer))
0133 sctp_transport_put(transport);
0134
0135 if (del_timer(&transport->probe_timer))
0136 sctp_transport_put(transport);
0137
0138
0139 if (del_timer(&transport->proto_unreach_timer))
0140 sctp_transport_put(transport);
0141
0142 sctp_transport_put(transport);
0143 }
0144
0145 static void sctp_transport_destroy_rcu(struct rcu_head *head)
0146 {
0147 struct sctp_transport *transport;
0148
0149 transport = container_of(head, struct sctp_transport, rcu);
0150
0151 dst_release(transport->dst);
0152 kfree(transport);
0153 SCTP_DBG_OBJCNT_DEC(transport);
0154 }
0155
0156
0157
0158
0159 static void sctp_transport_destroy(struct sctp_transport *transport)
0160 {
0161 if (unlikely(refcount_read(&transport->refcnt))) {
0162 WARN(1, "Attempt to destroy undead transport %p!\n", transport);
0163 return;
0164 }
0165
0166 sctp_packet_free(&transport->packet);
0167
0168 if (transport->asoc)
0169 sctp_association_put(transport->asoc);
0170
0171 call_rcu(&transport->rcu, sctp_transport_destroy_rcu);
0172 }
0173
0174
0175
0176
0177 void sctp_transport_reset_t3_rtx(struct sctp_transport *transport)
0178 {
0179
0180
0181
0182
0183
0184
0185
0186
0187 if (!timer_pending(&transport->T3_rtx_timer))
0188 if (!mod_timer(&transport->T3_rtx_timer,
0189 jiffies + transport->rto))
0190 sctp_transport_hold(transport);
0191 }
0192
0193 void sctp_transport_reset_hb_timer(struct sctp_transport *transport)
0194 {
0195 unsigned long expires;
0196
0197
0198 expires = jiffies + sctp_transport_timeout(transport);
0199 if ((time_before(transport->hb_timer.expires, expires) ||
0200 !timer_pending(&transport->hb_timer)) &&
0201 !mod_timer(&transport->hb_timer,
0202 expires + prandom_u32_max(transport->rto)))
0203 sctp_transport_hold(transport);
0204 }
0205
0206 void sctp_transport_reset_reconf_timer(struct sctp_transport *transport)
0207 {
0208 if (!timer_pending(&transport->reconf_timer))
0209 if (!mod_timer(&transport->reconf_timer,
0210 jiffies + transport->rto))
0211 sctp_transport_hold(transport);
0212 }
0213
0214 void sctp_transport_reset_probe_timer(struct sctp_transport *transport)
0215 {
0216 if (!mod_timer(&transport->probe_timer,
0217 jiffies + transport->probe_interval))
0218 sctp_transport_hold(transport);
0219 }
0220
0221 void sctp_transport_reset_raise_timer(struct sctp_transport *transport)
0222 {
0223 if (!mod_timer(&transport->probe_timer,
0224 jiffies + transport->probe_interval * 30))
0225 sctp_transport_hold(transport);
0226 }
0227
0228
0229
0230
0231
0232 void sctp_transport_set_owner(struct sctp_transport *transport,
0233 struct sctp_association *asoc)
0234 {
0235 transport->asoc = asoc;
0236 sctp_association_hold(asoc);
0237 }
0238
0239
0240 void sctp_transport_pmtu(struct sctp_transport *transport, struct sock *sk)
0241 {
0242
0243 if (!transport->dst || transport->dst->obsolete) {
0244 sctp_transport_dst_release(transport);
0245 transport->af_specific->get_dst(transport, &transport->saddr,
0246 &transport->fl, sk);
0247 }
0248
0249 if (transport->param_flags & SPP_PMTUD_DISABLE) {
0250 struct sctp_association *asoc = transport->asoc;
0251
0252 if (!transport->pathmtu && asoc && asoc->pathmtu)
0253 transport->pathmtu = asoc->pathmtu;
0254 if (transport->pathmtu)
0255 return;
0256 }
0257
0258 if (transport->dst)
0259 transport->pathmtu = sctp_dst_mtu(transport->dst);
0260 else
0261 transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT;
0262
0263 sctp_transport_pl_update(transport);
0264 }
0265
0266 void sctp_transport_pl_send(struct sctp_transport *t)
0267 {
0268 if (t->pl.probe_count < SCTP_MAX_PROBES)
0269 goto out;
0270
0271 t->pl.probe_count = 0;
0272 if (t->pl.state == SCTP_PL_BASE) {
0273 if (t->pl.probe_size == SCTP_BASE_PLPMTU) {
0274 t->pl.state = SCTP_PL_ERROR;
0275
0276 t->pl.pmtu = SCTP_BASE_PLPMTU;
0277 t->pathmtu = t->pl.pmtu + sctp_transport_pl_hlen(t);
0278 sctp_assoc_sync_pmtu(t->asoc);
0279 }
0280 } else if (t->pl.state == SCTP_PL_SEARCH) {
0281 if (t->pl.pmtu == t->pl.probe_size) {
0282 t->pl.state = SCTP_PL_BASE;
0283 t->pl.probe_size = SCTP_BASE_PLPMTU;
0284 t->pl.probe_high = 0;
0285
0286 t->pl.pmtu = SCTP_BASE_PLPMTU;
0287 t->pathmtu = t->pl.pmtu + sctp_transport_pl_hlen(t);
0288 sctp_assoc_sync_pmtu(t->asoc);
0289 } else {
0290 t->pl.probe_high = t->pl.probe_size;
0291 t->pl.probe_size = t->pl.pmtu;
0292 }
0293 } else if (t->pl.state == SCTP_PL_COMPLETE) {
0294 if (t->pl.pmtu == t->pl.probe_size) {
0295 t->pl.state = SCTP_PL_BASE;
0296 t->pl.probe_size = SCTP_BASE_PLPMTU;
0297
0298 t->pl.pmtu = SCTP_BASE_PLPMTU;
0299 t->pathmtu = t->pl.pmtu + sctp_transport_pl_hlen(t);
0300 sctp_assoc_sync_pmtu(t->asoc);
0301 }
0302 }
0303
0304 out:
0305 pr_debug("%s: PLPMTUD: transport: %p, state: %d, pmtu: %d, size: %d, high: %d\n",
0306 __func__, t, t->pl.state, t->pl.pmtu, t->pl.probe_size, t->pl.probe_high);
0307 t->pl.probe_count++;
0308 }
0309
0310 bool sctp_transport_pl_recv(struct sctp_transport *t)
0311 {
0312 pr_debug("%s: PLPMTUD: transport: %p, state: %d, pmtu: %d, size: %d, high: %d\n",
0313 __func__, t, t->pl.state, t->pl.pmtu, t->pl.probe_size, t->pl.probe_high);
0314
0315 t->pl.pmtu = t->pl.probe_size;
0316 t->pl.probe_count = 0;
0317 if (t->pl.state == SCTP_PL_BASE) {
0318 t->pl.state = SCTP_PL_SEARCH;
0319 t->pl.probe_size += SCTP_PL_BIG_STEP;
0320 } else if (t->pl.state == SCTP_PL_ERROR) {
0321 t->pl.state = SCTP_PL_SEARCH;
0322
0323 t->pl.pmtu = t->pl.probe_size;
0324 t->pathmtu = t->pl.pmtu + sctp_transport_pl_hlen(t);
0325 sctp_assoc_sync_pmtu(t->asoc);
0326 t->pl.probe_size += SCTP_PL_BIG_STEP;
0327 } else if (t->pl.state == SCTP_PL_SEARCH) {
0328 if (!t->pl.probe_high) {
0329 t->pl.probe_size = min(t->pl.probe_size + SCTP_PL_BIG_STEP,
0330 SCTP_MAX_PLPMTU);
0331 return false;
0332 }
0333 t->pl.probe_size += SCTP_PL_MIN_STEP;
0334 if (t->pl.probe_size >= t->pl.probe_high) {
0335 t->pl.probe_high = 0;
0336 t->pl.state = SCTP_PL_COMPLETE;
0337
0338 t->pl.probe_size = t->pl.pmtu;
0339 t->pathmtu = t->pl.pmtu + sctp_transport_pl_hlen(t);
0340 sctp_assoc_sync_pmtu(t->asoc);
0341 sctp_transport_reset_raise_timer(t);
0342 }
0343 } else if (t->pl.state == SCTP_PL_COMPLETE) {
0344
0345 t->pl.state = SCTP_PL_SEARCH;
0346 t->pl.probe_size += SCTP_PL_MIN_STEP;
0347 }
0348
0349 return t->pl.state == SCTP_PL_COMPLETE;
0350 }
0351
0352 static bool sctp_transport_pl_toobig(struct sctp_transport *t, u32 pmtu)
0353 {
0354 pr_debug("%s: PLPMTUD: transport: %p, state: %d, pmtu: %d, size: %d, ptb: %d\n",
0355 __func__, t, t->pl.state, t->pl.pmtu, t->pl.probe_size, pmtu);
0356
0357 if (pmtu < SCTP_MIN_PLPMTU || pmtu >= t->pl.probe_size)
0358 return false;
0359
0360 if (t->pl.state == SCTP_PL_BASE) {
0361 if (pmtu >= SCTP_MIN_PLPMTU && pmtu < SCTP_BASE_PLPMTU) {
0362 t->pl.state = SCTP_PL_ERROR;
0363
0364 t->pl.pmtu = SCTP_BASE_PLPMTU;
0365 t->pathmtu = t->pl.pmtu + sctp_transport_pl_hlen(t);
0366 return true;
0367 }
0368 } else if (t->pl.state == SCTP_PL_SEARCH) {
0369 if (pmtu >= SCTP_BASE_PLPMTU && pmtu < t->pl.pmtu) {
0370 t->pl.state = SCTP_PL_BASE;
0371 t->pl.probe_size = SCTP_BASE_PLPMTU;
0372 t->pl.probe_count = 0;
0373
0374 t->pl.probe_high = 0;
0375 t->pl.pmtu = SCTP_BASE_PLPMTU;
0376 t->pathmtu = t->pl.pmtu + sctp_transport_pl_hlen(t);
0377 return true;
0378 } else if (pmtu > t->pl.pmtu && pmtu < t->pl.probe_size) {
0379 t->pl.probe_size = pmtu;
0380 t->pl.probe_count = 0;
0381 }
0382 } else if (t->pl.state == SCTP_PL_COMPLETE) {
0383 if (pmtu >= SCTP_BASE_PLPMTU && pmtu < t->pl.pmtu) {
0384 t->pl.state = SCTP_PL_BASE;
0385 t->pl.probe_size = SCTP_BASE_PLPMTU;
0386 t->pl.probe_count = 0;
0387
0388 t->pl.probe_high = 0;
0389 t->pl.pmtu = SCTP_BASE_PLPMTU;
0390 t->pathmtu = t->pl.pmtu + sctp_transport_pl_hlen(t);
0391 sctp_transport_reset_probe_timer(t);
0392 return true;
0393 }
0394 }
0395
0396 return false;
0397 }
0398
0399 bool sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu)
0400 {
0401 struct sock *sk = t->asoc->base.sk;
0402 struct dst_entry *dst;
0403 bool change = true;
0404
0405 if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) {
0406 pr_warn_ratelimited("%s: Reported pmtu %d too low, using default minimum of %d\n",
0407 __func__, pmtu, SCTP_DEFAULT_MINSEGMENT);
0408
0409 pmtu = SCTP_DEFAULT_MINSEGMENT;
0410 }
0411 pmtu = SCTP_TRUNC4(pmtu);
0412
0413 if (sctp_transport_pl_enabled(t))
0414 return sctp_transport_pl_toobig(t, pmtu - sctp_transport_pl_hlen(t));
0415
0416 dst = sctp_transport_dst_check(t);
0417 if (dst) {
0418 struct sctp_pf *pf = sctp_get_pf_specific(dst->ops->family);
0419 union sctp_addr addr;
0420
0421 pf->af->from_sk(&addr, sk);
0422 pf->to_sk_daddr(&t->ipaddr, sk);
0423 dst->ops->update_pmtu(dst, sk, NULL, pmtu, true);
0424 pf->to_sk_daddr(&addr, sk);
0425
0426 dst = sctp_transport_dst_check(t);
0427 }
0428
0429 if (!dst) {
0430 t->af_specific->get_dst(t, &t->saddr, &t->fl, sk);
0431 dst = t->dst;
0432 }
0433
0434 if (dst) {
0435
0436 pmtu = sctp_dst_mtu(dst);
0437 change = t->pathmtu != pmtu;
0438 }
0439 t->pathmtu = pmtu;
0440
0441 return change;
0442 }
0443
0444
0445
0446
0447 void sctp_transport_route(struct sctp_transport *transport,
0448 union sctp_addr *saddr, struct sctp_sock *opt)
0449 {
0450 struct sctp_association *asoc = transport->asoc;
0451 struct sctp_af *af = transport->af_specific;
0452
0453 sctp_transport_dst_release(transport);
0454 af->get_dst(transport, saddr, &transport->fl, sctp_opt2sk(opt));
0455
0456 if (saddr)
0457 memcpy(&transport->saddr, saddr, sizeof(union sctp_addr));
0458 else
0459 af->get_saddr(opt, transport, &transport->fl);
0460
0461 sctp_transport_pmtu(transport, sctp_opt2sk(opt));
0462
0463
0464
0465
0466 if (transport->dst && asoc &&
0467 (!asoc->peer.primary_path || transport == asoc->peer.active_path))
0468 opt->pf->to_sk_saddr(&transport->saddr, asoc->base.sk);
0469 }
0470
0471
0472 int sctp_transport_hold(struct sctp_transport *transport)
0473 {
0474 return refcount_inc_not_zero(&transport->refcnt);
0475 }
0476
0477
0478
0479
0480 void sctp_transport_put(struct sctp_transport *transport)
0481 {
0482 if (refcount_dec_and_test(&transport->refcnt))
0483 sctp_transport_destroy(transport);
0484 }
0485
0486
0487 void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
0488 {
0489 if (unlikely(!tp->rto_pending))
0490
0491 pr_debug("%s: rto_pending not set on transport %p!\n", __func__, tp);
0492
0493 if (tp->rttvar || tp->srtt) {
0494 struct net *net = tp->asoc->base.net;
0495
0496
0497
0498
0499
0500
0501
0502
0503
0504
0505
0506 tp->rttvar = tp->rttvar - (tp->rttvar >> net->sctp.rto_beta)
0507 + (((__u32)abs((__s64)tp->srtt - (__s64)rtt)) >> net->sctp.rto_beta);
0508 tp->srtt = tp->srtt - (tp->srtt >> net->sctp.rto_alpha)
0509 + (rtt >> net->sctp.rto_alpha);
0510 } else {
0511
0512
0513
0514 tp->srtt = rtt;
0515 tp->rttvar = rtt >> 1;
0516 }
0517
0518
0519
0520
0521 if (tp->rttvar == 0)
0522 tp->rttvar = SCTP_CLOCK_GRANULARITY;
0523
0524
0525 tp->rto = tp->srtt + (tp->rttvar << 2);
0526
0527
0528
0529
0530 if (tp->rto < tp->asoc->rto_min)
0531 tp->rto = tp->asoc->rto_min;
0532
0533
0534
0535
0536 if (tp->rto > tp->asoc->rto_max)
0537 tp->rto = tp->asoc->rto_max;
0538
0539 sctp_max_rto(tp->asoc, tp);
0540 tp->rtt = rtt;
0541
0542
0543
0544
0545 tp->rto_pending = 0;
0546
0547 pr_debug("%s: transport:%p, rtt:%d, srtt:%d rttvar:%d, rto:%ld\n",
0548 __func__, tp, rtt, tp->srtt, tp->rttvar, tp->rto);
0549 }
0550
0551
0552
0553
0554 void sctp_transport_raise_cwnd(struct sctp_transport *transport,
0555 __u32 sack_ctsn, __u32 bytes_acked)
0556 {
0557 struct sctp_association *asoc = transport->asoc;
0558 __u32 cwnd, ssthresh, flight_size, pba, pmtu;
0559
0560 cwnd = transport->cwnd;
0561 flight_size = transport->flight_size;
0562
0563
0564 if (asoc->fast_recovery &&
0565 TSN_lte(asoc->fast_recovery_exit, sack_ctsn))
0566 asoc->fast_recovery = 0;
0567
0568 ssthresh = transport->ssthresh;
0569 pba = transport->partial_bytes_acked;
0570 pmtu = transport->asoc->pathmtu;
0571
0572 if (cwnd <= ssthresh) {
0573
0574
0575
0576
0577
0578
0579
0580
0581
0582
0583
0584
0585
0586
0587 if (asoc->fast_recovery)
0588 return;
0589
0590
0591
0592
0593
0594
0595 if (flight_size < cwnd)
0596 return;
0597
0598 if (bytes_acked > pmtu)
0599 cwnd += pmtu;
0600 else
0601 cwnd += bytes_acked;
0602
0603 pr_debug("%s: slow start: transport:%p, bytes_acked:%d, "
0604 "cwnd:%d, ssthresh:%d, flight_size:%d, pba:%d\n",
0605 __func__, transport, bytes_acked, cwnd, ssthresh,
0606 flight_size, pba);
0607 } else {
0608
0609
0610
0611
0612
0613
0614
0615
0616
0617
0618
0619
0620
0621
0622
0623
0624
0625
0626
0627
0628
0629
0630 pba += bytes_acked;
0631 if (pba > cwnd && flight_size < cwnd)
0632 pba = cwnd;
0633 if (pba >= cwnd && flight_size >= cwnd) {
0634 pba = pba - cwnd;
0635 cwnd += pmtu;
0636 }
0637
0638 pr_debug("%s: congestion avoidance: transport:%p, "
0639 "bytes_acked:%d, cwnd:%d, ssthresh:%d, "
0640 "flight_size:%d, pba:%d\n", __func__,
0641 transport, bytes_acked, cwnd, ssthresh,
0642 flight_size, pba);
0643 }
0644
0645 transport->cwnd = cwnd;
0646 transport->partial_bytes_acked = pba;
0647 }
0648
0649
0650
0651
0652 void sctp_transport_lower_cwnd(struct sctp_transport *transport,
0653 enum sctp_lower_cwnd reason)
0654 {
0655 struct sctp_association *asoc = transport->asoc;
0656
0657 switch (reason) {
0658 case SCTP_LOWER_CWND_T3_RTX:
0659
0660
0661
0662
0663
0664
0665
0666 transport->ssthresh = max(transport->cwnd/2,
0667 4*asoc->pathmtu);
0668 transport->cwnd = asoc->pathmtu;
0669
0670
0671 asoc->fast_recovery = 0;
0672 break;
0673
0674 case SCTP_LOWER_CWND_FAST_RTX:
0675
0676
0677
0678
0679
0680
0681
0682
0683
0684
0685
0686
0687 if (asoc->fast_recovery)
0688 return;
0689
0690
0691 asoc->fast_recovery = 1;
0692 asoc->fast_recovery_exit = asoc->next_tsn - 1;
0693
0694 transport->ssthresh = max(transport->cwnd/2,
0695 4*asoc->pathmtu);
0696 transport->cwnd = transport->ssthresh;
0697 break;
0698
0699 case SCTP_LOWER_CWND_ECNE:
0700
0701
0702
0703
0704
0705
0706
0707
0708
0709
0710
0711
0712 if (time_after(jiffies, transport->last_time_ecne_reduced +
0713 transport->rtt)) {
0714 transport->ssthresh = max(transport->cwnd/2,
0715 4*asoc->pathmtu);
0716 transport->cwnd = transport->ssthresh;
0717 transport->last_time_ecne_reduced = jiffies;
0718 }
0719 break;
0720
0721 case SCTP_LOWER_CWND_INACTIVE:
0722
0723
0724
0725
0726
0727
0728
0729
0730 transport->cwnd = max(transport->cwnd/2,
0731 4*asoc->pathmtu);
0732
0733 transport->ssthresh = transport->cwnd;
0734 break;
0735 }
0736
0737 transport->partial_bytes_acked = 0;
0738
0739 pr_debug("%s: transport:%p, reason:%d, cwnd:%d, ssthresh:%d\n",
0740 __func__, transport, reason, transport->cwnd,
0741 transport->ssthresh);
0742 }
0743
0744
0745
0746
0747
0748
0749
0750
0751
0752
0753
0754 void sctp_transport_burst_limited(struct sctp_transport *t)
0755 {
0756 struct sctp_association *asoc = t->asoc;
0757 u32 old_cwnd = t->cwnd;
0758 u32 max_burst_bytes;
0759
0760 if (t->burst_limited || asoc->max_burst == 0)
0761 return;
0762
0763 max_burst_bytes = t->flight_size + (asoc->max_burst * asoc->pathmtu);
0764 if (max_burst_bytes < old_cwnd) {
0765 t->cwnd = max_burst_bytes;
0766 t->burst_limited = old_cwnd;
0767 }
0768 }
0769
0770
0771
0772
0773 void sctp_transport_burst_reset(struct sctp_transport *t)
0774 {
0775 if (t->burst_limited) {
0776 t->cwnd = t->burst_limited;
0777 t->burst_limited = 0;
0778 }
0779 }
0780
0781
0782 unsigned long sctp_transport_timeout(struct sctp_transport *trans)
0783 {
0784
0785 unsigned long timeout = trans->rto >> 1;
0786
0787 if (trans->state != SCTP_UNCONFIRMED &&
0788 trans->state != SCTP_PF)
0789 timeout += trans->hbinterval;
0790
0791 return max_t(unsigned long, timeout, HZ / 5);
0792 }
0793
0794
0795 void sctp_transport_reset(struct sctp_transport *t)
0796 {
0797 struct sctp_association *asoc = t->asoc;
0798
0799
0800
0801
0802
0803
0804 t->cwnd = min(4*asoc->pathmtu, max_t(__u32, 2*asoc->pathmtu, 4380));
0805 t->burst_limited = 0;
0806 t->ssthresh = asoc->peer.i.a_rwnd;
0807 t->rto = asoc->rto_initial;
0808 sctp_max_rto(asoc, t);
0809 t->rtt = 0;
0810 t->srtt = 0;
0811 t->rttvar = 0;
0812
0813
0814 t->partial_bytes_acked = 0;
0815 t->flight_size = 0;
0816 t->error_count = 0;
0817 t->rto_pending = 0;
0818 t->hb_sent = 0;
0819
0820
0821 t->cacc.changeover_active = 0;
0822 t->cacc.cycling_changeover = 0;
0823 t->cacc.next_tsn_at_change = 0;
0824 t->cacc.cacc_saw_newack = 0;
0825 }
0826
0827
0828 void sctp_transport_immediate_rtx(struct sctp_transport *t)
0829 {
0830
0831 if (del_timer(&t->T3_rtx_timer))
0832 sctp_transport_put(t);
0833
0834 sctp_retransmit(&t->asoc->outqueue, t, SCTP_RTXR_T3_RTX);
0835 if (!timer_pending(&t->T3_rtx_timer)) {
0836 if (!mod_timer(&t->T3_rtx_timer, jiffies + t->rto))
0837 sctp_transport_hold(t);
0838 }
0839 }
0840
0841
0842 void sctp_transport_dst_release(struct sctp_transport *t)
0843 {
0844 dst_release(t->dst);
0845 t->dst = NULL;
0846 t->dst_pending_confirm = 0;
0847 }
0848
0849
0850 void sctp_transport_dst_confirm(struct sctp_transport *t)
0851 {
0852 t->dst_pending_confirm = 1;
0853 }