Example #1
0
def receive_annoted_file_descriptor(receive_socket):
    """Receive a single file descriptor and attached annotation information via SCM_RIGHTS via the given socket. The method
    may raise an Exception when invoked on non-blocking sockets and no messages available.
    @return a tuple containing the received file descriptor, type information (see sendAnnotatedFileDescriptor) and the annotation
    information."""
    message_data, anc_data, _flags, _remote_address = receive_socket.recvmsg(
        1 << 16, socket.CMSG_LEN(struct.calcsize('i')))
    if len(anc_data) != 1:
        raise Exception('Received %d sets of ancillary data instead of 1' %
                        len(anc_data))
    cmsg_level, cmsg_type, cmsg_data = anc_data[0]
    if (cmsg_level != socket.SOL_SOCKET) or (cmsg_type != socket.SCM_RIGHTS):
        raise Exception('Received invalid message from remote side')
    # Do not accept multiple or unaligned FDs.
    if len(cmsg_data) != 4:
        raise Exception('Unsupported control message length %d' %
                        len(cmsg_data))
    received_fd = struct.unpack('i', cmsg_data)[0]

    split_pos = message_data.find(b'\x00')
    if split_pos < 0:
        raise Exception('No null byte in received message')
    type_info = message_data[:split_pos]
    annotation_data = message_data[split_pos + 1:]
    if received_fd <= 2:
        print('WARNING: received "reserved" fd %d' % received_fd,
              file=sys.stderr)
    if isinstance(type_info, str):
        type_info = type_info.encode()
    if isinstance(annotation_data, str):
        annotation_data = annotation_data.encode()
    return received_fd, type_info, annotation_data
Example #2
0
    def _read_ready(self):
        if self._conn_lost:
            return
        try:
            # 50 bytes is larger than sockaddr_in or sockaddr_in6
            data, ancdata, _, src = self._sock.recvmsg(self.max_size,
                                                       socket.CMSG_LEN(50))
            dst = self._sock_addr
            for cmsg_level, cmsg_type, cmsg_data in ancdata:
                if cmsg_level == socket.SOL_IP and cmsg_type == IP_RECVORIGDSTADDR:
                    dst = _native_sockaddr_to_python(cmsg_data)

            # on a dual stack, receive from IPv4 is possible, return mapped address like src
            if self._send_sock_v6 is not None and len(dst) == 2:
                dst = ("::ffff:" + dst[0], dst[1], 0, 0)

        except (BlockingIOError, InterruptedError):
            pass
        except OSError as exc:
            self._protocol.error_received(exc)
        except (SystemExit, KeyboardInterrupt):
            raise
        except BaseException as exc:
            self._fatal_error(exc, "Fatal read error on datagram transport")
        else:
            self._protocol.received_from(data, src, dst)
Example #3
0
 def recvfds(sock, size):
     '''Receive an array of fds over an AF_UNIX socket.'''
     a = array.array('i')
     bytes_size = a.itemsize * size
     msg, ancdata, flags, addr = sock.recvmsg(1,
                                              socket.CMSG_LEN(bytes_size))
     if not msg and not ancdata:
         raise EOFError
     try:
         if ACKNOWLEDGE:
             sock.send(b'A')
         if len(ancdata) != 1:
             raise RuntimeError('received %d items of ancdata' %
                                len(ancdata))
         cmsg_level, cmsg_type, cmsg_data = ancdata[0]
         if (cmsg_level == socket.SOL_SOCKET
                 and cmsg_type == socket.SCM_RIGHTS):
             if len(cmsg_data) % a.itemsize != 0:
                 raise ValueError
             a.frombytes(cmsg_data)
             assert len(a) % 256 == msg[0]
             return list(a)
     except (ValueError, IndexError):
         pass
     raise RuntimeError('Invalid data received')
