Tailles de paquets dans un flux TCP

10

Je fais du trafic réseau et je souhaite diviser chaque session TCP en une série de demandes et de réponses (les protocoles avec lesquels je travaille fonctionnent de cette façon, comme HTTP ou SSL).

J'avais une supposition simple (ignorer les paquets en panne et renvoyés) - étant donné un bloc de données qui doit être envoyé, il sera envoyé en utilisant les plus grands paquets possibles et le dernier paquet sera soit plus petit que la taille maximale, soit suivi par un paquet de l'autre côté (en ignorant les paquets vides ACK). Donc, dans une session HTTP, je m'attends à voir quelque chose comme (encore une fois, sans tenir compte des acks) -

Paquet 1 - Demande "Get ..."

Paquet 2 - Response, taille 1434

Paquet 3 - Response, taille 1434

Paquet 4 - Response, taille 1434

Paquet 5 - Response, taille 500

C'est ce que j'obtiens sur la plupart des séances, mais il y a au moins une occasion que j'ai vue qui ressemblait à

Paquet 1 - Demande "Get ..."

Paquet 2 - Response, taille 1434

Paquet 3 - Réponse, taille 1080

Paquet 4 - Response, taille 1434

Paquet 5 - Response, taille 500

Pas de retransmissions, de paquets en panne ici ou pas de retards exceptionnels sur le serveur.

Je veux savoir - qu'est-ce qui peut provoquer cela et quand cela se produira-t-il? À quel point mon hypothèse est-elle fausse?

METTRE À JOUR

Je mets un exemple de fichier pcap ici

MISE À JOUR 2

Y compris un tsharkvidage avec les champs pertinents ...

$ tshark -r http_1082.pcap -T fields -e frame.number -e frame.len \
    -e ip.src -e ip.dst -e tcp.flags.push -e http.request.method \
    -e http.request.uri -e http.response.code | head -n 47
1     66      192.168.1.103    206.33.49.126    0            
2     62      206.33.49.126    192.168.1.103    0            
3     64      192.168.1.103    206.33.49.126    0            
4     411     192.168.1.103    206.33.49.126    1    GET    /money/.element/script/3.0/video/xmp/xmp_playlistapi.js    
5     54      206.33.49.126    192.168.1.103    0            
6     1434    206.33.49.126    192.168.1.103    0            
7     1434    206.33.49.126    192.168.1.103    0            
8     64      192.168.1.103    206.33.49.126    0            
9     1434    206.33.49.126    192.168.1.103    0            
10    1434    206.33.49.126    192.168.1.103    0            
11    1434    206.33.49.126    192.168.1.103    0            
12    64      192.168.1.103    206.33.49.126    0            
13    1434    206.33.49.126    192.168.1.103    0            
14    1434    206.33.49.126    192.168.1.103    0            
15    1434    206.33.49.126    192.168.1.103    0            
16    1434    206.33.49.126    192.168.1.103    0            
17    64      192.168.1.103    206.33.49.126    0            
18    1434    206.33.49.126    192.168.1.103    0            
19    1434    206.33.49.126    192.168.1.103    0            
20    1434    206.33.49.126    192.168.1.103    0            
21    1434    206.33.49.126    192.168.1.103    0            
22    1434    206.33.49.126    192.168.1.103    0            
23    64      192.168.1.103    206.33.49.126    0            
24    1434    206.33.49.126    192.168.1.103    0            
25    1434    206.33.49.126    192.168.1.103    0            
26    1434    206.33.49.126    192.168.1.103    0            
27    1434    206.33.49.126    192.168.1.103    0            
28    1434    206.33.49.126    192.168.1.103    0            
29    1434    206.33.49.126    192.168.1.103    0            
30    64      192.168.1.103    206.33.49.126    0            
31    1434    206.33.49.126    192.168.1.103    0            
32    1434    206.33.49.126    192.168.1.103    0            
33    1434    206.33.49.126    192.168.1.103    0            
34    1082    206.33.49.126    192.168.1.103    1     <------ Packet in question        
35    1434    206.33.49.126    192.168.1.103    0            
36    1434    206.33.49.126    192.168.1.103    0            
37    1434    206.33.49.126    192.168.1.103    0            
38    64      192.168.1.103    206.33.49.126    0            
39    1434    206.33.49.126    192.168.1.103    0            
40    1434    206.33.49.126    192.168.1.103    0            
41    1434    206.33.49.126    192.168.1.103    0            
42    1434    206.33.49.126    192.168.1.103    0            
43    1434    206.33.49.126    192.168.1.103    0            
44    1434    206.33.49.126    192.168.1.103    0            
45    1434    206.33.49.126    192.168.1.103    0            
46    626     206.33.49.126    192.168.1.103    1            200
47    64      192.168.1.103    206.33.49.126    0 
Vadim
la source
Il peut y avoir tellement de raisons ... La taille de la fenêtre peut être trop petite (bien que très peu probable dans votre cas), il peut ne pas y avoir suffisamment de données à envoyer (la sortie est-elle générée par un script?), Le logiciel générant les données peut l'ont explicitement
vidé
@SanderSteffann, la taille de la fenêtre ne semble pas pertinente, les remerciements viennent à intervalles assez réguliers. La réponse entière est un javascript, donc je ne pense pas qu'elle soit générée par un autre script.
Vadim
@vadim, pourriez-vous s'il vous plaît poster une capture d'écran ou mieux, un lien hypertexte vers le pcap avec la charge utile de 1080 octets?
Mike Pennington
@MikePennington - merci pour votre contribution, je fournirai un lien vers le fichier pcap dans quelques heures.
Vadim
@MikePennington - J'ai ajouté un lien vers un fichier pcap qui le démontre.
Vadim

Réponses:

6

La couche TCP utilise l'algorithme Nagle pour tamponner le trafic (elle envoie moins de gros paquets, au lieu de plus de petits paquets ... ce qui la rend plus efficace); il existe un moyen pour l'application de dire «envoyez-le maintenant». Vous voyez cela dans l'en-tête TCP avec un indicateur appelé le bit PSH (push). Pendant que le bit est positionné par la pile, le push se fait à la demande de l'application.

Il s'agit donc d'un comportement voulu et normal.

Fredpbaker
la source
Point de clarification ... Les applications n'ont aucun contrôle direct sur le bit PSH ...
Mike Pennington
Tout à fait raison, il était censé être fait dans le RFC d'origine et ce qui a été fait Winsock et sockets
Fredpbaker
après avoir regardé le pcap, il est très peu probable que le serveur web ait mis PSH sur le trafic de l'OP
Mike Pennington
3

La taille du paquet dépend de la façon dont l'application et / ou les tampons du système d'exploitation et envoient les données réseau. Si l'application et / ou le système d'exploitation décide d'envoyer les données une fois que 1080 octets sont dans la mémoire tampon, le paquet sera de 1080 octets (plus les en-têtes). Il pourrait y avoir de nombreuses raisons pour cela. Dans votre cas, vous devrez rechercher dans le code source du serveur Web et / ou la pile réseau du système d'exploitation.

Sebastian Wiesinger
la source
Je vois beaucoup de paquets avec une taille maximale et seulement celui-ci avec une taille plus petite, donc ce n'est pas une valeur par défaut. Aurait-il pu s'agir d'un hoquet de serveur - il était coincé sur quelque chose d'autre pendant un délai suffisant pour que la pile réseau décide d'envoyer ce qui était dans le tampon?
Vadim
Bien sûr, cela aurait pu être n'importe quoi. Il n'y a aucun moyen de le savoir sans déboguer le serveur et le système d'exploitation sur lequel il fonctionne. Mais il n'y a rien à craindre à mon humble avis.
Sebastian Wiesinger
Je ne suis pas alarmé, cela semblait juste étrange et je voulais savoir s'il y avait plus que ça.
Vadim
1
Si vous avez des fils à regarder dans l'en-tête TCP de 1080 paquets pour le bit PSH (push). C'est la pile d'application qui dit d'envoyer ces données maintenant.
fredpbaker
1
Voir ci-dessus, c'est la pile TCP dans la plupart des cas
fredpbaker
1

La taille des paquets est définie par le système d'exploitation (en général) et est liée aux tampons, à la quantité de données fournies par l'application, etc. un plus gros paquet.

Parfois, la quantité d'applications en cours d'exécution peut exiger que le système d'exploitation soit plus rapide (envoyer tout ce qu'il contient dans le tampon jusqu'à présent) au lieu de saturer le tampon.

Peut-être pourriez-vous nous donner plus de détails sur le scénario avec lequel vous travailliez (ex.: OS du serveur, applications fonctionnant dessus).

woliveirajr
la source
0

Fondamentalement, le problème est que l'implémentation TCP ne sait pas ce que l'application va faire ensuite. Lorsque l'application serveur effectue une séquence d'écritures, la pile ne sait pas si les écritures qu'elle a reçues jusqu'à présent sont la séquence entière ou seulement une partie de celle-ci.

La plupart du temps, l'application serveur effectue des écritures dans le tampon plus rapidement que la pile réseau ne peut le vider. Ainsi, le tampon est plein et des paquets de taille réelle sortent.

Mais parfois, quelque chose d'autre ralentit l'application serveur. Peut-être en attente d'une lecture de disque sur une matrice de disques surchargée ou quelque chose. Ainsi, le tampon se vide et la pile réseau doit choisir entre l'envoi d'un petit paquet (plus de surcharge) ou l'attente de données qui pourraient ne jamais arriver (en ajoutant du retard).

Peter Green
la source
0

Si vous regardez la trame 34, vous verrez que le serveur a transmis une mémoire tampon de 32 Ko et que le bit PSH est défini. Si vous regardez 82, vous verrez la même chose, 32 Ko par rapport au bit PSH précédent. Le paquet 52 a un bit PSH même s'il y a eu moins de 2 Ko de réponse.

Le bit PSH est généralement défini par une pile TCP pour le dernier segment d'une PDU d'application écrite sur le réseau. Ainsi, l'application utilise un tampon de 32 Ko et lorsqu'il y a beaucoup de données, l'écrit sur le socket TCP 32 Ko à la fois. Quand il y a moins de données que dans les trames 51-52, c'est parce que l'application a écrit cet enregistrement en premier dans la réponse et que ce n'était que 1820 octets.

Notez que l'application à laquelle je fais référence peut en fait ne pas être l'application serveur elle-même mais certains logiciels intermédiaires tels qu'une machine virtuelle Java (JVM) ou autre. Le contenu des données ne permet pas de savoir pourquoi cette PDU de 1820 octets a été envoyée, peut-être qu'un tampon de 32 Ko n'était pas disponible à l'époque?

Le fait est que cela ne devrait pas avoir d'importance, il n'y a pas de pénalité de performance substantielle.

marctxk
la source