Exemple #1
0
    async def _handleSocketAccept(
            self, request: networking.MsgSocketAcceptRequest
    ) -> networking.MsgResponse:
        debug(
            f'socketAccept handle={request.handle} timeout={request.timeout}')

        responseMsg = networking.MsgResponse()
        response = responseMsg.socketAcceptResponse

        response.handle = -1
        response.address.port = 0
        response.address.ip = 0

        try:
            handle = self._getFreeHandle()
            socketCtx = self._getSocketCtx(request.handle)

            socketCtx.setTimeoutMsec(request.timeout)

            (connection,
             address) = await runInThread(lambda: socketCtx.socket.accept())
            self._sockets[handle] = SocketContext(connection, socketCtx.type)

            response.handle = handle
            serializeAddress(address, response.address)
            response.err = 0

        except Exception as ex:
            response.err = logAndConvertException(
                f'socketAccept failed handle={request.handle}', ex)

        return responseMsg
Exemple #2
0
    async def _handleGetHostByName(
            self, request: networking.MsgGetHostByNameRequest
    ) -> networking.MsgResponse:
        debug(f'getHostByNameRequest name={request.name}')

        responseMsg = networking.MsgResponse()
        response = responseMsg.getHostByNameResponse
        response.name = ""

        try:
            hostname, aliases, addresses = await runInThread(
                lambda: socket.gethostbyname_ex(request.name))

            response.name = hostname

            if len(aliases) > 0:
                response.alias = aliases[0]

            response.addresses[:] = [
                cast(int, serializeIp(x)) for x in addresses
                if serializeIp(x) is not None
            ][:3]

            response.err = 0

        except Exception as ex:
            response.err = logAndConvertException(
                f'failed to resolve host {request.name}', ex)

        return responseMsg
Exemple #3
0
    async def _handeSocketReceive(
            self, request: networking.MsgSocketReceiveRequest
    ) -> networking.MsgResponse:
        debug(
            f'socketReceiveRequest: handle={request.handle} flags={request.flags} timeout={request.timeout} maxLength={request.maxLen} addressRequested={request.addressRequested}'
        )

        responseMsg = networking.MsgResponse()
        response = responseMsg.socketReceiveResponse

        response.data = b''

        try:
            socketCtx = self._getSocketCtx(request.handle)
            flags = translateFlags(request.flags)

            socketCtx.setTimeoutMsec(request.timeout)
            data, address = await runInThread(
                lambda: socketCtx.socket.recvfrom(request.maxLen, flags))

            if address != None and request.addressRequested:
                serializeAddress(address, response.address)

            response.data = data
            response.err = 0

            logPayload(response.data)

        except socket.timeout:
            response.err = err.netErrTimeout

        except Exception as ex:
            response.err = logAndConvertException("failed to receive", ex)

        return responseMsg
Exemple #4
0
    async def _handleSocketClose(
            self, request: networking.MsgSocketCloseRequest
    ) -> networking.MsgResponse:
        debug(
            f'socketCloseRequest: handle={request.handle} timeout={request.timeout}'
        )

        responseMsg = networking.MsgResponse()
        response = responseMsg.socketCloseResponse

        try:
            socketContext = self._getSocketCtx(request.handle)
            self._sockets[request.handle] = None

            socketContext.setTimeoutMsec(request.timeout)

            await socketContext.close()
            response.err = 0

        except socket.timeout:
            response.err = err.netErrTimeout

        except Exception as ex:
            response.err = logAndConvertException(
                f'failed to close socket {request.handle}', ex)

        return responseMsg
Exemple #5
0
    async def _handleSocketBind(
            self, request: networking.MsgSocketBindRequest
    ) -> networking.MsgResponse:
        debug(
            f'socketBindRequest: handle={request.handle} address={deserializeAddress(request.address)} timeout={request.timeout}'
        )

        responseMsg = networking.MsgResponse()
        response = responseMsg.socketBindResponse

        try:
            socketCtx = self._getSocketCtx(request.handle)

            socketCtx.setTimeoutMsec(request.timeout)

            await runInThread(lambda: socketCtx.socket.bind(
                deserializeAddress(request.address)
                if self._forceBindAddress is None else self._forceBindAddress))

            socketCtx.bound = True
            response.err = 0

        except socket.timeout:
            response.err = err.netErrTimeout

        except Exception as ex:
            response.err = logAndConvertException("failed to bind socket", ex)

        return responseMsg
