1

I need to test that a given (python) application works properly when the network is slow. Is there a way to simulate this on a local machine? Ideally it would be possible to do this for a single application, without making admin-required modifications to the system. eg a packet dropping proxy server.

Paul
  • 141
  • 5
  • 2
  • https://unix.stackexchange.com/questions/39384/limiting-a-specific-shells-internet-bandwidth-usage covers this if by “slow” you mean low-bandwidth. If you want latency, I'm not sure if the tools mentioned in the answers can do it; if the older question doesn't help you, please edit your question to make it more specific. – Gilles 'SO- stop being evil' Nov 15 '19 at 18:30
  • 1
    what kind of program is that? a simple LD_PRELOAD hack which intercepts the read, recv, etc. calls and sleeps before returning the data may do. Otherwise, I may be mistaken, but I don't think you're be able to do that without privileges and/or virtualization. –  Nov 15 '19 at 20:11
  • @mosvy The program is a python script. I tested trickle out with python (using youtube-dl) but it didn't seem to have an effect. – Paul Nov 15 '19 at 20:35
  • @Paul, trickle works for me with youtube-dl. What system are you on? – Stéphane Chazelas Nov 16 '19 at 09:11
  • @StéphaneChazelas I am using Ubuntu 19.10, Python 3.7. An example trickle command I tried is "trickle -d 5 youtube-dl URL" – Paul Nov 16 '19 at 17:02
  • @Paul, indeed, I find trickle or tsocks works with python2.7, but not with python3.6 on Ubuntu 18.04. dante's socksify with my approach works though. Must be down to which network functions python3 uses and that those tools hijack or not. – Stéphane Chazelas Nov 16 '19 at 19:22

1 Answers1

1

Beside trickle, a possible hacky way that also has the benefit of giving some live status of the "speed" of throttled connection and lets you share the throttled connection between independent applications:

ssh -D 1080 -N -o ProxyCommand='
    pv -B8K -trabcN OUT -L2K |
    socat - tcp:%h:%p,rcvbuf=8K |
    pv -B8K -trabcN  IN -L30K' localhost

To launch a SOCKS5 server that is throttled because of the proxy command that is slowed down by pv's rate limiting (-L), here throttling output and input at different rates.

And then socksify your command with tsocks for instance configured with a ~/.tsocks.conf like:

server = 127.0.0.1
server_port = 1080
server_type = 5

Downloading some iso image without tsocks:

$ wget -O /dev/null http://releases.ubuntu.com/18.10/ubuntu-18.10-live-server-amd64.iso
/dev/null             2%[                    ]  19.60M  1.99MB/s    eta 6m 47s

the same socksified:

$ tsocks wget -O /dev/null http://releases.ubuntu.com/18.10/ubuntu-18.10-live-server-amd64.iso
/dev/null             0%[                    ] 802.40K  29.3KB/s    eta 3h 21m

Meanwhile, the pv output looks like:

      OUT: 3.65KiB 0:00:32 [0.00 B/s] [ 116 B/s]
       IN:  960KiB 0:00:32 [30.5KiB/s] [30.0KiB/s]

(shows both current speed (-r) and average (-a)).

tsocks or other socksifying commands inject code in executables (using $LD_PRELOAD) to hijack their networking functions so they go through the SOCKS server. That won't work for commands that are statically linked or are setuid/setgid...

Also note that tsocks only does TCP. I believe ssh's SOCKS server also only does TCP, so even if you switched to another socksifier like dante's, you would still not be able to throttle UDP traffic that way. You could try and devise a similar approach using dante's SOCKS server instead of ssh though.

edit. When it comes to python3, I find that neither trickle nor tsocks manage to divert python3's networking (testing with youtube-dl). dante's socksify seems to work though. To use it, create a ~/.dante.conf like:

route {
        from: 0.0.0.0/0   to: 0.0.0.0/0   via: 127.0.0.1 port = 1080
}

And call your application as:

SOCKS_CONF=~/.dante.conf socksify youtube-dl https://...