OutboundMulticast.cpp 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
  4. *
  5. * (c) ZeroTier, Inc.
  6. * https://www.zerotier.com/
  7. */
  8. #include "OutboundMulticast.hpp"
  9. #include "Constants.hpp"
  10. #include "Network.hpp"
  11. #include "Node.hpp"
  12. #include "RuntimeEnvironment.hpp"
  13. #include "Switch.hpp"
  14. #include "Topology.hpp"
  15. namespace ZeroTier {
  16. void OutboundMulticast::init(
  17. const RuntimeEnvironment* RR,
  18. uint64_t timestamp,
  19. uint64_t nwid,
  20. bool disableCompression,
  21. unsigned int limit,
  22. unsigned int gatherLimit,
  23. const MAC& src,
  24. const MulticastGroup& dest,
  25. unsigned int etherType,
  26. const void* payload,
  27. unsigned int len)
  28. {
  29. uint8_t flags = 0;
  30. _timestamp = timestamp;
  31. _nwid = nwid;
  32. if (src) {
  33. _macSrc = src;
  34. flags |= 0x04;
  35. }
  36. else {
  37. _macSrc.fromAddress(RR->identity.address(), nwid);
  38. }
  39. _macDest = dest.mac();
  40. _limit = limit;
  41. _frameLen = (len < ZT_MAX_MTU) ? len : ZT_MAX_MTU;
  42. _etherType = etherType;
  43. if (gatherLimit) {
  44. flags |= 0x02;
  45. }
  46. _packet.setSource(RR->identity.address());
  47. _packet.setVerb(Packet::VERB_MULTICAST_FRAME);
  48. _packet.append((uint64_t)nwid);
  49. _packet.append(flags);
  50. if (gatherLimit) {
  51. _packet.append((uint32_t)gatherLimit);
  52. }
  53. if (src) {
  54. src.appendTo(_packet);
  55. }
  56. dest.mac().appendTo(_packet);
  57. _packet.append((uint32_t)dest.adi());
  58. _packet.append((uint16_t)etherType);
  59. _packet.append(payload, _frameLen);
  60. if (! disableCompression) {
  61. _packet.compress();
  62. }
  63. memcpy(_frameData, payload, _frameLen);
  64. }
  65. void OutboundMulticast::sendOnly(const RuntimeEnvironment* RR, void* tPtr, const Address& toAddr)
  66. {
  67. const SharedPtr<Network> nw(RR->node->network(_nwid));
  68. uint8_t QoSBucket = 255; // Dummy value
  69. if ((nw) && (nw->filterOutgoingPacket(tPtr, true, RR->identity.address(), toAddr, _macSrc, _macDest, _frameData, _frameLen, _etherType, 0, QoSBucket))) {
  70. nw->pushCredentialsIfNeeded(tPtr, toAddr, RR->node->now());
  71. _packet.newInitializationVector();
  72. _packet.setDestination(toAddr);
  73. RR->node->expectReplyTo(_packet.packetId());
  74. _tmp = _packet;
  75. RR->sw->send(tPtr, _tmp, true, _nwid, ZT_QOS_NO_FLOW);
  76. }
  77. }
  78. } // namespace ZeroTier