def monitor(server_w, id):
    conn = Channel()
    server_w((id, conn.writer()))
    inp = conn.reader()

    # Monitor the first three messages an then kill the connection
    for _ in range(3):
        print "[MONITOR] %s" % inp()

    poison(inp)
def client(IP, port):
    """ Process simulating a client

    :param IP:  Writer to server
    :param id:  Id for this process.
    """
    conn = Channel()
    IP(('10.0.0.12', port, conn.writer()))
    inp = conn.reader()
    outp = inp()

    for _ in xrange(10):
        outp('Hello from %d ' % port)
        msg = inp()
        print msg
        sleep(0.1)
    poison(outp)
def firewall(whitelist, swear_words, addr, port, client_w, monitor_r):
    """ Firewall layer for the server. All communication should pass through a
    firewall process to reach a server.

    :param whitelist:  list of (ip, port) doubles of allowed clients.
    :param swear_words:  List of words not allowed in messages to a server job.
    :param addr:
    :param port:
    :param conn:
    """
    # Verify IP/Port whitelist
    if (addr, port) in whitelist:
        # Setup as node between client and server.
        client_chan = Channel()
        server_chan = Channel()
        server_r = server_chan.reader()

        Spawn(do_service(server_chan.writer()))
        server_w = server_r()
        client_w(client_chan.writer())
        client_r = client_chan.reader()

        monitor_writer = None;

        while True:
            g, msg = AltSelect(InputGuard(client_r), InputGuard(monitor_r))

            if (g == client_r):
                # Poison channels if client swears.
                for swear in swear_words:
                    if swear in msg:
                        poison(client_w, server_r, client_r, monitor_r)
                        return

                # If no swears, then forward message to server and write response
                # back to client.
                server_w("[SFW] " + msg)
                client_w("[RESP] " + server_r())
                if monitor_writer is not None:
                    monitor_writer(msg)
            else:
                monitor_writer = msg
    else:
        poison(client_w)