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(); }
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; }
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); } } }