void ForwarderRank::_generateDelegatesFor(const DataObjectRef &dObj, const NodeRef &target, const NodeRefList *other_targets) { List<Pair<NodeRef, bubble_metric_t> > sorted_delegate_list; // Figure out which node to look for: bubble_node_id_t target_id = id_from_string(target->getIdStr()); LABEL_T targetLabel = rib[target_id].first; //RANK_T targetRank = rib[target_id].second; HAGGLE_DBG("HAGGLE_DBG:_generateDelegatesFor node %d string %s label %s\n", target_id, target->getIdStr(), targetLabel.c_str()); for (bubble_rib_t::iterator it = rib.begin();it != rib.end(); it++) { if (it->first != this_node_id && it->first != target_id) { NodeRef delegate = kernel->getNodeStore()->retrieve(id_number_to_nodeid[it->first], true); if (delegate && !isTarget(delegate, other_targets)) { LABEL_T &neighborLabel = it->second.first; RANK_T &neighborRank = it->second.second; HAGGLE_DBG("HAGGLE_DBG: _generateDelegatesFor neighborLabel=%s, targetLabel=%s\n", neighborLabel.c_str(), targetLabel.c_str()); if (neighborLabel.compare(targetLabel)==0) { //NodeRef delegate = Node::create_with_id(Node::TYPE_PEER, id_number_to_nodeid[it->first].c_str(), "Label delegate node"); sortedNodeListInsert(sorted_delegate_list, delegate, it->second); HAGGLE_DBG("HAGGLE_DBG: _generateDelegatesFor Label same: Node '%s' is a good delegate for target '%s' [label=%s, rank=%ld]\n", delegate->getName().c_str(), target->getName().c_str(), neighborLabel.c_str(), neighborRank); } } } } // Add up to max_generated_delegates delegates to the result in order of decreasing metric if (!sorted_delegate_list.empty()) { NodeRefList delegates; unsigned long num_delegates = max_generated_delegates; while (num_delegates && sorted_delegate_list.size()) { NodeRef delegate = sorted_delegate_list.front().first; sorted_delegate_list.pop_front(); delegates.push_back(delegate); num_delegates--; } kernel->addEvent(new Event(EVENT_TYPE_DELEGATE_NODES, dObj, target, delegates)); HAGGLE_DBG("HAGGLE_DBG: Forward Generated %lu delegates for target %s\n", delegates.size(), target->getName().c_str()); } else { HAGGLE_DBG("No delegates found for target %s\n", target->getName().c_str()); } }
bool NetworkCodingConfiguration::isNetworkCodingEnabled(DataObjectRef dataObject, NodeRef targetNodeToNetworkCodeFor) { // if network coding turned on doesn't matter about dataobjects or targetnoderefids if( NetworkCodingConfiguration::isNetworkCodingTurnedOn ) { return true; } if( !targetNodeToNetworkCodeFor ) { return false; } string targetNodeId = targetNodeToNetworkCodeFor->getName(); string dataObjectId; if (dataObject) dataObjectId = dataObject->getIdStr(); string key = dataObjectId + "|" + targetNodeId; { Mutex::AutoLocker l(NetworkCodingConfiguration::contextAwareMutex); // needs to be fine grained contextawarecodingtracker_t::iterator it = NetworkCodingConfiguration::contextawaretracker.find(key); if (it != NetworkCodingConfiguration::contextawaretracker.end()) { return true; } key = "|" + targetNodeId; it = NetworkCodingConfiguration::contextawaretracker.find(key); if (it != NetworkCodingConfiguration::contextawaretracker.end()) { HAGGLE_DBG("context aware coding is enabled for targetnoderefid=%s, saving status for dataobject=%s\n", targetNodeId.c_str(), dataObjectId.c_str()); NetworkCodingConfiguration::contextawaretracker.insert(make_pair(dataObjectId + "|" + targetNodeId, true)); return true; } } return false; }
void DataManager::onSendResult(Event *e) { DataObjectRef& dObj = e->getDataObject(); NodeRef node = e->getNode(); if (!dObj) { HAGGLE_ERR("No data object in send result\n"); return; } if(dObj->isControlMessage()) { // MOS - keep control messages out of Bloom filter return; } if (!node) { HAGGLE_ERR("No node in send result\n"); return; } if (!node->isStored()) { HAGGLE_DBG2("Send result node %s is not in node store, trying to retrieve\n", node->getName().c_str()); NodeRef peer = kernel->getNodeStore()->retrieve(node); if (peer) { HAGGLE_DBG2("Found node %s in node store, using the one in store\n", node->getName().c_str()); node = peer; } else { HAGGLE_ERR("Did not find node %s in node store\n", node->getName().c_str()); } } if (e->getType() == EVENT_TYPE_DATAOBJECT_SEND_SUCCESSFUL) { // Add data object to node's bloomfilter. HAGGLE_DBG("Adding data object [%s] to node %s's bloomfilter\n", DataObject::idString(dObj).c_str(), node->getName().c_str()); node->getBloomfilter()->add(dObj); if (dataObjectsSent.size() >= MAX_DATAOBJECTS_LISTED) { dataObjectsSent.pop_front(); } dataObjectsSent.push_back(dObj->getIdStr()); // SW: JLM: START CACHE STRATEGY: if ((e->getType() == EVENT_TYPE_DATAOBJECT_SEND_SUCCESSFUL) && cacheStrategy && !cacheStrategy->isDone()) { cacheStrategy->handleSendSuccess(dObj, node); } // SW: JLM: END CACHE STRATEGY. } }
NodeRef Skeleton::findNode( const std::string& name, const NodeRef& node ) const { if( node->getName() == name ) { return node; } for( const NodeRef& child : node->getChildren() ) { NodeRef foundNode = findNode( name, child ); if (foundNode != nullptr) { return foundNode; } } return nullptr; }
void NetworkCodingConfiguration:: turnOnNetworkCodingForDataObjectandTargetNode(string parentDataObjectId, NodeRef targetNodeRef) { string targetNodeRefIdStr = targetNodeRef->getName(); HAGGLE_DBG("context aware coding enable for dataobject id = %s targetnoderefid = %s\n", parentDataObjectId.c_str(),targetNodeRefIdStr.c_str()); string key = parentDataObjectId + "|" + targetNodeRefIdStr; { Mutex::AutoLocker l(NetworkCodingConfiguration::contextAwareMutex); // needs to be fine grained contextawarecodingtracker_t::iterator it = NetworkCodingConfiguration::contextawaretracker.find(key); if (it == NetworkCodingConfiguration::contextawaretracker.end()) NetworkCodingConfiguration::contextawaretracker.insert(make_pair(key, true)); } }
void NetworkCodingConfiguration:: turnOffNetworkCodingForDataObjectandTargetNode(string parentDataObjectId, NodeRef targetNodeRef) { string targetNodeRefIdStr = targetNodeRef->getName(); HAGGLE_DBG("context aware coding disable for dataobject id = %s targetnoderefid = %s\n", parentDataObjectId.c_str(),targetNodeRefIdStr.c_str()); if (!parentDataObjectId.empty()) { HAGGLE_DBG("Not disabling context aware for data object id = %s as we may have started coding\n", parentDataObjectId.c_str()); } else { Mutex::AutoLocker l(NetworkCodingConfiguration::contextAwareMutex); // needs to be fine grained HAGGLE_DBG("Disabling context aware for all data objects for targetnoderefid = %s\n", targetNodeRefIdStr.c_str()); string key = parentDataObjectId + "|" + targetNodeRefIdStr; contextawarecodingtracker_t::iterator it = NetworkCodingConfiguration::contextawaretracker.find(key); if (it != NetworkCodingConfiguration::contextawaretracker.end()) NetworkCodingConfiguration::contextawaretracker.erase(it); } }
void FragmentationConfiguration:: turnOffFragmentationForDataObjectandTargetNode(string parentDataObjectId, NodeRef targetNodeRef) { //some reason empty target node so just return if(!targetNodeRef) { return; } string targetNodeRefIdStr = targetNodeRef->getName(); HAGGLE_DBG("disable fragmentation for for targetnoderefid = %s\n",targetNodeRefIdStr.c_str()); string key = parentDataObjectId + "|" + targetNodeRefIdStr; { Mutex::AutoLocker l(FragmentationConfiguration::contextAwareMutex); // needs to be fine grained contextawarefragmentationtracker_t::iterator it = FragmentationConfiguration::contextawaretracker.find(key); if (it == FragmentationConfiguration::contextawaretracker.end()) FragmentationConfiguration::contextawaretracker.insert(make_pair(key, true)); } }
void FragmentationConfiguration:: turnOnFragmentationForDataObjectandTargetNode(string parentDataObjectId, NodeRef targetNodeRef) { //some reason empty target node so just return if(!targetNodeRef) { return; } string targetNodeRefIdStr = targetNodeRef->getName(); HAGGLE_DBG("enable fragmentation for for targetnoderefid = %s\n",targetNodeRefIdStr.c_str()); if (!parentDataObjectId.empty()) { HAGGLE_DBG("Not enabling fragmentation for data object id = %s as we may have started coding\n", parentDataObjectId.c_str()); } else { Mutex::AutoLocker l(FragmentationConfiguration::contextAwareMutex); // needs to be fine grained HAGGLE_DBG("Enabling fragmentation for all data objects for targetnoderefid = %s\n", targetNodeRefIdStr.c_str()); string key = parentDataObjectId + "|" + targetNodeRefIdStr; contextawarefragmentationtracker_t::iterator it = FragmentationConfiguration::contextawaretracker.find(key); if (it != FragmentationConfiguration::contextawaretracker.end()) FragmentationConfiguration::contextawaretracker.erase(it); } }
bool FragmentationConfiguration::isFragmentationEnabled(DataObjectRef dataObject, NodeRef targetNodeToFragmentCodeFor) { // fragmentation is not enabled at all, so just return false and let nc checks run if(!FragmentationConfiguration::isFragmentationTurnedOn) { return false; } // no target node and already passed the is fragemtnation turned on, so return true if( !targetNodeToFragmentCodeFor ) { return true; } string targetNodeId = targetNodeToFragmentCodeFor->getName(); string dataObjectId; if (dataObject) dataObjectId = dataObject->getIdStr(); string key = dataObjectId + "|" + targetNodeId; { Mutex::AutoLocker l(FragmentationConfiguration::contextAwareMutex); // needs to be fine grained contextawarefragmentationtracker_t::iterator it = FragmentationConfiguration::contextawaretracker.find(key); if (it != FragmentationConfiguration::contextawaretracker.end()) { return false; } key = "|" + targetNodeId; it = FragmentationConfiguration::contextawaretracker.find(key); if (it != FragmentationConfiguration::contextawaretracker.end()) { HAGGLE_DBG("context aware coding is enabled for targetnoderefid=%s, saving status for dataobject=%s\n", targetNodeId.c_str(), dataObjectId.c_str()); FragmentationConfiguration::contextawaretracker.insert(make_pair(dataObjectId + "|" + targetNodeId, true)); return false; } } return true; }
NodeCycleExc::NodeCycleExc( const NodeRef &sourceNode, const NodeRef &destNode ) : AudioExc( string( "cyclical connection between source: " ) + sourceNode->getName() + string( " and dest: " ) + destNode->getName() ) { }
void ProtocolManager::onSendDataObjectActual(Event *e) { int numTx = 0; if (!e || !e->hasData()) return; // Get a copy to work with DataObjectRef dObj = e->getDataObject(); // Get target list: NodeRefList *targets = (e->getNodeList()).copy(); if (!targets) { HAGGLE_ERR("no targets in data object when sending\n"); return; } unsigned int numTargets = targets->size(); // Go through all targets: while (!targets->empty()) { // A current target reference NodeRef targ = targets->pop(); if (!targ) { HAGGLE_ERR("Target num %u is NULL!\n", numTargets); numTargets--; continue; } HAGGLE_DBG("Sending to target %u - %s \n", numTargets, targ->getName().c_str()); // If we are going to loop through the node's interfaces, we need to lock the node. targ.lock(); const InterfaceRefList *interfaces = targ->getInterfaces(); // Are there any interfaces here? if (interfaces == NULL || interfaces->size() == 0) { // No interfaces for target, so we generate a // send failure event and skip the target HAGGLE_DBG("Target %s has no interfaces\n", targ->getName().c_str()); targ.unlock(); kernel->addEvent(new Event(EVENT_TYPE_DATAOBJECT_SEND_FAILURE, dObj, targ)); numTargets--; continue; } /* Find the target interface that suits us best (we assume that for any remote target interface we have a corresponding local interface). */ InterfaceRef peerIface = NULL; bool done = false; InterfaceRefList::const_iterator it = interfaces->begin(); //HAGGLE_DBG("Target node %s has %lu interfaces\n", targ->getName().c_str(), interfaces->size()); for (; it != interfaces->end() && done == false; it++) { InterfaceRef iface = *it; // If this interface is up: if (iface->isUp()) { if (iface->getAddresses()->empty()) { HAGGLE_DBG("Interface %s:%s has no addresses - IGNORING.\n", iface->getTypeStr(), iface->getIdentifierStr()); continue; } switch (iface->getType()) { #if defined(ENABLE_BLUETOOTH) case Interface::TYPE_BLUETOOTH: /* Select Bluetooth only if there are no Ethernet or WiFi interfaces. */ if (!iface->getAddress<BluetoothAddress>()) { HAGGLE_DBG("Interface %s:%s has no Bluetooth address - IGNORING.\n", iface->getTypeStr(), iface->getIdentifierStr()); break; } if (!peerIface) peerIface = iface; else if (peerIface->getType() != Interface::TYPE_ETHERNET && peerIface->getType() != Interface::TYPE_WIFI) peerIface = iface; break; #endif #if defined(ENABLE_ETHERNET) case Interface::TYPE_ETHERNET: /* Let Ethernet take priority over the other types. */ if (!iface->getAddress<IPv4Address>() #if defined(ENABLE_IPv6) && !iface->getAddress<IPv6Address>() #endif ) { HAGGLE_DBG("Interface %s:%s has no IPv4 or IPv6 addresses - IGNORING.\n", iface->getTypeStr(), iface->getIdentifierStr()); break; } if (!peerIface) peerIface = iface; else if (peerIface->getType() == Interface::TYPE_BLUETOOTH || peerIface->getType() == Interface::TYPE_WIFI) peerIface = iface; break; case Interface::TYPE_WIFI: if (!iface->getAddress<IPv4Address>() #if defined(ENABLE_IPv6) && !iface->getAddress<IPv6Address>() #endif ) { HAGGLE_DBG("Interface %s:%s has no IPv4 or IPv6 addresses - IGNORING.\n", iface->getTypeStr(), iface->getIdentifierStr()); break; } if (!peerIface) peerIface = iface; else if (peerIface->getType() == Interface::TYPE_BLUETOOTH && peerIface->getType() != Interface::TYPE_ETHERNET) peerIface = iface; break; #endif // ENABLE_ETHERNET case Interface::TYPE_APPLICATION_PORT: case Interface::TYPE_APPLICATION_LOCAL: if (!iface->getAddress<IPv4Address>() #if defined(ENABLE_IPv6) && !iface->getAddress<IPv6Address>() #endif ) { HAGGLE_DBG("Interface %s:%s has no IPv4 or IPv6 addresses - IGNORING.\n", iface->getTypeStr(), iface->getIdentifierStr()); break; } // Not much choise here. if (targ->getType() == Node::TYPE_APPLICATION) { peerIface = iface; done = true; } else { HAGGLE_DBG("ERROR: Node %s is not application, but its interface is\n", targ->getName().c_str()); } break; #if defined(ENABLE_MEDIA) case Interface::TYPE_MEDIA: break; #endif case Interface::TYPE_UNDEFINED: default: break; } } else { //HAGGLE_DBG("Send interface %s was down, ignoring...\n", iface->getIdentifierStr()); } } // We are done looking for a suitable send interface // among the node's interface list, so now we unlock // the node. targ.unlock(); if (!peerIface) { HAGGLE_DBG("No send interface found for target %s. Aborting send of data object!!!\n", targ->getName().c_str()); // Failed to send to this target, send failure event: kernel->addEvent(new Event(EVENT_TYPE_DATAOBJECT_SEND_FAILURE, dObj, targ)); numTargets--; continue; } // Ok, we now have a target and a suitable interface, // now we must figure out a protocol to use when we // transmit to that interface Protocol *p = NULL; // We make a copy of the addresses list here so that we do not // have to lock the peer interface while we call getSenderProtocol(). // getSenderProtocol() might do a lookup in the interface store in order // to find the local interface which is parent of the peer interface. // This might cause a deadlock in case another thread also does a lookup // in the interface store while we hold the interface lock. const Addresses *adds = peerIface->getAddresses()->copy(); // Figure out a suitable protocol given the addresses associated // with the selected interface for (Addresses::const_iterator it = adds->begin(); p == NULL && it != adds->end(); it++) { switch ((*it)->getType()) { #if defined(ENABLE_BLUETOOTH) case Address::TYPE_BLUETOOTH: p = getSenderProtocol(Protocol::TYPE_RFCOMM, peerIface); break; #endif case Address::TYPE_IPV4: #if defined(ENABLE_IPv6) case Address::TYPE_IPV6: #endif if (peerIface->isApplication()) { #ifdef USE_UNIX_APPLICATION_SOCKET p = getSenderProtocol(Protocol::TYPE_LOCAL, peerIface); #else p = getSenderProtocol(Protocol::TYPE_UDP, peerIface); #endif } else p = getSenderProtocol(Protocol::TYPE_TCP, peerIface); break; #if defined(ENABLE_MEDIA) case Address::TYPE_FILEPATH: p = getSenderProtocol(Protocol::TYPE_MEDIA, peerIface); break; #endif default: break; } } delete adds; // Send data object to the found protocol: if (p) { if (p->sendDataObject(dObj, targ, peerIface)) { numTx++; } else { // Failed to send to this target, send failure event: kernel->addEvent(new Event(EVENT_TYPE_DATAOBJECT_SEND_FAILURE, dObj, targ)); } } else { HAGGLE_DBG("No suitable protocol found for interface %s:%s!\n", peerIface->getTypeStr(), peerIface->getIdentifierStr()); // Failed to send to this target, send failure event: kernel->addEvent(new Event(EVENT_TYPE_DATAOBJECT_SEND_FAILURE, dObj, targ)); } numTargets--; } HAGGLE_DBG("Scheduled %d data objects for sending\n", numTx); delete targets; }
void DataManager::onIncomingDataObject(Event *e) { if (!e || !e->hasData()) return; DataObjectRef& dObj = e->getDataObject(); if (!dObj) { HAGGLE_DBG("Incoming data object event without data object!\n"); return; } if(dObj->isControlMessage()) { // MOS - keep control messages out of Bloom filter return; } // Add the data object to the bloomfilter of the one who sent it: NodeRef peer = e->getNode(); // JM End: Associate origin social group to DO if (!peer || peer->getType() == Node::TYPE_UNDEFINED) { // No valid node in event, try to figure out from interface // Find the interface it came from: const InterfaceRef& iface = dObj->getRemoteInterface(); if (iface) { HAGGLE_DBG2("Incoming data object [%s] has no valid peer node but valid peer interface %s\n", DataObject::idString(dObj).c_str(), iface->getIdentifierStr()); peer = kernel->getNodeStore()->retrieve(iface); if(peer && peer->getType() != Node::TYPE_UNDEFINED) HAGGLE_DBG2("Setting incoming data object peer node to %s\n", peer->getName().c_str()); } else { HAGGLE_DBG("No valid peer interface in data object, cannot figure out peer node\n"); } } if (peer) { if (peer->getType() != Node::TYPE_APPLICATION && peer->getType() != Node::TYPE_UNDEFINED) { // Add the data object to the peer's bloomfilter so that // we do not send the data object back. HAGGLE_DBG("Adding data object [%s] to peer node %s's (%s num=%lu) bloomfilter\n", DataObject::idString(dObj).c_str(), peer->getName().c_str(), peer->isStored() ? "stored" : "not stored", peer->getNum()); /* LOG_ADD("%s: BLOOMFILTER:ADD %s\t%s:%s\n", Timeval::now().getAsString().c_str(), dObj->getIdStr(), peer->getTypeStr(), peer->getIdStr()); */ peer->getBloomfilter()->add(dObj); } } else { HAGGLE_DBG("No valid peer node for incoming data object [%s]\n", dObj->getIdStr()); } // Check if this is a control message from an application. We do not want // to bloat our bloomfilter with such messages, because they are sent // everytime an application connects. if (!dObj->isControlMessage()) { // Add the incoming data object also to our own bloomfilter // We do this early in order to avoid receiving duplicates in case // the same object is received at nearly the same time from multiple neighbors if (localBF->has(dObj)) { HAGGLE_DBG("Data object [%s] already in our bloomfilter, marking as duplicate...\n", dObj->getIdStr()); dObj->setDuplicate(); } else { if(!dObj->isNodeDescription()) { // MOS - local BF only contains data objects in new design localBF->add(dObj); HAGGLE_DBG("Adding data object [%s] to our bloomfilter, #objs=%d\n", DataObject::idString(dObj).c_str(), localBF->numObjects()); kernel->getThisNode()->getBloomfilter()->add(dObj); // MOS if(isNodeDescUpdateOnReceptionEnabled) { // MOS - immediately disseminate updated bloomfilter kernel->getThisNode()->setNodeDescriptionCreateTime(); kernel->addEvent(new Event(EVENT_TYPE_NODE_DESCRIPTION_SEND)); } } if(!periodicBloomfilterUpdateEvent->isScheduled()) // MOS - update now happening periodically kernel->getThisNode()->setBloomfilter(*localBF, setCreateTimeOnBloomfilterUpdate); } } }