mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	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
					
				
					 2 changed files with 677 additions and 315 deletions
				
			
		
										
											
												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; | ||||||
| }; | }; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue