mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-12 17:19:28 +01:00
sceNetAdhocctl: Leave the console out of its own peer lookups; give groups their own BSSID
From the basic and lifecycle pair tests, recorded on two PSPs: - GetNameByAddr for the console's own MAC gives NO_ENTRY, and GetAddrByName doesn't find the console itself. - GetPeerInfo with a size too small for the entry gives INVALID_BUFLEN. - A PTP connection accepted over the relay reports the peer's port as the game sees it, not the relay's offset port. - The built-in server makes up a locally administered BSSID for each group, which stays when the creator leaves. It was the MAC of the oldest member. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4197f2326a
commit
ee86058ec7
4 files changed
+26
-44
No files matched your search
@@ -2258,8 +2258,7 @@ int getNicknameCount(const char * nickname)
|
||||
// Counter
|
||||
int count = 0;
|
||||
|
||||
// Local Nickname Matches
|
||||
if (strncmp((char *)¶meter.nickname.data, nickname, ADHOCCTL_NICKNAME_LEN) == 0) count++;
|
||||
// The console itself isn't in the peer list (pspautotests net/adhoc/pair/basic).
|
||||
|
||||
// Peer Reference
|
||||
SceNetAdhocctlPeerInfo * peer = friends;
|
||||
|
||||
+13
-14
@@ -26,6 +26,7 @@
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <random>
|
||||
#include <signal.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
@@ -813,6 +814,15 @@ void connect_user(SceNetAdhocctlUserNode * user, SceNetAdhocctlGroupName * group
|
||||
// Copy Group Name
|
||||
g->group = *group;
|
||||
|
||||
// A PSP group's BSSID is a locally administered address of its own, not a member's MAC. It
|
||||
// stays when the creator leaves, and a group created again gets a new one (pspautotests
|
||||
// net/adhoc/pair/lifecycle).
|
||||
static std::mt19937 bssidRng(std::random_device{}());
|
||||
for (int i = 0; i < ETHER_ADDR_LEN; i++) {
|
||||
g->bssid.data[i] = (uint8_t)bssidRng();
|
||||
}
|
||||
g->bssid.data[0] = (g->bssid.data[0] & 0xFC) | 0x02;
|
||||
|
||||
// Increase Group Counter for Game
|
||||
g->game->groupcount++;
|
||||
}
|
||||
@@ -860,13 +870,12 @@ void connect_user(SceNetAdhocctlUserNode * user, SceNetAdhocctlGroupName * group
|
||||
iResult = (int)send(user->stream, (const char*)&packet, sizeof(packet), MSG_NOSIGNAL);
|
||||
if (iResult < 0) ERROR_LOG(Log::sceNet, "AdhocServer: connect_user[send user] (Socket error %d)", socket_errno);
|
||||
|
||||
// Set BSSID
|
||||
if(peer->group_next == NULL) bssid.mac = peer->resolver.mac;
|
||||
|
||||
// Move Pointer
|
||||
peer = peer->group_next;
|
||||
}
|
||||
|
||||
bssid.mac = g->bssid;
|
||||
|
||||
// Link User to Group
|
||||
user->group_next = g->player;
|
||||
if(g->player != NULL) g->player->group_prev = user;
|
||||
@@ -1057,17 +1066,7 @@ void send_scan_results(SceNetAdhocctlUserNode * user)
|
||||
// Set Group Name
|
||||
packet.group = group->group;
|
||||
|
||||
// Iterate Players in Network Group
|
||||
SceNetAdhocctlUserNode * peer = group->player;
|
||||
for(; peer != NULL; peer = peer->group_next)
|
||||
{
|
||||
// Found Network Founder
|
||||
if(peer->group_next == NULL)
|
||||
{
|
||||
// Set Group Host MAC
|
||||
packet.mac = peer->resolver.mac;
|
||||
}
|
||||
}
|
||||
packet.mac = group->bssid;
|
||||
|
||||
// Send Group Packet
|
||||
int iResult = (int)send(user->stream, (const char*)&packet, sizeof(packet), MSG_NOSIGNAL);
|
||||
|
||||
@@ -262,6 +262,9 @@ struct SceNetAdhocctlGroupNode {
|
||||
|
||||
// Double-Linked Player List
|
||||
SceNetAdhocctlUserNode * player;
|
||||
|
||||
// Made up when the group is created, and kept while it lasts
|
||||
SceNetEtherAddr bssid;
|
||||
};
|
||||
|
||||
// User Count
|
||||
|
||||
@@ -1462,7 +1462,7 @@ static int ptp_accept_postoffice(int idx, SceNetEtherAddr *saddr, uint16_t *spor
|
||||
internal->data.ptp.laddr = adhocSockets[idx]->data.ptp.laddr;
|
||||
internal->data.ptp.lport = adhocSockets[idx]->data.ptp.lport;
|
||||
internal->data.ptp.paddr = mac_cpy;
|
||||
internal->data.ptp.pport = port_cpy;
|
||||
internal->data.ptp.pport = reverse_port_simple(port_cpy);
|
||||
internal->data.ptp.state = ADHOC_PTP_STATE_ESTABLISHED;
|
||||
internal->data.ptp.rcv_sb_cc = adhocSockets[idx]->data.ptp.rcv_sb_cc;
|
||||
internal->data.ptp.snd_sb_cc = adhocSockets[idx]->data.ptp.snd_sb_cc;
|
||||
@@ -4055,16 +4055,11 @@ static int sceNetAdhocctlGetNameByAddr(MIPSState *mips, const char *mac, u32 nam
|
||||
SceNetEtherAddr localmac;
|
||||
getLocalMac(&localmac);
|
||||
|
||||
// Local MAC Matches
|
||||
// The console itself isn't in the peer list: NO_ENTRY, and the name isn't written (pspautotests
|
||||
// net/adhoc/pair/basic).
|
||||
if (isMacMatch(&localmac, (const SceNetEtherAddr*)mac))
|
||||
{
|
||||
// Write Data
|
||||
*nickname = parameter.nickname;
|
||||
|
||||
DEBUG_LOG(Log::sceNet, "sceNetAdhocctlGetNameByAddr - [PlayerName:%s]", (char*)nickname);
|
||||
|
||||
// Return Success
|
||||
return 0;
|
||||
return hleLogDebug(Log::sceNet, SCE_NET_ADHOC_ERROR_NO_ENTRY, "local MAC");
|
||||
}
|
||||
|
||||
// Multithreading Lock
|
||||
@@ -4120,7 +4115,9 @@ int sceNetAdhocctlGetPeerInfo(MIPSState *mips, const char *mac, int size, u32 pe
|
||||
}
|
||||
// Library initialized
|
||||
if (netAdhocctlInited) {
|
||||
if ((size < (int)sizeof(SceNetAdhocctlPeerInfoEmu)) || (buf == NULL)) return SCE_NET_ADHOCCTL_ERROR_INVALID_ARG;
|
||||
if (buf == NULL) return SCE_NET_ADHOCCTL_ERROR_INVALID_ARG;
|
||||
// A size too small for the entry gives the ad hoc library's INVALID_BUFLEN (pspautotests net/adhoc/pair/basic).
|
||||
if (size < (int)sizeof(SceNetAdhocctlPeerInfoEmu)) return hleLogError(Log::sceNet, SCE_NET_ADHOC_ERROR_INVALID_BUFLEN, "buffer too small");
|
||||
|
||||
int retval = SCE_NET_ADHOC_ERROR_NO_ENTRY; // -1;
|
||||
|
||||
@@ -6735,24 +6732,8 @@ static int sceNetAdhocctlGetAddrByName(MIPSState *mips, const char *nickName, u3
|
||||
// Minimum Space available
|
||||
if (requestcount > 0)
|
||||
{
|
||||
// Local Nickname Matches
|
||||
if (strncmp((char *)¶meter.nickname.data, nickName, ADHOCCTL_NICKNAME_LEN) == 0)
|
||||
{
|
||||
// Get Local IP Address
|
||||
sockaddr_in addr;
|
||||
SceNetEtherAddr mac;
|
||||
|
||||
getLocalIp(&addr);
|
||||
buf[discovered].nickname = parameter.nickname;
|
||||
buf[discovered].nickname.data[ADHOCCTL_NICKNAME_LEN - 1] = 0; // last char need to be null-terminated char
|
||||
getLocalMac(&mac);
|
||||
buf[discovered].mac_addr = mac;
|
||||
buf[discovered].flags = 0x0400;
|
||||
u64 lastrecv = std::max(0LL, static_cast<s64>(CoreTiming::GetGlobalTimeUsScaled() - defaultLastRecvDelta));
|
||||
buf[discovered++].last_recv = lastrecv;
|
||||
|
||||
DEBUG_LOG(Log::sceNet, "Peer [%s][%s][%s][%llu]", mac2str(&mac).c_str(), ip2str(addr.sin_addr).c_str(), nickName, lastrecv);
|
||||
}
|
||||
// The console itself isn't in the peer list, so it's never found here (pspautotests
|
||||
// net/adhoc/pair/basic).
|
||||
|
||||
// Peer Reference
|
||||
SceNetAdhocctlPeerInfo * peer = friends;
|
||||
|
||||
Reference in new issue
Block a user