1: From: Dave Taht <d@taht.net>
2:
3: In the bufferbloat age, anything that can make for a kinder, gentler bulk
4: transfer protocol seems desirable.
5:
6: This add support for user and server selectable congestion control algorithms.
7:
8: For example:
9: --congestion-alg=lp # For the tcp-lp algorithm on the command line
10:
11: And diffserv support:
12: --diffserv=8 for setting the CS1 bit
13:
14: Also available in rsync daemon modules:
15:
16: [mystuff]
17: congestion alg = westwood # for a wireless connection
18: diffserv = 8
19:
20: This could be improved by being able to specify a list of congestion algorithms
21: to try, symbolic names for diffserv (CS1), a better name than 'congestion-alg',
22: and some error checking.
23:
24: To use this patch, run these commands for a successful build:
25:
26: patch -p1 <patches/congestion.diff
27: ./configure (optional if already run)
28: make
29:
30: based-on: e94bad1c156fc3910f24e2b3b71a81b0b0bdeb70
31: diff --git a/daemon-parm.txt b/daemon-parm.txt
32: --- a/daemon-parm.txt
33: +++ b/daemon-parm.txt
34: @@ -18,6 +18,7 @@ Locals: =================================================================
35: STRING auth_users NULL
36: STRING charset NULL
37: STRING comment NULL
38: +STRING congestion_alg NULL
39: STRING dont_compress DEFAULT_DONT_COMPRESS
40: STRING early_exec NULL
41: STRING exclude NULL
42: @@ -45,6 +46,7 @@ STRING uid NULL
43: PATH path NULL
44: PATH temp_dir NULL
45:
46: +INTEGER diffserv 8
47: INTEGER max_connections 0
48: INTEGER max_verbosity 1
49: INTEGER timeout 0
50: diff --git a/options.c b/options.c
51: --- a/options.c
52: +++ b/options.c
53: @@ -72,6 +72,8 @@ int delete_during = 0;
54: int delete_before = 0;
55: int delete_after = 0;
56: int delete_excluded = 0;
57: +int diffserv = 8;
58: +char *congestion_alg = NULL;
59: int remove_source_files = 0;
60: int one_file_system = 0;
61: int protocol_version = PROTOCOL_VERSION;
62: @@ -816,6 +818,8 @@ static struct poptOption long_options[] = {
63: {"outbuf", 0, POPT_ARG_STRING, &outbuf_mode, 0, 0, 0 },
64: {"remote-option", 'M', POPT_ARG_STRING, 0, 'M', 0, 0 },
65: {"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 },
66: + {"congestion-alg", 0, POPT_ARG_STRING, &congestion_alg, 0, 0, 0 },
67: + {"diffserv", 0, POPT_ARG_INT, &diffserv, 0, 0, 0 },
68: {"checksum-seed", 0, POPT_ARG_INT, &checksum_seed, 0, 0, 0 },
69: {"server", 0, POPT_ARG_NONE, 0, OPT_SERVER, 0, 0 },
70: {"sender", 0, POPT_ARG_NONE, 0, OPT_SENDER, 0, 0 },
71: diff --git a/rsync.1.md b/rsync.1.md
72: --- a/rsync.1.md
73: +++ b/rsync.1.md
74: @@ -443,6 +443,8 @@ detailed description below for a complete description.
75: --address=ADDRESS bind address for outgoing socket to daemon
76: --port=PORT specify double-colon alternate port number
77: --sockopts=OPTIONS specify custom TCP options
78: +--diffserv=[0-63] specify diffserv setting
79: +--congestion-alg=STRING choose a congestion algo
80: --blocking-io use blocking I/O for the remote shell
81: --outbuf=N|L|B set out buffering to None, Line, or Block
82: --stats give some file-transfer stats
83: diff --git a/socket.c b/socket.c
84: --- a/socket.c
85: +++ b/socket.c
86: @@ -40,6 +40,8 @@ extern char *sockopts;
87: extern int default_af_hint;
88: extern int connect_timeout;
89: extern int pid_file_fd;
90: +extern int diffserv;
91: +extern char *congestion_alg;
92:
93: #ifdef HAVE_SIGACTION
94: static struct sigaction sigact;
95: @@ -166,6 +168,37 @@ static void contimeout_handler(UNUSED(int val))
96: connect_timeout = -1;
97: }
98:
99: +/* Set special socket options
100: + *
101: + * Diffserv is a value in the range of 0-63, and needs to be shifted left
102: + * 2 places AND treated differently for ipv4 and ipv6.
103: + * Setting TCP congestion control is rather Linux specific (at the moment)
104: + * and sends a varying length string to setsockopt rather than an integer
105: + * or character.
106: +*/
107: +
108: +void set_special_sockopts(int s)
109: +{
110: +#if defined(TCP_CONGESTION)
111: + if (congestion_alg) {
112: + if (setsockopt(s, SOL_TCP, TCP_CONGESTION, congestion_alg, strlen(congestion_alg)) == -1)
113: + rprintf(FINFO, "Couldn't set %s congestion algorithm\n", congestion_alg);
114: + }
115: +#endif
116: +
117: +/* setting the diffserv/tos bits is different on ipv6 and
118: + * ipv4, so we just hammer down on both and ignore the result
119: + * And ipv6 demands an int for v. I didn't write the spec.
120: + */
121: + if (diffserv) {
122: + int v = (diffserv & 63) <<2;
123: + setsockopt(s,IPPROTO_IP, IP_TOS, &v, sizeof(v));
124: +#if defined(IPV6_TCLASS)
125: + setsockopt(s,IPPROTO_IPV6, IPV6_TCLASS, &v, sizeof(v));
126: +#endif
127: + }
128: +}
129: +
130: /* Open a socket to a tcp remote host with the specified port.
131: *
132: * Based on code from Warren. Proxy support by Stephen Rothwell.
133: @@ -272,6 +305,7 @@ int open_socket_out(char *host, int port, const char *bind_addr, int af_hint)
134: alarm(connect_timeout);
135: }
136:
137: + set_special_sockopts(s);
138: set_socket_options(s, sockopts);
139: while (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
140: if (connect_timeout < 0)
141: @@ -440,6 +474,7 @@ static int *open_socket_in(int type, int port, const char *bind_addr,
142: continue;
143: }
144:
145: + set_special_sockopts(s);
146: setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
147: (char *)&one, sizeof one);
148: if (sockopts)
149: diff -Nurp a/rsync.1 b/rsync.1
150: --- a/rsync.1
151: +++ b/rsync.1
152: @@ -519,6 +519,8 @@ detailed description below for a complet
153: --address=ADDRESS bind address for outgoing socket to daemon
154: --port=PORT specify double-colon alternate port number
155: --sockopts=OPTIONS specify custom TCP options
156: +--diffserv=[0-63] specify diffserv setting
157: +--congestion-alg=STRING choose a congestion algo
158: --blocking-io use blocking I/O for the remote shell
159: --outbuf=N|L|B set out buffering to None, Line, or Block
160: --stats give some file-transfer stats
161: diff -Nurp a/rsync.1.html b/rsync.1.html
162: --- a/rsync.1.html
163: +++ b/rsync.1.html
164: @@ -434,6 +434,8 @@ detailed description below for a complet
165: --address=ADDRESS bind address for outgoing socket to daemon
166: --port=PORT specify double-colon alternate port number
167: --sockopts=OPTIONS specify custom TCP options
168: +--diffserv=[0-63] specify diffserv setting
169: +--congestion-alg=STRING choose a congestion algo
170: --blocking-io use blocking I/O for the remote shell
171: --outbuf=N|L|B set out buffering to None, Line, or Block
172: --stats give some file-transfer stats
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>