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;
}
Example #3
0
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.
	}
}
Example #4
0
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;

}
Example #10
0
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;
}
Example #12
0
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);
		}
	}
}