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
|
// hints for the communication
|
||||||
addrinfo addressHints {};
|
addrinfo addressHints {};
|
||||||
addressHints.ai_family = useIpv6 ? AF_INET6 : AF_INET;
|
addressHints.ai_family = useIpv6 ? AF_INET6 : AF_INET;
|
||||||
// addressHints.ai_flags = AI_PASSIVE;
|
|
||||||
addressHints.ai_socktype = SOCK_DGRAM;
|
addressHints.ai_socktype = SOCK_DGRAM;
|
||||||
addressHints.ai_protocol = IPPROTO_UDP;
|
addressHints.ai_protocol = IPPROTO_UDP;
|
||||||
|
|
||||||
|
@ -58,21 +57,42 @@ EventManager::EventManager(const std::string& address, const std::string& port,
|
||||||
if (this->context.socket < 0)
|
if (this->context.socket < 0)
|
||||||
throw std::runtime_error("Could not create the socket: " + std::string(strerror(errno)));
|
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
|
// get the information for the broadcast local-link address
|
||||||
// TODO(Faraphel): ip / port as argument ?
|
|
||||||
if(const int error = getaddrinfo(
|
if(const int error = getaddrinfo(
|
||||||
address.c_str(),
|
address.c_str(),
|
||||||
port.c_str(),
|
port.c_str(),
|
||||||
&addressHints,
|
&addressHints,
|
||||||
&context.broadcastAddressInfo
|
&context.broadcastAddressInfo
|
||||||
) != 0)
|
) != 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
|
// bind the socket to the address
|
||||||
if (bind(
|
if (bind(
|
||||||
this->context.socket,
|
this->context.socket,
|
||||||
this->context.broadcastAddressInfo->ai_addr,
|
anyAddressInfo->ai_addr,
|
||||||
this->context.broadcastAddressInfo->ai_addrlen
|
anyAddressInfo->ai_addrlen
|
||||||
) < 0)
|
) < 0)
|
||||||
throw std::runtime_error("Could not bind to the address: " + std::string(strerror(errno)));
|
throw std::runtime_error("Could not bind to the address: " + std::string(strerror(errno)));
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "InfoEvent.hpp"
|
#include "InfoEvent.hpp"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <iostream>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,6 +14,8 @@ void InfoEvent::handle(
|
||||||
const sockaddr_storage& fromAddress,
|
const sockaddr_storage& fromAddress,
|
||||||
const socklen_t fromAddressLength
|
const socklen_t fromAddressLength
|
||||||
) {
|
) {
|
||||||
|
std::cout << "Received peer information." << std::endl;
|
||||||
|
|
||||||
// get the peer information
|
// get the peer information
|
||||||
Peer peer;
|
Peer peer;
|
||||||
std::memcpy(&peer, content.data.data(), sizeof(Peer));
|
std::memcpy(&peer, content.data.data(), sizeof(Peer));
|
||||||
|
|
|
@ -33,7 +33,7 @@ void event::SearchEvent::handle(
|
||||||
|
|
||||||
// TODO(Faraphel): send back the timestamp too
|
// TODO(Faraphel): send back the timestamp too
|
||||||
|
|
||||||
// broadcast our information
|
// send back our information
|
||||||
if (sendto(
|
if (sendto(
|
||||||
context.socket,
|
context.socket,
|
||||||
&packet,
|
&packet,
|
||||||
|
@ -46,7 +46,15 @@ void event::SearchEvent::handle(
|
||||||
return;
|
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) {
|
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.
|
// search if a server is available among the peer.
|
||||||
const auto& server = std::ranges::find_if(
|
const auto& server = std::ranges::find_if(
|
||||||
context.remotePeers,
|
context.remotePeers,
|
||||||
|
@ -38,6 +45,8 @@ void UndefinedTask::handle(Context& context) {
|
||||||
std::chrono::high_resolution_clock::now() - context.latestPeerDiscovery >
|
std::chrono::high_resolution_clock::now() - context.latestPeerDiscovery >
|
||||||
std::chrono::milliseconds(5000)
|
std::chrono::milliseconds(5000)
|
||||||
) {
|
) {
|
||||||
|
std::cout << "No more peers discovered." << std::endl;
|
||||||
|
|
||||||
// otherwise, become the server if we have the highest ID.
|
// otherwise, become the server if we have the highest ID.
|
||||||
// TODO(Faraphel): should use the machine with the lowest average ping
|
// TODO(Faraphel): should use the machine with the lowest average ping
|
||||||
if (context.me.serverEnabled) {
|
if (context.me.serverEnabled) {
|
||||||
|
@ -54,7 +63,7 @@ void UndefinedTask::handle(Context& context) {
|
||||||
|
|
||||||
// check if we are this peer
|
// check if we are this peer
|
||||||
if (context.me.id == serverCandidate->first) {
|
if (context.me.id == serverCandidate->first) {
|
||||||
std::cout << "becoming server..." << std::endl;
|
std::cout << "Becoming server..." << std::endl;
|
||||||
// set ourselves as the server
|
// set ourselves as the server
|
||||||
context.server = serverCandidate->second;
|
context.server = serverCandidate->second;
|
||||||
context.me.status = TaskType::SERVER;
|
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
|
// prepare a search message
|
||||||
|
@ -79,6 +88,8 @@ void UndefinedTask::handle(Context& context) {
|
||||||
std::memcpy(&packetContent.data, &packetData, sizeof(packetData));
|
std::memcpy(&packetContent.data, &packetData, sizeof(packetData));
|
||||||
packet.setContent(packetContent);
|
packet.setContent(packetContent);
|
||||||
|
|
||||||
|
std::cout << "Looking for new peers." << std::endl;
|
||||||
|
|
||||||
// send the search message
|
// send the search message
|
||||||
if (sendto(
|
if (sendto(
|
||||||
context.socket,
|
context.socket,
|
||||||
|
|
Loading…
Reference in a new issue