Example #4
0
def recv_fd(sock):
    msg, ancdata, flags, addr = sock.recvmsg(
        1, socket.CMSG_LEN(struct.calcsize("i")))
    cmsg_level, cmsg_type, cmsg_data = ancdata[0]
    assert cmsg_level == socket.SOL_SOCKET and cmsg_type == socket.SCM_RIGHTS
    sock.sendall(b"OK")
    return struct.unpack("i", cmsg_data[0])
    def receive_file_descriptors(self,
                                 sock: socket.SocketType) -> dict[str, Any]:
        """Receive file descriptors.

        See https://docs.python.org/3/library/socket.html#socket.socket.recvmsg .

        Protocol:
        1. Size of the filenames array (json) (64bites, #filenames_length).
        2. Filenames & file descriptors.
        3. Wait for single byte to confirm.
        """
        filenames_length = int.from_bytes(sock.recv(8), byteorder="big")
        logger.debug("Received file descriptors message of length: %d.",
                     filenames_length)
        if filenames_length == 0:
            return dict()
        fds = array.array("i")  # Array of ints
        msg, ancdata, flags, addr = sock.recvmsg(
            filenames_length,
            socket.CMSG_LEN(DESCRIPTOR_CHUNK_SIZE * fds.itemsize))
        logger.debug("Received file descriptors: %s, %s.", msg, ancdata)
        filenames = json.loads(msg.decode())
        for cmsg_level, cmsg_type, cmsg_data in ancdata:
            if cmsg_level == socket.SOL_SOCKET and cmsg_type == socket.SCM_RIGHTS:
                # Append data, ignoring any truncated integers at the end.
                fds.frombytes(cmsg_data[:len(cmsg_data) -
                                        (len(cmsg_data) % fds.itemsize)])
        return dict(zip(filenames, fds))
Example #6
0
def receive(sock_info):
    # pylint:disable=too-many-locals
    (sock, interface_name, interface_index) = sock_info
    ancillary_size = socket.CMSG_LEN(MAX_SIZE)
    try:
        message, ancillary_messages, _msg_flags, source = sock.recvmsg(
            MAX_SIZE, ancillary_size)
        message_str = message.decode()
    except Exception as exception:
        report("exception {} while receiving on {}".format(
            exception, interface_name))
    else:
        rx_interface_index = None
        for anc in ancillary_messages:
            # pylint:disable=no-member
            if anc[0] == socket.SOL_IP and anc[1] == socket.IP_PKTINFO:
                packet_info = in_pktinfo.from_buffer_copy(anc[2])
                rx_interface_index = packet_info.ipi_ifindex
            elif anc[0] == socket.SOL_IPV6 and anc[1] == socket.IPV6_PKTINFO:
                packet_info = in6_pktinfo.from_buffer_copy(anc[2])
                rx_interface_index = packet_info.ipi6_ifindex
        if rx_interface_index and (rx_interface_index != interface_index):
            return
        report("received {} on {} from {}".format(message_str, interface_name,
                                                  source))
Example #7
0
    async def receive_fds(self, msglen: int,
                          maxfds: int) -> Tuple[bytes, List[int]]:
        if not isinstance(msglen, int) or msglen < 0:
            raise ValueError('msglen must be a non-negative integer')
        if not isinstance(maxfds, int) or maxfds < 1:
            raise ValueError('maxfds must be a positive integer')

        fds = array.array("i")
        await checkpoint()
        with self._receive_guard:
            while True:
                try:
                    message, ancdata, flags, addr = await self._trio_socket.recvmsg(
                        msglen, socket.CMSG_LEN(maxfds * fds.itemsize))
                except BaseException as exc:
                    self._convert_socket_error(exc)
                else:
                    if not message and not ancdata:
                        raise EndOfStream

                    break

        for cmsg_level, cmsg_type, cmsg_data in ancdata:
            if cmsg_level != socket.SOL_SOCKET or cmsg_type != socket.SCM_RIGHTS:
                raise RuntimeError(
                    f'Received unexpected ancillary data; message = {message}, '
                    f'cmsg_level = {cmsg_level}, cmsg_type = {cmsg_type}')

            fds.frombytes(cmsg_data[:len(cmsg_data) -
                                    (len(cmsg_data) % fds.itemsize)])

        return message, list(fds)
