dccp.h revision 34ca6860810342441f801226b19ae6c9e0ecb34f
1#ifndef _DCCP_H
2#define _DCCP_H
3/*
4 *  net/dccp/dccp.h
5 *
6 *  An implementation of the DCCP protocol
7 *  Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
8 *  Copyright (c) 2005 Ian McDonald <iam4@cs.waikato.ac.nz>
9 *
10 *	This program is free software; you can redistribute it and/or modify it
11 *	under the terms of the GNU General Public License version 2 as
12 *	published by the Free Software Foundation.
13 */
14
15#include <linux/config.h>
16#include <linux/dccp.h>
17#include <net/snmp.h>
18#include <net/sock.h>
19#include <net/tcp.h>
20#include "ackvec.h"
21
22#ifdef CONFIG_IP_DCCP_DEBUG
23extern int dccp_debug;
24
25#define dccp_pr_debug(format, a...) \
26	do { if (dccp_debug) \
27		printk(KERN_DEBUG "%s: " format, __FUNCTION__ , ##a); \
28	} while (0)
29#define dccp_pr_debug_cat(format, a...) do { if (dccp_debug) \
30					     printk(format, ##a); } while (0)
31#else
32#define dccp_pr_debug(format, a...)
33#define dccp_pr_debug_cat(format, a...)
34#endif
35
36extern struct inet_hashinfo dccp_hashinfo;
37
38extern atomic_t dccp_orphan_count;
39extern int dccp_tw_count;
40extern void dccp_tw_deschedule(struct inet_timewait_sock *tw);
41
42extern void dccp_time_wait(struct sock *sk, int state, int timeo);
43
44/* FIXME: Right size this */
45#define DCCP_MAX_OPT_LEN 128
46
47#define DCCP_MAX_PACKET_HDR 32
48
49#define MAX_DCCP_HEADER  (DCCP_MAX_PACKET_HDR + DCCP_MAX_OPT_LEN + MAX_HEADER)
50
51#define DCCP_TIMEWAIT_LEN (60 * HZ) /* how long to wait to destroy TIME-WAIT
52				     * state, about 60 seconds */
53
54/* draft-ietf-dccp-spec-11.txt initial RTO value */
55#define DCCP_TIMEOUT_INIT ((unsigned)(3 * HZ))
56
57/* Maximal interval between probes for local resources.  */
58#define DCCP_RESOURCE_PROBE_INTERVAL ((unsigned)(HZ / 2U))
59
60#define DCCP_RTO_MAX ((unsigned)(120 * HZ)) /* FIXME: using TCP value */
61
62extern struct proto dccp_prot;
63
64/* is seq1 < seq2 ? */
65static inline int before48(const u64 seq1, const u64 seq2)
66{
67	return (s64)((seq1 << 16) - (seq2 << 16)) < 0;
68}
69
70/* is seq1 > seq2 ? */
71static inline int after48(const u64 seq1, const u64 seq2)
72{
73	return (s64)((seq2 << 16) - (seq1 << 16)) < 0;
74}
75
76/* is seq2 <= seq1 <= seq3 ? */
77static inline int between48(const u64 seq1, const u64 seq2, const u64 seq3)
78{
79	return (seq3 << 16) - (seq2 << 16) >= (seq1 << 16) - (seq2 << 16);
80}
81
82static inline u64 max48(const u64 seq1, const u64 seq2)
83{
84	return after48(seq1, seq2) ? seq1 : seq2;
85}
86
87enum {
88	DCCP_MIB_NUM = 0,
89	DCCP_MIB_ACTIVEOPENS,			/* ActiveOpens */
90	DCCP_MIB_ESTABRESETS,			/* EstabResets */
91	DCCP_MIB_CURRESTAB,			/* CurrEstab */
92	DCCP_MIB_OUTSEGS,			/* OutSegs */
93	DCCP_MIB_OUTRSTS,
94	DCCP_MIB_ABORTONTIMEOUT,
95	DCCP_MIB_TIMEOUTS,
96	DCCP_MIB_ABORTFAILED,
97	DCCP_MIB_PASSIVEOPENS,
98	DCCP_MIB_ATTEMPTFAILS,
99	DCCP_MIB_OUTDATAGRAMS,
100	DCCP_MIB_INERRS,
101	DCCP_MIB_OPTMANDATORYERROR,
102	DCCP_MIB_INVALIDOPT,
103	__DCCP_MIB_MAX
104};
105
106#define DCCP_MIB_MAX	__DCCP_MIB_MAX
107struct dccp_mib {
108	unsigned long	mibs[DCCP_MIB_MAX];
109} __SNMP_MIB_ALIGN__;
110
111DECLARE_SNMP_STAT(struct dccp_mib, dccp_statistics);
112#define DCCP_INC_STATS(field)	    SNMP_INC_STATS(dccp_statistics, field)
113#define DCCP_INC_STATS_BH(field)    SNMP_INC_STATS_BH(dccp_statistics, field)
114#define DCCP_INC_STATS_USER(field)  SNMP_INC_STATS_USER(dccp_statistics, field)
115#define DCCP_DEC_STATS(field)	    SNMP_DEC_STATS(dccp_statistics, field)
116#define DCCP_ADD_STATS_BH(field, val) \
117			SNMP_ADD_STATS_BH(dccp_statistics, field, val)
118#define DCCP_ADD_STATS_USER(field, val)	\
119			SNMP_ADD_STATS_USER(dccp_statistics, field, val)
120
121extern int  dccp_retransmit_skb(struct sock *sk, struct sk_buff *skb);
122
123extern int dccp_send_response(struct sock *sk);
124extern void dccp_send_ack(struct sock *sk);
125extern void dccp_send_delayed_ack(struct sock *sk);
126extern void dccp_send_sync(struct sock *sk, const u64 seq,
127			   const enum dccp_pkt_type pkt_type);
128
129extern int dccp_write_xmit(struct sock *sk, struct sk_buff *skb, long *timeo);
130extern void dccp_write_space(struct sock *sk);
131
132extern void dccp_init_xmit_timers(struct sock *sk);
133static inline void dccp_clear_xmit_timers(struct sock *sk)
134{
135	inet_csk_clear_xmit_timers(sk);
136}
137
138extern unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu);
139
140extern const char *dccp_packet_name(const int type);
141extern const char *dccp_state_name(const int state);
142
143static inline void dccp_set_state(struct sock *sk, const int state)
144{
145	const int oldstate = sk->sk_state;
146
147	dccp_pr_debug("%s(%p) %-10.10s -> %s\n",
148		      dccp_role(sk), sk,
149		      dccp_state_name(oldstate), dccp_state_name(state));
150	WARN_ON(state == oldstate);
151
152	switch (state) {
153	case DCCP_OPEN:
154		if (oldstate != DCCP_OPEN)
155			DCCP_INC_STATS(DCCP_MIB_CURRESTAB);
156		break;
157
158	case DCCP_CLOSED:
159		if (oldstate == DCCP_CLOSING || oldstate == DCCP_OPEN)
160			DCCP_INC_STATS(DCCP_MIB_ESTABRESETS);
161
162		sk->sk_prot->unhash(sk);
163		if (inet_csk(sk)->icsk_bind_hash != NULL &&
164		    !(sk->sk_userlocks & SOCK_BINDPORT_LOCK))
165			inet_put_port(&dccp_hashinfo, sk);
166		/* fall through */
167	default:
168		if (oldstate == DCCP_OPEN)
169			DCCP_DEC_STATS(DCCP_MIB_CURRESTAB);
170	}
171
172	/* Change state AFTER socket is unhashed to avoid closed
173	 * socket sitting in hash tables.
174	 */
175	sk->sk_state = state;
176}
177
178static inline void dccp_done(struct sock *sk)
179{
180	dccp_set_state(sk, DCCP_CLOSED);
181	dccp_clear_xmit_timers(sk);
182
183	sk->sk_shutdown = SHUTDOWN_MASK;
184
185	if (!sock_flag(sk, SOCK_DEAD))
186		sk->sk_state_change(sk);
187	else
188		inet_csk_destroy_sock(sk);
189}
190
191static inline void dccp_openreq_init(struct request_sock *req,
192				     struct dccp_sock *dp,
193				     struct sk_buff *skb)
194{
195	/*
196	 * FIXME: fill in the other req fields from the DCCP options
197	 * received
198	 */
199	inet_rsk(req)->rmt_port = dccp_hdr(skb)->dccph_sport;
200	inet_rsk(req)->acked	= 0;
201	req->rcv_wnd = 0;
202}
203
204extern int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb);
205
206extern struct sock *dccp_create_openreq_child(struct sock *sk,
207					      const struct request_sock *req,
208					      const struct sk_buff *skb);
209
210extern int dccp_v4_do_rcv(struct sock *sk, struct sk_buff *skb);
211
212extern void dccp_v4_err(struct sk_buff *skb, u32);
213
214extern int dccp_v4_rcv(struct sk_buff *skb);
215
216extern struct sock *dccp_v4_request_recv_sock(struct sock *sk,
217					      struct sk_buff *skb,
218					      struct request_sock *req,
219					      struct dst_entry *dst);
220extern struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb,
221				   struct request_sock *req,
222				   struct request_sock **prev);
223
224extern int dccp_child_process(struct sock *parent, struct sock *child,
225			      struct sk_buff *skb);
226extern int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
227				  struct dccp_hdr *dh, unsigned len);
228extern int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
229				const struct dccp_hdr *dh, const unsigned len);
230
231extern void		dccp_close(struct sock *sk, long timeout);
232extern struct sk_buff	*dccp_make_response(struct sock *sk,
233					    struct dst_entry *dst,
234					    struct request_sock *req);
235extern struct sk_buff	*dccp_make_reset(struct sock *sk,
236					 struct dst_entry *dst,
237					 enum dccp_reset_codes code);
238
239extern int	   dccp_connect(struct sock *sk);
240extern int	   dccp_disconnect(struct sock *sk, int flags);
241extern int	   dccp_getsockopt(struct sock *sk, int level, int optname,
242				   char __user *optval, int __user *optlen);
243extern int	   dccp_setsockopt(struct sock *sk, int level, int optname,
244				   char __user *optval, int optlen);
245extern int	   dccp_ioctl(struct sock *sk, int cmd, unsigned long arg);
246extern int	   dccp_sendmsg(struct kiocb *iocb, struct sock *sk,
247				struct msghdr *msg, size_t size);
248extern int	   dccp_recvmsg(struct kiocb *iocb, struct sock *sk,
249				struct msghdr *msg, size_t len, int nonblock,
250				int flags, int *addr_len);
251extern void	   dccp_shutdown(struct sock *sk, int how);
252
253extern int	   dccp_v4_checksum(const struct sk_buff *skb,
254				    const u32 saddr, const u32 daddr);
255
256extern int	   dccp_v4_send_reset(struct sock *sk,
257				      enum dccp_reset_codes code);
258extern void	   dccp_send_close(struct sock *sk, const int active);
259
260struct dccp_skb_cb {
261	__u8  dccpd_type:4;
262	__u8  dccpd_ccval:4;
263	__u8  dccpd_reset_code;
264	__u16 dccpd_opt_len;
265	__u64 dccpd_seq;
266	__u64 dccpd_ack_seq;
267};
268
269#define DCCP_SKB_CB(__skb) ((struct dccp_skb_cb *)&((__skb)->cb[0]))
270
271static inline int dccp_non_data_packet(const struct sk_buff *skb)
272{
273	const __u8 type = DCCP_SKB_CB(skb)->dccpd_type;
274
275	return type == DCCP_PKT_ACK	 ||
276	       type == DCCP_PKT_CLOSE	 ||
277	       type == DCCP_PKT_CLOSEREQ ||
278	       type == DCCP_PKT_RESET	 ||
279	       type == DCCP_PKT_SYNC	 ||
280	       type == DCCP_PKT_SYNCACK;
281}
282
283static inline int dccp_packet_without_ack(const struct sk_buff *skb)
284{
285	const __u8 type = DCCP_SKB_CB(skb)->dccpd_type;
286
287	return type == DCCP_PKT_DATA || type == DCCP_PKT_REQUEST;
288}
289
290#define DCCP_MAX_SEQNO ((((u64)1) << 48) - 1)
291#define DCCP_PKT_WITHOUT_ACK_SEQ (DCCP_MAX_SEQNO << 2)
292
293static inline void dccp_set_seqno(u64 *seqno, u64 value)
294{
295	if (value > DCCP_MAX_SEQNO)
296		value -= DCCP_MAX_SEQNO + 1;
297	*seqno = value;
298}
299
300static inline u64 dccp_delta_seqno(u64 seqno1, u64 seqno2)
301{
302	return ((seqno2 << 16) - (seqno1 << 16)) >> 16;
303}
304
305static inline void dccp_inc_seqno(u64 *seqno)
306{
307	if (++*seqno > DCCP_MAX_SEQNO)
308		*seqno = 0;
309}
310
311static inline void dccp_hdr_set_seq(struct dccp_hdr *dh, const u64 gss)
312{
313	struct dccp_hdr_ext *dhx = (struct dccp_hdr_ext *)((void *)dh +
314							   sizeof(*dh));
315
316#if defined(__LITTLE_ENDIAN_BITFIELD)
317	dh->dccph_seq	   = htonl((gss >> 32)) >> 8;
318#elif defined(__BIG_ENDIAN_BITFIELD)
319	dh->dccph_seq	   = htonl((gss >> 32));
320#else
321#error  "Adjust your <asm/byteorder.h> defines"
322#endif
323	dhx->dccph_seq_low = htonl(gss & 0xffffffff);
324}
325
326static inline void dccp_hdr_set_ack(struct dccp_hdr_ack_bits *dhack,
327				    const u64 gsr)
328{
329#if defined(__LITTLE_ENDIAN_BITFIELD)
330	dhack->dccph_ack_nr_high = htonl((gsr >> 32)) >> 8;
331#elif defined(__BIG_ENDIAN_BITFIELD)
332	dhack->dccph_ack_nr_high = htonl((gsr >> 32));
333#else
334#error  "Adjust your <asm/byteorder.h> defines"
335#endif
336	dhack->dccph_ack_nr_low  = htonl(gsr & 0xffffffff);
337}
338
339static inline void dccp_update_gsr(struct sock *sk, u64 seq)
340{
341	struct dccp_sock *dp = dccp_sk(sk);
342
343	dp->dccps_gsr = seq;
344	dccp_set_seqno(&dp->dccps_swl,
345		       (dp->dccps_gsr + 1 -
346		        (dp->dccps_options.dccpo_sequence_window / 4)));
347	dccp_set_seqno(&dp->dccps_swh,
348		       (dp->dccps_gsr +
349			(3 * dp->dccps_options.dccpo_sequence_window) / 4));
350}
351
352static inline void dccp_update_gss(struct sock *sk, u64 seq)
353{
354	struct dccp_sock *dp = dccp_sk(sk);
355
356	dp->dccps_awh = dp->dccps_gss = seq;
357	dccp_set_seqno(&dp->dccps_awl,
358		       (dp->dccps_gss -
359			dp->dccps_options.dccpo_sequence_window + 1));
360}
361
362static inline int dccp_ack_pending(const struct sock *sk)
363{
364	const struct dccp_sock *dp = dccp_sk(sk);
365	return dp->dccps_timestamp_echo != 0 ||
366#ifdef CONFIG_IP_DCCP_ACKVEC
367	       (dp->dccps_options.dccpo_send_ack_vector &&
368		dccp_ackvec_pending(dp->dccps_hc_rx_ackvec)) ||
369#endif
370	       inet_csk_ack_scheduled(sk);
371}
372
373extern void dccp_insert_options(struct sock *sk, struct sk_buff *skb);
374extern void dccp_insert_option_elapsed_time(struct sock *sk,
375					    struct sk_buff *skb,
376					    u32 elapsed_time);
377extern void dccp_insert_option_timestamp(struct sock *sk,
378					 struct sk_buff *skb);
379extern void dccp_insert_option(struct sock *sk, struct sk_buff *skb,
380			       unsigned char option,
381			       const void *value, unsigned char len);
382
383extern struct socket *dccp_ctl_socket;
384
385extern void dccp_timestamp(const struct sock *sk, struct timeval *tv);
386
387static inline suseconds_t timeval_usecs(const struct timeval *tv)
388{
389	return tv->tv_sec * USEC_PER_SEC + tv->tv_usec;
390}
391
392static inline suseconds_t timeval_delta(const struct timeval *large,
393					const struct timeval *small)
394{
395	time_t	    secs  = large->tv_sec  - small->tv_sec;
396	suseconds_t usecs = large->tv_usec - small->tv_usec;
397
398	if (usecs < 0) {
399		secs--;
400		usecs += USEC_PER_SEC;
401	}
402	return secs * USEC_PER_SEC + usecs;
403}
404
405static inline void timeval_add_usecs(struct timeval *tv,
406				     const suseconds_t usecs)
407{
408	tv->tv_usec += usecs;
409	while (tv->tv_usec >= USEC_PER_SEC) {
410		tv->tv_sec++;
411		tv->tv_usec -= USEC_PER_SEC;
412	}
413}
414
415static inline void timeval_sub_usecs(struct timeval *tv,
416				     const suseconds_t usecs)
417{
418	tv->tv_usec -= usecs;
419	while (tv->tv_usec < 0) {
420		tv->tv_sec--;
421		tv->tv_usec += USEC_PER_SEC;
422	}
423}
424
425#endif /* _DCCP_H */
426