Exemplo n.º 1
0
def Server(cmdch, brdch):

    try:
        ipr = IPRoute()
        lock = ipr._sproxy.lock
        ipr._s_channel = brdch
        poll = select.poll()
        poll.register(ipr, select.POLLIN | select.POLLPRI)
        poll.register(cmdch, select.POLLIN | select.POLLPRI)
    except Exception as e:
        cmdch.send({'stage': 'init', 'error': e})
        return 255

    # all is OK so far
    cmdch.send({'stage': 'init', 'error': None})
    # 8<-------------------------------------------------------------
    while True:
        events = poll.poll()
        for (fd, event) in events:
            if fd == ipr.fileno():
                bufsize = ipr.getsockopt(SOL_SOCKET, SO_RCVBUF) // 2
                with lock:
                    brdch.send({
                        'stage': 'broadcast',
                        'data': ipr.recv(bufsize)
                    })
            elif fd == cmdch.fileno():
                cmd = cmdch.recv()
                if cmd['stage'] == 'shutdown':
                    poll.unregister(ipr)
                    poll.unregister(cmdch)
                    ipr.close()
                    return
                elif cmd['stage'] == 'command':
                    error = None
                    try:
                        ret = getattr(ipr, cmd['name'])(*cmd['argv'],
                                                        **cmd['kwarg'])
                    except Exception as e:
                        error = e
                        error.tb = traceback.format_exc()
                    cmdch.send({
                        'stage': 'command',
                        'error': error,
                        'return': ret,
                        'cookie': cmd['cookie']
                    })
Exemplo n.º 2
0
def Server(cmdch, brdch):

    try:
        ipr = IPRoute()
        lock = ipr._sproxy.lock
        ipr._s_channel = brdch
        poll = select.poll()
        poll.register(ipr, select.POLLIN | select.POLLPRI)
        poll.register(cmdch, select.POLLIN | select.POLLPRI)
    except Exception as e:
        cmdch.send({'stage': 'init',
                    'error': e})
        return 255

    # all is OK so far
    cmdch.send({'stage': 'init',
                'error': None})
    # 8<-------------------------------------------------------------
    while True:
        events = poll.poll()
        for (fd, event) in events:
            if fd == ipr.fileno():
                bufsize = ipr.getsockopt(SOL_SOCKET, SO_RCVBUF) // 2
                with lock:
                    brdch.send({'stage': 'broadcast',
                                'data': ipr.recv(bufsize)})
            elif fd == cmdch.fileno():
                cmd = cmdch.recv()
                if cmd['stage'] == 'shutdown':
                    poll.unregister(ipr)
                    poll.unregister(cmdch)
                    ipr.close()
                    return
                elif cmd['stage'] == 'command':
                    error = None
                    try:
                        ret = getattr(ipr, cmd['name'])(*cmd['argv'],
                                                        **cmd['kwarg'])
                    except Exception as e:
                        error = e
                        error.tb = traceback.format_exc()
                    cmdch.send({'stage': 'command',
                                'error': error,
                                'return': ret,
                                'cookie': cmd['cookie']})