Exemple #6
0
    async def _handleSocketSend(
            self, request: networking.MsgSocketSendRequest
    ) -> networking.MsgResponse:
        debug(
            f'socketSendRequest: handle={request.handle} len={len(request.data)} flags={request.flags} timeout={request.timeout} {f"address={deserializeAddress(request.address)}" if request.HasField("address") else ""}'
        )

        logPayload(request.data)

        responseMsg = networking.MsgResponse()
        response = responseMsg.socketSendResponse
        response.bytesSent = -1

        try:
            socketCtx = self._getSocketCtx(request.handle)
            sock = socketCtx.socket
            flags = translateFlags(request.flags)

            socketCtx.setTimeoutMsec(request.timeout)

            if socketCtx.type == socket.SOCK_RAW:
                data = removeIpHeader(request.data, socketCtx)

                address = deserializeAddress(
                    request.address) if request.HasField("address") else (
                        ipFromIpPacket(request.data), 1)

                response.bytesSent = await runInThread(lambda: sock.sendto(
                    data, flags, address) + len(request.data) - len(data))

            elif request.HasField("address"):
                response.bytesSent = await runInThread(lambda: sock.sendto(
                    request.data, flags, deserializeAddress(request.address)))

            else:
                response.bytesSent = await runInThread(
                    lambda: sock.send(request.data, flags))

            response.err = 0

        except socket.timeout:
            response.err = err.netErrTimeout

        except Exception as ex:
            response.err = logAndConvertException("failed to send", ex)

        return responseMsg
Exemple #7
0
    async def _handleSocketAddr(
            self, request: networking.MsgSocketAddrRequest
    ) -> networking.MsgResponse:
        debug(
            f'socketAddrRequest: handle={request.handle} requestAddressLocal={request.requestAddressLocal} requestAddressRemote={request.requestAddressRemote} timeout={request.timeout}'
        )

        responseMsg = networking.MsgResponse()
        response = responseMsg.socketAddrResponse

        try:
            socketCtx = self._getSocketCtx(request.handle)
            sock = socketCtx.socket

            socketCtx.setTimeoutMsec(request.timeout)

            if request.requestAddressLocal:
                try:
                    serializeAddress(
                        await runInThread(lambda: sock.getsockname()),
                        response.addressLocal)
                except OSError as ex:
                    if ex.errno in errno.errorcode and errno.errorcode[
                            ex.errno] == "WSAEINVAL":
                        response.addressLocal.port = 0
                        response.addressLocal.ip = 0
                    else:
                        raise ex

                socketCtx.updateTimeout()

            if request.requestAddressRemote:
                serializeAddress(await runInThread(lambda: sock.getpeername()),
                                 response.addressRemote)

            response.err = 0

        except socket.timeout:
            response.err = err.netErrTimeout

        except Exception as ex:
            response.err = logAndConvertException(
                "failed to get socket addresses", ex)

        return responseMsg
Exemple #8
0
    async def _handleSocketOpen(
            self, request: networking.MsgSocketOpenRequest
    ) -> networking.MsgResponse:
        debug(
            f'socketOpenRequest: type={request.type} protocol={request.protocol}'
        )

        responseMsg = networking.MsgResponse()
        response = responseMsg.socketOpenResponse

        response.handle = -1

        if not request.type in SOCKET_TYPE:
            response.err = err.netErrParamErr
            return responseMsg

        try:
            sockType = SOCKET_TYPE[request.type]
            sockProtocol = 0

            if sockType == socket.SOCK_RAW:
                if request.protocol == 255 or request.protocol == 1:
                    sockProtocol = socket.IPPROTO_ICMP
                else:
                    warning(
                        f'unsupported protocol for RAW socket: {request.protocol}'
                    )
                    response.err = err.netErrParamErr

                    return responseMsg

            handle = self._getFreeHandle()

            sock = await runInThread(
                lambda: socket.socket(socket.AF_INET, sockType, sockProtocol))

            self._sockets[handle] = SocketContext(sock, sockType)

            response.handle = handle
            response.err = 0

        except Exception as ex:
            response.err = logAndConvertException("failed to open socket", ex)

        return responseMsg
Exemple #9
0
    async def _handleSocketOptionSet(
        self, request: networking.MsgSocketOptionSetRequest
    ) -> networking.MsgResponse:
        value = sockopt.sockoptValue(request)

        debug(
            f'socketOptionSet handle={request.handle} level={request.level} option={request.option} value={value} timeout={request.timeout}'
        )  # type: ignore

        responseMsg = networking.MsgResponse()
        response = responseMsg.socketOptionSetResponse
        response.err = 0

        try:
            socketCtx = self._getSocketCtx(request.handle)
            socket = socketCtx.socket

            if request.level == netSocketOptLevelSocket and request.option == netSocketOptSockNonBlocking:
                await runInThread(lambda: socketCtx.setNonblocking(bool(value))
                                  )
            else:
                level = sockopt.translateSockoptLevel(request.level)
                option = sockopt.translateSockoptOption(
                    request.level, request.option)

                if level is None or option is None:
                    response.err = err.netErrParamErr
                else:
                    socketCtx.setTimeoutMsec(request.timeout)

                    # https://github.com/python/mypy/issues/4297
                    _level = level
                    _option = option

                    await runInThread(
                        lambda: socket.setsockopt(_level, _option, value))

        except Exception as ex:
            response.err = logAndConvertException(
                f'socketOptionSet failed handle={request.handle}', ex)

        return responseMsg
