2011-02-23 20 views
11

Escenario hipotético: Un flujo de paquete udp llega a la máquina X, que ejecuta dos programas, uno que está escuchando los paquetes con recv() y otro que ejecuta pcap.¿Cómo funciona el búfer de pcap unix?

En este caso, según tengo entendido, los paquetes se almacenan en la interfaz hasta que el núcleo los interrogue y luego los transfiera a un búfer en la memoria Kernals y copie los paquetes en otros dos búferes, uno buffer para el programa que escucha con recv, y un buffer para el programa que escucha con pcap. Los paquetes se eliminan del respectivo búfer cuando se leen, ya sea por pcap_next() o recv(), la próxima vez que el planificador de procesos los ejecuta (supongo que están bloqueando en este caso). ¿Es esto correcto? ¿Hay realmente 4 buffers usados, o se maneja de otra manera?

Estoy buscando una descripción, lo más detallada posible, sobre qué buffers están realmente involucrados en este caso, y cómo los paquetes se mueven de uno a otro (por ejemplo, un paquete se copia al búfer pcaps antes de que se vaya a la memoria intermedia recv, después o indefinido?).

Sé que esto parece una gran pregunta, pero lo único que realmente me importa es dónde se almacena el paquete, y cuánto tiempo permanece ahí. Los puntos bullet están bien. Idealmente, me gustaría obtener una respuesta general, pero si varía según el sistema operativo, estoy más interesado en Linux.

Respuesta

8

caso de Linux (BSD son probablemente algo similar, utilizando mbuf s en lugar de skbuff s):

Linux utiliza skbuffs (buffers de los conectores) para amortiguar los datos de red. Un skbuff tiene metadatos sobre algunos datos de red y algunos indicadores sobre esos datos.

Taps (usuarios de pcap) crean clones de skbuffs. Un clon es un skbuff nuevo, pero apunta a los mismos datos. Cuando alguien necesita modificar los datos compartidos por varias skbuffs (la skbuff original y sus clones), primero necesita crear una nueva copia (copy-on-write).

Cuando alguien ya no necesita un skbuff, es kfree_skb() lo es. kfree_skb() disminuye el recuento de referencias, y cuando ese recuento de referencias llega a cero, se libera el skbuff. Es un poco más complicado dar cuenta de los clones, pero esta es la idea general.

+0

Entonces, ¿está diciendo que la función recv() usa el buffer del núcleo, pero cada instancia pcap tiene su propia copia del buffer? ¿En qué etapa se hacen estos clones, cuando se recibe el paquete? cuando pcap quiere leerlo? – Benubird

+0

Cada instancia pcap tiene su propia copia de los metadatos, pero todos comparten los mismos datos. Los clones se crean cuando se recibe el paquete (en 'skb_deliver()' IIRC). – ninjalj

Cuestiones relacionadas