Groupsock.hh 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. /**********
  2. This library is free software; you can redistribute it and/or modify it under
  3. the terms of the GNU Lesser General Public License as published by the
  4. Free Software Foundation; either version 3 of the License, or (at your
  5. option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
  6. This library is distributed in the hope that it will be useful, but WITHOUT
  7. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
  9. more details.
  10. You should have received a copy of the GNU Lesser General Public License
  11. along with this library; if not, write to the Free Software Foundation, Inc.,
  12. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  13. **********/
  14. // "mTunnel" multicast access service
  15. // Copyright (c) 1996-2019 Live Networks, Inc. All rights reserved.
  16. // 'Group sockets'
  17. // C++ header
  18. #ifndef _GROUPSOCK_HH
  19. #define _GROUPSOCK_HH
  20. #ifndef _GROUPSOCK_VERSION_HH
  21. #include "groupsock_version.hh"
  22. #endif
  23. #ifndef _NET_INTERFACE_HH
  24. #include "NetInterface.hh"
  25. #endif
  26. #ifndef _GROUPEID_HH
  27. #include "GroupEId.hh"
  28. #endif
  29. // An "OutputSocket" is (by default) used only to send packets.
  30. // No packets are received on it (unless a subclass arranges this)
  31. class OutputSocket: public Socket {
  32. public:
  33. OutputSocket(UsageEnvironment& env);
  34. virtual ~OutputSocket();
  35. virtual Boolean write(netAddressBits address, portNumBits portNum/*in network order*/, u_int8_t ttl,
  36. unsigned char* buffer, unsigned bufferSize);
  37. Boolean write(struct sockaddr_in& addressAndPort, u_int8_t ttl,
  38. unsigned char* buffer, unsigned bufferSize) {
  39. return write(addressAndPort.sin_addr.s_addr, addressAndPort.sin_port, ttl, buffer, bufferSize);
  40. }
  41. protected:
  42. OutputSocket(UsageEnvironment& env, Port port);
  43. portNumBits sourcePortNum() const {return fSourcePort.num();}
  44. private: // redefined virtual function
  45. virtual Boolean handleRead(unsigned char* buffer, unsigned bufferMaxSize,
  46. unsigned& bytesRead,
  47. struct sockaddr_in& fromAddressAndPort);
  48. private:
  49. Port fSourcePort;
  50. unsigned fLastSentTTL;
  51. };
  52. class destRecord {
  53. public:
  54. destRecord(struct in_addr const& addr, Port const& port, u_int8_t ttl, unsigned sessionId,
  55. destRecord* next);
  56. virtual ~destRecord();
  57. public:
  58. destRecord* fNext;
  59. GroupEId fGroupEId;
  60. unsigned fSessionId;
  61. };
  62. // A "Groupsock" is used to both send and receive packets.
  63. // As the name suggests, it was originally designed to send/receive
  64. // multicast, but it can send/receive unicast as well.
  65. class Groupsock: public OutputSocket {
  66. public:
  67. Groupsock(UsageEnvironment& env, struct in_addr const& groupAddr,
  68. Port port, u_int8_t ttl);
  69. // used for a 'source-independent multicast' group
  70. Groupsock(UsageEnvironment& env, struct in_addr const& groupAddr,
  71. struct in_addr const& sourceFilterAddr,
  72. Port port);
  73. // used for a 'source-specific multicast' group
  74. virtual ~Groupsock();
  75. virtual destRecord* createNewDestRecord(struct in_addr const& addr, Port const& port, u_int8_t ttl, unsigned sessionId, destRecord* next);
  76. // Can be redefined by subclasses that also subclass "destRecord"
  77. void changeDestinationParameters(struct in_addr const& newDestAddr,
  78. Port newDestPort, int newDestTTL,
  79. unsigned sessionId = 0);
  80. // By default, the destination address, port and ttl for
  81. // outgoing packets are those that were specified in
  82. // the constructor. This works OK for multicast sockets,
  83. // but for unicast we usually want the destination port
  84. // number, at least, to be different from the source port.
  85. // (If a parameter is 0 (or ~0 for ttl), then no change is made to that parameter.)
  86. // (If no existing "destRecord" exists with this "sessionId", then we add a new "destRecord".)
  87. unsigned lookupSessionIdFromDestination(struct sockaddr_in const& destAddrAndPort) const;
  88. // returns 0 if not found
  89. // As a special case, we also allow multiple destinations (addresses & ports)
  90. // (This can be used to implement multi-unicast.)
  91. virtual void addDestination(struct in_addr const& addr, Port const& port, unsigned sessionId);
  92. virtual void removeDestination(unsigned sessionId);
  93. void removeAllDestinations();
  94. Boolean hasMultipleDestinations() const { return fDests != NULL && fDests->fNext != NULL; }
  95. struct in_addr const& groupAddress() const {
  96. return fIncomingGroupEId.groupAddress();
  97. }
  98. struct in_addr const& sourceFilterAddress() const {
  99. return fIncomingGroupEId.sourceFilterAddress();
  100. }
  101. Boolean isSSM() const {
  102. return fIncomingGroupEId.isSSM();
  103. }
  104. u_int8_t ttl() const { return fIncomingGroupEId.ttl(); }
  105. void multicastSendOnly(); // send, but don't receive any multicast packets
  106. virtual Boolean output(UsageEnvironment& env, unsigned char* buffer, unsigned bufferSize,
  107. DirectedNetInterface* interfaceNotToFwdBackTo = NULL);
  108. DirectedNetInterfaceSet& members() { return fMembers; }
  109. Boolean deleteIfNoMembers;
  110. Boolean isSlave; // for tunneling
  111. static NetInterfaceTrafficStats statsIncoming;
  112. static NetInterfaceTrafficStats statsOutgoing;
  113. static NetInterfaceTrafficStats statsRelayedIncoming;
  114. static NetInterfaceTrafficStats statsRelayedOutgoing;
  115. NetInterfaceTrafficStats statsGroupIncoming; // *not* static
  116. NetInterfaceTrafficStats statsGroupOutgoing; // *not* static
  117. NetInterfaceTrafficStats statsGroupRelayedIncoming; // *not* static
  118. NetInterfaceTrafficStats statsGroupRelayedOutgoing; // *not* static
  119. Boolean wasLoopedBackFromUs(UsageEnvironment& env, struct sockaddr_in& fromAddressAndPort);
  120. public: // redefined virtual functions
  121. virtual Boolean handleRead(unsigned char* buffer, unsigned bufferMaxSize,
  122. unsigned& bytesRead,
  123. struct sockaddr_in& fromAddressAndPort);
  124. protected:
  125. destRecord* lookupDestRecordFromDestination(struct sockaddr_in const& destAddrAndPort) const;
  126. private:
  127. void removeDestinationFrom(destRecord*& dests, unsigned sessionId);
  128. // used to implement (the public) "removeDestination()", and "changeDestinationParameters()"
  129. int outputToAllMembersExcept(DirectedNetInterface* exceptInterface,
  130. u_int8_t ttlToFwd,
  131. unsigned char* data, unsigned size,
  132. netAddressBits sourceAddr);
  133. protected:
  134. destRecord* fDests;
  135. private:
  136. GroupEId fIncomingGroupEId;
  137. DirectedNetInterfaceSet fMembers;
  138. };
  139. UsageEnvironment& operator<<(UsageEnvironment& s, const Groupsock& g);
  140. // A data structure for looking up a 'groupsock'
  141. // by (multicast address, port), or by socket number
  142. class GroupsockLookupTable {
  143. public:
  144. Groupsock* Fetch(UsageEnvironment& env, netAddressBits groupAddress,
  145. Port port, u_int8_t ttl, Boolean& isNew);
  146. // Creates a new Groupsock if none already exists
  147. Groupsock* Fetch(UsageEnvironment& env, netAddressBits groupAddress,
  148. netAddressBits sourceFilterAddr,
  149. Port port, Boolean& isNew);
  150. // Creates a new Groupsock if none already exists
  151. Groupsock* Lookup(netAddressBits groupAddress, Port port);
  152. // Returns NULL if none already exists
  153. Groupsock* Lookup(netAddressBits groupAddress,
  154. netAddressBits sourceFilterAddr,
  155. Port port);
  156. // Returns NULL if none already exists
  157. Groupsock* Lookup(UsageEnvironment& env, int sock);
  158. // Returns NULL if none already exists
  159. Boolean Remove(Groupsock const* groupsock);
  160. // Used to iterate through the groupsocks in the table
  161. class Iterator {
  162. public:
  163. Iterator(GroupsockLookupTable& groupsocks);
  164. Groupsock* next(); // NULL iff none
  165. private:
  166. AddressPortLookupTable::Iterator fIter;
  167. };
  168. private:
  169. Groupsock* AddNew(UsageEnvironment& env,
  170. netAddressBits groupAddress,
  171. netAddressBits sourceFilterAddress,
  172. Port port, u_int8_t ttl);
  173. private:
  174. friend class Iterator;
  175. AddressPortLookupTable fTable;
  176. };
  177. #endif