void ForwarderRank::_endNeighbor(const NodeRef &neighbor)
{
	// We don't handle routing to anything but other haggle nodes:
	if (neighbor->getType() != Node::TYPE_PEER)
		return;
	
	// Update our private metric regarding this node:
	bubble_node_id_t neighbor_id = id_from_string(neighbor->getIdStr());
	
	HAGGLE_DBG("HAGGLE_DBG: _endNeighbor node left: node %ld %s \n", neighbor_id, neighbor->getIdStr());

	rib_timestamp = Timeval::now();
}
Example #2
0
void
ReplicationManager::onNodeContactNew(Event *e)
{
    if (getState() > MANAGER_STATE_RUNNING) {
        HAGGLE_DBG("In shutdown, ignoring node contact end\n");
        return;
    }
	
    if (!e) {
        return;
    }

    NodeRef node = e->getNode();

    if (node && node->getType() != Node::TYPE_UNDEFINED) {
        getModule()->notifyNewContact(node);
    }
}
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 #4
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);
		}
	}
}