4 points par GN⁺ 2024-01-17 | 1 commentaires | Partager sur WhatsApp
  • Speedbump est un proxy TCP écrit en Go, qui ajoute une latence réseau variable au trafic TCP relayé afin de simuler des conditions de délai
  • Il est possible d’ajouter à la latence de base des composantes de latence en forme d’onde sinusoïdale, en dents de scie, carrée et triangulaire, et plusieurs composantes peuvent être combinées simultanément
  • L’exemple montre une configuration qui proxyfie le trafic à destination de localhost:80 sur le port 2000, avec un délai de base de 100ms, une amplitude sinusoïdale de 100ms et une période de 1m
  • L’installation est possible via le téléchargement de binaires précompilés publiés avec chaque release, via go build depuis le code source, ou en exécutant l’image de conteneur kffl/speedbump
  • En plus de la CLI, l’outil peut aussi être utilisé comme bibliothèque via le package Go lib, avec des paramètres pour ajuster la taille du buffer, celle de la file d’attente de latence, le niveau de logs, ainsi que l’hôte et le port d’écoute

Proxy pour simuler la latence TCP

  • Speedbump est un proxy TCP écrit en Go, capable de simuler une latence réseau variable
  • La destination du proxy se spécifie via l’argument CLI <destination>, indiqué au format host:post
  • Son fonctionnement de base consiste à relayer le trafic TCP vers la destination tout en y ajoutant le délai configuré

Installation et modes d’exécution

  • La méthode d’installation la plus simple consiste à télécharger les binaires précompilés automatiquement joints dans les Assets de chaque release
  • Pour compiler depuis les sources, il suffit de cloner le dépôt puis d’exécuter go build
  • Pour l’exécuter en conteneur, on peut utiliser l’image kffl/speedbump

Exemple d’utilisation de base

  • Il est possible d’écouter sur le port 2000 et de proxyfier le trafic TCP vers localhost:80 en appliquant un délai de base de 100ms, une amplitude sinusoïdale de 100ms et une période de 1m
    • Cette configuration produit une latence additionnelle maximale de 200ms et minimale de 0
    • Exemple d’exécution : speedbump --latency=100ms --sine-amplitude=100ms --sine-period=1m --port=2000 localhost:80
  • La même configuration peut aussi être exécutée avec l’image de conteneur
    • Exemple : docker run --net=host kffl/speedbump:latest --latency=100ms --sine-amplitude=100ms --sine-period=1m --port=2000 localhost:80
  • Une composante de latence en dents de scie peut également être configurée
    • L’exemple utilise un délai de base de 300ms, une amplitude en dents de scie de 200ms, une période de 2m, le port 2000 et la destination localhost:80
    • La commande d’exécution est speedbump --latency=300ms --saw-amplitude=200ms --saw-period=2m --port=2000 localhost:80

Combinaison de composantes de latence

  • Speedbump peut appliquer plusieurs composantes de latence en même temps
  • Le README inclut un exemple de graphe de latence combinant une onde en dents de scie et une onde sinusoïdale

Arguments CLI et utilisation comme bibliothèque

  • speedbump --help fournit une syntaxe d’utilisation au format speedbump [<flags>] <destination>
  • Les principaux paramètres réseau sont les suivants
    • --host : IP ou nom d’hôte d’écoute ; s’il n’est pas spécifié, l’outil se lie à toutes les interfaces réseau
    • --port : port d’écoute, avec une valeur par défaut de 8000
    • --buffer : taille du buffer utilisé pour la lecture TCP, avec une valeur par défaut de 64KB
    • --queue-size : taille de la file d’attente de latence où sont stockés les buffers lus, avec une valeur par défaut de 1024
  • Des valeurs par défaut et des options de forme d’onde sont proposées pour la latence
    • --latency : latence de base ajoutée au trafic relayé, avec une valeur par défaut de 5ms
    • --sine-amplitude, --sine-period : amplitude et période de la latence sinusoïdale
    • --saw-amplitude, --saw-period : amplitude et période de la latence en dents de scie
    • --square-amplitude, --square-period : amplitude et période de la latence carrée
    • --triangle-amplitude, --triangle-period : amplitude et période de la latence triangulaire
  • Des options liées à l’exploitation sont également incluses
    • --log-level : niveau de logs, avec les valeurs possibles DEBUG, TRACE, INFO, WARN, ERROR
    • --version : affiche la version de l’application
  • Speedbump peut aussi être utilisé comme bibliothèque Go via le package lib
  • La licence est l’Apache 2.0 License

