Speedbump - proxy TCP com latência variável
(github.com/kffl)- Speedbump é um proxy TCP escrito em Go que adiciona latência de rede variável ao tráfego TCP encaminhado pelo proxy para simular cenários de atraso
- É possível somar à latência base componentes de latência em forma de onda senoidal, dente de serra, onda quadrada e onda triangular, e vários componentes podem ser combinados ao mesmo tempo
- O exemplo mostra uma configuração que faz proxy do tráfego para
localhost:80na porta2000, aplicando atraso base de100ms, amplitude senoidal de100mse período de1m - A instalação pode ser feita baixando os binários pré-compilados de cada release, compilando do código-fonte com
go build, ou executando a imagem de contêinerkffl/speedbump - Além da CLI, também pode ser usado como biblioteca por meio do pacote Go
lib, com ajuste de parâmetros como tamanho de buffer, tamanho da fila de atraso, nível de log, host de escuta e porta
Proxy para simulação de latência TCP
- Speedbump é um proxy TCP escrito em Go e pode simular latência de rede variável
- O destino do proxy é especificado pelo argumento
<destination>da CLI, no formatohost:post - O funcionamento padrão é encaminhar o tráfego TCP ao destino enquanto adiciona o atraso configurado
Instalação e formas de execução
- A forma mais fácil de instalar é baixar os binários pré-compilados anexados automaticamente em
Assetsde cada release - Para compilar a partir do código-fonte, clone o repositório e execute
go build - Para executar em contêiner, é possível usar a imagem kffl/speedbump
Exemplo básico de uso
- É possível escutar na porta
2000e encaminhar o tráfego TCP paralocalhost:80, aplicando latência base de100ms, amplitude senoidal de100mse período de1m- Essa configuração gera latência adicional máxima de
200mse mínima de0 - Exemplo de execução:
speedbump --latency=100ms --sine-amplitude=100ms --sine-period=1m --port=2000 localhost:80
- Essa configuração gera latência adicional máxima de
- A mesma configuração também pode ser executada com a imagem de contêiner
- Exemplo:
docker run --net=host kffl/speedbump:latest --latency=100ms --sine-amplitude=100ms --sine-period=1m --port=2000 localhost:80
- Exemplo:
- Também é possível configurar um componente de latência em dente de serra
- O exemplo usa latência base de
300ms, amplitude em dente de serra de200ms, período de2m, porta2000e destinolocalhost:80 - O comando é
speedbump --latency=300ms --saw-amplitude=200ms --saw-period=2m --port=2000 localhost:80
- O exemplo usa latência base de
Combinação de componentes de latência
- Speedbump pode aplicar vários componentes de latência ao mesmo tempo
- O README inclui um exemplo de gráfico de atraso combinando dente de serra e senoide
Argumentos da CLI e uso como biblioteca
speedbump --helpmostra o uso no formatospeedbump [<flags>] <destination>- As principais configurações de rede são as seguintes
--host: IP ou nome de host para escuta; se não for especificado, faz bind em todas as interfaces de rede--port: porta de escuta; o padrão é8000--buffer: tamanho do buffer usado na leitura TCP; o padrão é64KB--queue-size: tamanho da fila de atraso que armazena os buffers lidos; o padrão é1024
- Há valores padrão relacionados à latência e opções de forma de onda
--latency: latência base adicionada ao tráfego encaminhado; o padrão é5ms--sine-amplitude,--sine-period: amplitude e período da latência senoidal--saw-amplitude,--saw-period: amplitude e período da latência em dente de serra--square-amplitude,--square-period: amplitude e período da latência em onda quadrada--triangle-amplitude,--triangle-period: amplitude e período da latência em onda triangular
- Também há opções operacionais
--log-level: nível de log; os valores possíveis sãoDEBUG,TRACE,INFO,WARN,ERROR--version: exibe a versão da aplicação
- Speedbump também pode ser usado como biblioteca Go, fornecida por meio do pacote
lib - A licença é a Apache 2.0 License
1 comentários
Opiniões no Hacker News
Eu estava procurando algo parecido para testar várias implementações de ActivityPub em diferentes escalas e condições de rede, mas já tinha tudo de que precisava instalado na minha máquina com
tcNa minha distribuição, ele vinha incluído no pacote iproute2, e há uma explicação aqui também: https://wiki.archlinux.org/title/advanced_traffic_control
Para adicionar atraso a uma interface específica, basta executar algo como
tc qdisc add dev eth0 root netem delay 100msÉ fácil de usar, funciona bem também em contêineres Docker, permite aplicar condições como atraso, perda e duplicação de pacotes, e é bem possível que já esteja instalado
tc/netem/tbfsão realmente ótimos. Fiz uma GUI simples em Python por cima disso e rodei em um Pi dentro de uma case com tela sensível ao toque; era uma caixinha preta com opções como “queda de pacotes: [0%] [1%] [10%] [50%] / corrupção de pacotes: ...”, e os clientes ficavam bem impressionadosAchei curioso que front-ends parecidos não pareçam existir como produtos comerciais de hardware; se eu não deixei passar na busca, parece que não há isso no mercado
tcé que aplicá-lo a pacotes recebidos é meio estranho e trabalhosoAntigamente, criei meu próprio emulador para imitar um terminal comercial específico de satélite. Esse terminal acumulava pacotes em uma fila e, quando atingia um certo limite ou passava de um timeout, despejava tudo de uma vez; ele ainda tentava “gentilmente” reordenar pacotes pequenos para o início da fila a fim de reduzir a latência, mas a pilha TCP detestava isso
tcnão faz issoPode ser bem útil para simular os efeitos climáticos sobre satélite/RF variando com o tempo
A Netflix fez exatamente isso, e o nome era latency monkey
Descobrimos que determinar se um subserviço está “lento” é muito mais difícil do que determinar se está “indisponível”, então essa era uma forma importante de testar como o serviço lidava com lentidão e problemas de rede
A implementação era muito simples: descartava pacotes em uma taxa configurável, o que forçava retransmissões e fazia com que, do outro lado, os pacotes chegassem atrasados e fora de ordem
No fim, isso revelou muitos problemas no código de tratamento de erros relacionado a acesso à rede
Acho que todo engenheiro de software que cria aplicações interativas para a internet deveria usar ferramentas assim no trabalho diário. Não só para TCP, mas também para QUIC; e, para cobrir DNS, idealmente todo UDP também
Tenho certeza de que 90% do inchaço das aplicações web desapareceria se quem as cria não usasse apenas ambientes de computação tipo Cadillac banhado a ouro
https://firefox-source-docs.mozilla.org/devtools-user/networ...
Claro que isso se aplica apenas a testes de front-end baseados em navegador
Muitos apps funcionam muito mal em ambientes em que a conectividade de rede cai de forma intermitente, como em situações de ajuda em desastres
Seria útil para outras pessoas se mais desenvolvedores de apps testassem simulando conectividade intermitente
Do tópico “Toxiproxy is a framework for simulating network conditions” (2021) https://news.ycombinator.com/item?id=29084277#29088775:
Porque estão enviando apenas pacotes de 50 bytes, e 1 em cada 10 deles se perde. Enquanto isso, uma thread do servidor fica sem fazer nada útil
No Mac, dá para fazer a mesma coisa só com ferramentas integradas
Há um projeto que está inativo há algum tempo, mas cujo nome já diz muita coisa: https://github.com/tylertreat/comcast
Recentemente, ao tentar simular uma rede lenta no Mac, encontrei o Network Link Conditioner, que é bem bom. Não é preciso configurar nada como um proxy
É necessário instalá-lo a partir das ferramentas adicionais do Xcode
https://nshipster.com/network-link-conditioner/
Também vale conferir a excelente ferramenta toxiproxy, da Shopify: https://github.com/Shopify/toxiproxy
É também uma forma muito boa de testar implementações próprias de bibliotecas de rede, porque a pilha precisa lidar corretamente com a maioria das situações adversas
A ideia de “engenharia do caos” é ótima
Estou desenvolvendo uma barra de progresso para um web crawler, mas, testando em localhost, é rápido demais para perceber se há algum problema
Com o speedbump, basta executar
podman run --net=host kffl/speedbump:latest --latency=1s --port=8001 localhost:8000e testar o crawler em http://localhost:8001É uma ferramenta limpa
Usei uma ferramenta parecida no Windows
https://jagt.github.io/clumsy/
O FreeBSD também tem o dummynet como parte do ipfw, permitindo injetar atraso, limitação de largura de banda, tamanho de fila e perda de pacotes. É o mesmo recurso que existe no MacOS
tcno Linux?