Exemplo n.º 3
0
def Server(cmdch, brdch):
    '''
    A server routine to run an IPRoute object and expose it via
    custom RPC.

    many TODOs:

    * document the protocol
    * provide not only IPRoute

    RPC

    Messages sent via channels are dictionaries with predefined
    structure. There are 4 s.c. stages::

        init        (server <-----> client)
        command     (server <-----> client)
        broadcast   (server ------> client)
        shutdown    (server <------ client)


    Stage 'init' is used during initialization. The client
    establishes connections to the server and announces them
    by sending a single message via each channel::

        {'stage': 'init',
         'domain': ch_domain,
         'client': client.uuid}

    Here, the client uuid is used to group all the connections
    of the same client and `ch_domain` is either 'command', or
    'broadcast'. The latter will become a unidirectional
    channel from the server to the client, all data that
    arrives on the server side via netlink socket will be
    forwarded to the broadcast channel.

    The command channel will be used to make RPC calls and
    to shut the worker thread down before the client
    disconnects from the server.

    When all the registration is done, the server sends a
    single message via the command channel::

        {'stage': 'init',
         'error': exception or None}

    If the `error` field is None, everything is ok. If it
    is an exception, the init is failed and the exception
    should be thrown on the client side.

    In the runtime, all the data that arrives on the netlink
    socket fd, is to be forwarded directly via the
    broadcast channel.

    Commands are handled with the `command` stage::

        # request

        {'stage': 'command',
         'name': str,
         'cookie': cookie,
         'argv': [...],
         'kwarg': {...}}

        # response

        {'stage': 'command',
         'error': exception or None,
         'return': retval,
         'cookie': cookie}

    Right now the protocol is synchronous, so there is not
    need in cookie yet. But in some future it can turn into
    async, and then cookies will be used to match messages.

    The final stage is 'shutdown'. It terminates the worker
    thread, has no response and no messages can passed after.

    '''

    def close(s, frame):
        # just leave everything else as is
        brdch.send({'stage': 'signal',
                    'data': s})

    try:
        ipr = IPRoute()
        lock = ipr._sproxy.lock
        ipr._s_channel = ProxyChannel(brdch, 'broadcast')
        poll = select.poll()
        poll.register(ipr, select.POLLIN | select.POLLPRI)
        poll.register(cmdch, select.POLLIN | select.POLLPRI)
    except Exception as e:
        cmdch.send({'stage': 'init',
                    'error': e})
        return 255

    # all is OK so far
    cmdch.send({'stage': 'init',
                'error': None})
    signal.signal(signal.SIGHUP, close)
    signal.signal(signal.SIGINT, close)
    signal.signal(signal.SIGTERM, close)

    # 8<-------------------------------------------------------------
    while True:
        try:
            events = poll.poll()
        except:
            continue
        for (fd, event) in events:
            if fd == ipr.fileno():
                bufsize = ipr.getsockopt(SOL_SOCKET, SO_RCVBUF) // 2
                with lock:
                    error = None
                    data = None
                    try:
                        data = ipr.recv(bufsize)
                    except Exception as e:
                        error = e
                        error.tb = traceback.format_exc()
                    brdch.send({'stage': 'broadcast',
                                'data': data,
                                'error': error})
            elif fd == cmdch.fileno():
                cmd = cmdch.recv()
                if cmd['stage'] == 'shutdown':
                    poll.unregister(ipr)
                    poll.unregister(cmdch)
                    ipr.close()
                    return
                elif cmd['stage'] == 'reconstruct':
                    error = None
                    try:
                        msg = cmd['argv'][0]()
                        msg.load(pickle.loads(cmd['argv'][1]))
                        msg.encode()
                        ipr.sendto_gate(msg, cmd['argv'][2])
                    except Exception as e:
                        error = e
                        error.tb = traceback.format_exc()
                    cmdch.send({'stage': 'reconstruct',
                                'error': error,
                                'return': None,
                                'cookie': cmd['cookie']})

                elif cmd['stage'] == 'command':
                    error = None
                    try:
                        ret = getattr(ipr, cmd['name'])(*cmd['argv'],
                                                        **cmd['kwarg'])
                    except Exception as e:
                        error = e
                        error.tb = traceback.format_exc()
                    cmdch.send({'stage': 'command',
                                'error': error,
                                'return': ret,
                                'cookie': cmd['cookie']})
Exemplo n.º 4
0
def Server(trnsp_in, trnsp_out):

    try:
        ipr = IPRoute()
        lock = ipr._sproxy.lock
        ipr._s_channel = ProxyChannel(trnsp_out, 'broadcast')
    except Exception as e:
        trnsp_out.send({'stage': 'init', 'error': e})
        return 255

    inputs = [ipr.fileno(), trnsp_in.fileno()]
    outputs = []

    # all is OK so far
    trnsp_out.send({'stage': 'init', 'error': None})

    # 8<-------------------------------------------------------------
    while True:
        try:
            events, _, _ = select.select(inputs, outputs, inputs)
        except:
            continue
        for fd in events:
            if fd == ipr.fileno():
                bufsize = ipr.getsockopt(SOL_SOCKET, SO_RCVBUF) // 2
                with lock:
                    error = None
                    data = None
                    try:
                        data = ipr.recv(bufsize)
                    except Exception as e:
                        error = e
                        error.tb = traceback.format_exc()
                    trnsp_out.send({
                        'stage': 'broadcast',
                        'data': data,
                        'error': error
                    })
            elif fd == trnsp_in.fileno():
                cmd = trnsp_in.recv_cmd()
                if cmd['stage'] == 'shutdown':
                    ipr.close()
                    return
                elif cmd['stage'] == 'reconstruct':
                    error = None
                    try:
                        msg = cmd['argv'][0]()
                        msg.load(pickle.loads(cmd['argv'][1]))
                        msg.encode()
                        ipr.sendto_gate(msg, cmd['argv'][2])
                    except Exception as e:
                        error = e
                        error.tb = traceback.format_exc()
                    trnsp_out.send({
                        'stage': 'reconstruct',
                        'error': error,
                        'return': None,
                        'cookie': cmd['cookie']
                    })

                elif cmd['stage'] == 'command':
                    error = None
                    try:
                        ret = getattr(ipr, cmd['name'])(*cmd['argv'],
                                                        **cmd['kwarg'])
                    except Exception as e:
                        ret = None
                        error = e
                        error.tb = traceback.format_exc()
                    trnsp_out.send({
                        'stage': 'command',
                        'error': error,
                        'return': ret,
                        'cookie': cmd['cookie']
                    })
Exemplo n.º 5
0
from socket import socket
from socket import AF_INET
from socket import SOCK_STREAM
from socket import SOL_SOCKET
from socket import SO_REUSEADDR

ip = IPRoute()

##
#
pr = socket(AF_INET, SOCK_STREAM)
pr.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
pr.bind(('127.0.0.1', 4011))
pr.listen(1)
(client, addr) = pr.accept()
ip._s_channel = client

##
#
poll = select.poll()
poll.register(client, select.POLLIN | select.POLLPRI)
poll.register(ip, select.POLLIN | select.POLLPRI)

while True:
    events = poll.poll()
    for (fd, event) in events:
        if fd == client.fileno():
            try:
                ip.sendto(client.recv(16384), (0, 0))
            except:
                sys.exit(0)