Blame view
include/linux/dccp.h
10.7 KB
7c657876b
|
1 2 |
#ifndef _LINUX_DCCP_H #define _LINUX_DCCP_H |
5a47a470e
|
3 4 |
#include <linux/in.h> |
a6b7a4078
|
5 |
#include <linux/interrupt.h> |
19ac21465
|
6 |
#include <linux/ktime.h> |
5a47a470e
|
7 8 9 10 11 |
#include <linux/list.h> #include <linux/uio.h> #include <linux/workqueue.h> #include <net/inet_connection_sock.h> |
14c850212
|
12 |
#include <net/inet_sock.h> |
64cf1e5d8
|
13 |
#include <net/inet_timewait_sock.h> |
5a47a470e
|
14 |
#include <net/tcp_states.h> |
607ca46e9
|
15 |
#include <uapi/linux/dccp.h> |
5a47a470e
|
16 17 |
enum dccp_state { |
f11135a34
|
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
DCCP_OPEN = TCP_ESTABLISHED, DCCP_REQUESTING = TCP_SYN_SENT, DCCP_LISTEN = TCP_LISTEN, DCCP_RESPOND = TCP_SYN_RECV, /* * States involved in closing a DCCP connection: * 1) ACTIVE_CLOSEREQ is entered by a server sending a CloseReq. * * 2) CLOSING can have three different meanings (RFC 4340, 8.3): * a. Client has performed active-close, has sent a Close to the server * from state OPEN or PARTOPEN, and is waiting for the final Reset * (in this case, SOCK_DONE == 1). * b. Client is asked to perform passive-close, by receiving a CloseReq * in (PART)OPEN state. It sends a Close and waits for final Reset * (in this case, SOCK_DONE == 0). * c. Server performs an active-close as in (a), keeps TIMEWAIT state. * * 3) The following intermediate states are employed to give passively * closing nodes a chance to process their unread data: * - PASSIVE_CLOSE (from OPEN => CLOSED) and * - PASSIVE_CLOSEREQ (from (PART)OPEN to CLOSING; case (b) above). */ DCCP_ACTIVE_CLOSEREQ = TCP_FIN_WAIT1, DCCP_PASSIVE_CLOSE = TCP_CLOSE_WAIT, /* any node receiving a Close */ DCCP_CLOSING = TCP_CLOSING, DCCP_TIME_WAIT = TCP_TIME_WAIT, DCCP_CLOSED = TCP_CLOSE, |
85645bab5
|
45 |
DCCP_NEW_SYN_RECV = TCP_NEW_SYN_RECV, |
f11135a34
|
46 47 |
DCCP_PARTOPEN = TCP_MAX_STATES, DCCP_PASSIVE_CLOSEREQ, /* clients receiving CloseReq */ |
9b91ad274
|
48 |
DCCP_MAX_STATES |
5a47a470e
|
49 |
}; |
5a47a470e
|
50 |
enum { |
f11135a34
|
51 52 53 54 55 56 57 58 |
DCCPF_OPEN = TCPF_ESTABLISHED, DCCPF_REQUESTING = TCPF_SYN_SENT, DCCPF_LISTEN = TCPF_LISTEN, DCCPF_RESPOND = TCPF_SYN_RECV, DCCPF_ACTIVE_CLOSEREQ = TCPF_FIN_WAIT1, DCCPF_CLOSING = TCPF_CLOSING, DCCPF_TIME_WAIT = TCPF_TIME_WAIT, DCCPF_CLOSED = TCPF_CLOSE, |
85645bab5
|
59 |
DCCPF_NEW_SYN_RECV = TCPF_NEW_SYN_RECV, |
f11135a34
|
60 |
DCCPF_PARTOPEN = (1 << DCCP_PARTOPEN), |
5a47a470e
|
61 62 63 64 |
}; static inline struct dccp_hdr *dccp_hdr(const struct sk_buff *skb) { |
9c70220b7
|
65 |
return (struct dccp_hdr *)skb_transport_header(skb); |
5a47a470e
|
66 |
} |
9b42078ed
|
67 68 |
static inline struct dccp_hdr *dccp_zeroed_hdr(struct sk_buff *skb, int headlen) { |
badff6d01
|
69 70 |
skb_push(skb, headlen); skb_reset_transport_header(skb); |
9c70220b7
|
71 |
return memset(skb_transport_header(skb), 0, headlen); |
9b42078ed
|
72 |
} |
fde20105f
|
73 |
static inline struct dccp_hdr_ext *dccp_hdrx(const struct dccp_hdr *dh) |
5a47a470e
|
74 |
{ |
fde20105f
|
75 |
return (struct dccp_hdr_ext *)((unsigned char *)dh + sizeof(*dh)); |
5a47a470e
|
76 |
} |
1d3de414e
|
77 78 79 80 |
static inline unsigned int __dccp_basic_hdr_len(const struct dccp_hdr *dh) { return sizeof(*dh) + (dh->dccph_x ? sizeof(struct dccp_hdr_ext) : 0); } |
5a47a470e
|
81 82 83 |
static inline unsigned int dccp_basic_hdr_len(const struct sk_buff *skb) { const struct dccp_hdr *dh = dccp_hdr(skb); |
1d3de414e
|
84 |
return __dccp_basic_hdr_len(dh); |
5a47a470e
|
85 |
} |
fde20105f
|
86 |
static inline __u64 dccp_hdr_seq(const struct dccp_hdr *dh) |
5a47a470e
|
87 |
{ |
60fe62e78
|
88 |
__u64 seq_nr = ntohs(dh->dccph_seq); |
5a47a470e
|
89 90 |
if (dh->dccph_x != 0) |
fde20105f
|
91 |
seq_nr = (seq_nr << 32) + ntohl(dccp_hdrx(dh)->dccph_seq_low); |
60fe62e78
|
92 93 |
else seq_nr += (u32)dh->dccph_seq2 << 16; |
5a47a470e
|
94 95 96 97 98 99 |
return seq_nr; } static inline struct dccp_hdr_request *dccp_hdr_request(struct sk_buff *skb) { |
9c70220b7
|
100 101 |
return (struct dccp_hdr_request *)(skb_transport_header(skb) + dccp_basic_hdr_len(skb)); |
5a47a470e
|
102 103 104 105 |
} static inline struct dccp_hdr_ack_bits *dccp_hdr_ack_bits(const struct sk_buff *skb) { |
9c70220b7
|
106 107 |
return (struct dccp_hdr_ack_bits *)(skb_transport_header(skb) + dccp_basic_hdr_len(skb)); |
5a47a470e
|
108 109 110 111 112 |
} static inline u64 dccp_hdr_ack_seq(const struct sk_buff *skb) { const struct dccp_hdr_ack_bits *dhack = dccp_hdr_ack_bits(skb); |
60fe62e78
|
113 |
return ((u64)ntohs(dhack->dccph_ack_nr_high) << 32) + ntohl(dhack->dccph_ack_nr_low); |
5a47a470e
|
114 115 116 117 |
} static inline struct dccp_hdr_response *dccp_hdr_response(struct sk_buff *skb) { |
9c70220b7
|
118 119 |
return (struct dccp_hdr_response *)(skb_transport_header(skb) + dccp_basic_hdr_len(skb)); |
5a47a470e
|
120 121 122 123 |
} static inline struct dccp_hdr_reset *dccp_hdr_reset(struct sk_buff *skb) { |
9c70220b7
|
124 125 |
return (struct dccp_hdr_reset *)(skb_transport_header(skb) + dccp_basic_hdr_len(skb)); |
5a47a470e
|
126 |
} |
1d3de414e
|
127 128 129 130 131 |
static inline unsigned int __dccp_hdr_len(const struct dccp_hdr *dh) { return __dccp_basic_hdr_len(dh) + dccp_packet_hdr_len(dh->dccph_type); } |
5a47a470e
|
132 133 |
static inline unsigned int dccp_hdr_len(const struct sk_buff *skb) { |
1d3de414e
|
134 |
return __dccp_hdr_len(dccp_hdr(skb)); |
5a47a470e
|
135 |
} |
7c657876b
|
136 |
/** |
b4d4f7c70
|
137 138 |
* struct dccp_request_sock - represent DCCP-specific connection request * @dreq_inet_rsk: structure inherited from |
f541fb7e2
|
139 140 141 142 |
* @dreq_iss: initial sequence number, sent on the first Response (RFC 4340, 7.1) * @dreq_gss: greatest sequence number sent (for retransmitted Responses) * @dreq_isr: initial sequence number received in the first Request * @dreq_gsr: greatest sequence number received (for retransmitted Request(s)) |
b4d4f7c70
|
143 |
* @dreq_service: service code present on the Request (there is just one) |
ac75773c2
|
144 |
* @dreq_featneg: feature negotiation options for this connection |
b4d4f7c70
|
145 146 147 148 |
* The following two fields are analogous to the ones in dccp_sock: * @dreq_timestamp_echo: last received timestamp to echo (13.1) * @dreq_timestamp_echo: the time of receiving the last @dreq_timestamp_echo */ |
7c657876b
|
149 150 151 |
struct dccp_request_sock { struct inet_request_sock dreq_inet_rsk; __u64 dreq_iss; |
f541fb7e2
|
152 |
__u64 dreq_gss; |
7c657876b
|
153 |
__u64 dreq_isr; |
f541fb7e2
|
154 |
__u64 dreq_gsr; |
60fe62e78
|
155 |
__be32 dreq_service; |
ac75773c2
|
156 |
struct list_head dreq_featneg; |
b4d4f7c70
|
157 158 |
__u32 dreq_timestamp_echo; __u32 dreq_timestamp_time; |
7c657876b
|
159 160 161 162 163 164 |
}; static inline struct dccp_request_sock *dccp_rsk(const struct request_sock *req) { return (struct dccp_request_sock *)req; } |
64cf1e5d8
|
165 |
extern struct inet_timewait_death_row dccp_death_row; |
8b8194124
|
166 167 |
extern int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq, struct sk_buff *skb); |
7c657876b
|
168 |
struct dccp_options_received { |
5b5d0e704
|
169 |
u64 dccpor_ndp:48; |
7c657876b
|
170 171 172 173 174 175 176 177 178 179 180 181 182 |
u32 dccpor_timestamp; u32 dccpor_timestamp_echo; u32 dccpor_elapsed_time; }; struct ccid; enum dccp_role { DCCP_ROLE_UNDEFINED, DCCP_ROLE_LISTEN, DCCP_ROLE_CLIENT, DCCP_ROLE_SERVER, }; |
67e6b6292
|
183 184 |
struct dccp_service_list { __u32 dccpsl_nr; |
60fe62e78
|
185 |
__be32 dccpsl_list[0]; |
67e6b6292
|
186 187 188 |
}; #define DCCP_SERVICE_INVALID_VALUE htonl((__u32)-1) |
8109b02b5
|
189 |
#define DCCP_SERVICE_CODE_IS_ABSENT 0 |
67e6b6292
|
190 |
|
0c6119d99
|
191 |
static inline bool dccp_list_has_service(const struct dccp_service_list *sl, |
60fe62e78
|
192 |
const __be32 service) |
67e6b6292
|
193 194 195 196 197 |
{ if (likely(sl != NULL)) { u32 i = sl->dccpsl_nr; while (i--) if (sl->dccpsl_list[i] == service) |
0c6119d99
|
198 |
return true; |
67e6b6292
|
199 |
} |
0c6119d99
|
200 |
return false; |
67e6b6292
|
201 |
} |
ae31c3399
|
202 |
struct dccp_ackvec; |
7c657876b
|
203 204 205 206 207 208 209 210 211 212 213 214 215 |
/** * struct dccp_sock - DCCP socket state * * @dccps_swl - sequence number window low * @dccps_swh - sequence number window high * @dccps_awl - acknowledgement number window low * @dccps_awh - acknowledgement number window high * @dccps_iss - initial sequence number sent * @dccps_isr - initial sequence number received * @dccps_osr - first OPEN sequence number received * @dccps_gss - greatest sequence number sent * @dccps_gsr - greatest valid sequence number received * @dccps_gar - greatest valid ack number received on a non-Sync; initialized to %dccps_iss |
09dbc3895
|
216 217 |
* @dccps_service - first (passive sock) or unique (active sock) service code * @dccps_service_list - second .. last service code on passive socket |
7c657876b
|
218 |
* @dccps_timestamp_echo - latest timestamp received on a TIMESTAMP option |
b4d4f7c70
|
219 |
* @dccps_timestamp_time - time of receiving latest @dccps_timestamp_echo |
91d73c15c
|
220 221 |
* @dccps_l_ack_ratio - feature-local Ack Ratio * @dccps_r_ack_ratio - feature-remote Ack Ratio |
792b48780
|
222 223 |
* @dccps_l_seq_win - local Sequence Window (influences ack number validity) * @dccps_r_seq_win - remote Sequence Window (influences seq number validity) |
6f4e5fff1
|
224 225 |
* @dccps_pcslen - sender partial checksum coverage (via sockopt) * @dccps_pcrlen - receiver partial checksum coverage (via sockopt) |
4098dce5b
|
226 |
* @dccps_send_ndp_count - local Send NDP Count feature (7.7.2) |
7c657876b
|
227 |
* @dccps_ndp_count - number of Non Data Packets since last data packet |
91d73c15c
|
228 |
* @dccps_mss_cache - current value of MSS (path MTU minus header sizes) |
a94f0f970
|
229 |
* @dccps_rate_last - timestamp for rate-limiting DCCP-Sync (RFC 4340, 7.5.4) |
ac75773c2
|
230 |
* @dccps_featneg - tracks feature-negotiation state (mostly during handshake) |
ae31c3399
|
231 |
* @dccps_hc_rx_ackvec - rx half connection ack vector |
91d73c15c
|
232 233 234 |
* @dccps_hc_rx_ccid - CCID used for the receiver (or receiving half-connection) * @dccps_hc_tx_ccid - CCID used for the sender (or sending half-connection) * @dccps_options_received - parsed set of retrieved options |
871a2c16c
|
235 236 |
* @dccps_qpolicy - TX dequeueing policy, one of %dccp_packet_dequeueing_policy * @dccps_tx_qlen - maximum length of the TX queue |
91d73c15c
|
237 238 239 |
* @dccps_role - role of this sock, one of %dccp_role * @dccps_hc_rx_insert_options - receiver wants to add options when acking * @dccps_hc_tx_insert_options - sender wants to add options when sending |
b8599d207
|
240 |
* @dccps_server_timewait - server holds timewait state on close (RFC 4340, 8.3) |
d83447f09
|
241 |
* @dccps_sync_scheduled - flag which signals "send out-of-band message soon" |
dc841e30e
|
242 243 |
* @dccps_xmitlet - tasklet scheduled by the TX CCID to dequeue data packets * @dccps_xmit_timer - used by the TX CCID to delay sending (rate-based pacing) |
89560b53b
|
244 |
* @dccps_syn_rtt - RTT sample from Request/Response exchange (in usecs) |
7c657876b
|
245 246 247 248 |
*/ struct dccp_sock { /* inet_connection_sock has to be the first member of dccp_sock */ struct inet_connection_sock dccps_inet_connection; |
89560b53b
|
249 |
#define dccps_syn_rtt dccps_inet_connection.icsk_ack.lrcvtime |
7c657876b
|
250 251 252 253 254 255 256 257 258 259 |
__u64 dccps_swl; __u64 dccps_swh; __u64 dccps_awl; __u64 dccps_awh; __u64 dccps_iss; __u64 dccps_isr; __u64 dccps_osr; __u64 dccps_gss; __u64 dccps_gsr; __u64 dccps_gar; |
60fe62e78
|
260 |
__be32 dccps_service; |
cf6b5fbe7
|
261 |
__u32 dccps_mss_cache; |
67e6b6292
|
262 |
struct dccp_service_list *dccps_service_list; |
7c657876b
|
263 |
__u32 dccps_timestamp_echo; |
b4d4f7c70
|
264 |
__u32 dccps_timestamp_time; |
2a91aa396
|
265 266 |
__u16 dccps_l_ack_ratio; __u16 dccps_r_ack_ratio; |
792b48780
|
267 268 |
__u64 dccps_l_seq_win:48; __u64 dccps_r_seq_win:48; |
294505598
|
269 270 |
__u8 dccps_pcslen:4; __u8 dccps_pcrlen:4; |
4098dce5b
|
271 |
__u8 dccps_send_ndp_count:1; |
5b5d0e704
|
272 |
__u64 dccps_ndp_count:48; |
a94f0f970
|
273 |
unsigned long dccps_rate_last; |
ac75773c2
|
274 |
struct list_head dccps_featneg; |
ae31c3399
|
275 |
struct dccp_ackvec *dccps_hc_rx_ackvec; |
7c657876b
|
276 277 278 |
struct ccid *dccps_hc_rx_ccid; struct ccid *dccps_hc_tx_ccid; struct dccp_options_received dccps_options_received; |
871a2c16c
|
279 280 |
__u8 dccps_qpolicy; __u32 dccps_tx_qlen; |
7c657876b
|
281 |
enum dccp_role dccps_role:2; |
507d37cf2
|
282 283 |
__u8 dccps_hc_rx_insert_options:1; __u8 dccps_hc_tx_insert_options:1; |
b8599d207
|
284 |
__u8 dccps_server_timewait:1; |
d83447f09
|
285 |
__u8 dccps_sync_scheduled:1; |
dc841e30e
|
286 |
struct tasklet_struct dccps_xmitlet; |
97e5848dd
|
287 |
struct timer_list dccps_xmit_timer; |
7c657876b
|
288 |
}; |
8109b02b5
|
289 |
|
7c657876b
|
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 |
static inline struct dccp_sock *dccp_sk(const struct sock *sk) { return (struct dccp_sock *)sk; } static inline const char *dccp_role(const struct sock *sk) { switch (dccp_sk(sk)->dccps_role) { case DCCP_ROLE_UNDEFINED: return "undefined"; case DCCP_ROLE_LISTEN: return "listen"; case DCCP_ROLE_SERVER: return "server"; case DCCP_ROLE_CLIENT: return "client"; } return NULL; } |
42cb80a23
|
305 |
extern void dccp_syn_ack_timeout(const struct request_sock *req); |
c72e11833
|
306 |
|
7c657876b
|
307 |
#endif /* _LINUX_DCCP_H */ |