17c657876SArnaldo Carvalho de Melo /* 27c657876SArnaldo Carvalho de Melo * net/dccp/ccids/ccid3.c 37c657876SArnaldo Carvalho de Melo * 47c657876SArnaldo Carvalho de Melo * Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand. 51bc09869SIan McDonald * Copyright (c) 2005 Ian McDonald <iam4@cs.waikato.ac.nz> 67c657876SArnaldo Carvalho de Melo * 77c657876SArnaldo Carvalho de Melo * An implementation of the DCCP protocol 87c657876SArnaldo Carvalho de Melo * 97c657876SArnaldo Carvalho de Melo * This code has been developed by the University of Waikato WAND 107c657876SArnaldo Carvalho de Melo * research group. For further information please see http://www.wand.net.nz/ 117c657876SArnaldo Carvalho de Melo * 127c657876SArnaldo Carvalho de Melo * This code also uses code from Lulea University, rereleased as GPL by its 137c657876SArnaldo Carvalho de Melo * authors: 147c657876SArnaldo Carvalho de Melo * Copyright (c) 2003 Nils-Erik Mattsson, Joacim Haggmark, Magnus Erixzon 157c657876SArnaldo Carvalho de Melo * 167c657876SArnaldo Carvalho de Melo * Changes to meet Linux coding standards, to make it meet latest ccid3 draft 177c657876SArnaldo Carvalho de Melo * and to make it work as a loadable module in the DCCP stack written by 187c657876SArnaldo Carvalho de Melo * Arnaldo Carvalho de Melo <acme@conectiva.com.br>. 197c657876SArnaldo Carvalho de Melo * 207c657876SArnaldo Carvalho de Melo * Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br> 217c657876SArnaldo Carvalho de Melo * 227c657876SArnaldo Carvalho de Melo * This program is free software; you can redistribute it and/or modify 237c657876SArnaldo Carvalho de Melo * it under the terms of the GNU General Public License as published by 247c657876SArnaldo Carvalho de Melo * the Free Software Foundation; either version 2 of the License, or 257c657876SArnaldo Carvalho de Melo * (at your option) any later version. 267c657876SArnaldo Carvalho de Melo * 277c657876SArnaldo Carvalho de Melo * This program is distributed in the hope that it will be useful, 287c657876SArnaldo Carvalho de Melo * but WITHOUT ANY WARRANTY; without even the implied warranty of 297c657876SArnaldo Carvalho de Melo * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 307c657876SArnaldo Carvalho de Melo * GNU General Public License for more details. 317c657876SArnaldo Carvalho de Melo * 327c657876SArnaldo Carvalho de Melo * You should have received a copy of the GNU General Public License 337c657876SArnaldo Carvalho de Melo * along with this program; if not, write to the Free Software 347c657876SArnaldo Carvalho de Melo * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 357c657876SArnaldo Carvalho de Melo */ 367c657876SArnaldo Carvalho de Melo 378c60f3faSArnaldo Carvalho de Melo #include <linux/config.h> 387c657876SArnaldo Carvalho de Melo #include "../ccid.h" 397c657876SArnaldo Carvalho de Melo #include "../dccp.h" 408c60f3faSArnaldo Carvalho de Melo #include "../packet_history.h" 417c657876SArnaldo Carvalho de Melo #include "ccid3.h" 427c657876SArnaldo Carvalho de Melo 437c657876SArnaldo Carvalho de Melo #ifdef CCID3_DEBUG 447c657876SArnaldo Carvalho de Melo extern int ccid3_debug; 457c657876SArnaldo Carvalho de Melo 467c657876SArnaldo Carvalho de Melo #define ccid3_pr_debug(format, a...) \ 477c657876SArnaldo Carvalho de Melo do { if (ccid3_debug) \ 487c657876SArnaldo Carvalho de Melo printk(KERN_DEBUG "%s: " format, __FUNCTION__, ##a); \ 497c657876SArnaldo Carvalho de Melo } while (0) 507c657876SArnaldo Carvalho de Melo #else 517c657876SArnaldo Carvalho de Melo #define ccid3_pr_debug(format, a...) 527c657876SArnaldo Carvalho de Melo #endif 537c657876SArnaldo Carvalho de Melo 547c657876SArnaldo Carvalho de Melo #define TFRC_MIN_PACKET_SIZE 16 557c657876SArnaldo Carvalho de Melo #define TFRC_STD_PACKET_SIZE 256 567c657876SArnaldo Carvalho de Melo #define TFRC_MAX_PACKET_SIZE 65535 577c657876SArnaldo Carvalho de Melo 58cef07fd6SArnaldo Carvalho de Melo #define TFRC_INITIAL_TIMEOUT (2 * USEC_PER_SEC) 597c657876SArnaldo Carvalho de Melo /* two seconds as per CCID3 spec 11 */ 607c657876SArnaldo Carvalho de Melo 61cef07fd6SArnaldo Carvalho de Melo #define TFRC_OPSYS_HALF_TIME_GRAN (USEC_PER_SEC / (2 * HZ)) 627c657876SArnaldo Carvalho de Melo /* above is in usecs - half the scheduling granularity as per RFC3448 4.6 */ 637c657876SArnaldo Carvalho de Melo 647c657876SArnaldo Carvalho de Melo #define TFRC_WIN_COUNT_PER_RTT 4 657c657876SArnaldo Carvalho de Melo #define TFRC_WIN_COUNT_LIMIT 16 667c657876SArnaldo Carvalho de Melo 677c657876SArnaldo Carvalho de Melo #define TFRC_MAX_BACK_OFF_TIME 64 687c657876SArnaldo Carvalho de Melo /* above is in seconds */ 697c657876SArnaldo Carvalho de Melo 707c657876SArnaldo Carvalho de Melo #define TFRC_SMALLEST_P 40 717c657876SArnaldo Carvalho de Melo 727c657876SArnaldo Carvalho de Melo #define TFRC_RECV_IVAL_F_LENGTH 8 /* length(w[]) */ 737c657876SArnaldo Carvalho de Melo 747c657876SArnaldo Carvalho de Melo /* Number of later packets received before one is considered lost */ 757c657876SArnaldo Carvalho de Melo #define TFRC_RECV_NUM_LATE_LOSS 3 767c657876SArnaldo Carvalho de Melo 777c657876SArnaldo Carvalho de Melo enum ccid3_options { 787c657876SArnaldo Carvalho de Melo TFRC_OPT_LOSS_EVENT_RATE = 192, 797c657876SArnaldo Carvalho de Melo TFRC_OPT_LOSS_INTERVALS = 193, 807c657876SArnaldo Carvalho de Melo TFRC_OPT_RECEIVE_RATE = 194, 817c657876SArnaldo Carvalho de Melo }; 827c657876SArnaldo Carvalho de Melo 837c657876SArnaldo Carvalho de Melo static int ccid3_debug; 847c657876SArnaldo Carvalho de Melo 85a1d3a355SArnaldo Carvalho de Melo static struct dccp_tx_hist *ccid3_tx_hist; 86a1d3a355SArnaldo Carvalho de Melo static struct dccp_rx_hist *ccid3_rx_hist; 878c60f3faSArnaldo Carvalho de Melo 88ba89966cSEric Dumazet static kmem_cache_t *ccid3_loss_interval_hist_slab __read_mostly; 897c657876SArnaldo Carvalho de Melo 90a1d3a355SArnaldo Carvalho de Melo static inline struct ccid3_loss_interval_hist_entry * 91a1d3a355SArnaldo Carvalho de Melo ccid3_loss_interval_hist_entry_new(const unsigned int __nocast prio) 927c657876SArnaldo Carvalho de Melo { 937c657876SArnaldo Carvalho de Melo return kmem_cache_alloc(ccid3_loss_interval_hist_slab, prio); 947c657876SArnaldo Carvalho de Melo } 957c657876SArnaldo Carvalho de Melo 967c657876SArnaldo Carvalho de Melo static inline void ccid3_loss_interval_hist_entry_delete(struct ccid3_loss_interval_hist_entry *entry) 977c657876SArnaldo Carvalho de Melo { 987c657876SArnaldo Carvalho de Melo if (entry != NULL) 997c657876SArnaldo Carvalho de Melo kmem_cache_free(ccid3_loss_interval_hist_slab, entry); 1007c657876SArnaldo Carvalho de Melo } 1017c657876SArnaldo Carvalho de Melo 1027c657876SArnaldo Carvalho de Melo static void ccid3_loss_interval_history_delete(struct list_head *hist) 1037c657876SArnaldo Carvalho de Melo { 1047c657876SArnaldo Carvalho de Melo struct ccid3_loss_interval_hist_entry *entry, *next; 1057c657876SArnaldo Carvalho de Melo 1067c657876SArnaldo Carvalho de Melo list_for_each_entry_safe(entry, next, hist, ccid3lih_node) { 1077c657876SArnaldo Carvalho de Melo list_del_init(&entry->ccid3lih_node); 1087c657876SArnaldo Carvalho de Melo kmem_cache_free(ccid3_loss_interval_hist_slab, entry); 1097c657876SArnaldo Carvalho de Melo } 1107c657876SArnaldo Carvalho de Melo } 1117c657876SArnaldo Carvalho de Melo 1127c657876SArnaldo Carvalho de Melo static int ccid3_init(struct sock *sk) 1137c657876SArnaldo Carvalho de Melo { 1147c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk); 1157c657876SArnaldo Carvalho de Melo return 0; 1167c657876SArnaldo Carvalho de Melo } 1177c657876SArnaldo Carvalho de Melo 1187c657876SArnaldo Carvalho de Melo static void ccid3_exit(struct sock *sk) 1197c657876SArnaldo Carvalho de Melo { 1207c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk); 1217c657876SArnaldo Carvalho de Melo } 1227c657876SArnaldo Carvalho de Melo 1237c657876SArnaldo Carvalho de Melo /* TFRC sender states */ 1247c657876SArnaldo Carvalho de Melo enum ccid3_hc_tx_states { 1257c657876SArnaldo Carvalho de Melo TFRC_SSTATE_NO_SENT = 1, 1267c657876SArnaldo Carvalho de Melo TFRC_SSTATE_NO_FBACK, 1277c657876SArnaldo Carvalho de Melo TFRC_SSTATE_FBACK, 1287c657876SArnaldo Carvalho de Melo TFRC_SSTATE_TERM, 1297c657876SArnaldo Carvalho de Melo }; 1307c657876SArnaldo Carvalho de Melo 1317c657876SArnaldo Carvalho de Melo #ifdef CCID3_DEBUG 1327c657876SArnaldo Carvalho de Melo static const char *ccid3_tx_state_name(enum ccid3_hc_tx_states state) 1337c657876SArnaldo Carvalho de Melo { 1347c657876SArnaldo Carvalho de Melo static char *ccid3_state_names[] = { 1357c657876SArnaldo Carvalho de Melo [TFRC_SSTATE_NO_SENT] = "NO_SENT", 1367c657876SArnaldo Carvalho de Melo [TFRC_SSTATE_NO_FBACK] = "NO_FBACK", 1377c657876SArnaldo Carvalho de Melo [TFRC_SSTATE_FBACK] = "FBACK", 1387c657876SArnaldo Carvalho de Melo [TFRC_SSTATE_TERM] = "TERM", 1397c657876SArnaldo Carvalho de Melo }; 1407c657876SArnaldo Carvalho de Melo 1417c657876SArnaldo Carvalho de Melo return ccid3_state_names[state]; 1427c657876SArnaldo Carvalho de Melo } 1437c657876SArnaldo Carvalho de Melo #endif 1447c657876SArnaldo Carvalho de Melo 1457c657876SArnaldo Carvalho de Melo static inline void ccid3_hc_tx_set_state(struct sock *sk, enum ccid3_hc_tx_states state) 1467c657876SArnaldo Carvalho de Melo { 1477c657876SArnaldo Carvalho de Melo struct dccp_sock *dp = dccp_sk(sk); 1487c657876SArnaldo Carvalho de Melo struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private; 1497c657876SArnaldo Carvalho de Melo enum ccid3_hc_tx_states oldstate = hctx->ccid3hctx_state; 1507c657876SArnaldo Carvalho de Melo 1517c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s(%p) %-8.8s -> %s\n", 1527c657876SArnaldo Carvalho de Melo dccp_role(sk), sk, ccid3_tx_state_name(oldstate), ccid3_tx_state_name(state)); 1537c657876SArnaldo Carvalho de Melo WARN_ON(state == oldstate); 1547c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_state = state; 1557c657876SArnaldo Carvalho de Melo } 1567c657876SArnaldo Carvalho de Melo 157cef07fd6SArnaldo Carvalho de Melo static void timeval_sub(struct timeval large, struct timeval small, 158cef07fd6SArnaldo Carvalho de Melo struct timeval *result) 159cef07fd6SArnaldo Carvalho de Melo { 1607c657876SArnaldo Carvalho de Melo result->tv_sec = large.tv_sec-small.tv_sec; 1617c657876SArnaldo Carvalho de Melo if (large.tv_usec < small.tv_usec) { 1627c657876SArnaldo Carvalho de Melo (result->tv_sec)--; 163cef07fd6SArnaldo Carvalho de Melo result->tv_usec = USEC_PER_SEC + 164cef07fd6SArnaldo Carvalho de Melo large.tv_usec - small.tv_usec; 1657c657876SArnaldo Carvalho de Melo } else 1667c657876SArnaldo Carvalho de Melo result->tv_usec = large.tv_usec-small.tv_usec; 1677c657876SArnaldo Carvalho de Melo } 1687c657876SArnaldo Carvalho de Melo 169cef07fd6SArnaldo Carvalho de Melo static inline void timeval_fix(struct timeval *tv) 170cef07fd6SArnaldo Carvalho de Melo { 171cef07fd6SArnaldo Carvalho de Melo if (tv->tv_usec >= USEC_PER_SEC) { 1727c657876SArnaldo Carvalho de Melo tv->tv_sec++; 173cef07fd6SArnaldo Carvalho de Melo tv->tv_usec -= USEC_PER_SEC; 1747c657876SArnaldo Carvalho de Melo } 1757c657876SArnaldo Carvalho de Melo } 1767c657876SArnaldo Carvalho de Melo 1777c657876SArnaldo Carvalho de Melo #define CALCX_ARRSIZE 500 1787c657876SArnaldo Carvalho de Melo 1797c657876SArnaldo Carvalho de Melo #define CALCX_SPLIT 50000 1807c657876SArnaldo Carvalho de Melo /* equivalent to 0.05 */ 1817c657876SArnaldo Carvalho de Melo 1827c657876SArnaldo Carvalho de Melo static const u32 calcx_lookup[CALCX_ARRSIZE][2] = { 1837c657876SArnaldo Carvalho de Melo { 37172 , 8172 }, 1847c657876SArnaldo Carvalho de Melo { 53499 , 11567 }, 1857c657876SArnaldo Carvalho de Melo { 66664 , 14180 }, 1867c657876SArnaldo Carvalho de Melo { 78298 , 16388 }, 1877c657876SArnaldo Carvalho de Melo { 89021 , 18339 }, 1887c657876SArnaldo Carvalho de Melo { 99147 , 20108 }, 1897c657876SArnaldo Carvalho de Melo { 108858 , 21738 }, 1907c657876SArnaldo Carvalho de Melo { 118273 , 23260 }, 1917c657876SArnaldo Carvalho de Melo { 127474 , 24693 }, 1927c657876SArnaldo Carvalho de Melo { 136520 , 26052 }, 1937c657876SArnaldo Carvalho de Melo { 145456 , 27348 }, 1947c657876SArnaldo Carvalho de Melo { 154316 , 28589 }, 1957c657876SArnaldo Carvalho de Melo { 163130 , 29783 }, 1967c657876SArnaldo Carvalho de Melo { 171919 , 30935 }, 1977c657876SArnaldo Carvalho de Melo { 180704 , 32049 }, 1987c657876SArnaldo Carvalho de Melo { 189502 , 33130 }, 1997c657876SArnaldo Carvalho de Melo { 198328 , 34180 }, 2007c657876SArnaldo Carvalho de Melo { 207194 , 35202 }, 2017c657876SArnaldo Carvalho de Melo { 216114 , 36198 }, 2027c657876SArnaldo Carvalho de Melo { 225097 , 37172 }, 2037c657876SArnaldo Carvalho de Melo { 234153 , 38123 }, 2047c657876SArnaldo Carvalho de Melo { 243294 , 39055 }, 2057c657876SArnaldo Carvalho de Melo { 252527 , 39968 }, 2067c657876SArnaldo Carvalho de Melo { 261861 , 40864 }, 2077c657876SArnaldo Carvalho de Melo { 271305 , 41743 }, 2087c657876SArnaldo Carvalho de Melo { 280866 , 42607 }, 2097c657876SArnaldo Carvalho de Melo { 290553 , 43457 }, 2107c657876SArnaldo Carvalho de Melo { 300372 , 44293 }, 2117c657876SArnaldo Carvalho de Melo { 310333 , 45117 }, 2127c657876SArnaldo Carvalho de Melo { 320441 , 45929 }, 2137c657876SArnaldo Carvalho de Melo { 330705 , 46729 }, 2147c657876SArnaldo Carvalho de Melo { 341131 , 47518 }, 2157c657876SArnaldo Carvalho de Melo { 351728 , 48297 }, 2167c657876SArnaldo Carvalho de Melo { 362501 , 49066 }, 2177c657876SArnaldo Carvalho de Melo { 373460 , 49826 }, 2187c657876SArnaldo Carvalho de Melo { 384609 , 50577 }, 2197c657876SArnaldo Carvalho de Melo { 395958 , 51320 }, 2207c657876SArnaldo Carvalho de Melo { 407513 , 52054 }, 2217c657876SArnaldo Carvalho de Melo { 419281 , 52780 }, 2227c657876SArnaldo Carvalho de Melo { 431270 , 53499 }, 2237c657876SArnaldo Carvalho de Melo { 443487 , 54211 }, 2247c657876SArnaldo Carvalho de Melo { 455940 , 54916 }, 2257c657876SArnaldo Carvalho de Melo { 468635 , 55614 }, 2267c657876SArnaldo Carvalho de Melo { 481581 , 56306 }, 2277c657876SArnaldo Carvalho de Melo { 494785 , 56991 }, 2287c657876SArnaldo Carvalho de Melo { 508254 , 57671 }, 2297c657876SArnaldo Carvalho de Melo { 521996 , 58345 }, 2307c657876SArnaldo Carvalho de Melo { 536019 , 59014 }, 2317c657876SArnaldo Carvalho de Melo { 550331 , 59677 }, 2327c657876SArnaldo Carvalho de Melo { 564939 , 60335 }, 2337c657876SArnaldo Carvalho de Melo { 579851 , 60988 }, 2347c657876SArnaldo Carvalho de Melo { 595075 , 61636 }, 2357c657876SArnaldo Carvalho de Melo { 610619 , 62279 }, 2367c657876SArnaldo Carvalho de Melo { 626491 , 62918 }, 2377c657876SArnaldo Carvalho de Melo { 642700 , 63553 }, 2387c657876SArnaldo Carvalho de Melo { 659253 , 64183 }, 2397c657876SArnaldo Carvalho de Melo { 676158 , 64809 }, 2407c657876SArnaldo Carvalho de Melo { 693424 , 65431 }, 2417c657876SArnaldo Carvalho de Melo { 711060 , 66050 }, 2427c657876SArnaldo Carvalho de Melo { 729073 , 66664 }, 2437c657876SArnaldo Carvalho de Melo { 747472 , 67275 }, 2447c657876SArnaldo Carvalho de Melo { 766266 , 67882 }, 2457c657876SArnaldo Carvalho de Melo { 785464 , 68486 }, 2467c657876SArnaldo Carvalho de Melo { 805073 , 69087 }, 2477c657876SArnaldo Carvalho de Melo { 825103 , 69684 }, 2487c657876SArnaldo Carvalho de Melo { 845562 , 70278 }, 2497c657876SArnaldo Carvalho de Melo { 866460 , 70868 }, 2507c657876SArnaldo Carvalho de Melo { 887805 , 71456 }, 2517c657876SArnaldo Carvalho de Melo { 909606 , 72041 }, 2527c657876SArnaldo Carvalho de Melo { 931873 , 72623 }, 2537c657876SArnaldo Carvalho de Melo { 954614 , 73202 }, 2547c657876SArnaldo Carvalho de Melo { 977839 , 73778 }, 2557c657876SArnaldo Carvalho de Melo { 1001557 , 74352 }, 2567c657876SArnaldo Carvalho de Melo { 1025777 , 74923 }, 2577c657876SArnaldo Carvalho de Melo { 1050508 , 75492 }, 2587c657876SArnaldo Carvalho de Melo { 1075761 , 76058 }, 2597c657876SArnaldo Carvalho de Melo { 1101544 , 76621 }, 2607c657876SArnaldo Carvalho de Melo { 1127867 , 77183 }, 2617c657876SArnaldo Carvalho de Melo { 1154739 , 77741 }, 2627c657876SArnaldo Carvalho de Melo { 1182172 , 78298 }, 2637c657876SArnaldo Carvalho de Melo { 1210173 , 78852 }, 2647c657876SArnaldo Carvalho de Melo { 1238753 , 79405 }, 2657c657876SArnaldo Carvalho de Melo { 1267922 , 79955 }, 2667c657876SArnaldo Carvalho de Melo { 1297689 , 80503 }, 2677c657876SArnaldo Carvalho de Melo { 1328066 , 81049 }, 2687c657876SArnaldo Carvalho de Melo { 1359060 , 81593 }, 2697c657876SArnaldo Carvalho de Melo { 1390684 , 82135 }, 2707c657876SArnaldo Carvalho de Melo { 1422947 , 82675 }, 2717c657876SArnaldo Carvalho de Melo { 1455859 , 83213 }, 2727c657876SArnaldo Carvalho de Melo { 1489430 , 83750 }, 2737c657876SArnaldo Carvalho de Melo { 1523671 , 84284 }, 2747c657876SArnaldo Carvalho de Melo { 1558593 , 84817 }, 2757c657876SArnaldo Carvalho de Melo { 1594205 , 85348 }, 2767c657876SArnaldo Carvalho de Melo { 1630518 , 85878 }, 2777c657876SArnaldo Carvalho de Melo { 1667543 , 86406 }, 2787c657876SArnaldo Carvalho de Melo { 1705290 , 86932 }, 2797c657876SArnaldo Carvalho de Melo { 1743770 , 87457 }, 2807c657876SArnaldo Carvalho de Melo { 1782994 , 87980 }, 2817c657876SArnaldo Carvalho de Melo { 1822973 , 88501 }, 2827c657876SArnaldo Carvalho de Melo { 1863717 , 89021 }, 2837c657876SArnaldo Carvalho de Melo { 1905237 , 89540 }, 2847c657876SArnaldo Carvalho de Melo { 1947545 , 90057 }, 2857c657876SArnaldo Carvalho de Melo { 1990650 , 90573 }, 2867c657876SArnaldo Carvalho de Melo { 2034566 , 91087 }, 2877c657876SArnaldo Carvalho de Melo { 2079301 , 91600 }, 2887c657876SArnaldo Carvalho de Melo { 2124869 , 92111 }, 2897c657876SArnaldo Carvalho de Melo { 2171279 , 92622 }, 2907c657876SArnaldo Carvalho de Melo { 2218543 , 93131 }, 2917c657876SArnaldo Carvalho de Melo { 2266673 , 93639 }, 2927c657876SArnaldo Carvalho de Melo { 2315680 , 94145 }, 2937c657876SArnaldo Carvalho de Melo { 2365575 , 94650 }, 2947c657876SArnaldo Carvalho de Melo { 2416371 , 95154 }, 2957c657876SArnaldo Carvalho de Melo { 2468077 , 95657 }, 2967c657876SArnaldo Carvalho de Melo { 2520707 , 96159 }, 2977c657876SArnaldo Carvalho de Melo { 2574271 , 96660 }, 2987c657876SArnaldo Carvalho de Melo { 2628782 , 97159 }, 2997c657876SArnaldo Carvalho de Melo { 2684250 , 97658 }, 3007c657876SArnaldo Carvalho de Melo { 2740689 , 98155 }, 3017c657876SArnaldo Carvalho de Melo { 2798110 , 98651 }, 3027c657876SArnaldo Carvalho de Melo { 2856524 , 99147 }, 3037c657876SArnaldo Carvalho de Melo { 2915944 , 99641 }, 3047c657876SArnaldo Carvalho de Melo { 2976382 , 100134 }, 3057c657876SArnaldo Carvalho de Melo { 3037850 , 100626 }, 3067c657876SArnaldo Carvalho de Melo { 3100360 , 101117 }, 3077c657876SArnaldo Carvalho de Melo { 3163924 , 101608 }, 3087c657876SArnaldo Carvalho de Melo { 3228554 , 102097 }, 3097c657876SArnaldo Carvalho de Melo { 3294263 , 102586 }, 3107c657876SArnaldo Carvalho de Melo { 3361063 , 103073 }, 3117c657876SArnaldo Carvalho de Melo { 3428966 , 103560 }, 3127c657876SArnaldo Carvalho de Melo { 3497984 , 104045 }, 3137c657876SArnaldo Carvalho de Melo { 3568131 , 104530 }, 3147c657876SArnaldo Carvalho de Melo { 3639419 , 105014 }, 3157c657876SArnaldo Carvalho de Melo { 3711860 , 105498 }, 3167c657876SArnaldo Carvalho de Melo { 3785467 , 105980 }, 3177c657876SArnaldo Carvalho de Melo { 3860253 , 106462 }, 3187c657876SArnaldo Carvalho de Melo { 3936229 , 106942 }, 3197c657876SArnaldo Carvalho de Melo { 4013410 , 107422 }, 3207c657876SArnaldo Carvalho de Melo { 4091808 , 107902 }, 3217c657876SArnaldo Carvalho de Melo { 4171435 , 108380 }, 3227c657876SArnaldo Carvalho de Melo { 4252306 , 108858 }, 3237c657876SArnaldo Carvalho de Melo { 4334431 , 109335 }, 3247c657876SArnaldo Carvalho de Melo { 4417825 , 109811 }, 3257c657876SArnaldo Carvalho de Melo { 4502501 , 110287 }, 3267c657876SArnaldo Carvalho de Melo { 4588472 , 110762 }, 3277c657876SArnaldo Carvalho de Melo { 4675750 , 111236 }, 3287c657876SArnaldo Carvalho de Melo { 4764349 , 111709 }, 3297c657876SArnaldo Carvalho de Melo { 4854283 , 112182 }, 3307c657876SArnaldo Carvalho de Melo { 4945564 , 112654 }, 3317c657876SArnaldo Carvalho de Melo { 5038206 , 113126 }, 3327c657876SArnaldo Carvalho de Melo { 5132223 , 113597 }, 3337c657876SArnaldo Carvalho de Melo { 5227627 , 114067 }, 3347c657876SArnaldo Carvalho de Melo { 5324432 , 114537 }, 3357c657876SArnaldo Carvalho de Melo { 5422652 , 115006 }, 3367c657876SArnaldo Carvalho de Melo { 5522299 , 115474 }, 3377c657876SArnaldo Carvalho de Melo { 5623389 , 115942 }, 3387c657876SArnaldo Carvalho de Melo { 5725934 , 116409 }, 3397c657876SArnaldo Carvalho de Melo { 5829948 , 116876 }, 3407c657876SArnaldo Carvalho de Melo { 5935446 , 117342 }, 3417c657876SArnaldo Carvalho de Melo { 6042439 , 117808 }, 3427c657876SArnaldo Carvalho de Melo { 6150943 , 118273 }, 3437c657876SArnaldo Carvalho de Melo { 6260972 , 118738 }, 3447c657876SArnaldo Carvalho de Melo { 6372538 , 119202 }, 3457c657876SArnaldo Carvalho de Melo { 6485657 , 119665 }, 3467c657876SArnaldo Carvalho de Melo { 6600342 , 120128 }, 3477c657876SArnaldo Carvalho de Melo { 6716607 , 120591 }, 3487c657876SArnaldo Carvalho de Melo { 6834467 , 121053 }, 3497c657876SArnaldo Carvalho de Melo { 6953935 , 121514 }, 3507c657876SArnaldo Carvalho de Melo { 7075025 , 121976 }, 3517c657876SArnaldo Carvalho de Melo { 7197752 , 122436 }, 3527c657876SArnaldo Carvalho de Melo { 7322131 , 122896 }, 3537c657876SArnaldo Carvalho de Melo { 7448175 , 123356 }, 3547c657876SArnaldo Carvalho de Melo { 7575898 , 123815 }, 3557c657876SArnaldo Carvalho de Melo { 7705316 , 124274 }, 3567c657876SArnaldo Carvalho de Melo { 7836442 , 124733 }, 3577c657876SArnaldo Carvalho de Melo { 7969291 , 125191 }, 3587c657876SArnaldo Carvalho de Melo { 8103877 , 125648 }, 3597c657876SArnaldo Carvalho de Melo { 8240216 , 126105 }, 3607c657876SArnaldo Carvalho de Melo { 8378321 , 126562 }, 3617c657876SArnaldo Carvalho de Melo { 8518208 , 127018 }, 3627c657876SArnaldo Carvalho de Melo { 8659890 , 127474 }, 3637c657876SArnaldo Carvalho de Melo { 8803384 , 127930 }, 3647c657876SArnaldo Carvalho de Melo { 8948702 , 128385 }, 3657c657876SArnaldo Carvalho de Melo { 9095861 , 128840 }, 3667c657876SArnaldo Carvalho de Melo { 9244875 , 129294 }, 3677c657876SArnaldo Carvalho de Melo { 9395760 , 129748 }, 3687c657876SArnaldo Carvalho de Melo { 9548529 , 130202 }, 3697c657876SArnaldo Carvalho de Melo { 9703198 , 130655 }, 3707c657876SArnaldo Carvalho de Melo { 9859782 , 131108 }, 3717c657876SArnaldo Carvalho de Melo { 10018296 , 131561 }, 3727c657876SArnaldo Carvalho de Melo { 10178755 , 132014 }, 3737c657876SArnaldo Carvalho de Melo { 10341174 , 132466 }, 3747c657876SArnaldo Carvalho de Melo { 10505569 , 132917 }, 3757c657876SArnaldo Carvalho de Melo { 10671954 , 133369 }, 3767c657876SArnaldo Carvalho de Melo { 10840345 , 133820 }, 3777c657876SArnaldo Carvalho de Melo { 11010757 , 134271 }, 3787c657876SArnaldo Carvalho de Melo { 11183206 , 134721 }, 3797c657876SArnaldo Carvalho de Melo { 11357706 , 135171 }, 3807c657876SArnaldo Carvalho de Melo { 11534274 , 135621 }, 3817c657876SArnaldo Carvalho de Melo { 11712924 , 136071 }, 3827c657876SArnaldo Carvalho de Melo { 11893673 , 136520 }, 3837c657876SArnaldo Carvalho de Melo { 12076536 , 136969 }, 3847c657876SArnaldo Carvalho de Melo { 12261527 , 137418 }, 3857c657876SArnaldo Carvalho de Melo { 12448664 , 137867 }, 3867c657876SArnaldo Carvalho de Melo { 12637961 , 138315 }, 3877c657876SArnaldo Carvalho de Melo { 12829435 , 138763 }, 3887c657876SArnaldo Carvalho de Melo { 13023101 , 139211 }, 3897c657876SArnaldo Carvalho de Melo { 13218974 , 139658 }, 3907c657876SArnaldo Carvalho de Melo { 13417071 , 140106 }, 3917c657876SArnaldo Carvalho de Melo { 13617407 , 140553 }, 3927c657876SArnaldo Carvalho de Melo { 13819999 , 140999 }, 3937c657876SArnaldo Carvalho de Melo { 14024862 , 141446 }, 3947c657876SArnaldo Carvalho de Melo { 14232012 , 141892 }, 3957c657876SArnaldo Carvalho de Melo { 14441465 , 142339 }, 3967c657876SArnaldo Carvalho de Melo { 14653238 , 142785 }, 3977c657876SArnaldo Carvalho de Melo { 14867346 , 143230 }, 3987c657876SArnaldo Carvalho de Melo { 15083805 , 143676 }, 3997c657876SArnaldo Carvalho de Melo { 15302632 , 144121 }, 4007c657876SArnaldo Carvalho de Melo { 15523842 , 144566 }, 4017c657876SArnaldo Carvalho de Melo { 15747453 , 145011 }, 4027c657876SArnaldo Carvalho de Melo { 15973479 , 145456 }, 4037c657876SArnaldo Carvalho de Melo { 16201939 , 145900 }, 4047c657876SArnaldo Carvalho de Melo { 16432847 , 146345 }, 4057c657876SArnaldo Carvalho de Melo { 16666221 , 146789 }, 4067c657876SArnaldo Carvalho de Melo { 16902076 , 147233 }, 4077c657876SArnaldo Carvalho de Melo { 17140429 , 147677 }, 4087c657876SArnaldo Carvalho de Melo { 17381297 , 148121 }, 4097c657876SArnaldo Carvalho de Melo { 17624696 , 148564 }, 4107c657876SArnaldo Carvalho de Melo { 17870643 , 149007 }, 4117c657876SArnaldo Carvalho de Melo { 18119154 , 149451 }, 4127c657876SArnaldo Carvalho de Melo { 18370247 , 149894 }, 4137c657876SArnaldo Carvalho de Melo { 18623936 , 150336 }, 4147c657876SArnaldo Carvalho de Melo { 18880241 , 150779 }, 4157c657876SArnaldo Carvalho de Melo { 19139176 , 151222 }, 4167c657876SArnaldo Carvalho de Melo { 19400759 , 151664 }, 4177c657876SArnaldo Carvalho de Melo { 19665007 , 152107 }, 4187c657876SArnaldo Carvalho de Melo { 19931936 , 152549 }, 4197c657876SArnaldo Carvalho de Melo { 20201564 , 152991 }, 4207c657876SArnaldo Carvalho de Melo { 20473907 , 153433 }, 4217c657876SArnaldo Carvalho de Melo { 20748982 , 153875 }, 4227c657876SArnaldo Carvalho de Melo { 21026807 , 154316 }, 4237c657876SArnaldo Carvalho de Melo { 21307399 , 154758 }, 4247c657876SArnaldo Carvalho de Melo { 21590773 , 155199 }, 4257c657876SArnaldo Carvalho de Melo { 21876949 , 155641 }, 4267c657876SArnaldo Carvalho de Melo { 22165941 , 156082 }, 4277c657876SArnaldo Carvalho de Melo { 22457769 , 156523 }, 4287c657876SArnaldo Carvalho de Melo { 22752449 , 156964 }, 4297c657876SArnaldo Carvalho de Melo { 23049999 , 157405 }, 4307c657876SArnaldo Carvalho de Melo { 23350435 , 157846 }, 4317c657876SArnaldo Carvalho de Melo { 23653774 , 158287 }, 4327c657876SArnaldo Carvalho de Melo { 23960036 , 158727 }, 4337c657876SArnaldo Carvalho de Melo { 24269236 , 159168 }, 4347c657876SArnaldo Carvalho de Melo { 24581392 , 159608 }, 4357c657876SArnaldo Carvalho de Melo { 24896521 , 160049 }, 4367c657876SArnaldo Carvalho de Melo { 25214642 , 160489 }, 4377c657876SArnaldo Carvalho de Melo { 25535772 , 160929 }, 4387c657876SArnaldo Carvalho de Melo { 25859927 , 161370 }, 4397c657876SArnaldo Carvalho de Melo { 26187127 , 161810 }, 4407c657876SArnaldo Carvalho de Melo { 26517388 , 162250 }, 4417c657876SArnaldo Carvalho de Melo { 26850728 , 162690 }, 4427c657876SArnaldo Carvalho de Melo { 27187165 , 163130 }, 4437c657876SArnaldo Carvalho de Melo { 27526716 , 163569 }, 4447c657876SArnaldo Carvalho de Melo { 27869400 , 164009 }, 4457c657876SArnaldo Carvalho de Melo { 28215234 , 164449 }, 4467c657876SArnaldo Carvalho de Melo { 28564236 , 164889 }, 4477c657876SArnaldo Carvalho de Melo { 28916423 , 165328 }, 4487c657876SArnaldo Carvalho de Melo { 29271815 , 165768 }, 4497c657876SArnaldo Carvalho de Melo { 29630428 , 166208 }, 4507c657876SArnaldo Carvalho de Melo { 29992281 , 166647 }, 4517c657876SArnaldo Carvalho de Melo { 30357392 , 167087 }, 4527c657876SArnaldo Carvalho de Melo { 30725779 , 167526 }, 4537c657876SArnaldo Carvalho de Melo { 31097459 , 167965 }, 4547c657876SArnaldo Carvalho de Melo { 31472452 , 168405 }, 4557c657876SArnaldo Carvalho de Melo { 31850774 , 168844 }, 4567c657876SArnaldo Carvalho de Melo { 32232445 , 169283 }, 4577c657876SArnaldo Carvalho de Melo { 32617482 , 169723 }, 4587c657876SArnaldo Carvalho de Melo { 33005904 , 170162 }, 4597c657876SArnaldo Carvalho de Melo { 33397730 , 170601 }, 4607c657876SArnaldo Carvalho de Melo { 33792976 , 171041 }, 4617c657876SArnaldo Carvalho de Melo { 34191663 , 171480 }, 4627c657876SArnaldo Carvalho de Melo { 34593807 , 171919 }, 4637c657876SArnaldo Carvalho de Melo { 34999428 , 172358 }, 4647c657876SArnaldo Carvalho de Melo { 35408544 , 172797 }, 4657c657876SArnaldo Carvalho de Melo { 35821174 , 173237 }, 4667c657876SArnaldo Carvalho de Melo { 36237335 , 173676 }, 4677c657876SArnaldo Carvalho de Melo { 36657047 , 174115 }, 4687c657876SArnaldo Carvalho de Melo { 37080329 , 174554 }, 4697c657876SArnaldo Carvalho de Melo { 37507197 , 174993 }, 4707c657876SArnaldo Carvalho de Melo { 37937673 , 175433 }, 4717c657876SArnaldo Carvalho de Melo { 38371773 , 175872 }, 4727c657876SArnaldo Carvalho de Melo { 38809517 , 176311 }, 4737c657876SArnaldo Carvalho de Melo { 39250924 , 176750 }, 4747c657876SArnaldo Carvalho de Melo { 39696012 , 177190 }, 4757c657876SArnaldo Carvalho de Melo { 40144800 , 177629 }, 4767c657876SArnaldo Carvalho de Melo { 40597308 , 178068 }, 4777c657876SArnaldo Carvalho de Melo { 41053553 , 178507 }, 4787c657876SArnaldo Carvalho de Melo { 41513554 , 178947 }, 4797c657876SArnaldo Carvalho de Melo { 41977332 , 179386 }, 4807c657876SArnaldo Carvalho de Melo { 42444904 , 179825 }, 4817c657876SArnaldo Carvalho de Melo { 42916290 , 180265 }, 4827c657876SArnaldo Carvalho de Melo { 43391509 , 180704 }, 4837c657876SArnaldo Carvalho de Melo { 43870579 , 181144 }, 4847c657876SArnaldo Carvalho de Melo { 44353520 , 181583 }, 4857c657876SArnaldo Carvalho de Melo { 44840352 , 182023 }, 4867c657876SArnaldo Carvalho de Melo { 45331092 , 182462 }, 4877c657876SArnaldo Carvalho de Melo { 45825761 , 182902 }, 4887c657876SArnaldo Carvalho de Melo { 46324378 , 183342 }, 4897c657876SArnaldo Carvalho de Melo { 46826961 , 183781 }, 4907c657876SArnaldo Carvalho de Melo { 47333531 , 184221 }, 4917c657876SArnaldo Carvalho de Melo { 47844106 , 184661 }, 4927c657876SArnaldo Carvalho de Melo { 48358706 , 185101 }, 4937c657876SArnaldo Carvalho de Melo { 48877350 , 185541 }, 4947c657876SArnaldo Carvalho de Melo { 49400058 , 185981 }, 4957c657876SArnaldo Carvalho de Melo { 49926849 , 186421 }, 4967c657876SArnaldo Carvalho de Melo { 50457743 , 186861 }, 4977c657876SArnaldo Carvalho de Melo { 50992759 , 187301 }, 4987c657876SArnaldo Carvalho de Melo { 51531916 , 187741 }, 4997c657876SArnaldo Carvalho de Melo { 52075235 , 188181 }, 5007c657876SArnaldo Carvalho de Melo { 52622735 , 188622 }, 5017c657876SArnaldo Carvalho de Melo { 53174435 , 189062 }, 5027c657876SArnaldo Carvalho de Melo { 53730355 , 189502 }, 5037c657876SArnaldo Carvalho de Melo { 54290515 , 189943 }, 5047c657876SArnaldo Carvalho de Melo { 54854935 , 190383 }, 5057c657876SArnaldo Carvalho de Melo { 55423634 , 190824 }, 5067c657876SArnaldo Carvalho de Melo { 55996633 , 191265 }, 5077c657876SArnaldo Carvalho de Melo { 56573950 , 191706 }, 5087c657876SArnaldo Carvalho de Melo { 57155606 , 192146 }, 5097c657876SArnaldo Carvalho de Melo { 57741621 , 192587 }, 5107c657876SArnaldo Carvalho de Melo { 58332014 , 193028 }, 5117c657876SArnaldo Carvalho de Melo { 58926806 , 193470 }, 5127c657876SArnaldo Carvalho de Melo { 59526017 , 193911 }, 5137c657876SArnaldo Carvalho de Melo { 60129666 , 194352 }, 5147c657876SArnaldo Carvalho de Melo { 60737774 , 194793 }, 5157c657876SArnaldo Carvalho de Melo { 61350361 , 195235 }, 5167c657876SArnaldo Carvalho de Melo { 61967446 , 195677 }, 5177c657876SArnaldo Carvalho de Melo { 62589050 , 196118 }, 5187c657876SArnaldo Carvalho de Melo { 63215194 , 196560 }, 5197c657876SArnaldo Carvalho de Melo { 63845897 , 197002 }, 5207c657876SArnaldo Carvalho de Melo { 64481179 , 197444 }, 5217c657876SArnaldo Carvalho de Melo { 65121061 , 197886 }, 5227c657876SArnaldo Carvalho de Melo { 65765563 , 198328 }, 5237c657876SArnaldo Carvalho de Melo { 66414705 , 198770 }, 5247c657876SArnaldo Carvalho de Melo { 67068508 , 199213 }, 5257c657876SArnaldo Carvalho de Melo { 67726992 , 199655 }, 5267c657876SArnaldo Carvalho de Melo { 68390177 , 200098 }, 5277c657876SArnaldo Carvalho de Melo { 69058085 , 200540 }, 5287c657876SArnaldo Carvalho de Melo { 69730735 , 200983 }, 5297c657876SArnaldo Carvalho de Melo { 70408147 , 201426 }, 5307c657876SArnaldo Carvalho de Melo { 71090343 , 201869 }, 5317c657876SArnaldo Carvalho de Melo { 71777343 , 202312 }, 5327c657876SArnaldo Carvalho de Melo { 72469168 , 202755 }, 5337c657876SArnaldo Carvalho de Melo { 73165837 , 203199 }, 5347c657876SArnaldo Carvalho de Melo { 73867373 , 203642 }, 5357c657876SArnaldo Carvalho de Melo { 74573795 , 204086 }, 5367c657876SArnaldo Carvalho de Melo { 75285124 , 204529 }, 5377c657876SArnaldo Carvalho de Melo { 76001380 , 204973 }, 5387c657876SArnaldo Carvalho de Melo { 76722586 , 205417 }, 5397c657876SArnaldo Carvalho de Melo { 77448761 , 205861 }, 5407c657876SArnaldo Carvalho de Melo { 78179926 , 206306 }, 5417c657876SArnaldo Carvalho de Melo { 78916102 , 206750 }, 5427c657876SArnaldo Carvalho de Melo { 79657310 , 207194 }, 5437c657876SArnaldo Carvalho de Melo { 80403571 , 207639 }, 5447c657876SArnaldo Carvalho de Melo { 81154906 , 208084 }, 5457c657876SArnaldo Carvalho de Melo { 81911335 , 208529 }, 5467c657876SArnaldo Carvalho de Melo { 82672880 , 208974 }, 5477c657876SArnaldo Carvalho de Melo { 83439562 , 209419 }, 5487c657876SArnaldo Carvalho de Melo { 84211402 , 209864 }, 5497c657876SArnaldo Carvalho de Melo { 84988421 , 210309 }, 5507c657876SArnaldo Carvalho de Melo { 85770640 , 210755 }, 5517c657876SArnaldo Carvalho de Melo { 86558080 , 211201 }, 5527c657876SArnaldo Carvalho de Melo { 87350762 , 211647 }, 5537c657876SArnaldo Carvalho de Melo { 88148708 , 212093 }, 5547c657876SArnaldo Carvalho de Melo { 88951938 , 212539 }, 5557c657876SArnaldo Carvalho de Melo { 89760475 , 212985 }, 5567c657876SArnaldo Carvalho de Melo { 90574339 , 213432 }, 5577c657876SArnaldo Carvalho de Melo { 91393551 , 213878 }, 5587c657876SArnaldo Carvalho de Melo { 92218133 , 214325 }, 5597c657876SArnaldo Carvalho de Melo { 93048107 , 214772 }, 5607c657876SArnaldo Carvalho de Melo { 93883493 , 215219 }, 5617c657876SArnaldo Carvalho de Melo { 94724314 , 215666 }, 5627c657876SArnaldo Carvalho de Melo { 95570590 , 216114 }, 5637c657876SArnaldo Carvalho de Melo { 96422343 , 216561 }, 5647c657876SArnaldo Carvalho de Melo { 97279594 , 217009 }, 5657c657876SArnaldo Carvalho de Melo { 98142366 , 217457 }, 5667c657876SArnaldo Carvalho de Melo { 99010679 , 217905 }, 5677c657876SArnaldo Carvalho de Melo { 99884556 , 218353 }, 5687c657876SArnaldo Carvalho de Melo { 100764018 , 218801 }, 5697c657876SArnaldo Carvalho de Melo { 101649086 , 219250 }, 5707c657876SArnaldo Carvalho de Melo { 102539782 , 219698 }, 5717c657876SArnaldo Carvalho de Melo { 103436128 , 220147 }, 5727c657876SArnaldo Carvalho de Melo { 104338146 , 220596 }, 5737c657876SArnaldo Carvalho de Melo { 105245857 , 221046 }, 5747c657876SArnaldo Carvalho de Melo { 106159284 , 221495 }, 5757c657876SArnaldo Carvalho de Melo { 107078448 , 221945 }, 5767c657876SArnaldo Carvalho de Melo { 108003370 , 222394 }, 5777c657876SArnaldo Carvalho de Melo { 108934074 , 222844 }, 5787c657876SArnaldo Carvalho de Melo { 109870580 , 223294 }, 5797c657876SArnaldo Carvalho de Melo { 110812910 , 223745 }, 5807c657876SArnaldo Carvalho de Melo { 111761087 , 224195 }, 5817c657876SArnaldo Carvalho de Melo { 112715133 , 224646 }, 5827c657876SArnaldo Carvalho de Melo { 113675069 , 225097 }, 5837c657876SArnaldo Carvalho de Melo { 114640918 , 225548 }, 5847c657876SArnaldo Carvalho de Melo { 115612702 , 225999 }, 5857c657876SArnaldo Carvalho de Melo { 116590442 , 226450 }, 5867c657876SArnaldo Carvalho de Melo { 117574162 , 226902 }, 5877c657876SArnaldo Carvalho de Melo { 118563882 , 227353 }, 5887c657876SArnaldo Carvalho de Melo { 119559626 , 227805 }, 5897c657876SArnaldo Carvalho de Melo { 120561415 , 228258 }, 5907c657876SArnaldo Carvalho de Melo { 121569272 , 228710 }, 5917c657876SArnaldo Carvalho de Melo { 122583219 , 229162 }, 5927c657876SArnaldo Carvalho de Melo { 123603278 , 229615 }, 5937c657876SArnaldo Carvalho de Melo { 124629471 , 230068 }, 5947c657876SArnaldo Carvalho de Melo { 125661822 , 230521 }, 5957c657876SArnaldo Carvalho de Melo { 126700352 , 230974 }, 5967c657876SArnaldo Carvalho de Melo { 127745083 , 231428 }, 5977c657876SArnaldo Carvalho de Melo { 128796039 , 231882 }, 5987c657876SArnaldo Carvalho de Melo { 129853241 , 232336 }, 5997c657876SArnaldo Carvalho de Melo { 130916713 , 232790 }, 6007c657876SArnaldo Carvalho de Melo { 131986475 , 233244 }, 6017c657876SArnaldo Carvalho de Melo { 133062553 , 233699 }, 6027c657876SArnaldo Carvalho de Melo { 134144966 , 234153 }, 6037c657876SArnaldo Carvalho de Melo { 135233739 , 234608 }, 6047c657876SArnaldo Carvalho de Melo { 136328894 , 235064 }, 6057c657876SArnaldo Carvalho de Melo { 137430453 , 235519 }, 6067c657876SArnaldo Carvalho de Melo { 138538440 , 235975 }, 6077c657876SArnaldo Carvalho de Melo { 139652876 , 236430 }, 6087c657876SArnaldo Carvalho de Melo { 140773786 , 236886 }, 6097c657876SArnaldo Carvalho de Melo { 141901190 , 237343 }, 6107c657876SArnaldo Carvalho de Melo { 143035113 , 237799 }, 6117c657876SArnaldo Carvalho de Melo { 144175576 , 238256 }, 6127c657876SArnaldo Carvalho de Melo { 145322604 , 238713 }, 6137c657876SArnaldo Carvalho de Melo { 146476218 , 239170 }, 6147c657876SArnaldo Carvalho de Melo { 147636442 , 239627 }, 6157c657876SArnaldo Carvalho de Melo { 148803298 , 240085 }, 6167c657876SArnaldo Carvalho de Melo { 149976809 , 240542 }, 6177c657876SArnaldo Carvalho de Melo { 151156999 , 241000 }, 6187c657876SArnaldo Carvalho de Melo { 152343890 , 241459 }, 6197c657876SArnaldo Carvalho de Melo { 153537506 , 241917 }, 6207c657876SArnaldo Carvalho de Melo { 154737869 , 242376 }, 6217c657876SArnaldo Carvalho de Melo { 155945002 , 242835 }, 6227c657876SArnaldo Carvalho de Melo { 157158929 , 243294 }, 6237c657876SArnaldo Carvalho de Melo { 158379673 , 243753 }, 6247c657876SArnaldo Carvalho de Melo { 159607257 , 244213 }, 6257c657876SArnaldo Carvalho de Melo { 160841704 , 244673 }, 6267c657876SArnaldo Carvalho de Melo { 162083037 , 245133 }, 6277c657876SArnaldo Carvalho de Melo { 163331279 , 245593 }, 6287c657876SArnaldo Carvalho de Melo { 164586455 , 246054 }, 6297c657876SArnaldo Carvalho de Melo { 165848586 , 246514 }, 6307c657876SArnaldo Carvalho de Melo { 167117696 , 246975 }, 6317c657876SArnaldo Carvalho de Melo { 168393810 , 247437 }, 6327c657876SArnaldo Carvalho de Melo { 169676949 , 247898 }, 6337c657876SArnaldo Carvalho de Melo { 170967138 , 248360 }, 6347c657876SArnaldo Carvalho de Melo { 172264399 , 248822 }, 6357c657876SArnaldo Carvalho de Melo { 173568757 , 249284 }, 6367c657876SArnaldo Carvalho de Melo { 174880235 , 249747 }, 6377c657876SArnaldo Carvalho de Melo { 176198856 , 250209 }, 6387c657876SArnaldo Carvalho de Melo { 177524643 , 250672 }, 6397c657876SArnaldo Carvalho de Melo { 178857621 , 251136 }, 6407c657876SArnaldo Carvalho de Melo { 180197813 , 251599 }, 6417c657876SArnaldo Carvalho de Melo { 181545242 , 252063 }, 6427c657876SArnaldo Carvalho de Melo { 182899933 , 252527 }, 6437c657876SArnaldo Carvalho de Melo { 184261908 , 252991 }, 6447c657876SArnaldo Carvalho de Melo { 185631191 , 253456 }, 6457c657876SArnaldo Carvalho de Melo { 187007807 , 253920 }, 6467c657876SArnaldo Carvalho de Melo { 188391778 , 254385 }, 6477c657876SArnaldo Carvalho de Melo { 189783129 , 254851 }, 6487c657876SArnaldo Carvalho de Melo { 191181884 , 255316 }, 6497c657876SArnaldo Carvalho de Melo { 192588065 , 255782 }, 6507c657876SArnaldo Carvalho de Melo { 194001698 , 256248 }, 6517c657876SArnaldo Carvalho de Melo { 195422805 , 256714 }, 6527c657876SArnaldo Carvalho de Melo { 196851411 , 257181 }, 6537c657876SArnaldo Carvalho de Melo { 198287540 , 257648 }, 6547c657876SArnaldo Carvalho de Melo { 199731215 , 258115 }, 6557c657876SArnaldo Carvalho de Melo { 201182461 , 258582 }, 6567c657876SArnaldo Carvalho de Melo { 202641302 , 259050 }, 6577c657876SArnaldo Carvalho de Melo { 204107760 , 259518 }, 6587c657876SArnaldo Carvalho de Melo { 205581862 , 259986 }, 6597c657876SArnaldo Carvalho de Melo { 207063630 , 260454 }, 6607c657876SArnaldo Carvalho de Melo { 208553088 , 260923 }, 6617c657876SArnaldo Carvalho de Melo { 210050262 , 261392 }, 6627c657876SArnaldo Carvalho de Melo { 211555174 , 261861 }, 6637c657876SArnaldo Carvalho de Melo { 213067849 , 262331 }, 6647c657876SArnaldo Carvalho de Melo { 214588312 , 262800 }, 6657c657876SArnaldo Carvalho de Melo { 216116586 , 263270 }, 6667c657876SArnaldo Carvalho de Melo { 217652696 , 263741 }, 6677c657876SArnaldo Carvalho de Melo { 219196666 , 264211 }, 6687c657876SArnaldo Carvalho de Melo { 220748520 , 264682 }, 6697c657876SArnaldo Carvalho de Melo { 222308282 , 265153 }, 6707c657876SArnaldo Carvalho de Melo { 223875978 , 265625 }, 6717c657876SArnaldo Carvalho de Melo { 225451630 , 266097 }, 6727c657876SArnaldo Carvalho de Melo { 227035265 , 266569 }, 6737c657876SArnaldo Carvalho de Melo { 228626905 , 267041 }, 6747c657876SArnaldo Carvalho de Melo { 230226576 , 267514 }, 6757c657876SArnaldo Carvalho de Melo { 231834302 , 267986 }, 6767c657876SArnaldo Carvalho de Melo { 233450107 , 268460 }, 6777c657876SArnaldo Carvalho de Melo { 235074016 , 268933 }, 6787c657876SArnaldo Carvalho de Melo { 236706054 , 269407 }, 6797c657876SArnaldo Carvalho de Melo { 238346244 , 269881 }, 6807c657876SArnaldo Carvalho de Melo { 239994613 , 270355 }, 6817c657876SArnaldo Carvalho de Melo { 241651183 , 270830 }, 6827c657876SArnaldo Carvalho de Melo { 243315981 , 271305 } 6837c657876SArnaldo Carvalho de Melo }; 6847c657876SArnaldo Carvalho de Melo 6857c657876SArnaldo Carvalho de Melo /* Calculate the send rate as per section 3.1 of RFC3448 6867c657876SArnaldo Carvalho de Melo 6877c657876SArnaldo Carvalho de Melo Returns send rate in bytes per second 6887c657876SArnaldo Carvalho de Melo 6897c657876SArnaldo Carvalho de Melo Integer maths and lookups are used as not allowed floating point in kernel 6907c657876SArnaldo Carvalho de Melo 6917c657876SArnaldo Carvalho de Melo The function for Xcalc as per section 3.1 of RFC3448 is: 6927c657876SArnaldo Carvalho de Melo 6937c657876SArnaldo Carvalho de Melo X = s 6947c657876SArnaldo Carvalho de Melo ------------------------------------------------------------- 6957c657876SArnaldo Carvalho de Melo R*sqrt(2*b*p/3) + (t_RTO * (3*sqrt(3*b*p/8) * p * (1+32*p^2))) 6967c657876SArnaldo Carvalho de Melo 6977c657876SArnaldo Carvalho de Melo where 6987c657876SArnaldo Carvalho de Melo X is the trasmit rate in bytes/second 6997c657876SArnaldo Carvalho de Melo s is the packet size in bytes 7007c657876SArnaldo Carvalho de Melo R is the round trip time in seconds 7017c657876SArnaldo Carvalho de Melo p is the loss event rate, between 0 and 1.0, of the number of loss events 7027c657876SArnaldo Carvalho de Melo as a fraction of the number of packets transmitted 7037c657876SArnaldo Carvalho de Melo t_RTO is the TCP retransmission timeout value in seconds 7047c657876SArnaldo Carvalho de Melo b is the number of packets acknowledged by a single TCP acknowledgement 7057c657876SArnaldo Carvalho de Melo 7067c657876SArnaldo Carvalho de Melo we can assume that b = 1 and t_RTO is 4 * R. With this the equation becomes: 7077c657876SArnaldo Carvalho de Melo 7087c657876SArnaldo Carvalho de Melo X = s 7097c657876SArnaldo Carvalho de Melo ----------------------------------------------------------------------- 7107c657876SArnaldo Carvalho de Melo R * sqrt(2 * p / 3) + (12 * R * (sqrt(3 * p / 8) * p * (1 + 32 * p^2))) 7117c657876SArnaldo Carvalho de Melo 7127c657876SArnaldo Carvalho de Melo 7137c657876SArnaldo Carvalho de Melo which we can break down into: 7147c657876SArnaldo Carvalho de Melo 7157c657876SArnaldo Carvalho de Melo X = s 7167c657876SArnaldo Carvalho de Melo -------- 7177c657876SArnaldo Carvalho de Melo R * f(p) 7187c657876SArnaldo Carvalho de Melo 7197c657876SArnaldo Carvalho de Melo where f(p) = sqrt(2 * p / 3) + (12 * sqrt(3 * p / 8) * p * (1 + 32 * p * p)) 7207c657876SArnaldo Carvalho de Melo 7217c657876SArnaldo Carvalho de Melo Function parameters: 7227c657876SArnaldo Carvalho de Melo s - bytes 7237c657876SArnaldo Carvalho de Melo R - RTT in usecs 7247c657876SArnaldo Carvalho de Melo p - loss rate (decimal fraction multiplied by 1,000,000) 7257c657876SArnaldo Carvalho de Melo 7267c657876SArnaldo Carvalho de Melo Returns Xcalc in bytes per second 7277c657876SArnaldo Carvalho de Melo 7287c657876SArnaldo Carvalho de Melo DON'T alter this code unless you run test cases against it as the code 7297c657876SArnaldo Carvalho de Melo has been manipulated to stop underflow/overlow. 7307c657876SArnaldo Carvalho de Melo 7317c657876SArnaldo Carvalho de Melo */ 7327c657876SArnaldo Carvalho de Melo static u32 ccid3_calc_x(u16 s, u32 R, u32 p) 7337c657876SArnaldo Carvalho de Melo { 7347c657876SArnaldo Carvalho de Melo int index; 7357c657876SArnaldo Carvalho de Melo u32 f; 7367c657876SArnaldo Carvalho de Melo u64 tmp1, tmp2; 7377c657876SArnaldo Carvalho de Melo 7387c657876SArnaldo Carvalho de Melo if (p < CALCX_SPLIT) 7397c657876SArnaldo Carvalho de Melo index = (p / (CALCX_SPLIT / CALCX_ARRSIZE)) - 1; 7407c657876SArnaldo Carvalho de Melo else 7417c657876SArnaldo Carvalho de Melo index = (p / (1000000 / CALCX_ARRSIZE)) - 1; 7427c657876SArnaldo Carvalho de Melo 7437c657876SArnaldo Carvalho de Melo if (index < 0) 7447c657876SArnaldo Carvalho de Melo /* p should be 0 unless there is a bug in my code */ 7457c657876SArnaldo Carvalho de Melo index = 0; 7467c657876SArnaldo Carvalho de Melo 7477c657876SArnaldo Carvalho de Melo if (R == 0) 7487c657876SArnaldo Carvalho de Melo R = 1; /* RTT can't be zero or else divide by zero */ 7497c657876SArnaldo Carvalho de Melo 7507c657876SArnaldo Carvalho de Melo BUG_ON(index >= CALCX_ARRSIZE); 7517c657876SArnaldo Carvalho de Melo 7527c657876SArnaldo Carvalho de Melo if (p >= CALCX_SPLIT) 7537c657876SArnaldo Carvalho de Melo f = calcx_lookup[index][0]; 7547c657876SArnaldo Carvalho de Melo else 7557c657876SArnaldo Carvalho de Melo f = calcx_lookup[index][1]; 7567c657876SArnaldo Carvalho de Melo 7577c657876SArnaldo Carvalho de Melo tmp1 = ((u64)s * 100000000); 7587c657876SArnaldo Carvalho de Melo tmp2 = ((u64)R * (u64)f); 7597c657876SArnaldo Carvalho de Melo do_div(tmp2,10000); 7607c657876SArnaldo Carvalho de Melo do_div(tmp1,tmp2); 7617c657876SArnaldo Carvalho de Melo /* don't alter above math unless you test due to overflow on 32 bit */ 7627c657876SArnaldo Carvalho de Melo 7637c657876SArnaldo Carvalho de Melo return (u32)tmp1; 7647c657876SArnaldo Carvalho de Melo } 7657c657876SArnaldo Carvalho de Melo 7667c657876SArnaldo Carvalho de Melo /* Calculate new t_ipi (inter packet interval) by t_ipi = s / X_inst */ 7677c657876SArnaldo Carvalho de Melo static inline void ccid3_calc_new_t_ipi(struct ccid3_hc_tx_sock *hctx) 7687c657876SArnaldo Carvalho de Melo { 7697c657876SArnaldo Carvalho de Melo if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK) 7707c657876SArnaldo Carvalho de Melo return; 7717c657876SArnaldo Carvalho de Melo /* if no feedback spec says t_ipi is 1 second (set elsewhere and then 7727c657876SArnaldo Carvalho de Melo * doubles after every no feedback timer (separate function) */ 7737c657876SArnaldo Carvalho de Melo 7747c657876SArnaldo Carvalho de Melo if (hctx->ccid3hctx_x < 10) { 7757c657876SArnaldo Carvalho de Melo ccid3_pr_debug("ccid3_calc_new_t_ipi - ccid3hctx_x < 10\n"); 7767c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_x = 10; 7777c657876SArnaldo Carvalho de Melo } 7787c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_t_ipi = (hctx->ccid3hctx_s * 100000) 7797c657876SArnaldo Carvalho de Melo / (hctx->ccid3hctx_x / 10); 7807c657876SArnaldo Carvalho de Melo /* reason for above maths with 10 in there is to avoid 32 bit 7817c657876SArnaldo Carvalho de Melo * overflow for jumbo packets */ 7827c657876SArnaldo Carvalho de Melo 7837c657876SArnaldo Carvalho de Melo } 7847c657876SArnaldo Carvalho de Melo 7857c657876SArnaldo Carvalho de Melo /* Calculate new delta by delta = min(t_ipi / 2, t_gran / 2) */ 7867c657876SArnaldo Carvalho de Melo static inline void ccid3_calc_new_delta(struct ccid3_hc_tx_sock *hctx) 7877c657876SArnaldo Carvalho de Melo { 7887c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_delta = min_t(u32, hctx->ccid3hctx_t_ipi / 2, TFRC_OPSYS_HALF_TIME_GRAN); 7897c657876SArnaldo Carvalho de Melo 7907c657876SArnaldo Carvalho de Melo } 7917c657876SArnaldo Carvalho de Melo 7927c657876SArnaldo Carvalho de Melo /* 7937c657876SArnaldo Carvalho de Melo * Update X by 7947c657876SArnaldo Carvalho de Melo * If (p > 0) 7957c657876SArnaldo Carvalho de Melo * x_calc = calcX(s, R, p); 7967c657876SArnaldo Carvalho de Melo * X = max(min(X_calc, 2 * X_recv), s / t_mbi); 7977c657876SArnaldo Carvalho de Melo * Else 7987c657876SArnaldo Carvalho de Melo * If (now - tld >= R) 7997c657876SArnaldo Carvalho de Melo * X = max(min(2 * X, 2 * X_recv), s / R); 8007c657876SArnaldo Carvalho de Melo * tld = now; 8017c657876SArnaldo Carvalho de Melo */ 8027c657876SArnaldo Carvalho de Melo static void ccid3_hc_tx_update_x(struct sock *sk) 8037c657876SArnaldo Carvalho de Melo { 8047c657876SArnaldo Carvalho de Melo struct dccp_sock *dp = dccp_sk(sk); 8057c657876SArnaldo Carvalho de Melo struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private; 8067c657876SArnaldo Carvalho de Melo 8077c657876SArnaldo Carvalho de Melo if (hctx->ccid3hctx_p >= TFRC_SMALLEST_P) { /* to avoid large error in calcX */ 8087c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_x_calc = ccid3_calc_x(hctx->ccid3hctx_s, 8097c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_rtt, 8107c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_p); 8117c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_x = max_t(u32, min_t(u32, hctx->ccid3hctx_x_calc, 2 * hctx->ccid3hctx_x_recv), 8127c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_s / TFRC_MAX_BACK_OFF_TIME); 8137c657876SArnaldo Carvalho de Melo } else if (now_delta(hctx->ccid3hctx_t_ld) >= hctx->ccid3hctx_rtt) { 8147c657876SArnaldo Carvalho de Melo u32 rtt = hctx->ccid3hctx_rtt; 8157c657876SArnaldo Carvalho de Melo if (rtt < 10) { 8167c657876SArnaldo Carvalho de Melo rtt = 10; 8177c657876SArnaldo Carvalho de Melo } /* avoid divide by zero below */ 8187c657876SArnaldo Carvalho de Melo 8197c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_x = max_t(u32, min_t(u32, 2 * hctx->ccid3hctx_x_recv, 2 * hctx->ccid3hctx_x), 8207c657876SArnaldo Carvalho de Melo (hctx->ccid3hctx_s * 100000) / (rtt / 10)); 8217c657876SArnaldo Carvalho de Melo /* Using 100000 and 10 to avoid 32 bit overflow for jumbo frames */ 8227c657876SArnaldo Carvalho de Melo do_gettimeofday(&hctx->ccid3hctx_t_ld); 8237c657876SArnaldo Carvalho de Melo } 8247c657876SArnaldo Carvalho de Melo 8257c657876SArnaldo Carvalho de Melo if (hctx->ccid3hctx_x == 0) { 8267c657876SArnaldo Carvalho de Melo ccid3_pr_debug("ccid3hctx_x = 0!\n"); 8277c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_x = 1; 8287c657876SArnaldo Carvalho de Melo } 8297c657876SArnaldo Carvalho de Melo } 8307c657876SArnaldo Carvalho de Melo 8317c657876SArnaldo Carvalho de Melo static void ccid3_hc_tx_no_feedback_timer(unsigned long data) 8327c657876SArnaldo Carvalho de Melo { 8337c657876SArnaldo Carvalho de Melo struct sock *sk = (struct sock *)data; 8347c657876SArnaldo Carvalho de Melo struct dccp_sock *dp = dccp_sk(sk); 8357c657876SArnaldo Carvalho de Melo unsigned long next_tmout = 0; 8367c657876SArnaldo Carvalho de Melo struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private; 8377c657876SArnaldo Carvalho de Melo u32 rtt; 8387c657876SArnaldo Carvalho de Melo 8397c657876SArnaldo Carvalho de Melo bh_lock_sock(sk); 8407c657876SArnaldo Carvalho de Melo if (sock_owned_by_user(sk)) { 8417c657876SArnaldo Carvalho de Melo /* Try again later. */ 8427c657876SArnaldo Carvalho de Melo /* XXX: set some sensible MIB */ 8437c657876SArnaldo Carvalho de Melo sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, jiffies + HZ / 5); 8447c657876SArnaldo Carvalho de Melo goto out; 8457c657876SArnaldo Carvalho de Melo } 8467c657876SArnaldo Carvalho de Melo 8477c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p, state=%s\n", dccp_role(sk), sk, 8487c657876SArnaldo Carvalho de Melo ccid3_tx_state_name(hctx->ccid3hctx_state)); 8497c657876SArnaldo Carvalho de Melo 8507c657876SArnaldo Carvalho de Melo if (hctx->ccid3hctx_x < 10) { 8517c657876SArnaldo Carvalho de Melo ccid3_pr_debug("TFRC_SSTATE_NO_FBACK ccid3hctx_x < 10\n"); 8527c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_x = 10; 8537c657876SArnaldo Carvalho de Melo } 8547c657876SArnaldo Carvalho de Melo 8557c657876SArnaldo Carvalho de Melo switch (hctx->ccid3hctx_state) { 8567c657876SArnaldo Carvalho de Melo case TFRC_SSTATE_TERM: 8577c657876SArnaldo Carvalho de Melo goto out; 8587c657876SArnaldo Carvalho de Melo case TFRC_SSTATE_NO_FBACK: 8597c657876SArnaldo Carvalho de Melo /* Halve send rate */ 8607c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_x /= 2; 8617c657876SArnaldo Carvalho de Melo if (hctx->ccid3hctx_x < (hctx->ccid3hctx_s / TFRC_MAX_BACK_OFF_TIME)) 8627c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_x = hctx->ccid3hctx_s / TFRC_MAX_BACK_OFF_TIME; 8637c657876SArnaldo Carvalho de Melo 8647c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p, state=%s, updated tx rate to %d bytes/s\n", 8657c657876SArnaldo Carvalho de Melo dccp_role(sk), sk, ccid3_tx_state_name(hctx->ccid3hctx_state), 8667c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_x); 8677c657876SArnaldo Carvalho de Melo next_tmout = max_t(u32, 2 * (hctx->ccid3hctx_s * 100000) 8687c657876SArnaldo Carvalho de Melo / (hctx->ccid3hctx_x / 10), TFRC_INITIAL_TIMEOUT); 8697c657876SArnaldo Carvalho de Melo /* do above maths with 100000 and 10 to prevent overflow on 32 bit */ 8707c657876SArnaldo Carvalho de Melo /* FIXME - not sure above calculation is correct. See section 5 of CCID3 11 8717c657876SArnaldo Carvalho de Melo * should adjust tx_t_ipi and double that to achieve it really */ 8727c657876SArnaldo Carvalho de Melo break; 8737c657876SArnaldo Carvalho de Melo case TFRC_SSTATE_FBACK: 8747c657876SArnaldo Carvalho de Melo /* Check if IDLE since last timeout and recv rate is less than 4 packets per RTT */ 8757c657876SArnaldo Carvalho de Melo rtt = hctx->ccid3hctx_rtt; 8767c657876SArnaldo Carvalho de Melo if (rtt < 10) 8777c657876SArnaldo Carvalho de Melo rtt = 10; 8787c657876SArnaldo Carvalho de Melo /* stop divide by zero below */ 8797c657876SArnaldo Carvalho de Melo if (!hctx->ccid3hctx_idle || (hctx->ccid3hctx_x_recv >= 8807c657876SArnaldo Carvalho de Melo 4 * (hctx->ccid3hctx_s * 100000) / (rtt / 10))) { 8817c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p, state=%s, not idle\n", dccp_role(sk), sk, 8827c657876SArnaldo Carvalho de Melo ccid3_tx_state_name(hctx->ccid3hctx_state)); 8837c657876SArnaldo Carvalho de Melo /* Halve sending rate */ 8847c657876SArnaldo Carvalho de Melo 8857c657876SArnaldo Carvalho de Melo /* If (X_calc > 2 * X_recv) 8867c657876SArnaldo Carvalho de Melo * X_recv = max(X_recv / 2, s / (2 * t_mbi)); 8877c657876SArnaldo Carvalho de Melo * Else 8887c657876SArnaldo Carvalho de Melo * X_recv = X_calc / 4; 8897c657876SArnaldo Carvalho de Melo */ 8907c657876SArnaldo Carvalho de Melo BUG_ON(hctx->ccid3hctx_p >= TFRC_SMALLEST_P && hctx->ccid3hctx_x_calc == 0); 8917c657876SArnaldo Carvalho de Melo 8927c657876SArnaldo Carvalho de Melo /* check also if p is zero -> x_calc is infinity? */ 8937c657876SArnaldo Carvalho de Melo if (hctx->ccid3hctx_p < TFRC_SMALLEST_P || 8947c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_x_calc > 2 * hctx->ccid3hctx_x_recv) 8957c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_x_recv = max_t(u32, hctx->ccid3hctx_x_recv / 2, 8967c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_s / (2 * TFRC_MAX_BACK_OFF_TIME)); 8977c657876SArnaldo Carvalho de Melo else 8987c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_x_recv = hctx->ccid3hctx_x_calc / 4; 8997c657876SArnaldo Carvalho de Melo 9007c657876SArnaldo Carvalho de Melo /* Update sending rate */ 9017c657876SArnaldo Carvalho de Melo ccid3_hc_tx_update_x(sk); 9027c657876SArnaldo Carvalho de Melo } 9037c657876SArnaldo Carvalho de Melo if (hctx->ccid3hctx_x == 0) { 9047c657876SArnaldo Carvalho de Melo ccid3_pr_debug("TFRC_SSTATE_FBACK ccid3hctx_x = 0!\n"); 9057c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_x = 10; 9067c657876SArnaldo Carvalho de Melo } 9077c657876SArnaldo Carvalho de Melo /* Schedule no feedback timer to expire in max(4 * R, 2 * s / X) */ 908c68e64cfSArnaldo Carvalho de Melo next_tmout = max_t(u32, hctx->ccid3hctx_t_rto, 9097c657876SArnaldo Carvalho de Melo 2 * (hctx->ccid3hctx_s * 100000) / (hctx->ccid3hctx_x / 10)); 9107c657876SArnaldo Carvalho de Melo break; 9117c657876SArnaldo Carvalho de Melo default: 9127c657876SArnaldo Carvalho de Melo printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n", 9137c657876SArnaldo Carvalho de Melo __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state); 9147c657876SArnaldo Carvalho de Melo dump_stack(); 9157c657876SArnaldo Carvalho de Melo goto out; 9167c657876SArnaldo Carvalho de Melo } 9177c657876SArnaldo Carvalho de Melo 9187c657876SArnaldo Carvalho de Melo sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, 9197c657876SArnaldo Carvalho de Melo jiffies + max_t(u32, 1, usecs_to_jiffies(next_tmout))); 9207c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_idle = 1; 9217c657876SArnaldo Carvalho de Melo out: 9227c657876SArnaldo Carvalho de Melo bh_unlock_sock(sk); 9237c657876SArnaldo Carvalho de Melo sock_put(sk); 9247c657876SArnaldo Carvalho de Melo } 9257c657876SArnaldo Carvalho de Melo 92627258ee5SArnaldo Carvalho de Melo static int ccid3_hc_tx_send_packet(struct sock *sk, 92727258ee5SArnaldo Carvalho de Melo struct sk_buff *skb, int len) 9287c657876SArnaldo Carvalho de Melo { 9297c657876SArnaldo Carvalho de Melo struct dccp_sock *dp = dccp_sk(sk); 9307c657876SArnaldo Carvalho de Melo struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private; 9318c60f3faSArnaldo Carvalho de Melo struct dccp_tx_hist_entry *new_packet; 9327c657876SArnaldo Carvalho de Melo struct timeval now; 93327258ee5SArnaldo Carvalho de Melo long delay; 9347c657876SArnaldo Carvalho de Melo int rc = -ENOTCONN; 9357c657876SArnaldo Carvalho de Melo 9367c657876SArnaldo Carvalho de Melo // ccid3_pr_debug("%s, sk=%p, skb=%p, len=%d\n", dccp_role(sk), sk, skb, len); 9377c657876SArnaldo Carvalho de Melo /* 9387c657876SArnaldo Carvalho de Melo * check if pure ACK or Terminating */ 9397c657876SArnaldo Carvalho de Melo /* XXX: We only call this function for DATA and DATAACK, on, these packets can have 9407c657876SArnaldo Carvalho de Melo * zero length, but why the comment about "pure ACK"? 9417c657876SArnaldo Carvalho de Melo */ 9427c657876SArnaldo Carvalho de Melo if (hctx == NULL || len == 0 || hctx->ccid3hctx_state == TFRC_SSTATE_TERM) 9437c657876SArnaldo Carvalho de Melo goto out; 9447c657876SArnaldo Carvalho de Melo 9457c657876SArnaldo Carvalho de Melo /* See if last packet allocated was not sent */ 9468c60f3faSArnaldo Carvalho de Melo new_packet = dccp_tx_hist_head(&hctx->ccid3hctx_hist); 9478c60f3faSArnaldo Carvalho de Melo if (new_packet == NULL || new_packet->dccphtx_sent) { 9488c60f3faSArnaldo Carvalho de Melo new_packet = dccp_tx_hist_entry_new(ccid3_tx_hist, SLAB_ATOMIC); 9497c657876SArnaldo Carvalho de Melo 9507c657876SArnaldo Carvalho de Melo rc = -ENOBUFS; 9517c657876SArnaldo Carvalho de Melo if (new_packet == NULL) { 9527c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p, not enough mem to add " 9537c657876SArnaldo Carvalho de Melo "to history, send refused\n", dccp_role(sk), sk); 9547c657876SArnaldo Carvalho de Melo goto out; 9557c657876SArnaldo Carvalho de Melo } 9567c657876SArnaldo Carvalho de Melo 9578c60f3faSArnaldo Carvalho de Melo dccp_tx_hist_add_entry(&hctx->ccid3hctx_hist, new_packet); 9587c657876SArnaldo Carvalho de Melo } 9597c657876SArnaldo Carvalho de Melo 9607c657876SArnaldo Carvalho de Melo do_gettimeofday(&now); 9617c657876SArnaldo Carvalho de Melo 9627c657876SArnaldo Carvalho de Melo switch (hctx->ccid3hctx_state) { 9637c657876SArnaldo Carvalho de Melo case TFRC_SSTATE_NO_SENT: 9647c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p, first packet(%llu)\n", dccp_role(sk), sk, 9657c657876SArnaldo Carvalho de Melo dp->dccps_gss); 9667c657876SArnaldo Carvalho de Melo 9677c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_no_feedback_timer.function = ccid3_hc_tx_no_feedback_timer; 9687c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_no_feedback_timer.data = (unsigned long)sk; 9697c657876SArnaldo Carvalho de Melo sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, jiffies + usecs_to_jiffies(TFRC_INITIAL_TIMEOUT)); 9707c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_last_win_count = 0; 9717c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_t_last_win_count = now; 9727c657876SArnaldo Carvalho de Melo ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK); 9737c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_t_ipi = TFRC_INITIAL_TIMEOUT; 9747c657876SArnaldo Carvalho de Melo 9757c657876SArnaldo Carvalho de Melo /* Set nominal send time for initial packet */ 9767c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_t_nom = now; 9777c657876SArnaldo Carvalho de Melo (hctx->ccid3hctx_t_nom).tv_usec += hctx->ccid3hctx_t_ipi; 9787c657876SArnaldo Carvalho de Melo timeval_fix(&(hctx->ccid3hctx_t_nom)); 9797c657876SArnaldo Carvalho de Melo ccid3_calc_new_delta(hctx); 9807c657876SArnaldo Carvalho de Melo rc = 0; 9817c657876SArnaldo Carvalho de Melo break; 9827c657876SArnaldo Carvalho de Melo case TFRC_SSTATE_NO_FBACK: 9837c657876SArnaldo Carvalho de Melo case TFRC_SSTATE_FBACK: 98427258ee5SArnaldo Carvalho de Melo delay = (now_delta(hctx->ccid3hctx_t_nom) - hctx->ccid3hctx_delta); 98527258ee5SArnaldo Carvalho de Melo ccid3_pr_debug("send_packet delay=%ld\n", delay); 98627258ee5SArnaldo Carvalho de Melo delay /= -1000; 9877c657876SArnaldo Carvalho de Melo /* divide by -1000 is to convert to ms and get sign right */ 98827258ee5SArnaldo Carvalho de Melo rc = delay > 0 ? -EAGAIN : 0; 9897c657876SArnaldo Carvalho de Melo break; 9907c657876SArnaldo Carvalho de Melo default: 9917c657876SArnaldo Carvalho de Melo printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n", 9927c657876SArnaldo Carvalho de Melo __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state); 9937c657876SArnaldo Carvalho de Melo dump_stack(); 9947c657876SArnaldo Carvalho de Melo rc = -EINVAL; 9957c657876SArnaldo Carvalho de Melo break; 9967c657876SArnaldo Carvalho de Melo } 9977c657876SArnaldo Carvalho de Melo 9987c657876SArnaldo Carvalho de Melo /* Can we send? if so add options and add to packet history */ 9997c657876SArnaldo Carvalho de Melo if (rc == 0) 1000c1734376SArnaldo Carvalho de Melo new_packet->dccphtx_ccval = 10018c60f3faSArnaldo Carvalho de Melo DCCP_SKB_CB(skb)->dccpd_ccval = 10028c60f3faSArnaldo Carvalho de Melo hctx->ccid3hctx_last_win_count; 10037c657876SArnaldo Carvalho de Melo out: 10047c657876SArnaldo Carvalho de Melo return rc; 10057c657876SArnaldo Carvalho de Melo } 10067c657876SArnaldo Carvalho de Melo 10077c657876SArnaldo Carvalho de Melo static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len) 10087c657876SArnaldo Carvalho de Melo { 10097c657876SArnaldo Carvalho de Melo struct dccp_sock *dp = dccp_sk(sk); 10107c657876SArnaldo Carvalho de Melo struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private; 10117c657876SArnaldo Carvalho de Melo struct timeval now; 10127c657876SArnaldo Carvalho de Melo 10137c657876SArnaldo Carvalho de Melo BUG_ON(hctx == NULL); 10147c657876SArnaldo Carvalho de Melo 10157c657876SArnaldo Carvalho de Melo if (hctx->ccid3hctx_state == TFRC_SSTATE_TERM) { 10167c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p, while state is TFRC_SSTATE_TERM!\n", 10177c657876SArnaldo Carvalho de Melo dccp_role(sk), sk); 10187c657876SArnaldo Carvalho de Melo return; 10197c657876SArnaldo Carvalho de Melo } 10207c657876SArnaldo Carvalho de Melo 10217c657876SArnaldo Carvalho de Melo do_gettimeofday(&now); 10227c657876SArnaldo Carvalho de Melo 10237c657876SArnaldo Carvalho de Melo /* check if we have sent a data packet */ 10247c657876SArnaldo Carvalho de Melo if (len > 0) { 10257c657876SArnaldo Carvalho de Melo unsigned long quarter_rtt; 10268c60f3faSArnaldo Carvalho de Melo struct dccp_tx_hist_entry *packet; 10277c657876SArnaldo Carvalho de Melo 10288c60f3faSArnaldo Carvalho de Melo packet = dccp_tx_hist_head(&hctx->ccid3hctx_hist); 10298c60f3faSArnaldo Carvalho de Melo if (packet == NULL) { 10307c657876SArnaldo Carvalho de Melo printk(KERN_CRIT "%s: packet doesn't exists in history!\n", __FUNCTION__); 10317c657876SArnaldo Carvalho de Melo return; 10327c657876SArnaldo Carvalho de Melo } 10338c60f3faSArnaldo Carvalho de Melo if (packet->dccphtx_sent) { 10347c657876SArnaldo Carvalho de Melo printk(KERN_CRIT "%s: no unsent packet in history!\n", __FUNCTION__); 10357c657876SArnaldo Carvalho de Melo return; 10367c657876SArnaldo Carvalho de Melo } 10378c60f3faSArnaldo Carvalho de Melo packet->dccphtx_tstamp = now; 10388c60f3faSArnaldo Carvalho de Melo packet->dccphtx_seqno = dp->dccps_gss; 10398c60f3faSArnaldo Carvalho de Melo #if 0 10408c60f3faSArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p, seqno=%llu inserted!\n", 10418c60f3faSArnaldo Carvalho de Melo dccp_role(sk), sk, packet->dccphtx_seqno); 10428c60f3faSArnaldo Carvalho de Melo #endif 10437c657876SArnaldo Carvalho de Melo /* 10447c657876SArnaldo Carvalho de Melo * Check if win_count have changed */ 10457c657876SArnaldo Carvalho de Melo /* COMPLIANCE_BEGIN 10467c657876SArnaldo Carvalho de Melo * Algorithm in "8.1. Window Counter Valuer" in draft-ietf-dccp-ccid3-11.txt 10477c657876SArnaldo Carvalho de Melo */ 10487c657876SArnaldo Carvalho de Melo quarter_rtt = now_delta(hctx->ccid3hctx_t_last_win_count) / (hctx->ccid3hctx_rtt / 4); 10497c657876SArnaldo Carvalho de Melo if (quarter_rtt > 0) { 10507c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_t_last_win_count = now; 10517c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_last_win_count = (hctx->ccid3hctx_last_win_count + 10527c657876SArnaldo Carvalho de Melo min_t(unsigned long, quarter_rtt, 5)) % 16; 10537c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p, window changed from %u to %u!\n", 10547c657876SArnaldo Carvalho de Melo dccp_role(sk), sk, 1055c1734376SArnaldo Carvalho de Melo packet->dccphtx_ccval, 10567c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_last_win_count); 10577c657876SArnaldo Carvalho de Melo } 10587c657876SArnaldo Carvalho de Melo /* COMPLIANCE_END */ 10597c657876SArnaldo Carvalho de Melo #if 0 10607c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p, packet sent (%llu,%u)\n", 10617c657876SArnaldo Carvalho de Melo dccp_role(sk), sk, 10628c60f3faSArnaldo Carvalho de Melo packet->dccphtx_seqno, 1063c1734376SArnaldo Carvalho de Melo packet->dccphtx_ccval); 10647c657876SArnaldo Carvalho de Melo #endif 10657c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_idle = 0; 1066c1734376SArnaldo Carvalho de Melo packet->dccphtx_rtt = hctx->ccid3hctx_rtt; 10678c60f3faSArnaldo Carvalho de Melo packet->dccphtx_sent = 1; 10687c657876SArnaldo Carvalho de Melo } else 10697c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p, seqno=%llu NOT inserted!\n", 10707c657876SArnaldo Carvalho de Melo dccp_role(sk), sk, dp->dccps_gss); 10717c657876SArnaldo Carvalho de Melo 10727c657876SArnaldo Carvalho de Melo switch (hctx->ccid3hctx_state) { 10737c657876SArnaldo Carvalho de Melo case TFRC_SSTATE_NO_SENT: 10747c657876SArnaldo Carvalho de Melo /* if first wasn't pure ack */ 10757c657876SArnaldo Carvalho de Melo if (len != 0) 10767c657876SArnaldo Carvalho de Melo printk(KERN_CRIT "%s: %s, First packet sent is noted as a data packet\n", 10777c657876SArnaldo Carvalho de Melo __FUNCTION__, dccp_role(sk)); 10787c657876SArnaldo Carvalho de Melo return; 10797c657876SArnaldo Carvalho de Melo case TFRC_SSTATE_NO_FBACK: 10807c657876SArnaldo Carvalho de Melo case TFRC_SSTATE_FBACK: 10817c657876SArnaldo Carvalho de Melo if (len > 0) { 10827c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_t_nom = now; 10837c657876SArnaldo Carvalho de Melo ccid3_calc_new_t_ipi(hctx); 10847c657876SArnaldo Carvalho de Melo ccid3_calc_new_delta(hctx); 10857c657876SArnaldo Carvalho de Melo (hctx->ccid3hctx_t_nom).tv_usec += hctx->ccid3hctx_t_ipi; 10867c657876SArnaldo Carvalho de Melo timeval_fix(&(hctx->ccid3hctx_t_nom)); 10877c657876SArnaldo Carvalho de Melo } 10887c657876SArnaldo Carvalho de Melo break; 10897c657876SArnaldo Carvalho de Melo default: 10907c657876SArnaldo Carvalho de Melo printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n", 10917c657876SArnaldo Carvalho de Melo __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state); 10927c657876SArnaldo Carvalho de Melo dump_stack(); 10937c657876SArnaldo Carvalho de Melo break; 10947c657876SArnaldo Carvalho de Melo } 10957c657876SArnaldo Carvalho de Melo } 10967c657876SArnaldo Carvalho de Melo 10977c657876SArnaldo Carvalho de Melo static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) 10987c657876SArnaldo Carvalho de Melo { 10997c657876SArnaldo Carvalho de Melo struct dccp_sock *dp = dccp_sk(sk); 11007c657876SArnaldo Carvalho de Melo struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private; 11017c657876SArnaldo Carvalho de Melo struct ccid3_options_received *opt_recv; 11028c60f3faSArnaldo Carvalho de Melo struct dccp_tx_hist_entry *packet; 11037c657876SArnaldo Carvalho de Melo unsigned long next_tmout; 11041bc09869SIan McDonald u32 t_elapsed; 11057c657876SArnaldo Carvalho de Melo u32 pinv; 11067c657876SArnaldo Carvalho de Melo u32 x_recv; 11077c657876SArnaldo Carvalho de Melo u32 r_sample; 11087c657876SArnaldo Carvalho de Melo #if 0 11097c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p(%s), skb=%p(%s)\n", 11107c657876SArnaldo Carvalho de Melo dccp_role(sk), sk, dccp_state_name(sk->sk_state), 11117c657876SArnaldo Carvalho de Melo skb, dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type)); 11127c657876SArnaldo Carvalho de Melo #endif 11137c657876SArnaldo Carvalho de Melo if (hctx == NULL) 11147c657876SArnaldo Carvalho de Melo return; 11157c657876SArnaldo Carvalho de Melo 11167c657876SArnaldo Carvalho de Melo if (hctx->ccid3hctx_state == TFRC_SSTATE_TERM) { 11177c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p, received a packet when terminating!\n", dccp_role(sk), sk); 11187c657876SArnaldo Carvalho de Melo return; 11197c657876SArnaldo Carvalho de Melo } 11207c657876SArnaldo Carvalho de Melo 11217c657876SArnaldo Carvalho de Melo /* we are only interested in ACKs */ 11227c657876SArnaldo Carvalho de Melo if (!(DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK || 11237c657876SArnaldo Carvalho de Melo DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_DATAACK)) 11247c657876SArnaldo Carvalho de Melo return; 11257c657876SArnaldo Carvalho de Melo 11267c657876SArnaldo Carvalho de Melo opt_recv = &hctx->ccid3hctx_options_received; 11277c657876SArnaldo Carvalho de Melo 11287c657876SArnaldo Carvalho de Melo t_elapsed = dp->dccps_options_received.dccpor_elapsed_time; 11297c657876SArnaldo Carvalho de Melo x_recv = opt_recv->ccid3or_receive_rate; 11307c657876SArnaldo Carvalho de Melo pinv = opt_recv->ccid3or_loss_event_rate; 11317c657876SArnaldo Carvalho de Melo 11327c657876SArnaldo Carvalho de Melo switch (hctx->ccid3hctx_state) { 11337c657876SArnaldo Carvalho de Melo case TFRC_SSTATE_NO_SENT: 11347c657876SArnaldo Carvalho de Melo /* FIXME: what to do here? */ 11357c657876SArnaldo Carvalho de Melo return; 11367c657876SArnaldo Carvalho de Melo case TFRC_SSTATE_NO_FBACK: 11377c657876SArnaldo Carvalho de Melo case TFRC_SSTATE_FBACK: 11387c657876SArnaldo Carvalho de Melo /* Calculate new round trip sample by 11397c657876SArnaldo Carvalho de Melo * R_sample = (now - t_recvdata) - t_delay */ 11407c657876SArnaldo Carvalho de Melo /* get t_recvdata from history */ 11418c60f3faSArnaldo Carvalho de Melo packet = dccp_tx_hist_find_entry(&hctx->ccid3hctx_hist, 11428c60f3faSArnaldo Carvalho de Melo DCCP_SKB_CB(skb)->dccpd_ack_seq); 11437c657876SArnaldo Carvalho de Melo if (packet == NULL) { 11447c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p, seqno %llu(%s) does't exist in history!\n", 11457c657876SArnaldo Carvalho de Melo dccp_role(sk), sk, DCCP_SKB_CB(skb)->dccpd_ack_seq, 11467c657876SArnaldo Carvalho de Melo dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type)); 11477c657876SArnaldo Carvalho de Melo return; 11487c657876SArnaldo Carvalho de Melo } 11497c657876SArnaldo Carvalho de Melo 11507c657876SArnaldo Carvalho de Melo /* Update RTT */ 11518c60f3faSArnaldo Carvalho de Melo r_sample = now_delta(packet->dccphtx_tstamp); 11527c657876SArnaldo Carvalho de Melo /* FIXME: */ 11537c657876SArnaldo Carvalho de Melo // r_sample -= usecs_to_jiffies(t_elapsed * 10); 11547c657876SArnaldo Carvalho de Melo 11557c657876SArnaldo Carvalho de Melo /* Update RTT estimate by 11567c657876SArnaldo Carvalho de Melo * If (No feedback recv) 11577c657876SArnaldo Carvalho de Melo * R = R_sample; 11587c657876SArnaldo Carvalho de Melo * Else 11597c657876SArnaldo Carvalho de Melo * R = q * R + (1 - q) * R_sample; 11607c657876SArnaldo Carvalho de Melo * 11617c657876SArnaldo Carvalho de Melo * q is a constant, RFC 3448 recomments 0.9 11627c657876SArnaldo Carvalho de Melo */ 11637c657876SArnaldo Carvalho de Melo if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK) { 11647c657876SArnaldo Carvalho de Melo ccid3_hc_tx_set_state(sk, TFRC_SSTATE_FBACK); 11657c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_rtt = r_sample; 11667c657876SArnaldo Carvalho de Melo } else 11677c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_rtt = (hctx->ccid3hctx_rtt * 9) / 10 + r_sample / 10; 11687c657876SArnaldo Carvalho de Melo 11697c657876SArnaldo Carvalho de Melo /* 11707c657876SArnaldo Carvalho de Melo * XXX: this is to avoid a division by zero in ccid3_hc_tx_packet_sent 11717c657876SArnaldo Carvalho de Melo * implemention of the new window count. 11727c657876SArnaldo Carvalho de Melo */ 11737c657876SArnaldo Carvalho de Melo if (hctx->ccid3hctx_rtt < 4) 11747c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_rtt = 4; 11757c657876SArnaldo Carvalho de Melo 11767c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p, New RTT estimate=%uus, r_sample=%us\n", 11777c657876SArnaldo Carvalho de Melo dccp_role(sk), sk, 11787c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_rtt, 11797c657876SArnaldo Carvalho de Melo r_sample); 11807c657876SArnaldo Carvalho de Melo 11817c657876SArnaldo Carvalho de Melo /* Update timeout interval */ 1182c68e64cfSArnaldo Carvalho de Melo hctx->ccid3hctx_t_rto = max_t(u32, 4 * hctx->ccid3hctx_rtt, 1183cef07fd6SArnaldo Carvalho de Melo USEC_PER_SEC); 11847c657876SArnaldo Carvalho de Melo 11857c657876SArnaldo Carvalho de Melo /* Update receive rate */ 11867c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_x_recv = x_recv; /* x_recv in bytes per second */ 11877c657876SArnaldo Carvalho de Melo 11887c657876SArnaldo Carvalho de Melo /* Update loss event rate */ 11897c657876SArnaldo Carvalho de Melo if (pinv == ~0 || pinv == 0) 11907c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_p = 0; 11917c657876SArnaldo Carvalho de Melo else { 11927c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_p = 1000000 / pinv; 11937c657876SArnaldo Carvalho de Melo 11947c657876SArnaldo Carvalho de Melo if (hctx->ccid3hctx_p < TFRC_SMALLEST_P) { 11957c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_p = TFRC_SMALLEST_P; 11967c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p, Smallest p used!\n", dccp_role(sk), sk); 11977c657876SArnaldo Carvalho de Melo } 11987c657876SArnaldo Carvalho de Melo } 11997c657876SArnaldo Carvalho de Melo 12007c657876SArnaldo Carvalho de Melo /* unschedule no feedback timer */ 12017c657876SArnaldo Carvalho de Melo sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer); 12027c657876SArnaldo Carvalho de Melo 12037c657876SArnaldo Carvalho de Melo /* Update sending rate */ 12047c657876SArnaldo Carvalho de Melo ccid3_hc_tx_update_x(sk); 12057c657876SArnaldo Carvalho de Melo 12067c657876SArnaldo Carvalho de Melo /* Update next send time */ 12077c657876SArnaldo Carvalho de Melo if (hctx->ccid3hctx_t_ipi > (hctx->ccid3hctx_t_nom).tv_usec) { 1208cef07fd6SArnaldo Carvalho de Melo hctx->ccid3hctx_t_nom.tv_usec += USEC_PER_SEC; 12097c657876SArnaldo Carvalho de Melo (hctx->ccid3hctx_t_nom).tv_sec--; 12107c657876SArnaldo Carvalho de Melo } 12117c657876SArnaldo Carvalho de Melo /* FIXME - if no feedback then t_ipi can go > 1 second */ 12127c657876SArnaldo Carvalho de Melo (hctx->ccid3hctx_t_nom).tv_usec -= hctx->ccid3hctx_t_ipi; 12137c657876SArnaldo Carvalho de Melo ccid3_calc_new_t_ipi(hctx); 12147c657876SArnaldo Carvalho de Melo (hctx->ccid3hctx_t_nom).tv_usec += hctx->ccid3hctx_t_ipi; 12157c657876SArnaldo Carvalho de Melo timeval_fix(&(hctx->ccid3hctx_t_nom)); 12167c657876SArnaldo Carvalho de Melo ccid3_calc_new_delta(hctx); 12177c657876SArnaldo Carvalho de Melo 12187c657876SArnaldo Carvalho de Melo /* remove all packets older than the one acked from history */ 12198c60f3faSArnaldo Carvalho de Melo dccp_tx_hist_purge_older(ccid3_tx_hist, 12208c60f3faSArnaldo Carvalho de Melo &hctx->ccid3hctx_hist, packet); 12218c60f3faSArnaldo Carvalho de Melo 12227c657876SArnaldo Carvalho de Melo if (hctx->ccid3hctx_x < 10) { 12237c657876SArnaldo Carvalho de Melo ccid3_pr_debug("ccid3_hc_tx_packet_recv hctx->ccid3hctx_x < 10\n"); 12247c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_x = 10; 12257c657876SArnaldo Carvalho de Melo } 12267c657876SArnaldo Carvalho de Melo /* to prevent divide by zero below */ 12277c657876SArnaldo Carvalho de Melo 12287c657876SArnaldo Carvalho de Melo /* Schedule no feedback timer to expire in max(4 * R, 2 * s / X) */ 1229c68e64cfSArnaldo Carvalho de Melo next_tmout = max(hctx->ccid3hctx_t_rto, 12308c60f3faSArnaldo Carvalho de Melo (2 * (hctx->ccid3hctx_s * 100000) / 12318c60f3faSArnaldo Carvalho de Melo (hctx->ccid3hctx_x / 10))); 12327c657876SArnaldo Carvalho de Melo /* maths with 100000 and 10 is to prevent overflow with 32 bit */ 12337c657876SArnaldo Carvalho de Melo 12347c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p, Scheduled no feedback timer to expire in %lu jiffies (%luus)\n", 12357c657876SArnaldo Carvalho de Melo dccp_role(sk), sk, usecs_to_jiffies(next_tmout), next_tmout); 12367c657876SArnaldo Carvalho de Melo 12377c657876SArnaldo Carvalho de Melo sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, 12387c657876SArnaldo Carvalho de Melo jiffies + max_t(u32,1,usecs_to_jiffies(next_tmout))); 12397c657876SArnaldo Carvalho de Melo 12407c657876SArnaldo Carvalho de Melo /* set idle flag */ 12417c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_idle = 1; 12427c657876SArnaldo Carvalho de Melo break; 12437c657876SArnaldo Carvalho de Melo default: 12447c657876SArnaldo Carvalho de Melo printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n", 12457c657876SArnaldo Carvalho de Melo __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state); 12467c657876SArnaldo Carvalho de Melo dump_stack(); 12477c657876SArnaldo Carvalho de Melo break; 12487c657876SArnaldo Carvalho de Melo } 12497c657876SArnaldo Carvalho de Melo } 12507c657876SArnaldo Carvalho de Melo 12517c657876SArnaldo Carvalho de Melo static void ccid3_hc_tx_insert_options(struct sock *sk, struct sk_buff *skb) 12527c657876SArnaldo Carvalho de Melo { 12537c657876SArnaldo Carvalho de Melo const struct dccp_sock *dp = dccp_sk(sk); 12547c657876SArnaldo Carvalho de Melo struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private; 12557c657876SArnaldo Carvalho de Melo 12567c657876SArnaldo Carvalho de Melo if (hctx == NULL || !(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN)) 12577c657876SArnaldo Carvalho de Melo return; 12587c657876SArnaldo Carvalho de Melo 12597c657876SArnaldo Carvalho de Melo DCCP_SKB_CB(skb)->dccpd_ccval = hctx->ccid3hctx_last_win_count; 12607c657876SArnaldo Carvalho de Melo } 12617c657876SArnaldo Carvalho de Melo 12627c657876SArnaldo Carvalho de Melo static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option, 12637c657876SArnaldo Carvalho de Melo unsigned char len, u16 idx, unsigned char *value) 12647c657876SArnaldo Carvalho de Melo { 12657c657876SArnaldo Carvalho de Melo int rc = 0; 12667c657876SArnaldo Carvalho de Melo struct dccp_sock *dp = dccp_sk(sk); 12677c657876SArnaldo Carvalho de Melo struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private; 12687c657876SArnaldo Carvalho de Melo struct ccid3_options_received *opt_recv; 12697c657876SArnaldo Carvalho de Melo 12707c657876SArnaldo Carvalho de Melo if (hctx == NULL) 12717c657876SArnaldo Carvalho de Melo return 0; 12727c657876SArnaldo Carvalho de Melo 12737c657876SArnaldo Carvalho de Melo opt_recv = &hctx->ccid3hctx_options_received; 12747c657876SArnaldo Carvalho de Melo 12757c657876SArnaldo Carvalho de Melo if (opt_recv->ccid3or_seqno != dp->dccps_gsr) { 12767c657876SArnaldo Carvalho de Melo opt_recv->ccid3or_seqno = dp->dccps_gsr; 12777c657876SArnaldo Carvalho de Melo opt_recv->ccid3or_loss_event_rate = ~0; 12787c657876SArnaldo Carvalho de Melo opt_recv->ccid3or_loss_intervals_idx = 0; 12797c657876SArnaldo Carvalho de Melo opt_recv->ccid3or_loss_intervals_len = 0; 12807c657876SArnaldo Carvalho de Melo opt_recv->ccid3or_receive_rate = 0; 12817c657876SArnaldo Carvalho de Melo } 12827c657876SArnaldo Carvalho de Melo 12837c657876SArnaldo Carvalho de Melo switch (option) { 12847c657876SArnaldo Carvalho de Melo case TFRC_OPT_LOSS_EVENT_RATE: 12857c657876SArnaldo Carvalho de Melo if (len != 4) { 12867c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p, invalid len for TFRC_OPT_LOSS_EVENT_RATE\n", 12877c657876SArnaldo Carvalho de Melo dccp_role(sk), sk); 12887c657876SArnaldo Carvalho de Melo rc = -EINVAL; 12897c657876SArnaldo Carvalho de Melo } else { 12907c657876SArnaldo Carvalho de Melo opt_recv->ccid3or_loss_event_rate = ntohl(*(u32 *)value); 12917c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p, LOSS_EVENT_RATE=%u\n", 12927c657876SArnaldo Carvalho de Melo dccp_role(sk), sk, 12937c657876SArnaldo Carvalho de Melo opt_recv->ccid3or_loss_event_rate); 12947c657876SArnaldo Carvalho de Melo } 12957c657876SArnaldo Carvalho de Melo break; 12967c657876SArnaldo Carvalho de Melo case TFRC_OPT_LOSS_INTERVALS: 12977c657876SArnaldo Carvalho de Melo opt_recv->ccid3or_loss_intervals_idx = idx; 12987c657876SArnaldo Carvalho de Melo opt_recv->ccid3or_loss_intervals_len = len; 12997c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p, LOSS_INTERVALS=(%u, %u)\n", 13007c657876SArnaldo Carvalho de Melo dccp_role(sk), sk, 13017c657876SArnaldo Carvalho de Melo opt_recv->ccid3or_loss_intervals_idx, 13027c657876SArnaldo Carvalho de Melo opt_recv->ccid3or_loss_intervals_len); 13037c657876SArnaldo Carvalho de Melo break; 13047c657876SArnaldo Carvalho de Melo case TFRC_OPT_RECEIVE_RATE: 13057c657876SArnaldo Carvalho de Melo if (len != 4) { 13067c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p, invalid len for TFRC_OPT_RECEIVE_RATE\n", 13077c657876SArnaldo Carvalho de Melo dccp_role(sk), sk); 13087c657876SArnaldo Carvalho de Melo rc = -EINVAL; 13097c657876SArnaldo Carvalho de Melo } else { 13107c657876SArnaldo Carvalho de Melo opt_recv->ccid3or_receive_rate = ntohl(*(u32 *)value); 13117c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p, RECEIVE_RATE=%u\n", 13127c657876SArnaldo Carvalho de Melo dccp_role(sk), sk, 13137c657876SArnaldo Carvalho de Melo opt_recv->ccid3or_receive_rate); 13147c657876SArnaldo Carvalho de Melo } 13157c657876SArnaldo Carvalho de Melo break; 13167c657876SArnaldo Carvalho de Melo } 13177c657876SArnaldo Carvalho de Melo 13187c657876SArnaldo Carvalho de Melo return rc; 13197c657876SArnaldo Carvalho de Melo } 13207c657876SArnaldo Carvalho de Melo 13217c657876SArnaldo Carvalho de Melo static int ccid3_hc_tx_init(struct sock *sk) 13227c657876SArnaldo Carvalho de Melo { 13237c657876SArnaldo Carvalho de Melo struct dccp_sock *dp = dccp_sk(sk); 13247c657876SArnaldo Carvalho de Melo struct ccid3_hc_tx_sock *hctx; 13257c657876SArnaldo Carvalho de Melo 13267c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk); 13277c657876SArnaldo Carvalho de Melo 13287c657876SArnaldo Carvalho de Melo hctx = dp->dccps_hc_tx_ccid_private = kmalloc(sizeof(*hctx), gfp_any()); 13297c657876SArnaldo Carvalho de Melo if (hctx == NULL) 13307c657876SArnaldo Carvalho de Melo return -ENOMEM; 13317c657876SArnaldo Carvalho de Melo 13327c657876SArnaldo Carvalho de Melo memset(hctx, 0, sizeof(*hctx)); 13337c657876SArnaldo Carvalho de Melo 13347c657876SArnaldo Carvalho de Melo if (dp->dccps_avg_packet_size >= TFRC_MIN_PACKET_SIZE && 13357c657876SArnaldo Carvalho de Melo dp->dccps_avg_packet_size <= TFRC_MAX_PACKET_SIZE) 13367c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_s = (u16)dp->dccps_avg_packet_size; 13377c657876SArnaldo Carvalho de Melo else 13387c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_s = TFRC_STD_PACKET_SIZE; 13397c657876SArnaldo Carvalho de Melo 13407c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_x = hctx->ccid3hctx_s; /* set transmission rate to 1 packet per second */ 13417c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_rtt = 4; /* See ccid3_hc_tx_packet_sent win_count calculatation */ 1342c68e64cfSArnaldo Carvalho de Melo hctx->ccid3hctx_t_rto = USEC_PER_SEC; 13437c657876SArnaldo Carvalho de Melo hctx->ccid3hctx_state = TFRC_SSTATE_NO_SENT; 13447c657876SArnaldo Carvalho de Melo INIT_LIST_HEAD(&hctx->ccid3hctx_hist); 13457c657876SArnaldo Carvalho de Melo init_timer(&hctx->ccid3hctx_no_feedback_timer); 13467c657876SArnaldo Carvalho de Melo 13477c657876SArnaldo Carvalho de Melo return 0; 13487c657876SArnaldo Carvalho de Melo } 13497c657876SArnaldo Carvalho de Melo 13507c657876SArnaldo Carvalho de Melo static void ccid3_hc_tx_exit(struct sock *sk) 13517c657876SArnaldo Carvalho de Melo { 13527c657876SArnaldo Carvalho de Melo struct dccp_sock *dp = dccp_sk(sk); 13537c657876SArnaldo Carvalho de Melo struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private; 13547c657876SArnaldo Carvalho de Melo 13557c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk); 13567c657876SArnaldo Carvalho de Melo BUG_ON(hctx == NULL); 13577c657876SArnaldo Carvalho de Melo 13587c657876SArnaldo Carvalho de Melo ccid3_hc_tx_set_state(sk, TFRC_SSTATE_TERM); 13597c657876SArnaldo Carvalho de Melo sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer); 13607c657876SArnaldo Carvalho de Melo 13617c657876SArnaldo Carvalho de Melo /* Empty packet history */ 13628c60f3faSArnaldo Carvalho de Melo dccp_tx_hist_purge(ccid3_tx_hist, &hctx->ccid3hctx_hist); 13637c657876SArnaldo Carvalho de Melo 13647c657876SArnaldo Carvalho de Melo kfree(dp->dccps_hc_tx_ccid_private); 13657c657876SArnaldo Carvalho de Melo dp->dccps_hc_tx_ccid_private = NULL; 13667c657876SArnaldo Carvalho de Melo } 13677c657876SArnaldo Carvalho de Melo 13687c657876SArnaldo Carvalho de Melo /* 13697c657876SArnaldo Carvalho de Melo * RX Half Connection methods 13707c657876SArnaldo Carvalho de Melo */ 13717c657876SArnaldo Carvalho de Melo 13727c657876SArnaldo Carvalho de Melo /* TFRC receiver states */ 13737c657876SArnaldo Carvalho de Melo enum ccid3_hc_rx_states { 13747c657876SArnaldo Carvalho de Melo TFRC_RSTATE_NO_DATA = 1, 13757c657876SArnaldo Carvalho de Melo TFRC_RSTATE_DATA, 13767c657876SArnaldo Carvalho de Melo TFRC_RSTATE_TERM = 127, 13777c657876SArnaldo Carvalho de Melo }; 13787c657876SArnaldo Carvalho de Melo 13797c657876SArnaldo Carvalho de Melo #ifdef CCID3_DEBUG 13807c657876SArnaldo Carvalho de Melo static const char *ccid3_rx_state_name(enum ccid3_hc_rx_states state) 13817c657876SArnaldo Carvalho de Melo { 13827c657876SArnaldo Carvalho de Melo static char *ccid3_rx_state_names[] = { 13837c657876SArnaldo Carvalho de Melo [TFRC_RSTATE_NO_DATA] = "NO_DATA", 13847c657876SArnaldo Carvalho de Melo [TFRC_RSTATE_DATA] = "DATA", 13857c657876SArnaldo Carvalho de Melo [TFRC_RSTATE_TERM] = "TERM", 13867c657876SArnaldo Carvalho de Melo }; 13877c657876SArnaldo Carvalho de Melo 13887c657876SArnaldo Carvalho de Melo return ccid3_rx_state_names[state]; 13897c657876SArnaldo Carvalho de Melo } 13907c657876SArnaldo Carvalho de Melo #endif 13917c657876SArnaldo Carvalho de Melo 13927c657876SArnaldo Carvalho de Melo static inline void ccid3_hc_rx_set_state(struct sock *sk, enum ccid3_hc_rx_states state) 13937c657876SArnaldo Carvalho de Melo { 13947c657876SArnaldo Carvalho de Melo struct dccp_sock *dp = dccp_sk(sk); 13957c657876SArnaldo Carvalho de Melo struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private; 13967c657876SArnaldo Carvalho de Melo enum ccid3_hc_rx_states oldstate = hcrx->ccid3hcrx_state; 13977c657876SArnaldo Carvalho de Melo 13987c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s(%p) %-8.8s -> %s\n", 13997c657876SArnaldo Carvalho de Melo dccp_role(sk), sk, ccid3_rx_state_name(oldstate), ccid3_rx_state_name(state)); 14007c657876SArnaldo Carvalho de Melo WARN_ON(state == oldstate); 14017c657876SArnaldo Carvalho de Melo hcrx->ccid3hcrx_state = state; 14027c657876SArnaldo Carvalho de Melo } 14037c657876SArnaldo Carvalho de Melo 14048c60f3faSArnaldo Carvalho de Melo static int ccid3_hc_rx_add_hist(struct sock *sk, 14058c60f3faSArnaldo Carvalho de Melo struct dccp_rx_hist_entry *packet) 14067c657876SArnaldo Carvalho de Melo { 14077c657876SArnaldo Carvalho de Melo struct dccp_sock *dp = dccp_sk(sk); 14087c657876SArnaldo Carvalho de Melo struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private; 14098c60f3faSArnaldo Carvalho de Melo struct dccp_rx_hist_entry *entry, *next, *iter; 14107c657876SArnaldo Carvalho de Melo u8 num_later = 0; 14117c657876SArnaldo Carvalho de Melo 14128c60f3faSArnaldo Carvalho de Melo iter = dccp_rx_hist_head(&hcrx->ccid3hcrx_hist); 14138c60f3faSArnaldo Carvalho de Melo if (iter == NULL) 14148c60f3faSArnaldo Carvalho de Melo dccp_rx_hist_add_entry(&hcrx->ccid3hcrx_hist, packet); 14157c657876SArnaldo Carvalho de Melo else { 14168c60f3faSArnaldo Carvalho de Melo const u64 seqno = packet->dccphrx_seqno; 14178c60f3faSArnaldo Carvalho de Melo 14188c60f3faSArnaldo Carvalho de Melo if (after48(seqno, iter->dccphrx_seqno)) 14198c60f3faSArnaldo Carvalho de Melo dccp_rx_hist_add_entry(&hcrx->ccid3hcrx_hist, packet); 14207c657876SArnaldo Carvalho de Melo else { 14218c60f3faSArnaldo Carvalho de Melo if (dccp_rx_hist_entry_data_packet(iter)) 14227c657876SArnaldo Carvalho de Melo num_later = 1; 14237c657876SArnaldo Carvalho de Melo 14248c60f3faSArnaldo Carvalho de Melo list_for_each_entry_continue(iter, 14258c60f3faSArnaldo Carvalho de Melo &hcrx->ccid3hcrx_hist, 14268c60f3faSArnaldo Carvalho de Melo dccphrx_node) { 14278c60f3faSArnaldo Carvalho de Melo if (after48(seqno, iter->dccphrx_seqno)) { 14288c60f3faSArnaldo Carvalho de Melo dccp_rx_hist_add_entry(&iter->dccphrx_node, 14298c60f3faSArnaldo Carvalho de Melo packet); 14307c657876SArnaldo Carvalho de Melo goto trim_history; 14317c657876SArnaldo Carvalho de Melo } 14327c657876SArnaldo Carvalho de Melo 14338c60f3faSArnaldo Carvalho de Melo if (dccp_rx_hist_entry_data_packet(iter)) 14347c657876SArnaldo Carvalho de Melo num_later++; 14357c657876SArnaldo Carvalho de Melo 14367c657876SArnaldo Carvalho de Melo if (num_later == TFRC_RECV_NUM_LATE_LOSS) { 14378c60f3faSArnaldo Carvalho de Melo dccp_rx_hist_entry_delete(ccid3_rx_hist, packet); 14387c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p, packet(%llu) already lost!\n", 14397c657876SArnaldo Carvalho de Melo dccp_role(sk), sk, seqno); 14407c657876SArnaldo Carvalho de Melo return 1; 14417c657876SArnaldo Carvalho de Melo } 14427c657876SArnaldo Carvalho de Melo } 14437c657876SArnaldo Carvalho de Melo 14447c657876SArnaldo Carvalho de Melo if (num_later < TFRC_RECV_NUM_LATE_LOSS) 14458c60f3faSArnaldo Carvalho de Melo dccp_rx_hist_add_entry(&hcrx->ccid3hcrx_hist, 14468c60f3faSArnaldo Carvalho de Melo packet); 14477c657876SArnaldo Carvalho de Melo /* FIXME: else what? should we destroy the packet like above? */ 14487c657876SArnaldo Carvalho de Melo } 14497c657876SArnaldo Carvalho de Melo } 14507c657876SArnaldo Carvalho de Melo 14517c657876SArnaldo Carvalho de Melo trim_history: 14527c657876SArnaldo Carvalho de Melo /* Trim history (remove all packets after the NUM_LATE_LOSS + 1 data packets) */ 14537c657876SArnaldo Carvalho de Melo num_later = TFRC_RECV_NUM_LATE_LOSS + 1; 14547c657876SArnaldo Carvalho de Melo 14557c657876SArnaldo Carvalho de Melo if (!list_empty(&hcrx->ccid3hcrx_loss_interval_hist)) { 14568c60f3faSArnaldo Carvalho de Melo list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist, 14578c60f3faSArnaldo Carvalho de Melo dccphrx_node) { 14587c657876SArnaldo Carvalho de Melo if (num_later == 0) { 14598c60f3faSArnaldo Carvalho de Melo list_del_init(&entry->dccphrx_node); 14608c60f3faSArnaldo Carvalho de Melo dccp_rx_hist_entry_delete(ccid3_rx_hist, entry); 14618c60f3faSArnaldo Carvalho de Melo } else if (dccp_rx_hist_entry_data_packet(entry)) 14627c657876SArnaldo Carvalho de Melo --num_later; 14637c657876SArnaldo Carvalho de Melo } 14647c657876SArnaldo Carvalho de Melo } else { 14657c657876SArnaldo Carvalho de Melo int step = 0; 14667c657876SArnaldo Carvalho de Melo u8 win_count = 0; /* Not needed, but lets shut up gcc */ 14677c657876SArnaldo Carvalho de Melo int tmp; 14687c657876SArnaldo Carvalho de Melo /* 14697c657876SArnaldo Carvalho de Melo * We have no loss interval history so we need at least one 14707c657876SArnaldo Carvalho de Melo * rtt:s of data packets to approximate rtt. 14717c657876SArnaldo Carvalho de Melo */ 14728c60f3faSArnaldo Carvalho de Melo list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist, 14738c60f3faSArnaldo Carvalho de Melo dccphrx_node) { 14747c657876SArnaldo Carvalho de Melo if (num_later == 0) { 14757c657876SArnaldo Carvalho de Melo switch (step) { 14767c657876SArnaldo Carvalho de Melo case 0: 14777c657876SArnaldo Carvalho de Melo step = 1; 14787c657876SArnaldo Carvalho de Melo /* OK, find next data packet */ 14797c657876SArnaldo Carvalho de Melo num_later = 1; 14807c657876SArnaldo Carvalho de Melo break; 14817c657876SArnaldo Carvalho de Melo case 1: 14827c657876SArnaldo Carvalho de Melo step = 2; 14837c657876SArnaldo Carvalho de Melo /* OK, find next data packet */ 14847c657876SArnaldo Carvalho de Melo num_later = 1; 1485c1734376SArnaldo Carvalho de Melo win_count = entry->dccphrx_ccval; 14867c657876SArnaldo Carvalho de Melo break; 14877c657876SArnaldo Carvalho de Melo case 2: 1488c1734376SArnaldo Carvalho de Melo tmp = win_count - entry->dccphrx_ccval; 14897c657876SArnaldo Carvalho de Melo if (tmp < 0) 14907c657876SArnaldo Carvalho de Melo tmp += TFRC_WIN_COUNT_LIMIT; 14917c657876SArnaldo Carvalho de Melo if (tmp > TFRC_WIN_COUNT_PER_RTT + 1) { 14927c657876SArnaldo Carvalho de Melo /* we have found a packet older than one rtt 14937c657876SArnaldo Carvalho de Melo * remove the rest */ 14947c657876SArnaldo Carvalho de Melo step = 3; 14957c657876SArnaldo Carvalho de Melo } else /* OK, find next data packet */ 14967c657876SArnaldo Carvalho de Melo num_later = 1; 14977c657876SArnaldo Carvalho de Melo break; 14987c657876SArnaldo Carvalho de Melo case 3: 14998c60f3faSArnaldo Carvalho de Melo list_del_init(&entry->dccphrx_node); 15008c60f3faSArnaldo Carvalho de Melo dccp_rx_hist_entry_delete(ccid3_rx_hist, entry); 15017c657876SArnaldo Carvalho de Melo break; 15027c657876SArnaldo Carvalho de Melo } 15038c60f3faSArnaldo Carvalho de Melo } else if (dccp_rx_hist_entry_data_packet(entry)) 15047c657876SArnaldo Carvalho de Melo --num_later; 15057c657876SArnaldo Carvalho de Melo } 15067c657876SArnaldo Carvalho de Melo } 15077c657876SArnaldo Carvalho de Melo 15087c657876SArnaldo Carvalho de Melo return 0; 15097c657876SArnaldo Carvalho de Melo } 15107c657876SArnaldo Carvalho de Melo 15117c657876SArnaldo Carvalho de Melo static void ccid3_hc_rx_send_feedback(struct sock *sk) 15127c657876SArnaldo Carvalho de Melo { 15137c657876SArnaldo Carvalho de Melo struct dccp_sock *dp = dccp_sk(sk); 15147c657876SArnaldo Carvalho de Melo struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private; 15158c60f3faSArnaldo Carvalho de Melo struct dccp_rx_hist_entry *packet; 15167c657876SArnaldo Carvalho de Melo 15177c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk); 15187c657876SArnaldo Carvalho de Melo 15197c657876SArnaldo Carvalho de Melo switch (hcrx->ccid3hcrx_state) { 15207c657876SArnaldo Carvalho de Melo case TFRC_RSTATE_NO_DATA: 15217c657876SArnaldo Carvalho de Melo hcrx->ccid3hcrx_x_recv = 0; 15227c657876SArnaldo Carvalho de Melo break; 15237c657876SArnaldo Carvalho de Melo case TFRC_RSTATE_DATA: { 15247c657876SArnaldo Carvalho de Melo u32 delta = now_delta(hcrx->ccid3hcrx_tstamp_last_feedback); 15257c657876SArnaldo Carvalho de Melo 15267c657876SArnaldo Carvalho de Melo if (delta == 0) 15277c657876SArnaldo Carvalho de Melo delta = 1; /* to prevent divide by zero */ 1528cef07fd6SArnaldo Carvalho de Melo hcrx->ccid3hcrx_x_recv = (hcrx->ccid3hcrx_bytes_recv * 1529cef07fd6SArnaldo Carvalho de Melo USEC_PER_SEC) / delta; 15307c657876SArnaldo Carvalho de Melo } 15317c657876SArnaldo Carvalho de Melo break; 15327c657876SArnaldo Carvalho de Melo default: 15337c657876SArnaldo Carvalho de Melo printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n", 15347c657876SArnaldo Carvalho de Melo __FUNCTION__, dccp_role(sk), sk, hcrx->ccid3hcrx_state); 15357c657876SArnaldo Carvalho de Melo dump_stack(); 15367c657876SArnaldo Carvalho de Melo return; 15377c657876SArnaldo Carvalho de Melo } 15387c657876SArnaldo Carvalho de Melo 15398c60f3faSArnaldo Carvalho de Melo packet = dccp_rx_hist_find_data_packet(&hcrx->ccid3hcrx_hist); 15407c657876SArnaldo Carvalho de Melo if (packet == NULL) { 15417c657876SArnaldo Carvalho de Melo printk(KERN_CRIT "%s: %s, sk=%p, no data packet in history!\n", 15427c657876SArnaldo Carvalho de Melo __FUNCTION__, dccp_role(sk), sk); 15437c657876SArnaldo Carvalho de Melo dump_stack(); 15447c657876SArnaldo Carvalho de Melo return; 15457c657876SArnaldo Carvalho de Melo } 15467c657876SArnaldo Carvalho de Melo 15477c657876SArnaldo Carvalho de Melo do_gettimeofday(&(hcrx->ccid3hcrx_tstamp_last_feedback)); 1548c1734376SArnaldo Carvalho de Melo hcrx->ccid3hcrx_last_counter = packet->dccphrx_ccval; 15498c60f3faSArnaldo Carvalho de Melo hcrx->ccid3hcrx_seqno_last_counter = packet->dccphrx_seqno; 15507c657876SArnaldo Carvalho de Melo hcrx->ccid3hcrx_bytes_recv = 0; 15517c657876SArnaldo Carvalho de Melo 15527c657876SArnaldo Carvalho de Melo /* Convert to multiples of 10us */ 15538c60f3faSArnaldo Carvalho de Melo hcrx->ccid3hcrx_elapsed_time = now_delta(packet->dccphrx_tstamp) / 10; 15547c657876SArnaldo Carvalho de Melo if (hcrx->ccid3hcrx_p == 0) 15557c657876SArnaldo Carvalho de Melo hcrx->ccid3hcrx_pinv = ~0; 15567c657876SArnaldo Carvalho de Melo else 15577c657876SArnaldo Carvalho de Melo hcrx->ccid3hcrx_pinv = 1000000 / hcrx->ccid3hcrx_p; 15587c657876SArnaldo Carvalho de Melo dccp_send_ack(sk); 15597c657876SArnaldo Carvalho de Melo } 15607c657876SArnaldo Carvalho de Melo 15617c657876SArnaldo Carvalho de Melo static void ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb) 15627c657876SArnaldo Carvalho de Melo { 15637c657876SArnaldo Carvalho de Melo const struct dccp_sock *dp = dccp_sk(sk); 15644fded33bSArnaldo Carvalho de Melo u32 x_recv, pinv; 15657c657876SArnaldo Carvalho de Melo struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private; 15667c657876SArnaldo Carvalho de Melo 15677c657876SArnaldo Carvalho de Melo if (hcrx == NULL || !(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN)) 15687c657876SArnaldo Carvalho de Melo return; 15697c657876SArnaldo Carvalho de Melo 15707c657876SArnaldo Carvalho de Melo DCCP_SKB_CB(skb)->dccpd_ccval = hcrx->ccid3hcrx_last_counter; 15714fded33bSArnaldo Carvalho de Melo 15724fded33bSArnaldo Carvalho de Melo if (dccp_packet_without_ack(skb)) 15734fded33bSArnaldo Carvalho de Melo return; 15744fded33bSArnaldo Carvalho de Melo 15754fded33bSArnaldo Carvalho de Melo if (hcrx->ccid3hcrx_elapsed_time != 0) 15764fded33bSArnaldo Carvalho de Melo dccp_insert_option_elapsed_time(sk, skb, 15774fded33bSArnaldo Carvalho de Melo hcrx->ccid3hcrx_elapsed_time); 15784fded33bSArnaldo Carvalho de Melo dccp_insert_option_timestamp(sk, skb); 15794fded33bSArnaldo Carvalho de Melo x_recv = htonl(hcrx->ccid3hcrx_x_recv); 15804fded33bSArnaldo Carvalho de Melo pinv = htonl(hcrx->ccid3hcrx_pinv); 15814fded33bSArnaldo Carvalho de Melo dccp_insert_option(sk, skb, TFRC_OPT_LOSS_EVENT_RATE, 15824fded33bSArnaldo Carvalho de Melo &pinv, sizeof(pinv)); 15834fded33bSArnaldo Carvalho de Melo dccp_insert_option(sk, skb, TFRC_OPT_RECEIVE_RATE, 15844fded33bSArnaldo Carvalho de Melo &x_recv, sizeof(x_recv)); 15857c657876SArnaldo Carvalho de Melo } 15867c657876SArnaldo Carvalho de Melo 15877c657876SArnaldo Carvalho de Melo /* Weights used to calculate loss event rate */ 15887c657876SArnaldo Carvalho de Melo /* 15897c657876SArnaldo Carvalho de Melo * These are integers as per section 8 of RFC3448. We can then divide by 4 * 15907c657876SArnaldo Carvalho de Melo * when we use it. 15917c657876SArnaldo Carvalho de Melo */ 1592a1d3a355SArnaldo Carvalho de Melo static const int ccid3_hc_rx_w[TFRC_RECV_IVAL_F_LENGTH] = { 1593a1d3a355SArnaldo Carvalho de Melo 4, 4, 4, 4, 3, 2, 1, 1, 1594a1d3a355SArnaldo Carvalho de Melo }; 15957c657876SArnaldo Carvalho de Melo 15967c657876SArnaldo Carvalho de Melo /* 15977c657876SArnaldo Carvalho de Melo * args: fvalue - function value to match 15987c657876SArnaldo Carvalho de Melo * returns: p closest to that value 15997c657876SArnaldo Carvalho de Melo * 16007c657876SArnaldo Carvalho de Melo * both fvalue and p are multiplied by 1,000,000 to use ints 16017c657876SArnaldo Carvalho de Melo */ 1602a1d3a355SArnaldo Carvalho de Melo static u32 calcx_reverse_lookup(u32 fvalue) { 16037c657876SArnaldo Carvalho de Melo int ctr = 0; 16047c657876SArnaldo Carvalho de Melo int small; 16057c657876SArnaldo Carvalho de Melo 16067c657876SArnaldo Carvalho de Melo if (fvalue < calcx_lookup[0][1]) 16077c657876SArnaldo Carvalho de Melo return 0; 16087c657876SArnaldo Carvalho de Melo if (fvalue <= calcx_lookup[CALCX_ARRSIZE-1][1]) 16097c657876SArnaldo Carvalho de Melo small = 1; 16107c657876SArnaldo Carvalho de Melo else if (fvalue > calcx_lookup[CALCX_ARRSIZE-1][0]) 16117c657876SArnaldo Carvalho de Melo return 1000000; 16127c657876SArnaldo Carvalho de Melo else 16137c657876SArnaldo Carvalho de Melo small = 0; 16147c657876SArnaldo Carvalho de Melo while (fvalue > calcx_lookup[ctr][small]) 16157c657876SArnaldo Carvalho de Melo ctr++; 16167c657876SArnaldo Carvalho de Melo if (small) 16177c657876SArnaldo Carvalho de Melo return (CALCX_SPLIT * ctr / CALCX_ARRSIZE); 16187c657876SArnaldo Carvalho de Melo else 16197c657876SArnaldo Carvalho de Melo return (1000000 * ctr / CALCX_ARRSIZE) ; 16207c657876SArnaldo Carvalho de Melo } 16217c657876SArnaldo Carvalho de Melo 16227c657876SArnaldo Carvalho de Melo /* calculate first loss interval 16237c657876SArnaldo Carvalho de Melo * 16247c657876SArnaldo Carvalho de Melo * returns estimated loss interval in usecs */ 16257c657876SArnaldo Carvalho de Melo 16267c657876SArnaldo Carvalho de Melo static u32 ccid3_hc_rx_calc_first_li(struct sock *sk) 16277c657876SArnaldo Carvalho de Melo { 16287c657876SArnaldo Carvalho de Melo struct dccp_sock *dp = dccp_sk(sk); 16297c657876SArnaldo Carvalho de Melo struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private; 16308c60f3faSArnaldo Carvalho de Melo struct dccp_rx_hist_entry *entry, *next, *tail = NULL; 16317c657876SArnaldo Carvalho de Melo u32 rtt, delta, x_recv, fval, p, tmp2; 1632a10cedd4SPatrick McHardy struct timeval tstamp = { 0 }, tmp_tv; 16337c657876SArnaldo Carvalho de Melo int interval = 0; 16347c657876SArnaldo Carvalho de Melo int win_count = 0; 16357c657876SArnaldo Carvalho de Melo int step = 0; 16367c657876SArnaldo Carvalho de Melo u64 tmp1; 16377c657876SArnaldo Carvalho de Melo 16388c60f3faSArnaldo Carvalho de Melo list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist, 16398c60f3faSArnaldo Carvalho de Melo dccphrx_node) { 16408c60f3faSArnaldo Carvalho de Melo if (dccp_rx_hist_entry_data_packet(entry)) { 16417c657876SArnaldo Carvalho de Melo tail = entry; 16427c657876SArnaldo Carvalho de Melo 16437c657876SArnaldo Carvalho de Melo switch (step) { 16447c657876SArnaldo Carvalho de Melo case 0: 16458c60f3faSArnaldo Carvalho de Melo tstamp = entry->dccphrx_tstamp; 1646c1734376SArnaldo Carvalho de Melo win_count = entry->dccphrx_ccval; 16477c657876SArnaldo Carvalho de Melo step = 1; 16487c657876SArnaldo Carvalho de Melo break; 16497c657876SArnaldo Carvalho de Melo case 1: 1650c1734376SArnaldo Carvalho de Melo interval = win_count - entry->dccphrx_ccval; 16517c657876SArnaldo Carvalho de Melo if (interval < 0) 16527c657876SArnaldo Carvalho de Melo interval += TFRC_WIN_COUNT_LIMIT; 16537c657876SArnaldo Carvalho de Melo if (interval > 4) 16547c657876SArnaldo Carvalho de Melo goto found; 16557c657876SArnaldo Carvalho de Melo break; 16567c657876SArnaldo Carvalho de Melo } 16577c657876SArnaldo Carvalho de Melo } 16587c657876SArnaldo Carvalho de Melo } 16597c657876SArnaldo Carvalho de Melo 16607c657876SArnaldo Carvalho de Melo if (step == 0) { 16617c657876SArnaldo Carvalho de Melo printk(KERN_CRIT "%s: %s, sk=%p, packet history contains no data packets!\n", 16627c657876SArnaldo Carvalho de Melo __FUNCTION__, dccp_role(sk), sk); 16637c657876SArnaldo Carvalho de Melo return ~0; 16647c657876SArnaldo Carvalho de Melo } 16657c657876SArnaldo Carvalho de Melo 16667c657876SArnaldo Carvalho de Melo if (interval == 0) { 16677c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p, Could not find a win_count interval > 0. Defaulting to 1\n", 16687c657876SArnaldo Carvalho de Melo dccp_role(sk), sk); 16697c657876SArnaldo Carvalho de Melo interval = 1; 16707c657876SArnaldo Carvalho de Melo } 16717c657876SArnaldo Carvalho de Melo found: 16728c60f3faSArnaldo Carvalho de Melo timeval_sub(tstamp,tail->dccphrx_tstamp,&tmp_tv); 1673cef07fd6SArnaldo Carvalho de Melo rtt = (tmp_tv.tv_sec * USEC_PER_SEC + tmp_tv.tv_usec) * 4 / interval; 16747c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p, approximated RTT to %uus\n", 16757c657876SArnaldo Carvalho de Melo dccp_role(sk), sk, rtt); 16767c657876SArnaldo Carvalho de Melo if (rtt == 0) 16777c657876SArnaldo Carvalho de Melo rtt = 1; 16787c657876SArnaldo Carvalho de Melo 16797c657876SArnaldo Carvalho de Melo delta = now_delta(hcrx->ccid3hcrx_tstamp_last_feedback); 16807c657876SArnaldo Carvalho de Melo if (delta == 0) 16817c657876SArnaldo Carvalho de Melo delta = 1; 16827c657876SArnaldo Carvalho de Melo 1683cef07fd6SArnaldo Carvalho de Melo x_recv = (hcrx->ccid3hcrx_bytes_recv * USEC_PER_SEC) / delta; 16847c657876SArnaldo Carvalho de Melo 16857c657876SArnaldo Carvalho de Melo tmp1 = (u64)x_recv * (u64)rtt; 16867c657876SArnaldo Carvalho de Melo do_div(tmp1,10000000); 16877c657876SArnaldo Carvalho de Melo tmp2 = (u32)tmp1; 16887c657876SArnaldo Carvalho de Melo fval = (hcrx->ccid3hcrx_s * 100000) / tmp2; 16897c657876SArnaldo Carvalho de Melo /* do not alter order above or you will get overflow on 32 bit */ 16907c657876SArnaldo Carvalho de Melo p = calcx_reverse_lookup(fval); 16917c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p, receive rate=%u bytes/s, implied loss rate=%u\n",\ 16927c657876SArnaldo Carvalho de Melo dccp_role(sk), sk, x_recv, p); 16937c657876SArnaldo Carvalho de Melo 16947c657876SArnaldo Carvalho de Melo if (p == 0) 16957c657876SArnaldo Carvalho de Melo return ~0; 16967c657876SArnaldo Carvalho de Melo else 16977c657876SArnaldo Carvalho de Melo return 1000000 / p; 16987c657876SArnaldo Carvalho de Melo } 16997c657876SArnaldo Carvalho de Melo 17007c657876SArnaldo Carvalho de Melo static void ccid3_hc_rx_update_li(struct sock *sk, u64 seq_loss, u8 win_loss) 17017c657876SArnaldo Carvalho de Melo { 17027c657876SArnaldo Carvalho de Melo struct dccp_sock *dp = dccp_sk(sk); 17037c657876SArnaldo Carvalho de Melo struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private; 17047c657876SArnaldo Carvalho de Melo struct ccid3_loss_interval_hist_entry *li_entry; 17057c657876SArnaldo Carvalho de Melo 17067c657876SArnaldo Carvalho de Melo if (seq_loss != DCCP_MAX_SEQNO + 1) { 17077c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p, seq_loss=%llu, win_loss=%u, packet loss detected\n", 17087c657876SArnaldo Carvalho de Melo dccp_role(sk), sk, seq_loss, win_loss); 17097c657876SArnaldo Carvalho de Melo 17107c657876SArnaldo Carvalho de Melo if (list_empty(&hcrx->ccid3hcrx_loss_interval_hist)) { 17117c657876SArnaldo Carvalho de Melo struct ccid3_loss_interval_hist_entry *li_tail = NULL; 17127c657876SArnaldo Carvalho de Melo int i; 17137c657876SArnaldo Carvalho de Melo 17147c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p, first loss event detected, creating history\n", dccp_role(sk), sk); 17157c657876SArnaldo Carvalho de Melo for (i = 0; i <= TFRC_RECV_IVAL_F_LENGTH; ++i) { 17167c657876SArnaldo Carvalho de Melo li_entry = ccid3_loss_interval_hist_entry_new(SLAB_ATOMIC); 17177c657876SArnaldo Carvalho de Melo if (li_entry == NULL) { 17187c657876SArnaldo Carvalho de Melo ccid3_loss_interval_history_delete(&hcrx->ccid3hcrx_loss_interval_hist); 17197c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p, not enough mem for creating history\n", 17207c657876SArnaldo Carvalho de Melo dccp_role(sk), sk); 17217c657876SArnaldo Carvalho de Melo return; 17227c657876SArnaldo Carvalho de Melo } 17237c657876SArnaldo Carvalho de Melo if (li_tail == NULL) 17247c657876SArnaldo Carvalho de Melo li_tail = li_entry; 17257c657876SArnaldo Carvalho de Melo list_add(&li_entry->ccid3lih_node, &hcrx->ccid3hcrx_loss_interval_hist); 17267c657876SArnaldo Carvalho de Melo } 17277c657876SArnaldo Carvalho de Melo 17287c657876SArnaldo Carvalho de Melo li_entry->ccid3lih_seqno = seq_loss; 17297c657876SArnaldo Carvalho de Melo li_entry->ccid3lih_win_count = win_loss; 17307c657876SArnaldo Carvalho de Melo 17317c657876SArnaldo Carvalho de Melo li_tail->ccid3lih_interval = ccid3_hc_rx_calc_first_li(sk); 17327c657876SArnaldo Carvalho de Melo } 17337c657876SArnaldo Carvalho de Melo } 17347c657876SArnaldo Carvalho de Melo /* FIXME: find end of interval */ 17357c657876SArnaldo Carvalho de Melo } 17367c657876SArnaldo Carvalho de Melo 17377c657876SArnaldo Carvalho de Melo static void ccid3_hc_rx_detect_loss(struct sock *sk) 17387c657876SArnaldo Carvalho de Melo { 17397c657876SArnaldo Carvalho de Melo struct dccp_sock *dp = dccp_sk(sk); 17407c657876SArnaldo Carvalho de Melo struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private; 17418c60f3faSArnaldo Carvalho de Melo struct dccp_rx_hist_entry *entry, *next, *packet; 17428c60f3faSArnaldo Carvalho de Melo struct dccp_rx_hist_entry *a_loss = NULL; 17438c60f3faSArnaldo Carvalho de Melo struct dccp_rx_hist_entry *b_loss = NULL; 17447c657876SArnaldo Carvalho de Melo u64 seq_loss = DCCP_MAX_SEQNO + 1; 17457c657876SArnaldo Carvalho de Melo u8 win_loss = 0; 17467c657876SArnaldo Carvalho de Melo u8 num_later = TFRC_RECV_NUM_LATE_LOSS; 17477c657876SArnaldo Carvalho de Melo 17488c60f3faSArnaldo Carvalho de Melo list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist, 17498c60f3faSArnaldo Carvalho de Melo dccphrx_node) { 17507c657876SArnaldo Carvalho de Melo if (num_later == 0) { 17517c657876SArnaldo Carvalho de Melo b_loss = entry; 17527c657876SArnaldo Carvalho de Melo break; 17538c60f3faSArnaldo Carvalho de Melo } else if (dccp_rx_hist_entry_data_packet(entry)) 17547c657876SArnaldo Carvalho de Melo --num_later; 17557c657876SArnaldo Carvalho de Melo } 17567c657876SArnaldo Carvalho de Melo 17577c657876SArnaldo Carvalho de Melo if (b_loss == NULL) 17587c657876SArnaldo Carvalho de Melo goto out_update_li; 17597c657876SArnaldo Carvalho de Melo 17607c657876SArnaldo Carvalho de Melo num_later = 1; 1761757f612eSArnaldo Carvalho de Melo 17628c60f3faSArnaldo Carvalho de Melo list_for_each_entry_safe_continue(entry, next, &hcrx->ccid3hcrx_hist, 17638c60f3faSArnaldo Carvalho de Melo dccphrx_node) { 17647c657876SArnaldo Carvalho de Melo if (num_later == 0) { 17657c657876SArnaldo Carvalho de Melo a_loss = entry; 17667c657876SArnaldo Carvalho de Melo break; 17678c60f3faSArnaldo Carvalho de Melo } else if (dccp_rx_hist_entry_data_packet(entry)) 17687c657876SArnaldo Carvalho de Melo --num_later; 17697c657876SArnaldo Carvalho de Melo } 17707c657876SArnaldo Carvalho de Melo 17717c657876SArnaldo Carvalho de Melo if (a_loss == NULL) { 17727c657876SArnaldo Carvalho de Melo if (list_empty(&hcrx->ccid3hcrx_loss_interval_hist)) { 17737c657876SArnaldo Carvalho de Melo /* no loss event have occured yet */ 17747c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p, TODO: find a lost data " 17757c657876SArnaldo Carvalho de Melo "packet by comparing to initial seqno\n", 17767c657876SArnaldo Carvalho de Melo dccp_role(sk), sk); 17777c657876SArnaldo Carvalho de Melo goto out_update_li; 17787c657876SArnaldo Carvalho de Melo } else { 17797c657876SArnaldo Carvalho de Melo pr_info("%s: %s, sk=%p, ERROR! Less than 4 data packets in history", 17807c657876SArnaldo Carvalho de Melo __FUNCTION__, dccp_role(sk), sk); 17817c657876SArnaldo Carvalho de Melo return; 17827c657876SArnaldo Carvalho de Melo } 17837c657876SArnaldo Carvalho de Melo } 17847c657876SArnaldo Carvalho de Melo 17857c657876SArnaldo Carvalho de Melo /* Locate a lost data packet */ 17867c657876SArnaldo Carvalho de Melo entry = packet = b_loss; 17878c60f3faSArnaldo Carvalho de Melo list_for_each_entry_safe_continue(entry, next, &hcrx->ccid3hcrx_hist, 17888c60f3faSArnaldo Carvalho de Melo dccphrx_node) { 17898c60f3faSArnaldo Carvalho de Melo u64 delta = dccp_delta_seqno(entry->dccphrx_seqno, 17908c60f3faSArnaldo Carvalho de Melo packet->dccphrx_seqno); 17917c657876SArnaldo Carvalho de Melo 17927c657876SArnaldo Carvalho de Melo if (delta != 0) { 17938c60f3faSArnaldo Carvalho de Melo if (dccp_rx_hist_entry_data_packet(packet)) 17947c657876SArnaldo Carvalho de Melo --delta; 17957c657876SArnaldo Carvalho de Melo /* 17967c657876SArnaldo Carvalho de Melo * FIXME: check this, probably this % usage is because 17977c657876SArnaldo Carvalho de Melo * in earlier drafts the ndp count was just 8 bits 17987c657876SArnaldo Carvalho de Melo * long, but now it cam be up to 24 bits long. 17997c657876SArnaldo Carvalho de Melo */ 18007c657876SArnaldo Carvalho de Melo #if 0 18017c657876SArnaldo Carvalho de Melo if (delta % DCCP_NDP_LIMIT != 18028c60f3faSArnaldo Carvalho de Melo (packet->dccphrx_ndp - 18038c60f3faSArnaldo Carvalho de Melo entry->dccphrx_ndp) % DCCP_NDP_LIMIT) 18047c657876SArnaldo Carvalho de Melo #endif 18058c60f3faSArnaldo Carvalho de Melo if (delta != 18068c60f3faSArnaldo Carvalho de Melo packet->dccphrx_ndp - entry->dccphrx_ndp) { 18078c60f3faSArnaldo Carvalho de Melo seq_loss = entry->dccphrx_seqno; 18087c657876SArnaldo Carvalho de Melo dccp_inc_seqno(&seq_loss); 18097c657876SArnaldo Carvalho de Melo } 18107c657876SArnaldo Carvalho de Melo } 18117c657876SArnaldo Carvalho de Melo packet = entry; 18127c657876SArnaldo Carvalho de Melo if (packet == a_loss) 18137c657876SArnaldo Carvalho de Melo break; 18147c657876SArnaldo Carvalho de Melo } 18157c657876SArnaldo Carvalho de Melo 18167c657876SArnaldo Carvalho de Melo if (seq_loss != DCCP_MAX_SEQNO + 1) 1817c1734376SArnaldo Carvalho de Melo win_loss = a_loss->dccphrx_ccval; 18187c657876SArnaldo Carvalho de Melo 18197c657876SArnaldo Carvalho de Melo out_update_li: 18207c657876SArnaldo Carvalho de Melo ccid3_hc_rx_update_li(sk, seq_loss, win_loss); 18217c657876SArnaldo Carvalho de Melo } 18227c657876SArnaldo Carvalho de Melo 18237c657876SArnaldo Carvalho de Melo static u32 ccid3_hc_rx_calc_i_mean(struct sock *sk) 18247c657876SArnaldo Carvalho de Melo { 18257c657876SArnaldo Carvalho de Melo struct dccp_sock *dp = dccp_sk(sk); 18267c657876SArnaldo Carvalho de Melo struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private; 18277c657876SArnaldo Carvalho de Melo struct ccid3_loss_interval_hist_entry *li_entry, *li_next; 18287c657876SArnaldo Carvalho de Melo int i = 0; 18297c657876SArnaldo Carvalho de Melo u32 i_tot; 18307c657876SArnaldo Carvalho de Melo u32 i_tot0 = 0; 18317c657876SArnaldo Carvalho de Melo u32 i_tot1 = 0; 18327c657876SArnaldo Carvalho de Melo u32 w_tot = 0; 18337c657876SArnaldo Carvalho de Melo 18347c657876SArnaldo Carvalho de Melo list_for_each_entry_safe(li_entry, li_next, &hcrx->ccid3hcrx_loss_interval_hist, ccid3lih_node) { 18357c657876SArnaldo Carvalho de Melo if (i < TFRC_RECV_IVAL_F_LENGTH) { 18367c657876SArnaldo Carvalho de Melo i_tot0 += li_entry->ccid3lih_interval * ccid3_hc_rx_w[i]; 18377c657876SArnaldo Carvalho de Melo w_tot += ccid3_hc_rx_w[i]; 18387c657876SArnaldo Carvalho de Melo } 18397c657876SArnaldo Carvalho de Melo 18407c657876SArnaldo Carvalho de Melo if (i != 0) 18417c657876SArnaldo Carvalho de Melo i_tot1 += li_entry->ccid3lih_interval * ccid3_hc_rx_w[i - 1]; 18427c657876SArnaldo Carvalho de Melo 18437c657876SArnaldo Carvalho de Melo if (++i > TFRC_RECV_IVAL_F_LENGTH) 18447c657876SArnaldo Carvalho de Melo break; 18457c657876SArnaldo Carvalho de Melo } 18467c657876SArnaldo Carvalho de Melo 18477c657876SArnaldo Carvalho de Melo if (i != TFRC_RECV_IVAL_F_LENGTH) { 18487c657876SArnaldo Carvalho de Melo pr_info("%s: %s, sk=%p, ERROR! Missing entry in interval history!\n", 18497c657876SArnaldo Carvalho de Melo __FUNCTION__, dccp_role(sk), sk); 18507c657876SArnaldo Carvalho de Melo return 0; 18517c657876SArnaldo Carvalho de Melo } 18527c657876SArnaldo Carvalho de Melo 18537c657876SArnaldo Carvalho de Melo i_tot = max(i_tot0, i_tot1); 18547c657876SArnaldo Carvalho de Melo 18557c657876SArnaldo Carvalho de Melo /* FIXME: Why do we do this? -Ian McDonald */ 18567c657876SArnaldo Carvalho de Melo if (i_tot * 4 < w_tot) 18577c657876SArnaldo Carvalho de Melo i_tot = w_tot * 4; 18587c657876SArnaldo Carvalho de Melo 18597c657876SArnaldo Carvalho de Melo return i_tot * 4 / w_tot; 18607c657876SArnaldo Carvalho de Melo } 18617c657876SArnaldo Carvalho de Melo 18627c657876SArnaldo Carvalho de Melo static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) 18637c657876SArnaldo Carvalho de Melo { 18647c657876SArnaldo Carvalho de Melo struct dccp_sock *dp = dccp_sk(sk); 18657c657876SArnaldo Carvalho de Melo struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private; 18664fded33bSArnaldo Carvalho de Melo const struct dccp_options_received *opt_recv; 18678c60f3faSArnaldo Carvalho de Melo struct dccp_rx_hist_entry *packet; 18687c657876SArnaldo Carvalho de Melo struct timeval now; 18694fded33bSArnaldo Carvalho de Melo u32 now_usecs; 18707c657876SArnaldo Carvalho de Melo u8 win_count; 18717c657876SArnaldo Carvalho de Melo u32 p_prev; 18727c657876SArnaldo Carvalho de Melo int ins; 18737c657876SArnaldo Carvalho de Melo #if 0 18747c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p(%s), skb=%p(%s)\n", 18757c657876SArnaldo Carvalho de Melo dccp_role(sk), sk, dccp_state_name(sk->sk_state), 18767c657876SArnaldo Carvalho de Melo skb, dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type)); 18777c657876SArnaldo Carvalho de Melo #endif 18787c657876SArnaldo Carvalho de Melo if (hcrx == NULL) 18797c657876SArnaldo Carvalho de Melo return; 18807c657876SArnaldo Carvalho de Melo 18817c657876SArnaldo Carvalho de Melo BUG_ON(!(hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA || 18827c657876SArnaldo Carvalho de Melo hcrx->ccid3hcrx_state == TFRC_RSTATE_DATA)); 18837c657876SArnaldo Carvalho de Melo 18844fded33bSArnaldo Carvalho de Melo opt_recv = &dp->dccps_options_received; 18854fded33bSArnaldo Carvalho de Melo 18867c657876SArnaldo Carvalho de Melo switch (DCCP_SKB_CB(skb)->dccpd_type) { 18877c657876SArnaldo Carvalho de Melo case DCCP_PKT_ACK: 18887c657876SArnaldo Carvalho de Melo if (hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA) 18897c657876SArnaldo Carvalho de Melo return; 18907c657876SArnaldo Carvalho de Melo case DCCP_PKT_DATAACK: 18914fded33bSArnaldo Carvalho de Melo if (opt_recv->dccpor_timestamp_echo == 0) 18927c657876SArnaldo Carvalho de Melo break; 18937c657876SArnaldo Carvalho de Melo p_prev = hcrx->ccid3hcrx_rtt; 18947c657876SArnaldo Carvalho de Melo do_gettimeofday(&now); 18954fded33bSArnaldo Carvalho de Melo now_usecs = now.tv_sec * USEC_PER_SEC + now.tv_usec; 18964fded33bSArnaldo Carvalho de Melo hcrx->ccid3hcrx_rtt = now_usecs - 18974fded33bSArnaldo Carvalho de Melo (opt_recv->dccpor_timestamp_echo - 18984fded33bSArnaldo Carvalho de Melo opt_recv->dccpor_elapsed_time) * 10; 18997c657876SArnaldo Carvalho de Melo if (p_prev != hcrx->ccid3hcrx_rtt) 19004fded33bSArnaldo Carvalho de Melo ccid3_pr_debug("%s, New RTT=%luus, elapsed time=%u\n", 19014fded33bSArnaldo Carvalho de Melo dccp_role(sk), hcrx->ccid3hcrx_rtt, 19024fded33bSArnaldo Carvalho de Melo opt_recv->dccpor_elapsed_time); 19037c657876SArnaldo Carvalho de Melo break; 19047c657876SArnaldo Carvalho de Melo case DCCP_PKT_DATA: 19057c657876SArnaldo Carvalho de Melo break; 19067c657876SArnaldo Carvalho de Melo default: 19077c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p, not DATA/DATAACK/ACK packet(%s)\n", 19087c657876SArnaldo Carvalho de Melo dccp_role(sk), sk, 19097c657876SArnaldo Carvalho de Melo dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type)); 19107c657876SArnaldo Carvalho de Melo return; 19117c657876SArnaldo Carvalho de Melo } 19127c657876SArnaldo Carvalho de Melo 19134fded33bSArnaldo Carvalho de Melo packet = dccp_rx_hist_entry_new(ccid3_rx_hist, opt_recv->dccpor_ndp, 19148c60f3faSArnaldo Carvalho de Melo skb, SLAB_ATOMIC); 19157c657876SArnaldo Carvalho de Melo if (packet == NULL) { 19167c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p, Not enough mem to add rx packet to history (consider it lost)!", 19177c657876SArnaldo Carvalho de Melo dccp_role(sk), sk); 19187c657876SArnaldo Carvalho de Melo return; 19197c657876SArnaldo Carvalho de Melo } 19207c657876SArnaldo Carvalho de Melo 1921c1734376SArnaldo Carvalho de Melo win_count = packet->dccphrx_ccval; 19227c657876SArnaldo Carvalho de Melo 19237c657876SArnaldo Carvalho de Melo ins = ccid3_hc_rx_add_hist(sk, packet); 19247c657876SArnaldo Carvalho de Melo 19257c657876SArnaldo Carvalho de Melo if (DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK) 19267c657876SArnaldo Carvalho de Melo return; 19277c657876SArnaldo Carvalho de Melo 19287c657876SArnaldo Carvalho de Melo switch (hcrx->ccid3hcrx_state) { 19297c657876SArnaldo Carvalho de Melo case TFRC_RSTATE_NO_DATA: 19307c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p(%s), skb=%p, sending initial feedback\n", 19317c657876SArnaldo Carvalho de Melo dccp_role(sk), sk, dccp_state_name(sk->sk_state), skb); 19327c657876SArnaldo Carvalho de Melo ccid3_hc_rx_send_feedback(sk); 19337c657876SArnaldo Carvalho de Melo ccid3_hc_rx_set_state(sk, TFRC_RSTATE_DATA); 19347c657876SArnaldo Carvalho de Melo return; 19357c657876SArnaldo Carvalho de Melo case TFRC_RSTATE_DATA: 19367c657876SArnaldo Carvalho de Melo hcrx->ccid3hcrx_bytes_recv += skb->len - dccp_hdr(skb)->dccph_doff * 4; 19377c657876SArnaldo Carvalho de Melo if (ins == 0) { 19384fded33bSArnaldo Carvalho de Melo if (now_delta(hcrx->ccid3hcrx_tstamp_last_ack) >= 19394fded33bSArnaldo Carvalho de Melo hcrx->ccid3hcrx_rtt) { 19404fded33bSArnaldo Carvalho de Melo do_gettimeofday(&hcrx->ccid3hcrx_tstamp_last_ack); 19417c657876SArnaldo Carvalho de Melo ccid3_hc_rx_send_feedback(sk); 19427c657876SArnaldo Carvalho de Melo } 19437c657876SArnaldo Carvalho de Melo return; 19447c657876SArnaldo Carvalho de Melo } 19457c657876SArnaldo Carvalho de Melo break; 19467c657876SArnaldo Carvalho de Melo default: 19477c657876SArnaldo Carvalho de Melo printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n", 19487c657876SArnaldo Carvalho de Melo __FUNCTION__, dccp_role(sk), sk, hcrx->ccid3hcrx_state); 19497c657876SArnaldo Carvalho de Melo dump_stack(); 19507c657876SArnaldo Carvalho de Melo return; 19517c657876SArnaldo Carvalho de Melo } 19527c657876SArnaldo Carvalho de Melo 19537c657876SArnaldo Carvalho de Melo /* Dealing with packet loss */ 19544fded33bSArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p(%s), data loss! Reacting...\n", 19554fded33bSArnaldo Carvalho de Melo dccp_role(sk), sk, dccp_state_name(sk->sk_state)); 19567c657876SArnaldo Carvalho de Melo 19577c657876SArnaldo Carvalho de Melo ccid3_hc_rx_detect_loss(sk); 19587c657876SArnaldo Carvalho de Melo p_prev = hcrx->ccid3hcrx_p; 19597c657876SArnaldo Carvalho de Melo 19607c657876SArnaldo Carvalho de Melo /* Calculate loss event rate */ 19617c657876SArnaldo Carvalho de Melo if (!list_empty(&hcrx->ccid3hcrx_loss_interval_hist)) 19627c657876SArnaldo Carvalho de Melo /* Scaling up by 1000000 as fixed decimal */ 19637c657876SArnaldo Carvalho de Melo hcrx->ccid3hcrx_p = 1000000 / ccid3_hc_rx_calc_i_mean(sk); 19647c657876SArnaldo Carvalho de Melo 19657c657876SArnaldo Carvalho de Melo if (hcrx->ccid3hcrx_p > p_prev) { 19667c657876SArnaldo Carvalho de Melo ccid3_hc_rx_send_feedback(sk); 19677c657876SArnaldo Carvalho de Melo return; 19687c657876SArnaldo Carvalho de Melo } 19697c657876SArnaldo Carvalho de Melo } 19707c657876SArnaldo Carvalho de Melo 19717c657876SArnaldo Carvalho de Melo static int ccid3_hc_rx_init(struct sock *sk) 19727c657876SArnaldo Carvalho de Melo { 19737c657876SArnaldo Carvalho de Melo struct dccp_sock *dp = dccp_sk(sk); 19747c657876SArnaldo Carvalho de Melo struct ccid3_hc_rx_sock *hcrx; 19757c657876SArnaldo Carvalho de Melo 19767c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk); 19777c657876SArnaldo Carvalho de Melo 19787c657876SArnaldo Carvalho de Melo hcrx = dp->dccps_hc_rx_ccid_private = kmalloc(sizeof(*hcrx), gfp_any()); 19797c657876SArnaldo Carvalho de Melo if (hcrx == NULL) 19807c657876SArnaldo Carvalho de Melo return -ENOMEM; 19817c657876SArnaldo Carvalho de Melo 19827c657876SArnaldo Carvalho de Melo memset(hcrx, 0, sizeof(*hcrx)); 19837c657876SArnaldo Carvalho de Melo 19847c657876SArnaldo Carvalho de Melo if (dp->dccps_avg_packet_size >= TFRC_MIN_PACKET_SIZE && 19857c657876SArnaldo Carvalho de Melo dp->dccps_avg_packet_size <= TFRC_MAX_PACKET_SIZE) 19867c657876SArnaldo Carvalho de Melo hcrx->ccid3hcrx_s = (u16)dp->dccps_avg_packet_size; 19877c657876SArnaldo Carvalho de Melo else 19887c657876SArnaldo Carvalho de Melo hcrx->ccid3hcrx_s = TFRC_STD_PACKET_SIZE; 19897c657876SArnaldo Carvalho de Melo 19907c657876SArnaldo Carvalho de Melo hcrx->ccid3hcrx_state = TFRC_RSTATE_NO_DATA; 19917c657876SArnaldo Carvalho de Melo INIT_LIST_HEAD(&hcrx->ccid3hcrx_hist); 19927c657876SArnaldo Carvalho de Melo INIT_LIST_HEAD(&hcrx->ccid3hcrx_loss_interval_hist); 19934fded33bSArnaldo Carvalho de Melo /* 19944fded33bSArnaldo Carvalho de Melo * XXX this seems to be paranoid, need to think more about this, for 19954fded33bSArnaldo Carvalho de Melo * now start with something different than zero. -acme 19964fded33bSArnaldo Carvalho de Melo */ 19974fded33bSArnaldo Carvalho de Melo hcrx->ccid3hcrx_rtt = USEC_PER_SEC / 5; 19987c657876SArnaldo Carvalho de Melo return 0; 19997c657876SArnaldo Carvalho de Melo } 20007c657876SArnaldo Carvalho de Melo 20017c657876SArnaldo Carvalho de Melo static void ccid3_hc_rx_exit(struct sock *sk) 20027c657876SArnaldo Carvalho de Melo { 20037c657876SArnaldo Carvalho de Melo struct dccp_sock *dp = dccp_sk(sk); 20047c657876SArnaldo Carvalho de Melo struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private; 20057c657876SArnaldo Carvalho de Melo 20067c657876SArnaldo Carvalho de Melo ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk); 20077c657876SArnaldo Carvalho de Melo 20087c657876SArnaldo Carvalho de Melo if (hcrx == NULL) 20097c657876SArnaldo Carvalho de Melo return; 20107c657876SArnaldo Carvalho de Melo 20117c657876SArnaldo Carvalho de Melo ccid3_hc_rx_set_state(sk, TFRC_RSTATE_TERM); 20127c657876SArnaldo Carvalho de Melo 20137c657876SArnaldo Carvalho de Melo /* Empty packet history */ 20148c60f3faSArnaldo Carvalho de Melo dccp_rx_hist_purge(ccid3_rx_hist, &hcrx->ccid3hcrx_hist); 20157c657876SArnaldo Carvalho de Melo 20167c657876SArnaldo Carvalho de Melo /* Empty loss interval history */ 20177c657876SArnaldo Carvalho de Melo ccid3_loss_interval_history_delete(&hcrx->ccid3hcrx_loss_interval_hist); 20187c657876SArnaldo Carvalho de Melo 20197c657876SArnaldo Carvalho de Melo kfree(dp->dccps_hc_rx_ccid_private); 20207c657876SArnaldo Carvalho de Melo dp->dccps_hc_rx_ccid_private = NULL; 20217c657876SArnaldo Carvalho de Melo } 20227c657876SArnaldo Carvalho de Melo 20232babe1f6SArnaldo Carvalho de Melo static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info) 20242babe1f6SArnaldo Carvalho de Melo { 20252babe1f6SArnaldo Carvalho de Melo const struct dccp_sock *dp = dccp_sk(sk); 20262babe1f6SArnaldo Carvalho de Melo const struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private; 20272babe1f6SArnaldo Carvalho de Melo 20282babe1f6SArnaldo Carvalho de Melo if (hcrx == NULL) 20292babe1f6SArnaldo Carvalho de Melo return; 20302babe1f6SArnaldo Carvalho de Melo 20312babe1f6SArnaldo Carvalho de Melo info->tcpi_ca_state = hcrx->ccid3hcrx_state; 20322babe1f6SArnaldo Carvalho de Melo info->tcpi_options |= TCPI_OPT_TIMESTAMPS; 20332babe1f6SArnaldo Carvalho de Melo info->tcpi_rcv_rtt = hcrx->ccid3hcrx_rtt; 20342babe1f6SArnaldo Carvalho de Melo } 20352babe1f6SArnaldo Carvalho de Melo 20362babe1f6SArnaldo Carvalho de Melo static void ccid3_hc_tx_get_info(struct sock *sk, struct tcp_info *info) 20372babe1f6SArnaldo Carvalho de Melo { 20382babe1f6SArnaldo Carvalho de Melo const struct dccp_sock *dp = dccp_sk(sk); 20392babe1f6SArnaldo Carvalho de Melo const struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private; 20402babe1f6SArnaldo Carvalho de Melo 20412babe1f6SArnaldo Carvalho de Melo if (hctx == NULL) 20422babe1f6SArnaldo Carvalho de Melo return; 20432babe1f6SArnaldo Carvalho de Melo 20442babe1f6SArnaldo Carvalho de Melo info->tcpi_rto = hctx->ccid3hctx_t_rto; 20452babe1f6SArnaldo Carvalho de Melo info->tcpi_rtt = hctx->ccid3hctx_rtt; 20462babe1f6SArnaldo Carvalho de Melo } 20472babe1f6SArnaldo Carvalho de Melo 20487c657876SArnaldo Carvalho de Melo static struct ccid ccid3 = { 20497c657876SArnaldo Carvalho de Melo .ccid_id = 3, 20507c657876SArnaldo Carvalho de Melo .ccid_name = "ccid3", 20517c657876SArnaldo Carvalho de Melo .ccid_owner = THIS_MODULE, 20527c657876SArnaldo Carvalho de Melo .ccid_init = ccid3_init, 20537c657876SArnaldo Carvalho de Melo .ccid_exit = ccid3_exit, 20547c657876SArnaldo Carvalho de Melo .ccid_hc_tx_init = ccid3_hc_tx_init, 20557c657876SArnaldo Carvalho de Melo .ccid_hc_tx_exit = ccid3_hc_tx_exit, 20567c657876SArnaldo Carvalho de Melo .ccid_hc_tx_send_packet = ccid3_hc_tx_send_packet, 20577c657876SArnaldo Carvalho de Melo .ccid_hc_tx_packet_sent = ccid3_hc_tx_packet_sent, 20587c657876SArnaldo Carvalho de Melo .ccid_hc_tx_packet_recv = ccid3_hc_tx_packet_recv, 20597c657876SArnaldo Carvalho de Melo .ccid_hc_tx_insert_options = ccid3_hc_tx_insert_options, 20607c657876SArnaldo Carvalho de Melo .ccid_hc_tx_parse_options = ccid3_hc_tx_parse_options, 20617c657876SArnaldo Carvalho de Melo .ccid_hc_rx_init = ccid3_hc_rx_init, 20627c657876SArnaldo Carvalho de Melo .ccid_hc_rx_exit = ccid3_hc_rx_exit, 20637c657876SArnaldo Carvalho de Melo .ccid_hc_rx_insert_options = ccid3_hc_rx_insert_options, 20647c657876SArnaldo Carvalho de Melo .ccid_hc_rx_packet_recv = ccid3_hc_rx_packet_recv, 20652babe1f6SArnaldo Carvalho de Melo .ccid_hc_rx_get_info = ccid3_hc_rx_get_info, 20662babe1f6SArnaldo Carvalho de Melo .ccid_hc_tx_get_info = ccid3_hc_tx_get_info, 20677c657876SArnaldo Carvalho de Melo }; 20687c657876SArnaldo Carvalho de Melo 20697c657876SArnaldo Carvalho de Melo module_param(ccid3_debug, int, 0444); 20707c657876SArnaldo Carvalho de Melo MODULE_PARM_DESC(ccid3_debug, "Enable debug messages"); 20717c657876SArnaldo Carvalho de Melo 20727c657876SArnaldo Carvalho de Melo static __init int ccid3_module_init(void) 20737c657876SArnaldo Carvalho de Melo { 20748c60f3faSArnaldo Carvalho de Melo int rc = -ENOBUFS; 20757c657876SArnaldo Carvalho de Melo 20768c60f3faSArnaldo Carvalho de Melo ccid3_rx_hist = dccp_rx_hist_new("ccid3"); 20778c60f3faSArnaldo Carvalho de Melo if (ccid3_rx_hist == NULL) 20787c657876SArnaldo Carvalho de Melo goto out; 20797c657876SArnaldo Carvalho de Melo 20808c60f3faSArnaldo Carvalho de Melo ccid3_tx_hist = dccp_tx_hist_new("ccid3"); 20818c60f3faSArnaldo Carvalho de Melo if (ccid3_tx_hist == NULL) 20828c60f3faSArnaldo Carvalho de Melo goto out_free_rx; 20837c657876SArnaldo Carvalho de Melo 20848c60f3faSArnaldo Carvalho de Melo ccid3_loss_interval_hist_slab = kmem_cache_create("li_hist_ccid3", 20858c60f3faSArnaldo Carvalho de Melo sizeof(struct ccid3_loss_interval_hist_entry), 20868c60f3faSArnaldo Carvalho de Melo 0, SLAB_HWCACHE_ALIGN, 20878c60f3faSArnaldo Carvalho de Melo NULL, NULL); 20887c657876SArnaldo Carvalho de Melo if (ccid3_loss_interval_hist_slab == NULL) 20898c60f3faSArnaldo Carvalho de Melo goto out_free_tx; 20907c657876SArnaldo Carvalho de Melo 20917c657876SArnaldo Carvalho de Melo rc = ccid_register(&ccid3); 20927c657876SArnaldo Carvalho de Melo if (rc != 0) 20937c657876SArnaldo Carvalho de Melo goto out_free_loss_interval_history; 20947c657876SArnaldo Carvalho de Melo out: 20957c657876SArnaldo Carvalho de Melo return rc; 20968c60f3faSArnaldo Carvalho de Melo 20977c657876SArnaldo Carvalho de Melo out_free_loss_interval_history: 20987c657876SArnaldo Carvalho de Melo kmem_cache_destroy(ccid3_loss_interval_hist_slab); 20997c657876SArnaldo Carvalho de Melo ccid3_loss_interval_hist_slab = NULL; 21008c60f3faSArnaldo Carvalho de Melo out_free_tx: 21018c60f3faSArnaldo Carvalho de Melo dccp_tx_hist_delete(ccid3_tx_hist); 21028c60f3faSArnaldo Carvalho de Melo ccid3_tx_hist = NULL; 21038c60f3faSArnaldo Carvalho de Melo out_free_rx: 21048c60f3faSArnaldo Carvalho de Melo dccp_rx_hist_delete(ccid3_rx_hist); 21058c60f3faSArnaldo Carvalho de Melo ccid3_rx_hist = NULL; 21067c657876SArnaldo Carvalho de Melo goto out; 21077c657876SArnaldo Carvalho de Melo } 21087c657876SArnaldo Carvalho de Melo module_init(ccid3_module_init); 21097c657876SArnaldo Carvalho de Melo 21107c657876SArnaldo Carvalho de Melo static __exit void ccid3_module_exit(void) 21117c657876SArnaldo Carvalho de Melo { 2112725ba8eeSArnaldo Carvalho de Melo #ifdef CONFIG_IP_DCCP_UNLOAD_HACK 2113725ba8eeSArnaldo Carvalho de Melo /* 2114725ba8eeSArnaldo Carvalho de Melo * Hack to use while developing, so that we get rid of the control 2115725ba8eeSArnaldo Carvalho de Melo * sock, that is what keeps a refcount on dccp.ko -acme 2116725ba8eeSArnaldo Carvalho de Melo */ 2117725ba8eeSArnaldo Carvalho de Melo extern void dccp_ctl_sock_exit(void); 2118725ba8eeSArnaldo Carvalho de Melo 2119725ba8eeSArnaldo Carvalho de Melo dccp_ctl_sock_exit(); 2120725ba8eeSArnaldo Carvalho de Melo #endif 21217c657876SArnaldo Carvalho de Melo ccid_unregister(&ccid3); 21227c657876SArnaldo Carvalho de Melo 21238c60f3faSArnaldo Carvalho de Melo if (ccid3_tx_hist != NULL) { 21248c60f3faSArnaldo Carvalho de Melo dccp_tx_hist_delete(ccid3_tx_hist); 21258c60f3faSArnaldo Carvalho de Melo ccid3_tx_hist = NULL; 21267c657876SArnaldo Carvalho de Melo } 21278c60f3faSArnaldo Carvalho de Melo if (ccid3_rx_hist != NULL) { 21288c60f3faSArnaldo Carvalho de Melo dccp_rx_hist_delete(ccid3_rx_hist); 21298c60f3faSArnaldo Carvalho de Melo ccid3_rx_hist = NULL; 21307c657876SArnaldo Carvalho de Melo } 21317c657876SArnaldo Carvalho de Melo if (ccid3_loss_interval_hist_slab != NULL) { 21327c657876SArnaldo Carvalho de Melo kmem_cache_destroy(ccid3_loss_interval_hist_slab); 21337c657876SArnaldo Carvalho de Melo ccid3_loss_interval_hist_slab = NULL; 21347c657876SArnaldo Carvalho de Melo } 21357c657876SArnaldo Carvalho de Melo } 21367c657876SArnaldo Carvalho de Melo module_exit(ccid3_module_exit); 21377c657876SArnaldo Carvalho de Melo 21387c657876SArnaldo Carvalho de Melo MODULE_AUTHOR("Ian McDonald <iam4@cs.waikato.ac.nz> & Arnaldo Carvalho de Melo <acme@ghostprotocols.net>"); 21397c657876SArnaldo Carvalho de Melo MODULE_DESCRIPTION("DCCP TFRC CCID3 CCID"); 21407c657876SArnaldo Carvalho de Melo MODULE_LICENSE("GPL"); 21417c657876SArnaldo Carvalho de Melo MODULE_ALIAS("net-dccp-ccid-3"); 2142