1 commentaires

 
GN⁺ 2024-01-17
Commentaires sur Hacker News
  • J’avais cherché quelque chose de similaire pour tester différentes implémentations ActivityPub à diverses échelles et dans diverses conditions réseau, mais j’avais déjà tout ce qu’il fallait installé sur ma machine avec tc
    Sur ma distribution, c’était inclus dans le paquet iproute2, et c’est aussi expliqué ici : https://wiki.archlinux.org/title/advanced_traffic_control
    Pour ajouter de la latence sur une interface donnée, il suffit d’exécuter quelque chose comme tc qdisc add dev eth0 root netem delay 100ms
    C’est facile à utiliser, ça fonctionne bien aussi dans des conteneurs Docker, on peut appliquer des conditions comme la latence, la perte de paquets ou les doublons, et il est possible que ce soit déjà installé

    • tc/netem/tbf, c’est vraiment excellent. J’avais construit une petite interface graphique Python par-dessus et je l’avais fait tourner sur un Pi dans un boîtier à écran tactile ; c’était une petite boîte noire avec “perte de paquets : [0%] [1%] [10%] [50%] / corruption de paquets : ...”, et les clients étaient assez impressionnés
      Ce qui est surprenant, c’est qu’on ne voit pas vraiment de frontend similaire sous forme de produit matériel commercial ; sauf si je l’ai raté dans mes recherches, ça n’existe pas sur le marché
    • L’inconvénient de tc, c’est que c’est un peu bizarre et pénible si on veut l’appliquer aux paquets entrants
      J’avais autrefois construit mon propre émulateur pour imiter un terminal satellite commercial précis. Cet équipement mettait les paquets en file d’attente, puis les expulsait d’un coup lorsqu’un certain seuil était atteint ou qu’une limite de temps était dépassée ; il essayait aussi de “gentiment” réordonner les petits paquets vers le début de la file pour réduire la latence, mais la pile TCP détestait vraiment ça
    • Ce qui est bien avec speedbump, c’est qu’on peut faire varier les conditions de panne dans le temps. tc ne sait pas faire ça
      Cela pourrait être très utile pour simuler les effets météo sur des liaisons satellite/RF qui évoluent au fil du temps
  • C’est exactement ce que Netflix avait créé, et ça s’appelait latency monkey
    Ils se sont rendu compte qu’il est bien plus difficile de déterminer si un service est “lent” que de déterminer s’il est “indisponible”, et c’était donc un moyen important de tester la façon dont les services gèrent les ralentissements et les problèmes réseau
    L’implémentation était très simple : elle supprimait des paquets selon un taux configurable, ce qui forçait les retransmissions ; côté distant, les paquets arrivaient alors en retard et dans le désordre
    Au final, cela a permis de trouver beaucoup de problèmes dans le code de gestion d’erreurs lié à l’accès réseau

  • À mon avis, tous les ingénieurs logiciels qui créent des applications Internet interactives devraient absolument utiliser ce genre d’outils au quotidien. Il ne faut pas seulement TCP, mais aussi QUIC, et idéalement tout l’UDP si on veut couvrir aussi le DNS
    Je suis convaincu que 90 % de l’embonpoint des applis web disparaîtrait si les gens qui les développent n’utilisaient pas uniquement des environnements de calcul façon Cadillac suréquipée

  • Dans des situations comme les opérations de secours en cas de catastrophe, où la connectivité réseau est intermittente, beaucoup d’applications se comportent très mal
    Si davantage de développeurs d’applications testaient en simulant une connectivité intermittente, cela pourrait aider les autres
    Extrait de “Toxiproxy is a framework for simulating network conditions” (2021) https://news.ycombinator.com/item?id=29084277#29088775 :

    Beaucoup d’applications n’ont pas, par exemple, la fonctionnalité « mettre dans la boîte d’envoi » qu’on attend d’un client mail

    • [ ] Quelqu’un pourrait-il créer un ensemble de « mutations de cas de test » toxiproxy de référence pour simuler les problèmes de connectivité typiques du #DisasterRelief ?
    • Ce que je déteste le plus, c’est quand on ne remplit pas les buffers avant d’envoyer les paquets. Dans ce cas, avec une mauvaise connexion Internet, donc avec perte de paquets et forte latence entraînant des retransmissions TCP, on tombe soudain à 120kps
      Parce qu’on n’envoie que des paquets de 50 octets, et qu’un sur dix est perdu. Pendant ce temps, un thread du serveur ne fait rien d’utile
  • Sur Mac, on peut faire la même chose avec les outils intégrés

    # Setup pipe  
    sudo dnctl pipe 1 config bw 1Kbit/s delay 800
    
    # Setup matching pf rule  
    echo "dummynet out proto tcp from any to 127.0.0.1 port 11211 pipe 1" | sudo pfctl -f -
    
    # Turn on firewall  
    sudo pfctl -e
    
    # Test  
    time nc -vz 127.0.0.1 11211  
    Connection to 127.0.0.1 port 11211 [tcp/*] succeeded!  
    nc -vz 127.0.0.1 11211 0.01s user 0.00s system 0% cpu 1.333 total  
    
    • Dummynet et ces fonctionnalités viennent de FreeBSD, où elles existent depuis très longtemps. Je m’en servais déjà pour tester la perte de paquets il y a plus de 15 ans, et ça marchait bien
  • Il existe aussi un projet inactif depuis un moment, mais dont le nom en dit long : https://github.com/tylertreat/comcast

  • Récemment, en essayant de simuler un réseau lent sur Mac, je suis tombé sur Network Link Conditioner, et c’est plutôt bien. Pas besoin de configurer quelque chose comme un proxy
    Il faut l’installer depuis les outils additionnels de Xcode
    https://nshipster.com/network-link-conditioner/

  • Le très bon outil toxiproxy de Shopify vaut aussi le détour : https://github.com/Shopify/toxiproxy
    C’est aussi une très bonne manière de tester en implémentant soi-même une bibliothèque réseau, car la pile doit être capable de gérer correctement la plupart des situations défavorables
    L’idée de « chaos engineering » est géniale

    • J’avais moi aussi trouvé toxiproxy au départ, mais son modèle client-serveur ne me convenait pas, alors que speedbump correspondait exactement à mon besoin de simulation de latence HTTP
      Je développe une barre de progression pour un crawler web, et tester en localhost va trop vite pour voir facilement s’il y a un problème
      Avec speedbump, il suffit d’exécuter podman run --net=host kffl/speedbump:latest --latency=1s --port=8001 localhost:8000, puis de tester le crawler sur http://localhost:8001
      C’est un outil propre et élégant
  • J’ai déjà utilisé un outil similaire sur Windows
    https://jagt.github.io/clumsy/

    • Je m’en suis servi il y a une dizaine d’années pour tester diverses conditions réseau intercontinentales, et les résultats correspondaient bien à la réalité. Je le recommande
    • Ça a l’air sympa, mais à voir la capture d’écran, on dirait plutôt une application à l’échelle du système avec filtrage, plutôt qu’une application par adaptateur
  • Sur FreeBSD aussi, il y a dummynet comme composant d’ipfw, ce qui permet d’injecter de la latence, des limitations de bande passante, de la taille de file d’attente et de la perte de paquets. C’est la même fonctionnalité que sur macOS

    • C’est l’équivalent de tc sur Linux ?