Example #8
0
    def receive_file_descriptors(
            self, sock: socket.SocketType) -> Tuple[str, dict[str, Any], bool]:
        """Receive file descriptors.

        See https://docs.python.org/3/library/socket.html#socket.socket.recvmsg .

        Protocol:
        1. Size of the filenames array (json) (64bites, #filenames_length).
        2. Connector name, filenames, presigned flag & file descriptors.
        3. Send response in the form {"success": bool, "presigned_urls": list}.
        """
        filenames_length = int.from_bytes(sock.recv(8), byteorder="big")
        logger.debug("Received file descriptors message of length: %d.",
                     filenames_length)
        if filenames_length == 0:
            return ("", dict(), False)
        fds = array.array("i")  # Array of ints
        msg, ancdata, flags, addr = sock.recvmsg(
            filenames_length,
            socket.CMSG_LEN(DESCRIPTOR_CHUNK_SIZE * fds.itemsize))
        logger.debug("Received file descriptors: %s, %s.", msg, ancdata)
        storage_name, filenames, need_presigned_urls = json.loads(msg.decode())
        for cmsg_level, cmsg_type, cmsg_data in ancdata:
            if cmsg_level == socket.SOL_SOCKET and cmsg_type == socket.SCM_RIGHTS:
                # Append data, ignoring any truncated integers at the end.
                fds.frombytes(cmsg_data[:len(cmsg_data) -
                                        (len(cmsg_data) % fds.itemsize)])
        return (storage_name, dict(zip(filenames, fds)), need_presigned_urls)
def _ReceiveFDs(sock):
  """Receives FDs from ash-chrome that will be used to launch lacros-chrome.

  Args:
    sock: A connected unix domain socket.

  Returns:
    File objects for the mojo connection and maybe startup data file.
  """
  # This function is borrowed from with modifications:
  # https://docs.python.org/3/library/socket.html#socket.socket.recvmsg
  fds = array.array("i")  # Array of ints
  # Along with the file descriptor, ash-chrome also sends the version in the
  # regular data.
  version, ancdata, _, _ = sock.recvmsg(1, socket.CMSG_LEN(fds.itemsize))
  for cmsg_level, cmsg_type, cmsg_data in ancdata:
    if cmsg_level == socket.SOL_SOCKET and cmsg_type == socket.SCM_RIGHTS:
      # New ash-chrome returns two FDs: one for mojo connection, and the second
      # for the startup data FD. Old one returns only the mojo connection.
      # TODO(crbug.com/1156033): Clean up the code after dropping the
      # old protocol support.
      assert len(cmsg_data) in (fds.itemsize, fds.itemsize *
                                2), ('Expecting exactly 1 or 2 FDs')
      fds.frombytes(cmsg_data[:])

  assert version == b'\x00', 'Expecting version code to be 0'
  assert len(fds) in (1, 2), 'Expecting exactly 1 or 2 FDs'
  mojo_fd = os.fdopen(fds[0])
  startup_fd = None if len(fds) < 2 else os.fdopen(fds[1])
  return mojo_fd, startup_fd
Example #10
0
    def receive_fd(self):
        '''Receive a file descriptor over UNIX domain socket using recvmsg.'''
        # A message to signal we are ready for the fd msg
        self.send_msg(self.cur_hdr[0], EMPTY_STRUCT, EMPTY_TUPLE)

        fds = array.array("i")  # Array of ints
        maxfds = 1
        msglen = 1
        while True:
            try:
                _, ancdata, _, _ = self.socket.recvmsg(
                    msglen, socket.CMSG_LEN(maxfds * fds.itemsize))
                break
            except BlockingIOError:
                pass
        for cmsg_level, cmsg_type, cmsg_data in ancdata:
            if cmsg_level == socket.SOL_SOCKET and cmsg_type == socket.SCM_RIGHTS:
                # Append data, ignoring any truncated integers at the end.
                fds.fromstring(cmsg_data[:len(cmsg_data) -
                                         (len(cmsg_data) % fds.itemsize)])
        fds_list = list(fds)
        if len(fds_list) != 1:
            logging.error('Expecting a single file descriptor')
            raise exception(errno.EINVAL)

        return fds_list[0]
