···744744 hcrx->ccid3hcrx_state = state;745745}746746747747-static int ccid3_hc_rx_add_hist(struct sock *sk,748748- struct dccp_rx_hist_entry *packet)749749-{750750- struct dccp_sock *dp = dccp_sk(sk);751751- struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;752752- struct dccp_rx_hist_entry *entry, *next, *iter;753753- u8 num_later = 0;754754-755755- iter = dccp_rx_hist_head(&hcrx->ccid3hcrx_hist);756756- if (iter == NULL)757757- dccp_rx_hist_add_entry(&hcrx->ccid3hcrx_hist, packet);758758- else {759759- const u64 seqno = packet->dccphrx_seqno;760760-761761- if (after48(seqno, iter->dccphrx_seqno))762762- dccp_rx_hist_add_entry(&hcrx->ccid3hcrx_hist, packet);763763- else {764764- if (dccp_rx_hist_entry_data_packet(iter))765765- num_later = 1;766766-767767- list_for_each_entry_continue(iter,768768- &hcrx->ccid3hcrx_hist,769769- dccphrx_node) {770770- if (after48(seqno, iter->dccphrx_seqno)) {771771- dccp_rx_hist_add_entry(&iter->dccphrx_node,772772- packet);773773- goto trim_history;774774- }775775-776776- if (dccp_rx_hist_entry_data_packet(iter))777777- num_later++;778778-779779- if (num_later == TFRC_RECV_NUM_LATE_LOSS) {780780- dccp_rx_hist_entry_delete(ccid3_rx_hist,781781- packet);782782- ccid3_pr_debug("%s, sk=%p, packet"783783- "(%llu) already lost!\n",784784- dccp_role(sk), sk,785785- seqno);786786- return 1;787787- }788788- }789789-790790- if (num_later < TFRC_RECV_NUM_LATE_LOSS)791791- dccp_rx_hist_add_entry(&hcrx->ccid3hcrx_hist,792792- packet);793793- /*794794- * FIXME: else what? should we destroy the packet795795- * like above?796796- */797797- }798798- }799799-800800-trim_history:801801- /*802802- * Trim history (remove all packets after the NUM_LATE_LOSS + 1803803- * data packets)804804- */805805- num_later = TFRC_RECV_NUM_LATE_LOSS + 1;806806-807807- if (!list_empty(&hcrx->ccid3hcrx_li_hist)) {808808- list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist,809809- dccphrx_node) {810810- if (num_later == 0) {811811- list_del_init(&entry->dccphrx_node);812812- dccp_rx_hist_entry_delete(ccid3_rx_hist, entry);813813- } else if (dccp_rx_hist_entry_data_packet(entry))814814- --num_later;815815- }816816- } else {817817- int step = 0;818818- u8 win_count = 0; /* Not needed, but lets shut up gcc */819819- int tmp;820820- /*821821- * We have no loss interval history so we need at least one822822- * rtt:s of data packets to approximate rtt.823823- */824824- list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist,825825- dccphrx_node) {826826- if (num_later == 0) {827827- switch (step) {828828- case 0:829829- step = 1;830830- /* OK, find next data packet */831831- num_later = 1;832832- break;833833- case 1:834834- step = 2;835835- /* OK, find next data packet */836836- num_later = 1;837837- win_count = entry->dccphrx_ccval;838838- break;839839- case 2:840840- tmp = win_count - entry->dccphrx_ccval;841841- if (tmp < 0)842842- tmp += TFRC_WIN_COUNT_LIMIT;843843- if (tmp > TFRC_WIN_COUNT_PER_RTT + 1) {844844- /*845845- * We have found a packet older846846- * than one rtt remove the rest847847- */848848- step = 3;849849- } else /* OK, find next data packet */850850- num_later = 1;851851- break;852852- case 3:853853- list_del_init(&entry->dccphrx_node);854854- dccp_rx_hist_entry_delete(ccid3_rx_hist,855855- entry);856856- break;857857- }858858- } else if (dccp_rx_hist_entry_data_packet(entry))859859- --num_later;860860- }861861- }862862-863863- return 0;864864-}865865-866747static void ccid3_hc_rx_send_feedback(struct sock *sk)867748{868749 struct dccp_sock *dp = dccp_sk(sk);···1066118510671186 win_count = packet->dccphrx_ccval;1068118710691069- ins = ccid3_hc_rx_add_hist(sk, packet);11881188+ ins = dccp_rx_hist_add_packet(ccid3_rx_hist, &hcrx->ccid3hcrx_hist,11891189+ &hcrx->ccid3hcrx_li_hist, packet);1070119010711191 if (DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK)10721192 return;
-6
net/dccp/ccids/ccid3.h
···5151/* In usecs - half the scheduling granularity as per RFC3448 4.6 */5252#define TFRC_OPSYS_HALF_TIME_GRAN (USEC_PER_SEC / (2 * HZ))53535454-#define TFRC_WIN_COUNT_PER_RTT 45555-#define TFRC_WIN_COUNT_LIMIT 165656-5754/* In seconds */5855#define TFRC_MAX_BACK_OFF_TIME 6459566057#define TFRC_SMALLEST_P 406161-6262-/* Number of later packets received before one is considered lost */6363-#define TFRC_RECV_NUM_LATE_LOSS 364586559enum ccid3_options {6660 TFRC_OPT_LOSS_EVENT_RATE = 192,
+111
net/dccp/ccids/lib/packet_history.c
···113113114114EXPORT_SYMBOL_GPL(dccp_rx_hist_find_data_packet);115115116116+int dccp_rx_hist_add_packet(struct dccp_rx_hist *hist,117117+ struct list_head *rx_list,118118+ struct list_head *li_list,119119+ struct dccp_rx_hist_entry *packet)120120+{121121+ struct dccp_rx_hist_entry *entry, *next, *iter;122122+ u8 num_later = 0;123123+124124+ iter = dccp_rx_hist_head(rx_list);125125+ if (iter == NULL)126126+ dccp_rx_hist_add_entry(rx_list, packet);127127+ else {128128+ const u64 seqno = packet->dccphrx_seqno;129129+130130+ if (after48(seqno, iter->dccphrx_seqno))131131+ dccp_rx_hist_add_entry(rx_list, packet);132132+ else {133133+ if (dccp_rx_hist_entry_data_packet(iter))134134+ num_later = 1;135135+136136+ list_for_each_entry_continue(iter, rx_list,137137+ dccphrx_node) {138138+ if (after48(seqno, iter->dccphrx_seqno)) {139139+ dccp_rx_hist_add_entry(&iter->dccphrx_node,140140+ packet);141141+ goto trim_history;142142+ }143143+144144+ if (dccp_rx_hist_entry_data_packet(iter))145145+ num_later++;146146+147147+ if (num_later == TFRC_RECV_NUM_LATE_LOSS) {148148+ dccp_rx_hist_entry_delete(hist, packet);149149+ return 1;150150+ }151151+ }152152+153153+ if (num_later < TFRC_RECV_NUM_LATE_LOSS)154154+ dccp_rx_hist_add_entry(rx_list, packet);155155+ /*156156+ * FIXME: else what? should we destroy the packet157157+ * like above?158158+ */159159+ }160160+ }161161+162162+trim_history:163163+ /*164164+ * Trim history (remove all packets after the NUM_LATE_LOSS + 1165165+ * data packets)166166+ */167167+ num_later = TFRC_RECV_NUM_LATE_LOSS + 1;168168+169169+ if (!list_empty(li_list)) {170170+ list_for_each_entry_safe(entry, next, rx_list, dccphrx_node) {171171+ if (num_later == 0) {172172+ list_del_init(&entry->dccphrx_node);173173+ dccp_rx_hist_entry_delete(hist, entry);174174+ } else if (dccp_rx_hist_entry_data_packet(entry))175175+ --num_later;176176+ }177177+ } else {178178+ int step = 0;179179+ u8 win_count = 0; /* Not needed, but lets shut up gcc */180180+ int tmp;181181+ /*182182+ * We have no loss interval history so we need at least one183183+ * rtt:s of data packets to approximate rtt.184184+ */185185+ list_for_each_entry_safe(entry, next, rx_list, dccphrx_node) {186186+ if (num_later == 0) {187187+ switch (step) {188188+ case 0:189189+ step = 1;190190+ /* OK, find next data packet */191191+ num_later = 1;192192+ break;193193+ case 1:194194+ step = 2;195195+ /* OK, find next data packet */196196+ num_later = 1;197197+ win_count = entry->dccphrx_ccval;198198+ break;199199+ case 2:200200+ tmp = win_count - entry->dccphrx_ccval;201201+ if (tmp < 0)202202+ tmp += TFRC_WIN_COUNT_LIMIT;203203+ if (tmp > TFRC_WIN_COUNT_PER_RTT + 1) {204204+ /*205205+ * We have found a packet older206206+ * than one rtt remove the rest207207+ */208208+ step = 3;209209+ } else /* OK, find next data packet */210210+ num_later = 1;211211+ break;212212+ case 3:213213+ list_del_init(&entry->dccphrx_node);214214+ dccp_rx_hist_entry_delete(hist, entry);215215+ break;216216+ }217217+ } else if (dccp_rx_hist_entry_data_packet(entry))218218+ --num_later;219219+ }220220+ }221221+222222+ return 0;223223+}224224+225225+EXPORT_SYMBOL_GPL(dccp_rx_hist_add_packet);226226+116227struct dccp_tx_hist *dccp_tx_hist_new(const char *name)117228{118229 struct dccp_tx_hist *hist = kmalloc(sizeof(*hist), GFP_ATOMIC);
+11
net/dccp/ccids/lib/packet_history.h
···44444545#include "../../dccp.h"46464747+/* Number of later packets received before one is considered lost */4848+#define TFRC_RECV_NUM_LATE_LOSS 34949+5050+#define TFRC_WIN_COUNT_PER_RTT 45151+#define TFRC_WIN_COUNT_LIMIT 165252+4753struct dccp_tx_hist_entry {4854 struct list_head dccphtx_node;4955 u64 dccphtx_seqno:48,···187181 return entry->dccphrx_type == DCCP_PKT_DATA ||188182 entry->dccphrx_type == DCCP_PKT_DATAACK;189183}184184+185185+extern int dccp_rx_hist_add_packet(struct dccp_rx_hist *hist,186186+ struct list_head *rx_list,187187+ struct list_head *li_list,188188+ struct dccp_rx_hist_entry *packet);190189191190#endif /* _DCCP_PKT_HIST_ */