ELO-330: Programación de Sistemas
Tarea 3: Estrangulador de Tráfico TCP

Objetivos: ejercitar uso de hebras, mecanismos de exclusión mutua y conexiones TCP.

Nombres: throttle_tcp : limitador de ancho de banda ocupado por una conexión TCP.

Sintaxis: throttle_tcp puerto [host_remoto] puerto_remoto

Descripción
   En ocasiones nos veamos enfrentados a la necesidad de correr una aplicación que establece conexiones a través de Internet y nos interesaría averiguar cuál es su comportamiento ante usuarios con poco ancho de banda; por ejemplo, aquellos con acceso móvil o desde sus hogares con poco ancho de banda. Generalmente los desarrollos se hacen en un laboratorio con red de área local de al menos 100Mbps de tasas en nivel físico. Surge la pregunta ¿Cómo puedo correr un proyecto haciéndolo creer que tiene menos ancho de banda? Una opción es usar un HUB o switch antiguo de 10 Mbps y así obligar a uno de los computadores a correr más lento. El principal problema es que así sólo se pueden probar enlaces de 10 Mbps (que es mucho para un celular).
 A través de esta tarea usted creará una aplicación proxy para estrangular conexiones TCP. La idea es poner un proceso intermedio en la conexión a intervenir y luego ajustar el ancho de banda de salida a lo que se desee, ver Figura 1.

Figura 1: Intercepción de tráfico y cambio de parámetros

  puerto corresponde al puerto local donde throttle_tcp se espera por conexiones TCP. Tan pronto llegue un cliente a este puerto, throttle_tcp abre una conexión hacia el host_remoto en el puerto_remoto. Si se omite el host_remoto se entiende que es la misma máquina (localhost).
  En lugar de pasar los paquetes libremente de un lado a otro y en ambas direcciones, throttle_tcp instala dos hebras encargadas de enviar controladamente el tráfico de salida. Cada hebra a cargo de una dirección. La figura 2 muestra una de ellas. Una tercera hebra se preocupa por controlar la cuota de tráfico posible a cada una de las otra hebras. 
  throttle_tcp usa leaky bucket y un esquema de espera en la lectura para limitar el tráfico de salida. La limitación de tráfico es la misma en ambas direcciones, luego se usa una misma hebra para extraer bytes a una tasa fija de los baldes de ambas direcciones. Esta tasa y el tamaño de ráfaga son ingresados por teclado y se pueden cambiar en cada momento. Es decir, siempre hay un prompt esperando que el usuario defina otro valor para esta tasa, que representa el ancho de banda permitido, y otro valor para la capacidad del balde que representa la cantidad máxima de bytes a enviar en forma consecutiva (ráfaga).
 
Figura 2: Modelo para una dirección del flujo

Esta tarea sigue las normas generales del ramo para evaluación de tareas y procedimiento de entrega.

Adicional voluntario:  En la tarea 2 usted ejerció la creación de gráficos. Voluntariamente, en esta tarea usted puede reutilizar parte de ese trabajo para que throttle_tcp muestre dos gráficos. Uno con las variaciones de tasa de entrada y otro con la tasa de salida (bytes por minuto). Estos gráficos son refrescados regularmente (por ejemplo cada dos segundos).

Ayuda:
-   Tanto para el flujo en un sentido como en otro usted puede considerar:
    Un Hilo que lee como máximo tantos bytes como espacio libre por llenar posea en el balde, incrementa el contenido del balde en el tamaño de datos leídos y los envía. Se debe cuidar de no rebalsar el balde. Si el balde está lleno, espera hasta que haya espacio, envía tantos bytes como los que pueda ingresar al balde.
    Por otro lado está la hebra que extrae bytes enviados (decrementa el contenido del balde) a una razón constante (ingresada por teclado). Considere usar la misma hebra para ambos baldes (de dirección hacia y desde el servidor).
    Si usted desea puede tener una cuarta hebra encargada de leer y actualizar los valores de tasa y tamaño de ráfaga.

- Para implementar Leaky Bucket eficientemente estudioe el uso de Variables de Condición y el ejemplo: leakyBucket_with_sleep.c.
 
- Para probar su tarea, considere usar un navegador configurado para trabajar con un proxy de salida. En particular considerar el uso de  SOCKS. En lugar de apuntar al servidor SOCKS usted lo hace apuntar a throttle_tcp y éste lo hace apuntar al verdadero servidor SOCKS. Así todo el tráfico web pasará por su limitador de tráfico y usted podrá limitar las tasa de accesos a youtube entre otros.

- Haga su tarea de a poco y con tiempo. Con gusto atenderé todas sus preguntas en especial en clases y horas de atención!