コード例 #1
0
ファイル: iocore.py プロジェクト: bouttier/pyroute2
 def route_local(self, sock, data, seq):
     # extract masq info
     target = self.masquerade.get(seq, None)
     if target is None:
         for cid, u32 in self.subscribe.items():
             self.filter_u32(u32, data)
     else:
         offset = 0
         while offset < data.length:
             data.seek(offset)
             (length,
              mtype,
              flags,
              seq,
              pid) = struct.unpack('IHHII', data.read(16))
             data.seek(offset + 8)
             data.write(struct.pack('II',
                                    target.data.nonce,
                                    target.data.pid))
             # skip to the next in chunk
             offset += length
         # envelope data
         envelope = envmsg()
         envelope['header']['sequence_number'] = target.envelope.nonce
         envelope['header']['pid'] = target.envelope.pid
         envelope['header']['type'] = NLMSG_TRANSPORT
         envelope['dst'] = target.src
         envelope['src'] = target.dst
         envelope['attrs'] = [['IPR_ATTR_CDATA',
                               data.getvalue()]]
         envelope.encode()
         # target
         target.socket.send(envelope.buf.getvalue())
コード例 #2
0
ファイル: iocore.py プロジェクト: chantra/pyroute2
    def _route(self, sock, raw):
        buf = io.BytesIO()
        buf.length = buf.write(raw)
        if self._stop_event.is_set():
            return

        buf.seek(0)

        if self.save is not None:
            # concatenate buffers
            buf.seek(0)
            self.save.write(buf.read())
            self.save.length += buf.length
            # discard save
            buf = self.save
            self.save = None

        offset = 0
        while offset < buf.length:
            buf.seek(offset)
            (length,
             mtype,
             flags) = struct.unpack('IHH', buf.read(8))

            if offset + length > buf.length:
                # create save buffer
                buf.seek(offset)
                self.save = io.BytesIO()
                self.save.length = self.save.write(buf.read())
                # truncate the buffer
                buf.truncate(offset)
                break

            buf.seek(offset)
            data = io.BytesIO()
            data.write(buf.read(length))
            data.length = length
            data.seek(0)

            # data traffic
            envelope = envmsg(data)
            envelope.decode()
            nonce = envelope['header']['sequence_number']
            try:
                buf = io.BytesIO()
                buf.length = buf.write(envelope.
                                       get_attr('IPR_ATTR_CDATA'))
                buf.seek(0)
                if ((flags & NLT_CONTROL) and
                        (flags & NLT_RESPONSE)):
                    msg = mgmtmsg(buf)
                    msg.decode()
                    self.listeners[nonce].put_nowait(msg)
                else:
                    self.parse(envelope, buf)
            except AttributeError:
                # now silently drop bad packet
                pass

            offset += length
コード例 #3
0
ファイル: iocore.py プロジェクト: bouttier/pyroute2
 def command(self, cmd, attrs=[]):
     msg = mgmtmsg(io.BytesIO())
     msg['header']['type'] = NLMSG_CONTROL
     msg['cmd'] = cmd
     msg['attrs'] = attrs
     msg.encode()
     envelope = envmsg()
     envelope['header']['type'] = NLMSG_TRANSPORT
     envelope['header']['flags'] = 1
     envelope['attrs'] = [['IPR_ATTR_CDATA', msg.buf.getvalue()]]
     envelope.encode()
     self.control.send(envelope.buf.getvalue())
     envelope = envmsg(self.control.recv())
     envelope.decode()
     data = io.BytesIO(envelope.get_attr('IPR_ATTR_CDATA'))
     rsp = mgmtmsg(data)
     rsp.decode()
     return rsp
コード例 #4
0
ファイル: iocore.py プロジェクト: bouttier/pyroute2
 def filter_u32(self, u32, data):
     for offset, key, mask in u32['keys']:
         data.seek(offset)
         compare = struct.unpack('I', data.read(4))[0]
         if compare & mask != key:
             return
     # envelope data
     envelope = envmsg()
     envelope['header']['type'] = NLMSG_TRANSPORT
     envelope['attrs'] = [['IPR_ATTR_CDATA',
                           data.getvalue()]]
     envelope.encode()
     u32['socket'].send(envelope.buf.getvalue())
コード例 #5
0
 def filter_u32(self, u32, data):
     for offset, key, mask in u32['keys']:
         data.seek(offset)
         compare = struct.unpack('I', data.read(4))[0]
         if compare & mask != key:
             return
     # envelope data
     envelope = envmsg()
     envelope['header']['type'] = NLMSG_TRANSPORT
     envelope['attrs'] = [['IPR_ATTR_CDATA',
                           data.getvalue()]]
     envelope['id'] = uuid.uuid4().bytes
     envelope.encode()
     u32['socket'].send(envelope.buf.getvalue())
コード例 #6
0
    def route_control(self, sock, envelope):
        pid = envelope['header']['pid']
        nonce = envelope['header']['sequence_number']
        # src = envelope['src']
        dst = envelope['dst']
        sport = envelope['sport']
        dport = envelope['dport']
        data = io.BytesIO(envelope.get_attr('IPR_ATTR_CDATA'))
        cmd = self.parse_control(data)
        module = cmd['cmd']
        rsp = mgmtmsg()
        rsp['header']['type'] = NLMSG_CONTROL
        rsp['header']['sequence_number'] = nonce
        rsp['cmd'] = IPRCMD_ERR
        rsp['attrs'] = []

        rights = 0
        if sock in self.controls:
            rights = access.ADMIN
        elif sock in self.clients:
            rights = access.USER
        try:
            if rights & self.modules[module]['access']:
                self.modules[module]['command'](self, sock, envelope,
                                                cmd, rsp)
            else:
                raise IOError(13, 'Permission denied')

            rsp['cmd'] = IPRCMD_ACK
            rsp['attrs'].append(['IPR_ATTR_SOURCE', cmd['cmd']])
        except Exception:
            rsp['attrs'] = [['IPR_ATTR_ERROR', traceback.format_exc()]]

        rsp.encode()
        ne = envmsg()
        ne['header']['sequence_number'] = nonce
        ne['header']['pid'] = pid
        ne['header']['type'] = NLMSG_TRANSPORT
        ne['header']['flags'] = NLT_CONTROL | NLT_RESPONSE
        ne['src'] = dst
        ne['ttl'] = 16
        ne['id'] = uuid.uuid4().bytes
        ne['dport'] = sport
        ne['sport'] = dport
        ne['attrs'] = [['IPR_ATTR_CDATA', rsp.buf.getvalue()]]
        ne.encode()
        sock.send(ne.buf.getvalue())

        if self.shutdown_flag.is_set():
            self.shutdown()
コード例 #7
0
ファイル: iocore.py プロジェクト: rgacogne/pyroute2
 def push(self, host, msg, env_flags=None, nonce=0, cname=None):
     addr, port = host
     envelope = envmsg()
     envelope['header']['sequence_number'] = nonce
     envelope['header']['pid'] = os.getpid()
     envelope['header']['type'] = NLMSG_TRANSPORT
     if env_flags is not None:
         envelope['header']['flags'] = env_flags
     envelope['dst'] = addr
     envelope['src'] = self.default_broker
     envelope['dport'] = port
     envelope['ttl'] = 16
     envelope['id'] = uuid.uuid4().bytes
     envelope['attrs'] = [['IPR_ATTR_CDATA', msg]]
     if cname is not None:
         envelope['attrs'].append(['IPR_ATTR_CNAME', cname])
     envelope.encode()
     self.bridge.send(envelope.buf.getvalue())
コード例 #8
0
    def route_netlink(self, sock, raw):
        data = io.BytesIO()
        data.length = data.write(raw)
        data.seek(8)
        seq = struct.unpack('I', data.read(4))[0]

        # extract masq info
        target = self.masquerade.get(seq, None)
        if target is None:
            for cid, u32 in self.subscribe.items():
                self.filter_u32(u32, data)
        else:
            offset = 0
            while offset < data.length:
                data.seek(offset)
                (length,
                 mtype,
                 flags,
                 seq,
                 pid) = struct.unpack('IHHII', data.read(16))
                data.seek(offset + 8)
                data.write(struct.pack('II',
                                       target.data.nonce,
                                       target.data.pid))
                # skip to the next in chunk
                offset += length
            # envelope data
            envelope = envmsg()
            envelope['header']['sequence_number'] = \
                target.envelope['header']['sequence_number']
            envelope['header']['pid'] = \
                target.envelope['header']['pid']
            envelope['header']['type'] = NLMSG_TRANSPORT
            # envelope['dst'] = target.envelope['src']
            envelope['src'] = target.envelope['dst']
            envelope['ttl'] = 16
            envelope['id'] = uuid.uuid4().bytes
            envelope['dport'] = target.envelope['sport']
            envelope['sport'] = target.envelope['dport']
            envelope['attrs'] = [['IPR_ATTR_CDATA',
                                  data.getvalue()]]
            envelope.encode()
            # target
            target.socket.send(envelope.buf.getvalue())
コード例 #9
0
ファイル: iocore.py プロジェクト: chantra/pyroute2
 def push(self, host, msg,
          env_flags=None,
          nonce=0,
          cname=None):
     addr, port = host
     envelope = envmsg()
     envelope['header']['sequence_number'] = nonce
     envelope['header']['pid'] = os.getpid()
     envelope['header']['type'] = NLMSG_TRANSPORT
     if env_flags is not None:
         envelope['header']['flags'] = env_flags
     envelope['dst'] = addr
     envelope['src'] = self.default_broker
     envelope['dport'] = port
     envelope['ttl'] = 16
     envelope['attrs'] = [['IPR_ATTR_CDATA', msg]]
     if cname is not None:
         envelope['attrs'].append(['IPR_ATTR_CNAME', cname])
     envelope.encode()
     self.bridge.send(envelope.buf.getvalue())
コード例 #10
0
 def handle_connect(self, fd, event):
     (client, addr) = fd.accept()
     self.add_client(client)
     # announce address
     # .. _ioc-connect:
     rsp = mgmtmsg()
     rsp['header']['type'] = NLMSG_CONTROL
     rsp['cmd'] = IPRCMD_ACK
     rsp['attrs'] = [['IPR_ATTR_ADDR', self.addr]]
     rsp.encode()
     ne = envmsg()
     ne['dst'] = self.broadcast
     ne['id'] = uuid.uuid4().bytes
     ne['header']['pid'] = os.getpid()
     ne['header']['type'] = NLMSG_TRANSPORT
     ne['header']['flags'] = NLT_CONTROL | NLT_RESPONSE
     ne['attrs'] = [['IPR_ATTR_CDATA',
                     rsp.buf.getvalue()]]
     ne.encode()
     client.send(ne.buf.getvalue())
     self.ioloop.register(client, self.route, defer=True)
コード例 #11
0
ファイル: client.py プロジェクト: bouttier/pyroute2
 def nlm_push(self, msg,
              msg_type=None,
              msg_flags=None,
              env_flags=None,
              realm=0,
              nonce=0):
     msg['header']['sequence_number'] = nonce
     msg['header']['pid'] = os.getpid()
     if msg_type is not None:
         msg['header']['type'] = msg_type
     if msg_flags is not None:
         msg['header']['flags'] = msg_flags
     msg.encode()
     envelope = envmsg()
     envelope['header']['sequence_number'] = nonce
     envelope['header']['pid'] = os.getpid()
     envelope['header']['type'] = NLMSG_TRANSPORT
     if env_flags is not None:
         envelope['header']['flags'] = env_flags
     envelope['dst'] = realm
     envelope['src'] = 0
     envelope['attrs'] = [['IPR_ATTR_CDATA', msg.buf.getvalue()]]
     envelope.encode()
     self.bridge.send(envelope.buf.getvalue())
コード例 #12
0
ファイル: client.py プロジェクト: bouttier/pyroute2
    def _feed_buffers(self):
        '''
        Background thread to feed reassembled buffers to the parser
        '''
        save = None
        while True:
            buf = io.BytesIO()
            buf.length = buf.write(self.buffers.get())
            if self._stop_event.is_set():
                return

            buf.seek(0)

            if save is not None:
                # concatenate buffers
                buf.seek(0)
                save.write(buf.read())
                save.length += buf.length
                # discard save
                buf = save
                save = None

            offset = 0
            while offset < buf.length:
                buf.seek(offset)
                (length,
                 mtype,
                 flags) = struct.unpack('IHH', buf.read(8))

                if offset + length > buf.length:
                    # create save buffer
                    buf.seek(offset)
                    save = io.BytesIO()
                    save.length = save.write(buf.read())
                    # truncate the buffer
                    buf.truncate(offset)
                    break

                buf.seek(offset)
                data = io.BytesIO()
                data.write(buf.read(length))
                data.length = length
                data.seek(0)

                # data traffic
                envelope = envmsg(data)
                envelope.decode()
                nonce = envelope['header']['sequence_number']
                try:
                    buf = io.BytesIO()
                    buf.length = buf.write(envelope.
                                           get_attr('IPR_ATTR_CDATA'))
                    buf.seek(0)
                    if flags == 1:
                        msg = mgmtmsg(buf)
                        msg.decode()
                        self.listeners[nonce].put_nowait(msg)
                    else:
                        self.parse(buf)
                except AttributeError:
                    # now silently drop bad packet
                    pass

                offset += length
コード例 #13
0
ファイル: iocore.py プロジェクト: bouttier/pyroute2
 def parse_envelope(self, data):
     data.seek(0)
     envelope = envmsg(data)
     envelope.decode()
     return envelope
コード例 #14
0
ファイル: iocore.py プロジェクト: bouttier/pyroute2
    def route_control(self, sock, data):
        # open envelope
        envelope = self.parse_envelope(data)
        pid = envelope['header']['pid']
        nonce = envelope['header']['sequence_number']
        src = envelope['src']
        dst = envelope['dst']
        data = io.BytesIO(envelope.get_attr('IPR_ATTR_CDATA'))
        cmd = self.parse_control(data)
        rsp = mgmtmsg()
        rsp['header']['type'] = NLMSG_CONTROL
        rsp['header']['sequence_number'] = nonce
        rsp['cmd'] = IPRCMD_ERR
        rsp['attrs'] = []

        if sock in self.controls:
            if cmd['cmd'] == IPRCMD_STOP:
                # Last 'hello'
                rsp['cmd'] = IPRCMD_ACK
                rsp.encode()
                ne = envmsg()
                ne['header']['sequence_number'] = nonce
                ne['header']['pid'] = pid
                ne['header']['type'] = NLMSG_TRANSPORT
                ne['header']['flags'] = 1
                ne['dst'] = src
                ne['src'] = dst
                ne['attrs'] = [['IPR_ATTR_CDATA', rsp.buf.getvalue()]]
                ne.encode()
                sock.send(ne.buf.getvalue())
                # Stop iothread -- shutdown sequence
                self._stop_event.set()
                self.queue.put(None)
                self.control.send(struct.pack('I', 4))
                return

            elif cmd['cmd'] == IPRCMD_RELOAD:
                # Reload io cycle
                self._reload_event.set()
                rsp['cmd'] = IPRCMD_ACK

            elif cmd['cmd'] == IPRCMD_SERVE:
                url = cmd.get_attr('IPR_ATTR_HOST')
                key = cmd.get_attr('IPR_ATTR_SSL_KEY')
                cert = cmd.get_attr('IPR_ATTR_SSL_CERT')
                ca = cmd.get_attr('IPR_ATTR_SSL_CA')
                (new_sock, addr) = _get_socket(url, server_side=True,
                                               key=key,
                                               cert=cert,
                                               ca=ca)
                new_sock.bind(addr)
                if new_sock.type == socket.SOCK_STREAM:
                    new_sock.listen(16)
                    self.servers.add(new_sock)
                self._rlist.add(new_sock)
                self.noop()
                rsp['cmd'] = IPRCMD_ACK

            elif cmd['cmd'] == IPRCMD_SHUTDOWN:
                url = cmd.get_attr('IPR_ATTR_HOST')
                for old_sock in tuple(self.servers):
                    if _repr_sockets([old_sock], 'local') == [url]:
                        self._rlist.remove(old_sock)
                        self.servers.remove(old_sock)
                        self.noop()
                        rsp['cmd'] = IPRCMD_ACK

            elif cmd['cmd'] == IPRCMD_DISCONNECT:
                # drop a connection, identified by an addr
                try:
                    addr = cmd.get_attr('IPR_ATTR_ADDR')
                    self.deregister_link(addr)
                    rsp['cmd'] = IPRCMD_ACK
                    self.noop()
                except Exception as e:
                    rsp['attrs'] = [['IPR_ATTR_ERROR', str(e)]]

            elif cmd['cmd'] == IPRCMD_CONNECT:
                # connect to a system
                try:
                    url = cmd.get_attr('IPR_ATTR_HOST')
                    key = cmd.get_attr('IPR_ATTR_SSL_KEY')
                    cert = cmd.get_attr('IPR_ATTR_SSL_CERT')
                    ca = cmd.get_attr('IPR_ATTR_SSL_CA')
                    target = urlparse.urlparse(url)
                    if target.scheme == 'netlink':
                        new_sock = NetlinkSocket(int(target.hostname))
                        new_sock.bind(int(target.port))
                        sys = cmd.get_attr('IPR_ATTR_SYS',
                                           self.default_sys[target.scheme])
                        send = lambda d, s:\
                            new_sock.sendto(self.gate_untag(d, s), (0, 0))
                        realm = self.alloc_addr(sys)
                        rsp['attrs'].append(['IPR_ATTR_ADDR', realm])
                        self.register_link(realm, new_sock, send)
                        rsp['cmd'] = IPRCMD_ACK
                        self.noop()
                    elif target.scheme == 'udp':
                        (new_sock, addr) = _get_socket(url,
                                                       server_side=False)
                        sys = cmd.get_attr('IPR_ATTR_SYS',
                                           self.default_sys[target.scheme])
                        send = lambda d, s:\
                            new_sock.sendto(self.gate_forward(d, s), addr)
                        realm = self.alloc_addr(sys)
                        rsp['attrs'].append(['IPR_ATTR_ADDR', realm])
                        self.register_link(realm, new_sock, send)
                        rsp['cmd'] = IPRCMD_ACK
                        self.noop()
                    else:
                        (new_sock, addr) = _get_socket(url,
                                                       server_side=False,
                                                       key=key,
                                                       cert=cert,
                                                       ca=ca)
                        new_sock.connect(addr)
                        sys = cmd.get_attr('IPR_ATTR_SYS',

                                           self.default_sys[target.scheme])
                        send = lambda d, s:\
                            new_sock.send(self.gate_forward(d, s))
                        realm = self.alloc_addr(sys)
                        rsp['attrs'].append(['IPR_ATTR_ADDR', realm])
                        self.register_link(realm, new_sock, send)
                        rsp['cmd'] = IPRCMD_ACK
                        self.noop()
                except Exception:
                    rsp['attrs'].append(['IPR_ATTR_ERROR',
                                         traceback.format_exc()])
        if sock in self.clients:
            if cmd['cmd'] == IPRCMD_SUBSCRIBE:
                try:
                    cid = self._cid.pop()
                    self.subscribe[cid] = {'socket': sock,
                                           'keys': []}
                    for key in cmd.get_attrs('IPR_ATTR_KEY'):
                        target = (key['offset'],
                                  key['key'],
                                  key['mask'])
                        self.subscribe[cid]['keys'].append(target)
                    rsp['cmd'] = IPRCMD_ACK
                    rsp['attrs'].append(['IPR_ATTR_CID', cid])
                except Exception:
                    rsp['attrs'].append(['IPR_ATTR_ERROR',
                                         traceback.format_exc()])

            elif cmd['cmd'] == IPRCMD_UNSUBSCRIBE:
                cid = cmd.get_attr('IPR_ATTR_CID')
                if cid in self.subscribe:
                    del self.subscribe[cid]
                    self._cid.append(cid)
                    rsp['cmd'] = IPRCMD_ACK

            elif cmd['cmd'] == IPRCMD_REGISTER:
                # auth request
                secret = cmd.get_attr('IPR_ATTR_SECRET')
                if secret == self.secret:
                    self.controls.add(sock)
                    rsp['cmd'] = IPRCMD_ACK

        rsp.encode()
        ne = envmsg()
        ne['header']['sequence_number'] = nonce
        ne['header']['pid'] = pid
        ne['header']['type'] = NLMSG_TRANSPORT
        ne['header']['flags'] = 1
        ne['dst'] = src
        ne['src'] = dst
        ne['attrs'] = [['IPR_ATTR_CDATA', rsp.buf.getvalue()]]
        ne.encode()
        sock.send(ne.buf.getvalue())
コード例 #15
0
ファイル: connect.py プロジェクト: hegusung/pyroute2
def command(broker, sock, env, cmd, rsp):
    url = cmd.get_attr('IPR_ATTR_HOST')
    key = cmd.get_attr('IPR_ATTR_SSL_KEY')
    cert = cmd.get_attr('IPR_ATTR_SSL_CERT')
    ca = cmd.get_attr('IPR_ATTR_SSL_CA')

    target = urlparse.urlparse(url)
    peer = broker.addr
    remote = False
    established = False
    uid = str(uuid.uuid4())

    route = broker.route

    if url in broker.providers:
        new_sock = broker.providers[url]
        established = True
        gate = lambda d, s:\
            new_sock.send(broker.gate_forward(d, s))

    elif target.scheme == 'netlink':
        res = target.path.split("/")
        new_sock = NetlinkSocket(int(res[1]))
        new_sock.bind(int(res[2]))
        gate = lambda d, s:\
            new_sock.sendto(broker.gate_untag(d, s), (0, 0))
        route = broker.route_netlink

    elif target.scheme == 'udp':
        (new_sock, addr) = get_socket(url, server=False)
        gate = lambda d, s:\
            new_sock.sendto(broker.gate_forward(d, s), addr)
        remote = True

    else:
        (new_sock, addr) = get_socket(url,
                                      server=False,
                                      key=key,
                                      cert=cert,
                                      ca=ca)
        try:
            new_sock.connect(addr)
        except Exception:
            new_sock.close()
            raise
        remote = True
        # stream sockets provide the peer announce
        buf = io.BytesIO()
        buf.length = buf.write(new_sock.recv(16384))
        buf.seek(0)
        msg = envmsg(buf)
        msg.decode()
        buf = io.BytesIO()
        buf.length = buf.write(msg.get_attr('IPR_ATTR_CDATA'))
        buf.seek(0)
        msg = mgmtmsg(buf)
        msg.decode()
        peer = msg.get_attr('IPR_ATTR_ADDR')

        gate = lambda d, s:\
            new_sock.send(broker.gate_forward(d, s))

    port = broker.alloc_addr()
    link = broker.register_link(uid=uid,
                                port=port,
                                sock=new_sock,
                                established=established,
                                remote=remote)
    link.gate = gate
    broker.discover[target.path] = port
    rsp['attrs'].append(['IPR_ATTR_UUID', uid])
    rsp['attrs'].append(['IPR_ATTR_ADDR', peer])
    try:
        broker.ioloop.register(new_sock, route,
                               defer=True)
    except Exception as e:
        if e.errno != errno.EEXIST:
            raise e
コード例 #16
0
def command(broker, sock, env, cmd, rsp):
    url = cmd.get_attr('IPR_ATTR_HOST')
    key = cmd.get_attr('IPR_ATTR_SSL_KEY')
    cert = cmd.get_attr('IPR_ATTR_SSL_CERT')
    ca = cmd.get_attr('IPR_ATTR_SSL_CA')

    target = urlparse.urlparse(url)
    peer = broker.addr
    remote = False
    established = False
    uid = str(uuid.uuid4())

    route = broker.route

    if url in broker.providers:
        new_sock = broker.providers[url]
        established = True
        gate = lambda d, s:\
            new_sock.send(broker.gate_forward(d, s))

    elif target.scheme == 'netlink':
        res = target.path.split("/")
        new_sock = NetlinkSocket(int(res[1]))
        new_sock.bind(int(res[2]))
        gate = lambda d, s:\
            new_sock.sendto(broker.gate_untag(d, s), (0, 0))
        route = broker.route_netlink

    elif target.scheme == 'udp':
        (new_sock, addr) = get_socket(url, server=False)
        gate = lambda d, s:\
            new_sock.sendto(broker.gate_forward(d, s), addr)
        remote = True

    else:
        (new_sock, addr) = get_socket(url,
                                      server=False,
                                      key=key,
                                      cert=cert,
                                      ca=ca)
        try:
            new_sock.connect(addr)
        except Exception:
            new_sock.close()
            raise
        remote = True
        # stream sockets provide the peer announce
        buf = io.BytesIO()
        buf.length = buf.write(new_sock.recv(16384))
        buf.seek(0)
        msg = envmsg(buf)
        msg.decode()
        buf = io.BytesIO()
        buf.length = buf.write(msg.get_attr('IPR_ATTR_CDATA'))
        buf.seek(0)
        msg = mgmtmsg(buf)
        msg.decode()
        peer = msg.get_attr('IPR_ATTR_ADDR')

        gate = lambda d, s:\
            new_sock.send(broker.gate_forward(d, s))

    port = broker.alloc_addr()
    link = broker.register_link(uid=uid,
                                port=port,
                                sock=new_sock,
                                established=established,
                                remote=remote)
    link.gate = gate
    broker.discover[target.path] = port
    rsp['attrs'].append(['IPR_ATTR_UUID', uid])
    rsp['attrs'].append(['IPR_ATTR_ADDR', peer])
    try:
        broker.ioloop.register(new_sock, route, defer=True)
    except Exception as e:
        if e.errno != errno.EEXIST:
            raise e