Exemple #10
0
    async def _handleSocketListen(
            self, request: networking.MsgSocketListenRequest
    ) -> networking.MsgResponse:
        debug(
            f'socketOptionListen handle={request.handle} backlock={request.backlog} timeout={request.timeout}'
        )

        responseMsg = networking.MsgResponse()
        response = responseMsg.socketListenResponse

        try:
            socketCtx = self._getSocketCtx(request.handle)

            socketCtx.setTimeoutMsec(request.timeout)
            await runInThread(lambda: socketCtx.socket.listen(request.backlog))

            response.err = 0

        except Exception as ex:
            response.err = logAndConvertException(
                f'socketListen failed handle={request.handle}', ex)

        return responseMsg
Exemple #11
0
    async def _handleGetServByName(
            self, request: networking.MsgGetServByNameRequest
    ) -> networking.MsgResponse:
        debug(
            f'getServByNameRequest name={request.name} protocol={request.protocol}'
        )

        responseMsg = networking.MsgResponse()
        response = responseMsg.getServByNameResponse
        response.port = 0

        try:
            response.port = await runInThread(
                lambda: socket.getservbyname(request.name, request.protocol))

            response.err = 0

        except Exception as ex:
            info(f'failed to resolve service: {formatException(ex)}')

            response.err = err.netErrUnknownService

        return responseMsg
Exemple #12
0
    async def _handleSettingGet(
            self, request: networking.MsgSettingGetRequest
    ) -> networking.MsgResponse:
        debug(f'settingGet setting={request.setting}')

        responseMsg = networking.MsgResponse()
        response = responseMsg.settingGetResponse
        response.err = 0

        try:
            if request.setting == netSettingHostName:
                response.strval = socket.gethostname()

            elif request.setting in [
                    netSettingPrimaryDNS, netSettingSecondaryDNS,
                    netSettingRTPrimaryDNS, netSettingRTSecondaryDNS
            ]:
                resolver = dns.resolver.Resolver()

                if self._nameserver is None:
                    for nameserver in resolver.nameservers:
                        ip = serializeIp(nameserver)

                        if ip != None:
                            break
                else:
                    ip = self._nameserver

                response.uint32val = ip if ip is not None else 0x08080808

            else:
                response.err = err.netErrParamErr

        except Exception as ex:
            response.err = logAndConvertException('settingGet failed', ex)

        return responseMsg
Exemple #13
0
    async def _handleSocketConnect(
            self, request: networking.MsgSocketConnectRequest
    ) -> networking.MsgResponse:
        debug(
            f'socketConnectRequest handle={request.handle} address={deserializeAddress(request.address)} timeout={request.timeout}'
        )

        responseMsg = networking.MsgResponse()
        response = responseMsg.socketConnectResponse

        try:
            socketContext = self._getSocketCtx(request.handle)

            socketContext.setTimeoutMsec(request.timeout)

            if self._forceBindAddress is not None and not socketContext.bound:
                forceBindAddress = self._forceBindAddress

                await runInThread(
                    lambda: socketContext.socket.bind(forceBindAddress))

                socketContext.bound = True
                socketContext.updateTimeout()

            await runInThread(lambda: socketContext.socket.connect(
                deserializeAddress(request.address)))

            response.err = 0

        except socket.timeout:
            response.err = err.netErrTimeout

        except Exception as ex:
            response.err = logAndConvertException('failed to connect socket',
                                                  ex)

        return responseMsg
Exemple #14
0
    async def _handleSelect(
            self,
            request: networking.MsgSelectRequest) -> networking.MsgResponse:
        debug(
            f'select width={request.width} readFDs={self._fdSetToHandles(request.readFDs, request.width)} writeFDs={self._fdSetToHandles(request.writeFDs, request.width)} exceptFDs={self._fdSetToHandles(request.exceptFDs, request.width)} timeout={request.timeout}'
        )

        responseMsg = networking.MsgResponse()
        response = responseMsg.selectResponse

        try:
            response.readFDs = 0
            response.writeFDs = 0
            response.exceptFDs = 0
            response.err = err.netErrInternal

            timeout = min(
                MAX_TIMEOUT, request.timeout /
                1000 if request.timeout >= 0 else MAX_TIMEOUT)

            rlist, wlist, xlist = await runInThread(lambda: select.select(
                self._fdSetToSockets(request.readFDs, request.width),
                self._fdSetToSockets(request.writeFDs, request.width),
                self._fdSetToSockets(request.exceptFDs, request.width), timeout
            ))

            response.readFDs = self._socketsToFdSet(rlist)
            response.writeFDs = self._socketsToFdSet(wlist)
            response.exceptFDs = self._socketsToFdSet(xlist)

            response.err = 0

        except Exception as ex:
            response.err = logAndConvertException('select failed', ex)

        return responseMsg