Example #11
0
 def _recv_raw(self, sock, x):
     """Internal function to receive a Packet,
     and process ancillary data.
     """
     flags_len = socket.CMSG_LEN(4096)
     timestamp = None
     pkt, ancdata, flags, sa_ll = sock.recvmsg(x, flags_len)
     if not pkt:
         return pkt, sa_ll
     for cmsg_lvl, cmsg_type, cmsg_data in ancdata:
         # Check available ancillary data
         if (cmsg_lvl == SOL_PACKET and cmsg_type == PACKET_AUXDATA):
             # Parse AUXDATA
             auxdata = tpacket_auxdata.from_buffer_copy(cmsg_data)
             if auxdata.tp_vlan_tci != 0 or \
                     auxdata.tp_status & TP_STATUS_VLAN_VALID:
                 # Insert VLAN tag
                 tag = struct.pack("!HH", ETH_P_8021Q,
                                   auxdata.tp_vlan_tci)
                 pkt = pkt[:12] + tag + pkt[12:]
         elif cmsg_lvl == socket.SOL_SOCKET and \
                 cmsg_type == SO_TIMESTAMPNS:
             length = len(cmsg_data)
             if length == 16:  # __kernel_timespec
                 tmp = struct.unpack("ll", cmsg_data)
             elif length == 8:  # timespec
                 tmp = struct.unpack("ii", cmsg_data)
             else:
                 log_runtime.warning("Unknown timespec format.. ?!")
                 continue
             timestamp = tmp[0] + tmp[1] * 1e-9
     return pkt, sa_ll, timestamp
Example #12
0
def recv_sock(pr):
    ancsize = socket.CMSG_LEN(struct.calcsize('i'))
    msg, ancdata, flags, addr = pr.recvmsg(1,  ancsize)
    cmsg_level, cmsg_type, cmsg_data = ancdata[0]
    fd = struct.unpack('i', cmsg_data)[0]
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, fileno=fd)
    return sock
Example #13
0
        def recvfrom(s, sz):
            _to = None

            data, ancdata, msg_flags, _from = s.recvmsg(
                sz, socket.CMSG_LEN(sz))

            for anc in ancdata:
                if anc[0] == socket.SOL_IP and anc[1] == socket.IP_PKTINFO:
                    addr = in_pktinfo.from_buffer_copy(anc[2])
                    addr = ipaddress.IPv4Address(
                        memoryview(addr.ipi_addr).tobytes())
                    _to = (str(addr), s.getsockname()[1])
                    break

                elif anc[0] == socket.SOL_IPV6 and anc[
                        1] == socket.IPV6_PKTINFO:
                    addr = in6_pktinfo.from_buffer_copy(anc[2])
                    addr = ipaddress.ip_address(
                        memoryview(addr.ipi6_addr).tobytes())
                    _to = (str(addr), s.getsockname()[1])
                    break

            debug.logger & debug.flagIO and debug.logger(
                'recvfrom: received %d octets from %s to %s; '
                'iov blob %r' % (len(data), _from, _to, ancdata))

            return data, addressType(_from).setLocalAddress(_to)
Example #14
0
def recv_fds(sock, msglen, maxfds):
    fds = array.array("i")   # Array of ints
    msg, ancdata, flags, addr = sock.recvmsg(msglen, socket.CMSG_LEN(maxfds * fds.itemsize))
    for cmsg_level, cmsg_type, cmsg_data in ancdata:
        if cmsg_level == socket.SOL_SOCKET and cmsg_type == socket.SCM_RIGHTS:
            fds.frombytes(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)])
            
    return msg, list(fds)
