aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/dccp/ccids/ccid3.c122
-rw-r--r--net/dccp/ccids/ccid3.h6
-rw-r--r--net/dccp/ccids/lib/packet_history.c111
-rw-r--r--net/dccp/ccids/lib/packet_history.h11
4 files changed, 124 insertions, 126 deletions
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index a215c46d6f1b..849f5580efbd 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -744,125 +744,6 @@ static inline void ccid3_hc_rx_set_state(struct sock *sk,
744 hcrx->ccid3hcrx_state = state; 744 hcrx->ccid3hcrx_state = state;
745} 745}
746 746
747static int ccid3_hc_rx_add_hist(struct sock *sk,
748 struct dccp_rx_hist_entry *packet)
749{
750 struct dccp_sock *dp = dccp_sk(sk);
751 struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
752 struct dccp_rx_hist_entry *entry, *next, *iter;
753 u8 num_later = 0;
754
755 iter = dccp_rx_hist_head(&hcrx->ccid3hcrx_hist);
756 if (iter == NULL)
757 dccp_rx_hist_add_entry(&hcrx->ccid3hcrx_hist, packet);
758 else {
759 const u64 seqno = packet->dccphrx_seqno;
760
761 if (after48(seqno, iter->dccphrx_seqno))
762 dccp_rx_hist_add_entry(&hcrx->ccid3hcrx_hist, packet);
763 else {
764 if (dccp_rx_hist_entry_data_packet(iter))
765 num_later = 1;
766
767 list_for_each_entry_continue(iter,
768 &hcrx->ccid3hcrx_hist,
769 dccphrx_node) {
770 if (after48(seqno, iter->dccphrx_seqno)) {
771 dccp_rx_hist_add_entry(&iter->dccphrx_node,
772 packet);
773 goto trim_history;
774 }
775
776 if (dccp_rx_hist_entry_data_packet(iter))
777 num_later++;
778
779 if (num_later == TFRC_RECV_NUM_LATE_LOSS) {
780 dccp_rx_hist_entry_delete(ccid3_rx_hist,
781 packet);
782 ccid3_pr_debug("%s, sk=%p, packet"
783 "(%llu) already lost!\n",
784 dccp_role(sk), sk,
785 seqno);
786 return 1;
787 }
788 }
789
790 if (num_later < TFRC_RECV_NUM_LATE_LOSS)
791 dccp_rx_hist_add_entry(&hcrx->ccid3hcrx_hist,
792 packet);
793 /*
794 * FIXME: else what? should we destroy the packet
795 * like above?
796 */
797 }
798 }
799
800trim_history:
801 /*
802 * Trim history (remove all packets after the NUM_LATE_LOSS + 1
803 * data packets)
804 */
805 num_later = TFRC_RECV_NUM_LATE_LOSS + 1;
806
807 if (!list_empty(&hcrx->ccid3hcrx_li_hist)) {
808 list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist,
809 dccphrx_node) {
810 if (num_later == 0) {
811 list_del_init(&entry->dccphrx_node);
812 dccp_rx_hist_entry_delete(ccid3_rx_hist, entry);
813 } else if (dccp_rx_hist_entry_data_packet(entry))
814 --num_later;
815 }
816 } else {
817 int step = 0;
818 u8 win_count = 0; /* Not needed, but lets shut up gcc */
819 int tmp;
820 /*
821 * We have no loss interval history so we need at least one
822 * rtt:s of data packets to approximate rtt.
823 */
824 list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist,
825 dccphrx_node) {
826 if (num_later == 0) {
827 switch (step) {
828 case 0:
829 step = 1;
830 /* OK, find next data packet */
831 num_later = 1;
832 break;
833 case 1:
834 step = 2;
835 /* OK, find next data packet */
836 num_later = 1;
837 win_count = entry->dccphrx_ccval;
838 break;
839 case 2:
840 tmp = win_count - entry->dccphrx_ccval;
841 if (tmp < 0)
842 tmp += TFRC_WIN_COUNT_LIMIT;
843 if (tmp > TFRC_WIN_COUNT_PER_RTT + 1) {
844 /*
845 * We have found a packet older
846 * than one rtt remove the rest
847 */
848 step = 3;
849 } else /* OK, find next data packet */
850 num_later = 1;
851 break;
852 case 3:
853 list_del_init(&entry->dccphrx_node);
854 dccp_rx_hist_entry_delete(ccid3_rx_hist,
855 entry);
856 break;
857 }
858 } else if (dccp_rx_hist_entry_data_packet(entry))
859 --num_later;
860 }
861 }
862
863 return 0;
864}
865
866static void ccid3_hc_rx_send_feedback(struct sock *sk) 747static void ccid3_hc_rx_send_feedback(struct sock *sk)
867{ 748{
868 struct dccp_sock *dp = dccp_sk(sk); 749 struct dccp_sock *dp = dccp_sk(sk);
@@ -1185,7 +1066,8 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
1185 1066
1186 win_count = packet->dccphrx_ccval; 1067 win_count = packet->dccphrx_ccval;
1187 1068
1188 ins = ccid3_hc_rx_add_hist(sk, packet); 1069 ins = dccp_rx_hist_add_packet(ccid3_rx_hist, &hcrx->ccid3hcrx_hist,
1070 &hcrx->ccid3hcrx_li_hist, packet);
1189 1071
1190 if (DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK) 1072 if (DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK)
1191 return; 1073 return;
diff --git a/net/dccp/ccids/ccid3.h b/net/dccp/ccids/ccid3.h
index f68d0b4e31e9..ee8cbace6630 100644
--- a/net/dccp/ccids/ccid3.h
+++ b/net/dccp/ccids/ccid3.h
@@ -51,17 +51,11 @@
51/* In usecs - half the scheduling granularity as per RFC3448 4.6 */ 51/* In usecs - half the scheduling granularity as per RFC3448 4.6 */
52#define TFRC_OPSYS_HALF_TIME_GRAN (USEC_PER_SEC / (2 * HZ)) 52#define TFRC_OPSYS_HALF_TIME_GRAN (USEC_PER_SEC / (2 * HZ))
53 53
54#define TFRC_WIN_COUNT_PER_RTT 4
55#define TFRC_WIN_COUNT_LIMIT 16
56
57/* In seconds */ 54/* In seconds */
58#define TFRC_MAX_BACK_OFF_TIME 64 55#define TFRC_MAX_BACK_OFF_TIME 64
59 56
60#define TFRC_SMALLEST_P 40 57#define TFRC_SMALLEST_P 40
61 58
62/* Number of later packets received before one is considered lost */
63#define TFRC_RECV_NUM_LATE_LOSS 3
64
65enum ccid3_options { 59enum ccid3_options {
66 TFRC_OPT_LOSS_EVENT_RATE = 192, 60 TFRC_OPT_LOSS_EVENT_RATE = 192,
67 TFRC_OPT_LOSS_INTERVALS = 193, 61 TFRC_OPT_LOSS_INTERVALS = 193,
diff --git a/net/dccp/ccids/lib/packet_history.c b/net/dccp/ccids/lib/packet_history.c
index f252a9555e31..e2576b45ac0b 100644
--- a/net/dccp/ccids/lib/packet_history.c
+++ b/net/dccp/ccids/lib/packet_history.c
@@ -113,6 +113,117 @@ struct dccp_rx_hist_entry *
113 113
114EXPORT_SYMBOL_GPL(dccp_rx_hist_find_data_packet); 114EXPORT_SYMBOL_GPL(dccp_rx_hist_find_data_packet);
115 115
116int dccp_rx_hist_add_packet(struct dccp_rx_hist *hist,
117 struct list_head *rx_list,
118 struct list_head *li_list,
119 struct dccp_rx_hist_entry *packet)
120{
121 struct dccp_rx_hist_entry *entry, *next, *iter;
122 u8 num_later = 0;
123
124 iter = dccp_rx_hist_head(rx_list);
125 if (iter == NULL)
126 dccp_rx_hist_add_entry(rx_list, packet);
127 else {
128 const u64 seqno = packet->dccphrx_seqno;
129
130 if (after48(seqno, iter->dccphrx_seqno))
131 dccp_rx_hist_add_entry(rx_list, packet);
132 else {
133 if (dccp_rx_hist_entry_data_packet(iter))
134 num_later = 1;
135
136 list_for_each_entry_continue(iter, rx_list,
137 dccphrx_node) {
138 if (after48(seqno, iter->dccphrx_seqno)) {
139 dccp_rx_hist_add_entry(&iter->dccphrx_node,
140 packet);
141 goto trim_history;
142 }
143
144 if (dccp_rx_hist_entry_data_packet(iter))
145 num_later++;
146
147 if (num_later == TFRC_RECV_NUM_LATE_LOSS) {
148 dccp_rx_hist_entry_delete(hist, packet);
149 return 1;
150 }
151 }
152
153 if (num_later < TFRC_RECV_NUM_LATE_LOSS)
154 dccp_rx_hist_add_entry(rx_list, packet);
155 /*
156 * FIXME: else what? should we destroy the packet
157 * like above?
158 */
159 }
160 }
161
162trim_history:
163 /*
164 * Trim history (remove all packets after the NUM_LATE_LOSS + 1
165 * data packets)
166 */
167 num_later = TFRC_RECV_NUM_LATE_LOSS + 1;
168
169 if (!list_empty(li_list)) {
170 list_for_each_entry_safe(entry, next, rx_list, dccphrx_node) {
171 if (num_later == 0) {
172 list_del_init(&entry->dccphrx_node);
173 dccp_rx_hist_entry_delete(hist, entry);
174 } else if (dccp_rx_hist_entry_data_packet(entry))
175 --num_later;
176 }
177 } else {
178 int step = 0;
179 u8 win_count = 0; /* Not needed, but lets shut up gcc */
180 int tmp;
181 /*
182 * We have no loss interval history so we need at least one
183 * rtt:s of data packets to approximate rtt.
184 */
185 list_for_each_entry_safe(entry, next, rx_list, dccphrx_node) {
186 if (num_later == 0) {
187 switch (step) {
188 case 0:
189 step = 1;
190 /* OK, find next data packet */
191 num_later = 1;
192 break;
193 case 1:
194 step = 2;
195 /* OK, find next data packet */
196 num_later = 1;
197 win_count = entry->dccphrx_ccval;
198 break;
199 case 2:
200 tmp = win_count - entry->dccphrx_ccval;
201 if (tmp < 0)
202 tmp += TFRC_WIN_COUNT_LIMIT;
203 if (tmp > TFRC_WIN_COUNT_PER_RTT + 1) {
204 /*
205 * We have found a packet older
206 * than one rtt remove the rest
207 */
208 step = 3;
209 } else /* OK, find next data packet */
210 num_later = 1;
211 break;
212 case 3:
213 list_del_init(&entry->dccphrx_node);
214 dccp_rx_hist_entry_delete(hist, entry);
215 break;
216 }
217 } else if (dccp_rx_hist_entry_data_packet(entry))
218 --num_later;
219 }
220 }
221
222 return 0;
223}
224
225EXPORT_SYMBOL_GPL(dccp_rx_hist_add_packet);
226
116struct dccp_tx_hist *dccp_tx_hist_new(const char *name) 227struct dccp_tx_hist *dccp_tx_hist_new(const char *name)
117{ 228{
118 struct dccp_tx_hist *hist = kmalloc(sizeof(*hist), GFP_ATOMIC); 229 struct dccp_tx_hist *hist = kmalloc(sizeof(*hist), GFP_ATOMIC);
diff --git a/net/dccp/ccids/lib/packet_history.h b/net/dccp/ccids/lib/packet_history.h
index 235828d822d9..ebfcb8e2c676 100644
--- a/net/dccp/ccids/lib/packet_history.h
+++ b/net/dccp/ccids/lib/packet_history.h
@@ -44,6 +44,12 @@
44 44
45#include "../../dccp.h" 45#include "../../dccp.h"
46 46
47/* Number of later packets received before one is considered lost */
48#define TFRC_RECV_NUM_LATE_LOSS 3
49
50#define TFRC_WIN_COUNT_PER_RTT 4
51#define TFRC_WIN_COUNT_LIMIT 16
52
47struct dccp_tx_hist_entry { 53struct dccp_tx_hist_entry {
48 struct list_head dccphtx_node; 54 struct list_head dccphtx_node;
49 u64 dccphtx_seqno:48, 55 u64 dccphtx_seqno:48,
@@ -182,4 +188,9 @@ static inline int
182 entry->dccphrx_type == DCCP_PKT_DATAACK; 188 entry->dccphrx_type == DCCP_PKT_DATAACK;
183} 189}
184 190
191extern int dccp_rx_hist_add_packet(struct dccp_rx_hist *hist,
192 struct list_head *rx_list,
193 struct list_head *li_list,
194 struct dccp_rx_hist_entry *packet);
195
185#endif /* _DCCP_PKT_HIST_ */ 196#endif /* _DCCP_PKT_HIST_ */