diff options
Diffstat (limited to 'net/dccp')
-rw-r--r-- | net/dccp/ackvec.c | 27 | ||||
-rw-r--r-- | net/dccp/ipv4.c | 39 | ||||
-rw-r--r-- | net/dccp/ipv6.c | 6 | ||||
-rw-r--r-- | net/dccp/options.c | 18 | ||||
-rw-r--r-- | net/dccp/output.c | 1 | ||||
-rw-r--r-- | net/dccp/proto.c | 8 |
6 files changed, 37 insertions, 62 deletions
diff --git a/net/dccp/ackvec.c b/net/dccp/ackvec.c index f8208874ac7d..0c54b89a4e9b 100644 --- a/net/dccp/ackvec.c +++ b/net/dccp/ackvec.c | |||
@@ -67,10 +67,6 @@ static void dccp_ackvec_insert_avr(struct dccp_ackvec *av, | |||
67 | int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb) | 67 | int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb) |
68 | { | 68 | { |
69 | struct dccp_sock *dp = dccp_sk(sk); | 69 | struct dccp_sock *dp = dccp_sk(sk); |
70 | #ifdef CONFIG_IP_DCCP_DEBUG | ||
71 | const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ? | ||
72 | "CLIENT tx: " : "server tx: "; | ||
73 | #endif | ||
74 | struct dccp_ackvec *av = dp->dccps_hc_rx_ackvec; | 70 | struct dccp_ackvec *av = dp->dccps_hc_rx_ackvec; |
75 | int len = av->dccpav_vec_len + 2; | 71 | int len = av->dccpav_vec_len + 2; |
76 | struct timeval now; | 72 | struct timeval now; |
@@ -129,9 +125,9 @@ int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb) | |||
129 | 125 | ||
130 | dccp_ackvec_insert_avr(av, avr); | 126 | dccp_ackvec_insert_avr(av, avr); |
131 | 127 | ||
132 | dccp_pr_debug("%sACK Vector 0, len=%d, ack_seqno=%llu, " | 128 | dccp_pr_debug("%s ACK Vector 0, len=%d, ack_seqno=%llu, " |
133 | "ack_ackno=%llu\n", | 129 | "ack_ackno=%llu\n", |
134 | debug_prefix, avr->dccpavr_sent_len, | 130 | dccp_role(sk), avr->dccpavr_sent_len, |
135 | (unsigned long long)avr->dccpavr_ack_seqno, | 131 | (unsigned long long)avr->dccpavr_ack_seqno, |
136 | (unsigned long long)avr->dccpavr_ack_ackno); | 132 | (unsigned long long)avr->dccpavr_ack_ackno); |
137 | return 0; | 133 | return 0; |
@@ -380,14 +376,9 @@ void dccp_ackvec_check_rcv_ackno(struct dccp_ackvec *av, struct sock *sk, | |||
380 | */ | 376 | */ |
381 | list_for_each_entry_reverse(avr, &av->dccpav_records, dccpavr_node) { | 377 | list_for_each_entry_reverse(avr, &av->dccpav_records, dccpavr_node) { |
382 | if (ackno == avr->dccpavr_ack_seqno) { | 378 | if (ackno == avr->dccpavr_ack_seqno) { |
383 | #ifdef CONFIG_IP_DCCP_DEBUG | 379 | dccp_pr_debug("%s ACK packet 0, len=%d, ack_seqno=%llu, " |
384 | struct dccp_sock *dp = dccp_sk(sk); | ||
385 | const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ? | ||
386 | "CLIENT rx ack: " : "server rx ack: "; | ||
387 | #endif | ||
388 | dccp_pr_debug("%sACK packet 0, len=%d, ack_seqno=%llu, " | ||
389 | "ack_ackno=%llu, ACKED!\n", | 380 | "ack_ackno=%llu, ACKED!\n", |
390 | debug_prefix, 1, | 381 | dccp_role(sk), 1, |
391 | (unsigned long long)avr->dccpavr_ack_seqno, | 382 | (unsigned long long)avr->dccpavr_ack_seqno, |
392 | (unsigned long long)avr->dccpavr_ack_ackno); | 383 | (unsigned long long)avr->dccpavr_ack_ackno); |
393 | dccp_ackvec_throw_record(av, avr); | 384 | dccp_ackvec_throw_record(av, avr); |
@@ -437,16 +428,10 @@ found: | |||
437 | if (between48(avr->dccpavr_ack_seqno, ackno_end_rl, ackno)) { | 428 | if (between48(avr->dccpavr_ack_seqno, ackno_end_rl, ackno)) { |
438 | const u8 state = *vector & DCCP_ACKVEC_STATE_MASK; | 429 | const u8 state = *vector & DCCP_ACKVEC_STATE_MASK; |
439 | if (state != DCCP_ACKVEC_STATE_NOT_RECEIVED) { | 430 | if (state != DCCP_ACKVEC_STATE_NOT_RECEIVED) { |
440 | #ifdef CONFIG_IP_DCCP_DEBUG | 431 | dccp_pr_debug("%s ACK vector 0, len=%d, " |
441 | struct dccp_sock *dp = dccp_sk(sk); | ||
442 | const char *debug_prefix = | ||
443 | dp->dccps_role == DCCP_ROLE_CLIENT ? | ||
444 | "CLIENT rx ack: " : "server rx ack: "; | ||
445 | #endif | ||
446 | dccp_pr_debug("%sACK vector 0, len=%d, " | ||
447 | "ack_seqno=%llu, ack_ackno=%llu, " | 432 | "ack_seqno=%llu, ack_ackno=%llu, " |
448 | "ACKED!\n", | 433 | "ACKED!\n", |
449 | debug_prefix, len, | 434 | dccp_role(sk), len, |
450 | (unsigned long long) | 435 | (unsigned long long) |
451 | avr->dccpavr_ack_seqno, | 436 | avr->dccpavr_ack_seqno, |
452 | (unsigned long long) | 437 | (unsigned long long) |
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index 61c09014dade..34d6d197c3b2 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c | |||
@@ -518,7 +518,7 @@ static void dccp_v4_ctl_send_reset(struct sk_buff *rxskb) | |||
518 | sizeof(struct dccp_hdr_reset); | 518 | sizeof(struct dccp_hdr_reset); |
519 | struct sk_buff *skb; | 519 | struct sk_buff *skb; |
520 | struct dst_entry *dst; | 520 | struct dst_entry *dst; |
521 | u64 seqno; | 521 | u64 seqno = 0; |
522 | 522 | ||
523 | /* Never send a reset in response to a reset. */ | 523 | /* Never send a reset in response to a reset. */ |
524 | if (rxdh->dccph_type == DCCP_PKT_RESET) | 524 | if (rxdh->dccph_type == DCCP_PKT_RESET) |
@@ -552,13 +552,11 @@ static void dccp_v4_ctl_send_reset(struct sk_buff *rxskb) | |||
552 | DCCP_SKB_CB(rxskb)->dccpd_reset_code; | 552 | DCCP_SKB_CB(rxskb)->dccpd_reset_code; |
553 | 553 | ||
554 | /* See "8.3.1. Abnormal Termination" in RFC 4340 */ | 554 | /* See "8.3.1. Abnormal Termination" in RFC 4340 */ |
555 | seqno = 0; | ||
556 | if (DCCP_SKB_CB(rxskb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) | 555 | if (DCCP_SKB_CB(rxskb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) |
557 | dccp_set_seqno(&seqno, DCCP_SKB_CB(rxskb)->dccpd_ack_seq + 1); | 556 | dccp_set_seqno(&seqno, DCCP_SKB_CB(rxskb)->dccpd_ack_seq + 1); |
558 | 557 | ||
559 | dccp_hdr_set_seq(dh, seqno); | 558 | dccp_hdr_set_seq(dh, seqno); |
560 | dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), | 559 | dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), DCCP_SKB_CB(rxskb)->dccpd_seq); |
561 | DCCP_SKB_CB(rxskb)->dccpd_seq); | ||
562 | 560 | ||
563 | dccp_csum_outgoing(skb); | 561 | dccp_csum_outgoing(skb); |
564 | dh->dccph_checksum = dccp_v4_csum_finish(skb, rxskb->nh.iph->saddr, | 562 | dh->dccph_checksum = dccp_v4_csum_finish(skb, rxskb->nh.iph->saddr, |
@@ -734,6 +732,11 @@ discard: | |||
734 | 732 | ||
735 | EXPORT_SYMBOL_GPL(dccp_v4_do_rcv); | 733 | EXPORT_SYMBOL_GPL(dccp_v4_do_rcv); |
736 | 734 | ||
735 | /** | ||
736 | * dccp_invalid_packet - check for malformed packets | ||
737 | * Implements RFC 4340, 8.5: Step 1: Check header basics | ||
738 | * Packets that fail these checks are ignored and do not receive Resets. | ||
739 | */ | ||
737 | int dccp_invalid_packet(struct sk_buff *skb) | 740 | int dccp_invalid_packet(struct sk_buff *skb) |
738 | { | 741 | { |
739 | const struct dccp_hdr *dh; | 742 | const struct dccp_hdr *dh; |
@@ -742,6 +745,7 @@ int dccp_invalid_packet(struct sk_buff *skb) | |||
742 | if (skb->pkt_type != PACKET_HOST) | 745 | if (skb->pkt_type != PACKET_HOST) |
743 | return 1; | 746 | return 1; |
744 | 747 | ||
748 | /* If the packet is shorter than 12 bytes, drop packet and return */ | ||
745 | if (!pskb_may_pull(skb, sizeof(struct dccp_hdr))) { | 749 | if (!pskb_may_pull(skb, sizeof(struct dccp_hdr))) { |
746 | LIMIT_NETDEBUG(KERN_WARNING "DCCP: pskb_may_pull failed\n"); | 750 | LIMIT_NETDEBUG(KERN_WARNING "DCCP: pskb_may_pull failed\n"); |
747 | return 1; | 751 | return 1; |
@@ -749,42 +753,37 @@ int dccp_invalid_packet(struct sk_buff *skb) | |||
749 | 753 | ||
750 | dh = dccp_hdr(skb); | 754 | dh = dccp_hdr(skb); |
751 | 755 | ||
752 | /* If the packet type is not understood, drop packet and return */ | 756 | /* If P.type is not understood, drop packet and return */ |
753 | if (dh->dccph_type >= DCCP_PKT_INVALID) { | 757 | if (dh->dccph_type >= DCCP_PKT_INVALID) { |
754 | LIMIT_NETDEBUG(KERN_WARNING "DCCP: invalid packet type\n"); | 758 | LIMIT_NETDEBUG(KERN_WARNING "DCCP: invalid packet type\n"); |
755 | return 1; | 759 | return 1; |
756 | } | 760 | } |
757 | 761 | ||
758 | /* | 762 | /* |
759 | * If P.Data Offset is too small for packet type, or too large for | 763 | * If P.Data Offset is too small for packet type, drop packet and return |
760 | * packet, drop packet and return | ||
761 | */ | 764 | */ |
762 | if (dh->dccph_doff < dccp_hdr_len(skb) / sizeof(u32)) { | 765 | if (dh->dccph_doff < dccp_hdr_len(skb) / sizeof(u32)) { |
763 | LIMIT_NETDEBUG(KERN_WARNING "DCCP: P.Data Offset(%u) " | 766 | LIMIT_NETDEBUG(KERN_WARNING "DCCP: P.Data Offset(%u) " |
764 | "too small 1\n", | 767 | "too small\n", dh->dccph_doff); |
765 | dh->dccph_doff); | ||
766 | return 1; | 768 | return 1; |
767 | } | 769 | } |
768 | 770 | /* | |
771 | * If P.Data Offset is too too large for packet, drop packet and return | ||
772 | */ | ||
769 | if (!pskb_may_pull(skb, dh->dccph_doff * sizeof(u32))) { | 773 | if (!pskb_may_pull(skb, dh->dccph_doff * sizeof(u32))) { |
770 | LIMIT_NETDEBUG(KERN_WARNING "DCCP: P.Data Offset(%u) " | 774 | LIMIT_NETDEBUG(KERN_WARNING "DCCP: P.Data Offset(%u) " |
771 | "too small 2\n", | 775 | "too large\n", dh->dccph_doff); |
772 | dh->dccph_doff); | ||
773 | return 1; | 776 | return 1; |
774 | } | 777 | } |
775 | 778 | ||
776 | dh = dccp_hdr(skb); | ||
777 | |||
778 | /* | 779 | /* |
779 | * If P.type is not Data, Ack, or DataAck and P.X == 0 (the packet | 780 | * If P.type is not Data, Ack, or DataAck and P.X == 0 (the packet |
780 | * has short sequence numbers), drop packet and return | 781 | * has short sequence numbers), drop packet and return |
781 | */ | 782 | */ |
782 | if (dh->dccph_x == 0 && | 783 | if (dh->dccph_type >= DCCP_PKT_DATA && |
783 | dh->dccph_type != DCCP_PKT_DATA && | 784 | dh->dccph_type <= DCCP_PKT_DATAACK && dh->dccph_x == 0) { |
784 | dh->dccph_type != DCCP_PKT_ACK && | 785 | LIMIT_NETDEBUG(KERN_WARNING "DCCP: P.type (%s) not Data||Ack||" |
785 | dh->dccph_type != DCCP_PKT_DATAACK) { | 786 | "DataAck, while P.X == 0\n", |
786 | LIMIT_NETDEBUG(KERN_WARNING "DCCP: P.type (%s) not Data, Ack " | ||
787 | "nor DataAck and P.X == 0\n", | ||
788 | dccp_packet_name(dh->dccph_type)); | 787 | dccp_packet_name(dh->dccph_type)); |
789 | return 1; | 788 | return 1; |
790 | } | 789 | } |
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index 2165b1740c7c..fc326173c215 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c | |||
@@ -318,7 +318,7 @@ static void dccp_v6_ctl_send_reset(struct sk_buff *rxskb) | |||
318 | sizeof(struct dccp_hdr_reset); | 318 | sizeof(struct dccp_hdr_reset); |
319 | struct sk_buff *skb; | 319 | struct sk_buff *skb; |
320 | struct flowi fl; | 320 | struct flowi fl; |
321 | u64 seqno; | 321 | u64 seqno = 0; |
322 | 322 | ||
323 | if (rxdh->dccph_type == DCCP_PKT_RESET) | 323 | if (rxdh->dccph_type == DCCP_PKT_RESET) |
324 | return; | 324 | return; |
@@ -345,13 +345,11 @@ static void dccp_v6_ctl_send_reset(struct sk_buff *rxskb) | |||
345 | DCCP_SKB_CB(rxskb)->dccpd_reset_code; | 345 | DCCP_SKB_CB(rxskb)->dccpd_reset_code; |
346 | 346 | ||
347 | /* See "8.3.1. Abnormal Termination" in RFC 4340 */ | 347 | /* See "8.3.1. Abnormal Termination" in RFC 4340 */ |
348 | seqno = 0; | ||
349 | if (DCCP_SKB_CB(rxskb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) | 348 | if (DCCP_SKB_CB(rxskb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) |
350 | dccp_set_seqno(&seqno, DCCP_SKB_CB(rxskb)->dccpd_ack_seq + 1); | 349 | dccp_set_seqno(&seqno, DCCP_SKB_CB(rxskb)->dccpd_ack_seq + 1); |
351 | 350 | ||
352 | dccp_hdr_set_seq(dh, seqno); | 351 | dccp_hdr_set_seq(dh, seqno); |
353 | dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), | 352 | dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), DCCP_SKB_CB(rxskb)->dccpd_seq); |
354 | DCCP_SKB_CB(rxskb)->dccpd_seq); | ||
355 | 353 | ||
356 | dccp_csum_outgoing(skb); | 354 | dccp_csum_outgoing(skb); |
357 | dh->dccph_checksum = dccp_v6_csum_finish(skb, &rxskb->nh.ipv6h->saddr, | 355 | dh->dccph_checksum = dccp_v6_csum_finish(skb, &rxskb->nh.ipv6h->saddr, |
diff --git a/net/dccp/options.c b/net/dccp/options.c index 2d0ef27f4ab9..7e50678e2471 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c | |||
@@ -60,10 +60,6 @@ static u32 dccp_decode_value_var(const unsigned char *bf, const u8 len) | |||
60 | int dccp_parse_options(struct sock *sk, struct sk_buff *skb) | 60 | int dccp_parse_options(struct sock *sk, struct sk_buff *skb) |
61 | { | 61 | { |
62 | struct dccp_sock *dp = dccp_sk(sk); | 62 | struct dccp_sock *dp = dccp_sk(sk); |
63 | #ifdef CONFIG_IP_DCCP_DEBUG | ||
64 | const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ? | ||
65 | "CLIENT rx opt: " : "server rx opt: "; | ||
66 | #endif | ||
67 | const struct dccp_hdr *dh = dccp_hdr(skb); | 63 | const struct dccp_hdr *dh = dccp_hdr(skb); |
68 | const u8 pkt_type = DCCP_SKB_CB(skb)->dccpd_type; | 64 | const u8 pkt_type = DCCP_SKB_CB(skb)->dccpd_type; |
69 | unsigned char *options = (unsigned char *)dh + dccp_hdr_len(skb); | 65 | unsigned char *options = (unsigned char *)dh + dccp_hdr_len(skb); |
@@ -119,7 +115,7 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb) | |||
119 | goto out_invalid_option; | 115 | goto out_invalid_option; |
120 | 116 | ||
121 | opt_recv->dccpor_ndp = dccp_decode_value_var(value, len); | 117 | opt_recv->dccpor_ndp = dccp_decode_value_var(value, len); |
122 | dccp_pr_debug("%sNDP count=%d\n", debug_prefix, | 118 | dccp_pr_debug("%s rx opt: NDP count=%d\n", dccp_role(sk), |
123 | opt_recv->dccpor_ndp); | 119 | opt_recv->dccpor_ndp); |
124 | break; | 120 | break; |
125 | case DCCPO_CHANGE_L: | 121 | case DCCPO_CHANGE_L: |
@@ -165,8 +161,8 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb) | |||
165 | dp->dccps_timestamp_echo = opt_recv->dccpor_timestamp; | 161 | dp->dccps_timestamp_echo = opt_recv->dccpor_timestamp; |
166 | dccp_timestamp(sk, &dp->dccps_timestamp_time); | 162 | dccp_timestamp(sk, &dp->dccps_timestamp_time); |
167 | 163 | ||
168 | dccp_pr_debug("%sTIMESTAMP=%u, ackno=%llu\n", | 164 | dccp_pr_debug("%s rx opt: TIMESTAMP=%u, ackno=%llu\n", |
169 | debug_prefix, opt_recv->dccpor_timestamp, | 165 | dccp_role(sk), opt_recv->dccpor_timestamp, |
170 | (unsigned long long) | 166 | (unsigned long long) |
171 | DCCP_SKB_CB(skb)->dccpd_ack_seq); | 167 | DCCP_SKB_CB(skb)->dccpd_ack_seq); |
172 | break; | 168 | break; |
@@ -176,8 +172,8 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb) | |||
176 | 172 | ||
177 | opt_recv->dccpor_timestamp_echo = ntohl(*(__be32 *)value); | 173 | opt_recv->dccpor_timestamp_echo = ntohl(*(__be32 *)value); |
178 | 174 | ||
179 | dccp_pr_debug("%sTIMESTAMP_ECHO=%u, len=%d, ackno=%llu, ", | 175 | dccp_pr_debug("%s rx opt: TIMESTAMP_ECHO=%u, len=%d, " |
180 | debug_prefix, | 176 | "ackno=%llu, ", dccp_role(sk), |
181 | opt_recv->dccpor_timestamp_echo, | 177 | opt_recv->dccpor_timestamp_echo, |
182 | len + 2, | 178 | len + 2, |
183 | (unsigned long long) | 179 | (unsigned long long) |
@@ -211,8 +207,8 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb) | |||
211 | if (elapsed_time > opt_recv->dccpor_elapsed_time) | 207 | if (elapsed_time > opt_recv->dccpor_elapsed_time) |
212 | opt_recv->dccpor_elapsed_time = elapsed_time; | 208 | opt_recv->dccpor_elapsed_time = elapsed_time; |
213 | 209 | ||
214 | dccp_pr_debug("%sELAPSED_TIME=%d\n", debug_prefix, | 210 | dccp_pr_debug("%s rx opt: ELAPSED_TIME=%d\n", |
215 | elapsed_time); | 211 | dccp_role(sk), elapsed_time); |
216 | break; | 212 | break; |
217 | /* | 213 | /* |
218 | * From RFC 4340, sec. 10.3: | 214 | * From RFC 4340, sec. 10.3: |
diff --git a/net/dccp/output.c b/net/dccp/output.c index ef22f3cc791a..c34eada7f025 100644 --- a/net/dccp/output.c +++ b/net/dccp/output.c | |||
@@ -333,6 +333,7 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst, | |||
333 | return NULL; | 333 | return NULL; |
334 | } | 334 | } |
335 | 335 | ||
336 | /* Build and checksum header */ | ||
336 | dh = dccp_zeroed_hdr(skb, dccp_header_size); | 337 | dh = dccp_zeroed_hdr(skb, dccp_header_size); |
337 | 338 | ||
338 | dh->dccph_sport = inet_sk(sk)->sport; | 339 | dh->dccph_sport = inet_sk(sk)->sport; |
diff --git a/net/dccp/proto.c b/net/dccp/proto.c index 9c9c08cffdaf..0225bdacd3b1 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c | |||
@@ -452,9 +452,8 @@ out_free_val: | |||
452 | static int do_dccp_setsockopt(struct sock *sk, int level, int optname, | 452 | static int do_dccp_setsockopt(struct sock *sk, int level, int optname, |
453 | char __user *optval, int optlen) | 453 | char __user *optval, int optlen) |
454 | { | 454 | { |
455 | struct dccp_sock *dp; | 455 | struct dccp_sock *dp = dccp_sk(sk); |
456 | int err; | 456 | int val, err = 0; |
457 | int val; | ||
458 | 457 | ||
459 | if (optlen < sizeof(int)) | 458 | if (optlen < sizeof(int)) |
460 | return -EINVAL; | 459 | return -EINVAL; |
@@ -466,9 +465,6 @@ static int do_dccp_setsockopt(struct sock *sk, int level, int optname, | |||
466 | return dccp_setsockopt_service(sk, val, optval, optlen); | 465 | return dccp_setsockopt_service(sk, val, optval, optlen); |
467 | 466 | ||
468 | lock_sock(sk); | 467 | lock_sock(sk); |
469 | dp = dccp_sk(sk); | ||
470 | err = 0; | ||
471 | |||
472 | switch (optname) { | 468 | switch (optname) { |
473 | case DCCP_SOCKOPT_PACKET_SIZE: | 469 | case DCCP_SOCKOPT_PACKET_SIZE: |
474 | dp->dccps_packet_size = val; | 470 | dp->dccps_packet_size = val; |