Example #15
0
def recv_fd(sock):
    '''Get file descriptor for memory map'''
    fds = array.array("i")   # Array of ints
    _, ancdata, _, _ = sock.recvmsg(0, socket.CMSG_LEN(4))
    for cmsg_level, cmsg_type, cmsg_data in ancdata:
        if cmsg_level == socket.SOL_SOCKET and cmsg_type == socket.SCM_RIGHTS:
            fds.frombytes(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)])
    return list(fds)[0]
Example #16
0
def recv_socket(s):
    data, ancdata, msg_flags, address = s.recvmsg(
        4, socket.CMSG_LEN(sys.getsizeof(int())))
    for cmsg_level, cmsg_type, cmsg_data in ancdata:
        if (cmsg_level == socket.SOL_SOCKET
                and cmsg_type == socket.SCM_RIGHTS):
            return data.decode(), BufferedSocketReader(
                fileno=int.from_bytes(cmsg_data, sys.byteorder))
Example #17
0
def recv_fds(sock, msglen, maxfds):
    fds = array.array("i")   # Array of ints
    msg, ancdata, flags, addr = sock.recvmsg(msglen, socket.CMSG_LEN(maxfds * fds.itemsize))
    for cmsg_level, cmsg_type, cmsg_data in ancdata:
        if (cmsg_level == socket.SOL_SOCKET and cmsg_type == socket.SCM_RIGHTS):
            # Append data, ignoring any truncated integers at the end.
            fds.fromstring(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)])
    return msg, list(fds)
def loop_slave(pr, handlers):
    while True:
        bufsize = 1
        ancsize = socket.CMSG_LEN(struct.calcsize('i'))
        msg, ancdata, flags, addr = pr.recvmsg(bufsize, ancsize)
        cmsg_level, cmsg_type, cmsg_data = ancdata[0]
        fd = struct.unpack('i', cmsg_data)[0]
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, fileno=fd)
        handle_conn(sock, sock.getpeername(), handlers)
Example #19
0
    def recv(self):
        """Receive a Message

        This receives the next pending message from the socket. This operation
        is synchronous.

        A tuple consisting of the deserialized message payload, the auxiliary
        file-descriptor set, and the socket-address of the sender is returned.
        """

        # On `SOCK_DGRAM`, packets might be arbitrarily sized. There is no
        # hard-coded upper limit, since it is only restricted by the size of
        # the kernel write buffer on sockets (which itself can be modified via
        # sysctl). The only real maximum is probably something like 2^31-1,
        # since that is the maximum of that sysctl datatype.
        # Anyway, `MSG_TRUNC+MSG_PEEK` usually allows us to easily peek at the
        # incoming buffer. Unfortunately, the python `recvmsg()` wrapper
        # discards the return code and we cannot use that. Instead, we simply
        # loop until we know the size. This is slightly awkward, but seems fine
        # as long as you do not put this into a hot-path.
        size = 4096
        while True:
            peek = self._socket.recvmsg(size, 0, socket.MSG_PEEK)
            if not (peek[2] & socket.MSG_TRUNC):
                break
            size *= 2

        # Fetch a packet from the socket. On linux, the maximum SCM_RIGHTS array
        # size is hard-coded to 253. This allows us to size the ancillary buffer
        # big enough to receive any possible message.
        fds = array.array("i")
        msg = self._socket.recvmsg(size, socket.CMSG_LEN(253 * fds.itemsize))

        # First thing we do is always to fetch the CMSG FDs into an FdSet. This
        # guarantees that we do not leak FDs in case the message handling fails
        # for other reasons.
        for level, ty, data in msg[1]:
            if level == socket.SOL_SOCKET and ty == socket.SCM_RIGHTS:
                assert len(data) % fds.itemsize == 0
                fds.frombytes(data)
        fdset = FdSet(rawfds=fds)

        # Check the returned message flags. If the message was truncated, we
        # have to discard it. This shouldn't happen, but there is no harm in
        # handling it. However, `CTRUNC` can happen, since it is also triggered
        # when LSMs reject FD transmission. Treat it the same as a parser error.
        flags = msg[2]
        if flags & (socket.MSG_TRUNC | socket.MSG_CTRUNC):
            raise BufferError

        try:
            payload = json.loads(msg[0])
        except json.JSONDecodeError:
            raise BufferError

        return (payload, fdset, msg[3])
