Implement some missing SOC functionality (#7176)
* Implement some missing SOC functionality * Add LOG_POLL macro for debugging * Fix compilation * Temporary fix for Android * Temporary fix for Android (for real) * Apply suggestions * Add stubbed notice to android sockatmark * Apply suggestions
This commit is contained in:
parent
2b20082581
commit
d680b79725
File diff suppressed because it is too large
Load Diff
|
@ -14,6 +14,10 @@ namespace Core {
|
||||||
class System;
|
class System;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace IPC {
|
||||||
|
class RequestParser;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Service::SOC {
|
namespace Service::SOC {
|
||||||
|
|
||||||
/// Holds information about a particular socket
|
/// Holds information about a particular socket
|
||||||
|
@ -26,12 +30,18 @@ struct SocketHolder {
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
bool blocking = true; ///< Whether the socket is blocking or not.
|
bool blocking = true; ///< Whether the socket is blocking or not.
|
||||||
|
bool isGlobal = false;
|
||||||
|
bool shutdown_rd = false;
|
||||||
|
|
||||||
|
u32 ownerProcess = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <class Archive>
|
template <class Archive>
|
||||||
void serialize(Archive& ar, const unsigned int) {
|
void serialize(Archive& ar, const unsigned int) {
|
||||||
ar& socket_fd;
|
ar& socket_fd;
|
||||||
ar& blocking;
|
ar& blocking;
|
||||||
|
ar& isGlobal;
|
||||||
|
ar& ownerProcess;
|
||||||
}
|
}
|
||||||
friend class boost::serialization::access;
|
friend class boost::serialization::access;
|
||||||
};
|
};
|
||||||
|
@ -51,9 +61,15 @@ public:
|
||||||
std::optional<InterfaceInfo> GetDefaultInterfaceInfo();
|
std::optional<InterfaceInfo> GetDefaultInterfaceInfo();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr ResultCode ERR_INVALID_HANDLE =
|
static constexpr ResultCode ERR_WRONG_PROCESS =
|
||||||
ResultCode(ErrorDescription::InvalidHandle, ErrorModule::SOC, ErrorSummary::InvalidArgument,
|
ResultCode(4, ErrorModule::SOC, ErrorSummary::InvalidState, ErrorLevel::Status);
|
||||||
ErrorLevel::Permanent);
|
static constexpr ResultCode ERR_NOT_INITIALIZED =
|
||||||
|
ResultCode(6, ErrorModule::SOC, ErrorSummary::InvalidArgument, ErrorLevel::Permanent);
|
||||||
|
static constexpr ResultCode ERR_INVALID_SOCKET_DESCRIPTOR =
|
||||||
|
ResultCode(7, ErrorModule::SOC, ErrorSummary::InvalidArgument, ErrorLevel::Permanent);
|
||||||
|
static constexpr ResultCode ERR_ALREADY_INITIALIZED =
|
||||||
|
ResultCode(11, ErrorModule::SOC, ErrorSummary::InvalidState, ErrorLevel::Status);
|
||||||
|
|
||||||
static constexpr u32 SOC_ERR_INAVLID_ENUM_VALUE = 0xFFFF8025;
|
static constexpr u32 SOC_ERR_INAVLID_ENUM_VALUE = 0xFFFF8025;
|
||||||
|
|
||||||
static constexpr u32 SOC_SOL_IP = 0x0000;
|
static constexpr u32 SOC_SOL_IP = 0x0000;
|
||||||
|
@ -70,6 +86,19 @@ private:
|
||||||
bool GetSocketBlocking(const SocketHolder& socket_holder);
|
bool GetSocketBlocking(const SocketHolder& socket_holder);
|
||||||
u32 SetSocketBlocking(SocketHolder& socket_holder, bool blocking);
|
u32 SetSocketBlocking(SocketHolder& socket_holder, bool blocking);
|
||||||
|
|
||||||
|
std::optional<std::reference_wrapper<SocketHolder>> GetSocketHolder(u32 ctr_socket_fd,
|
||||||
|
u32 process_id,
|
||||||
|
IPC::RequestParser& rp);
|
||||||
|
|
||||||
|
// Close and delete all sockets, optinally only the ones owned by the
|
||||||
|
// specified process ID.
|
||||||
|
void CloseAndDeleteAllSockets(s32 process_id = -1);
|
||||||
|
|
||||||
|
s32 SendToImpl(SocketHolder& holder, u32 len, u32 flags, u32 addr_len,
|
||||||
|
const std::vector<u8>& input_buff, const u8* dest_addr_buff);
|
||||||
|
|
||||||
|
static void RecvBusyWaitForEvent(SocketHolder& holder);
|
||||||
|
|
||||||
// From
|
// From
|
||||||
// https://github.com/devkitPro/libctru/blob/1de86ea38aec419744149daf692556e187d4678a/libctru/include/3ds/services/soc.h#L15
|
// https://github.com/devkitPro/libctru/blob/1de86ea38aec419744149daf692556e187d4678a/libctru/include/3ds/services/soc.h#L15
|
||||||
enum class NetworkOpt {
|
enum class NetworkOpt {
|
||||||
|
@ -86,33 +115,22 @@ private:
|
||||||
NETOPT_DHCP_LEASE_TIME = 0xC001, ///< The DHCP lease time remaining, in seconds
|
NETOPT_DHCP_LEASE_TIME = 0xC001, ///< The DHCP lease time remaining, in seconds
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HostByNameData {
|
|
||||||
static const u32 max_entries = 24;
|
|
||||||
|
|
||||||
u16_le addr_type;
|
|
||||||
u16_le addr_len;
|
|
||||||
u16_le addr_count;
|
|
||||||
u16_le alias_count;
|
|
||||||
std::array<char, 256> h_name;
|
|
||||||
std::array<std::array<char, 256>, max_entries> aliases;
|
|
||||||
std::array<std::array<u8, 16>, max_entries> addresses;
|
|
||||||
};
|
|
||||||
static_assert(sizeof(HostByNameData) == 0x1A88, "Invalid HostByNameData size");
|
|
||||||
|
|
||||||
void Socket(Kernel::HLERequestContext& ctx);
|
void Socket(Kernel::HLERequestContext& ctx);
|
||||||
void Bind(Kernel::HLERequestContext& ctx);
|
void Bind(Kernel::HLERequestContext& ctx);
|
||||||
void Fcntl(Kernel::HLERequestContext& ctx);
|
void Fcntl(Kernel::HLERequestContext& ctx);
|
||||||
void Listen(Kernel::HLERequestContext& ctx);
|
void Listen(Kernel::HLERequestContext& ctx);
|
||||||
void Accept(Kernel::HLERequestContext& ctx);
|
void Accept(Kernel::HLERequestContext& ctx);
|
||||||
|
void SockAtMark(Kernel::HLERequestContext& ctx);
|
||||||
void GetHostId(Kernel::HLERequestContext& ctx);
|
void GetHostId(Kernel::HLERequestContext& ctx);
|
||||||
void Close(Kernel::HLERequestContext& ctx);
|
void Close(Kernel::HLERequestContext& ctx);
|
||||||
void SendToOther(Kernel::HLERequestContext& ctx);
|
void SendToOther(Kernel::HLERequestContext& ctx);
|
||||||
void SendTo(Kernel::HLERequestContext& ctx);
|
void SendToSingle(Kernel::HLERequestContext& ctx);
|
||||||
void RecvFromOther(Kernel::HLERequestContext& ctx);
|
void RecvFromOther(Kernel::HLERequestContext& ctx);
|
||||||
void RecvFrom(Kernel::HLERequestContext& ctx);
|
void RecvFrom(Kernel::HLERequestContext& ctx);
|
||||||
void Poll(Kernel::HLERequestContext& ctx);
|
void Poll(Kernel::HLERequestContext& ctx);
|
||||||
void GetSockName(Kernel::HLERequestContext& ctx);
|
void GetSockName(Kernel::HLERequestContext& ctx);
|
||||||
void Shutdown(Kernel::HLERequestContext& ctx);
|
void Shutdown(Kernel::HLERequestContext& ctx);
|
||||||
|
void GetHostByAddr(Kernel::HLERequestContext& ctx);
|
||||||
void GetHostByName(Kernel::HLERequestContext& ctx);
|
void GetHostByName(Kernel::HLERequestContext& ctx);
|
||||||
void GetPeerName(Kernel::HLERequestContext& ctx);
|
void GetPeerName(Kernel::HLERequestContext& ctx);
|
||||||
void Connect(Kernel::HLERequestContext& ctx);
|
void Connect(Kernel::HLERequestContext& ctx);
|
||||||
|
@ -121,6 +139,9 @@ private:
|
||||||
void GetSockOpt(Kernel::HLERequestContext& ctx);
|
void GetSockOpt(Kernel::HLERequestContext& ctx);
|
||||||
void SetSockOpt(Kernel::HLERequestContext& ctx);
|
void SetSockOpt(Kernel::HLERequestContext& ctx);
|
||||||
void GetNetworkOpt(Kernel::HLERequestContext& ctx);
|
void GetNetworkOpt(Kernel::HLERequestContext& ctx);
|
||||||
|
void SendToMultiple(Kernel::HLERequestContext& ctx);
|
||||||
|
void CloseSockets(Kernel::HLERequestContext& ctx);
|
||||||
|
void AddGlobalSocket(Kernel::HLERequestContext& ctx);
|
||||||
|
|
||||||
// Some platforms seem to have GetAddrInfo and GetNameInfo defined as macros,
|
// Some platforms seem to have GetAddrInfo and GetNameInfo defined as macros,
|
||||||
// so we have to use a different name here.
|
// so we have to use a different name here.
|
||||||
|
@ -133,17 +154,10 @@ private:
|
||||||
return next_socket_id++;
|
return next_socket_id++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// System timer adjust
|
|
||||||
std::chrono::time_point<std::chrono::steady_clock> adjust_value_last;
|
|
||||||
void PreTimerAdjust();
|
|
||||||
void PostTimerAdjust(Kernel::HLERequestContext& ctx, const std::string& caller_method);
|
|
||||||
|
|
||||||
/// Close all open sockets
|
|
||||||
void CleanupSockets();
|
|
||||||
|
|
||||||
/// Holds info about the currently open sockets
|
/// Holds info about the currently open sockets
|
||||||
friend struct CTRPollFD;
|
friend struct CTRPollFD;
|
||||||
std::unordered_map<u32, SocketHolder> open_sockets;
|
std::unordered_map<u32, SocketHolder> created_sockets;
|
||||||
|
std::set<u32> initialized_processes;
|
||||||
|
|
||||||
/// Cache interface info for the current session
|
/// Cache interface info for the current session
|
||||||
/// These two fields are not saved to savestates on purpose
|
/// These two fields are not saved to savestates on purpose
|
||||||
|
@ -155,7 +169,8 @@ private:
|
||||||
template <class Archive>
|
template <class Archive>
|
||||||
void serialize(Archive& ar, const unsigned int) {
|
void serialize(Archive& ar, const unsigned int) {
|
||||||
ar& boost::serialization::base_object<Kernel::SessionRequestHandler>(*this);
|
ar& boost::serialization::base_object<Kernel::SessionRequestHandler>(*this);
|
||||||
ar& open_sockets;
|
ar& created_sockets;
|
||||||
|
ar& initialized_processes;
|
||||||
}
|
}
|
||||||
friend class boost::serialization::access;
|
friend class boost::serialization::access;
|
||||||
};
|
};
|
||||||
|
|
Reference in New Issue