16 de Abril, 2004

Calidad de servicio con Packet Filter

Con el artículo de ayer, en el que hablaba de Daniel Hartmeier, me he acordado que tenía pendiente meter reglas orientadas a garantizar la calidad del servicio en blackshell.

Además Daniel tiene en su página personal un ejemplo que me viene al pelo.

La idea es priorizar los ACKs del protocolo TCP. Me explico. Aunque se estén enviando paquetes en una dirección, como cuando descargamos algo o alguien descarga algo de nuestra máquina, el protocolo TCP requiere que el que recibe envíe en la otra dirección paquetes ACK (equivalente a decir: recibido OK). Estos paquetes son especiales ya que no tienen datos, y la información que transmiten son ellos mismos.

Así pues cuando estamos descargando datos a nuestra máxima velocidad y comenzamos a enviar datos de forma continuada, ¿qué ocurre? Que esos paquetes ACK se retrasan debido al tráfico saliente, y por consiguiente hay una caída de rendimiento en la descarga.

He hecho pruebas, bajando de un servidor estratégicamente elegido para obtener mi mejor bajada, y cuando la velocidad de descarga era 35KB/s, he subido un fichero por FTP a otro servidor distinto. La velocidad de descarga cae a 12KB/s con cortes importantes, por esos ACK que se retrasan.

La solución de Daniel es bastante sencilla (y en parte por eso la he puesto en páctica :D). Veamos las lineas importantes del pf.conf de blackshell:

# prioridades -> TCP ACKs
altq on $ext_if priq bandwidth 150Kb queue { qpri, qdef }

queue qpri priority 7
queue qdef priority 1 priq(default)

... más abajo ...

pass out on $ext_if proto tcp from $ext_if to any flags S/SA \
        keep state queue (qdef, qpri)
pass in on $ext_if proto tcp from any to $ext_if flags S/SA \
        keep state queue (qdef, qpri)

ext_if es una macro que contiene el interface con salida a internet (rl0 en este caso).

En primer lugar creamos una cola de prioridad en nuestra tarjeta de red objetivo, con scheduler (organizador) basado en prioridades y definiendo una cantidad máxima de ancho de banda para el scheduler. Además se definen dos colas derivadas de esta definición, qdef y qpri.

He puesto 150Kbps de ancho de banda porque es la velocidad a la que subo datos con mi linea (aunque creo que de 144Kbps no he pasado). Si este valor es muy bajo desaprovecharíamos nuestra conexión, y si es muy alto la cola nunca llegaría a entrar en acción.

Definimos despues qpri con una prioridad alta y qdef con una prioridad baja, que además será la cola por defecto.

Finalmente aplicamos las colas en la parte en la que dejamos pasar el tráfico TCP. La gracia de PF es la claridad con la que se entienden las reglas:

Deja pasar la salida en rl0 para el protocolo tcp desde rl0 a cualquiera con los flags S/SA guardando el estado con colas qdef y luego qpri.

Casi todo se entiende perfectamente. El flag S/SA es para que solo mire los marcadores SYN fuera de SYN + ACK del paquete (que se dan en la negociación al comienzo de la conexión), cosa con mucho sentido porque una vez que se ajusta una conexión a esta regla el "guardando el estado" hace que esa conexión no vuelva a ser valorada porque PF recuerda esta decisión.

Finalmente llega la parte interesante: las colas. Cuando de proporcionan dos colas entre paréntesis, la primera se toma por defecto y las segunda es para paquetes ToS y paquetes TCP ACK sin datos (¡ahí le hemos dado!). Los paquetes ToS se utilizan en la etapa de login de SSH, así que esta regla va a aportar más beneficios de los que buscábamos en un principio ;).

¿Qué se consigue con estas reglas? Pues que cuando repito la prueba, la descarga no baja de sus 35KB/s y la subida sigue siendo a tope :D. Esto es porque los paquetes ACK sin datos salen con más prioridad y no se retrasan, y ya que no tienen datos y son pequeños, tampoco se aprecia en la subida.

Esta es la potencia (y simplicidad) de Packet Filter. Aun me queda pendiente introducir algunas reglas para la red wireless, pero bueno... eso ya puede ser más complicado ya que no puedo valorar un ancho de banda constante, así que tendré que estudiar el tema con detenimiento. Es que no soy experto en PF :P, si alguien ve alguna barbaridad en este texto, ¡que me lo comente!

Anotación por Juan J. Martínez.

Los comentarios están cerrados: los comentarios se cierran automáticamente una vez pasados 30 días. Si quieres comentar algo acerca de la anotación, puedes hacerlo por e-mail.