diff options
author | Gerrit Renker <gerrit@erg.abdn.ac.uk> | 2008-09-04 01:30:19 -0400 |
---|---|---|
committer | Gerrit Renker <gerrit@erg.abdn.ac.uk> | 2008-09-04 01:45:34 -0400 |
commit | 3306c781ff13aea89606435c134ec84e3c608681 (patch) | |
tree | 281cfebaf9504e4747938509efca0cc255b3372f | |
parent | 47a61e7b433a014296971ea1226eb1adb6310ab4 (diff) |
dccp: Add packet type information to CCID-specific option parsing
This patch ...
1. adds packet type information to ccid_hc_{rx,tx}_parse_options(). This is
necessary, since table 3 in RFC 4340, 5.8 leaves it to the CCIDs to state
which options may (not) appear on what packet type.
2. adds such a check for CCID-3's {Loss Event, Receive} Rate as specified in
RFC 4340 8.3 ("Receive Rate options MUST NOT be sent on DCCP-Data packets")
and 8.5 ("Loss Event Rate options MUST NOT be sent on DCCP-Data packets").
3. removes an unused argument `idx' from ccid_hc_{rx,tx}_parse_options(). This
is also no longer necessary, since the CCID-specific option-parsing routines
are passed every single parameter of the type-length-value option encoding.
Also added documentation and made argument naming scheme consistent.
Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
-rw-r--r-- | net/dccp/ccid.h | 46 | ||||
-rw-r--r-- | net/dccp/ccids/ccid3.c | 14 | ||||
-rw-r--r-- | net/dccp/options.c | 16 |
3 files changed, 35 insertions, 41 deletions
diff --git a/net/dccp/ccid.h b/net/dccp/ccid.h index 20ba066b2775..bce517c99996 100644 --- a/net/dccp/ccid.h +++ b/net/dccp/ccid.h | |||
@@ -60,18 +60,14 @@ struct ccid_operations { | |||
60 | void (*ccid_hc_tx_exit)(struct sock *sk); | 60 | void (*ccid_hc_tx_exit)(struct sock *sk); |
61 | void (*ccid_hc_rx_packet_recv)(struct sock *sk, | 61 | void (*ccid_hc_rx_packet_recv)(struct sock *sk, |
62 | struct sk_buff *skb); | 62 | struct sk_buff *skb); |
63 | int (*ccid_hc_rx_parse_options)(struct sock *sk, | 63 | int (*ccid_hc_rx_parse_options)(struct sock *sk, u8 pkt, |
64 | unsigned char option, | 64 | u8 opt, u8 *val, u8 len); |
65 | unsigned char len, u16 idx, | ||
66 | unsigned char* value); | ||
67 | int (*ccid_hc_rx_insert_options)(struct sock *sk, | 65 | int (*ccid_hc_rx_insert_options)(struct sock *sk, |
68 | struct sk_buff *skb); | 66 | struct sk_buff *skb); |
69 | void (*ccid_hc_tx_packet_recv)(struct sock *sk, | 67 | void (*ccid_hc_tx_packet_recv)(struct sock *sk, |
70 | struct sk_buff *skb); | 68 | struct sk_buff *skb); |
71 | int (*ccid_hc_tx_parse_options)(struct sock *sk, | 69 | int (*ccid_hc_tx_parse_options)(struct sock *sk, u8 pkt, |
72 | unsigned char option, | 70 | u8 opt, u8 *val, u8 len); |
73 | unsigned char len, u16 idx, | ||
74 | unsigned char* value); | ||
75 | int (*ccid_hc_tx_send_packet)(struct sock *sk, | 71 | int (*ccid_hc_tx_send_packet)(struct sock *sk, |
76 | struct sk_buff *skb); | 72 | struct sk_buff *skb); |
77 | void (*ccid_hc_tx_packet_sent)(struct sock *sk, | 73 | void (*ccid_hc_tx_packet_sent)(struct sock *sk, |
@@ -163,27 +159,31 @@ static inline void ccid_hc_tx_packet_recv(struct ccid *ccid, struct sock *sk, | |||
163 | ccid->ccid_ops->ccid_hc_tx_packet_recv(sk, skb); | 159 | ccid->ccid_ops->ccid_hc_tx_packet_recv(sk, skb); |
164 | } | 160 | } |
165 | 161 | ||
162 | /** | ||
163 | * ccid_hc_tx_parse_options - Parse CCID-specific options sent by the receiver | ||
164 | * @pkt: type of packet that @opt appears on (RFC 4340, 5.1) | ||
165 | * @opt: the CCID-specific option type (RFC 4340, 5.8 and 10.3) | ||
166 | * @val: value of @opt | ||
167 | * @len: length of @val in bytes | ||
168 | */ | ||
166 | static inline int ccid_hc_tx_parse_options(struct ccid *ccid, struct sock *sk, | 169 | static inline int ccid_hc_tx_parse_options(struct ccid *ccid, struct sock *sk, |
167 | unsigned char option, | 170 | u8 pkt, u8 opt, u8 *val, u8 len) |
168 | unsigned char len, u16 idx, | ||
169 | unsigned char* value) | ||
170 | { | 171 | { |
171 | int rc = 0; | 172 | if (ccid->ccid_ops->ccid_hc_tx_parse_options == NULL) |
172 | if (ccid->ccid_ops->ccid_hc_tx_parse_options != NULL) | 173 | return 0; |
173 | rc = ccid->ccid_ops->ccid_hc_tx_parse_options(sk, option, len, idx, | 174 | return ccid->ccid_ops->ccid_hc_tx_parse_options(sk, pkt, opt, val, len); |
174 | value); | ||
175 | return rc; | ||
176 | } | 175 | } |
177 | 176 | ||
177 | /** | ||
178 | * ccid_hc_rx_parse_options - Parse CCID-specific options sent by the sender | ||
179 | * Arguments are analogous to ccid_hc_tx_parse_options() | ||
180 | */ | ||
178 | static inline int ccid_hc_rx_parse_options(struct ccid *ccid, struct sock *sk, | 181 | static inline int ccid_hc_rx_parse_options(struct ccid *ccid, struct sock *sk, |
179 | unsigned char option, | 182 | u8 pkt, u8 opt, u8 *val, u8 len) |
180 | unsigned char len, u16 idx, | ||
181 | unsigned char* value) | ||
182 | { | 183 | { |
183 | int rc = 0; | 184 | if (ccid->ccid_ops->ccid_hc_rx_parse_options == NULL) |
184 | if (ccid->ccid_ops->ccid_hc_rx_parse_options != NULL) | 185 | return 0; |
185 | rc = ccid->ccid_ops->ccid_hc_rx_parse_options(sk, option, len, idx, value); | 186 | return ccid->ccid_ops->ccid_hc_rx_parse_options(sk, pkt, opt, val, len); |
186 | return rc; | ||
187 | } | 187 | } |
188 | 188 | ||
189 | static inline int ccid_hc_rx_insert_options(struct ccid *ccid, struct sock *sk, | 189 | static inline int ccid_hc_rx_insert_options(struct ccid *ccid, struct sock *sk, |
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index 12b601f11bfd..4c422fb2189f 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c | |||
@@ -483,9 +483,8 @@ done_computing_x: | |||
483 | jiffies + usecs_to_jiffies(t_nfb)); | 483 | jiffies + usecs_to_jiffies(t_nfb)); |
484 | } | 484 | } |
485 | 485 | ||
486 | static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option, | 486 | static int ccid3_hc_tx_parse_options(struct sock *sk, u8 packet_type, |
487 | unsigned char len, u16 idx, | 487 | u8 option, u8 *optval, u8 optlen) |
488 | unsigned char *value) | ||
489 | { | 488 | { |
490 | struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); | 489 | struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); |
491 | struct ccid3_options_received *opt_recv = &hctx->options_received; | 490 | struct ccid3_options_received *opt_recv = &hctx->options_received; |
@@ -494,12 +493,15 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option, | |||
494 | switch (option) { | 493 | switch (option) { |
495 | case TFRC_OPT_RECEIVE_RATE: | 494 | case TFRC_OPT_RECEIVE_RATE: |
496 | case TFRC_OPT_LOSS_EVENT_RATE: | 495 | case TFRC_OPT_LOSS_EVENT_RATE: |
497 | if (unlikely(len != 4)) { | 496 | /* Must be ignored on Data packets, cf. RFC 4342 8.3 and 8.5 */ |
497 | if (packet_type == DCCP_PKT_DATA) | ||
498 | break; | ||
499 | if (unlikely(optlen != 4)) { | ||
498 | DCCP_WARN("%s(%p), invalid len %d for %u\n", | 500 | DCCP_WARN("%s(%p), invalid len %d for %u\n", |
499 | dccp_role(sk), sk, len, option); | 501 | dccp_role(sk), sk, optlen, option); |
500 | return -EINVAL; | 502 | return -EINVAL; |
501 | } | 503 | } |
502 | opt_val = ntohl(get_unaligned((__be32 *)value)); | 504 | opt_val = ntohl(get_unaligned((__be32 *)optval)); |
503 | 505 | ||
504 | if (option == TFRC_OPT_RECEIVE_RATE) { | 506 | if (option == TFRC_OPT_RECEIVE_RATE) { |
505 | opt_recv->ccid3or_receive_rate = opt_val; | 507 | opt_recv->ccid3or_receive_rate = opt_val; |
diff --git a/net/dccp/options.c b/net/dccp/options.c index fd51cc70c63e..b102774694c6 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c | |||
@@ -226,23 +226,15 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq, | |||
226 | dccp_pr_debug("%s rx opt: ELAPSED_TIME=%d\n", | 226 | dccp_pr_debug("%s rx opt: ELAPSED_TIME=%d\n", |
227 | dccp_role(sk), elapsed_time); | 227 | dccp_role(sk), elapsed_time); |
228 | break; | 228 | break; |
229 | case 128 ... 191: { | 229 | case 128 ... 191: |
230 | const u16 idx = value - options; | ||
231 | |||
232 | if (ccid_hc_rx_parse_options(dp->dccps_hc_rx_ccid, sk, | 230 | if (ccid_hc_rx_parse_options(dp->dccps_hc_rx_ccid, sk, |
233 | opt, len, idx, | 231 | pkt_type, opt, value, len)) |
234 | value) != 0) | ||
235 | goto out_invalid_option; | 232 | goto out_invalid_option; |
236 | } | ||
237 | break; | 233 | break; |
238 | case 192 ... 255: { | 234 | case 192 ... 255: |
239 | const u16 idx = value - options; | ||
240 | |||
241 | if (ccid_hc_tx_parse_options(dp->dccps_hc_tx_ccid, sk, | 235 | if (ccid_hc_tx_parse_options(dp->dccps_hc_tx_ccid, sk, |
242 | opt, len, idx, | 236 | pkt_type, opt, value, len)) |
243 | value) != 0) | ||
244 | goto out_invalid_option; | 237 | goto out_invalid_option; |
245 | } | ||
246 | break; | 238 | break; |
247 | default: | 239 | default: |
248 | DCCP_CRIT("DCCP(%p): option %d(len=%d) not " | 240 | DCCP_CRIT("DCCP(%p): option %d(len=%d) not " |