Skip to content

Commit 9f70f46

Browse files
nhormandavem330
authored andcommitted
sctp: properly latch and use autoclose value from sock to association
Currently, sctp associations latch a sockets autoclose value to an association at association init time, subject to capping constraints from the max_autoclose sysctl value. This leads to an odd situation where an application may set a socket level autoclose timeout, but sliently sctp will limit the autoclose timeout to something less than that. Fix this by modifying the autoclose setsockopt function to check the limit, cap it and warn the user via syslog that the timeout is capped. This will allow getsockopt to return valid autoclose timeout values that reflect what subsequent associations actually use. While were at it, also elimintate the assoc->autoclose variable, it duplicates whats in the timeout array, which leads to multiple sources for the same information, that may differ (as the former isn't subject to any capping). This gives us the timeout information in a canonical place and saves some space in the association structure as well. Signed-off-by: Neil Horman <nhorman@tuxdriver.com> Acked-by: Vlad Yasevich <vyasevich@gmail.com> CC: Wang Weidong <wangweidong1@huawei.com> CC: David Miller <davem@davemloft.net> CC: Vlad Yasevich <vyasevich@gmail.com> CC: netdev@vger.kernel.org Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 231df15 commit 9f70f46

File tree

5 files changed

+13
-17
lines changed

5 files changed

+13
-17
lines changed

include/net/sctp/structs.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1726,12 +1726,6 @@ struct sctp_association {
17261726
/* How many duplicated TSNs have we seen? */
17271727
int numduptsns;
17281728

1729-
/* Number of seconds of idle time before an association is closed.
1730-
* In the association context, this is really used as a boolean
1731-
* since the real timeout is stored in the timeouts array
1732-
*/
1733-
__u32 autoclose;
1734-
17351729
/* These are to support
17361730
* "SCTP Extensions for Dynamic Reconfiguration of IP Addresses
17371731
* and Enforcement of Flow and Message Limits"

net/sctp/associola.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
154154

155155
asoc->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0;
156156
asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = asoc->sackdelay;
157-
asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] =
158-
min_t(unsigned long, sp->autoclose, net->sctp.max_autoclose) * HZ;
157+
asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = sp->autoclose * HZ;
159158

160159
/* Initializes the timers */
161160
for (i = SCTP_EVENT_TIMEOUT_NONE; i < SCTP_NUM_TIMEOUT_TYPES; ++i)
@@ -291,8 +290,6 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
291290
asoc->peer.ipv6_address = 1;
292291
INIT_LIST_HEAD(&asoc->asocs);
293292

294-
asoc->autoclose = sp->autoclose;
295-
296293
asoc->default_stream = sp->default_stream;
297294
asoc->default_ppid = sp->default_ppid;
298295
asoc->default_flags = sp->default_flags;

net/sctp/output.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,8 @@ int sctp_packet_transmit(struct sctp_packet *packet)
581581
unsigned long timeout;
582582

583583
/* Restart the AUTOCLOSE timer when sending data. */
584-
if (sctp_state(asoc, ESTABLISHED) && asoc->autoclose) {
584+
if (sctp_state(asoc, ESTABLISHED) &&
585+
asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) {
585586
timer = &asoc->timers[SCTP_EVENT_TIMEOUT_AUTOCLOSE];
586587
timeout = asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE];
587588

net/sctp/sm_statefuns.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -820,7 +820,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(struct net *net,
820820
SCTP_INC_STATS(net, SCTP_MIB_PASSIVEESTABS);
821821
sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL());
822822

823-
if (new_asoc->autoclose)
823+
if (new_asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE])
824824
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
825825
SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
826826

@@ -908,7 +908,7 @@ sctp_disposition_t sctp_sf_do_5_1E_ca(struct net *net,
908908
SCTP_INC_STATS(net, SCTP_MIB_CURRESTAB);
909909
SCTP_INC_STATS(net, SCTP_MIB_ACTIVEESTABS);
910910
sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL());
911-
if (asoc->autoclose)
911+
if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE])
912912
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
913913
SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
914914

@@ -2970,7 +2970,7 @@ sctp_disposition_t sctp_sf_eat_data_6_2(struct net *net,
29702970
if (chunk->chunk_hdr->flags & SCTP_DATA_SACK_IMM)
29712971
force = SCTP_FORCE();
29722972

2973-
if (asoc->autoclose) {
2973+
if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) {
29742974
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
29752975
SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
29762976
}
@@ -3878,7 +3878,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn(struct net *net,
38783878
SCTP_CHUNK(chunk));
38793879

38803880
/* Count this as receiving DATA. */
3881-
if (asoc->autoclose) {
3881+
if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) {
38823882
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
38833883
SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
38843884
}
@@ -5267,7 +5267,7 @@ sctp_disposition_t sctp_sf_do_9_2_start_shutdown(
52675267
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
52685268
SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
52695269

5270-
if (asoc->autoclose)
5270+
if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE])
52715271
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
52725272
SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
52735273

@@ -5346,7 +5346,7 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown_ack(
53465346
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
53475347
SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
53485348

5349-
if (asoc->autoclose)
5349+
if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE])
53505350
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
53515351
SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
53525352

net/sctp/socket.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2196,6 +2196,7 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval,
21962196
unsigned int optlen)
21972197
{
21982198
struct sctp_sock *sp = sctp_sk(sk);
2199+
struct net *net = sock_net(sk);
21992200

22002201
/* Applicable to UDP-style socket only */
22012202
if (sctp_style(sk, TCP))
@@ -2205,6 +2206,9 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval,
22052206
if (copy_from_user(&sp->autoclose, optval, optlen))
22062207
return -EFAULT;
22072208

2209+
if (sp->autoclose > net->sctp.max_autoclose)
2210+
sp->autoclose = net->sctp.max_autoclose;
2211+
22082212
return 0;
22092213
}
22102214

0 commit comments

Comments
 (0)