From 0f219edcc9fbe330503c147c781f7ee8408c08ff Mon Sep 17 00:00:00 2001 From: Katharine Chui Date: Tue, 17 Mar 2026 17:36:17 +0100 Subject: [PATCH] fix street rider sending pdp packets using wrong pdp dst addresses in relay mode In P2P mode, this issue was solved by resolving the final IP address without the first byte. Fix the issue again for relay mode by resolving the true mac address before sending. True mac resolving was also added to relay mode ptp connect as a precaution. --- Core/HLE/proAdhoc.cpp | 18 ++++++++++++++++++ Core/HLE/proAdhoc.h | 6 ++++++ Core/HLE/sceNetAdhoc.cpp | 19 ++++++++++++------- 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index e68d4f227a..17101c5996 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -2333,6 +2333,24 @@ bool resolveIP(uint32_t ip, SceNetEtherAddr * mac) { return false; } +void fixGameMac(SceNetEtherAddr *mac) { + SceNetEtherAddr localMac; + getLocalMac(&localMac); + if (isMacMatch(&localMac, mac)) { + *mac = localMac; + return; + } + + std::lock_guard peer_guard(peerlock); + SceNetAdhocctlPeerInfo * peer = friends; + for (; peer != NULL; peer = peer->next) { + if (isMacMatch(&peer->mac_addr, mac)) { + *mac = peer->mac_addr; + return; + } + } +} + bool resolveMAC(SceNetEtherAddr* mac, uint32_t* ip, u16* port_offset) { // Get Local MAC Address SceNetEtherAddr localMac; diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index 0bee8b83d1..657feff4d9 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -1322,6 +1322,12 @@ bool resolveIP(uint32_t ip, SceNetEtherAddr * mac); */ bool resolveMAC(SceNetEtherAddr* mac, uint32_t* ip, u16* port_offset = nullptr); +/** + * Fix mac address if the game messed with the first byte + * @param mac Peer MAC Address + */ +void fixGameMac(SceNetEtherAddr *mac); + /** * Check whether Network Name contains only valid symbols * @param group_name To-be-checked Network Name diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 5b7b11f03b..5a462d5dcf 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -724,8 +724,8 @@ static int pdp_recv_postoffice(int idx, SceNetEtherAddr *saddr, uint16_t *sport, return SOCKET_ERROR; } - int sport_copy; - SceNetEtherAddr saddr_copy; + int sport_copy = 0; + SceNetEtherAddr saddr_copy = {0}; int len_copy = *len; if (len_copy > AEMU_POSTOFFICE_PDP_BLOCK_MAX) { @@ -919,7 +919,10 @@ static int pdp_send_postoffice(int idx, const SceNetEtherAddr *daddr, uint16_t d return SOCKET_ERROR; } - int pdp_send_status = pdp_send(pdp_sock, (const char *)daddr, offset_port_simple(dport), (char *)data, len, true); + SceNetEtherAddr fixed_daddr = *daddr; + fixGameMac(&fixed_daddr); + + int pdp_send_status = pdp_send(pdp_sock, (const char *)&fixed_daddr, offset_port_simple(dport), (char *)data, len, true); if (pdp_send_status == AEMU_POSTOFFICE_CLIENT_SESSION_DEAD) { handle_relay_connect_failure(); pdp_delete(internal->postofficeHandle); @@ -1252,9 +1255,9 @@ static int ptp_accept_postoffice(int idx, SceNetEtherAddr *saddr, uint16_t *spor return SCE_NET_ADHOC_ERROR_WOULD_BLOCK; } - int state; - int port_cpy; - SceNetEtherAddr mac_cpy; + int state = 0; + int port_cpy = 0; + SceNetEtherAddr mac_cpy = {0}; void *new_ptp_socket = ptp_accept(ptp_listen_socket, (char *)&mac_cpy, &port_cpy, true, &state); if (new_ptp_socket == NULL) { if (state == AEMU_POSTOFFICE_CLIENT_SESSION_DEAD) { @@ -1410,7 +1413,9 @@ static int ptp_connect_postoffice(int idx, const char *caller) { internal->connectThread = new std::thread([internal, addr, idx] { int state; - void *ptp_socket = ptp_connect_v4(&addr, (const char *)&internal->data.ptp.laddr, offset_port_simple(internal->data.ptp.lport), (const char *)&internal->data.ptp.paddr, offset_port_simple(internal->data.ptp.pport), &state); + SceNetEtherAddr fixed_daddr = internal->data.ptp.paddr; + fixGameMac(&fixed_daddr); + void *ptp_socket = ptp_connect_v4(&addr, (const char *)&internal->data.ptp.laddr, offset_port_simple(internal->data.ptp.lport), (const char *)&fixed_daddr, offset_port_simple(internal->data.ptp.pport), &state); if (ptp_socket == NULL) { internal->connectThreadResult = SCE_NET_ADHOC_ERROR_CONNECTION_REFUSED; ERROR_LOG(Log::sceNet, "%s: failed connecting to ptp socket, %d", __func__, state);