citra-emu
/
citra-canary
Archived
1
0
Fork 0

Let connected clients handle the eapol packet

This commit is contained in:
B3n30 2018-03-08 15:59:44 +01:00
parent 33a0e87ac2
commit 29d6e05044
1 changed files with 26 additions and 7 deletions

View File

@ -239,19 +239,18 @@ static void HandleEAPoLPacket(const Network::WifiPacket& packet) {
GenerateEAPoLLogoffFrame(packet.transmitter_address, node.network_node_id, node_info,
network_info.max_nodes, network_info.total_nodes);
// TODO(Subv): Encrypt the packet.
eapol_logoff.destination_address = packet.transmitter_address;
// On a 3ds the eapol packet is only sent to packet.transmitter_address
// while a packet containing the node information is broadcasted
// For now we will bradcast the eapol packet instead
eapol_logoff.destination_address = Network::BroadcastMac;
eapol_logoff.type = WifiPacket::PacketType::Data;
SendPacket(eapol_logoff);
// TODO(B3N30): Broadcast updated node list
// The 3ds does this presumably to support spectators.
connection_status_event->Signal();
} else {
if (connection_status.status != static_cast<u32>(NetworkStatus::Connecting)) {
LOG_DEBUG(Service_NWM, "Connection sequence aborted, because connection status is %u",
connection_status.status);
return;
}
} else if (connection_status.status == static_cast<u32>(NetworkStatus::Connecting)) {
auto logoff = ParseEAPoLLogoffFrame(packet.data);
network_info.host_mac_address = packet.transmitter_address;
@ -279,6 +278,26 @@ static void HandleEAPoLPacket(const Network::WifiPacket& packet) {
// otherwise it might cause deadlocks
connection_status_event->Signal();
connection_event->Signal();
} else if (connection_status.status == static_cast<u32>(NetworkStatus::ConnectedAsClient)) {
// On a 3ds this packet wouldn't be addressed to already connected clients
// We use this information because in the current implementation the host
// isn't broadcsting the node information
auto logoff = ParseEAPoLLogoffFrame(packet.data);
network_info.total_nodes = logoff.connected_nodes;
connection_status.total_nodes = logoff.connected_nodes;
node_info.clear();
node_info.reserve(network_info.max_nodes);
for (size_t index = 0; index < logoff.connected_nodes; ++index) {
if (!(connection_status.node_bitmask & 1 << index)) {
connection_status.changed_nodes |= 1 << index;
}
connection_status.nodes[index] = logoff.nodes[index].network_node_id;
connection_status.node_bitmask |= 1 << index;
node_info.emplace_back(DeserializeNodeInfo(logoff.nodes[index]));
}
connection_status_event->Signal();
}
}