aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp
diff options
context:
space:
mode:
Diffstat (limited to 'net/dccp')
-rw-r--r--net/dccp/output.c6
-rw-r--r--net/dccp/proto.c13
2 files changed, 16 insertions, 3 deletions
diff --git a/net/dccp/output.c b/net/dccp/output.c
index e97584aa4898..b2e17910930d 100644
--- a/net/dccp/output.c
+++ b/net/dccp/output.c
@@ -567,8 +567,10 @@ void dccp_send_close(struct sock *sk, const int active)
567 567
568 /* Reserve space for headers and prepare control bits. */ 568 /* Reserve space for headers and prepare control bits. */
569 skb_reserve(skb, sk->sk_prot->max_header); 569 skb_reserve(skb, sk->sk_prot->max_header);
570 DCCP_SKB_CB(skb)->dccpd_type = dp->dccps_role == DCCP_ROLE_CLIENT ? 570 if (dp->dccps_role == DCCP_ROLE_SERVER && !dp->dccps_server_timewait)
571 DCCP_PKT_CLOSE : DCCP_PKT_CLOSEREQ; 571 DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_CLOSEREQ;
572 else
573 DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_CLOSE;
572 574
573 if (active) { 575 if (active) {
574 dccp_write_xmit(sk, 1); 576 dccp_write_xmit(sk, 1);
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index 8a73c8f98d76..cc87c500bfb8 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -551,6 +551,12 @@ static int do_dccp_setsockopt(struct sock *sk, int level, int optname,
551 (struct dccp_so_feat __user *) 551 (struct dccp_so_feat __user *)
552 optval); 552 optval);
553 break; 553 break;
554 case DCCP_SOCKOPT_SERVER_TIMEWAIT:
555 if (dp->dccps_role != DCCP_ROLE_SERVER)
556 err = -EOPNOTSUPP;
557 else
558 dp->dccps_server_timewait = (val != 0);
559 break;
554 case DCCP_SOCKOPT_SEND_CSCOV: /* sender side, RFC 4340, sec. 9.2 */ 560 case DCCP_SOCKOPT_SEND_CSCOV: /* sender side, RFC 4340, sec. 9.2 */
555 if (val < 0 || val > 15) 561 if (val < 0 || val > 15)
556 err = -EINVAL; 562 err = -EINVAL;
@@ -653,6 +659,10 @@ static int do_dccp_getsockopt(struct sock *sk, int level, int optname,
653 val = dp->dccps_mss_cache; 659 val = dp->dccps_mss_cache;
654 len = sizeof(val); 660 len = sizeof(val);
655 break; 661 break;
662 case DCCP_SOCKOPT_SERVER_TIMEWAIT:
663 val = dp->dccps_server_timewait;
664 len = sizeof(val);
665 break;
656 case DCCP_SOCKOPT_SEND_CSCOV: 666 case DCCP_SOCKOPT_SEND_CSCOV:
657 val = dp->dccps_pcslen; 667 val = dp->dccps_pcslen;
658 len = sizeof(val); 668 len = sizeof(val);
@@ -918,7 +928,8 @@ static void dccp_terminate_connection(struct sock *sk)
918 case DCCP_OPEN: 928 case DCCP_OPEN:
919 dccp_send_close(sk, 1); 929 dccp_send_close(sk, 1);
920 930
921 if (dccp_sk(sk)->dccps_role == DCCP_ROLE_SERVER) 931 if (dccp_sk(sk)->dccps_role == DCCP_ROLE_SERVER &&
932 !dccp_sk(sk)->dccps_server_timewait)
922 next_state = DCCP_ACTIVE_CLOSEREQ; 933 next_state = DCCP_ACTIVE_CLOSEREQ;
923 else 934 else
924 next_state = DCCP_CLOSING; 935 next_state = DCCP_CLOSING;