Example #20
0
def recv_fd(sock):
    """
    Receive a single file descriptor
    """
    msg, ancdata, flags, addr = sock.recvmsg(
        1, socket.CMSG_LEN(struct.calcsize('i')))
    cmsg_level, cmsg_type, cmsg_data = ancdata[0]
    assert cmsg_level == socket.SOL_SOCKET and cmsg_type == socket.SCM_RIGHTS
    sock.sendall(b'OK')
    return struct.unpack('i', cmsg_data)[0]
Example #21
0
def load_fds(sock, msglen):
    fds = array.array("i")  # Array of ints
    msg, ancdata, _, addr = sock.recvmsg(msglen,
                                         socket.CMSG_LEN(253 * fds.itemsize))
    for cmsg_level, cmsg_type, cmsg_data in ancdata:
        if (cmsg_level == socket.SOL_SOCKET
                and cmsg_type == socket.SCM_RIGHTS):
            # Append data, ignoring any truncated integers at the end.
            fds.frombytes(cmsg_data[:len(cmsg_data) -
                                    (len(cmsg_data) % fds.itemsize)])
    return json.loads(msg), list(fds), addr
Example #22
0
def read_fd(sock):
    """Read a descriptor from the socket."""
    data_size, ancdata_size = 1, socket.CMSG_LEN(struct.calcsize(FMT))

    # read the data and ancillary data from the UNIX domain socket
    # we're interested only in ancillary data that contains descriptor
    msg, ancdata, flags, addr = sock.recvmsg(data_size, ancdata_size)

    cmsg_level, cmsg_type, cmsg_data  = ancdata[0]
    if cmsg_level == socket.SOL_SOCKET and cmsg_type == socket.SCM_RIGHTS:
        fd = struct.unpack(FMT, cmsg_data)[0]
        return fd
Example #23
0
 def recv_handle(conn):
     size = struct.calcsize("@i")
     with socket.fromfd(conn.fileno(), socket.AF_UNIX, socket.SOCK_STREAM) as s:
         msg, ancdata, flags, addr = s.recvmsg(1, socket.CMSG_LEN(size))
         try:
             cmsg_level, cmsg_type, cmsg_data = ancdata[0]
             if (cmsg_level == socket.SOL_SOCKET and
                 cmsg_type == socket.SCM_RIGHTS):
                 return struct.unpack("@i", cmsg_data[:size])[0]
         except (ValueError, IndexError, struct.error):
             pass
         raise RuntimeError('Invalid data received')
