Giter Club home page Giter Club logo

speedbump's Introduction

speedbump - TCP proxy with variable latency

speedbump logo
Speedbump is a TCP proxy written in Go which allows for simulating variable network latency.

CI Workflow Go Report Card Docker Pulls Docker Image Version GoDoc

Usage

Installation

The easiest way to install speedbump is to download pre-built binaries for your platform that are automatically attached to each release under Assets. If you wish to build speedbump from source, clone this repository and run go build. Alternatively, you can run speedbump as a container using the kffl/speedbump image.

Basic usage examples

Spawn a new instance listening on port 2000 that proxies TCP traffic to localhost:80 with a base latency of 100ms and sine wave amplitude of 100ms (resulting in maximum added latency being 200ms and minimum being 0), period of which is 1 minute:

speedbump --latency=100ms --sine-amplitude=100ms --sine-period=1m --port=2000 localhost:80

or when running speedbump using the kffl/speedbump container image:

docker run --net=host kffl/speedbump:latest --latency=100ms --sine-amplitude=100ms \
           --sine-period=1m --port=2000 localhost:80

Spawn a new instance with a base latency of 300ms and a sawtooth wave latency summand with amplitude of 200ms and period of 2 minutes (visualized by the graph below):

speedbump --latency=300ms --saw-amplitude=200ms --saw-period=2m --port=2000 localhost:80
speedbump sawtooth wave graph

Combining latency summands

It is possible to run speedbump with multiple latency summands at once:

speedbump sawtooth + sine graph

CLI Arguments Reference:

Output of speedbump --help:

usage: speedbump [<flags>] <destination>

TCP proxy for simulating variable network latency.

Flags:
  --help                  Show context-sensitive help (also try --help-long and
                          --help-man).
  --host=""               IP or hostname to listen on. Speedbump will bind to
                          all available network interfaces if unspecified.
  --port=8000             Port number to listen on.
  --buffer=64KB           Size of the buffer used for TCP reads.
  --queue-size=1024       Size of the delay queue storing read buffers.
  --latency=5ms           Base latency added to proxied traffic.
  --log-level=INFO        Log level. Possible values: DEBUG, TRACE, INFO, WARN,
                          ERROR.
  --sine-amplitude=0      Amplitude of the latency sine wave.
  --sine-period=0         Period of the latency sine wave.
  --saw-amplitude=0       Amplitude of the latency sawtooth wave.
  --saw-period=0          Period of the latency sawtooth wave.
  --square-amplitude=0    Amplitude of the latency square wave.
  --square-period=0       Period of the latency square wave.
  --triangle-amplitude=0  Amplitude of the latency triangle wave.
  --triangle-period=0     Period of the latency triangle wave.
  --version               Show application version.

Args:
  <destination>  TCP proxy destination in host:post format.

Using speedbump as a library

Speedbump can be used as a Go library via its lib package. Check lib README for additional information.

License

Copyright Paweł Kuffel 2022, licensed under Apache 2.0 License.

Speedbump logo contains the Go Gopher mascot which was originally designed by Renee French (http://reneefrench.blogspot.com/) and licensed under Creative Commons 3.0 Attributions license.

speedbump's People

Contributors

dependabot[bot] avatar kffl avatar roertbb avatar szkf avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

speedbump's Issues

Add delay queue size config parameter

As of now, the delay queue (which stores buffers read from source before they are sent to proxy destination) has a hard-coded size of 1024. When the queue is full, new read operations are not performed until the underlying buffered channel has some transit buffers consumed from it, which may result in additional delay being introduced on top of the simulated one. For this reason it may be beneficial to let the developer tweak not only the size of the read buffers, but also the size of the delay queue storing them i.e. via --queue-size CLI flag.

Support for using speedbump as a library

As of now, speedbump can only be used as a standalone program. There are some potential use cases for calling speedbump as an external library from within other Go code (i.e. for the purpose of adding programmatic TCP delay during a e2e test or a load test).

In order for speedbump to be used as a library, the following changes need to be made:

  • adding support for graceful shutdown (i.e. .Stop() method on a Sppedbump instance), related to #6
  • adding required go docs comments to exported members
  • exporting some currently unexported config struct fields

`lib` API improvements

As discussed in the recent PRs (17, 18), the API exposed by the lib package that allows other Go programs to use speedbump as a dependency could see some improvements to make it more intuitive, namely:

  • the Start() method could return immediately in case of both the proxy starting successfully (instead of blocking until Stop() is called) as well as a startup error occurring
  • the Stop() method could wait until all connections are closed before returning (which is currently indicated by Start() returning)

Such changes would require a major release bump due to their breaking nature, timing for which appears to be quite good, especially given the fact that #18 fixed an exported field name typo in an exported struct LatencyCfg.

Logging improvements

As of now, logging is done via fmt.Printf and fmt.Println, which doens't scale well. A logging library could be used instead that would support:

  • different log levels (specified via a CLI flag)
  • key/value pairs added to log entries (i.e. connection ID, error)
  • child loggers with fixed k/v pairs (i.e. connection-scoped ones that would include the connection ID)

Allow providing interface to bind to e.g. 127.0.0.1?

Happy to find this today.

My understanding of go isn't the greatest, but it looks like this listens on all available interfaces. Is it possible to specify the network interface? Or somehow only bind to loopback?

Graceful shutdown

A graceful shutdown mechanism could be implemented that would close the existing proxy connections (both the src->proxy and proxy->dest TCP connections for each active connection) before the process exits upon receiving SIGINT/SITERM.

Square wave latency summand

Hi,

I can see that the square wave latency summand is planned in the roadmap:

Additional latency summands (i.e. triangle wave and square wave)

I would like to implement it.

Adding symmetrical delay (feature request)

Hi. First off, thanks for sharing this utility, it has been great for testing out the netcode in my hobby game project.

One thing I noticed when performing testing was that the delay seems to be added in just a single direction, leading to highly asymmetric one way delays.

For example, with a 500ms latency setting connecting two netcat endpoints:

Node A: nc localhost 2500
Node B: speedbump --latency=500ms --port=2500 localhost:5555
Node C: nc -l -p 5555

I see that from A->C, ~500ms latency is added (confirmed with wireshark looking at the loopback interface). However, from C->A there seems to be no additional latency added.

Is there a mode where I can add symmetrical, 250ms of latency in each direction for a total round trip time of 500ms?

In practice the forward one way delay and backwards one way delay would not be exactly equal. In "extreme" examples, they may be quite different (for instance on satellite internet, or a home internet connection heavily loaded in just one direction). However, under good network connections, I think having the latency be roughly symmetric is somewhat reasonable...

Do you think this would be a generally useful option to have? would love to hear your thoughts on it.

I ran the above test using the code at git commit a556c99.

Documentation improvements

The following improvements should be made to the documentation:

  • a diagram illustrating the inner workings of speedbump, especially the fact that the delay queue works in the client -> proxy dest direction and not the other way around;
  • description of motivation behind building the project and its common use cases (testing application instrumentation stacks)
  • a link to the project's roadmap in README.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.