995 IPv4ControlInfo *controlInfo = (IPv4ControlInfo *)msg->getControlInfo();
997 ASSERT(ie->isMulticast());
999 EV_INFO <<
"Received IGMPv3 Membership Report on interface '" << ie->getName() <<
"'.\n";
1006 for (
unsigned int i = 0; i < msg->getGroupRecordArraySize(); i++) {
1007 GroupRecord gr = msg->getGroupRecord(i);
1008 EV_DETAIL <<
"Found a record for group '" << gr.groupAddress <<
"'.\n";
1011 sort(gr.sourceList.begin(), gr.sourceList.end());
1014 RouterGroupData *groupData = interfaceData->getOrCreateGroupData(gr.groupAddress);
1016 IPv4MulticastSourceList oldSourceList;
1017 groupData->collectForwardedSources(oldSourceList);
1019 EV_DETAIL <<
"Router State is " << groupData->getStateInfo() <<
".\n";
1023 EV_DETAIL <<
"Received IS_IN" << receivedSources <<
" report.\n";
1026 for (
auto & receivedSource : receivedSources) {
1028 SourceRecord *record = groupData->getOrCreateSourceRecord(receivedSource);
1029 startTimer(record->sourceTimer, groupMembershipInterval);
1033 EV_DETAIL <<
"Received IS_EX" << receivedSources <<
" report.\n";
1037 startTimer(groupData->timer, groupMembershipInterval);
1041 for (
auto it = groupData->sources.begin(); it != groupData->sources.end(); ++it) {
1042 if (
find(receivedSources.begin(), receivedSources.end(), it->first) == receivedSources.end()) {
1043 EV_DETAIL <<
"Deleting source record of '" << it->first <<
"'.\n";
1044 groupData->deleteSourceRecord(it->first);
1050 for (
auto & receivedSource : receivedSources) {
1051 if (!groupData->hasSourceRecord(receivedSource)) {
1052 SourceRecord *record = groupData->createSourceRecord(receivedSource);
1054 EV_DETAIL <<
"Setting source timer of '" << receivedSource <<
"' to '" << timerValue <<
"'.\n";
1056 startTimer(record->sourceTimer, groupMembershipInterval);
1064 EV_DETAIL <<
"Received ALLOW" << receivedSources <<
" report.\n";
1068 for (
auto & receivedSource : receivedSources) {
1069 EV_DETAIL <<
"Setting source timer of '" << receivedSource <<
"' to '" << groupMembershipInterval <<
"'.\n";
1070 SourceRecord *record = groupData->getOrCreateSourceRecord(receivedSource);
1071 startTimer(record->sourceTimer, groupMembershipInterval);
1075 EV_DETAIL <<
"Received BLOCK" << receivedSources <<
" report.\n";
1080 for (
auto & elem : groupData->sources)
1081 sourcesA.push_back(elem.first);
1084 if (!aIntersectB.empty()) {
1085 EV_INFO <<
"Sending Group-and-Source-Specific Query for group '" << groupData->groupAddr
1086 <<
"' on interface '" << ie->getName() <<
"'.\n";
1092 for (
auto it = groupData->sources.begin(); it != groupData->sources.end(); ++it) {
1093 if (!groupData->hasSourceRecord(it->first)) {
1094 SourceRecord *record = groupData->createSourceRecord(it->first);
1095 double grouptimertime = groupData->timer->getArrivalTime().dbl() - simTime().dbl();
1096 EV_DETAIL <<
"Setting source timer of '" << it->first <<
"' to '" << grouptimertime <<
"'.\n";
1097 startTimer(record->sourceTimer, grouptimertime);
1102 for (
auto & elem : groupData->sources) {
1103 if (!elem.second->sourceTimer->isScheduled()) {
1104 ySources.push_back(elem.first);
1108 if (!aMinusY.empty()) {
1109 EV_INFO <<
"Sending Group-and-Source-Specific Query for group '" << groupData->groupAddr
1110 <<
"' on interface '" << ie->getName() <<
"'.\n";
1116 EV_DETAIL <<
"Received TO_IN" << receivedSources <<
" report.\n";
1120 for (
auto & receivedSource : receivedSources) {
1121 EV_DETAIL <<
"Setting source timer of '" << receivedSource <<
"' to '" << groupMembershipInterval <<
"'.\n";
1122 SourceRecord *record = groupData->getOrCreateSourceRecord(receivedSource);
1123 startTimer(record->sourceTimer, groupMembershipInterval);
1127 for (
auto & elem : groupData->sources)
1128 sourcesA.push_back(elem.first);
1130 if (!aMinusB.empty()) {
1131 EV_INFO <<
"Sending Group-and-Source-Specific Query for group '" << groupData->groupAddr
1132 <<
"' on interface '" << ie->getName() <<
"'.\n";
1139 for (
auto & elem : groupData->sources) {
1140 if (elem.second->sourceTimer->isScheduled())
1141 sourcesX.push_back(elem.first);
1145 for (
auto & receivedSource : receivedSources) {
1146 EV_DETAIL <<
"Setting source timer of '" << receivedSource <<
"' to '" << groupMembershipInterval <<
"'.\n";
1147 SourceRecord *record = groupData->getOrCreateSourceRecord(receivedSource);
1148 startTimer(record->sourceTimer, groupMembershipInterval);
1153 if (!xMinusA.empty()) {
1154 EV_INFO <<
"Sending Group-and-Source-Specific Query for group '" << groupData->groupAddr
1155 <<
"' on interface '" << ie->getName() <<
"'.\n";
1160 EV_INFO <<
"Sending Group-Specific Query for group '" << groupData->groupAddr
1161 <<
"' on interface '" << ie->getName() <<
"'.\n";
1166 EV_DETAIL <<
"Received TO_EX" << receivedSources <<
" report.\n";
1170 EV_DETAIL <<
"Setting group timer to '" << groupMembershipInterval <<
"'.\n";
1171 startTimer(groupData->timer, groupMembershipInterval);
1178 for (
auto & elem : groupData->sources)
1179 sourcesA.push_back(elem.first);
1182 for (
auto & receivedSource : receivedSources) {
1183 if (!groupData->hasSourceRecord(receivedSource)) {
1184 EV_DETAIL <<
"Setting source timer of '" << receivedSource <<
"' to '0'.\n";
1185 groupData->createSourceRecord(receivedSource);
1190 for (
auto & elem : sourcesA) {
1191 if (
find(receivedSources.begin(), receivedSources.end(), elem) == receivedSources.end()) {
1192 EV_DETAIL <<
"Deleting source record of '" << elem <<
"'.\n";
1193 groupData->deleteSourceRecord(elem);
1199 if (!aIntersectB.empty()) {
1200 EV_INFO <<
"Sending Group-Specific Query for group '" << groupData->groupAddr
1201 <<
"' on interface '" << ie->getName() <<
"'.\n";
1207 EV_DETAIL <<
"Setting group timer to '" << groupMembershipInterval <<
"'.\n";
1208 startTimer(groupData->timer, groupMembershipInterval);
1212 for (
auto & elem : groupData->sources) {
1213 if (!elem.second->sourceTimer->isScheduled())
1214 sourcesY.push_back(elem.first);
1218 for (
auto it = groupData->sources.begin(); it != groupData->sources.end(); ) {
1219 auto rec = it->first;
1221 if (
find(receivedSources.begin(), receivedSources.end(), it->first) == receivedSources.end()) {
1222 EV_DETAIL <<
"Deleting source record of '" << rec <<
"'.\n";
1223 groupData->deleteSourceRecord(rec);
1228 for (
auto & receivedSource : receivedSources) {
1229 if (!groupData->hasSourceRecord(receivedSource)) {
1230 EV_DETAIL <<
"Setting source timer of '" << receivedSource <<
"' to '" << groupMembershipInterval <<
"'.\n";
1231 SourceRecord *record = groupData->createSourceRecord(receivedSource);
1232 startTimer(record->sourceTimer, groupMembershipInterval);
1238 if (!aMinusY.empty()) {
1239 EV_INFO <<
"Sending Group-Specific Query for group '" << groupData->groupAddr
1240 <<
"' on interface '" << ie->getName() <<
"'.\n";
1246 EV_DETAIL <<
"New Router State is " << groupData->getStateInfo() <<
".\n";
1249 IPv4MulticastSourceList newSourceList;
1250 groupData->collectForwardedSources(newSourceList);
1252 if (newSourceList != oldSourceList) {
1253 ie->ipv4Data()->setMulticastListeners(groupData->groupAddr, newSourceList.filterMode, newSourceList.sources);
IInterfaceTable * ift
Definition: IGMPv3.h:174
virtual InterfaceEntry * getInterfaceById(int id) const =0
Returns an interface by its Id.
virtual RouterInterfaceData * getRouterInterfaceData(InterfaceEntry *ie)
Definition: IGMPv3.cc:348
virtual void sendGroupSpecificQuery(RouterGroupData *group)
Definition: IGMPv3.cc:594
int numReportsRecv
Definition: IGMPv3.h:207
virtual void sendGroupAndSourceSpecificQuery(RouterGroupData *group, const IPv4AddressVector &sources)
Definition: IGMPv3.cc:619
void sort(std::vector< T > &v)
Definition: stlutils.h:112
virtual bool isMulticastForwardingEnabled() const =0
Multicast forwarding on/off.
double groupMembershipInterval
Definition: IGMPv3.h:180
IRoutingTable * rt
Definition: IGMPv3.h:173
std::vector< IPv4Address > IPv4AddressVector
Definition: IGMPv3.h:42
virtual void startTimer(cMessage *timer, double interval)
Definition: IGMPv3.cc:568
std::vector< T >::iterator find(std::vector< T > &v, const T &a)
Definition: stlutils.h:48