diff options
Diffstat (limited to 'net/dccp')
-rw-r--r-- | net/dccp/input.c | 6 | ||||
-rw-r--r-- | net/dccp/ipv4.c | 8 | ||||
-rw-r--r-- | net/dccp/ipv6.c | 8 | ||||
-rw-r--r-- | net/dccp/options.c | 34 |
4 files changed, 34 insertions, 22 deletions
diff --git a/net/dccp/input.c b/net/dccp/input.c index dacd4fd3c63c..08392ed86c25 100644 --- a/net/dccp/input.c +++ b/net/dccp/input.c | |||
@@ -369,7 +369,7 @@ int dccp_rcv_established(struct sock *sk, struct sk_buff *skb, | |||
369 | if (dccp_check_seqno(sk, skb)) | 369 | if (dccp_check_seqno(sk, skb)) |
370 | goto discard; | 370 | goto discard; |
371 | 371 | ||
372 | if (dccp_parse_options(sk, skb)) | 372 | if (dccp_parse_options(sk, NULL, skb)) |
373 | goto discard; | 373 | goto discard; |
374 | 374 | ||
375 | if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) | 375 | if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) |
@@ -427,7 +427,7 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk, | |||
427 | goto out_invalid_packet; | 427 | goto out_invalid_packet; |
428 | } | 428 | } |
429 | 429 | ||
430 | if (dccp_parse_options(sk, skb)) | 430 | if (dccp_parse_options(sk, NULL, skb)) |
431 | goto out_invalid_packet; | 431 | goto out_invalid_packet; |
432 | 432 | ||
433 | /* Obtain usec RTT sample from SYN exchange (used by CCID 3) */ | 433 | /* Obtain usec RTT sample from SYN exchange (used by CCID 3) */ |
@@ -609,7 +609,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
609 | /* | 609 | /* |
610 | * Step 8: Process options and mark acknowledgeable | 610 | * Step 8: Process options and mark acknowledgeable |
611 | */ | 611 | */ |
612 | if (dccp_parse_options(sk, skb)) | 612 | if (dccp_parse_options(sk, NULL, skb)) |
613 | goto discard; | 613 | goto discard; |
614 | 614 | ||
615 | if (dcb->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) | 615 | if (dcb->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) |
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index db17b83e8d3e..02fc91ce2505 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c | |||
@@ -600,11 +600,12 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb) | |||
600 | if (req == NULL) | 600 | if (req == NULL) |
601 | goto drop; | 601 | goto drop; |
602 | 602 | ||
603 | if (dccp_parse_options(sk, skb)) | ||
604 | goto drop_and_free; | ||
605 | |||
606 | dccp_reqsk_init(req, skb); | 603 | dccp_reqsk_init(req, skb); |
607 | 604 | ||
605 | dreq = dccp_rsk(req); | ||
606 | if (dccp_parse_options(sk, dreq, skb)) | ||
607 | goto drop_and_free; | ||
608 | |||
608 | if (security_inet_conn_request(sk, skb, req)) | 609 | if (security_inet_conn_request(sk, skb, req)) |
609 | goto drop_and_free; | 610 | goto drop_and_free; |
610 | 611 | ||
@@ -621,7 +622,6 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb) | |||
621 | * In fact we defer setting S.GSR, S.SWL, S.SWH to | 622 | * In fact we defer setting S.GSR, S.SWL, S.SWH to |
622 | * dccp_create_openreq_child. | 623 | * dccp_create_openreq_child. |
623 | */ | 624 | */ |
624 | dreq = dccp_rsk(req); | ||
625 | dreq->dreq_isr = dcb->dccpd_seq; | 625 | dreq->dreq_isr = dcb->dccpd_seq; |
626 | dreq->dreq_iss = dccp_v4_init_sequence(skb); | 626 | dreq->dreq_iss = dccp_v4_init_sequence(skb); |
627 | dreq->dreq_service = service; | 627 | dreq->dreq_service = service; |
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index a08e2cb11915..f42b75ce7f5c 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c | |||
@@ -415,11 +415,12 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb) | |||
415 | if (req == NULL) | 415 | if (req == NULL) |
416 | goto drop; | 416 | goto drop; |
417 | 417 | ||
418 | if (dccp_parse_options(sk, skb)) | ||
419 | goto drop_and_free; | ||
420 | |||
421 | dccp_reqsk_init(req, skb); | 418 | dccp_reqsk_init(req, skb); |
422 | 419 | ||
420 | dreq = dccp_rsk(req); | ||
421 | if (dccp_parse_options(sk, dreq, skb)) | ||
422 | goto drop_and_free; | ||
423 | |||
423 | if (security_inet_conn_request(sk, skb, req)) | 424 | if (security_inet_conn_request(sk, skb, req)) |
424 | goto drop_and_free; | 425 | goto drop_and_free; |
425 | 426 | ||
@@ -449,7 +450,6 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb) | |||
449 | * In fact we defer setting S.GSR, S.SWL, S.SWH to | 450 | * In fact we defer setting S.GSR, S.SWL, S.SWH to |
450 | * dccp_create_openreq_child. | 451 | * dccp_create_openreq_child. |
451 | */ | 452 | */ |
452 | dreq = dccp_rsk(req); | ||
453 | dreq->dreq_isr = dcb->dccpd_seq; | 453 | dreq->dreq_isr = dcb->dccpd_seq; |
454 | dreq->dreq_iss = dccp_v6_init_sequence(skb); | 454 | dreq->dreq_iss = dccp_v6_init_sequence(skb); |
455 | dreq->dreq_service = service; | 455 | dreq->dreq_service = service; |
diff --git a/net/dccp/options.c b/net/dccp/options.c index 523250b45ea5..f496d4dc7efc 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c | |||
@@ -46,7 +46,13 @@ static u32 dccp_decode_value_var(const unsigned char *bf, const u8 len) | |||
46 | return value; | 46 | return value; |
47 | } | 47 | } |
48 | 48 | ||
49 | int dccp_parse_options(struct sock *sk, struct sk_buff *skb) | 49 | /** |
50 | * dccp_parse_options - Parse DCCP options present in @skb | ||
51 | * @sk: client|server|listening dccp socket (when @dreq != NULL) | ||
52 | * @dreq: request socket to use during connection setup, or NULL | ||
53 | */ | ||
54 | int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq, | ||
55 | struct sk_buff *skb) | ||
50 | { | 56 | { |
51 | struct dccp_sock *dp = dccp_sk(sk); | 57 | struct dccp_sock *dp = dccp_sk(sk); |
52 | const struct dccp_hdr *dh = dccp_hdr(skb); | 58 | const struct dccp_hdr *dh = dccp_hdr(skb); |
@@ -92,6 +98,20 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb) | |||
92 | goto out_invalid_option; | 98 | goto out_invalid_option; |
93 | } | 99 | } |
94 | 100 | ||
101 | /* | ||
102 | * CCID-Specific Options (from RFC 4340, sec. 10.3): | ||
103 | * | ||
104 | * Option numbers 128 through 191 are for options sent from the | ||
105 | * HC-Sender to the HC-Receiver; option numbers 192 through 255 | ||
106 | * are for options sent from the HC-Receiver to the HC-Sender. | ||
107 | * | ||
108 | * CCID-specific options are ignored during connection setup, as | ||
109 | * negotiation may still be in progress (see RFC 4340, 10.3). | ||
110 | * | ||
111 | */ | ||
112 | if (dreq != NULL && opt >= 128) | ||
113 | goto ignore_option; | ||
114 | |||
95 | switch (opt) { | 115 | switch (opt) { |
96 | case DCCPO_PADDING: | 116 | case DCCPO_PADDING: |
97 | break; | 117 | break; |
@@ -150,6 +170,7 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb) | |||
150 | opt_val = get_unaligned((__be32 *)value); | 170 | opt_val = get_unaligned((__be32 *)value); |
151 | opt_recv->dccpor_timestamp = ntohl(opt_val); | 171 | opt_recv->dccpor_timestamp = ntohl(opt_val); |
152 | 172 | ||
173 | /* FIXME: if dreq != NULL, don't store this on listening socket */ | ||
153 | dp->dccps_timestamp_echo = opt_recv->dccpor_timestamp; | 174 | dp->dccps_timestamp_echo = opt_recv->dccpor_timestamp; |
154 | dp->dccps_timestamp_time = ktime_get_real(); | 175 | dp->dccps_timestamp_time = ktime_get_real(); |
155 | 176 | ||
@@ -213,15 +234,6 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb) | |||
213 | dccp_pr_debug("%s rx opt: ELAPSED_TIME=%d\n", | 234 | dccp_pr_debug("%s rx opt: ELAPSED_TIME=%d\n", |
214 | dccp_role(sk), elapsed_time); | 235 | dccp_role(sk), elapsed_time); |
215 | break; | 236 | break; |
216 | /* | ||
217 | * From RFC 4340, sec. 10.3: | ||
218 | * | ||
219 | * Option numbers 128 through 191 are for | ||
220 | * options sent from the HC-Sender to the | ||
221 | * HC-Receiver; option numbers 192 through 255 | ||
222 | * are for options sent from the HC-Receiver to | ||
223 | * the HC-Sender. | ||
224 | */ | ||
225 | case 128 ... 191: { | 237 | case 128 ... 191: { |
226 | const u16 idx = value - options; | 238 | const u16 idx = value - options; |
227 | 239 | ||
@@ -245,7 +257,7 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb) | |||
245 | "implemented, ignoring", sk, opt, len); | 257 | "implemented, ignoring", sk, opt, len); |
246 | break; | 258 | break; |
247 | } | 259 | } |
248 | 260 | ignore_option: | |
249 | if (opt != DCCPO_MANDATORY) | 261 | if (opt != DCCPO_MANDATORY) |
250 | mandatory = 0; | 262 | mandatory = 0; |
251 | } | 263 | } |