Example #24
0
def _ReceiveFDs(sock):
    """Receives FDs from ash-chrome that will be used to launch lacros-chrome.

    Args:
      sock: A connected unix domain socket.

    Returns:
      File objects for the mojo connection and maybe startup data file.
    """
    # This function is borrowed from with modifications:
    # https://docs.python.org/3/library/socket.html#socket.socket.recvmsg
    fds = array.array("i")  # Array of ints
    # Along with the file descriptor, ash-chrome also sends the version in the
    # regular data.
    version, ancdata, _, _ = sock.recvmsg(
        1, socket.CMSG_LEN(fds.itemsize * _NUM_FDS_MAX))
    for cmsg_level, cmsg_type, cmsg_data in ancdata:
        if cmsg_level == socket.SOL_SOCKET and cmsg_type == socket.SCM_RIGHTS:
            # There are three versions currently this script supports.
            # The oldest one: ash-chrome returns one FD, the mojo connection of
            # old bootstrap procedure (i.e., it will be BrowserService).
            # The middle one: ash-chrome returns two FDs, the mojo connection of
            # old bootstrap procedure, and the second for the start up data FD.
            # The newest one: ash-chrome returns three FDs, the mojo connection of
            # old bootstrap procedure, the second for the start up data FD, and
            # the third for another mojo connection of new bootstrap procedure.
            # TODO(crbug.com/1156033): Clean up the code to drop the support of
            # oldest one after M91.
            # TODO(crbug.com/1180712): Clean up the mojo procedure support of the
            # the middle one after M92.
            cmsg_len_candidates = [(i + 1) * fds.itemsize
                                   for i in range(_NUM_FDS_MAX)]
            assert len(cmsg_data) in cmsg_len_candidates, (
                'CMSG_LEN is unexpected: %d' % (len(cmsg_data), ))
            fds.frombytes(cmsg_data[:])

    if version == b'\x00':
        assert len(fds) in (1, 2, 3), 'Expecting exactly 1, 2, or 3 FDs'
        legacy_mojo_fd = os.fdopen(fds[0])
        startup_fd = None if len(fds) < 2 else os.fdopen(fds[1])
        mojo_fd = None if len(fds) < 3 else os.fdopen(fds[2])
    elif version == b'\x01':
        assert len(fds) == 2, 'Expecting exactly 2 FDs'
        legacy_mojo_fd = None
        startup_fd = os.fdopen(fds[0])
        mojo_fd = os.fdopen(fds[1])
    elif version:
        raise AssertionError('Unknown version: \\x%s' % version.hex())
    else:
        raise AssertionError(
            'Failed to receive startup message from ash-chrome. '
            'Make sure you\'re logged in to Chrome OS.')
    return legacy_mojo_fd, startup_fd, mojo_fd
Example #25
0
def _recv_fds(sock, bufsize, maxfds, flags=0):
    fds = array.array('i')
    msg, ancdata, flags, addr = sock.recvmsg(
        bufsize,
        socket.CMSG_LEN(maxfds * fds.itemsize),
        flags,
    )
    for cmsg_level, cmsg_type, cmsg_data in ancdata:
        if cmsg_level == socket.SOL_SOCKET and cmsg_type == socket.SCM_RIGHTS:
            fds.frombytes(cmsg_data[:len(cmsg_data) -
                                    (len(cmsg_data) % fds.itemsize)])
    return msg, list(fds), flags, addr
Example #26
0
    def recv_fds(self):
        assert self._mode == 'receiver'
        fds = array.array('i')
        msg, ancdata, msg_flags, address = self.receiver.recvmsg(
            self.fixed_msg_len, socket.CMSG_LEN(self.max_fds * fds.itemsize))

        for cmsg_level, cmsg_type, cmsg_data in ancdata:
            if (cmsg_level == socket.SOL_SOCKET
                    and cmsg_type == socket.SCM_RIGHTS):
                truncated = len(cmsg_data) % fds.itemsize
                fds.frombytes(cmsg_data[:len(cmsg_data) - truncated])

        return msg, fds
def recv_fds(sock, msglen, maxfds):
    """ Receive FDs from the unix socket. Copy-pasted from the Python doc.
    Used only if both grading and student containers are using docker runtime"""
    fds = array.array("i")  # Array of ints
    msg, ancdata, _, addr = sock.recvmsg(
        msglen, socket.CMSG_LEN(maxfds * fds.itemsize))
    for cmsg_level, cmsg_type, cmsg_data in ancdata:
        if (cmsg_level == socket.SOL_SOCKET
                and cmsg_type == socket.SCM_RIGHTS):
            # Append data, ignoring any truncated integers at the end.
            fds.fromstring(cmsg_data[:len(cmsg_data) -
                                     (len(cmsg_data) % fds.itemsize)])
    return msg, list(fds)
