@ -554,6 +554,8 @@ bool IncomingPacket::_doP5_MULTICAST_FRAME(const RuntimeEnvironment *RR,const Sh
const unsigned int signatureLen = at < uint16_t > ( ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_FRAME + frameLen ) ;
{
if ( origin = = RR - > identity . address ( ) )
return true ;
Mutex : : Lock _l ( p5MulticastDedupBuffer_m ) ;
if ( ! p5MulticastDedupBufferPtr ) {
memset ( p5MulticastDedupBuffer , 0 , sizeof ( p5MulticastDedupBuffer ) ) ;
@ -566,6 +568,32 @@ bool IncomingPacket::_doP5_MULTICAST_FRAME(const RuntimeEnvironment *RR,const Sh
p5MulticastDedupBuffer [ p5MulticastDedupBufferPtr + + % 1024 ] = guid ;
}
SharedPtr < Network > network ( RR - > nc - > network ( nwid ) ) ;
if ( network ) {
if ( ( flags & ZT_PROTO_VERB_P5_MULTICAST_FRAME_FLAGS_HAS_MEMBERSHIP_CERTIFICATE ) ! = 0 ) {
CertificateOfMembership com ;
com . deserialize ( * this , ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_FRAME + frameLen + 2 + signatureLen ) ;
if ( com . hasRequiredFields ( ) )
network - > addMembershipCertificate ( com , false ) ;
}
if ( ! network - > isAllowed ( origin ) ) {
SharedPtr < Peer > originPeer ( RR - > topology - > getPeer ( origin ) ) ;
if ( originPeer )
_sendErrorNeedCertificate ( RR , originPeer , nwid ) ;
} else if ( ( frameLen > 0 ) & & ( frameLen < = 2800 ) ) {
if ( ! dest . mac ( ) . isMulticast ( ) )
return true ;
if ( ( ! sourceMac ) | | ( sourceMac . isMulticast ( ) ) | | ( sourceMac = = network - > mac ( ) ) )
return true ;
if ( sourceMac ! = MAC ( origin , nwid ) ) {
if ( network - > permitsBridging ( origin ) ) {
network - > learnBridgeRoute ( sourceMac , origin ) ;
} else return true ;
}
network - > tapPut ( sourceMac , dest . mac ( ) , etherType , frame , frameLen ) ;
}
}
peer - > receive ( RR , _fromSock , _remoteAddress , hops ( ) , packetId ( ) , Packet : : VERB_P5_MULTICAST_FRAME , 0 , Packet : : VERB_NOP , Utils : : now ( ) ) ;
if ( RR - > topology - > amSupernode ( ) ) {
@ -577,12 +605,14 @@ bool IncomingPacket::_doP5_MULTICAST_FRAME(const RuntimeEnvironment *RR,const Sh
const unsigned int limit = 128 ; // use a fairly generous limit since we want legacy peers to always work until they go away
std : : vector < Address > members ( RR - > mc - > getMembers ( nwid , dest , limit ) ) ;
SharedPtr < Peer > lpp ;
setAt ( ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_PROPAGATION_DEPTH , ( uint16_t ) 0xffff ) ;
setSource ( RR - > identity . address ( ) ) ;
compress ( ) ;
for ( std : : vector < Address > : : iterator lp ( members . begin ( ) ) ; lp ! = members . end ( ) ; + + lp ) {
SharedPtr < Peer > lpp ( RR - > topology - > getPeer ( * lp ) ) ;
if ( ! senderIsLegacy )
lpp = RR - > topology - > getPeer ( * lp ) ;
if ( ( * lp ! = origin ) & & ( * lp ! = peer - > address ( ) ) & & ( ( senderIsLegacy ) | | ( ! lpp ) | | ( lpp - > remoteVersionMajor ( ) < 1 ) ) ) {
newInitializationVector ( ) ;
setDestination ( * lp ) ;
@ -605,35 +635,6 @@ bool IncomingPacket::_doP5_MULTICAST_FRAME(const RuntimeEnvironment *RR,const Sh
sn - > send ( RR , data ( ) , size ( ) , Utils : : now ( ) ) ;
}
}
SharedPtr < Network > network ( RR - > nc - > network ( nwid ) ) ;
if ( network ) {
if ( ( flags & ZT_PROTO_VERB_P5_MULTICAST_FRAME_FLAGS_HAS_MEMBERSHIP_CERTIFICATE ) ) {
CertificateOfMembership com ;
com . deserialize ( * this , ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FRAME + frameLen + 2 + signatureLen ) ;
if ( com . hasRequiredFields ( ) )
network - > addMembershipCertificate ( com , false ) ;
}
if ( ! network - > isAllowed ( origin ) ) {
_sendErrorNeedCertificate ( RR , peer , network - > id ( ) ) ;
return true ;
}
if ( ( frameLen > 0 ) & & ( frameLen < = 2800 ) ) {
if ( ! dest . mac ( ) . isMulticast ( ) )
return true ;
if ( ( ! sourceMac ) | | ( sourceMac . isMulticast ( ) ) | | ( sourceMac = = network - > mac ( ) ) )
return true ;
if ( sourceMac ! = MAC ( origin , network - > id ( ) ) ) {
if ( network - > permitsBridging ( origin ) ) {
network - > learnBridgeRoute ( sourceMac , origin ) ;
} else return true ;
}
network - > tapPut ( sourceMac , dest . mac ( ) , etherType , frame , frameLen ) ;
}
}
} catch ( std : : exception & ex ) {
TRACE ( " dropped P5_MULTICAST_FRAME from %s(%s): unexpected exception: %s " , source ( ) . toString ( ) . c_str ( ) , _remoteAddress . toString ( ) . c_str ( ) , ex . what ( ) ) ;
} catch ( . . . ) {