packet_history.h revision 276f2edc52e309b38a216245952e05880e182c83
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
51/**
52 *  tfrc_tx_hist_entry  -  Simple singly-linked TX history list
53 *  @next:  next oldest entry (LIFO order)
54 *  @seqno: sequence number of this entry
55 *  @stamp: send time of packet with sequence number @seqno
56 */
57struct tfrc_tx_hist_entry {
58	struct tfrc_tx_hist_entry *next;
59	u64			  seqno;
60	ktime_t			  stamp;
61};
62
63extern int  tfrc_tx_hist_add(struct tfrc_tx_hist_entry **headp, u64 seqno);
64extern void tfrc_tx_hist_purge(struct tfrc_tx_hist_entry **headp);
65
66extern struct tfrc_tx_hist_entry *
67	tfrc_tx_hist_find_entry(struct tfrc_tx_hist_entry *head, u64 ackno);
68
69/*
70 * 	Receiver History data structures and declarations
71 */
72struct dccp_rx_hist_entry {
73	struct list_head dccphrx_node;
74	u64		 dccphrx_seqno:48,
75			 dccphrx_ccval:4,
76			 dccphrx_type:4;
77	u32		 dccphrx_ndp; /* In fact it is from 8 to 24 bits */
78	ktime_t		 dccphrx_tstamp;
79};
80
81struct dccp_rx_hist {
82	struct kmem_cache *dccprxh_slab;
83};
84
85extern struct dccp_rx_hist *dccp_rx_hist_new(const char *name);
86extern void 		dccp_rx_hist_delete(struct dccp_rx_hist *hist);
87
88static inline struct dccp_rx_hist_entry *
89			dccp_rx_hist_entry_new(struct dccp_rx_hist *hist,
90					       const u32 ndp,
91					       const struct sk_buff *skb,
92					       const gfp_t prio)
93{
94	struct dccp_rx_hist_entry *entry = kmem_cache_alloc(hist->dccprxh_slab,
95							    prio);
96
97	if (entry != NULL) {
98		const struct dccp_hdr *dh = dccp_hdr(skb);
99
100		entry->dccphrx_seqno = DCCP_SKB_CB(skb)->dccpd_seq;
101		entry->dccphrx_ccval = dh->dccph_ccval;
102		entry->dccphrx_type  = dh->dccph_type;
103		entry->dccphrx_ndp   = ndp;
104		entry->dccphrx_tstamp = ktime_get_real();
105	}
106
107	return entry;
108}
109
110static inline struct dccp_rx_hist_entry *
111			dccp_rx_hist_head(struct list_head *list)
112{
113	struct dccp_rx_hist_entry *head = NULL;
114
115	if (!list_empty(list))
116		head = list_entry(list->next, struct dccp_rx_hist_entry,
117				  dccphrx_node);
118	return head;
119}
120
121extern int dccp_rx_hist_find_entry(const struct list_head *list, const u64 seq,
122				   u8 *ccval);
123extern struct dccp_rx_hist_entry *
124		dccp_rx_hist_find_data_packet(const struct list_head *list);
125
126extern void dccp_rx_hist_add_packet(struct dccp_rx_hist *hist,
127				    struct list_head *rx_list,
128				    struct list_head *li_list,
129				    struct dccp_rx_hist_entry *packet,
130				    u64 nonloss_seqno);
131
132static inline void dccp_rx_hist_entry_delete(struct dccp_rx_hist *hist,
133					     struct dccp_rx_hist_entry *entry)
134{
135	if (entry != NULL)
136		kmem_cache_free(hist->dccprxh_slab, entry);
137}
138
139extern void dccp_rx_hist_purge(struct dccp_rx_hist *hist,
140			       struct list_head *list);
141
142static inline int
143	dccp_rx_hist_entry_data_packet(const struct dccp_rx_hist_entry *entry)
144{
145	return entry->dccphrx_type == DCCP_PKT_DATA ||
146	       entry->dccphrx_type == DCCP_PKT_DATAACK;
147}
148
149extern u64 dccp_rx_hist_detect_loss(struct list_head *rx_list,
150				    struct list_head *li_list, u8 *win_loss);
151
152#endif /* _DCCP_PKT_HIST_ */
153