3

I have a huge rsync task where I'd like to syncronize file colletion of my workstation and remote server (rsync over ssh). I assume the whole process to take weeks so I don't want to cripple my network for the whole time by increasing latency of the network for all other processes.

I know that if I could persuate the rsync to switch to low priority congestion control (lp) it would automatically give most of the network bandwidth to other processes in case of any congestion.

I know that I can load support for the low priority congestion control simply by running sudo modprobe tcp_lp and user mode apps are allowed to use it as long it's listed in /proc/sys/net/ipv4/tcp_allowed_congestion_control.

However, I prefer keeping cdg or vegas as my default congestion control algorithm. How to get rsync (and the underlying ssh) to use congestion control algorithm lp instead?

My intent is to allow rsync to go full speed as long as the network is not used for anything.

1 Answers1

3

If the destination is known, specify the congestion control algorithm as a route option:

ip route add <ip_addr>/32 via <gateway> congctl lp

Alternatively, LD_PRELOAD a library that calls setsockopt(..., TCP_CONGESTION, "lp") on the TCP socket before connecting (probably a good place to do it is by hooking the existing setsockopt (IP_TOS) call that ssh already does), or patch ssh to do it by itself.

/* gcc -shared -o force_lp.so force_lp.c */

#define _GNU_SOURCE #include <dlfcn.h> #include <err.h> #include <netinet/ip.h> #include <netinet/tcp.h> #include <sys/socket.h>

int setsockopt(int fd, int level, int name, const void value, socklen_t len) { static int (real_setsockopt)(int, int, int, const void *, socklen_t); int r;

if (!real_setsockopt)
    real_setsockopt = dlsym(RTLD_NEXT, &quot;setsockopt&quot;);

if ((level == SOL_IP &amp;&amp; name == IP_TOS) ||
    (level == SOL_IPV6 &amp;&amp; name == IPV6_TCLASS))
{
    /* This is probably the TCP socket that will be used for SSH. */
    r = real_setsockopt(fd, SOL_TCP, TCP_CONGESTION, &quot;lp&quot;, sizeof &quot;lp&quot;);
    if (r != 0)
        warn(&quot;Could not set congestion control algorithm&quot;);
}

return real_setsockopt(fd, level, name, value, len);

}

Just to point this out, rsync doesn't have a say in the congestion algorithm because it never gets direct access to the TCP socket – it does everything by talking to the ssh process via stdio.

grawity
  • 501,077