Exemple #15
0
    async def _handleSocketOptionGet(
        self, request: networking.MsgSocketOptionGetRequest
    ) -> networking.MsgResponse:
        debug(
            f'socketOptionGet handle={request.handle} level={request.level} option={request.option} timeout={request.timeout}'
        )

        responseMsg = networking.MsgResponse()
        response = responseMsg.socketOptionGetResponse
        response.err = 0

        try:
            socketCtx = self._getSocketCtx(request.handle)
            socket = socketCtx.socket

            level = sockopt.translateSockoptLevel(request.level)
            option = sockopt.translateSockoptOption(request.level,
                                                    request.option)

            if request.level == netSocketOptLevelSocket and request.option == netSocketOptSockNonBlocking:
                response.intval = socketCtx.getNonblocking()

            elif level == None or option == None:
                response.err = err.netErrParamErr

            elif request.level == netSocketOptLevelSocket and request.option == netSocketOptSockLinger:
                socketCtx.setTimeoutMsec(request.timeout)

                # https://github.com/python/mypy/issues/4297
                assert level is not None and option is not None
                _level = level
                _option = option

                (onoff, linger) = unpack(
                    'ii', await
                    runInThread(lambda: socket.getsockopt(_level, _option, 8)))

                response.intval = (onoff & 0xffff) | ((linger & 0xffff) << 16)

            elif request.level == netSocketOptLevelIP:
                socketCtx.setTimeoutMsec(request.timeout)

                # https://github.com/python/mypy/issues/4297
                assert level is not None and option is not None
                _level = level
                _option = option

                response.bufval = await runInThread(
                    lambda: socket.getsockopt(_level, _option, 40))

            else:
                socketCtx.setTimeoutMsec(request.timeout)

                # https://github.com/python/mypy/issues/4297
                assert level is not None and option is not None
                _level = level
                _option = option

                response.intval = await runInThread(
                    lambda: socket.getsockopt(_level, _option))

        except Exception as ex:
            response.err = logAndConvertException(
                f'socketOptionGet failed handle={request.handle}', ex)

        return responseMsg
Exemple #16
0
    async def _handleMessage(self, message: bytes, ws: WebSocketResponse):
        request = networking.MsgRequest()
        request.ParseFromString(message)

        requestType = request.WhichOneof("payload")

        if requestType == "socketOpenRequest":
            response = await self._handleSocketOpen(request.socketOpenRequest)

        elif requestType == "socketBindRequest":
            response = await self._handleSocketBind(request.socketBindRequest)

        elif requestType == "socketAddrRequest":
            response = await self._handleSocketAddr(request.socketAddrRequest)

        elif requestType == "socketSendRequest":
            response = await self._handleSocketSend(request.socketSendRequest)

        elif requestType == "socketReceiveRequest":
            response = await self._handeSocketReceive(
                request.socketReceiveRequest)

        elif requestType == "socketCloseRequest":
            response = await self._handleSocketClose(request.socketCloseRequest
                                                     )

        elif requestType == "getHostByNameRequest":
            response = await self._handleGetHostByName(
                request.getHostByNameRequest)

        elif requestType == "getServByNameRequest":
            response = await self._handleGetServByName(
                request.getServByNameRequest)

        elif requestType == "socketConnectRequest":
            response = await self._handleSocketConnect(
                request.socketConnectRequest)

        elif requestType == "selectRequest":
            response = await self._handleSelect(request.selectRequest)

        elif requestType == "settingGetRequest":
            response = await self._handleSettingGet(request.settingGetRequest)

        elif requestType == "socketOptionSetRequest":
            response = await self._handleSocketOptionSet(
                request.socketOptionSetRequest)

        elif requestType == "socketOptionGetRequest":
            response = await self._handleSocketOptionGet(
                request.socketOptionGetRequest)

        elif requestType == "socketListenRequest":
            response = await self._handleSocketListen(
                request.socketListenRequest)

        elif requestType == "socketAcceptRequest":
            response = await self._handleSocketAccept(
                request.socketAcceptRequest)

        else:
            response = networking.MsgResponse()
            response.invalidRequestResponse.tag = True

            error(f'unknown request {requestType}')

        response.id = request.id

        await ws.send_bytes(response.SerializeToString())