mirror of
https://github.com/Vita3K/Vita3K.git
synced 2026-07-11 01:34:23 +02:00
modules/SceNet: Implement Getpeername and fix accept return P2P sock.
- Implement get peer address for both socket. - refactor, improve and rename variable of get socket address. - convert PosixSocket to P2PSocket when is created by one P2PSocket. - Handle SCE_NET_MSG_WAITALL correctly: only enable for stream sockets.
This commit is contained in:
@@ -322,16 +322,17 @@ EXPORT(int, sceNetGetStatisticsInfo) {
|
||||
return UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
EXPORT(int, sceNetGetpeername) {
|
||||
TRACY_FUNC(sceNetGetpeername);
|
||||
return UNIMPLEMENTED();
|
||||
EXPORT(int, sceNetGetpeername, int sid, SceNetSockaddr *addr, unsigned int *addrlen) {
|
||||
TRACY_FUNC(sceNetGetpeername, sid, addr, addrlen);
|
||||
auto sock = lock_and_find(sid, emuenv.net.socks, emuenv.kernel.mutex);
|
||||
RET_NET_ERRNO(sock ? sock->get_peer_address(addr, addrlen) : SCE_NET_ERROR_EBADF);
|
||||
}
|
||||
|
||||
EXPORT(int, sceNetGetsockname, int sid, SceNetSockaddr *name, unsigned int *namelen) {
|
||||
TRACY_FUNC(sceNetGetsockname, sid, name, namelen);
|
||||
EXPORT(int, sceNetGetsockname, int sid, SceNetSockaddr *addr, unsigned int *addrlen) {
|
||||
TRACY_FUNC(sceNetGetsockname, sid, addr, addrlen);
|
||||
auto sock = lock_and_find(sid, emuenv.net.socks, emuenv.kernel.mutex);
|
||||
|
||||
RET_NET_ERRNO(sock ? sock->get_socket_address(name, namelen) : SCE_NET_ERROR_EBADF);
|
||||
RET_NET_ERRNO(sock ? sock->get_socket_address(addr, addrlen) : SCE_NET_ERROR_EBADF);
|
||||
}
|
||||
|
||||
EXPORT(int, sceNetGetsockopt, int sid, int level, int optname, void *optval, unsigned int *optlen) {
|
||||
|
||||
@@ -46,8 +46,10 @@ typedef std::shared_ptr<Socket> SocketPtr;
|
||||
|
||||
struct Socket {
|
||||
int sockopt_so_onesbcast = 0;
|
||||
int sce_type;
|
||||
|
||||
explicit Socket(int domain, int type, int protocol) {}
|
||||
explicit Socket(int domain, int type, int protocol)
|
||||
: sce_type(type) {}
|
||||
|
||||
virtual ~Socket() = default;
|
||||
|
||||
@@ -59,10 +61,11 @@ struct Socket {
|
||||
virtual int recv_packet(void *buf, unsigned int len, int flags, SceNetSockaddr *from, unsigned int *fromlen) = 0;
|
||||
virtual int set_socket_options(int level, int optname, const void *optval, unsigned int optlen) = 0;
|
||||
virtual int get_socket_options(int level, int optname, void *optval, unsigned int *optlen) = 0;
|
||||
virtual int connect(const SceNetSockaddr *addr, unsigned int namelen) = 0;
|
||||
virtual int connect(const SceNetSockaddr *addr, unsigned int addrlen) = 0;
|
||||
virtual SocketPtr accept(SceNetSockaddr *addr, unsigned int *addrlen, int &err) = 0;
|
||||
virtual int listen(int backlog) = 0;
|
||||
virtual int get_socket_address(SceNetSockaddr *name, unsigned int *namelen) = 0;
|
||||
virtual int get_peer_address(SceNetSockaddr *addr, unsigned int *addrlen) = 0;
|
||||
virtual int get_socket_address(SceNetSockaddr *addr, unsigned int *addrlen) = 0;
|
||||
};
|
||||
|
||||
// udp, tcp
|
||||
@@ -85,8 +88,8 @@ struct PosixSocket : public Socket {
|
||||
: Socket(domain, type, protocol)
|
||||
, sock(socket(domain, type, protocol)) {}
|
||||
|
||||
explicit PosixSocket(abs_socket sock)
|
||||
: Socket(0, 0, 0)
|
||||
explicit PosixSocket(abs_socket sock, int type)
|
||||
: Socket(0, type, 0)
|
||||
, sock(sock) {}
|
||||
|
||||
static int translate_return_value(int retval);
|
||||
@@ -99,19 +102,23 @@ struct PosixSocket : public Socket {
|
||||
int recv_packet(void *buf, unsigned int len, int flags, SceNetSockaddr *from, unsigned int *fromlen) override;
|
||||
int set_socket_options(int level, int optname, const void *optval, unsigned int optlen) override;
|
||||
int get_socket_options(int level, int optname, void *optval, unsigned int *optlen) override;
|
||||
int connect(const SceNetSockaddr *addr, unsigned int namelen) override;
|
||||
int connect(const SceNetSockaddr *addr, unsigned int addrlen) override;
|
||||
SocketPtr accept(SceNetSockaddr *addr, unsigned int *addrlen, int &err) override;
|
||||
int listen(int backlog) override;
|
||||
int get_socket_address(SceNetSockaddr *name, unsigned int *namelen) override;
|
||||
int get_peer_address(SceNetSockaddr *addr, unsigned int *addrlen) override;
|
||||
int get_socket_address(SceNetSockaddr *addr, unsigned int *addrlen) override;
|
||||
};
|
||||
|
||||
struct P2PSocket : public PosixSocket {
|
||||
explicit P2PSocket(int domain, int type, int protocol);
|
||||
explicit P2PSocket(abs_socket sock, int type)
|
||||
: PosixSocket(sock, type) {}
|
||||
|
||||
int bind(const SceNetSockaddr *addr, unsigned int addrlen) override;
|
||||
int send_packet(const void *msg, unsigned int len, int flags, const SceNetSockaddr *to, unsigned int tolen) override;
|
||||
int recv_packet(void *buf, unsigned int len, int flags, SceNetSockaddr *from, unsigned int *fromlen) override;
|
||||
int connect(const SceNetSockaddr *addr, unsigned int namelen) override;
|
||||
int connect(const SceNetSockaddr *addr, unsigned int addrlen) override;
|
||||
SocketPtr accept(SceNetSockaddr *addr, unsigned int *addrlen, int &err) override;
|
||||
int get_socket_address(SceNetSockaddr *name, unsigned int *namelen) override;
|
||||
int get_peer_address(SceNetSockaddr *addr, unsigned int *addrlen) override;
|
||||
int get_socket_address(SceNetSockaddr *addr, unsigned int *addrlen) override;
|
||||
};
|
||||
|
||||
@@ -67,17 +67,20 @@ static int p2pSocketTypeToPosixSocketType(int type) {
|
||||
}
|
||||
|
||||
P2PSocket::P2PSocket(int domain, int type, int protocol)
|
||||
: PosixSocket(domain, p2pSocketTypeToPosixSocketType(type), protocol){};
|
||||
: PosixSocket(domain, p2pSocketTypeToPosixSocketType(type), protocol) { sce_type = type; }
|
||||
|
||||
SocketPtr P2PSocket::accept(SceNetSockaddr *addr, unsigned int *addrlen, int &err) {
|
||||
const auto res = PosixSocket::accept(addr, addrlen, err);
|
||||
const auto res = std::dynamic_pointer_cast<PosixSocket>(PosixSocket::accept(addr, addrlen, err));
|
||||
if (!res)
|
||||
return nullptr;
|
||||
|
||||
*addr = convertPosixToP2P(addr);
|
||||
return res;
|
||||
return std::make_shared<P2PSocket>(res->sock, res->sce_type);
|
||||
}
|
||||
|
||||
int P2PSocket::connect(const SceNetSockaddr *addr, unsigned int namelen) {
|
||||
int P2PSocket::connect(const SceNetSockaddr *addr, unsigned int addrlen) {
|
||||
const auto p2p_addr = convertP2PToPosix(addr);
|
||||
return PosixSocket::connect(&p2p_addr, namelen);
|
||||
return PosixSocket::connect(&p2p_addr, addrlen);
|
||||
}
|
||||
|
||||
int P2PSocket::recv_packet(void *buf, unsigned int len, int flags, SceNetSockaddr *from, unsigned int *fromlen) {
|
||||
@@ -98,8 +101,18 @@ int P2PSocket::bind(const SceNetSockaddr *addr, unsigned int addrlen) {
|
||||
return PosixSocket::bind(&p2p_addr, addrlen);
|
||||
}
|
||||
|
||||
int P2PSocket::get_socket_address(SceNetSockaddr *name, unsigned int *namelen) {
|
||||
const auto res = PosixSocket::get_socket_address(name, namelen);
|
||||
*name = convertPosixToP2P(name);
|
||||
int P2PSocket::get_peer_address(SceNetSockaddr *addr, unsigned int *addrlen) {
|
||||
const auto res = PosixSocket::get_peer_address(addr, addrlen);
|
||||
if (res == 0)
|
||||
*addr = convertPosixToP2P(addr);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int P2PSocket::get_socket_address(SceNetSockaddr *addr, unsigned int *addrlen) {
|
||||
const auto res = PosixSocket::get_socket_address(addr, addrlen);
|
||||
if (res == 0)
|
||||
*addr = convertPosixToP2P(addr);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ static bool should_abort(int abort_flags, int flags) {
|
||||
return (abort_flags & flags) != 0;
|
||||
}
|
||||
|
||||
int PosixSocket::connect(const SceNetSockaddr *addr, unsigned int namelen) {
|
||||
int PosixSocket::connect(const SceNetSockaddr *addr, unsigned int addrlen) {
|
||||
if (should_abort(abort_flags, SCE_NET_SOCKET_ABORT_FLAG_SND_PRESERVATION))
|
||||
return SCE_NET_ERROR_EINTR;
|
||||
|
||||
@@ -180,18 +180,31 @@ int PosixSocket::listen(int backlog) {
|
||||
return translate_return_value(::listen(sock, backlog));
|
||||
}
|
||||
|
||||
int PosixSocket::get_socket_address(SceNetSockaddr *name, unsigned int *namelen) {
|
||||
sockaddr addr;
|
||||
convertSceSockaddrToPosix(name, &addr);
|
||||
if (name != nullptr) {
|
||||
*namelen = sizeof(sockaddr_in);
|
||||
}
|
||||
int res = getsockname(sock, &addr, (socklen_t *)namelen);
|
||||
int PosixSocket::get_peer_address(SceNetSockaddr *addr, unsigned int *addrlen) {
|
||||
if (!addr || !addrlen)
|
||||
return SCE_NET_EINVAL;
|
||||
|
||||
sockaddr addr2{};
|
||||
const auto res = ::getpeername(sock, &addr2, (socklen_t *)addrlen);
|
||||
if (res >= 0) {
|
||||
convertPosixSockaddrToSce(&addr, name);
|
||||
*namelen = sizeof(SceNetSockaddrIn);
|
||||
convertPosixSockaddrToSce(&addr2, addr);
|
||||
*addrlen = sizeof(SceNetSockaddrIn);
|
||||
}
|
||||
return res;
|
||||
|
||||
return translate_return_value(res);
|
||||
}
|
||||
|
||||
int PosixSocket::get_socket_address(SceNetSockaddr *addr, unsigned int *addrlen) {
|
||||
if (!addr || !addrlen)
|
||||
return SCE_NET_EINVAL;
|
||||
|
||||
sockaddr addr2{};
|
||||
const auto res = ::getsockname(sock, &addr2, (socklen_t *)addrlen);
|
||||
if (res >= 0) {
|
||||
convertPosixSockaddrToSce(&addr2, addr);
|
||||
*addrlen = sizeof(SceNetSockaddrIn);
|
||||
}
|
||||
return translate_return_value(res);
|
||||
}
|
||||
|
||||
int PosixSocket::abort(int flags) {
|
||||
@@ -233,7 +246,7 @@ SocketPtr PosixSocket::accept(SceNetSockaddr *addr, unsigned int *addrlen, int &
|
||||
return nullptr;
|
||||
}
|
||||
sockaddr addr2{};
|
||||
abs_socket new_socket = ::accept(sock, &addr2, (socklen_t *)addrlen);
|
||||
const abs_socket new_socket = ::accept(sock, &addr2, (socklen_t *)addrlen);
|
||||
if (abort_pending(is_aborted)) {
|
||||
err = SCE_NET_ERROR_EINTR;
|
||||
return nullptr;
|
||||
@@ -245,7 +258,7 @@ SocketPtr PosixSocket::accept(SceNetSockaddr *addr, unsigned int *addrlen, int &
|
||||
#endif
|
||||
convertPosixSockaddrToSce(&addr2, addr);
|
||||
*addrlen = sizeof(SceNetSockaddrIn);
|
||||
return std::make_shared<PosixSocket>(new_socket);
|
||||
return std::make_shared<PosixSocket>(new_socket, sce_type);
|
||||
}
|
||||
err = translate_return_value(new_socket);
|
||||
return nullptr;
|
||||
@@ -423,7 +436,7 @@ int PosixSocket::get_socket_options(int level, int optname, void *optval, unsign
|
||||
return SCE_NET_ERROR_EINVAL;
|
||||
}
|
||||
|
||||
static int convertSceFlagsToPosix(int sce_flags) {
|
||||
static int convertSceFlagsToPosix(int sock_type, int sce_flags) {
|
||||
int posix_flags = 0;
|
||||
|
||||
if (sce_flags & SCE_NET_MSG_PEEK)
|
||||
@@ -432,7 +445,8 @@ static int convertSceFlagsToPosix(int sce_flags) {
|
||||
if (sce_flags & SCE_NET_MSG_DONTWAIT)
|
||||
posix_flags |= MSG_DONTWAIT;
|
||||
#endif
|
||||
if (sce_flags & SCE_NET_MSG_WAITALL)
|
||||
// MSG_WAITALL is only valid for stream sockets
|
||||
if ((sce_flags & SCE_NET_MSG_WAITALL) && ((sock_type == SCE_NET_SOCK_STREAM) || (sock_type == SCE_NET_SOCK_STREAM_P2P)))
|
||||
posix_flags |= MSG_WAITALL;
|
||||
|
||||
return posix_flags;
|
||||
@@ -466,7 +480,7 @@ int PosixSocket::recv_packet(void *buf, unsigned int len, int flags, SceNetSocka
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
const auto posix_flags = convertSceFlagsToPosix(flags);
|
||||
const auto posix_flags = convertSceFlagsToPosix(sce_type, flags);
|
||||
if (from == nullptr) {
|
||||
res = recv(sock, (char *)buf, len, posix_flags);
|
||||
} else {
|
||||
@@ -495,7 +509,7 @@ int PosixSocket::send_packet(const void *msg, unsigned int len, int flags, const
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
const auto posix_flags = convertSceFlagsToPosix(flags);
|
||||
const auto posix_flags = convertSceFlagsToPosix(sce_type, flags);
|
||||
if (to == nullptr) {
|
||||
res = send(sock, (const char *)msg, len, posix_flags);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user