]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - net/dccp/proto.c
dccp: Tidy up setsockopt calls
[mirror_ubuntu-bionic-kernel.git] / net / dccp / proto.c
CommitLineData
7c657876
ACM
1/*
2 * net/dccp/proto.c
3 *
4 * An implementation of the DCCP protocol
5 * Arnaldo Carvalho de Melo <acme@conectiva.com.br>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
7c657876
ACM
12#include <linux/dccp.h>
13#include <linux/module.h>
14#include <linux/types.h>
15#include <linux/sched.h>
16#include <linux/kernel.h>
17#include <linux/skbuff.h>
18#include <linux/netdevice.h>
19#include <linux/in.h>
20#include <linux/if_arp.h>
21#include <linux/init.h>
22#include <linux/random.h>
23#include <net/checksum.h>
24
14c85021 25#include <net/inet_sock.h>
7c657876
ACM
26#include <net/sock.h>
27#include <net/xfrm.h>
28
6273172e 29#include <asm/ioctls.h>
7c657876
ACM
30#include <linux/spinlock.h>
31#include <linux/timer.h>
32#include <linux/delay.h>
33#include <linux/poll.h>
7c657876
ACM
34
35#include "ccid.h"
36#include "dccp.h"
afe00251 37#include "feat.h"
7c657876 38
ba89966c 39DEFINE_SNMP_STAT(struct dccp_mib, dccp_statistics) __read_mostly;
7c657876 40
f21e68ca
ACM
41EXPORT_SYMBOL_GPL(dccp_statistics);
42
7c657876
ACM
43atomic_t dccp_orphan_count = ATOMIC_INIT(0);
44
f21e68ca
ACM
45EXPORT_SYMBOL_GPL(dccp_orphan_count);
46
075ae866
ACM
47struct inet_hashinfo __cacheline_aligned dccp_hashinfo = {
48 .lhash_lock = RW_LOCK_UNLOCKED,
49 .lhash_users = ATOMIC_INIT(0),
50 .lhash_wait = __WAIT_QUEUE_HEAD_INITIALIZER(dccp_hashinfo.lhash_wait),
51};
52
53EXPORT_SYMBOL_GPL(dccp_hashinfo);
54
b1308dc0
IM
55/* the maximum queue length for tx in packets. 0 is no limit */
56int sysctl_dccp_tx_qlen __read_mostly = 5;
57
c25a18ba
ACM
58void dccp_set_state(struct sock *sk, const int state)
59{
60 const int oldstate = sk->sk_state;
61
f11135a3 62 dccp_pr_debug("%s(%p) %s --> %s\n", dccp_role(sk), sk,
c25a18ba
ACM
63 dccp_state_name(oldstate), dccp_state_name(state));
64 WARN_ON(state == oldstate);
65
66 switch (state) {
67 case DCCP_OPEN:
68 if (oldstate != DCCP_OPEN)
69 DCCP_INC_STATS(DCCP_MIB_CURRESTAB);
70 break;
71
72 case DCCP_CLOSED:
0c869620
GR
73 if (oldstate == DCCP_OPEN || oldstate == DCCP_ACTIVE_CLOSEREQ ||
74 oldstate == DCCP_CLOSING)
c25a18ba
ACM
75 DCCP_INC_STATS(DCCP_MIB_ESTABRESETS);
76
77 sk->sk_prot->unhash(sk);
78 if (inet_csk(sk)->icsk_bind_hash != NULL &&
79 !(sk->sk_userlocks & SOCK_BINDPORT_LOCK))
ab1e0a13 80 inet_put_port(sk);
c25a18ba
ACM
81 /* fall through */
82 default:
83 if (oldstate == DCCP_OPEN)
84 DCCP_DEC_STATS(DCCP_MIB_CURRESTAB);
85 }
86
87 /* Change state AFTER socket is unhashed to avoid closed
88 * socket sitting in hash tables.
89 */
90 sk->sk_state = state;
91}
92
93EXPORT_SYMBOL_GPL(dccp_set_state);
94
0c869620
GR
95static void dccp_finish_passive_close(struct sock *sk)
96{
97 switch (sk->sk_state) {
98 case DCCP_PASSIVE_CLOSE:
99 /* Node (client or server) has received Close packet. */
100 dccp_send_reset(sk, DCCP_RESET_CODE_CLOSED);
101 dccp_set_state(sk, DCCP_CLOSED);
102 break;
103 case DCCP_PASSIVE_CLOSEREQ:
104 /*
105 * Client received CloseReq. We set the `active' flag so that
106 * dccp_send_close() retransmits the Close as per RFC 4340, 8.3.
107 */
108 dccp_send_close(sk, 1);
109 dccp_set_state(sk, DCCP_CLOSING);
110 }
111}
112
c25a18ba
ACM
113void dccp_done(struct sock *sk)
114{
115 dccp_set_state(sk, DCCP_CLOSED);
116 dccp_clear_xmit_timers(sk);
117
118 sk->sk_shutdown = SHUTDOWN_MASK;
119
120 if (!sock_flag(sk, SOCK_DEAD))
121 sk->sk_state_change(sk);
122 else
123 inet_csk_destroy_sock(sk);
124}
125
126EXPORT_SYMBOL_GPL(dccp_done);
127
7c657876
ACM
128const char *dccp_packet_name(const int type)
129{
130 static const char *dccp_packet_names[] = {
131 [DCCP_PKT_REQUEST] = "REQUEST",
132 [DCCP_PKT_RESPONSE] = "RESPONSE",
133 [DCCP_PKT_DATA] = "DATA",
134 [DCCP_PKT_ACK] = "ACK",
135 [DCCP_PKT_DATAACK] = "DATAACK",
136 [DCCP_PKT_CLOSEREQ] = "CLOSEREQ",
137 [DCCP_PKT_CLOSE] = "CLOSE",
138 [DCCP_PKT_RESET] = "RESET",
139 [DCCP_PKT_SYNC] = "SYNC",
140 [DCCP_PKT_SYNCACK] = "SYNCACK",
141 };
142
143 if (type >= DCCP_NR_PKT_TYPES)
144 return "INVALID";
145 else
146 return dccp_packet_names[type];
147}
148
149EXPORT_SYMBOL_GPL(dccp_packet_name);
150
151const char *dccp_state_name(const int state)
152{
153 static char *dccp_state_names[] = {
f11135a3
GR
154 [DCCP_OPEN] = "OPEN",
155 [DCCP_REQUESTING] = "REQUESTING",
156 [DCCP_PARTOPEN] = "PARTOPEN",
157 [DCCP_LISTEN] = "LISTEN",
158 [DCCP_RESPOND] = "RESPOND",
159 [DCCP_CLOSING] = "CLOSING",
160 [DCCP_ACTIVE_CLOSEREQ] = "CLOSEREQ",
161 [DCCP_PASSIVE_CLOSE] = "PASSIVE_CLOSE",
162 [DCCP_PASSIVE_CLOSEREQ] = "PASSIVE_CLOSEREQ",
163 [DCCP_TIME_WAIT] = "TIME_WAIT",
164 [DCCP_CLOSED] = "CLOSED",
7c657876
ACM
165 };
166
167 if (state >= DCCP_MAX_STATES)
168 return "INVALID STATE!";
169 else
170 return dccp_state_names[state];
171}
172
173EXPORT_SYMBOL_GPL(dccp_state_name);
174
72478873 175int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized)
3e0fadc5
ACM
176{
177 struct dccp_sock *dp = dccp_sk(sk);
a4bf3902 178 struct dccp_minisock *dmsk = dccp_msk(sk);
3e0fadc5 179 struct inet_connection_sock *icsk = inet_csk(sk);
3e0fadc5 180
a4bf3902 181 dccp_minisock_init(&dp->dccps_minisock);
3e0fadc5 182
e18d7a98
ACM
183 icsk->icsk_rto = DCCP_TIMEOUT_INIT;
184 icsk->icsk_syn_retries = sysctl_dccp_request_retries;
185 sk->sk_state = DCCP_CLOSED;
186 sk->sk_write_space = dccp_write_space;
187 icsk->icsk_sync_mss = dccp_sync_mss;
188 dp->dccps_mss_cache = 536;
189 dp->dccps_rate_last = jiffies;
190 dp->dccps_role = DCCP_ROLE_UNDEFINED;
191 dp->dccps_service = DCCP_SERVICE_CODE_IS_ABSENT;
192 dp->dccps_l_ack_ratio = dp->dccps_r_ack_ratio = 1;
193
194 dccp_init_xmit_timers(sk);
195
828755ce 196 INIT_LIST_HEAD(&dp->dccps_featneg);
3e0fadc5
ACM
197 /*
198 * FIXME: We're hardcoding the CCID, and doing this at this point makes
199 * the listening (master) sock get CCID control blocks, which is not
200 * necessary, but for now, to not mess with the test userspace apps,
201 * lets leave it here, later the real solution is to do this in a
202 * setsockopt(CCIDs-I-want/accept). -acme
203 */
72478873 204 if (likely(ctl_sock_initialized)) {
86349c8d 205 int rc = dccp_feat_init(sk);
3e0fadc5
ACM
206
207 if (rc)
208 return rc;
209
a4bf3902 210 if (dmsk->dccpms_send_ack_vector) {
3e0fadc5
ACM
211 dp->dccps_hc_rx_ackvec = dccp_ackvec_alloc(GFP_KERNEL);
212 if (dp->dccps_hc_rx_ackvec == NULL)
213 return -ENOMEM;
214 }
a4bf3902
ACM
215 dp->dccps_hc_rx_ccid = ccid_hc_rx_new(dmsk->dccpms_rx_ccid,
216 sk, GFP_KERNEL);
217 dp->dccps_hc_tx_ccid = ccid_hc_tx_new(dmsk->dccpms_tx_ccid,
218 sk, GFP_KERNEL);
8109b02b 219 if (unlikely(dp->dccps_hc_rx_ccid == NULL ||
3e0fadc5
ACM
220 dp->dccps_hc_tx_ccid == NULL)) {
221 ccid_hc_rx_delete(dp->dccps_hc_rx_ccid, sk);
222 ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk);
a4bf3902 223 if (dmsk->dccpms_send_ack_vector) {
3e0fadc5
ACM
224 dccp_ackvec_free(dp->dccps_hc_rx_ackvec);
225 dp->dccps_hc_rx_ackvec = NULL;
226 }
227 dp->dccps_hc_rx_ccid = dp->dccps_hc_tx_ccid = NULL;
228 return -ENOMEM;
229 }
230 } else {
231 /* control socket doesn't need feat nego */
a4bf3902
ACM
232 INIT_LIST_HEAD(&dmsk->dccpms_pending);
233 INIT_LIST_HEAD(&dmsk->dccpms_conf);
3e0fadc5
ACM
234 }
235
3e0fadc5
ACM
236 return 0;
237}
238
239EXPORT_SYMBOL_GPL(dccp_init_sock);
240
7d06b2e0 241void dccp_destroy_sock(struct sock *sk)
3e0fadc5
ACM
242{
243 struct dccp_sock *dp = dccp_sk(sk);
8ca0d17b 244 struct dccp_minisock *dmsk = dccp_msk(sk);
3e0fadc5
ACM
245
246 /*
247 * DCCP doesn't use sk_write_queue, just sk_send_head
248 * for retransmissions
249 */
250 if (sk->sk_send_head != NULL) {
251 kfree_skb(sk->sk_send_head);
252 sk->sk_send_head = NULL;
253 }
254
255 /* Clean up a referenced DCCP bind bucket. */
256 if (inet_csk(sk)->icsk_bind_hash != NULL)
ab1e0a13 257 inet_put_port(sk);
3e0fadc5
ACM
258
259 kfree(dp->dccps_service_list);
260 dp->dccps_service_list = NULL;
261
8ca0d17b 262 if (dmsk->dccpms_send_ack_vector) {
3e0fadc5
ACM
263 dccp_ackvec_free(dp->dccps_hc_rx_ackvec);
264 dp->dccps_hc_rx_ackvec = NULL;
265 }
266 ccid_hc_rx_delete(dp->dccps_hc_rx_ccid, sk);
267 ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk);
268 dp->dccps_hc_rx_ccid = dp->dccps_hc_tx_ccid = NULL;
269
270 /* clean up feature negotiation state */
70208383 271 dccp_feat_list_purge(&dp->dccps_featneg);
3e0fadc5
ACM
272}
273
274EXPORT_SYMBOL_GPL(dccp_destroy_sock);
275
72a3effa 276static inline int dccp_listen_start(struct sock *sk, int backlog)
7c657876 277{
67e6b629
ACM
278 struct dccp_sock *dp = dccp_sk(sk);
279
280 dp->dccps_role = DCCP_ROLE_LISTEN;
093e1f46
GR
281 /* do not start to listen if feature negotiation setup fails */
282 if (dccp_feat_finalise_settings(dp))
283 return -EPROTO;
72a3effa 284 return inet_csk_listen_start(sk, backlog);
7c657876
ACM
285}
286
ce865a61
GR
287static inline int dccp_need_reset(int state)
288{
289 return state != DCCP_CLOSED && state != DCCP_LISTEN &&
290 state != DCCP_REQUESTING;
291}
292
7c657876
ACM
293int dccp_disconnect(struct sock *sk, int flags)
294{
295 struct inet_connection_sock *icsk = inet_csk(sk);
296 struct inet_sock *inet = inet_sk(sk);
297 int err = 0;
298 const int old_state = sk->sk_state;
299
300 if (old_state != DCCP_CLOSED)
301 dccp_set_state(sk, DCCP_CLOSED);
302
ce865a61
GR
303 /*
304 * This corresponds to the ABORT function of RFC793, sec. 3.8
305 * TCP uses a RST segment, DCCP a Reset packet with Code 2, "Aborted".
306 */
7c657876
ACM
307 if (old_state == DCCP_LISTEN) {
308 inet_csk_listen_stop(sk);
ce865a61
GR
309 } else if (dccp_need_reset(old_state)) {
310 dccp_send_reset(sk, DCCP_RESET_CODE_ABORTED);
311 sk->sk_err = ECONNRESET;
7c657876
ACM
312 } else if (old_state == DCCP_REQUESTING)
313 sk->sk_err = ECONNRESET;
314
315 dccp_clear_xmit_timers(sk);
48816322 316
7c657876 317 __skb_queue_purge(&sk->sk_receive_queue);
48816322 318 __skb_queue_purge(&sk->sk_write_queue);
7c657876
ACM
319 if (sk->sk_send_head != NULL) {
320 __kfree_skb(sk->sk_send_head);
321 sk->sk_send_head = NULL;
322 }
323
324 inet->dport = 0;
325
326 if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK))
327 inet_reset_saddr(sk);
328
329 sk->sk_shutdown = 0;
330 sock_reset_flag(sk, SOCK_DONE);
331
332 icsk->icsk_backoff = 0;
333 inet_csk_delack_init(sk);
334 __sk_dst_reset(sk);
335
547b792c 336 WARN_ON(inet->num && !icsk->icsk_bind_hash);
7c657876
ACM
337
338 sk->sk_error_report(sk);
339 return err;
340}
341
f21e68ca
ACM
342EXPORT_SYMBOL_GPL(dccp_disconnect);
343
331968bd
ACM
344/*
345 * Wait for a DCCP event.
346 *
347 * Note that we don't need to lock the socket, as the upper poll layers
348 * take care of normal races (between the test and the event) and we don't
349 * go look at any of the socket buffers directly.
350 */
f21e68ca
ACM
351unsigned int dccp_poll(struct file *file, struct socket *sock,
352 poll_table *wait)
331968bd
ACM
353{
354 unsigned int mask;
355 struct sock *sk = sock->sk;
356
357 poll_wait(file, sk->sk_sleep, wait);
358 if (sk->sk_state == DCCP_LISTEN)
359 return inet_csk_listen_poll(sk);
360
361 /* Socket is not locked. We are protected from async events
362 by poll logic and correct handling of state changes
363 made by another threads is impossible in any case.
364 */
365
366 mask = 0;
367 if (sk->sk_err)
368 mask = POLLERR;
369
370 if (sk->sk_shutdown == SHUTDOWN_MASK || sk->sk_state == DCCP_CLOSED)
371 mask |= POLLHUP;
372 if (sk->sk_shutdown & RCV_SHUTDOWN)
f348d70a 373 mask |= POLLIN | POLLRDNORM | POLLRDHUP;
331968bd
ACM
374
375 /* Connected? */
376 if ((1 << sk->sk_state) & ~(DCCPF_REQUESTING | DCCPF_RESPOND)) {
377 if (atomic_read(&sk->sk_rmem_alloc) > 0)
378 mask |= POLLIN | POLLRDNORM;
379
380 if (!(sk->sk_shutdown & SEND_SHUTDOWN)) {
381 if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk)) {
382 mask |= POLLOUT | POLLWRNORM;
383 } else { /* send SIGIO later */
384 set_bit(SOCK_ASYNC_NOSPACE,
385 &sk->sk_socket->flags);
386 set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
387
388 /* Race breaker. If space is freed after
389 * wspace test but before the flags are set,
390 * IO signal will be lost.
391 */
392 if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk))
393 mask |= POLLOUT | POLLWRNORM;
394 }
395 }
396 }
397 return mask;
398}
399
f21e68ca
ACM
400EXPORT_SYMBOL_GPL(dccp_poll);
401
7c657876
ACM
402int dccp_ioctl(struct sock *sk, int cmd, unsigned long arg)
403{
6273172e
ACM
404 int rc = -ENOTCONN;
405
406 lock_sock(sk);
407
408 if (sk->sk_state == DCCP_LISTEN)
409 goto out;
410
411 switch (cmd) {
412 case SIOCINQ: {
413 struct sk_buff *skb;
414 unsigned long amount = 0;
415
416 skb = skb_peek(&sk->sk_receive_queue);
417 if (skb != NULL) {
418 /*
419 * We will only return the amount of this packet since
420 * that is all that will be read.
421 */
422 amount = skb->len;
423 }
424 rc = put_user(amount, (int __user *)arg);
425 }
426 break;
427 default:
428 rc = -ENOIOCTLCMD;
429 break;
430 }
431out:
432 release_sock(sk);
433 return rc;
7c657876
ACM
434}
435
f21e68ca
ACM
436EXPORT_SYMBOL_GPL(dccp_ioctl);
437
60fe62e7 438static int dccp_setsockopt_service(struct sock *sk, const __be32 service,
67e6b629
ACM
439 char __user *optval, int optlen)
440{
441 struct dccp_sock *dp = dccp_sk(sk);
442 struct dccp_service_list *sl = NULL;
443
8109b02b 444 if (service == DCCP_SERVICE_INVALID_VALUE ||
67e6b629
ACM
445 optlen > DCCP_SERVICE_LIST_MAX_LEN * sizeof(u32))
446 return -EINVAL;
447
448 if (optlen > sizeof(service)) {
449 sl = kmalloc(optlen, GFP_KERNEL);
450 if (sl == NULL)
451 return -ENOMEM;
452
453 sl->dccpsl_nr = optlen / sizeof(u32) - 1;
454 if (copy_from_user(sl->dccpsl_list,
455 optval + sizeof(service),
456 optlen - sizeof(service)) ||
457 dccp_list_has_service(sl, DCCP_SERVICE_INVALID_VALUE)) {
458 kfree(sl);
459 return -EFAULT;
460 }
461 }
462
463 lock_sock(sk);
464 dp->dccps_service = service;
465
a51482bd 466 kfree(dp->dccps_service_list);
67e6b629
ACM
467
468 dp->dccps_service_list = sl;
469 release_sock(sk);
470 return 0;
471}
472
20f41eee
GR
473static int dccp_setsockopt_cscov(struct sock *sk, int cscov, bool rx)
474{
475 u8 *list, len;
476 int i, rc;
477
478 if (cscov < 0 || cscov > 15)
479 return -EINVAL;
480 /*
481 * Populate a list of permissible values, in the range cscov...15. This
482 * is necessary since feature negotiation of single values only works if
483 * both sides incidentally choose the same value. Since the list starts
484 * lowest-value first, negotiation will pick the smallest shared value.
485 */
486 if (cscov == 0)
487 return 0;
488 len = 16 - cscov;
489
490 list = kmalloc(len, GFP_KERNEL);
491 if (list == NULL)
492 return -ENOBUFS;
493
494 for (i = 0; i < len; i++)
495 list[i] = cscov++;
496
497 rc = dccp_feat_register_sp(sk, DCCPF_MIN_CSUM_COVER, rx, list, len);
498
499 if (rc == 0) {
500 if (rx)
501 dccp_sk(sk)->dccps_pcrlen = cscov;
502 else
503 dccp_sk(sk)->dccps_pcslen = cscov;
504 }
505 kfree(list);
506 return rc;
507}
508
3fdadf7d
DM
509static int do_dccp_setsockopt(struct sock *sk, int level, int optname,
510 char __user *optval, int optlen)
7c657876 511{
09dbc389
GR
512 struct dccp_sock *dp = dccp_sk(sk);
513 int val, err = 0;
7c657876 514
73bbe095
GR
515 switch (optname) {
516 case DCCP_SOCKOPT_PACKET_SIZE:
517 DCCP_WARN("sockopt(PACKET_SIZE) is deprecated: fix your app\n");
518 return 0;
519 case DCCP_SOCKOPT_CHANGE_L:
520 case DCCP_SOCKOPT_CHANGE_R:
521 DCCP_WARN("sockopt(CHANGE_L/R) is deprecated: fix your app\n");
522 return 0;
523 }
524
525 if (optlen < (int)sizeof(int))
a84ffe43
ACM
526 return -EINVAL;
527
528 if (get_user(val, (int __user *)optval))
529 return -EFAULT;
530
67e6b629
ACM
531 if (optname == DCCP_SOCKOPT_SERVICE)
532 return dccp_setsockopt_service(sk, val, optval, optlen);
a84ffe43 533
67e6b629 534 lock_sock(sk);
a84ffe43 535 switch (optname) {
b8599d20
GR
536 case DCCP_SOCKOPT_SERVER_TIMEWAIT:
537 if (dp->dccps_role != DCCP_ROLE_SERVER)
538 err = -EOPNOTSUPP;
539 else
540 dp->dccps_server_timewait = (val != 0);
541 break;
20f41eee
GR
542 case DCCP_SOCKOPT_SEND_CSCOV:
543 err = dccp_setsockopt_cscov(sk, val, false);
6f4e5fff 544 break;
20f41eee
GR
545 case DCCP_SOCKOPT_RECV_CSCOV:
546 err = dccp_setsockopt_cscov(sk, val, true);
6f4e5fff 547 break;
a84ffe43
ACM
548 default:
549 err = -ENOPROTOOPT;
550 break;
551 }
a84ffe43 552 release_sock(sk);
73bbe095 553
a84ffe43 554 return err;
7c657876
ACM
555}
556
3fdadf7d
DM
557int dccp_setsockopt(struct sock *sk, int level, int optname,
558 char __user *optval, int optlen)
559{
560 if (level != SOL_DCCP)
561 return inet_csk(sk)->icsk_af_ops->setsockopt(sk, level,
562 optname, optval,
563 optlen);
564 return do_dccp_setsockopt(sk, level, optname, optval, optlen);
565}
543d9cfe 566
f21e68ca
ACM
567EXPORT_SYMBOL_GPL(dccp_setsockopt);
568
3fdadf7d
DM
569#ifdef CONFIG_COMPAT
570int compat_dccp_setsockopt(struct sock *sk, int level, int optname,
543d9cfe 571 char __user *optval, int optlen)
3fdadf7d 572{
dec73ff0
ACM
573 if (level != SOL_DCCP)
574 return inet_csk_compat_setsockopt(sk, level, optname,
575 optval, optlen);
3fdadf7d
DM
576 return do_dccp_setsockopt(sk, level, optname, optval, optlen);
577}
543d9cfe 578
3fdadf7d
DM
579EXPORT_SYMBOL_GPL(compat_dccp_setsockopt);
580#endif
581
67e6b629 582static int dccp_getsockopt_service(struct sock *sk, int len,
60fe62e7 583 __be32 __user *optval,
67e6b629
ACM
584 int __user *optlen)
585{
586 const struct dccp_sock *dp = dccp_sk(sk);
587 const struct dccp_service_list *sl;
588 int err = -ENOENT, slen = 0, total_len = sizeof(u32);
589
590 lock_sock(sk);
67e6b629
ACM
591 if ((sl = dp->dccps_service_list) != NULL) {
592 slen = sl->dccpsl_nr * sizeof(u32);
593 total_len += slen;
594 }
595
596 err = -EINVAL;
597 if (total_len > len)
598 goto out;
599
600 err = 0;
601 if (put_user(total_len, optlen) ||
602 put_user(dp->dccps_service, optval) ||
603 (sl != NULL && copy_to_user(optval + 1, sl->dccpsl_list, slen)))
604 err = -EFAULT;
605out:
606 release_sock(sk);
607 return err;
608}
609
3fdadf7d 610static int do_dccp_getsockopt(struct sock *sk, int level, int optname,
a1d3a355 611 char __user *optval, int __user *optlen)
7c657876 612{
a84ffe43
ACM
613 struct dccp_sock *dp;
614 int val, len;
7c657876 615
a84ffe43
ACM
616 if (get_user(len, optlen))
617 return -EFAULT;
618
39ebc027 619 if (len < (int)sizeof(int))
a84ffe43
ACM
620 return -EINVAL;
621
622 dp = dccp_sk(sk);
623
624 switch (optname) {
625 case DCCP_SOCKOPT_PACKET_SIZE:
5aed3243 626 DCCP_WARN("sockopt(PACKET_SIZE) is deprecated: fix your app\n");
841bac1d 627 return 0;
88f964db
ACM
628 case DCCP_SOCKOPT_SERVICE:
629 return dccp_getsockopt_service(sk, len,
60fe62e7 630 (__be32 __user *)optval, optlen);
7c559a9e
GR
631 case DCCP_SOCKOPT_GET_CUR_MPS:
632 val = dp->dccps_mss_cache;
7c559a9e 633 break;
71bb4959
GR
634 case DCCP_SOCKOPT_AVAILABLE_CCIDS:
635 return ccid_getsockopt_builtin_ccids(sk, len, optval, optlen);
b8599d20
GR
636 case DCCP_SOCKOPT_SERVER_TIMEWAIT:
637 val = dp->dccps_server_timewait;
b8599d20 638 break;
6f4e5fff
GR
639 case DCCP_SOCKOPT_SEND_CSCOV:
640 val = dp->dccps_pcslen;
641 break;
642 case DCCP_SOCKOPT_RECV_CSCOV:
643 val = dp->dccps_pcrlen;
644 break;
88f964db
ACM
645 case 128 ... 191:
646 return ccid_hc_rx_getsockopt(dp->dccps_hc_rx_ccid, sk, optname,
647 len, (u32 __user *)optval, optlen);
648 case 192 ... 255:
649 return ccid_hc_tx_getsockopt(dp->dccps_hc_tx_ccid, sk, optname,
650 len, (u32 __user *)optval, optlen);
a84ffe43
ACM
651 default:
652 return -ENOPROTOOPT;
653 }
654
79133506 655 len = sizeof(val);
a84ffe43
ACM
656 if (put_user(len, optlen) || copy_to_user(optval, &val, len))
657 return -EFAULT;
658
659 return 0;
7c657876
ACM
660}
661
3fdadf7d
DM
662int dccp_getsockopt(struct sock *sk, int level, int optname,
663 char __user *optval, int __user *optlen)
664{
665 if (level != SOL_DCCP)
666 return inet_csk(sk)->icsk_af_ops->getsockopt(sk, level,
667 optname, optval,
668 optlen);
669 return do_dccp_getsockopt(sk, level, optname, optval, optlen);
670}
543d9cfe 671
f21e68ca
ACM
672EXPORT_SYMBOL_GPL(dccp_getsockopt);
673
3fdadf7d
DM
674#ifdef CONFIG_COMPAT
675int compat_dccp_getsockopt(struct sock *sk, int level, int optname,
543d9cfe 676 char __user *optval, int __user *optlen)
3fdadf7d 677{
dec73ff0
ACM
678 if (level != SOL_DCCP)
679 return inet_csk_compat_getsockopt(sk, level, optname,
680 optval, optlen);
3fdadf7d
DM
681 return do_dccp_getsockopt(sk, level, optname, optval, optlen);
682}
543d9cfe 683
3fdadf7d
DM
684EXPORT_SYMBOL_GPL(compat_dccp_getsockopt);
685#endif
686
7c657876
ACM
687int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
688 size_t len)
689{
690 const struct dccp_sock *dp = dccp_sk(sk);
691 const int flags = msg->msg_flags;
692 const int noblock = flags & MSG_DONTWAIT;
693 struct sk_buff *skb;
694 int rc, size;
695 long timeo;
696
697 if (len > dp->dccps_mss_cache)
698 return -EMSGSIZE;
699
700 lock_sock(sk);
b1308dc0
IM
701
702 if (sysctl_dccp_tx_qlen &&
703 (sk->sk_write_queue.qlen >= sysctl_dccp_tx_qlen)) {
704 rc = -EAGAIN;
705 goto out_release;
706 }
707
27258ee5 708 timeo = sock_sndtimeo(sk, noblock);
7c657876
ACM
709
710 /*
711 * We have to use sk_stream_wait_connect here to set sk_write_pending,
712 * so that the trick in dccp_rcv_request_sent_state_process.
713 */
714 /* Wait for a connection to finish. */
cecd8d0e 715 if ((1 << sk->sk_state) & ~(DCCPF_OPEN | DCCPF_PARTOPEN))
7c657876 716 if ((rc = sk_stream_wait_connect(sk, &timeo)) != 0)
27258ee5 717 goto out_release;
7c657876
ACM
718
719 size = sk->sk_prot->max_header + len;
720 release_sock(sk);
721 skb = sock_alloc_send_skb(sk, size, noblock, &rc);
722 lock_sock(sk);
7c657876
ACM
723 if (skb == NULL)
724 goto out_release;
725
726 skb_reserve(skb, sk->sk_prot->max_header);
727 rc = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
27258ee5
ACM
728 if (rc != 0)
729 goto out_discard;
730
97e5848d
IM
731 skb_queue_tail(&sk->sk_write_queue, skb);
732 dccp_write_xmit(sk,0);
7c657876
ACM
733out_release:
734 release_sock(sk);
735 return rc ? : len;
27258ee5
ACM
736out_discard:
737 kfree_skb(skb);
7c657876 738 goto out_release;
7c657876
ACM
739}
740
f21e68ca
ACM
741EXPORT_SYMBOL_GPL(dccp_sendmsg);
742
7c657876
ACM
743int dccp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
744 size_t len, int nonblock, int flags, int *addr_len)
745{
746 const struct dccp_hdr *dh;
7c657876
ACM
747 long timeo;
748
749 lock_sock(sk);
750
531669a0
ACM
751 if (sk->sk_state == DCCP_LISTEN) {
752 len = -ENOTCONN;
7c657876 753 goto out;
7c657876 754 }
7c657876 755
531669a0 756 timeo = sock_rcvtimeo(sk, nonblock);
7c657876
ACM
757
758 do {
531669a0 759 struct sk_buff *skb = skb_peek(&sk->sk_receive_queue);
7c657876 760
531669a0
ACM
761 if (skb == NULL)
762 goto verify_sock_status;
7c657876 763
531669a0 764 dh = dccp_hdr(skb);
7c657876 765
0c869620
GR
766 switch (dh->dccph_type) {
767 case DCCP_PKT_DATA:
768 case DCCP_PKT_DATAACK:
531669a0 769 goto found_ok_skb;
7c657876 770
0c869620
GR
771 case DCCP_PKT_CLOSE:
772 case DCCP_PKT_CLOSEREQ:
773 if (!(flags & MSG_PEEK))
774 dccp_finish_passive_close(sk);
775 /* fall through */
776 case DCCP_PKT_RESET:
777 dccp_pr_debug("found fin (%s) ok!\n",
778 dccp_packet_name(dh->dccph_type));
531669a0
ACM
779 len = 0;
780 goto found_fin_ok;
0c869620
GR
781 default:
782 dccp_pr_debug("packet_type=%s\n",
783 dccp_packet_name(dh->dccph_type));
784 sk_eat_skb(sk, skb, 0);
531669a0 785 }
531669a0
ACM
786verify_sock_status:
787 if (sock_flag(sk, SOCK_DONE)) {
788 len = 0;
7c657876 789 break;
531669a0 790 }
7c657876 791
531669a0
ACM
792 if (sk->sk_err) {
793 len = sock_error(sk);
794 break;
795 }
7c657876 796
531669a0
ACM
797 if (sk->sk_shutdown & RCV_SHUTDOWN) {
798 len = 0;
799 break;
800 }
7c657876 801
531669a0
ACM
802 if (sk->sk_state == DCCP_CLOSED) {
803 if (!sock_flag(sk, SOCK_DONE)) {
804 /* This occurs when user tries to read
805 * from never connected socket.
806 */
807 len = -ENOTCONN;
7c657876
ACM
808 break;
809 }
531669a0
ACM
810 len = 0;
811 break;
7c657876
ACM
812 }
813
531669a0
ACM
814 if (!timeo) {
815 len = -EAGAIN;
816 break;
817 }
7c657876 818
531669a0
ACM
819 if (signal_pending(current)) {
820 len = sock_intr_errno(timeo);
821 break;
822 }
7c657876 823
531669a0 824 sk_wait_data(sk, &timeo);
7c657876 825 continue;
7c657876 826 found_ok_skb:
531669a0
ACM
827 if (len > skb->len)
828 len = skb->len;
829 else if (len < skb->len)
830 msg->msg_flags |= MSG_TRUNC;
831
832 if (skb_copy_datagram_iovec(skb, 0, msg->msg_iov, len)) {
833 /* Exception. Bailout! */
834 len = -EFAULT;
835 break;
7c657876 836 }
7c657876
ACM
837 found_fin_ok:
838 if (!(flags & MSG_PEEK))
624d1164 839 sk_eat_skb(sk, skb, 0);
7c657876 840 break;
531669a0 841 } while (1);
7c657876
ACM
842out:
843 release_sock(sk);
531669a0 844 return len;
7c657876
ACM
845}
846
f21e68ca
ACM
847EXPORT_SYMBOL_GPL(dccp_recvmsg);
848
849int inet_dccp_listen(struct socket *sock, int backlog)
7c657876
ACM
850{
851 struct sock *sk = sock->sk;
852 unsigned char old_state;
853 int err;
854
855 lock_sock(sk);
856
857 err = -EINVAL;
858 if (sock->state != SS_UNCONNECTED || sock->type != SOCK_DCCP)
859 goto out;
860
861 old_state = sk->sk_state;
862 if (!((1 << old_state) & (DCCPF_CLOSED | DCCPF_LISTEN)))
863 goto out;
864
865 /* Really, if the socket is already in listen state
866 * we can only allow the backlog to be adjusted.
867 */
868 if (old_state != DCCP_LISTEN) {
869 /*
870 * FIXME: here it probably should be sk->sk_prot->listen_start
871 * see tcp_listen_start
872 */
72a3effa 873 err = dccp_listen_start(sk, backlog);
7c657876
ACM
874 if (err)
875 goto out;
876 }
877 sk->sk_max_ack_backlog = backlog;
878 err = 0;
879
880out:
881 release_sock(sk);
882 return err;
883}
884
f21e68ca
ACM
885EXPORT_SYMBOL_GPL(inet_dccp_listen);
886
0c869620 887static void dccp_terminate_connection(struct sock *sk)
7c657876 888{
0c869620 889 u8 next_state = DCCP_CLOSED;
7c657876 890
0c869620
GR
891 switch (sk->sk_state) {
892 case DCCP_PASSIVE_CLOSE:
893 case DCCP_PASSIVE_CLOSEREQ:
894 dccp_finish_passive_close(sk);
895 break;
896 case DCCP_PARTOPEN:
897 dccp_pr_debug("Stop PARTOPEN timer (%p)\n", sk);
898 inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK);
899 /* fall through */
900 case DCCP_OPEN:
901 dccp_send_close(sk, 1);
7c657876 902
b8599d20
GR
903 if (dccp_sk(sk)->dccps_role == DCCP_ROLE_SERVER &&
904 !dccp_sk(sk)->dccps_server_timewait)
0c869620
GR
905 next_state = DCCP_ACTIVE_CLOSEREQ;
906 else
907 next_state = DCCP_CLOSING;
908 /* fall through */
909 default:
910 dccp_set_state(sk, next_state);
911 }
7c657876
ACM
912}
913
914void dccp_close(struct sock *sk, long timeout)
915{
97e5848d 916 struct dccp_sock *dp = dccp_sk(sk);
7c657876 917 struct sk_buff *skb;
d83bd95b 918 u32 data_was_unread = 0;
134af346 919 int state;
7c657876
ACM
920
921 lock_sock(sk);
922
923 sk->sk_shutdown = SHUTDOWN_MASK;
924
925 if (sk->sk_state == DCCP_LISTEN) {
926 dccp_set_state(sk, DCCP_CLOSED);
927
928 /* Special case. */
929 inet_csk_listen_stop(sk);
930
931 goto adjudge_to_death;
932 }
933
97e5848d
IM
934 sk_stop_timer(sk, &dp->dccps_xmit_timer);
935
7c657876
ACM
936 /*
937 * We need to flush the recv. buffs. We do this only on the
938 * descriptor close, not protocol-sourced closes, because the
939 *reader process may not have drained the data yet!
940 */
7c657876 941 while ((skb = __skb_dequeue(&sk->sk_receive_queue)) != NULL) {
d83bd95b 942 data_was_unread += skb->len;
7c657876
ACM
943 __kfree_skb(skb);
944 }
945
d83bd95b
GR
946 if (data_was_unread) {
947 /* Unread data was tossed, send an appropriate Reset Code */
948 DCCP_WARN("DCCP: ABORT -- %u bytes unread\n", data_was_unread);
949 dccp_send_reset(sk, DCCP_RESET_CODE_ABORTED);
950 dccp_set_state(sk, DCCP_CLOSED);
951 } else if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) {
7c657876
ACM
952 /* Check zero linger _after_ checking for unread data. */
953 sk->sk_prot->disconnect(sk, 0);
0c869620
GR
954 } else if (sk->sk_state != DCCP_CLOSED) {
955 dccp_terminate_connection(sk);
7c657876
ACM
956 }
957
958 sk_stream_wait_close(sk, timeout);
959
960adjudge_to_death:
134af346
HX
961 state = sk->sk_state;
962 sock_hold(sk);
963 sock_orphan(sk);
964 atomic_inc(sk->sk_prot->orphan_count);
965
7ad07e7c
ACM
966 /*
967 * It is the last release_sock in its life. It will remove backlog.
968 */
7c657876
ACM
969 release_sock(sk);
970 /*
971 * Now socket is owned by kernel and we acquire BH lock
972 * to finish close. No need to check for user refs.
973 */
974 local_bh_disable();
975 bh_lock_sock(sk);
547b792c 976 WARN_ON(sock_owned_by_user(sk));
7c657876 977
134af346
HX
978 /* Have we already been destroyed by a softirq or backlog? */
979 if (state != DCCP_CLOSED && sk->sk_state == DCCP_CLOSED)
980 goto out;
7ad07e7c 981
7c657876
ACM
982 if (sk->sk_state == DCCP_CLOSED)
983 inet_csk_destroy_sock(sk);
984
985 /* Otherwise, socket is reprieved until protocol close. */
986
134af346 987out:
7c657876
ACM
988 bh_unlock_sock(sk);
989 local_bh_enable();
990 sock_put(sk);
991}
992
f21e68ca
ACM
993EXPORT_SYMBOL_GPL(dccp_close);
994
7c657876
ACM
995void dccp_shutdown(struct sock *sk, int how)
996{
8e8c71f1 997 dccp_pr_debug("called shutdown(%x)\n", how);
7c657876
ACM
998}
999
f21e68ca
ACM
1000EXPORT_SYMBOL_GPL(dccp_shutdown);
1001
24e8b7e4 1002static inline int dccp_mib_init(void)
7c657876 1003{
24e8b7e4 1004 return snmp_mib_init((void**)dccp_statistics, sizeof(struct dccp_mib));
7c657876
ACM
1005}
1006
24e8b7e4 1007static inline void dccp_mib_exit(void)
46f09ffa 1008{
24e8b7e4 1009 snmp_mib_free((void**)dccp_statistics);
46f09ffa
ACM
1010}
1011
7c657876
ACM
1012static int thash_entries;
1013module_param(thash_entries, int, 0444);
1014MODULE_PARM_DESC(thash_entries, "Number of ehash buckets");
1015
a1d3a355 1016#ifdef CONFIG_IP_DCCP_DEBUG
7c657876 1017int dccp_debug;
43264991 1018module_param(dccp_debug, bool, 0644);
7c657876 1019MODULE_PARM_DESC(dccp_debug, "Enable debug messages");
f21e68ca
ACM
1020
1021EXPORT_SYMBOL_GPL(dccp_debug);
a1d3a355 1022#endif
7c657876
ACM
1023
1024static int __init dccp_init(void)
1025{
1026 unsigned long goal;
1027 int ehash_order, bhash_order, i;
b61fafc4 1028 int rc = -ENOBUFS;
7c657876 1029
028b0275
PM
1030 BUILD_BUG_ON(sizeof(struct dccp_skb_cb) >
1031 FIELD_SIZEOF(struct sk_buff, cb));
1032
7690af3f
ACM
1033 dccp_hashinfo.bind_bucket_cachep =
1034 kmem_cache_create("dccp_bind_bucket",
1035 sizeof(struct inet_bind_bucket), 0,
20c2df83 1036 SLAB_HWCACHE_ALIGN, NULL);
7c657876 1037 if (!dccp_hashinfo.bind_bucket_cachep)
b61fafc4 1038 goto out;
7c657876
ACM
1039
1040 /*
1041 * Size and allocate the main established and bind bucket
1042 * hash tables.
1043 *
1044 * The methodology is similar to that of the buffer cache.
1045 */
1046 if (num_physpages >= (128 * 1024))
1047 goal = num_physpages >> (21 - PAGE_SHIFT);
1048 else
1049 goal = num_physpages >> (23 - PAGE_SHIFT);
1050
1051 if (thash_entries)
7690af3f
ACM
1052 goal = (thash_entries *
1053 sizeof(struct inet_ehash_bucket)) >> PAGE_SHIFT;
7c657876
ACM
1054 for (ehash_order = 0; (1UL << ehash_order) < goal; ehash_order++)
1055 ;
1056 do {
1057 dccp_hashinfo.ehash_size = (1UL << ehash_order) * PAGE_SIZE /
1058 sizeof(struct inet_ehash_bucket);
7690af3f
ACM
1059 while (dccp_hashinfo.ehash_size &
1060 (dccp_hashinfo.ehash_size - 1))
7c657876
ACM
1061 dccp_hashinfo.ehash_size--;
1062 dccp_hashinfo.ehash = (struct inet_ehash_bucket *)
1063 __get_free_pages(GFP_ATOMIC, ehash_order);
1064 } while (!dccp_hashinfo.ehash && --ehash_order > 0);
1065
1066 if (!dccp_hashinfo.ehash) {
59348b19 1067 DCCP_CRIT("Failed to allocate DCCP established hash table");
7c657876
ACM
1068 goto out_free_bind_bucket_cachep;
1069 }
1070
dbca9b27 1071 for (i = 0; i < dccp_hashinfo.ehash_size; i++) {
7c657876 1072 INIT_HLIST_HEAD(&dccp_hashinfo.ehash[i].chain);
dbca9b27 1073 INIT_HLIST_HEAD(&dccp_hashinfo.ehash[i].twchain);
7c657876
ACM
1074 }
1075
230140cf
ED
1076 if (inet_ehash_locks_alloc(&dccp_hashinfo))
1077 goto out_free_dccp_ehash;
1078
7c657876
ACM
1079 bhash_order = ehash_order;
1080
1081 do {
1082 dccp_hashinfo.bhash_size = (1UL << bhash_order) * PAGE_SIZE /
1083 sizeof(struct inet_bind_hashbucket);
7690af3f
ACM
1084 if ((dccp_hashinfo.bhash_size > (64 * 1024)) &&
1085 bhash_order > 0)
7c657876
ACM
1086 continue;
1087 dccp_hashinfo.bhash = (struct inet_bind_hashbucket *)
1088 __get_free_pages(GFP_ATOMIC, bhash_order);
1089 } while (!dccp_hashinfo.bhash && --bhash_order >= 0);
1090
1091 if (!dccp_hashinfo.bhash) {
59348b19 1092 DCCP_CRIT("Failed to allocate DCCP bind hash table");
230140cf 1093 goto out_free_dccp_locks;
7c657876
ACM
1094 }
1095
1096 for (i = 0; i < dccp_hashinfo.bhash_size; i++) {
1097 spin_lock_init(&dccp_hashinfo.bhash[i].lock);
1098 INIT_HLIST_HEAD(&dccp_hashinfo.bhash[i].chain);
1099 }
1100
46f09ffa 1101 rc = dccp_mib_init();
fa23e2ec 1102 if (rc)
7c657876
ACM
1103 goto out_free_dccp_bhash;
1104
9b07ef5d 1105 rc = dccp_ackvec_init();
7c657876 1106 if (rc)
b61fafc4 1107 goto out_free_dccp_mib;
9b07ef5d 1108
e55d912f 1109 rc = dccp_sysctl_init();
9b07ef5d
ACM
1110 if (rc)
1111 goto out_ackvec_exit;
4c70f383
GR
1112
1113 dccp_timestamping_init();
7c657876
ACM
1114out:
1115 return rc;
9b07ef5d
ACM
1116out_ackvec_exit:
1117 dccp_ackvec_exit();
b61fafc4 1118out_free_dccp_mib:
46f09ffa 1119 dccp_mib_exit();
7c657876
ACM
1120out_free_dccp_bhash:
1121 free_pages((unsigned long)dccp_hashinfo.bhash, bhash_order);
1122 dccp_hashinfo.bhash = NULL;
230140cf
ED
1123out_free_dccp_locks:
1124 inet_ehash_locks_free(&dccp_hashinfo);
7c657876
ACM
1125out_free_dccp_ehash:
1126 free_pages((unsigned long)dccp_hashinfo.ehash, ehash_order);
1127 dccp_hashinfo.ehash = NULL;
1128out_free_bind_bucket_cachep:
1129 kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep);
1130 dccp_hashinfo.bind_bucket_cachep = NULL;
7c657876
ACM
1131 goto out;
1132}
1133
7c657876
ACM
1134static void __exit dccp_fini(void)
1135{
46f09ffa 1136 dccp_mib_exit();
725ba8ee
ACM
1137 free_pages((unsigned long)dccp_hashinfo.bhash,
1138 get_order(dccp_hashinfo.bhash_size *
1139 sizeof(struct inet_bind_hashbucket)));
1140 free_pages((unsigned long)dccp_hashinfo.ehash,
1141 get_order(dccp_hashinfo.ehash_size *
1142 sizeof(struct inet_ehash_bucket)));
230140cf 1143 inet_ehash_locks_free(&dccp_hashinfo);
7c657876 1144 kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep);
9b07ef5d 1145 dccp_ackvec_exit();
e55d912f 1146 dccp_sysctl_exit();
7c657876
ACM
1147}
1148
1149module_init(dccp_init);
1150module_exit(dccp_fini);
1151
7c657876
ACM
1152MODULE_LICENSE("GPL");
1153MODULE_AUTHOR("Arnaldo Carvalho de Melo <acme@conectiva.com.br>");
1154MODULE_DESCRIPTION("DCCP - Datagram Congestion Controlled Protocol");