// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (c) 2007 The University of Aberdeen, Scotland, UK * Copyright (c) 2005-7 The University of Waikato, Hamilton, New Zealand. * Copyright (c) 2005-7 Ian McDonald <[email protected]> * * An implementation of the DCCP protocol * * This code has been developed by the University of Waikato WAND * research group. For further information please see https://www.wand.net.nz/ * * This code also uses code from Lulea University, rereleased as GPL by its * authors: * Copyright (c) 2003 Nils-Erik Mattsson, Joacim Haggmark, Magnus Erixzon * * Changes to meet Linux coding standards, to make it meet latest ccid3 draft * and to make it work as a loadable module in the DCCP stack written by * Arnaldo Carvalho de Melo <[email protected]>. * * Copyright (c) 2005 Arnaldo Carvalho de Melo <[email protected]> */ #include "../dccp.h" #include "ccid3.h" #include <asm/unaligned.h> #ifdef CONFIG_IP_DCCP_CCID3_DEBUG static bool ccid3_debug; #define ccid3_pr_debug(format, a...) … #else #define ccid3_pr_debug … #endif /* * Transmitter Half-Connection Routines */ #ifdef CONFIG_IP_DCCP_CCID3_DEBUG static const char *ccid3_tx_state_name(enum ccid3_hc_tx_states state) { … } #endif static void ccid3_hc_tx_set_state(struct sock *sk, enum ccid3_hc_tx_states state) { … } /* * Compute the initial sending rate X_init in the manner of RFC 3390: * * X_init = min(4 * s, max(2 * s, 4380 bytes)) / RTT * * Note that RFC 3390 uses MSS, RFC 4342 refers to RFC 3390, and rfc3448bis * (rev-02) clarifies the use of RFC 3390 with regard to the above formula. * For consistency with other parts of the code, X_init is scaled by 2^6. */ static inline u64 rfc3390_initial_rate(struct sock *sk) { … } /** * ccid3_update_send_interval - Calculate new t_ipi = s / X_inst * @hc: socket to have the send interval updated * * This respects the granularity of X_inst (64 * bytes/second). */ static void ccid3_update_send_interval(struct ccid3_hc_tx_sock *hc) { … } static u32 ccid3_hc_tx_idle_rtt(struct ccid3_hc_tx_sock *hc, ktime_t now) { … } /** * ccid3_hc_tx_update_x - Update allowed sending rate X * @sk: socket to be updated * @stamp: most recent time if available - can be left NULL. * * This function tracks draft rfc3448bis, check there for latest details. * * Note: X and X_recv are both stored in units of 64 * bytes/second, to support * fine-grained resolution of sending rates. This requires scaling by 2^6 * throughout the code. Only X_calc is unscaled (in bytes/second). * */ static void ccid3_hc_tx_update_x(struct sock *sk, ktime_t *stamp) { … } /** * ccid3_hc_tx_update_s - Track the mean packet size `s' * @hc: socket to be updated * @len: DCCP packet payload size in bytes * * cf. RFC 4342, 5.3 and RFC 3448, 4.1 */ static inline void ccid3_hc_tx_update_s(struct ccid3_hc_tx_sock *hc, int len) { … } /* * Update Window Counter using the algorithm from [RFC 4342, 8.1]. * As elsewhere, RTT > 0 is assumed by using dccp_sample_rtt(). */ static inline void ccid3_hc_tx_update_win_count(struct ccid3_hc_tx_sock *hc, ktime_t now) { … } static void ccid3_hc_tx_no_feedback_timer(struct timer_list *t) { … } /** * ccid3_hc_tx_send_packet - Delay-based dequeueing of TX packets * @sk: socket to send packet from * @skb: next packet candidate to send on @sk * * This function uses the convention of ccid_packet_dequeue_eval() and * returns a millisecond-delay value between 0 and t_mbi = 64000 msec. */ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb) { … } static void ccid3_hc_tx_packet_sent(struct sock *sk, unsigned int len) { … } static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) { … } static int ccid3_hc_tx_parse_options(struct sock *sk, u8 packet_type, u8 option, u8 *optval, u8 optlen) { … } static int ccid3_hc_tx_init(struct ccid *ccid, struct sock *sk) { … } static void ccid3_hc_tx_exit(struct sock *sk) { … } static void ccid3_hc_tx_get_info(struct sock *sk, struct tcp_info *info) { … } static int ccid3_hc_tx_getsockopt(struct sock *sk, const int optname, int len, u32 __user *optval, int __user *optlen) { … } /* * Receiver Half-Connection Routines */ /* CCID3 feedback types */ enum ccid3_fback_type { … }; #ifdef CONFIG_IP_DCCP_CCID3_DEBUG static const char *ccid3_rx_state_name(enum ccid3_hc_rx_states state) { … } #endif static void ccid3_hc_rx_set_state(struct sock *sk, enum ccid3_hc_rx_states state) { … } static void ccid3_hc_rx_send_feedback(struct sock *sk, const struct sk_buff *skb, enum ccid3_fback_type fbtype) { … } static int ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb) { … } /** * ccid3_first_li - Implements [RFC 5348, 6.3.1] * @sk: socket to calculate loss interval for * * Determine the length of the first loss interval via inverse lookup. * Assume that X_recv can be computed by the throughput equation * s * X_recv = -------- * R * fval * Find some p such that f(p) = fval; return 1/p (scaled). */ static u32 ccid3_first_li(struct sock *sk) { … } static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) { … } static int ccid3_hc_rx_init(struct ccid *ccid, struct sock *sk) { … } static void ccid3_hc_rx_exit(struct sock *sk) { … } static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info) { … } static int ccid3_hc_rx_getsockopt(struct sock *sk, const int optname, int len, u32 __user *optval, int __user *optlen) { … } struct ccid_operations ccid3_ops = …; #ifdef CONFIG_IP_DCCP_CCID3_DEBUG module_param(ccid3_debug, bool, 0644); MODULE_PARM_DESC(…) …; #endif