diff options
-rw-r--r-- | net/dccp/ccids/ccid3.c | 83 | ||||
-rw-r--r-- | net/dccp/ccids/lib/packet_history.c | 82 | ||||
-rw-r--r-- | net/dccp/ccids/lib/packet_history.h | 3 |
3 files changed, 89 insertions, 79 deletions
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index 849f5580efbd..4ff6ede0f07d 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c | |||
@@ -927,86 +927,11 @@ static void ccid3_hc_rx_detect_loss(struct sock *sk) | |||
927 | { | 927 | { |
928 | struct dccp_sock *dp = dccp_sk(sk); | 928 | struct dccp_sock *dp = dccp_sk(sk); |
929 | struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private; | 929 | struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private; |
930 | struct dccp_rx_hist_entry *entry, *next, *packet; | 930 | u8 win_loss; |
931 | struct dccp_rx_hist_entry *a_loss = NULL; | 931 | const u64 seq_loss = dccp_rx_hist_detect_loss(&hcrx->ccid3hcrx_hist, |
932 | struct dccp_rx_hist_entry *b_loss = NULL; | 932 | &hcrx->ccid3hcrx_li_hist, |
933 | u64 seq_loss = DCCP_MAX_SEQNO + 1; | 933 | &win_loss); |
934 | u8 win_loss = 0; | ||
935 | u8 num_later = TFRC_RECV_NUM_LATE_LOSS; | ||
936 | 934 | ||
937 | list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist, | ||
938 | dccphrx_node) { | ||
939 | if (num_later == 0) { | ||
940 | b_loss = entry; | ||
941 | break; | ||
942 | } else if (dccp_rx_hist_entry_data_packet(entry)) | ||
943 | --num_later; | ||
944 | } | ||
945 | |||
946 | if (b_loss == NULL) | ||
947 | goto out_update_li; | ||
948 | |||
949 | num_later = 1; | ||
950 | |||
951 | list_for_each_entry_safe_continue(entry, next, &hcrx->ccid3hcrx_hist, | ||
952 | dccphrx_node) { | ||
953 | if (num_later == 0) { | ||
954 | a_loss = entry; | ||
955 | break; | ||
956 | } else if (dccp_rx_hist_entry_data_packet(entry)) | ||
957 | --num_later; | ||
958 | } | ||
959 | |||
960 | if (a_loss == NULL) { | ||
961 | if (list_empty(&hcrx->ccid3hcrx_li_hist)) { | ||
962 | /* no loss event have occured yet */ | ||
963 | LIMIT_NETDEBUG("%s: TODO: find a lost data packet by " | ||
964 | "comparing to initial seqno\n", | ||
965 | dccp_role(sk)); | ||
966 | goto out_update_li; | ||
967 | } else { | ||
968 | pr_info("%s: %s, sk=%p, ERROR! Less than 4 data " | ||
969 | "packets in history", | ||
970 | __FUNCTION__, dccp_role(sk), sk); | ||
971 | return; | ||
972 | } | ||
973 | } | ||
974 | |||
975 | /* Locate a lost data packet */ | ||
976 | entry = packet = b_loss; | ||
977 | list_for_each_entry_safe_continue(entry, next, &hcrx->ccid3hcrx_hist, | ||
978 | dccphrx_node) { | ||
979 | u64 delta = dccp_delta_seqno(entry->dccphrx_seqno, | ||
980 | packet->dccphrx_seqno); | ||
981 | |||
982 | if (delta != 0) { | ||
983 | if (dccp_rx_hist_entry_data_packet(packet)) | ||
984 | --delta; | ||
985 | /* | ||
986 | * FIXME: check this, probably this % usage is because | ||
987 | * in earlier drafts the ndp count was just 8 bits | ||
988 | * long, but now it cam be up to 24 bits long. | ||
989 | */ | ||
990 | #if 0 | ||
991 | if (delta % DCCP_NDP_LIMIT != | ||
992 | (packet->dccphrx_ndp - | ||
993 | entry->dccphrx_ndp) % DCCP_NDP_LIMIT) | ||
994 | #endif | ||
995 | if (delta != | ||
996 | packet->dccphrx_ndp - entry->dccphrx_ndp) { | ||
997 | seq_loss = entry->dccphrx_seqno; | ||
998 | dccp_inc_seqno(&seq_loss); | ||
999 | } | ||
1000 | } | ||
1001 | packet = entry; | ||
1002 | if (packet == a_loss) | ||
1003 | break; | ||
1004 | } | ||
1005 | |||
1006 | if (seq_loss != DCCP_MAX_SEQNO + 1) | ||
1007 | win_loss = a_loss->dccphrx_ccval; | ||
1008 | |||
1009 | out_update_li: | ||
1010 | ccid3_hc_rx_update_li(sk, seq_loss, win_loss); | 935 | ccid3_hc_rx_update_li(sk, seq_loss, win_loss); |
1011 | } | 936 | } |
1012 | 937 | ||
diff --git a/net/dccp/ccids/lib/packet_history.c b/net/dccp/ccids/lib/packet_history.c index e2576b45ac0b..d3f9d2053830 100644 --- a/net/dccp/ccids/lib/packet_history.c +++ b/net/dccp/ccids/lib/packet_history.c | |||
@@ -224,6 +224,88 @@ trim_history: | |||
224 | 224 | ||
225 | EXPORT_SYMBOL_GPL(dccp_rx_hist_add_packet); | 225 | EXPORT_SYMBOL_GPL(dccp_rx_hist_add_packet); |
226 | 226 | ||
227 | u64 dccp_rx_hist_detect_loss(struct list_head *rx_list, | ||
228 | struct list_head *li_list, u8 *win_loss) | ||
229 | { | ||
230 | struct dccp_rx_hist_entry *entry, *next, *packet; | ||
231 | struct dccp_rx_hist_entry *a_loss = NULL; | ||
232 | struct dccp_rx_hist_entry *b_loss = NULL; | ||
233 | u64 seq_loss = DCCP_MAX_SEQNO + 1; | ||
234 | u8 num_later = TFRC_RECV_NUM_LATE_LOSS; | ||
235 | |||
236 | list_for_each_entry_safe(entry, next, rx_list, dccphrx_node) { | ||
237 | if (num_later == 0) { | ||
238 | b_loss = entry; | ||
239 | break; | ||
240 | } else if (dccp_rx_hist_entry_data_packet(entry)) | ||
241 | --num_later; | ||
242 | } | ||
243 | |||
244 | if (b_loss == NULL) | ||
245 | goto out; | ||
246 | |||
247 | num_later = 1; | ||
248 | list_for_each_entry_safe_continue(entry, next, rx_list, dccphrx_node) { | ||
249 | if (num_later == 0) { | ||
250 | a_loss = entry; | ||
251 | break; | ||
252 | } else if (dccp_rx_hist_entry_data_packet(entry)) | ||
253 | --num_later; | ||
254 | } | ||
255 | |||
256 | if (a_loss == NULL) { | ||
257 | if (list_empty(li_list)) { | ||
258 | /* no loss event have occured yet */ | ||
259 | LIMIT_NETDEBUG("%s: TODO: find a lost data packet by " | ||
260 | "comparing to initial seqno\n", | ||
261 | __FUNCTION__); | ||
262 | goto out; | ||
263 | } else { | ||
264 | LIMIT_NETDEBUG("%s: Less than 4 data pkts in history!", | ||
265 | __FUNCTION__); | ||
266 | goto out; | ||
267 | } | ||
268 | } | ||
269 | |||
270 | /* Locate a lost data packet */ | ||
271 | entry = packet = b_loss; | ||
272 | list_for_each_entry_safe_continue(entry, next, rx_list, dccphrx_node) { | ||
273 | u64 delta = dccp_delta_seqno(entry->dccphrx_seqno, | ||
274 | packet->dccphrx_seqno); | ||
275 | |||
276 | if (delta != 0) { | ||
277 | if (dccp_rx_hist_entry_data_packet(packet)) | ||
278 | --delta; | ||
279 | /* | ||
280 | * FIXME: check this, probably this % usage is because | ||
281 | * in earlier drafts the ndp count was just 8 bits | ||
282 | * long, but now it cam be up to 24 bits long. | ||
283 | */ | ||
284 | #if 0 | ||
285 | if (delta % DCCP_NDP_LIMIT != | ||
286 | (packet->dccphrx_ndp - | ||
287 | entry->dccphrx_ndp) % DCCP_NDP_LIMIT) | ||
288 | #endif | ||
289 | if (delta != packet->dccphrx_ndp - entry->dccphrx_ndp) { | ||
290 | seq_loss = entry->dccphrx_seqno; | ||
291 | dccp_inc_seqno(&seq_loss); | ||
292 | } | ||
293 | } | ||
294 | packet = entry; | ||
295 | if (packet == a_loss) | ||
296 | break; | ||
297 | } | ||
298 | out: | ||
299 | if (seq_loss != DCCP_MAX_SEQNO + 1) | ||
300 | *win_loss = a_loss->dccphrx_ccval; | ||
301 | else | ||
302 | *win_loss = 0; /* Paranoia */ | ||
303 | |||
304 | return seq_loss; | ||
305 | } | ||
306 | |||
307 | EXPORT_SYMBOL_GPL(dccp_rx_hist_detect_loss); | ||
308 | |||
227 | struct dccp_tx_hist *dccp_tx_hist_new(const char *name) | 309 | struct dccp_tx_hist *dccp_tx_hist_new(const char *name) |
228 | { | 310 | { |
229 | struct dccp_tx_hist *hist = kmalloc(sizeof(*hist), GFP_ATOMIC); | 311 | 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 ebfcb8e2c676..fb90a91aa93d 100644 --- a/net/dccp/ccids/lib/packet_history.h +++ b/net/dccp/ccids/lib/packet_history.h | |||
@@ -193,4 +193,7 @@ extern int dccp_rx_hist_add_packet(struct dccp_rx_hist *hist, | |||
193 | struct list_head *li_list, | 193 | struct list_head *li_list, |
194 | struct dccp_rx_hist_entry *packet); | 194 | struct dccp_rx_hist_entry *packet); |
195 | 195 | ||
196 | extern u64 dccp_rx_hist_detect_loss(struct list_head *rx_list, | ||
197 | struct list_head *li_list, u8 *win_loss); | ||
198 | |||
196 | #endif /* _DCCP_PKT_HIST_ */ | 199 | #endif /* _DCCP_PKT_HIST_ */ |