diff options
Diffstat (limited to 'net/dccp/input.c')
| -rw-r--r-- | net/dccp/input.c | 95 |
1 files changed, 28 insertions, 67 deletions
diff --git a/net/dccp/input.c b/net/dccp/input.c index c74034cf7ede..3454d5941900 100644 --- a/net/dccp/input.c +++ b/net/dccp/input.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | 16 | ||
| 17 | #include <net/sock.h> | 17 | #include <net/sock.h> |
| 18 | 18 | ||
| 19 | #include "ackvec.h" | ||
| 19 | #include "ccid.h" | 20 | #include "ccid.h" |
| 20 | #include "dccp.h" | 21 | #include "dccp.h" |
| 21 | 22 | ||
| @@ -60,8 +61,8 @@ static inline void dccp_event_ack_recv(struct sock *sk, struct sk_buff *skb) | |||
| 60 | struct dccp_sock *dp = dccp_sk(sk); | 61 | struct dccp_sock *dp = dccp_sk(sk); |
| 61 | 62 | ||
| 62 | if (dp->dccps_options.dccpo_send_ack_vector) | 63 | if (dp->dccps_options.dccpo_send_ack_vector) |
| 63 | dccp_ackpkts_check_rcv_ackno(dp->dccps_hc_rx_ackpkts, sk, | 64 | dccp_ackvec_check_rcv_ackno(dp->dccps_hc_rx_ackvec, sk, |
| 64 | DCCP_SKB_CB(skb)->dccpd_ack_seq); | 65 | DCCP_SKB_CB(skb)->dccpd_ack_seq); |
| 65 | } | 66 | } |
| 66 | 67 | ||
| 67 | static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb) | 68 | static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb) |
| @@ -164,37 +165,11 @@ int dccp_rcv_established(struct sock *sk, struct sk_buff *skb, | |||
| 164 | if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) | 165 | if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) |
| 165 | dccp_event_ack_recv(sk, skb); | 166 | dccp_event_ack_recv(sk, skb); |
| 166 | 167 | ||
| 167 | /* | 168 | if (dp->dccps_options.dccpo_send_ack_vector && |
| 168 | * FIXME: check ECN to see if we should use | 169 | dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk, |
| 169 | * DCCP_ACKPKTS_STATE_ECN_MARKED | 170 | DCCP_SKB_CB(skb)->dccpd_seq, |
| 170 | */ | 171 | DCCP_ACKVEC_STATE_RECEIVED)) |
| 171 | if (dp->dccps_options.dccpo_send_ack_vector) { | 172 | goto discard; |
| 172 | struct dccp_ackpkts *ap = dp->dccps_hc_rx_ackpkts; | ||
| 173 | |||
| 174 | if (dccp_ackpkts_add(dp->dccps_hc_rx_ackpkts, sk, | ||
| 175 | DCCP_SKB_CB(skb)->dccpd_seq, | ||
| 176 | DCCP_ACKPKTS_STATE_RECEIVED)) { | ||
| 177 | LIMIT_NETDEBUG(KERN_WARNING "DCCP: acknowledgeable " | ||
| 178 | "packets buffer full!\n"); | ||
| 179 | ap->dccpap_ack_seqno = DCCP_MAX_SEQNO + 1; | ||
| 180 | inet_csk_schedule_ack(sk); | ||
| 181 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK, | ||
| 182 | TCP_DELACK_MIN, | ||
| 183 | DCCP_RTO_MAX); | ||
| 184 | goto discard; | ||
| 185 | } | ||
| 186 | |||
| 187 | /* | ||
| 188 | * FIXME: this activation is probably wrong, have to study more | ||
| 189 | * TCP delack machinery and how it fits into DCCP draft, but | ||
| 190 | * for now it kinda "works" 8) | ||
| 191 | */ | ||
| 192 | if (!inet_csk_ack_scheduled(sk)) { | ||
| 193 | inet_csk_schedule_ack(sk); | ||
| 194 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK, 5 * HZ, | ||
| 195 | DCCP_RTO_MAX); | ||
| 196 | } | ||
| 197 | } | ||
| 198 | 173 | ||
| 199 | ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb); | 174 | ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb); |
| 200 | ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb); | 175 | ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb); |
| @@ -384,9 +359,9 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk, | |||
| 384 | } | 359 | } |
| 385 | 360 | ||
| 386 | out_invalid_packet: | 361 | out_invalid_packet: |
| 387 | return 1; /* dccp_v4_do_rcv will send a reset, but... | 362 | /* dccp_v4_do_rcv will send a reset */ |
| 388 | FIXME: the reset code should be | 363 | DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_PACKET_ERROR; |
| 389 | DCCP_RESET_CODE_PACKET_ERROR */ | 364 | return 1; |
| 390 | } | 365 | } |
| 391 | 366 | ||
| 392 | static int dccp_rcv_respond_partopen_state_process(struct sock *sk, | 367 | static int dccp_rcv_respond_partopen_state_process(struct sock *sk, |
| @@ -400,6 +375,9 @@ static int dccp_rcv_respond_partopen_state_process(struct sock *sk, | |||
| 400 | case DCCP_PKT_RESET: | 375 | case DCCP_PKT_RESET: |
| 401 | inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK); | 376 | inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK); |
| 402 | break; | 377 | break; |
| 378 | case DCCP_PKT_DATA: | ||
| 379 | if (sk->sk_state == DCCP_RESPOND) | ||
| 380 | break; | ||
| 403 | case DCCP_PKT_DATAACK: | 381 | case DCCP_PKT_DATAACK: |
| 404 | case DCCP_PKT_ACK: | 382 | case DCCP_PKT_ACK: |
| 405 | /* | 383 | /* |
| @@ -418,7 +396,8 @@ static int dccp_rcv_respond_partopen_state_process(struct sock *sk, | |||
| 418 | dccp_sk(sk)->dccps_osr = DCCP_SKB_CB(skb)->dccpd_seq; | 396 | dccp_sk(sk)->dccps_osr = DCCP_SKB_CB(skb)->dccpd_seq; |
| 419 | dccp_set_state(sk, DCCP_OPEN); | 397 | dccp_set_state(sk, DCCP_OPEN); |
| 420 | 398 | ||
| 421 | if (dh->dccph_type == DCCP_PKT_DATAACK) { | 399 | if (dh->dccph_type == DCCP_PKT_DATAACK || |
| 400 | dh->dccph_type == DCCP_PKT_DATA) { | ||
| 422 | dccp_rcv_established(sk, skb, dh, len); | 401 | dccp_rcv_established(sk, skb, dh, len); |
| 423 | queued = 1; /* packet was queued | 402 | queued = 1; /* packet was queued |
| 424 | (by dccp_rcv_established) */ | 403 | (by dccp_rcv_established) */ |
| @@ -433,6 +412,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
| 433 | struct dccp_hdr *dh, unsigned len) | 412 | struct dccp_hdr *dh, unsigned len) |
| 434 | { | 413 | { |
| 435 | struct dccp_sock *dp = dccp_sk(sk); | 414 | struct dccp_sock *dp = dccp_sk(sk); |
| 415 | struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb); | ||
| 436 | const int old_state = sk->sk_state; | 416 | const int old_state = sk->sk_state; |
| 437 | int queued = 0; | 417 | int queued = 0; |
| 438 | 418 | ||
| @@ -473,7 +453,8 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
| 473 | if (dh->dccph_type == DCCP_PKT_RESET) | 453 | if (dh->dccph_type == DCCP_PKT_RESET) |
| 474 | goto discard; | 454 | goto discard; |
| 475 | 455 | ||
| 476 | /* Caller (dccp_v4_do_rcv) will send Reset(No Connection)*/ | 456 | /* Caller (dccp_v4_do_rcv) will send Reset */ |
| 457 | dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION; | ||
| 477 | return 1; | 458 | return 1; |
| 478 | } | 459 | } |
| 479 | 460 | ||
| @@ -487,36 +468,17 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
| 487 | if (dccp_parse_options(sk, skb)) | 468 | if (dccp_parse_options(sk, skb)) |
| 488 | goto discard; | 469 | goto discard; |
| 489 | 470 | ||
| 490 | if (DCCP_SKB_CB(skb)->dccpd_ack_seq != | 471 | if (dcb->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) |
| 491 | DCCP_PKT_WITHOUT_ACK_SEQ) | ||
| 492 | dccp_event_ack_recv(sk, skb); | 472 | dccp_event_ack_recv(sk, skb); |
| 493 | 473 | ||
| 494 | ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb); | 474 | ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb); |
| 495 | ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb); | 475 | ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb); |
| 496 | 476 | ||
| 497 | /* | 477 | if (dp->dccps_options.dccpo_send_ack_vector && |
| 498 | * FIXME: check ECN to see if we should use | 478 | dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk, |
| 499 | * DCCP_ACKPKTS_STATE_ECN_MARKED | 479 | DCCP_SKB_CB(skb)->dccpd_seq, |
| 500 | */ | 480 | DCCP_ACKVEC_STATE_RECEIVED)) |
| 501 | if (dp->dccps_options.dccpo_send_ack_vector) { | 481 | goto discard; |
| 502 | if (dccp_ackpkts_add(dp->dccps_hc_rx_ackpkts, sk, | ||
| 503 | DCCP_SKB_CB(skb)->dccpd_seq, | ||
| 504 | DCCP_ACKPKTS_STATE_RECEIVED)) | ||
| 505 | goto discard; | ||
| 506 | /* | ||
| 507 | * FIXME: this activation is probably wrong, have to | ||
| 508 | * study more TCP delack machinery and how it fits into | ||
| 509 | * DCCP draft, but for now it kinda "works" 8) | ||
| 510 | */ | ||
| 511 | if ((dp->dccps_hc_rx_ackpkts->dccpap_ack_seqno == | ||
| 512 | DCCP_MAX_SEQNO + 1) && | ||
| 513 | !inet_csk_ack_scheduled(sk)) { | ||
| 514 | inet_csk_schedule_ack(sk); | ||
| 515 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK, | ||
| 516 | TCP_DELACK_MIN, | ||
| 517 | DCCP_RTO_MAX); | ||
| 518 | } | ||
| 519 | } | ||
| 520 | } | 482 | } |
| 521 | 483 | ||
| 522 | /* | 484 | /* |
| @@ -551,8 +513,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
| 551 | dh->dccph_type == DCCP_PKT_REQUEST) || | 513 | dh->dccph_type == DCCP_PKT_REQUEST) || |
| 552 | (sk->sk_state == DCCP_RESPOND && | 514 | (sk->sk_state == DCCP_RESPOND && |
| 553 | dh->dccph_type == DCCP_PKT_DATA)) { | 515 | dh->dccph_type == DCCP_PKT_DATA)) { |
| 554 | dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq, | 516 | dccp_send_sync(sk, dcb->dccpd_seq, DCCP_PKT_SYNC); |
| 555 | DCCP_PKT_SYNC); | ||
| 556 | goto discard; | 517 | goto discard; |
| 557 | } else if (dh->dccph_type == DCCP_PKT_CLOSEREQ) { | 518 | } else if (dh->dccph_type == DCCP_PKT_CLOSEREQ) { |
| 558 | dccp_rcv_closereq(sk, skb); | 519 | dccp_rcv_closereq(sk, skb); |
| @@ -563,13 +524,13 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
| 563 | } | 524 | } |
| 564 | 525 | ||
| 565 | if (unlikely(dh->dccph_type == DCCP_PKT_SYNC)) { | 526 | if (unlikely(dh->dccph_type == DCCP_PKT_SYNC)) { |
| 566 | dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq, | 527 | dccp_send_sync(sk, dcb->dccpd_seq, DCCP_PKT_SYNCACK); |
| 567 | DCCP_PKT_SYNCACK); | ||
| 568 | goto discard; | 528 | goto discard; |
| 569 | } | 529 | } |
| 570 | 530 | ||
| 571 | switch (sk->sk_state) { | 531 | switch (sk->sk_state) { |
| 572 | case DCCP_CLOSED: | 532 | case DCCP_CLOSED: |
| 533 | dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION; | ||
| 573 | return 1; | 534 | return 1; |
| 574 | 535 | ||
| 575 | case DCCP_REQUESTING: | 536 | case DCCP_REQUESTING: |
