fixed IPv6 mode not being able to receive response

This commit is contained in:
study-faraphel 2024-11-10 19:26:21 +01:00
parent 5567ad0df0
commit 05142cbb1f
4 changed files with 51 additions and 9 deletions

View file

@ -44,7 +44,6 @@ EventManager::EventManager(const std::string& address, const std::string& port,
// hints for the communication
addrinfo addressHints {};
addressHints.ai_family = useIpv6 ? AF_INET6 : AF_INET;
// addressHints.ai_flags = AI_PASSIVE;
addressHints.ai_socktype = SOCK_DGRAM;
addressHints.ai_protocol = IPPROTO_UDP;
@ -58,21 +57,42 @@ EventManager::EventManager(const std::string& address, const std::string& port,
if (this->context.socket < 0)
throw std::runtime_error("Could not create the socket: " + std::string(strerror(errno)));
// allow IPv6 multicast loopback so that we can receive our own messages.
int socketLoopback = 1;
if (setsockopt(
context.socket,
IPPROTO_IPV6,
IPV6_MULTICAST_LOOP,
&socketLoopback,
sizeof(socketLoopback)
) < 0) {
std::cerr << "Failed to set IPV6_MULTICAST_LOOP: " << strerror(errno) << std::endl;
}
// get the information for the broadcast local-link address
// TODO(Faraphel): ip / port as argument ?
if(const int error = getaddrinfo(
address.c_str(),
port.c_str(),
&addressHints,
&context.broadcastAddressInfo
) != 0)
throw std::runtime_error("Could not get the address: " + std::string(gai_strerror(error)));
throw std::runtime_error("Could not get the broadcast address: " + std::string(gai_strerror(error)));
// get the information for the broadcast local-link address
addrinfo *anyAddressInfo;
if(const int error = getaddrinfo(
nullptr,
port.c_str(),
&addressHints,
&anyAddressInfo
) != 0)
throw std::runtime_error("Could not get the any address: " + std::string(gai_strerror(error)));
// bind the socket to the address
if (bind(
this->context.socket,
this->context.broadcastAddressInfo->ai_addr,
this->context.broadcastAddressInfo->ai_addrlen
anyAddressInfo->ai_addr,
anyAddressInfo->ai_addrlen
) < 0)
throw std::runtime_error("Could not bind to the address: " + std::string(strerror(errno)));

View file

@ -1,6 +1,7 @@
#include "InfoEvent.hpp"
#include <cstring>
#include <iostream>
#include <sys/socket.h>
@ -13,6 +14,8 @@ void InfoEvent::handle(
const sockaddr_storage& fromAddress,
const socklen_t fromAddressLength
) {
std::cout << "Received peer information." << std::endl;
// get the peer information
Peer peer;
std::memcpy(&peer, content.data.data(), sizeof(Peer));

View file

@ -33,7 +33,7 @@ void event::SearchEvent::handle(
// TODO(Faraphel): send back the timestamp too
// broadcast our information
// send back our information
if (sendto(
context.socket,
&packet,
@ -46,7 +46,15 @@ void event::SearchEvent::handle(
return;
}
std::cout << "[Receiver] Sent information." << std::endl;
char hoststr[NI_MAXHOST];
char portstr[NI_MAXSERV];
getnameinfo(
reinterpret_cast<const sockaddr*>(&fromAddress), fromAddressLength,
hoststr, sizeof(hoststr),
portstr, sizeof(portstr),
NI_NUMERICHOST | NI_NUMERICSERV
);
std::cout << "[Receiver] Sent back information to " << hoststr << ":" << portstr << std::endl;
}

View file

@ -19,6 +19,13 @@ namespace drp::task {
void UndefinedTask::handle(Context& context) {
std::cout << "List of peers: " << std::endl;
for (const auto& peer : context.remotePeers)
std::cout <<
"\tPeer(id=" << peer.second->information.id << ", " <<
"status=" << std::to_string(static_cast<std::uint8_t>(peer.second->information.status)) << ")" <<
std::endl;
// search if a server is available among the peer.
const auto& server = std::ranges::find_if(
context.remotePeers,
@ -38,6 +45,8 @@ void UndefinedTask::handle(Context& context) {
std::chrono::high_resolution_clock::now() - context.latestPeerDiscovery >
std::chrono::milliseconds(5000)
) {
std::cout << "No more peers discovered." << std::endl;
// otherwise, become the server if we have the highest ID.
// TODO(Faraphel): should use the machine with the lowest average ping
if (context.me.serverEnabled) {
@ -54,7 +63,7 @@ void UndefinedTask::handle(Context& context) {
// check if we are this peer
if (context.me.id == serverCandidate->first) {
std::cout << "becoming server..." << std::endl;
std::cout << "Becoming server..." << std::endl;
// set ourselves as the server
context.server = serverCandidate->second;
context.me.status = TaskType::SERVER;
@ -62,7 +71,7 @@ void UndefinedTask::handle(Context& context) {
}
}
// TODO(Faraphel): sleep 1s
std::this_thread::sleep_for(std::chrono::seconds(1));
}
// prepare a search message
@ -79,6 +88,8 @@ void UndefinedTask::handle(Context& context) {
std::memcpy(&packetContent.data, &packetData, sizeof(packetData));
packet.setContent(packetContent);
std::cout << "Looking for new peers." << std::endl;
// send the search message
if (sendto(
context.socket,