Date: Wed, 22 Oct 2008 01:50:35 +0000 (UTC) From: Lawrence Stewart <lstewart@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r184150 - in projects/tcp_cc_7.x/sys: . conf modules modules/cc_htcp netinet Message-ID: <200810220150.m9M1oZGK013969@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: lstewart Date: Wed Oct 22 01:50:35 2008 New Revision: 184150 URL: http://svn.freebsd.org/changeset/base/184150 Log: Merge r184148 and r184149 from tcp_cc_8.x Added: projects/tcp_cc_7.x/sys/modules/cc_htcp/ - copied from r184148, projects/tcp_cc_8.x/sys/modules/cc_htcp/ projects/tcp_cc_7.x/sys/netinet/cc_htcp.c - copied unchanged from r184148, projects/tcp_cc_8.x/sys/netinet/cc_htcp.c Modified: projects/tcp_cc_7.x/sys/ (props changed) projects/tcp_cc_7.x/sys/conf/files projects/tcp_cc_7.x/sys/modules/Makefile projects/tcp_cc_7.x/sys/netinet/cc.c projects/tcp_cc_7.x/sys/netinet/tcp_usrreq.c Modified: projects/tcp_cc_7.x/sys/conf/files ============================================================================== --- projects/tcp_cc_7.x/sys/conf/files Wed Oct 22 01:13:31 2008 (r184149) +++ projects/tcp_cc_7.x/sys/conf/files Wed Oct 22 01:50:35 2008 (r184150) @@ -1795,6 +1795,7 @@ netinet/ip_options.c optional inet netinet/ip_output.c optional inet netinet/raw_ip.c optional inet netinet/cc.c optional inet +netinet/cc_htcp.c optional inet netinet/sctp_asconf.c optional inet sctp netinet/sctp_auth.c optional inet sctp netinet/sctp_bsd_addr.c optional inet sctp Modified: projects/tcp_cc_7.x/sys/modules/Makefile ============================================================================== --- projects/tcp_cc_7.x/sys/modules/Makefile Wed Oct 22 01:13:31 2008 (r184149) +++ projects/tcp_cc_7.x/sys/modules/Makefile Wed Oct 22 01:50:35 2008 (r184150) @@ -47,6 +47,7 @@ SUBDIR= ${_3dfx} \ ${_canbus} \ ${_cardbus} \ ${_cbb} \ + cc_htcp \ cd9660 \ cd9660_iconv \ cdce \ Modified: projects/tcp_cc_7.x/sys/netinet/cc.c ============================================================================== --- projects/tcp_cc_7.x/sys/netinet/cc.c Wed Oct 22 01:13:31 2008 (r184149) +++ projects/tcp_cc_7.x/sys/netinet/cc.c Wed Oct 22 01:50:35 2008 (r184150) @@ -164,7 +164,7 @@ cc_init() cc_register_algorithm(&newreno_cc_algo); /* set newreno to the system default */ - strncpy(cc_algorithm, newreno_cc_algo.name, sizeof(cc_algorithm)); + strlcpy(cc_algorithm, newreno_cc_algo.name, TCP_CA_NAME_MAX); } /* Copied: projects/tcp_cc_7.x/sys/netinet/cc_htcp.c (from r184148, projects/tcp_cc_8.x/sys/netinet/cc_htcp.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/tcp_cc_7.x/sys/netinet/cc_htcp.c Wed Oct 22 01:50:35 2008 (r184150, copy of r184148, projects/tcp_cc_8.x/sys/netinet/cc_htcp.c) @@ -0,0 +1,623 @@ +/*- + * Copyright (c) 2008 Swinburne University of Technology, Melbourne, Australia + * All rights reserved. + * + * This software was developed at the Centre for Advanced Internet + * Architectures, Swinburne University, by Lawrence Stewart and James Healy, + * made possible in part by a grant from the Cisco University Research Program + * Fund at Community Foundation Silicon Valley. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/* + * HTCP + * + * An implementation of HTCP congestion algorithm for FreeBSD 7.0 + * The algorithm is based on the one described in "H-TCP: A framework + * for congestion control in high-speed and long-distance networks" by + * Leith, Shorten and Lee. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/kernel.h> +#include <sys/systm.h> +#include <sys/malloc.h> +#include <sys/module.h> +#include <sys/sysctl.h> +#include <sys/socketvar.h> +#include <netinet/tcp_seq.h> +#include <netinet/tcp_timer.h> +#include <netinet/cc.h> + +/* useful defines */ +#define MODNAME "HTCP congestion control" +#define MODVERSION "0.9.1" +#define HTCP_SHIFT 8 +#define HTCP_ALPHA_INC_SHIFT 4 +#define HTCP_INIT_ALPHA 1 +#define HTCP_DELTA_L hz /* 1 sec in ticks */ +#define HTCP_MINBETA 128 /* 0.5 with a shift << 8 */ +#define HTCP_MAXBETA 204 /* ~0.8 with a shift << 8 */ +#define HTCP_MINROWE 26 /* ~0.1 with a shift << 8 */ +#define HTCP_MAXROWE 512 /* 2 with a shift << 8 */ +#define HTCP_RTT_REF 100 /* reference RTT in milliseconds used in the calculation of */ + /* alpha if htcp_rtt_scaling=1 */ +#define HTCP_MIN_RTT_SAMPLES 8 /* don't trust the TCP stack's smoothed rtt estimate */ + /* until this many samples have been taken */ +#define CAST_PTR_INT(X) (*((int*)(X))) + +/* + * HTCP_CALC_ALPHA performs a fixed point math calculation to + * determine the value of alpha, based on the function defined in + * H-TCP: A framework for congestion control in high-speed and long distance networks" + * + * i.e. 1 + 10(delta - delta_l) + ((delta - delta_l) / 2) ^ 2 + * + * "diff" is passed in to the macro as "delta - delta_l" and is + * expected to be in units of ticks. + * + * The joyousnous of fixed point maths means our function implementation + * looks a little funky... + * + * In order to maintain some precision in the calculations, a fixed point + * shift HTCP_ALPHA_INC_SHIFT is used to ensure the integer divisions don't + * truncate the results too badly. + * + * The "16" value is the "1" term in the alpha function shifted up by HTCP_ALPHA_INC_SHIFT + * + * The "160" value is the "10" multiplier in the alpha function multiplied by 2^HTCP_ALPHA_INC_SHIFT + * + * Specifying these as constants reduces the computations required. + * After up-shifting all the terms in the function and performing the + * required calculations, we down-shift the final result by + * HTCP_ALPHA_INC_SHIFT to ensure it is back in the correct range. + * + * The "hz" terms are required as kernels can be configured to run + * with different tick timers, which we have to adjust for in the + * alpha calculation (which originally was defined in terms of seconds). + * + * We also have to be careful to constrain the value of diff such that it + * won't overflow whilst performing the calculation. The middle term i.e. + * (160 * diff) / hz is the limiting factor in the calculation. We must + * constrain diff to be less than the max size of an unsigned long divided + * by the constant 160 figure i.e. + * diff < [(2 ^ (sizeof(u_long) * 8)) - 1] / 160 + * + * NB: Changing HTCP_ALPHA_INC_SHIFT will require you to MANUALLY update + * the constants used in this function! + */ +#define HTCP_CALC_ALPHA(diff) \ +(\ + (\ + (16) + \ + ((160 * (diff)) / hz) + \ + (((diff) / hz) * (((diff) << HTCP_ALPHA_INC_SHIFT) / (4 * hz))) \ + ) >> HTCP_ALPHA_INC_SHIFT \ +) + +/* function prototypes */ +int htcp_init(struct tcpcb *tp); +void htcp_deinit(struct tcpcb *tp); +void htcp_recalc_alpha(struct tcpcb *tp); +void htcp_recalc_beta(struct tcpcb *tp); +void htcp_pre_fr(struct tcpcb *tp, struct tcphdr *th); +void htcp_post_fr(struct tcpcb *tp, struct tcphdr *th); +void htcp_ack_received(struct tcpcb *tp, struct tcphdr *th); +void htcp_after_timeout(struct tcpcb *tp); +void htcp_after_idle(struct tcpcb *tp); +void htcp_ssthresh_update(struct tcpcb *tp); +void htcp_record_rtt(struct tcpcb *tp); + +struct htcp { + u_int alpha; /* alpha param, used for cwnd increase */ + u_int beta; /* beta param, used for cwnd increase and decreade */ + u_long prev_cwnd; /* the value of cwnd before entering fast recovery */ + /* used when setting the cwnd after exiting FR */ + u_long t_last_cong; /* time of last congestion event in ticks */ + u_int minrtt; /* the shortest rtt seen for a flow */ + u_int maxrtt; /* the largest rtt seen for a flow */ +}; + +static u_long htcp_max_diff; +static u_int htcp_rtt_scaling = 0; +static u_int htcp_adaptive_backoff = 0; +static u_int htcp_rtt_ref; + +#ifdef HTCP_DEBUG +static u_int htcp_debug_ticks = 1000; +#endif + +MALLOC_DECLARE(M_HTCP); +MALLOC_DEFINE(M_HTCP, "htcp data", "Per connection data required for the HTCP congestion algorithm"); + +/* function pointers for various hooks into the TCP stack */ +struct cc_algo htcp_cc_algo = { + .name = "htcp", + .init = htcp_init, + .deinit = htcp_deinit, + .cwnd_init = newreno_cwnd_init, + .ack_received = htcp_ack_received, + .pre_fr = htcp_pre_fr, + .post_fr = htcp_post_fr, + .after_idle = htcp_after_idle, + .after_timeout = htcp_after_timeout +}; + +/* + * Initialise HTCP on the specified TCP control block. Creates a + * new struct for HTCP specific data and sticks a pointer to it + * in the control block + */ +int +htcp_init(struct tcpcb *tp) +{ + struct htcp *htcp_data; + +#ifdef HTCP_DEBUG + printf("initialising tcp connection with htcp congestion control\n"); +#endif + + MALLOC(htcp_data, struct htcp *, sizeof(struct htcp), M_HTCP, M_NOWAIT); + + if (htcp_data == NULL) + return 1; + + /* init some key htcp values with sensible defaults */ + htcp_data->alpha = HTCP_INIT_ALPHA; + htcp_data->beta = HTCP_MINBETA; + htcp_data->t_last_cong = ticks; + htcp_data->prev_cwnd = 0; + htcp_data->minrtt = TCPTV_SRTTBASE; + htcp_data->maxrtt = TCPTV_SRTTBASE; + + CC_DATA(tp) = htcp_data; + + return 0; +} + +/* + * Free the struct used to store HTCP specific data for the specified + * TCP control block. + */ +void +htcp_deinit(struct tcpcb *tp) +{ +#ifdef HTCP_DEBUG + printf("deinitialising tcp connection with htcp congestion control\n"); +#endif + + if (CC_DATA(tp)) + FREE(CC_DATA(tp), M_HTCP); +} + +/* + * Recalculate the alpha value used for scaling cwnd up. + * This is currently called once for each ACK that is received. + */ +void +htcp_recalc_alpha(struct tcpcb *tp) +{ + u_int alpha, now; + struct htcp *htcp_data = CC_DATA(tp); + u_long delta = 0, diff = 0; + +#ifdef HTCP_DEBUG + static u_int debug_counter = 0; +#endif + + now = ticks; + + /* + * if ticks has wrapped around (will happen approximately once + * every 49 days on a machine running at 1000hz) and a flow straddles + * the wrap point, our alpha calcs will be completely wrong. + * We cut our losses and restart alpha from scratch + * by setting t_last_cong = now + delta_l + * + * This does not deflate our cwnd at all. It simply slows the rate + * cwnd is growing by until alpha regains the value it held + * prior to taking this drastic measure. + */ + if (now < htcp_data->t_last_cong) + htcp_data->t_last_cong = now + HTCP_DELTA_L; + + delta = now - htcp_data->t_last_cong; + + /* + * if its been less than HTCP_DELTA_L ticks since congestion, + * set alpha to 1. Otherwise, use the function defined in + * the key HTCP paper + */ + if (delta < HTCP_DELTA_L) + htcp_data->alpha = 1; + + else if ((diff = delta - HTCP_DELTA_L) < htcp_max_diff) + { + alpha = HTCP_CALC_ALPHA(diff); + + /* Adaptive backoff fairness adjustment: 2 * (1 - beta) * alpha_raw */ + if(htcp_adaptive_backoff) + alpha = max(1, (2 * ((1 << HTCP_SHIFT) - htcp_data->beta) * alpha) >> HTCP_SHIFT); + + /* + * RTT scaling: (RTT / RTT_ref) * alpha_raw + * alpha will be the raw value from HTCP_CALC_ALPHA() if adaptive backoff + * is off, or the adjusted value if adaptive backoff is on + */ + if(htcp_rtt_scaling) + alpha = max(1, (min(max(HTCP_MINROWE, (tp->t_srtt << HTCP_SHIFT) / htcp_rtt_ref), HTCP_MAXROWE) * alpha) >> HTCP_SHIFT); + + htcp_data->alpha = alpha; + } + + +#ifdef HTCP_DEBUG + /* print out a debug message to syslog periodically */ + if(ticks - debug_counter > htcp_debug_ticks) + { + debug_counter = ticks; + + printf("alpha: %-4u salpha: %-4u beta: %-4d t_last_cong: %-10u delta: %-6u cwnd: %-7u min|max rtt: %5u|%-5u rtt|rtt_ref: %5u|%-5u\n", + (unsigned int)HTCP_CALC_ALPHA(diff), + htcp_data->alpha, + htcp_data->beta, + (unsigned int)htcp_data->t_last_cong, + (unsigned int)delta, + (unsigned int)tp->snd_cwnd, + htcp_data->minrtt, + htcp_data->maxrtt, + tp->t_srtt, + htcp_rtt_ref + ); + } +#endif +} + +/* + * Recalculate the beta value used for scaling cwnd up and down. + * This is currently called once for each ACK that is received + */ +void +htcp_recalc_beta(struct tcpcb *tp) +{ + struct htcp *htcp_data = CC_DATA(tp); + + /* + * beta is stored as a fixed point number instead of floating point for + * efficiency reasons. The decimal point is moved 1 byte to the left, + * allowing for a 3 byte whole number and 1 byte fractional + * + * any time a number is multiplied or divided by beta, the answer must be right + * shifted by a byte to get the real answer + * + * beta is bounded to ensure it is always between HTCP_MINBETA and HTCP_MAXBETA + */ + + /* + * TCPTV_SRTTBASE is the initialised value of each connection's srtt, so we only + * calc beta if the connection's srtt has been changed from its inital value + */ + if (htcp_adaptive_backoff && htcp_data->minrtt != TCPTV_SRTTBASE && htcp_data->maxrtt != TCPTV_SRTTBASE) + htcp_data->beta = min(max(HTCP_MINBETA, (htcp_data->minrtt << HTCP_SHIFT) / htcp_data->maxrtt), HTCP_MAXBETA); + else + htcp_data->beta = HTCP_MINBETA; +} + +/* + * Record the minimum and maximum RTT seen on the connection. + * These are used in the calculation of beta if adaptive backoff is enabled. + */ +void +htcp_record_rtt(struct tcpcb *tp) +{ + struct htcp *htcp_data = CC_DATA(tp); + + /* TODO: Should there be some hysteresis for minrtt? */ + + /* + * record the current SRTT as our minrtt if it's the smalelst we've + * seen or minrtt is currently equal to its initialised value. + * Ignore srtt until a min number of samples have been taken + */ + if ((tp->t_srtt < htcp_data->minrtt || htcp_data->minrtt == TCPTV_SRTTBASE) && (tp->t_rttupdated >= HTCP_MIN_RTT_SAMPLES)) + htcp_data->minrtt = tp->t_srtt; + + /* + * record the current SRTT as our maxrtt if it's the largest we've + * seen. + * Ignore srtt until a min number of samples have been taken + */ + if (tp->t_srtt > htcp_data->maxrtt && tp->t_rttupdated >= HTCP_MIN_RTT_SAMPLES) + htcp_data->maxrtt = tp->t_srtt; +} + +/* + * Perform any necesary tasks before we enter fast recovery + */ +void +htcp_pre_fr(struct tcpcb *tp, struct tcphdr *th) +{ + struct htcp *htcp_data = CC_DATA(tp); + + htcp_ssthresh_update(tp); + + /* + * grab the current time and record it so we know when the most recent + * congestion event was + */ + htcp_data->t_last_cong = ticks; + + /* reset rttmax to ensure reductions in the rtt become visible */ + htcp_data->maxrtt = (htcp_data->minrtt + (htcp_data->maxrtt - htcp_data->minrtt) * 95) / 100; + + /* + * record the current cwnd so it can be used as the basis for resetting + * cwnd after exiting fr + */ + htcp_data->prev_cwnd = tp->snd_cwnd; +} + +/* + * Decrease cwnd in the event of packet loss. + */ +void +htcp_post_fr(struct tcpcb *tp, struct tcphdr *th) +{ + u_int cwnd_in_pkts; + struct htcp *htcp_data = CC_DATA(tp); + + /* + * if inflight data is less than ssthresh, set cwnd conservatively to avoid a burst of data, as + * suggested in the NewReno RFC. Otherwise, use the HTCP method. + */ + if (th && SEQ_GT(th->th_ack + tp->snd_ssthresh, tp->snd_max)) + tp->snd_cwnd = tp->snd_max - th->th_ack + tp->t_maxseg; + else + { + /* update cwnd as a function of beta ensure that it never falls below 1 MSS */ + cwnd_in_pkts = htcp_data->prev_cwnd / tp->t_maxseg; + tp->snd_cwnd = max(1,((htcp_data->beta * cwnd_in_pkts) >> HTCP_SHIFT)) * tp->t_maxseg; + } +} + +/* + * Increase cwnd on the arrival of an ACK. + */ +void +htcp_ack_received(struct tcpcb *tp, struct tcphdr *th) +{ + struct htcp *htcp_data = CC_DATA(tp); + u_int cwnd_in_pkts, incr; + + htcp_record_rtt(tp); + htcp_recalc_beta(tp); + htcp_recalc_alpha(tp); + + /* + * when alpha equals 1 or we're in slow-start, fall back to newreno increase function. + * Alpha will equal 1 for the first HTCP_DELTA_L ticks after the flow starts and after congestion + */ + if (htcp_data->alpha == 1 || tp->snd_cwnd < tp->snd_ssthresh) + newreno_ack_received(tp, th); + else + { + /* + * increase cwnd as a function of the alpha value, restricting + * it to the maximum window sized advertised by the other host + * This cap is identical to the one used in the newreno code + */ + cwnd_in_pkts = tp->snd_cwnd / tp->t_maxseg; + incr = (((htcp_data->alpha << HTCP_SHIFT) / cwnd_in_pkts) * tp->t_maxseg) >> HTCP_SHIFT; + tp->snd_cwnd = min(tp->snd_cwnd + incr, TCP_MAXWIN << tp->snd_scale); + } +} + +void +htcp_after_idle(struct tcpcb *tp) +{ + printf("after_idle hook called\n"); + newreno_after_idle(tp); +} + +/* + * Reset the cwnd after a retransmission timeout + */ +void +htcp_after_timeout(struct tcpcb *tp) +{ + struct htcp *htcp_data = CC_DATA(tp); + + htcp_ssthresh_update(tp); + + /* + * grab the current time and record it so we know when the most recent + * congestion event was. Only record it when the timeout has fired more + * than once, as there is a reasonable chance the first one is a false alarm + * and may not indicate congestion. + */ + if (tp->t_rxtshift >= 2) + htcp_data->t_last_cong = ticks; + + newreno_after_timeout(tp); +} + +/* + * Update the ssthresh in the event of congestion. + */ +void +htcp_ssthresh_update(struct tcpcb *tp) +{ + struct htcp *htcp_data = CC_DATA(tp); + + /* + * on the first congestion event, set ssthresh to cwnd * 0.5, on + * subsequent congestion events, set it to cwnd * beta. + */ + if (tp->snd_ssthresh == TCP_MAXWIN << TCP_MAX_WINSHIFT) + tp->snd_ssthresh = (tp->snd_cwnd * HTCP_MINBETA) >> HTCP_SHIFT; + else + tp->snd_ssthresh = (tp->snd_cwnd * htcp_data->beta) >> HTCP_SHIFT; +} + + +static int +htcp_rtt_scaling_handler(SYSCTL_HANDLER_ARGS) +{ + if(!req->newptr) + goto skip; + + /* if the value passed in isn't 0 or 1, return an error */ + if(CAST_PTR_INT(req->newptr) != 0 && CAST_PTR_INT(req->newptr) != 1) + return 1; + +skip: + return sysctl_handle_int(oidp, arg1, arg2, req); +} + +static int +htcp_adaptive_backoff_handler(SYSCTL_HANDLER_ARGS) +{ + if(!req->newptr) + goto skip; + + /* if the value passed in isn't 0 or 1, return an error */ + if(CAST_PTR_INT(req->newptr) != 0 && CAST_PTR_INT(req->newptr) != 1) + return 1; + +skip: + return sysctl_handle_int(oidp, arg1, arg2, req); +} + +#ifdef HTCP_DEBUG +static int +htcp_debug_ticks_handler(SYSCTL_HANDLER_ARGS) +{ + if(!req->newptr) + goto skip; + + /* if the value passed in is less than 1 */ + if(CAST_PTR_INT(req->newptr) < 1) + return 1; + +skip: + return sysctl_handle_int(oidp, arg1, arg2, req); +} +#endif + +/* + * Init the HTCP module when it is first loaded into the kernel. + * Calls the kernel function for registering a new congestion control + * algorithm + */ +static int +init_module(void) +{ + /* + * the maximum time in ticks after a congestion event before alpha stops + * increasing, due to the risk of overflow. + * see comment above HTCP_CALC_ALPHA for more info + */ + htcp_max_diff = (~((u_long)0)) / ((1 << HTCP_ALPHA_INC_SHIFT) * 10); + + /* + * HTCP_RTT_REF is defined in ms, and t_srtt in the tcpcb is stored in + * units of TCP_RTT_SCALE*hz. + * We perform the following calculation to ensure htcp_rtt_ref + * is in the same units as t_srtt. + */ + htcp_rtt_ref = (HTCP_RTT_REF * TCP_RTT_SCALE * hz) / 1000; + +#ifdef HTCP_DEBUG + /* set the default debug interval to 1 second */ + htcp_debug_ticks = hz; +#endif + + /* add htcp to the list of available algorithms */ + cc_register_algorithm(&htcp_cc_algo); + + uprintf("Loaded: %s v%s\n", MODNAME, MODVERSION); + + return 0; +} + +/* + * Called when the module is unloaded from the kernel. + */ +static int +deinit_module(void) +{ + cc_deregister_algorithm(&htcp_cc_algo); + + uprintf("Unloaded: %s v%s\n", MODNAME, MODVERSION); + + return 0; +} + +/* + * Tell the kernel which functions to use to init and de-init the module. + */ +static int +htcp_load_handler(module_t mod, int what, void *arg) +{ + switch(what) { + case MOD_LOAD: + return init_module(); + break; + + case MOD_QUIESCE: + case MOD_SHUTDOWN: + return deinit_module(); + break; + + case MOD_UNLOAD: + return 0; + break; + + default: + return EINVAL; + break; + } +} + +/* a struct that holds basic data on the module */ +static moduledata_t htcp_mod = +{ + "htcp", /* module's name */ + htcp_load_handler, /* execution entry point for the module */ + NULL +}; + +DECLARE_MODULE(htcp, htcp_mod, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY); + +SYSCTL_DECL(_net_inet_tcp_cc_htcp); +SYSCTL_NODE(_net_inet_tcp_cc, OID_AUTO, htcp, CTLFLAG_RW, NULL, "H-TCP related settings"); +SYSCTL_OID(_net_inet_tcp_cc_htcp, OID_AUTO, rtt_scaling, CTLTYPE_UINT|CTLFLAG_RW, &htcp_rtt_scaling, 0, &htcp_rtt_scaling_handler, "IU", "switch H-TCP RTT scaling on/off"); +SYSCTL_OID(_net_inet_tcp_cc_htcp, OID_AUTO, adaptive_backoff, CTLTYPE_UINT|CTLFLAG_RW, &htcp_adaptive_backoff, 0, &htcp_adaptive_backoff_handler, "IU", "switch H-TCP adaptive backoff on/off"); + +#ifdef HTCP_DEBUG +SYSCTL_OID(_net_inet_tcp_cc_htcp, OID_AUTO, debug_ticks, CTLTYPE_UINT|CTLFLAG_RW, &htcp_debug_ticks, 0, &htcp_debug_ticks_handler, "IU", "set the approximate number of ticks between printing debug messages to syslog"); +#endif Modified: projects/tcp_cc_7.x/sys/netinet/tcp_usrreq.c ============================================================================== --- projects/tcp_cc_7.x/sys/netinet/tcp_usrreq.c Wed Oct 22 01:13:31 2008 (r184149) +++ projects/tcp_cc_7.x/sys/netinet/tcp_usrreq.c Wed Oct 22 01:50:35 2008 (r184150) @@ -1470,7 +1470,7 @@ tcp_ctloutput(struct socket *so, struct break; case TCP_CONGESTION: bzero(buf, sizeof(buf)); - memcpy(&(CC_ALGO(tp)->name), buf, TCP_CA_NAME_MAX); + strlcpy(buf, CC_ALGO(tp)->name, TCP_CA_NAME_MAX); INP_WUNLOCK(inp); error = sooptcopyout(sopt, buf, TCP_CA_NAME_MAX); break;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200810220150.m9M1oZGK013969>