fixed IPv6 mode not being able to receive response
This commit is contained in:
parent
5567ad0df0
commit
05142cbb1f
4 changed files with 51 additions and 9 deletions
|
@ -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)));
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue