aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp/proto.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/dccp/proto.c')
-rw-r--r--net/dccp/proto.c281
1 files changed, 106 insertions, 175 deletions
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index ecf3be961e11..d0bd34819761 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -67,9 +67,6 @@ void dccp_set_state(struct sock *sk, const int state)
67 case DCCP_OPEN: 67 case DCCP_OPEN:
68 if (oldstate != DCCP_OPEN) 68 if (oldstate != DCCP_OPEN)
69 DCCP_INC_STATS(DCCP_MIB_CURRESTAB); 69 DCCP_INC_STATS(DCCP_MIB_CURRESTAB);
70 /* Client retransmits all Confirm options until entering OPEN */
71 if (oldstate == DCCP_PARTOPEN)
72 dccp_feat_list_purge(&dccp_sk(sk)->dccps_featneg);
73 break; 70 break;
74 71
75 case DCCP_CLOSED: 72 case DCCP_CLOSED:
@@ -178,25 +175,63 @@ EXPORT_SYMBOL_GPL(dccp_state_name);
178int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized) 175int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized)
179{ 176{
180 struct dccp_sock *dp = dccp_sk(sk); 177 struct dccp_sock *dp = dccp_sk(sk);
178 struct dccp_minisock *dmsk = dccp_msk(sk);
181 struct inet_connection_sock *icsk = inet_csk(sk); 179 struct inet_connection_sock *icsk = inet_csk(sk);
182 180
181 dccp_minisock_init(&dp->dccps_minisock);
182
183 icsk->icsk_rto = DCCP_TIMEOUT_INIT; 183 icsk->icsk_rto = DCCP_TIMEOUT_INIT;
184 icsk->icsk_syn_retries = sysctl_dccp_request_retries; 184 icsk->icsk_syn_retries = sysctl_dccp_request_retries;
185 sk->sk_state = DCCP_CLOSED; 185 sk->sk_state = DCCP_CLOSED;
186 sk->sk_write_space = dccp_write_space; 186 sk->sk_write_space = dccp_write_space;
187 icsk->icsk_sync_mss = dccp_sync_mss; 187 icsk->icsk_sync_mss = dccp_sync_mss;
188 dp->dccps_mss_cache = TCP_MIN_RCVMSS; 188 dp->dccps_mss_cache = 536;
189 dp->dccps_rate_last = jiffies; 189 dp->dccps_rate_last = jiffies;
190 dp->dccps_role = DCCP_ROLE_UNDEFINED; 190 dp->dccps_role = DCCP_ROLE_UNDEFINED;
191 dp->dccps_service = DCCP_SERVICE_CODE_IS_ABSENT; 191 dp->dccps_service = DCCP_SERVICE_CODE_IS_ABSENT;
192 dp->dccps_tx_qlen = sysctl_dccp_tx_qlen; 192 dp->dccps_l_ack_ratio = dp->dccps_r_ack_ratio = 1;
193 193
194 dccp_init_xmit_timers(sk); 194 dccp_init_xmit_timers(sk);
195 195
196 INIT_LIST_HEAD(&dp->dccps_featneg); 196 /*
197 /* control socket doesn't need feat nego */ 197 * FIXME: We're hardcoding the CCID, and doing this at this point makes
198 if (likely(ctl_sock_initialized)) 198 * the listening (master) sock get CCID control blocks, which is not
199 return dccp_feat_init(sk); 199 * necessary, but for now, to not mess with the test userspace apps,
200 * lets leave it here, later the real solution is to do this in a
201 * setsockopt(CCIDs-I-want/accept). -acme
202 */
203 if (likely(ctl_sock_initialized)) {
204 int rc = dccp_feat_init(dmsk);
205
206 if (rc)
207 return rc;
208
209 if (dmsk->dccpms_send_ack_vector) {
210 dp->dccps_hc_rx_ackvec = dccp_ackvec_alloc(GFP_KERNEL);
211 if (dp->dccps_hc_rx_ackvec == NULL)
212 return -ENOMEM;
213 }
214 dp->dccps_hc_rx_ccid = ccid_hc_rx_new(dmsk->dccpms_rx_ccid,
215 sk, GFP_KERNEL);
216 dp->dccps_hc_tx_ccid = ccid_hc_tx_new(dmsk->dccpms_tx_ccid,
217 sk, GFP_KERNEL);
218 if (unlikely(dp->dccps_hc_rx_ccid == NULL ||
219 dp->dccps_hc_tx_ccid == NULL)) {
220 ccid_hc_rx_delete(dp->dccps_hc_rx_ccid, sk);
221 ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk);
222 if (dmsk->dccpms_send_ack_vector) {
223 dccp_ackvec_free(dp->dccps_hc_rx_ackvec);
224 dp->dccps_hc_rx_ackvec = NULL;
225 }
226 dp->dccps_hc_rx_ccid = dp->dccps_hc_tx_ccid = NULL;
227 return -ENOMEM;
228 }
229 } else {
230 /* control socket doesn't need feat nego */
231 INIT_LIST_HEAD(&dmsk->dccpms_pending);
232 INIT_LIST_HEAD(&dmsk->dccpms_conf);
233 }
234
200 return 0; 235 return 0;
201} 236}
202 237
@@ -205,6 +240,7 @@ EXPORT_SYMBOL_GPL(dccp_init_sock);
205void dccp_destroy_sock(struct sock *sk) 240void dccp_destroy_sock(struct sock *sk)
206{ 241{
207 struct dccp_sock *dp = dccp_sk(sk); 242 struct dccp_sock *dp = dccp_sk(sk);
243 struct dccp_minisock *dmsk = dccp_msk(sk);
208 244
209 /* 245 /*
210 * DCCP doesn't use sk_write_queue, just sk_send_head 246 * DCCP doesn't use sk_write_queue, just sk_send_head
@@ -222,7 +258,7 @@ void dccp_destroy_sock(struct sock *sk)
222 kfree(dp->dccps_service_list); 258 kfree(dp->dccps_service_list);
223 dp->dccps_service_list = NULL; 259 dp->dccps_service_list = NULL;
224 260
225 if (dp->dccps_hc_rx_ackvec != NULL) { 261 if (dmsk->dccpms_send_ack_vector) {
226 dccp_ackvec_free(dp->dccps_hc_rx_ackvec); 262 dccp_ackvec_free(dp->dccps_hc_rx_ackvec);
227 dp->dccps_hc_rx_ackvec = NULL; 263 dp->dccps_hc_rx_ackvec = NULL;
228 } 264 }
@@ -231,7 +267,7 @@ void dccp_destroy_sock(struct sock *sk)
231 dp->dccps_hc_rx_ccid = dp->dccps_hc_tx_ccid = NULL; 267 dp->dccps_hc_rx_ccid = dp->dccps_hc_tx_ccid = NULL;
232 268
233 /* clean up feature negotiation state */ 269 /* clean up feature negotiation state */
234 dccp_feat_list_purge(&dp->dccps_featneg); 270 dccp_feat_clean(dmsk);
235} 271}
236 272
237EXPORT_SYMBOL_GPL(dccp_destroy_sock); 273EXPORT_SYMBOL_GPL(dccp_destroy_sock);
@@ -241,9 +277,6 @@ static inline int dccp_listen_start(struct sock *sk, int backlog)
241 struct dccp_sock *dp = dccp_sk(sk); 277 struct dccp_sock *dp = dccp_sk(sk);
242 278
243 dp->dccps_role = DCCP_ROLE_LISTEN; 279 dp->dccps_role = DCCP_ROLE_LISTEN;
244 /* do not start to listen if feature negotiation setup fails */
245 if (dccp_feat_finalise_settings(dp))
246 return -EPROTO;
247 return inet_csk_listen_start(sk, backlog); 280 return inet_csk_listen_start(sk, backlog);
248} 281}
249 282
@@ -433,70 +466,42 @@ static int dccp_setsockopt_service(struct sock *sk, const __be32 service,
433 return 0; 466 return 0;
434} 467}
435 468
436static int dccp_setsockopt_cscov(struct sock *sk, int cscov, bool rx) 469/* byte 1 is feature. the rest is the preference list */
470static int dccp_setsockopt_change(struct sock *sk, int type,
471 struct dccp_so_feat __user *optval)
437{ 472{
438 u8 *list, len; 473 struct dccp_so_feat opt;
439 int i, rc; 474 u8 *val;
475 int rc;
440 476
441 if (cscov < 0 || cscov > 15) 477 if (copy_from_user(&opt, optval, sizeof(opt)))
442 return -EINVAL; 478 return -EFAULT;
443 /* 479 /*
444 * Populate a list of permissible values, in the range cscov...15. This 480 * rfc4340: 6.1. Change Options
445 * is necessary since feature negotiation of single values only works if
446 * both sides incidentally choose the same value. Since the list starts
447 * lowest-value first, negotiation will pick the smallest shared value.
448 */ 481 */
449 if (cscov == 0) 482 if (opt.dccpsf_len < 1)
450 return 0;
451 len = 16 - cscov;
452
453 list = kmalloc(len, GFP_KERNEL);
454 if (list == NULL)
455 return -ENOBUFS;
456
457 for (i = 0; i < len; i++)
458 list[i] = cscov++;
459
460 rc = dccp_feat_register_sp(sk, DCCPF_MIN_CSUM_COVER, rx, list, len);
461
462 if (rc == 0) {
463 if (rx)
464 dccp_sk(sk)->dccps_pcrlen = cscov;
465 else
466 dccp_sk(sk)->dccps_pcslen = cscov;
467 }
468 kfree(list);
469 return rc;
470}
471
472static int dccp_setsockopt_ccid(struct sock *sk, int type,
473 char __user *optval, int optlen)
474{
475 u8 *val;
476 int rc = 0;
477
478 if (optlen < 1 || optlen > DCCP_FEAT_MAX_SP_VALS)
479 return -EINVAL; 483 return -EINVAL;
480 484
481 val = kmalloc(optlen, GFP_KERNEL); 485 val = kmalloc(opt.dccpsf_len, GFP_KERNEL);
482 if (val == NULL) 486 if (!val)
483 return -ENOMEM; 487 return -ENOMEM;
484 488
485 if (copy_from_user(val, optval, optlen)) { 489 if (copy_from_user(val, opt.dccpsf_val, opt.dccpsf_len)) {
486 kfree(val); 490 rc = -EFAULT;
487 return -EFAULT; 491 goto out_free_val;
488 } 492 }
489 493
490 lock_sock(sk); 494 rc = dccp_feat_change(dccp_msk(sk), type, opt.dccpsf_feat,
491 if (type == DCCP_SOCKOPT_TX_CCID || type == DCCP_SOCKOPT_CCID) 495 val, opt.dccpsf_len, GFP_KERNEL);
492 rc = dccp_feat_register_sp(sk, DCCPF_CCID, 1, val, optlen); 496 if (rc)
497 goto out_free_val;
493 498
494 if (!rc && (type == DCCP_SOCKOPT_RX_CCID || type == DCCP_SOCKOPT_CCID)) 499out:
495 rc = dccp_feat_register_sp(sk, DCCPF_CCID, 0, val, optlen); 500 return rc;
496 release_sock(sk);
497 501
502out_free_val:
498 kfree(val); 503 kfree(val);
499 return rc; 504 goto out;
500} 505}
501 506
502static int do_dccp_setsockopt(struct sock *sk, int level, int optname, 507static int do_dccp_setsockopt(struct sock *sk, int level, int optname,
@@ -505,21 +510,7 @@ static int do_dccp_setsockopt(struct sock *sk, int level, int optname,
505 struct dccp_sock *dp = dccp_sk(sk); 510 struct dccp_sock *dp = dccp_sk(sk);
506 int val, err = 0; 511 int val, err = 0;
507 512
508 switch (optname) { 513 if (optlen < sizeof(int))
509 case DCCP_SOCKOPT_PACKET_SIZE:
510 DCCP_WARN("sockopt(PACKET_SIZE) is deprecated: fix your app\n");
511 return 0;
512 case DCCP_SOCKOPT_CHANGE_L:
513 case DCCP_SOCKOPT_CHANGE_R:
514 DCCP_WARN("sockopt(CHANGE_L/R) is deprecated: fix your app\n");
515 return 0;
516 case DCCP_SOCKOPT_CCID:
517 case DCCP_SOCKOPT_RX_CCID:
518 case DCCP_SOCKOPT_TX_CCID:
519 return dccp_setsockopt_ccid(sk, optname, optval, optlen);
520 }
521
522 if (optlen < (int)sizeof(int))
523 return -EINVAL; 514 return -EINVAL;
524 515
525 if (get_user(val, (int __user *)optval)) 516 if (get_user(val, (int __user *)optval))
@@ -530,38 +521,53 @@ static int do_dccp_setsockopt(struct sock *sk, int level, int optname,
530 521
531 lock_sock(sk); 522 lock_sock(sk);
532 switch (optname) { 523 switch (optname) {
524 case DCCP_SOCKOPT_PACKET_SIZE:
525 DCCP_WARN("sockopt(PACKET_SIZE) is deprecated: fix your app\n");
526 err = 0;
527 break;
528 case DCCP_SOCKOPT_CHANGE_L:
529 if (optlen != sizeof(struct dccp_so_feat))
530 err = -EINVAL;
531 else
532 err = dccp_setsockopt_change(sk, DCCPO_CHANGE_L,
533 (struct dccp_so_feat __user *)
534 optval);
535 break;
536 case DCCP_SOCKOPT_CHANGE_R:
537 if (optlen != sizeof(struct dccp_so_feat))
538 err = -EINVAL;
539 else
540 err = dccp_setsockopt_change(sk, DCCPO_CHANGE_R,
541 (struct dccp_so_feat __user *)
542 optval);
543 break;
533 case DCCP_SOCKOPT_SERVER_TIMEWAIT: 544 case DCCP_SOCKOPT_SERVER_TIMEWAIT:
534 if (dp->dccps_role != DCCP_ROLE_SERVER) 545 if (dp->dccps_role != DCCP_ROLE_SERVER)
535 err = -EOPNOTSUPP; 546 err = -EOPNOTSUPP;
536 else 547 else
537 dp->dccps_server_timewait = (val != 0); 548 dp->dccps_server_timewait = (val != 0);
538 break; 549 break;
539 case DCCP_SOCKOPT_SEND_CSCOV: 550 case DCCP_SOCKOPT_SEND_CSCOV: /* sender side, RFC 4340, sec. 9.2 */
540 err = dccp_setsockopt_cscov(sk, val, false); 551 if (val < 0 || val > 15)
541 break;
542 case DCCP_SOCKOPT_RECV_CSCOV:
543 err = dccp_setsockopt_cscov(sk, val, true);
544 break;
545 case DCCP_SOCKOPT_QPOLICY_ID:
546 if (sk->sk_state != DCCP_CLOSED)
547 err = -EISCONN;
548 else if (val < 0 || val >= DCCPQ_POLICY_MAX)
549 err = -EINVAL; 552 err = -EINVAL;
550 else 553 else
551 dp->dccps_qpolicy = val; 554 dp->dccps_pcslen = val;
552 break; 555 break;
553 case DCCP_SOCKOPT_QPOLICY_TXQLEN: 556 case DCCP_SOCKOPT_RECV_CSCOV: /* receiver side, RFC 4340 sec. 9.2.1 */
554 if (val < 0) 557 if (val < 0 || val > 15)
555 err = -EINVAL; 558 err = -EINVAL;
556 else 559 else {
557 dp->dccps_tx_qlen = val; 560 dp->dccps_pcrlen = val;
561 /* FIXME: add feature negotiation,
562 * ChangeL(MinimumChecksumCoverage, val) */
563 }
558 break; 564 break;
559 default: 565 default:
560 err = -ENOPROTOOPT; 566 err = -ENOPROTOOPT;
561 break; 567 break;
562 } 568 }
563 release_sock(sk);
564 569
570 release_sock(sk);
565 return err; 571 return err;
566} 572}
567 573
@@ -642,18 +648,6 @@ static int do_dccp_getsockopt(struct sock *sk, int level, int optname,
642 case DCCP_SOCKOPT_GET_CUR_MPS: 648 case DCCP_SOCKOPT_GET_CUR_MPS:
643 val = dp->dccps_mss_cache; 649 val = dp->dccps_mss_cache;
644 break; 650 break;
645 case DCCP_SOCKOPT_AVAILABLE_CCIDS:
646 return ccid_getsockopt_builtin_ccids(sk, len, optval, optlen);
647 case DCCP_SOCKOPT_TX_CCID:
648 val = ccid_get_current_tx_ccid(dp);
649 if (val < 0)
650 return -ENOPROTOOPT;
651 break;
652 case DCCP_SOCKOPT_RX_CCID:
653 val = ccid_get_current_rx_ccid(dp);
654 if (val < 0)
655 return -ENOPROTOOPT;
656 break;
657 case DCCP_SOCKOPT_SERVER_TIMEWAIT: 651 case DCCP_SOCKOPT_SERVER_TIMEWAIT:
658 val = dp->dccps_server_timewait; 652 val = dp->dccps_server_timewait;
659 break; 653 break;
@@ -663,12 +657,6 @@ static int do_dccp_getsockopt(struct sock *sk, int level, int optname,
663 case DCCP_SOCKOPT_RECV_CSCOV: 657 case DCCP_SOCKOPT_RECV_CSCOV:
664 val = dp->dccps_pcrlen; 658 val = dp->dccps_pcrlen;
665 break; 659 break;
666 case DCCP_SOCKOPT_QPOLICY_ID:
667 val = dp->dccps_qpolicy;
668 break;
669 case DCCP_SOCKOPT_QPOLICY_TXQLEN:
670 val = dp->dccps_tx_qlen;
671 break;
672 case 128 ... 191: 660 case 128 ... 191:
673 return ccid_hc_rx_getsockopt(dp->dccps_hc_rx_ccid, sk, optname, 661 return ccid_hc_rx_getsockopt(dp->dccps_hc_rx_ccid, sk, optname,
674 len, (u32 __user *)optval, optlen); 662 len, (u32 __user *)optval, optlen);
@@ -711,47 +699,6 @@ int compat_dccp_getsockopt(struct sock *sk, int level, int optname,
711EXPORT_SYMBOL_GPL(compat_dccp_getsockopt); 699EXPORT_SYMBOL_GPL(compat_dccp_getsockopt);
712#endif 700#endif
713 701
714static int dccp_msghdr_parse(struct msghdr *msg, struct sk_buff *skb)
715{
716 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msg);
717
718 /*
719 * Assign an (opaque) qpolicy priority value to skb->priority.
720 *
721 * We are overloading this skb field for use with the qpolicy subystem.
722 * The skb->priority is normally used for the SO_PRIORITY option, which
723 * is initialised from sk_priority. Since the assignment of sk_priority
724 * to skb->priority happens later (on layer 3), we overload this field
725 * for use with queueing priorities as long as the skb is on layer 4.
726 * The default priority value (if nothing is set) is 0.
727 */
728 skb->priority = 0;
729
730 for (; cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg)) {
731
732 if (!CMSG_OK(msg, cmsg))
733 return -EINVAL;
734
735 if (cmsg->cmsg_level != SOL_DCCP)
736 continue;
737
738 if (cmsg->cmsg_type <= DCCP_SCM_QPOLICY_MAX &&
739 !dccp_qpolicy_param_ok(skb->sk, cmsg->cmsg_type))
740 return -EINVAL;
741
742 switch (cmsg->cmsg_type) {
743 case DCCP_SCM_PRIORITY:
744 if (cmsg->cmsg_len != CMSG_LEN(sizeof(__u32)))
745 return -EINVAL;
746 skb->priority = *(__u32 *)CMSG_DATA(cmsg);
747 break;
748 default:
749 return -EINVAL;
750 }
751 }
752 return 0;
753}
754
755int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, 702int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
756 size_t len) 703 size_t len)
757{ 704{
@@ -767,7 +714,8 @@ int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
767 714
768 lock_sock(sk); 715 lock_sock(sk);
769 716
770 if (dccp_qpolicy_full(sk)) { 717 if (sysctl_dccp_tx_qlen &&
718 (sk->sk_write_queue.qlen >= sysctl_dccp_tx_qlen)) {
771 rc = -EAGAIN; 719 rc = -EAGAIN;
772 goto out_release; 720 goto out_release;
773 } 721 }
@@ -795,12 +743,8 @@ int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
795 if (rc != 0) 743 if (rc != 0)
796 goto out_discard; 744 goto out_discard;
797 745
798 rc = dccp_msghdr_parse(msg, skb); 746 skb_queue_tail(&sk->sk_write_queue, skb);
799 if (rc != 0) 747 dccp_write_xmit(sk,0);
800 goto out_discard;
801
802 dccp_qpolicy_push(sk, skb);
803 dccp_write_xmit(sk);
804out_release: 748out_release:
805 release_sock(sk); 749 release_sock(sk);
806 return rc ? : len; 750 return rc ? : len;
@@ -1023,22 +967,9 @@ void dccp_close(struct sock *sk, long timeout)
1023 /* Check zero linger _after_ checking for unread data. */ 967 /* Check zero linger _after_ checking for unread data. */
1024 sk->sk_prot->disconnect(sk, 0); 968 sk->sk_prot->disconnect(sk, 0);
1025 } else if (sk->sk_state != DCCP_CLOSED) { 969 } else if (sk->sk_state != DCCP_CLOSED) {
1026 /*
1027 * Normal connection termination. May need to wait if there are
1028 * still packets in the TX queue that are delayed by the CCID.
1029 */
1030 dccp_flush_write_queue(sk, &timeout);
1031 dccp_terminate_connection(sk); 970 dccp_terminate_connection(sk);
1032 } 971 }
1033 972
1034 /*
1035 * Flush write queue. This may be necessary in several cases:
1036 * - we have been closed by the peer but still have application data;
1037 * - abortive termination (unread data or zero linger time),
1038 * - normal termination but queue could not be flushed within time limit
1039 */
1040 __skb_queue_purge(&sk->sk_write_queue);
1041
1042 sk_stream_wait_close(sk, timeout); 973 sk_stream_wait_close(sk, timeout);
1043 974
1044adjudge_to_death: 975adjudge_to_death: