Tamaños de paquetes en una secuencia TCP

10

Soy tráfico de red y deseo dividir cada sesión TCP en una serie de solicitudes y respuestas (los protocolos con los que estoy trabajando funcionan de esa manera, como HTTP o SSL).

Tenía una suposición simple (ignorar los paquetes fuera de servicio y reenviados): dada una porción de datos que debe enviarse, se enviará utilizando los paquetes más grandes posibles y el último paquete será más pequeño que el tamaño máximo o se seguirá por un paquete del otro lado (ignorando los paquetes vacíos ACK). Entonces, en una sesión HTTP, espero ver algo como (de nuevo, sin tener en cuenta los acks):

Paquete 1 - Solicitar "Obtener ..."

Paquete 2 - Respuesta, tamaño 1434

Paquete 3 - Respuesta, tamaño 1434

Paquete 4 - Respuesta, tamaño 1434

Paquete 5 - Respuesta, tamaño 500

Que es lo que obtengo en la mayoría de las sesiones, sin embargo, hay al menos una ocasión que vi que parecía

Paquete 1 - Solicitar "Obtener ..."

Paquete 2 - Respuesta, tamaño 1434

Paquete 3 - Respuesta, tamaño 1080

Paquete 4 - Respuesta, tamaño 1434

Paquete 5 - Respuesta, tamaño 500

Sin retransmisiones, paquetes fuera de servicio aquí o sin retrasos excepcionales en el servidor.

Quiero saber: ¿qué puede causar esto y cuándo ocurrirá? ¿Qué tan errónea es mi suposición?

ACTUALIZAR

Pongo un archivo pcap de ejemplo aquí

ACTUALIZACIÓN 2

Incluyendo un tsharkvolcado con campos relevantes ...

$ 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
fuente
Puede haber muchas razones ... El tamaño de la ventana puede ser demasiado pequeño (aunque muy poco probable en su caso), puede que no haya suficientes datos para enviar (¿el resultado generado por un script?), El software que genera los datos podría lo he
vaciado
@SanderSteffann, el tamaño de la ventana no parece relevante, los acks vienen a intervalos bastante regulares. Toda la respuesta es un javascript, así que no creo que sea generado por otro script.
Vadim
@vadim, ¿podría publicar una captura de pantalla o mejor, un hipervínculo al pcap con la carga útil de 1080 bytes?
Mike Pennington
@ MikePennington: gracias por su aporte, le proporcionaré un enlace al archivo pcap en varias horas.
Vadim
@ MikePennington: agregué un enlace a un archivo pcap que lo demuestra.
Vadim

Respuestas:

6

La capa TCP utiliza el algoritmo Nagle para almacenar el tráfico en el búfer (envía menos paquetes grandes, en lugar de más paquetes pequeños ... lo que lo hace más eficiente); hay una manera para que la aplicación diga 'enviarlo ahora'. Usted ve eso en el encabezado TCP con una bandera llamada bit PSH (push). Mientras la pila establece el bit, la inserción se realiza a petición de la aplicación.

Entonces este es un comportamiento intencionado y normal.

fredpbaker
fuente
Punto de aclaración ... Las aplicaciones no tienen control directo sobre el bit PSH ...
Mike Pennington
Muy bien, se suponía que se haría en el RFC original y lo que se hizo winsock y enchufes
fredpbaker
después de mirar el pcap, es muy poco probable que el servidor web establezca PSH en el tráfico del OP
Mike Pennington
3

El tamaño del paquete depende de cómo la aplicación y / o el sistema operativo almacenan y envían datos de la red. Si la aplicación y / o el sistema operativo deciden enviar los datos después de que 1080 bytes estén en el búfer, entonces el paquete será de 1080 bytes (más encabezados). Podría haber muchas razones para que haga eso. En su caso, debería buscar en el código fuente del servidor web y / o la pila de red del sistema operativo.

Sebastian Wiesinger
fuente
Veo muchos paquetes con un tamaño máximo y solo este con un tamaño más pequeño, por lo que no es un tipo predeterminado. ¿Podría haber sido un problema con el servidor: estaba atascado en otra cosa por un retraso que fue suficiente para que la pila de red decidiera enviar lo que estaba en el búfer?
Vadim
Claro, podría haber sido cualquier cosa. No hay forma de saberlo sin depurar el servidor y el sistema operativo en el que se está ejecutando. Pero no hay nada de que alarmarse en mi humilde opinión.
Sebastian Wiesinger
No estoy alarmado, simplemente parecía extraño y quería saber si hay algo más que eso.
Vadim
1
Si tiene hilos de conexión, busque en el encabezado TCP de 1080 paquetes el bit PSH (push). Esa es la pila de aplicaciones que dice enviar estos datos ahora.
fredpbaker
1
Ver arriba, es la pila TCP en la mayoría de los casos
fredpbaker
1

El tamaño del paquete está definido por el sistema operativo (en general) y está relacionado con los buffers, la cantidad de datos proporcionados por la aplicación, etc. Muchas estrategias se pueden utilizar para lograr el máximo rendimiento y, a veces, enviar paquetes más pequeños puede ser más rápido que esperar para crear Un paquete más grande.

A veces, la cantidad de aplicaciones en ejecución puede exigir que el sistema operativo sea más rápido (envíe lo que tenga en el búfer hasta ahora) en lugar de saturar el búfer.

Tal vez, podría darnos más detalles sobre el escenario con el que estaba trabajando (por ejemplo: sistema operativo del servidor, aplicaciones que se ejecutan en él).

woliveirajr
fuente
0

Básicamente, el problema es que la implementación de TCP no sabe qué hará la aplicación a continuación. Cuando la aplicación del servidor realiza una secuencia de escrituras, la pila no sabe si las escrituras que ha recibido hasta ahora son la secuencia completa o solo una parte de ella.

La mayoría de las veces, la aplicación del servidor hace que las escrituras en el búfer sean más rápidas de lo que la pila de red puede vaciarlo. Entonces el búfer está lleno y salen paquetes de tamaño completo.

Pero a veces algo más ralentiza la aplicación del servidor. Tal vez esperando que se lea un disco en una matriz de discos sobrecargados o algo así. Por lo tanto, el búfer se vacía y la pila de red tiene que elegir entre enviar un paquete más pequeño (más sobrecarga) o esperar datos que tal vez nunca lleguen (agregando retraso).

Peter Green
fuente
0

Si observa el cuadro 34, verá que el servidor ha transmitido un búfer de 32kB y que el bit PSH está configurado. Si observa 82, verá lo mismo, 32 kB del bit PSH anterior. El paquete 52 tiene un bit PSH a pesar de que ha habido menos de 2kB de la respuesta.

El bit PSH generalmente lo establece una pila TCP para el último segmento de una PDU de aplicación escrita en la red. Entonces, la aplicación usa un búfer de 32kB y cuando hay muchos datos, los escribe en el socket TCP de 32kB a la vez. Cuando hay menos datos como en los cuadros 51-52, es porque la aplicación escribió ese registro primero en la respuesta y solo tenía 1820 bytes.

Tenga en cuenta que la aplicación a la que me refiero puede, de hecho, no ser la aplicación del servidor en sí, sino algún software intermedio, como una máquina virtual Java (JVM) o lo que sea. No está claro por el contenido de los datos por qué se envió esa PDU de 1820 bytes, ¿tal vez un búfer de 32kB no estaba disponible en ese momento?

El punto es que no debería importar, no hay una penalización de rendimiento sustancial.

marctxk
fuente