diff options
author | Vlad Yasevich <vladislav.yasevich@hp.com> | 2006-08-26 02:40:29 +0200 |
---|---|---|
committer | Adrian Bunk <bunk@stusta.de> | 2006-08-26 02:40:29 +0200 |
commit | 2d17897a633579202cb548e759756a1cc823568b (patch) | |
tree | 0e5af47c5968d6849199281ee009cedbed7f9bb5 /net/sctp/socket.c | |
parent | fe7e513c0b87b1b41f162eb6d5ee9d48cdaaf578 (diff) |
SCTP: Limit association max_retrans setting in setsockopt.
When using ASSOCINFO socket option, we need to limit the number of
maximum association retransmissions to be no greater than the sum
of all the path retransmissions. This is specified in Section 7.1.2
of the SCTP socket API draft.
However, we only do this if the association has multiple paths. If
there is only one path, the protocol stack will use the
assoc_max_retrans setting when trying to retransmit packets.
Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Adrian Bunk <bunk@stusta.de>
Diffstat (limited to 'net/sctp/socket.c')
-rw-r--r-- | net/sctp/socket.c | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 42a22355e027..04707003ffae 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -2537,8 +2537,32 @@ static int sctp_setsockopt_associnfo(struct sock *sk, char __user *optval, int o /* Set the values to the specific association */ if (asoc) { - if (assocparams.sasoc_asocmaxrxt != 0) + if (assocparams.sasoc_asocmaxrxt != 0) { + __u32 path_sum = 0; + int paths = 0; + struct list_head *pos; + struct sctp_transport *peer_addr; + + list_for_each(pos, &asoc->peer.transport_addr_list) { + peer_addr = list_entry(pos, + struct sctp_transport, + transports); + path_sum += peer_addr->pathmaxrxt; + paths++; + } + + /* Only validate asocmaxrxt if we have more then + * one path/transport. We do this because path + * retransmissions are only counted when we have more + * then one path. + */ + if (paths > 1 && + assocparams.sasoc_asocmaxrxt > path_sum) + return -EINVAL; + asoc->max_retrans = assocparams.sasoc_asocmaxrxt; + } + if (assocparams.sasoc_cookie_life != 0) { asoc->cookie_life.tv_sec = assocparams.sasoc_cookie_life / 1000; |