ELO330 - Programación de Sistemas - Tarea 3
===========================================

Descripción
-----------

### Reflejando servidor en Internet

Esta solución permite acceder desde una red pública (Internet) a servicios ubicados en una subred interna (privada, bajo NAT) por medio de dos programas que permiten crear un túnel de tráfico entre estas dos zonas. La presencia de un NAT impide el acceso directo a los servicios detrás de este.

Para ello se necesita que desde la subred interna el programa "subnet relay client" (`src`) sea capaz de asociar conexiónes provenientes de un servidor proxy, ubicado en la red pública, a un servicio específico de la red interna.
Con esto, un cliente fuera de la subred interna solo necesita comunicarse con el "internet proxy server" (`ips`) para alcanzar dicho servicio en la subred privada.

Los detalles de la implementación podrán ser encontrados en el código donde se han comentado algunos aspectos importantes. Ambos programas comparten un código común, donde los pares de conexiónes `cliente-tunel` y `tunel-servicio` se almacenan y administran en una lista enlazada, mantenida periodicamente por cada programa.

#### Diagramas de flujo

- ![Internet proxy server](./img/ips_flowchart.svg)
- ![Subnet relay client](./img/src_flowchart.svg)

Requisitos
----------

Los programas solamente requieren de las herramientas básicas de compilación (GCC y GNU Make). Dependiendo de la distribución de linux, ambos programas pueden instalarse de la siguiente forma:

#### Debian / Ubuntu
    $ sudo apt-get update
    $ sudo apt-get install build-essential

#### Red Hat / CentOS / Fedora
    $ sudo yum update
    $ sudo yum group install "Development Tools"

Compilación
-----------

En la carpeta raíz del proyecto, ejecutar:

    make clean
    make

Forma de uso
------------

### Internet proxy server

    ./ips <forwarding port> <tunnel port>

- forwarding port: Puerto donde los clientes en una red pública/externa pueden acceder al servicio en la red privada.
- tunnel port: Puerto donde el subnet relay client (`src`) se conecta para vincular un servicio con el proxy.

### Subnet relay client

    ./src <proxy server> <proxy port> <target server> <target port>

- proxy server: Host o dirección IP del servidor proxy.
- proxy port: Puerto del servidor proxy.
- target server: Host o dirección IP del servicio a reflejar.
- target port: Puerto del servicio a reflejar.

#### Alcances

- Solo se reflejan servicios bajo puertos TCP.
- Se debe asegurar que hayan puertos disponibles, para ello se sugiere revisar con `netstat -tan`
- Los programas cuentan con rutinas que manejan ciertas situaciones de pérdida de conexión (no todas). Si el proxy pierde la conexión esperará a que el relay client se conecte nuevamente, en cambio, si el relay client pierde su conexión este intentara reconectarse hasta agotar un máximo de 5 intentos.

Resultados
----------

Con el programa `iperf` se realizaron pruebas en el servidor Aragorn para verificar de que la solución soporta al menos 10 conexiones concurrentes. Iperf puede instalarse desde los repositorios de su distribución.

Los pasos son los siguientes:

##### 1. Ejecutar el proxy server (desde Aragorn)
    $ ./ips 47203 47204

##### 2. Habilitar iperf en modo servidor (desde PC en red privada)
    $ iperf -s

##### 3. Ejecutar el relay client (desde el mismo PC, en otra terminal)
    $ ./src aragorn.elo.utfsm.cl 47204 localhost 5001

##### 4. Medir transferencia (desde cualquier punto de Internet)
    $ for i in {1..10}; do sh -c 'iperf -c aragorn.elo.utfsm.cl -p 47203 2>&1 >/dev/null &'; done

##### 5. Luego de unos segundos, se obtienen los resultados (extracto):
    ------------------------------------------------------------
    Server listening on TCP port 5001
    TCP window size: 85.3 KByte (default)
    ------------------------------------------------------------
    recvn abort failed: Success
    [  4] local 127.0.0.1 port 5001 connected with 127.0.0.1 port 55074
    [ ID] Interval       Transfer     Bandwidth
    [  4]  0.0- 0.0 sec  0.00 Bytes  0.00 bits/sec
    [  4] local 127.0.0.1 port 5001 connected with 127.0.0.1 port 55080
    [  5] local 127.0.0.1 port 5001 connected with 127.0.0.1 port 55086
    [  6] local 127.0.0.1 port 5001 connected with 127.0.0.1 port 55092
    [  8] local 127.0.0.1 port 5001 connected with 127.0.0.1 port 55104
    [  7] local 127.0.0.1 port 5001 connected with 127.0.0.1 port 55098
    [  9] local 127.0.0.1 port 5001 connected with 127.0.0.1 port 55110
    [ 10] local 127.0.0.1 port 5001 connected with 127.0.0.1 port 55116
    [ 11] local 127.0.0.1 port 5001 connected with 127.0.0.1 port 55122
    [ 12] local 127.0.0.1 port 5001 connected with 127.0.0.1 port 55128
    [ 13] local 127.0.0.1 port 5001 connected with 127.0.0.1 port 55134
    [  8]  0.0-10.1 sec  34.1 MBytes  28.5 Mbits/sec
    [ 12]  0.0-10.1 sec  33.8 MBytes  28.1 Mbits/sec
    [  4]  0.0-10.1 sec  43.9 MBytes  36.5 Mbits/sec
    [  5]  0.0-10.1 sec  34.2 MBytes  28.5 Mbits/sec
    [ 10]  0.0-10.1 sec  33.9 MBytes  28.2 Mbits/sec
    [  6]  0.0-10.1 sec  43.8 MBytes  36.4 Mbits/sec
    [  7]  0.0-10.1 sec  38.8 MBytes  32.2 Mbits/sec
    [  9]  0.0-10.1 sec  43.2 MBytes  35.9 Mbits/sec
    [ 11]  0.0-10.1 sec  38.8 MBytes  32.2 Mbits/sec
    [ 13]  0.0-10.1 sec  43.2 MBytes  35.9 Mbits/sec
    [SUM]  0.0-10.1 sec   388 MBytes   322 Mbits/sec
