packet_history.h revision 80193aee18bc862e284ba18504f3a3e14706a997
1/*
2 *  net/dccp/packet_history.h
3 *
4 *  Copyright (c) 2005-6 The University of Waikato, Hamilton, New Zealand.
5 *
6 *  An implementation of the DCCP protocol
7 *
8 *  This code has been developed by the University of Waikato WAND
9 *  research group. For further information please see http://www.wand.net.nz/
10 *  or e-mail Ian McDonald - ian.mcdonald@jandi.co.nz
11 *
12 *  This code also uses code from Lulea University, rereleased as GPL by its
13 *  authors:
14 *  Copyright (c) 2003 Nils-Erik Mattsson, Joacim Haggmark, Magnus Erixzon
15 *
16 *  Changes to meet Linux coding standards, to make it meet latest ccid3 draft
17 *  and to make it work as a loadable module in the DCCP stack written by
18 *  Arnaldo Carvalho de Melo <acme@conectiva.com.br>.
19 *
20 *  Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
21 *
22 *  This program is free software; you can redistribute it and/or modify
23 *  it under the terms of the GNU General Public License as published by
24 *  the Free Software Foundation; either version 2 of the License, or
25 *  (at your option) any later version.
26 *
27 *  This program is distributed in the hope that it will be useful,
28 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
29 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
30 *  GNU General Public License for more details.
31 *
32 *  You should have received a copy of the GNU General Public License
33 *  along with this program; if not, write to the Free Software
34 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
35 */
36
37#ifndef _DCCP_PKT_HIST_
38#define _DCCP_PKT_HIST_
39
40#include <linux/list.h>
41#include <linux/slab.h>
42#include <linux/time.h>
43
44#include "../../dccp.h"
45
46/* Number of later packets received before one is considered lost */
47#define TFRC_RECV_NUM_LATE_LOSS	 3
48
49#define TFRC_WIN_COUNT_PER_RTT	 4
50#define TFRC_WIN_COUNT_LIMIT	16
51
52struct dccp_tx_hist_entry {
53	struct list_head dccphtx_node;
54	u64		 dccphtx_seqno:48,
55			 dccphtx_ccval:4,
56			 dccphtx_sent:1;
57	u32		 dccphtx_rtt;
58	struct timeval	 dccphtx_tstamp;
59};
60
61struct dccp_rx_hist_entry {
62	struct list_head dccphrx_node;
63	u64		 dccphrx_seqno:48,
64			 dccphrx_ccval:4,
65			 dccphrx_type:4;
66	u32		 dccphrx_ndp; /* In fact it is from 8 to 24 bits */
67	struct timeval	 dccphrx_tstamp;
68};
69
70struct dccp_tx_hist {
71	kmem_cache_t *dccptxh_slab;
72};
73
74extern struct dccp_tx_hist *dccp_tx_hist_new(const char *name);
75extern void dccp_tx_hist_delete(struct dccp_tx_hist *hist);
76
77struct dccp_rx_hist {
78	kmem_cache_t *dccprxh_slab;
79};
80
81extern struct dccp_rx_hist *dccp_rx_hist_new(const char *name);
82extern void dccp_rx_hist_delete(struct dccp_rx_hist *hist);
83extern struct dccp_rx_hist_entry *
84		dccp_rx_hist_find_data_packet(const struct list_head *list);
85
86static inline struct dccp_tx_hist_entry *
87		dccp_tx_hist_entry_new(struct dccp_tx_hist *hist,
88				       const gfp_t prio)
89{
90	struct dccp_tx_hist_entry *entry = kmem_cache_alloc(hist->dccptxh_slab,
91							    prio);
92
93	if (entry != NULL)
94		entry->dccphtx_sent = 0;
95
96	return entry;
97}
98
99static inline void dccp_tx_hist_entry_delete(struct dccp_tx_hist *hist,
100					     struct dccp_tx_hist_entry *entry)
101{
102	if (entry != NULL)
103		kmem_cache_free(hist->dccptxh_slab, entry);
104}
105
106extern struct dccp_tx_hist_entry *
107			dccp_tx_hist_find_entry(const struct list_head *list,
108						const u64 seq);
109extern int dccp_rx_hist_find_entry(const struct list_head *list, const u64 seq,
110   u8 *ccval);
111
112static inline void dccp_tx_hist_add_entry(struct list_head *list,
113					  struct dccp_tx_hist_entry *entry)
114{
115	list_add(&entry->dccphtx_node, list);
116}
117
118extern void dccp_tx_hist_purge_older(struct dccp_tx_hist *hist,
119				     struct list_head *list,
120				     struct dccp_tx_hist_entry *next);
121
122extern void dccp_tx_hist_purge(struct dccp_tx_hist *hist,
123			       struct list_head *list);
124
125static inline struct dccp_tx_hist_entry *
126		dccp_tx_hist_head(struct list_head *list)
127{
128	struct dccp_tx_hist_entry *head = NULL;
129
130	if (!list_empty(list))
131		head = list_entry(list->next, struct dccp_tx_hist_entry,
132				  dccphtx_node);
133	return head;
134}
135
136static inline struct dccp_rx_hist_entry *
137		     dccp_rx_hist_entry_new(struct dccp_rx_hist *hist,
138				     	    const struct sock *sk,
139				     	    const u32 ndp,
140					    const struct sk_buff *skb,
141					    const gfp_t prio)
142{
143	struct dccp_rx_hist_entry *entry = kmem_cache_alloc(hist->dccprxh_slab,
144							    prio);
145
146	if (entry != NULL) {
147		const struct dccp_hdr *dh = dccp_hdr(skb);
148
149		entry->dccphrx_seqno = DCCP_SKB_CB(skb)->dccpd_seq;
150		entry->dccphrx_ccval = dh->dccph_ccval;
151		entry->dccphrx_type  = dh->dccph_type;
152		entry->dccphrx_ndp   = ndp;
153		dccp_timestamp(sk, &entry->dccphrx_tstamp);
154	}
155
156	return entry;
157}
158
159static inline void dccp_rx_hist_entry_delete(struct dccp_rx_hist *hist,
160					     struct dccp_rx_hist_entry *entry)
161{
162	if (entry != NULL)
163		kmem_cache_free(hist->dccprxh_slab, entry);
164}
165
166extern void dccp_rx_hist_purge(struct dccp_rx_hist *hist,
167			       struct list_head *list);
168
169static inline void dccp_rx_hist_add_entry(struct list_head *list,
170					  struct dccp_rx_hist_entry *entry)
171{
172	list_add(&entry->dccphrx_node, list);
173}
174
175static inline struct dccp_rx_hist_entry *
176		dccp_rx_hist_head(struct list_head *list)
177{
178	struct dccp_rx_hist_entry *head = NULL;
179
180	if (!list_empty(list))
181		head = list_entry(list->next, struct dccp_rx_hist_entry,
182				  dccphrx_node);
183	return head;
184}
185
186static inline int
187	dccp_rx_hist_entry_data_packet(const struct dccp_rx_hist_entry *entry)
188{
189	return entry->dccphrx_type == DCCP_PKT_DATA ||
190	       entry->dccphrx_type == DCCP_PKT_DATAACK;
191}
192
193extern int dccp_rx_hist_add_packet(struct dccp_rx_hist *hist,
194				   struct list_head *rx_list,
195				   struct list_head *li_list,
196				   struct dccp_rx_hist_entry *packet);
197
198extern u64 dccp_rx_hist_detect_loss(struct list_head *rx_list,
199				    struct list_head *li_list, u8 *win_loss);
200
201#endif /* _DCCP_PKT_HIST_ */
202