
Un outil de réplication de requêtes en ligne et de rejeu de flux TCP, idéal pour les tests réels, les tests de performance, les tests de stabilité, les tests de résistance, les tests de charge, les tests de fumée, et plus encore.
TCPCopy est un outil de rejeu de flux TCP pour des tests réalistes d'applications serveur Internet.
Un aperçu de TCPCopy pour les débutants
Un aperçu général de l'architecture de TCPCopy
Cas d'utilisation des tests avec TCPCopy
Exemples de préchauffage avec TCPCopy
Bien que le trafic réel soit crucial pour tester les applications serveur Internet, sa simulation précise est difficile en raison de la complexité des environnements en ligne. Pour permettre des tests plus réalistes, TCPCopy a été développé comme un outil de reproduction de flux en direct qui génère des charges de test très proches des charges de production. TCPCopy est largement utilisé par des entreprises en Chine.
TCPCopy a un impact minimal sur le système de production, ne consommant que du CPU, de la mémoire et de la bande passante supplémentaires. La charge reproduite reflète l'environnement de production en termes de diversité des requêtes, de latence réseau et d'utilisation des ressources.

Figure 1. Aperçu de l'architecture de TCPCopy.
Comme le montre la figure 1, TCPCopy se compose de deux composants : tcpcopy et intercept. Le composant tcpcopy s'exécute sur le serveur en ligne, capturant les requêtes en direct, tandis que intercept fonctionne sur le serveur assistant, effectuant des tâches telles que la transmission des informations de réponse à tcpcopy. L'application de test elle-même s'exécute sur le serveur cible.
Par défaut, tcpcopy utilise des sockets bruts pour capturer les paquets au niveau réseau (représentés par les flèches orange dans la figure). Il gère des processus tels que la simulation d'interaction TCP, le contrôle de la latence réseau et la simulation d'interaction de couche supérieure. Il envoie ensuite les paquets au serveur cible à l'aide de sockets bruts pour la sortie (représentés par les flèches rouge clair dans la figure).
La seule tâche requise sur le serveur cible est de configurer les règles de routage pour diriger les paquets de réponse (représentés par les flèches vert clair dans la figure) vers le serveur assistant.
Le rôle du composant intercept est de transmettre l'en-tête de réponse (par défaut) à tcpcopy. Il capture les paquets de réponse, extrait les informations de l'en-tête de réponse et envoie ces informations à tcpcopy via un canal dédié (représenté par les flèches bleu clair dans la figure). Dès réception de l'en-tête de réponse, tcpcopy utilise les informations pour modifier les attributs des paquets en ligne et continue d'envoyer les paquets suivants.
Il est important de noter que les réponses du serveur cible sont routées vers le serveur assistant, qui fonctionne comme un trou noir.
Pour intercept, vous avez deux options :
git clone git://github.com/session-replay-tools/intercept.git.Pour tcpcopy, vous avez également deux options :
git clone git://github.com/session-replay-tools/tcpcopy.git.intercept :cd intercept./configure makeintercept :make installintercept--single
Exécute intercept en mode non distribué.
--with-pfring=PATH
Spécifiez le chemin vers les sources de la bibliothèque PF_RING.
--with-debug
Compile intercept avec le support de débogage, les journaux étant enregistrés dans un fichier.
tcpcopy sur le serveur en lignetcpcopy : cd tcpcopy./configure maketcpcopy : make installtcpcopy--offline
Rejoue les flux TCP à partir d'un fichier pcap.
--pcap-capture
Capture les paquets au niveau de la couche liaison de données.
--pcap-send
Envoie les paquets au niveau de la couche liaison de données au lieu de la couche IP.
--with-pfring=PATH
Spécifiez le chemin vers les sources de la bibliothèque PF_RING.
--set-protocol-module=PATH
Configure tcpcopy pour fonctionner avec un module de protocole externe.
--single
Si intercept et tcpcopy sont tous deux configurés avec l'option --single, une seule instance de tcpcopy fonctionnera avec intercept, ce qui améliore les performances.
Supposons que tcpcopy et intercept soient tous deux configurés avec ./configure.
Sur le serveur cible exécutant les applications serveur :
Configurez les règles de routage pour diriger les paquets de réponse vers le serveur assistant. Par exemple, si 61.135.233.161 est l'adresse IP du serveur assistant, utilisez la commande de routage suivante pour diriger toutes les réponses des clients de la plage 62.135.200.x vers le serveur assistant :
route add -net 62.135.200.0 netmask 255.255.255.0 gw 61.135.233.161
Sur le serveur assistant exécutant intercept (privilège root ou capacité CAP_NET_RAW requise) :
./intercept -F <filtre> -i <périphérique>
Notez que le format du filtre est identique à celui du filtre pcap. Par exemple :
./intercept -i eth0 -F 'tcp and src port 8080' -d
Dans cet exemple, intercept capture les paquets de réponse d'une application basée sur TCP écoutant sur le port 8080, en utilisant le périphérique réseau eth0.
Veuillez noter que ip_forward n'est pas activé sur le serveur assistant.
Sur le serveur source en ligne (privilège root ou capacité CAP_NET_RAW requise) :
./tcpcopy -x portServeurLocal-adresseServeurCible:portServeurCible -s <serveur intercept> [-c <plage IP>]
CAP_NET_RAW (par exemple, setcap CAP_NET_RAW=ep tcpcopy)../configure --with-resp-payload pour intercept ne peut pas être utilisée avec l'option ./configure pour tcpcopy.ip_forward n'est pas activé sur le serveur assistant.Plusieurs facteurs peuvent affecter TCPCopy, comme détaillé dans les sections suivantes.
Par défaut, tcpcopy utilise une interface d'entrée par socket brut pour capturer les paquets au niveau réseau sur le serveur en ligne. Sous forte charge, le noyau du système peut perdre certains paquets.
S'il est configuré avec --pcap-capture, tcpcopy capture les paquets au niveau de la couche liaison de données et peut filtrer les paquets dans le noyau. L'utilisation de PF_RING avec la capture pcap peut réduire la perte de paquets.
Pour une capture optimale, envisagez de mettre en miroir les paquets entrants via un commutateur et de distribuer le trafic sur plusieurs machines à l'aide d'un équilibreur de charge.
tcpcopy utilise par défaut une interface de sortie par socket brut pour envoyer les paquets au niveau réseau vers le serveur cible. Pour éviter les problèmes de ip_conntrack ou améliorer les performances, utilisez --pcap-send pour envoyer les paquets au niveau de la couche liaison de données.
Les paquets envoyés par tcpcopy peuvent rencontrer des difficultés avant d'atteindre le serveur cible. Si l'adresse IP source est l'adresse IP de l'utilisateur final (par défaut), les dispositifs de sécurité peuvent supprimer le paquet comme invalide ou falsifié. Pour tester cela, utilisez tcpdump sur le serveur cible. Si les paquets sont envoyés avec succès dans le même segment réseau mais pas entre segments, les paquets peuvent être supprimés en cours de route.
Pour résoudre ce problème, déployez tcpcopy, les applications cibles et intercept dans le même segment réseau. Sinon, utilisez un proxy dans le même segment pour transférer les paquets vers le serveur cible dans un autre segment.
Le déploiement de l'application du serveur cible sur une machine virtuelle dans le même segment peut toujours rencontrer ces problèmes.
Le serveur cible peut utiliser rpfilter pour vérifier la légitimité des adresses IP sources, supprimant les paquets considérés comme falsifiés. Si les paquets sont capturés par tcpdump mais non traités, vérifiez les paramètres rpfilter et ajustez-les ou supprimez-les si nécessaire. D'autres problèmes comme les paramètres iptables peuvent également affecter tcpcopy.
Les applications sur le serveur cible peuvent ne pas traiter toutes les requêtes rapidement. Des bogues ou des limitations de l'application peuvent entraîner des réponses retardées ou des requêtes non traitées dans le tampon de socket.
Assurez-vous que ip_forward est défini sur false sur le serveur assistant pour l'empêcher de router les paquets et garantir qu'il fonctionne comme un trou noir.
Tout d'abord, utilisez telnet sur le serveur en ligne pour vous connecter au port du serveur de test. Cela permettra de vérifier si le chemin réseau est accessible. Si la connexion échoue, résolvez ce problème avant de poursuivre les diagnostics suivants.
Supposons que lors du test tcpcopy, l'application sur le serveur de test ne reçoive aucune requête. Déterminez si le paquet d'initialisation de connexion (c'est-à-dire le paquet SYN) atteint le serveur de test.
1.1 Seuls les paquets SYN sont capturés :
Si vous utilisez tcpdump sur le serveur de test et constatez que les paquets SYN répliqués arrivent, cela indique qu'ils ont atteint la couche liaison de données du serveur de test. Si netstat n'affiche aucune connexion pour l'application, cela signifie que les paquets ont été supprimés au niveau IP. Vérifiez si rpfilter est configuré — si c'est le cas, supprimez ce paramètre, et le problème devrait généralement être résolu. Si rpfilter n'est pas configuré, confirmez qu'il n'y a pas de conflits dans les paramètres iptables et ajustez les règles concernées si nécessaire.
1.2 SYN suivi d'un paquet RST : Si le paquet SYN est immédiatement suivi d'un paquet de réinitialisation (RST) (moins d'une seconde entre eux dans la même session), cela indique un problème de routage ou un conflit, provoquant l'envoi du paquet de réponse directement au client réel.
1.3 Le serveur de test répond avec le deuxième paquet d'initialisation : Capturez les paquets sur le serveur assistant pour vérifier si le deuxième paquet d'initialisation l'a atteint.
Si le paquet n'a pas atteint le serveur assistant, cela suggère que la configuration de routage n'est pas efficace, et donc intercept ne peut pas capturer le deuxième paquet d'initialisation, empêchant la poursuite du rejeu. Une solution possible est d'exécuter intercept directement sur le serveur de test (note : gardez la configuration de routage inchangée, et assurez-vous que le paramètre -c dans tcpcopy n'est pas défini sur l'adresse IP utilisée par tcpcopy pour se connecter à intercept, sinon tcpcopy ne pourra pas se connecter à intercept).
Si le deuxième paquet d'initialisation est capturé, vérifiez si ip_forward est activé. Si c'est le cas, désactivez ce paramètre, car il peut amener les paquets de réponse à être envoyés directement au client, interférant avec le test.
2.1 Paquets tcpcopy capturés sur le serveur en ligne :
Si vous capturez les paquets transférés par tcpcopy à l'aide de tcpdump sur le serveur en ligne, mais que les paquets n'atteignent pas le serveur de test, cela indique qu'ils ont été supprimés en cours de route. Vous pouvez essayer d'utiliser le paramètre -c dans tcpcopy pour modifier l'adresse IP du client en une adresse valide. Dans les cas extrêmes, définissez l'adresse IP du client sur l'adresse IP de la machine exécutant tcpcopy (note : des problèmes de NAT peuvent survenir, et si intercept s'exécute sur le serveur de test, assurez-vous que le paramètre -c dans tcpcopy n'est pas défini sur l'adresse IP utilisée par tcpcopy pour se connecter à intercept, sinon tcpcopy ne pourra pas se connecter à intercept).
2.2 Paquets tcpcopy non capturés sur le serveur en ligne :
Si aucune information all clt:xx n'est trouvée dans le journal de tcpcopy, cela indique que tcpcopy ne parvient pas à capturer les paquets au niveau IP. Dans ce cas, utilisez l'option --pcap-capture pour capturer les paquets au niveau de la couche liaison de données. Définissez le paramètre -F (par exemple, 'tcp and dst port 80 and dst host 10.100.1.2') et le paramètre -i (interface réseau) pour contourner la capture au niveau IP.
Si all clt:xx, où xx > 0, est visible dans le journal de tcpcopy, cela signifie que tcpcopy a capturé le paquet avec succès, mais qu'il a été filtré par la couche IP sur le serveur en ligne. Vérifiez les restrictions iptables sur la chaîne de sortie, entre autres paramètres. Si iptables est le problème et ne peut pas être modifié sur le serveur en ligne, utilisez l'option pour envoyer les paquets depuis la couche liaison de données.
Vous avez un bogue ou une demande de fonctionnalité ? Veuillez ouvrir un nouveau ticket. Avant d'ouvrir un ticket, veuillez rechercher les tickets existants.
Si vous trouvez ce projet utile, envisagez de faire un don :
Copyright 2025 sous la licence BSD.
Plusieurs personnes ont été cruciales dans la rédaction de ce document en relisant les brouillons et en offrant des commentaires. Je suis particulièrement reconnaissant pour les contributions de Hongshen Wang.
--with-tcmalloc
Utilise tcmalloc au lieu de malloc.
--with-debug
Compile tcpcopy avec le support de débogage, les journaux étant enregistrés dans un fichier.
Par exemple (en supposant que 61.135.233.160 est l'adresse IP du serveur cible) :
./tcpcopy -x 80-61.135.233.160:8080 -s 61.135.233.161 -c 62.135.200.x
Dans cet exemple, tcpcopy capture les paquets sur le port 80 du serveur actuel, change l'adresse IP du client en une adresse de la plage 62.135.200.x et envoie ces paquets au port 8080 du serveur cible (61.135.233.160). Il se connecte également à 61.135.233.161 pour demander à intercept de transmettre les paquets de réponse. Le paramètre -c est optionnel, mais il est utilisé ici pour simplifier les règles de routage.
./tcpcopy -h./intercept -h--pcap-send