packet_history.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  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. #ifndef _DCCP_PKT_HIST_
  37. #define _DCCP_PKT_HIST_
  38. #include <linux/ktime.h>
  39. #include <linux/list.h>
  40. #include <linux/slab.h>
  41. #include "../../dccp.h"
  42. /* Number of later packets received before one is considered lost */
  43. #define TFRC_RECV_NUM_LATE_LOSS 3
  44. #define TFRC_WIN_COUNT_PER_RTT 4
  45. #define TFRC_WIN_COUNT_LIMIT 16
  46. /*
  47. * Transmitter History data structures and declarations
  48. */
  49. struct dccp_tx_hist_entry {
  50. struct list_head dccphtx_node;
  51. u64 dccphtx_seqno:48,
  52. dccphtx_sent:1;
  53. u32 dccphtx_rtt;
  54. ktime_t dccphtx_tstamp;
  55. };
  56. struct dccp_tx_hist {
  57. struct kmem_cache *dccptxh_slab;
  58. };
  59. extern struct dccp_tx_hist *dccp_tx_hist_new(const char *name);
  60. extern void dccp_tx_hist_delete(struct dccp_tx_hist *hist);
  61. static inline struct dccp_tx_hist_entry *
  62. dccp_tx_hist_entry_new(struct dccp_tx_hist *hist,
  63. const gfp_t prio)
  64. {
  65. struct dccp_tx_hist_entry *entry = kmem_cache_alloc(hist->dccptxh_slab,
  66. prio);
  67. if (entry != NULL)
  68. entry->dccphtx_sent = 0;
  69. return entry;
  70. }
  71. static inline struct dccp_tx_hist_entry *
  72. dccp_tx_hist_head(struct list_head *list)
  73. {
  74. struct dccp_tx_hist_entry *head = NULL;
  75. if (!list_empty(list))
  76. head = list_entry(list->next, struct dccp_tx_hist_entry,
  77. dccphtx_node);
  78. return head;
  79. }
  80. extern struct dccp_tx_hist_entry *
  81. dccp_tx_hist_find_entry(const struct list_head *list,
  82. const u64 seq);
  83. static inline void dccp_tx_hist_add_entry(struct list_head *list,
  84. struct dccp_tx_hist_entry *entry)
  85. {
  86. list_add(&entry->dccphtx_node, list);
  87. }
  88. static inline void dccp_tx_hist_entry_delete(struct dccp_tx_hist *hist,
  89. struct dccp_tx_hist_entry *entry)
  90. {
  91. if (entry != NULL)
  92. kmem_cache_free(hist->dccptxh_slab, entry);
  93. }
  94. extern void dccp_tx_hist_purge(struct dccp_tx_hist *hist,
  95. struct list_head *list);
  96. extern void dccp_tx_hist_purge_older(struct dccp_tx_hist *hist,
  97. struct list_head *list,
  98. struct dccp_tx_hist_entry *next);
  99. /*
  100. * Receiver History data structures and declarations
  101. */
  102. struct dccp_rx_hist_entry {
  103. struct list_head dccphrx_node;
  104. u64 dccphrx_seqno:48,
  105. dccphrx_ccval:4,
  106. dccphrx_type:4;
  107. u32 dccphrx_ndp; /* In fact it is from 8 to 24 bits */
  108. ktime_t dccphrx_tstamp;
  109. };
  110. struct dccp_rx_hist {
  111. struct kmem_cache *dccprxh_slab;
  112. };
  113. extern struct dccp_rx_hist *dccp_rx_hist_new(const char *name);
  114. extern void dccp_rx_hist_delete(struct dccp_rx_hist *hist);
  115. static inline struct dccp_rx_hist_entry *
  116. dccp_rx_hist_entry_new(struct dccp_rx_hist *hist,
  117. const u32 ndp,
  118. const struct sk_buff *skb,
  119. const gfp_t prio)
  120. {
  121. struct dccp_rx_hist_entry *entry = kmem_cache_alloc(hist->dccprxh_slab,
  122. prio);
  123. if (entry != NULL) {
  124. const struct dccp_hdr *dh = dccp_hdr(skb);
  125. entry->dccphrx_seqno = DCCP_SKB_CB(skb)->dccpd_seq;
  126. entry->dccphrx_ccval = dh->dccph_ccval;
  127. entry->dccphrx_type = dh->dccph_type;
  128. entry->dccphrx_ndp = ndp;
  129. entry->dccphrx_tstamp = ktime_get_real();
  130. }
  131. return entry;
  132. }
  133. static inline struct dccp_rx_hist_entry *
  134. dccp_rx_hist_head(struct list_head *list)
  135. {
  136. struct dccp_rx_hist_entry *head = NULL;
  137. if (!list_empty(list))
  138. head = list_entry(list->next, struct dccp_rx_hist_entry,
  139. dccphrx_node);
  140. return head;
  141. }
  142. extern int dccp_rx_hist_find_entry(const struct list_head *list, const u64 seq,
  143. u8 *ccval);
  144. extern struct dccp_rx_hist_entry *
  145. dccp_rx_hist_find_data_packet(const struct list_head *list);
  146. extern void dccp_rx_hist_add_packet(struct dccp_rx_hist *hist,
  147. struct list_head *rx_list,
  148. struct list_head *li_list,
  149. struct dccp_rx_hist_entry *packet,
  150. u64 nonloss_seqno);
  151. static inline void dccp_rx_hist_entry_delete(struct dccp_rx_hist *hist,
  152. struct dccp_rx_hist_entry *entry)
  153. {
  154. if (entry != NULL)
  155. kmem_cache_free(hist->dccprxh_slab, entry);
  156. }
  157. extern void dccp_rx_hist_purge(struct dccp_rx_hist *hist,
  158. struct list_head *list);
  159. static inline int
  160. dccp_rx_hist_entry_data_packet(const struct dccp_rx_hist_entry *entry)
  161. {
  162. return entry->dccphrx_type == DCCP_PKT_DATA ||
  163. entry->dccphrx_type == DCCP_PKT_DATAACK;
  164. }
  165. extern u64 dccp_rx_hist_detect_loss(struct list_head *rx_list,
  166. struct list_head *li_list, u8 *win_loss);
  167. #endif /* _DCCP_PKT_HIST_ */