mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-13 17:49:29 +01:00
Merge pull request #14870 from ANR2ME/adhoc_matching
[AdhocMatching] An attempt to handle unknown/incorrect source port better on AdhocMatching
This commit is contained in:
2 files changed
+86
-28
No files matched your search
+19
-3
@@ -221,6 +221,19 @@ typedef struct SceNetEtherAddr {
|
||||
uint8_t data[ETHER_ADDR_LEN];
|
||||
} PACK SceNetEtherAddr;
|
||||
|
||||
inline bool operator<(const SceNetEtherAddr& lhs, const SceNetEtherAddr& rhs) {
|
||||
uint64_t l = 0;
|
||||
uint64_t r = 0;
|
||||
const uint8_t* lp = lhs.data;
|
||||
const uint8_t* rp = rhs.data;
|
||||
for (int8_t i = 5; i >= 0; i--) {
|
||||
int8_t sb = (CHAR_BIT * i);
|
||||
l |= (uint64_t)*lp++ << sb;
|
||||
r |= (uint64_t)*rp++ << sb;
|
||||
}
|
||||
return (l < r);
|
||||
}
|
||||
|
||||
// Broadcast MAC
|
||||
extern uint8_t broadcastMAC[ETHER_ADDR_LEN];
|
||||
|
||||
@@ -486,12 +499,15 @@ typedef struct SceNetAdhocMatchingContext {
|
||||
// Maximum Number of Peers (for HOST, P2P)
|
||||
s32_le maxpeers;
|
||||
|
||||
// Local MAC Address
|
||||
SceNetEtherAddr mac;
|
||||
|
||||
// Peer List for Connectees
|
||||
SceNetAdhocMatchingMemberInternal *peerlist; // SceNetAdhocMatchingMemberInfo[Emu]
|
||||
|
||||
// Peer Port list
|
||||
std::map<SceNetEtherAddr, u16_le> *peerPort;
|
||||
|
||||
// Local MAC Address
|
||||
SceNetEtherAddr mac;
|
||||
|
||||
// Local PDP Port
|
||||
u16_le port;
|
||||
|
||||
|
||||
+67
-25
@@ -4488,6 +4488,8 @@ int NetAdhocMatching_Delete(int matchingId) {
|
||||
free(item->hello);
|
||||
free(item->rxbuf);
|
||||
clearPeerList(item); //deleteAllMembers(item);
|
||||
(*item->peerPort).clear();
|
||||
delete item->peerPort;
|
||||
// Destroy locks
|
||||
item->eventlock->lock(); // Make sure it's not locked when being deleted
|
||||
item->eventlock->unlock();
|
||||
@@ -4638,6 +4640,7 @@ static int sceNetAdhocMatchingCreate(int mode, int maxnum, int port, int rxbufle
|
||||
context->timeout = (((u64)(keepalive_int)+(u64)rexmt_int) * (u64)init_count);
|
||||
context->timeout += adhocDefaultTimeout; // For internet play we need higher timeout than what the game wanted
|
||||
context->handler = handler;
|
||||
context->peerPort = new std::map<SceNetEtherAddr, u16_le>();
|
||||
|
||||
// Fill in Selfpeer
|
||||
context->mac = localmac;
|
||||
@@ -5468,16 +5471,16 @@ int sceNetAdhocMatchingAbortSendData(int matchingId, const char *mac) {
|
||||
|
||||
// Get the maximum memory usage by the matching library
|
||||
static int sceNetAdhocMatchingGetPoolMaxAlloc() {
|
||||
ERROR_LOG(SCENET, "UNIMPL sceNetAdhocMatchingGetPoolMaxAlloc()");
|
||||
ERROR_LOG(SCENET, "UNIMPL sceNetAdhocMatchingGetPoolMaxAlloc() at %08x", currentMIPS->pc);
|
||||
if (!g_Config.bEnableWlan)
|
||||
return -1;
|
||||
|
||||
// Lazy way out - hardcoded return value
|
||||
return fakePoolSize/2; // (50 * 1024);
|
||||
return hleLogDebug(SCENET, fakePoolSize/2, "faked value");
|
||||
}
|
||||
|
||||
int sceNetAdhocMatchingGetPoolStat(u32 poolstatPtr) {
|
||||
DEBUG_LOG(SCENET, "UNTESTED sceNetAdhocMatchingGetPoolStat(%08x)", poolstatPtr);
|
||||
DEBUG_LOG(SCENET, "UNTESTED sceNetAdhocMatchingGetPoolStat(%08x) at %08x", poolstatPtr, currentMIPS->pc);
|
||||
if (!g_Config.bEnableWlan)
|
||||
return -1;
|
||||
|
||||
@@ -5500,11 +5503,11 @@ int sceNetAdhocMatchingGetPoolStat(u32 poolstatPtr) {
|
||||
}
|
||||
|
||||
// Invalid Argument
|
||||
return ERROR_NET_ADHOC_MATCHING_INVALID_ARG;
|
||||
return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_INVALID_ARG, "adhocmatching invalid arg");
|
||||
}
|
||||
|
||||
// Uninitialized Library
|
||||
return ERROR_NET_ADHOC_MATCHING_NOT_INITIALIZED;
|
||||
return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_NOT_INITIALIZED, "adhocmatching not initialized");
|
||||
}
|
||||
|
||||
void __NetTriggerCallbacks()
|
||||
@@ -6010,9 +6013,24 @@ void broadcastPingMessage(SceNetAdhocMatchingContext * context)
|
||||
uint8_t ping = PSP_ADHOC_MATCHING_PACKET_PING;
|
||||
|
||||
// Send Broadcast
|
||||
context->socketlock->lock();
|
||||
sceNetAdhocPdpSend(context->socket, (const char*)(SceNetEtherAddr *)broadcastMAC, context->port, &ping, sizeof(ping), 0, ADHOC_F_NONBLOCK);
|
||||
context->socketlock->unlock();
|
||||
// FIXME: Not sure whether this PING supposed to be sent only to AdhocMatching members or to everyone in Adhocctl Group, since we already pinging the AdhocServer to avoid getting kicked out of Adhocctl Group
|
||||
peerlock.lock();
|
||||
auto peer = friends; // Use context->peerlist if only need to send to AdhocMatching members
|
||||
for (; peer != NULL; peer = peer->next) {
|
||||
// Skipping soon to be removed peer
|
||||
if (peer->last_recv == 0)
|
||||
continue;
|
||||
|
||||
u16_le port = context->port;
|
||||
auto it = (*context->peerPort).find(peer->mac_addr);
|
||||
if (it != (*context->peerPort).end())
|
||||
port = it->second;
|
||||
|
||||
context->socketlock->lock();
|
||||
sceNetAdhocPdpSend(context->socket, (const char*)&peer->mac_addr, port, &ping, sizeof(ping), 0, ADHOC_F_NONBLOCK);
|
||||
context->socketlock->unlock();
|
||||
}
|
||||
peerlock.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -6053,10 +6071,24 @@ void broadcastHelloMessage(SceNetAdhocMatchingContext * context)
|
||||
DataToHexString(10, 0, context->hello, context->hellolen, &hellohex);
|
||||
DEBUG_LOG(SCENET, "HELLO Dump (%d bytes):\n%s", context->hellolen, hellohex.c_str());
|
||||
|
||||
// Send Broadcast
|
||||
context->socketlock->lock();
|
||||
sceNetAdhocPdpSend(context->socket, (const char*)(SceNetEtherAddr *)broadcastMAC, context->port, hello, 5 + context->hellolen, 0, ADHOC_F_NONBLOCK);
|
||||
context->socketlock->unlock();
|
||||
// Send Broadcast, so everyone know we have a room here
|
||||
peerlock.lock();
|
||||
SceNetAdhocctlPeerInfo* peer = friends;
|
||||
for (; peer != NULL; peer = peer->next) {
|
||||
// Skipping soon to be removed peer
|
||||
if (peer->last_recv == 0)
|
||||
continue;
|
||||
|
||||
u16_le port = context->port;
|
||||
auto it = (*context->peerPort).find(peer->mac_addr);
|
||||
if (it != (*context->peerPort).end())
|
||||
port = it->second;
|
||||
|
||||
context->socketlock->lock();
|
||||
sceNetAdhocPdpSend(context->socket, (const char*)&peer->mac_addr, port, hello, 5 + context->hellolen, 0, ADHOC_F_NONBLOCK);
|
||||
context->socketlock->unlock();
|
||||
}
|
||||
peerlock.unlock();
|
||||
|
||||
// Free Memory, not needed since it may be reused again later
|
||||
//free(hello);
|
||||
@@ -6132,7 +6164,7 @@ void sendAcceptPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * ma
|
||||
|
||||
// Send Data
|
||||
context->socketlock->lock();
|
||||
sceNetAdhocPdpSend(context->socket, (const char*)mac, context->port, accept, 9 + optlen + siblingbuflen, 0, ADHOC_F_NONBLOCK);
|
||||
sceNetAdhocPdpSend(context->socket, (const char*)mac, (*context->peerPort)[*mac], accept, 9 + optlen + siblingbuflen, 0, ADHOC_F_NONBLOCK);
|
||||
context->socketlock->unlock();
|
||||
|
||||
// Free Memory
|
||||
@@ -6176,7 +6208,7 @@ void sendJoinPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * mac,
|
||||
|
||||
// Send Data
|
||||
context->socketlock->lock();
|
||||
sceNetAdhocPdpSend(context->socket, (const char*)mac, context->port, join, 5 + optlen, 0, ADHOC_F_NONBLOCK);
|
||||
sceNetAdhocPdpSend(context->socket, (const char*)mac, (*context->peerPort)[*mac], join, 5 + optlen, 0, ADHOC_F_NONBLOCK);
|
||||
context->socketlock->unlock();
|
||||
|
||||
// Free Memory
|
||||
@@ -6211,7 +6243,7 @@ void sendCancelPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * ma
|
||||
|
||||
// Send Data
|
||||
context->socketlock->lock();
|
||||
sceNetAdhocPdpSend(context->socket, (const char*)mac, context->port, cancel, 5 + optlen, 0, ADHOC_F_NONBLOCK);
|
||||
sceNetAdhocPdpSend(context->socket, (const char*)mac, (*context->peerPort)[*mac], cancel, 5 + optlen, 0, ADHOC_F_NONBLOCK);
|
||||
context->socketlock->unlock();
|
||||
|
||||
// Free Memory
|
||||
@@ -6273,7 +6305,7 @@ void sendBulkDataPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr *
|
||||
|
||||
// Send Data
|
||||
context->socketlock->lock();
|
||||
sceNetAdhocPdpSend(context->socket, (const char*)mac, context->port, send, 5 + datalen, 0, ADHOC_F_NONBLOCK);
|
||||
sceNetAdhocPdpSend(context->socket, (const char*)mac, (*context->peerPort)[*mac], send, 5 + datalen, 0, ADHOC_F_NONBLOCK);
|
||||
context->socketlock->unlock();
|
||||
|
||||
// Free Memory
|
||||
@@ -6322,7 +6354,7 @@ void sendBirthPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * mac
|
||||
{
|
||||
// Send Packet
|
||||
context->socketlock->lock();
|
||||
int sent = sceNetAdhocPdpSend(context->socket, (const char*)&peer->mac, context->port, packet, sizeof(packet), 0, ADHOC_F_NONBLOCK);
|
||||
int sent = sceNetAdhocPdpSend(context->socket, (const char*)&peer->mac, (*context->peerPort)[peer->mac], packet, sizeof(packet), 0, ADHOC_F_NONBLOCK);
|
||||
context->socketlock->unlock();
|
||||
|
||||
// Log Send Success
|
||||
@@ -6365,7 +6397,7 @@ void sendDeathPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * mac
|
||||
|
||||
// Send Bye Packet
|
||||
context->socketlock->lock();
|
||||
sceNetAdhocPdpSend(context->socket, (const char*)&peer->mac, context->port, packet, sizeof(packet[0]), 0, ADHOC_F_NONBLOCK);
|
||||
sceNetAdhocPdpSend(context->socket, (const char*)&peer->mac, (*context->peerPort)[peer->mac], packet, sizeof(packet[0]), 0, ADHOC_F_NONBLOCK);
|
||||
context->socketlock->unlock();
|
||||
}
|
||||
else
|
||||
@@ -6377,7 +6409,7 @@ void sendDeathPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * mac
|
||||
|
||||
// Send Death Packet
|
||||
context->socketlock->lock();
|
||||
sceNetAdhocPdpSend(context->socket, (const char*)&peer->mac, context->port, packet, sizeof(packet), 0, ADHOC_F_NONBLOCK);
|
||||
sceNetAdhocPdpSend(context->socket, (const char*)&peer->mac, (*context->peerPort)[peer->mac], packet, sizeof(packet), 0, ADHOC_F_NONBLOCK);
|
||||
context->socketlock->unlock();
|
||||
}
|
||||
}
|
||||
@@ -6405,7 +6437,7 @@ void sendByePacket(SceNetAdhocMatchingContext * context)
|
||||
|
||||
// Send Bye Packet
|
||||
context->socketlock->lock();
|
||||
sceNetAdhocPdpSend(context->socket, (const char*)&peer->mac, context->port, &opcode, sizeof(opcode), 0, ADHOC_F_NONBLOCK);
|
||||
sceNetAdhocPdpSend(context->socket, (const char*)&peer->mac, (*context->peerPort)[peer->mac], &opcode, sizeof(opcode), 0, ADHOC_F_NONBLOCK);
|
||||
context->socketlock->unlock();
|
||||
}
|
||||
}
|
||||
@@ -7250,7 +7282,8 @@ int matchingInputThread(int matchingId) // TODO: The MatchingInput thread is usi
|
||||
context->socketlock->unlock();
|
||||
|
||||
// Received Data from a Sender that interests us
|
||||
if (recvresult == 0 && rxbuflen > 0 && context->port == senderport)
|
||||
// Note: There are cases where the sender port might be re-mapped by router or ISP, so we shouldn't check the source port.
|
||||
if (recvresult == 0 && rxbuflen > 0)
|
||||
{
|
||||
// Log Receive Success
|
||||
if (context->rxbuf[0] > 1) {
|
||||
@@ -7269,6 +7302,19 @@ int matchingInputThread(int matchingId) // TODO: The MatchingInput thread is usi
|
||||
else {
|
||||
WARN_LOG(SCENET, "InputLoop[%d]: Unknown Peer[%s:%u] (Recved=%i, Length=%i)", matchingId, mac2str(&sendermac).c_str(), senderport, recvresult, rxbuflen);
|
||||
}
|
||||
|
||||
// Show a warning if other player is having their port being re-mapped, thus that other player may have issue with the communication.
|
||||
// Note: That other player may need to switch side between host and join, or reboot their router to solve this issue.
|
||||
if (context->port != senderport && senderport != (*context->peerPort)[sendermac]) {
|
||||
char name[9] = {};
|
||||
if (peer != NULL)
|
||||
truncate_cpy(name, sizeof(name), (const char*)peer->nickname.data);
|
||||
WARN_LOG(SCENET, "InputLoop[%d]: Unknown Source Port from [%s][%s:%u -> %u] (Recved=%i, Length=%i)", matchingId, name, mac2str(&sendermac).c_str(), senderport, context->port, recvresult, rxbuflen);
|
||||
host->NotifyUserMessage(std::string(n->T("AM: Data from Unknown Port")) + std::string(" [") + std::string(name) + std::string("]:") + std::to_string(senderport) + std::string(" -> ") + std::to_string(context->port) + std::string(" (") + std::to_string(portOffset) + std::string(")"), 2.0, 0x0080ff);
|
||||
}
|
||||
// Keep tracks of re-mapped peer's ports for further communication.
|
||||
// Note: This will only works if this player were able to receives data on normal port from other players (ie. this player's port wasn't remapped)
|
||||
(*context->peerPort)[sendermac] = senderport;
|
||||
peerlock.unlock();
|
||||
|
||||
// Ping Packet
|
||||
@@ -7303,10 +7349,6 @@ int matchingInputThread(int matchingId) // TODO: The MatchingInput thread is usi
|
||||
|
||||
// Ignore Incoming Trash Data
|
||||
}
|
||||
else if (recvresult == 0 && rxbuflen > 0) {
|
||||
WARN_LOG(SCENET, "InputLoop[%d]: Unknown Port[%s:%u] (Recved=%i, Length=%i)", matchingId, mac2str(&sendermac).c_str(), senderport, recvresult, rxbuflen);
|
||||
host->NotifyUserMessage(std::string(n->T("Data from incorrect Port")) + std::string(" [") + mac2str(&sendermac) + std::string("]:") + std::to_string(senderport) + std::string(" -> ") + std::to_string(context->port) + std::string(" (") + std::to_string(portOffset) + std::string(")"), 1.0, 0x0080ff);
|
||||
}
|
||||
|
||||
// Handle Peer Timeouts
|
||||
handleTimeout(context);
|
||||
|
||||
Reference in new issue
Block a user