Fix parsing of MULTICAST_GATHER

This commit is contained in:
Adam Ierymenko 2019-08-29 11:23:23 -07:00
parent 2d7a97bb94
commit dbad9585cd
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3

View file

@ -42,6 +42,7 @@
#include "../node/Mutex.hpp" #include "../node/Mutex.hpp"
#include "../node/SharedPtr.hpp" #include "../node/SharedPtr.hpp"
#include "../node/MulticastGroup.hpp" #include "../node/MulticastGroup.hpp"
#include "../node/CertificateOfMembership.hpp"
#include "../osdep/OSUtils.hpp" #include "../osdep/OSUtils.hpp"
#include <string> #include <string>
@ -155,6 +156,7 @@ static void handlePacket(const int v4s,const int v6s,const InetAddress *const ip
if (self.agree(id,peer->key)) { if (self.agree(id,peer->key)) {
if (pkt.dearmor(peer->key)) { if (pkt.dearmor(peer->key)) {
peer->id = id; peer->id = id;
peer->lastReceive = now;
peer->lastSync = 0; peer->lastSync = 0;
peersByIdentity.emplace(id,peer); peersByIdentity.emplace(id,peer);
peersByVirtAddr[id.address()].emplace(peer); peersByVirtAddr[id.address()].emplace(peer);
@ -252,6 +254,14 @@ static void handlePacket(const int v4s,const int v6s,const InetAddress *const ip
if (gatherLimit > 255) if (gatherLimit > 255)
gatherLimit = 255; gatherLimit = 255;
if ((flags & 0x01) != 0) {
try {
// We don't care about this but we need to skip it if present
CertificateOfMembership com;
com.deserialize(pkt,ZT_PROTO_VERB_MULTICAST_GATHER_IDX_COM);
} catch ( ... ) {} // discard invalid COMs
}
const uint64_t origId = pkt.packetId(); const uint64_t origId = pkt.packetId();
pkt.reset(source,self.address(),Packet::VERB_OK); pkt.reset(source,self.address(),Packet::VERB_OK);
pkt.append((uint8_t)Packet::VERB_MULTICAST_GATHER); pkt.append((uint8_t)Packet::VERB_MULTICAST_GATHER);
@ -312,12 +322,10 @@ static void handlePacket(const int v4s,const int v6s,const InetAddress *const ip
auto peers = peersByVirtAddr.find(dest); auto peers = peersByVirtAddr.find(dest);
if (peers != peersByVirtAddr.end()) { if (peers != peersByVirtAddr.end()) {
for(auto p=peers->second.begin();p!=peers->second.end();++p) { for(auto p=peers->second.begin();p!=peers->second.end();++p) {
if ((now - (*p)->lastReceive) < ZT_PEER_ACTIVITY_TIMEOUT) { if ((*p)->ip6) {
if ((*p)->ip6) { toAddrs.push_back(std::pair< InetAddress *,SharedPtr<RootPeer> >(&((*p)->ip6),*p));
toAddrs.push_back(std::pair< InetAddress *,SharedPtr<RootPeer> >(&((*p)->ip6),*p)); } else if ((*p)->ip4) {
} else if ((*p)->ip4) { toAddrs.push_back(std::pair< InetAddress *,SharedPtr<RootPeer> >(&((*p)->ip4),*p));
toAddrs.push_back(std::pair< InetAddress *,SharedPtr<RootPeer> >(&((*p)->ip4),*p));
}
} }
} }
} }
@ -396,8 +404,8 @@ static void handlePacket(const int v4s,const int v6s,const InetAddress *const ip
} }
for(auto i=toAddrs.begin();i!=toAddrs.end();++i) { for(auto i=toAddrs.begin();i!=toAddrs.end();++i) {
//printf("%s -> %s for %s" ZT_EOL_S,ip->toString(ipstr),i->toString(ipstr2),dest().toString(astr)); //printf("%s -> %s for %s -> %s" ZT_EOL_S,ip->toString(ipstr),i->first->toString(ipstr2),source.toString(astr),dest.toString(astr2));
sendto(i->first->isV4() ? v4s : v6s,pkt.data(),pkt.size(),0,(const struct sockaddr *)i->first,(socklen_t)((i->first->ss_family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6))); sendto(i->first->isV4() ? v4s : v6s,pkt.data(),pkt.size(),0,(const struct sockaddr *)i->first,(socklen_t)(i->first->isV4() ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6)));
} }
} }
@ -412,10 +420,18 @@ static int bindSocket(struct sockaddr *bindAddr)
return -1; return -1;
} }
int f = 131072; int f = 1048576;
setsockopt(s,SOL_SOCKET,SO_RCVBUF,(const char *)&f,sizeof(f)); while (f > 16384) {
f = 131072; if (setsockopt(s,SOL_SOCKET,SO_RCVBUF,(const char *)&f,sizeof(f)) == 0)
setsockopt(s,SOL_SOCKET,SO_SNDBUF,(const char *)&f,sizeof(f)); break;
f -= 16384;
}
f = 1048576;
while (f > 16384) {
if (setsockopt(s,SOL_SOCKET,SO_SNDBUF,(const char *)&f,sizeof(f)) == 0)
break;
f -= 16384;
}
if (bindAddr->sa_family == AF_INET6) { if (bindAddr->sa_family == AF_INET6) {
f = 1; setsockopt(s,IPPROTO_IPV6,IPV6_V6ONLY,(void *)&f,sizeof(f)); f = 1; setsockopt(s,IPPROTO_IPV6,IPV6_V6ONLY,(void *)&f,sizeof(f));