packet_history.h revision 9108d5f4b2cd82f55ad178caa0be66a866a06dcc
1/*
2 *  Packet RX/TX history data structures and routines for TFRC-based protocols.
3 *
4 *  Copyright (c) 2007   The University of Aberdeen, Scotland, UK
5 *  Copyright (c) 2005-6 The University of Waikato, Hamilton, New Zealand.
6 *
7 *  This code has been developed by the University of Waikato WAND
8 *  research group. For further information please see http://www.wand.net.nz/
9 *  or e-mail Ian McDonald - ian.mcdonald@jandi.co.nz
10 *
11 *  This code also uses code from Lulea University, rereleased as GPL by its
12 *  authors:
13 *  Copyright (c) 2003 Nils-Erik Mattsson, Joacim Haggmark, Magnus Erixzon
14 *
15 *  Changes to meet Linux coding standards, to make it meet latest ccid3 draft
16 *  and to make it work as a loadable module in the DCCP stack written by
17 *  Arnaldo Carvalho de Melo <acme@conectiva.com.br>.
18 *
19 *  Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
20 *
21 *  This program is free software; you can redistribute it and/or modify
22 *  it under the terms of the GNU General Public License as published by
23 *  the Free Software Foundation; either version 2 of the License, or
24 *  (at your option) any later version.
25 *
26 *  This program is distributed in the hope that it will be useful,
27 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
28 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29 *  GNU General Public License for more details.
30 *
31 *  You should have received a copy of the GNU General Public License
32 *  along with this program; if not, write to the Free Software
33 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
34 */
35
36#ifndef _DCCP_PKT_HIST_
37#define _DCCP_PKT_HIST_
38
39#include <linux/ktime.h>
40#include <linux/list.h>
41#include <linux/slab.h>
42
43#include "../../dccp.h"
44
45/* Number of later packets received before one is considered lost */
46#define TFRC_RECV_NUM_LATE_LOSS	 3
47
48#define TFRC_WIN_COUNT_PER_RTT	 4
49#define TFRC_WIN_COUNT_LIMIT	16
50
51struct tfrc_tx_hist_entry;
52
53extern int  tfrc_tx_hist_add(struct tfrc_tx_hist_entry **headp, u64 seqno);
54extern void tfrc_tx_hist_purge(struct tfrc_tx_hist_entry **headp);
55extern u32  tfrc_tx_hist_rtt(struct tfrc_tx_hist_entry *head,
56			     const u64 seqno, const ktime_t now);
57
58/*
59 * 	Receiver History data structures and declarations
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	ktime_t		 dccphrx_tstamp;
68};
69
70struct dccp_rx_hist {
71	struct kmem_cache *dccprxh_slab;
72};
73
74extern struct dccp_rx_hist *dccp_rx_hist_new(const char *name);
75extern void 		dccp_rx_hist_delete(struct dccp_rx_hist *hist);
76
77static inline struct dccp_rx_hist_entry *
78			dccp_rx_hist_entry_new(struct dccp_rx_hist *hist,
79					       const u32 ndp,
80					       const struct sk_buff *skb,
81					       const gfp_t prio)
82{
83	struct dccp_rx_hist_entry *entry = kmem_cache_alloc(hist->dccprxh_slab,
84							    prio);
85
86	if (entry != NULL) {
87		const struct dccp_hdr *dh = dccp_hdr(skb);
88
89		entry->dccphrx_seqno = DCCP_SKB_CB(skb)->dccpd_seq;
90		entry->dccphrx_ccval = dh->dccph_ccval;
91		entry->dccphrx_type  = dh->dccph_type;
92		entry->dccphrx_ndp   = ndp;
93		entry->dccphrx_tstamp = ktime_get_real();
94	}
95
96	return entry;
97}
98
99static inline struct dccp_rx_hist_entry *
100			dccp_rx_hist_head(struct list_head *list)
101{
102	struct dccp_rx_hist_entry *head = NULL;
103
104	if (!list_empty(list))
105		head = list_entry(list->next, struct dccp_rx_hist_entry,
106				  dccphrx_node);
107	return head;
108}
109
110extern int dccp_rx_hist_find_entry(const struct list_head *list, const u64 seq,
111				   u8 *ccval);
112extern struct dccp_rx_hist_entry *
113		dccp_rx_hist_find_data_packet(const struct list_head *list);
114
115extern void dccp_rx_hist_add_packet(struct dccp_rx_hist *hist,
116				    struct list_head *rx_list,
117				    struct list_head *li_list,
118				    struct dccp_rx_hist_entry *packet,
119				    u64 nonloss_seqno);
120
121static inline void dccp_rx_hist_entry_delete(struct dccp_rx_hist *hist,
122					     struct dccp_rx_hist_entry *entry)
123{
124	if (entry != NULL)
125		kmem_cache_free(hist->dccprxh_slab, entry);
126}
127
128extern void dccp_rx_hist_purge(struct dccp_rx_hist *hist,
129			       struct list_head *list);
130
131static inline int
132	dccp_rx_hist_entry_data_packet(const struct dccp_rx_hist_entry *entry)
133{
134	return entry->dccphrx_type == DCCP_PKT_DATA ||
135	       entry->dccphrx_type == DCCP_PKT_DATAACK;
136}
137
138extern u64 dccp_rx_hist_detect_loss(struct list_head *rx_list,
139				    struct list_head *li_list, u8 *win_loss);
140
141#endif /* _DCCP_PKT_HIST_ */
142