Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dccp.h
Go to the documentation of this file.
1 #ifndef _LINUX_DCCP_H
2 #define _LINUX_DCCP_H
3 
4 
5 #include <linux/in.h>
6 #include <linux/interrupt.h>
7 #include <linux/ktime.h>
8 #include <linux/list.h>
9 #include <linux/uio.h>
10 #include <linux/workqueue.h>
11 
13 #include <net/inet_sock.h>
14 #include <net/inet_timewait_sock.h>
15 #include <net/tcp_states.h>
16 #include <uapi/linux/dccp.h>
17 
18 enum dccp_state {
23  /*
24  * States involved in closing a DCCP connection:
25  * 1) ACTIVE_CLOSEREQ is entered by a server sending a CloseReq.
26  *
27  * 2) CLOSING can have three different meanings (RFC 4340, 8.3):
28  * a. Client has performed active-close, has sent a Close to the server
29  * from state OPEN or PARTOPEN, and is waiting for the final Reset
30  * (in this case, SOCK_DONE == 1).
31  * b. Client is asked to perform passive-close, by receiving a CloseReq
32  * in (PART)OPEN state. It sends a Close and waits for final Reset
33  * (in this case, SOCK_DONE == 0).
34  * c. Server performs an active-close as in (a), keeps TIMEWAIT state.
35  *
36  * 3) The following intermediate states are employed to give passively
37  * closing nodes a chance to process their unread data:
38  * - PASSIVE_CLOSE (from OPEN => CLOSED) and
39  * - PASSIVE_CLOSEREQ (from (PART)OPEN to CLOSING; case (b) above).
40  */
42  DCCP_PASSIVE_CLOSE = TCP_CLOSE_WAIT, /* any node receiving a Close */
47  DCCP_PASSIVE_CLOSEREQ, /* clients receiving CloseReq */
49 };
50 
51 enum {
61 };
62 
63 static inline struct dccp_hdr *dccp_hdr(const struct sk_buff *skb)
64 {
65  return (struct dccp_hdr *)skb_transport_header(skb);
66 }
67 
68 static inline struct dccp_hdr *dccp_zeroed_hdr(struct sk_buff *skb, int headlen)
69 {
70  skb_push(skb, headlen);
71  skb_reset_transport_header(skb);
72  return memset(skb_transport_header(skb), 0, headlen);
73 }
74 
75 static inline struct dccp_hdr_ext *dccp_hdrx(const struct dccp_hdr *dh)
76 {
77  return (struct dccp_hdr_ext *)((unsigned char *)dh + sizeof(*dh));
78 }
79 
80 static inline unsigned int __dccp_basic_hdr_len(const struct dccp_hdr *dh)
81 {
82  return sizeof(*dh) + (dh->dccph_x ? sizeof(struct dccp_hdr_ext) : 0);
83 }
84 
85 static inline unsigned int dccp_basic_hdr_len(const struct sk_buff *skb)
86 {
87  const struct dccp_hdr *dh = dccp_hdr(skb);
88  return __dccp_basic_hdr_len(dh);
89 }
90 
91 static inline __u64 dccp_hdr_seq(const struct dccp_hdr *dh)
92 {
93  __u64 seq_nr = ntohs(dh->dccph_seq);
94 
95  if (dh->dccph_x != 0)
96  seq_nr = (seq_nr << 32) + ntohl(dccp_hdrx(dh)->dccph_seq_low);
97  else
98  seq_nr += (u32)dh->dccph_seq2 << 16;
99 
100  return seq_nr;
101 }
102 
103 static inline struct dccp_hdr_request *dccp_hdr_request(struct sk_buff *skb)
104 {
105  return (struct dccp_hdr_request *)(skb_transport_header(skb) +
106  dccp_basic_hdr_len(skb));
107 }
108 
109 static inline struct dccp_hdr_ack_bits *dccp_hdr_ack_bits(const struct sk_buff *skb)
110 {
111  return (struct dccp_hdr_ack_bits *)(skb_transport_header(skb) +
112  dccp_basic_hdr_len(skb));
113 }
114 
115 static inline u64 dccp_hdr_ack_seq(const struct sk_buff *skb)
116 {
117  const struct dccp_hdr_ack_bits *dhack = dccp_hdr_ack_bits(skb);
118  return ((u64)ntohs(dhack->dccph_ack_nr_high) << 32) + ntohl(dhack->dccph_ack_nr_low);
119 }
120 
121 static inline struct dccp_hdr_response *dccp_hdr_response(struct sk_buff *skb)
122 {
123  return (struct dccp_hdr_response *)(skb_transport_header(skb) +
124  dccp_basic_hdr_len(skb));
125 }
126 
127 static inline struct dccp_hdr_reset *dccp_hdr_reset(struct sk_buff *skb)
128 {
129  return (struct dccp_hdr_reset *)(skb_transport_header(skb) +
130  dccp_basic_hdr_len(skb));
131 }
132 
133 static inline unsigned int __dccp_hdr_len(const struct dccp_hdr *dh)
134 {
135  return __dccp_basic_hdr_len(dh) +
136  dccp_packet_hdr_len(dh->dccph_type);
137 }
138 
139 static inline unsigned int dccp_hdr_len(const struct sk_buff *skb)
140 {
141  return __dccp_hdr_len(dccp_hdr(skb));
142 }
143 
167 };
168 
169 static inline struct dccp_request_sock *dccp_rsk(const struct request_sock *req)
170 {
171  return (struct dccp_request_sock *)req;
172 }
173 
175 
176 extern int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq,
177  struct sk_buff *skb);
178 
184 };
185 
186 struct ccid;
187 
188 enum dccp_role {
193 };
194 
198 };
199 
200 #define DCCP_SERVICE_INVALID_VALUE htonl((__u32)-1)
201 #define DCCP_SERVICE_CODE_IS_ABSENT 0
202 
203 static inline int dccp_list_has_service(const struct dccp_service_list *sl,
204  const __be32 service)
205 {
206  if (likely(sl != NULL)) {
207  u32 i = sl->dccpsl_nr;
208  while (i--)
209  if (sl->dccpsl_list[i] == service)
210  return 1;
211  }
212  return 0;
213 }
214 
215 struct dccp_ackvec;
216 
260 struct dccp_sock {
261  /* inet_connection_sock has to be the first member of dccp_sock */
263 #define dccps_syn_rtt dccps_inet_connection.icsk_ack.lrcvtime
287  unsigned long dccps_rate_last;
295  enum dccp_role dccps_role:2;
302 };
303 
304 static inline struct dccp_sock *dccp_sk(const struct sock *sk)
305 {
306  return (struct dccp_sock *)sk;
307 }
308 
309 static inline const char *dccp_role(const struct sock *sk)
310 {
311  switch (dccp_sk(sk)->dccps_role) {
312  case DCCP_ROLE_UNDEFINED: return "undefined";
313  case DCCP_ROLE_LISTEN: return "listen";
314  case DCCP_ROLE_SERVER: return "server";
315  case DCCP_ROLE_CLIENT: return "client";
316  }
317  return NULL;
318 }
319 
320 extern void dccp_syn_ack_timeout(struct sock *sk, struct request_sock *req);
321 
322 #endif /* _LINUX_DCCP_H */