Example #28
0
 def recvfrom(s, sz):
     _to = None
     data, ancdata, msg_flags, _from = s.recvmsg(sz, socket.CMSG_LEN(sz))
     for anc in ancdata:
         if anc[0] == socket.SOL_IP and anc[1] == socket.IP_PKTINFO:
             addr = in_pktinfo.from_buffer_copy(anc[2])
             addr = ipaddress.IPv4Address(memoryview(addr.ipi_addr).tobytes())
             _to = (str(addr), s.getsockname()[1])
         elif anc[0] == socket.SOL_IPV6 and anc[1] == socket.IPV6_PKTINFO:
             addr = in6_pktinfo.from_buffer_copy(anc[2])
             addr = ipaddress.ip_address(memoryview(addr.ipi6_addr).tobytes())
             _to = (str(addr), s.getsockname()[1])
     return data, addressType(_from).setLocalAddress(_to)
def recvfromto(s):
    _to = None
    data, ancdata, msg_flags, _from = s.recvmsg(5120,
                                                socket.CMSG_LEN(5120 * 5))
    for anc in ancdata:
        if anc[0] == socket.SOL_IP and anc[1] == IP_PKTINFO:
            addr = in_pktinfo.from_buffer_copy(anc[2])
            addr = ipaddress.IPv4Address(memoryview(addr.ipi_addr).tobytes())
            _to = (str(addr), s.getsockname()[1])
        elif anc[0] == SOL_IPV6 and anc[1] == IPV6_PKTINFO:
            addr = in6_pktinfo.from_buffer_copy(anc[2])
            addr = ipaddress.ip_address(memoryview(addr.ipi6_addr).tobytes())
            _to = (str(addr), s.getsockname()[1])
    return data, _from, _to
Example #30
0
 def _recv_raw(self, sock, x):
     # type: (socket.socket, int) -> Tuple[bytes, Any, Optional[float]]
     """Internal function to receive a Packet,
     and process ancillary data.
     """
     timestamp = None
     if not self.auxdata_available:
         pkt, _, _, sa_ll = sock.recvmsg(x)
         return pkt, sa_ll, timestamp
     flags_len = socket.CMSG_LEN(4096)
     pkt, ancdata, flags, sa_ll = sock.recvmsg(x, flags_len)
     if not pkt:
         return pkt, sa_ll, timestamp
     for cmsg_lvl, cmsg_type, cmsg_data in ancdata:
         # Check available ancillary data
         if (cmsg_lvl == SOL_PACKET and cmsg_type == PACKET_AUXDATA):
             # Parse AUXDATA
             try:
                 auxdata = tpacket_auxdata.from_buffer_copy(cmsg_data)
             except ValueError:
                 # Note: according to Python documentation, recvmsg()
                 #       can return a truncated message. A ValueError
                 #       exception likely indicates that Auxiliary
                 #       Data is not supported by the Linux kernel.
                 return pkt, sa_ll, timestamp
             if auxdata.tp_vlan_tci != 0 or \
                     auxdata.tp_status & TP_STATUS_VLAN_VALID:
                 # Insert VLAN tag
                 tpid = ETH_P_8021Q
                 if auxdata.tp_status & TP_STATUS_VLAN_TPID_VALID:
                     tpid = auxdata.tp_vlan_tpid
                 tag = struct.pack(
                     "!HH",
                     tpid,
                     auxdata.tp_vlan_tci
                 )
                 pkt = pkt[:12] + tag + pkt[12:]
         elif cmsg_lvl == socket.SOL_SOCKET and \
                 cmsg_type == SO_TIMESTAMPNS:
             length = len(cmsg_data)
             if length == 16:  # __kernel_timespec
                 tmp = struct.unpack("ll", cmsg_data)
             elif length == 8:  # timespec
                 tmp = struct.unpack("ii", cmsg_data)
             else:
                 log_runtime.warning("Unknown timespec format.. ?!")
                 continue
             timestamp = tmp[0] + tmp[1] * 1e-9
     return pkt, sa_ll, timestamp