diff options
-rw-r--r-- | net/dccp/ccids/ccid3.c | 122 | ||||
-rw-r--r-- | net/dccp/ccids/ccid3.h | 6 | ||||
-rw-r--r-- | net/dccp/ccids/lib/packet_history.c | 111 | ||||
-rw-r--r-- | net/dccp/ccids/lib/packet_history.h | 11 |
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 | ||
747 | static 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 | |||
800 | trim_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 | |||
866 | static void ccid3_hc_rx_send_feedback(struct sock *sk) | 747 | static 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 | |||
65 | enum ccid3_options { | 59 | enum 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 | ||
114 | EXPORT_SYMBOL_GPL(dccp_rx_hist_find_data_packet); | 114 | EXPORT_SYMBOL_GPL(dccp_rx_hist_find_data_packet); |
115 | 115 | ||
116 | int 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 | |||
162 | trim_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 | |||
225 | EXPORT_SYMBOL_GPL(dccp_rx_hist_add_packet); | ||
226 | |||
116 | struct dccp_tx_hist *dccp_tx_hist_new(const char *name) | 227 | struct 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 | |||
47 | struct dccp_tx_hist_entry { | 53 | struct 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 | ||
191 | extern 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_ */ |