예제 #1
0
void SecurityManager::onConfig(Metadata *m)
{
	const char *param = m->getParameter("security_level");
	
	if (param) {
		char *level = new char[strlen(param) + 1];
		size_t i;
		
		// Convert string to uppercase
		for (i = 0; i < strlen(param); i++) {
			level[i] = toupper(param[i]);
		}
		
		level[i] = '\0';
		
		if (strcmp(level, security_level_names[SECURITY_LEVEL_HIGH]) == 0) {
			securityLevel = SECURITY_LEVEL_HIGH;
			HAGGLE_DBG("Security level set to %s\n", security_level_names[SECURITY_LEVEL_HIGH]);
		} else if (strcmp(level, security_level_names[SECURITY_LEVEL_MEDIUM]) == 0) {
			securityLevel = SECURITY_LEVEL_MEDIUM;
			HAGGLE_DBG("Security level set to %s\n", security_level_names[SECURITY_LEVEL_MEDIUM]);
		} else if (strcmp(level, security_level_names[SECURITY_LEVEL_LOW]) == 0) {
			securityLevel = SECURITY_LEVEL_LOW;
			HAGGLE_DBG("Security level set to %s\n", security_level_names[SECURITY_LEVEL_LOW]);
		} else {
			HAGGLE_ERR("Unrecognized security level '%s'\n", level);
		}
		
		delete [] level;
	}
}
예제 #2
0
void Forwarder::onConfig(const Metadata& m) 
{
	if (m.getName().compare("Forwarder") != 0)
		return;
	
	const char *param = m.getParameter("max_generated_delegates");
	
	if (param) {
		char *ptr = NULL;
		unsigned long d = strtoul(param, &ptr, 10);
		
		if (ptr && ptr != param && *ptr == '\0') {
			HAGGLE_DBG("%s Setting max_generated_delegates to %lu\n", getName(), d);
			max_generated_delegates = d;
		}
	}
	
	param = m.getParameter("max_generated_targets");
	
	if (param) {
		char *ptr = NULL;
		unsigned long d = strtoul(param, &ptr, 10);
		
		if (ptr && ptr != param && *ptr == '\0') {
			HAGGLE_DBG("%s Setting max_generated_targets to %lu\n", getName(), d);
			max_generated_targets = d;
		}
	}
	
	const Metadata *md = m.getMetadata(getName());
	
	if (md) {
		onForwarderConfig(*md);
	}
}
예제 #3
0
void ForwarderRank::_onForwarderConfig(const Metadata& m)
{
	if (strcmp(getName(), m.getName().c_str()) != 0)
		return;
	
	HAGGLE_DBG("Prophet forwarder configuration\n");
	
	const char *param = m.getParameter("label");
	if (param) {
		
		myLabel = string(param);
		HAGGLE_DBG("%s: Setting label to %s\n", getName(), myLabel.c_str());
	}
	
	param = m.getParameter("rank");
	if (param)
	{
		char *ptr = NULL;
		RANK_T p = strtol(param,&ptr,10);
		
		if (ptr && ptr != param && *ptr == '\0')
		{
			myRank = p;
			HAGGLE_DBG("%s: Setting rank to %ld\n", getName(), myRank);
		}
	}
	
}
예제 #4
0
bool SecurityHelper::run()
{	
	HAGGLE_DBG("SecurityHelper running...\n");
	
	while (!shouldExit()) {
		QueueEvent_t qe;
		SecurityTask *task = NULL;
		
		qe = taskQ.retrieve(&task);
		
		switch (qe) {
		case QUEUE_ELEMENT:
			doTask(task);

			// Delete task here or return it with result in private event?
			//delete task;
			break;
		case QUEUE_WATCH_ABANDONED:
			HAGGLE_DBG("SecurityHelper instructed to exit...\n");
			return false;
		default:
			HAGGLE_ERR("Unknown security task queue return value\n");
		}
	}
	return false;
}
예제 #5
0
ProtocolEvent ProtocolRFCOMMClient::connectToPeer()
{
	struct sockaddr_bt peerAddr;
	BluetoothAddress *addr;
	
	if (!peerIface)
		return PROT_EVENT_ERROR;

	addr = peerIface->getAddress<BluetoothAddress>();

	if(!addr)
		return PROT_EVENT_ERROR;

	memset(&peerAddr, 0, sizeof(peerAddr));
	peerAddr.bt_family = AF_BLUETOOTH;

	BDADDR_swap(&peerAddr.bt_bdaddr, mac);
	peerAddr.bt_channel = channel & 0xff;

	HAGGLE_DBG("%s Trying to connect over RFCOMM to [%s] channel=%u\n", 
		   getName(), addr->getStr(), channel);

	ProtocolEvent ret = openConnection((struct sockaddr *) &peerAddr, sizeof(peerAddr));

	if (ret != PROT_EVENT_SUCCESS) {
		HAGGLE_DBG("%s Connection failed to [%s] channel=%u\n", 
			   getName(), addr->getStr(), channel);
		return ret;
	}

	HAGGLE_DBG("%s Connected to [%s] channel=%u\n", 
		   getName(), addr->getStr(), channel);

	return ret;
}
예제 #6
0
bool SecurityHelper::verifyDataObject(DataObjectRef& dObj, CertificateRef& cert) const
{
	RSA *key;
	
	// Cannot verify without signature
	if (!dObj->getSignature()) {
		HAGGLE_ERR("No signature in data object, cannot verify\n");
		return false;
	}	
	writeErrors("(not this): ");
	
	key = cert->getPubKey();

	if (RSA_verify(NID_sha1, dObj->getId(), sizeof(DataObjectId_t), 
		       const_cast<unsigned char *>(dObj->getSignature()), dObj->getSignatureLength(), key) != 1) {
		char *raw;
		size_t len;
		writeErrors("");
		dObj->getRawMetadataAlloc((unsigned char **)&raw, &len);
		if (raw) {
			HAGGLE_DBG("Signature is invalid:\n%s\n", raw);
			free(raw);
		}
		dObj->setSignatureStatus(DataObject::SIGNATURE_INVALID);

		return false;
	}
	
	HAGGLE_DBG("Signature is valid\n");
	dObj->setSignatureStatus(DataObject::SIGNATURE_VALID);

	return true;
}
예제 #7
0
void ProtocolManager::onNeighborInterfaceDown(Event *e)
{
	InterfaceRef& iface = e->getInterface();
	
	if (!iface)
		return;
	
	HAGGLE_DBG("Neighbor interface [%s] went away, checking for associated protocols\n", iface->getIdentifierStr());

	// Go through the protocol list
	protocol_registry_t::iterator it = protocol_registry.begin();
	
	for (;it != protocol_registry.end(); it++) {
		Protocol *p = (*it).second;
		
		/* 
		 Never bring down our application IPC protocol when
		 application interfaces go down (i.e., applications deregister).
		 */
		if (p->getLocalInterface()->getType() == Interface::TYPE_APPLICATION_PORT) {
			continue;
		}
		// Is the associated with this protocol?
		if (p->isClient() && p->isForInterface(iface)) {
			HAGGLE_DBG("Shutting down protocol %s because neighbor interface [%s] went away\n",
				   p->getName(), iface->getIdentifierStr());
			p->handleInterfaceDown(iface);
		}
	}
}
예제 #8
0
void ProtocolManager::onWatchableEvent(const Watchable& wbl)
{
	protocol_registry_t::iterator it = protocol_registry.begin();

	HAGGLE_DBG("Receive on %s\n", wbl.getStr());

	// Go through each protocol in turn:
	for (; it != protocol_registry.end(); it++) {
		Protocol *p = (*it).second;

		// Did the Watchable belong to this protocol
		if (p->hasWatchable(wbl)) {
			// Let the protocol handle whatever happened.
			p->handleWatchableEvent(wbl);
			return;
		}
	}

	HAGGLE_DBG("Was asked to handle a socket no protocol knows about!\n");
	// Should not happen, but needs to be dealt with because if it isn't,
	// the kernel will call us again in an endless loop!

	kernel->unregisterWatchable(wbl);

	CLOSE_SOCKET(wbl.getSocket());
}
예제 #9
0
bool 
SocketWrapper::multiplySndBufferSize(int factor)
{
    bool res = false;
#if defined(OS_LINUX) 
    int ret = 0;
    long optval = 0;
    socklen_t optlen = sizeof(optval);

    ret = ::getsockopt(sock, SOL_SOCKET, SO_SNDBUF, &optval, &optlen);

    if (-1 == ret) {
        return res;
    }

    HAGGLE_DBG("Original send buffer set to %ld bytes\n", optval); 

    optval = optval * factor;

    ret = ::setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &optval, optlen);

    if (-1 == ret) {
        HAGGLE_ERR("Could not set send buffer to %ld bytes\n", optval);
    } else {
        HAGGLE_DBG("Send buffer set to %ld bytes\n", optval); 
        res = true;
    }
#endif

	return res;
}
예제 #10
0
void ProtocolManager::onProtocolShutdownTimeout(Event *e)
{
	HAGGLE_DBG("Checking for still registered protocols: num registered=%lu\n", 
		   protocol_registry.size());
	
	if (!protocol_registry.empty()) {
		while (!protocol_registry.empty()) {
			Protocol *p = (*protocol_registry.begin()).second;
			protocol_registry.erase(p->getId());
			HAGGLE_DBG("Protocol \'%s\' still registered after shutdown. Detaching it!\n", p->getName());
			
			// We are not going to join with these threads, so we detach.
			if (p->isRunning()) {
				// In detached state, the protocol will delete itself
				// once it stops running.
				p->detach();
				p->cancel();
				
				// We have to clear the protocol's send queue as it may contain
				// data objects whose send verdict managersa are
				// waiting for. Clearing the queue will evict all data objects
				// from its queue with a FAILURE verdict.
				p->closeAndClearQueue();
			} else {
				delete p;
			}
		}
		unregisterWithKernel();
	}
}
예제 #11
0
bool ProtocolManager::registerProtocol(Protocol *p)
{
	protocol_registry_t::iterator it;

	if (!p)
		return false;
	
	// We are in shutdown, so do not accept this protocol to keep running.
	if (getState() > MANAGER_STATE_RUNNING) {
		p->shutdown();
		if (!p->isDetached()) {
			p->join();
			HAGGLE_DBG("Joined with protocol %s\n", p->getName());
		}
		return false;
	}
		
	if (protocol_registry.insert(make_pair(p->getId(), p)).second == false) {
		HAGGLE_ERR("Protocol %s already registered!\n", p->getName());
		return false;
	}

	p->setRegistered();
	
	HAGGLE_DBG("Protocol %s registered\n", p->getName());
	
	return true;
}
예제 #12
0
ProtocolEvent ProtocolUDPGeneric::waitForEvent(
    DataObjectRef &dObj, 
    Timeval *timeout, 
    bool writeevent)
{
    QueueElement *qe = NULL;
    Queue *q = getQueue();

    if (!q) {
        return PROT_EVENT_ERROR;
    }

    SocketWrapper *sock = getReadEndOfReceiveSocket();

    if (NULL == sock) {
        HAGGLE_ERR("%s Null receive socket\n", getName());
        return PROT_EVENT_ERROR_FATAL;
    }

    HAGGLE_DBG("%s Waiting for queue element or timeout... %s\n", 
	       getName(), timeout->getAsString().c_str());

    QueueEvent_t qev = q->retrieve(&qe, 
		      sock->getSOCKET(), 
		      timeout, 
		      writeevent);

    if (QUEUE_ELEMENT == qev) {
        dObj = qe->getDataObject();
        delete qe;
        return PROT_EVENT_TXQ_NEW_DATAOBJECT;
    }

    if (QUEUE_EMPTY == qev) {
        return PROT_EVENT_TXQ_EMPTY;
    }

    if (QUEUE_WATCH_WRITE == qev) {
        return PROT_EVENT_WRITEABLE;
    }

    if (QUEUE_WATCH_ABANDONED == qev) {
        // SW: this occurs when the protocol has been shutdown via some other
        // mechanism, such as interface down
        HAGGLE_DBG("%s Waiting for event abandoned\n", getName());
        return PROT_EVENT_SHOULD_EXIT;
    }
    
    if (QUEUE_TIMEOUT == qev) {
        HAGGLE_DBG("%s Waiting for event timeout\n", getName());
        return  PROT_EVENT_TIMEOUT;
    }

    if (QUEUE_WATCH_READ == qev) {
        return PROT_EVENT_INCOMING_DATA;
    } 

    HAGGLE_ERR("%s Waiting for event unknown error\n", getName());
    return PROT_EVENT_ERROR;
}
예제 #13
0
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());
    }

}
예제 #14
0
ProtocolEvent ProtocolTCPClient::connectToPeer()
{
	socklen_t addrlen;
        char buf[SOCKADDR_SIZE];
        struct sockaddr *peer_addr = (struct sockaddr *)buf;
	unsigned short peerPort;
	SocketAddress *addr = NULL;
	InterfaceRef pIface;
	
        // FIXME: use other port than the default one?
        peerPort = TCP_DEFAULT_PORT;

	if (!peerIface ||
	    !(peerIface->getAddress<IPv4Address>() || 
#if defined(ENABLE_IPv6)
	      peerIface->getAddress<IPv6Address>()
#else
		  0
#endif
		  ))
		return PROT_EVENT_ERROR;

#if defined(ENABLE_IPv6)
	IPv6Address *addr6 = peerIface->getAddress<IPv6Address>();
	if (addr6) {
		addrlen = addr6->fillInSockaddr((struct sockaddr_in6 *)peer_addr, peerPort);
		addr = addr6;
		HAGGLE_DBG("Using IPv6 address %s to connect to peer\n", addr6->getStr());
	}
#endif
	
	if (!addr) {
		// Since the check above passed, we know there has to be an IPv4 or an 
		// IPv6 address associated with the interface, and since there was no IPv6...
		IPv4Address *addr4 = peerIface->getAddress<IPv4Address>();
		if (addr4) {
			addrlen = addr4->fillInSockaddr((struct sockaddr_in *)peer_addr, peerPort);
			addr = addr4;
		}
	}

	if (!addr) {
		HAGGLE_DBG("No IP address to connect to\n");
		return PROT_EVENT_ERROR;
	}
	
	ProtocolEvent ret = openConnection(peer_addr, addrlen);

	if (ret != PROT_EVENT_SUCCESS) {
		HAGGLE_DBG("%s Connection failed to [%s] tcp port=%u\n", 
			getName(), addr->getStr(), peerPort);
		return ret;
	}

	HAGGLE_DBG("%s Connected to [%s] tcp port=%u\n", getName(), addr->getStr(), peerPort);

	return ret;
}
예제 #15
0
ProtocolEvent
SocketWrapper::openConnection(
    const struct sockaddr *saddr, 
    socklen_t addrlen)
{

    bool wasNonBlock = isNonblock();

    if (INVALID_SOCKET == sock) {
        HAGGLE_ERR("Socket is invalid\n");
        return PROT_EVENT_ERROR;
    }

    if (!saddr) {
        HAGGLE_ERR("Address is invalid\n");
        return PROT_EVENT_ERROR;
    } 

    // block while connecting

    if (nonblock) {
        setNonblock(false);
    }

    bool hasError = false;

    int ret = ::connect(sock, saddr, addrlen);

    if (SOCKET_ERROR == ret) {
        hasError = true;
        HAGGLE_ERR("Problems connecting: %s\n", 
            SocketWrapper::getProtocolErrorStr());
    }

    if (wasNonBlock) {
        setNonblock(true);
    }

    if (!hasError) {
        HAGGLE_DBG("Succesfully connected to socket.\n");
        setConnected(true);
        return PROT_EVENT_SUCCESS;
    } else {
        HAGGLE_DBG("An error occurred connecting: %s\n", 
            getProtocolErrorStr());
    }

    switch (getProtocolError()) {
    case PROT_ERROR_BAD_HANDLE:
    case PROT_ERROR_INVALID_ARGUMENT:
    case PROT_ERROR_NO_MEMORY:
    case PROT_ERROR_NOT_A_SOCKET:
    case PROT_ERROR_NO_STORAGE_SPACE:
        return PROT_EVENT_ERROR_FATAL;
    default: 
        return PROT_EVENT_ERROR;
    }    
}
예제 #16
0
ProtocolEvent ProtocolUDP::sendData(const void *buffer, size_t len, const int flags, size_t *bytes)
{
        char buf[SOCKADDR_SIZE];
        struct sockaddr *sa = (struct sockaddr *)buf;		
	socklen_t addrlen;
	SocketAddress *addr = NULL;
	ssize_t ret;
	
	if (!buffer) {
		HAGGLE_DBG("%s Send buffer is NULL\n", getName());
		return PROT_EVENT_ERROR;
	}
	
	if (!peerIface) {
		HAGGLE_DBG("%s Send interface invalid\n", getName());
		*bytes = 0;
		return PROT_EVENT_ERROR;
	}
	
#if defined(ENABLE_IPv6)
	addr = peerIface->getAddress<IPv6Address>();
#endif

	if (!addr)
		addr = peerIface->getAddress<IPv4Address>();
	
	if (!addr) {
		HAGGLE_DBG("%s Send interface has no valid address\n", getName());
		*bytes = 0;
		return PROT_EVENT_ERROR;
	}
	
	if (addr->getTransport()->getType() != Transport::TYPE_UDP) {
		HAGGLE_DBG("%s Send interface [%s] has no valid UDP port\n", getName(),
			   peerIface->getIdentifierStr());
		*bytes = 0;
		return PROT_EVENT_ERROR;
	}
	
	addrlen = addr->fillInSockaddr(sa);
	
	HAGGLE_DBG("%s sending to address %s:%d\n", 
		   getName(), addr->getURI(), 
		   reinterpret_cast<const TransportUDP *>(addr->getTransport())->getPort());
	
	ret = sendTo(buffer, len, flags, sa, addrlen);

	if (ret < 0)
		return PROT_EVENT_ERROR;
	else if (ret == 0)
		return PROT_EVENT_PEER_CLOSED;

	*bytes = ret;

	return PROT_EVENT_SUCCESS;	
}
예제 #17
0
/*
 This function is called after the SecurityHelper thread finished a task.
 The Security manager may act on any of the results if it wishes.
 
 */
void SecurityManager::onSecurityTaskComplete(Event *e)
{
	if (!e || !e->hasData())
		return;
        
        SecurityTask *task = static_cast<SecurityTask *>(e->getData());

        switch (task->type) {
                case SECURITY_TASK_GENERATE_CERTIFICATE:
                        HAGGLE_DBG("Certificate generated!\n");
			if (task->cert->getSubject() == kernel->getThisNode()->getIdStr()) {
				HAGGLE_DBG("Certificate is my own\n");
				
				/* Save our private key and our certificate */
				privKey = task->privKey;
				myCert = task->cert;
				signalIsReadyForStartup();
			}
			break;
                case SECURITY_TASK_VERIFY_CERTIFICATE:
			/*
			if (task->cert && task->cert->isVerified()) {
				printCertificates();
			}
			*/ 
			break;
		case SECURITY_TASK_VERIFY_DATAOBJECT:
			/*
			  NOTE:
			  Here is the possibility to generate a EVENT_TYPE_DATAOBJECT_VERIFIED
			  event even if the data object had a bad signature. In that case, the
			  Data manager will remove the data object from the bloomfilter so that
			  it can be received again (hopefully with a valid signature the next time).
			  However, this means that also the data object with the bad signature
			  can be received once more, in worst case in a never ending circle.

			  Perhaps the best solution is to hash both the data object ID and the 
			  signature (if available) into a node's bloomfilter?
			*/
			if (task->dObj->hasValidSignature()) {
				HAGGLE_DBG("DataObject %s has a valid signature!\n", 
					   task->dObj->getIdStr());
				kernel->addEvent(new Event(EVENT_TYPE_DATAOBJECT_VERIFIED, 
							   task->dObj));
			} else {
				HAGGLE_DBG("DataObject %s has an unverifiable signature!\n", 
					   task->dObj->getIdStr());
			}
			break;
                case SECURITY_TASK_SIGN_DATAOBJECT:
                        break;
        }
	delete task;
}
예제 #18
0
void SecurityManager::onRepositoryData(Event *e)
{
	RepositoryEntryRef re;
	
	if (!e->getData()) {
		signalIsReadyForStartup();
		return;
	}
	
	HAGGLE_DBG("Got repository callback\n");
	
	DataStoreQueryResult *qr = static_cast < DataStoreQueryResult * >(e->getData());
	
	if (qr->countRepositoryEntries() == 0) {
		HAGGLE_DBG("No repository entries, generating new certificate and keypair\n");
		helper->addTask(new SecurityTask(SECURITY_TASK_GENERATE_CERTIFICATE));
		
		// Delay signalling that we are ready for startup until we get the 
		// task result indicating our certificate is ready.
		delete qr;
		return;
	}
	
	while ((re = qr->detachFirstRepositoryEntry())) {
		if (strcmp(re->getKey(), "privkey") == 0) {
			
			// Just to make sure
			if (privKey)
				RSA_free(privKey);
			
			privKey = stringToRSAKey(re->getValueStr(), KEY_TYPE_PRIVATE);
			
			HAGGLE_DBG("Read my own private key from repository\n");
		} else {
			CertificateRef c = Certificate::fromPEM(re->getValueStr());
			
			if (c) {
				if (c->getSubject() == kernel->getThisNode()->getIdStr())
					myCert = c;
				
				storeCertificate(c);
				HAGGLE_DBG("Read certificate for subject '%s' from repository\n", 
					   c->getSubject().c_str());
			} else {
				HAGGLE_ERR("Could not read certificate from repository\n");
			}
		}
	}
	
	delete qr;
	
	signalIsReadyForStartup();
}
void bluetoothDiscoveryCompleteCallback(void *userRefCon, IOBluetoothDeviceInquiryRef inquiryRef, IOReturn error, Boolean aborted)
{
	ConnectivityBluetooth *conn = (ConnectivityBluetooth *) userRefCon;

	if (aborted) {
		HAGGLE_DBG("%s: inquiry aborted\n", conn->getName());
	} else {
		HAGGLE_DBG("%s: inquiry completed\n", conn->getName());
	}
	
	conn->isInquiring = false;
}
예제 #20
0
bool ForwarderRank::newRoutingInformation(const Metadata *m)
{	
	if (!m || m->getName() != getName())
		return false;
	
	bubble_node_id_t node_b_id = id_from_string(m->getParameter("node_id"));
	
	HAGGLE_DBG("HAGGLE_DBG: New %s routing information received from %s number %ld \n",
		   getName(),
		   m->getParameter("node_id"), id_from_string(m->getParameter("node_id")));
	
	const Metadata *mm = m->getMetadata("Metric");
	
	while (mm) {
		
		//bubble_node_id_t node_c_id = id_from_string(mm->getParameter("node_id"));
		
		LABEL_T node_b_label = mm->getParameter("label");
		
		const char* node_b_hostid = mm->getParameter("hostid");
		
		const char* tmp = mm->getParameter("rank");
		
		RANK_T node_b_rank = atol(tmp);
		
		rib[node_b_id].first = node_b_label;
		
		rib[node_b_id].second = node_b_rank;

		
		HAGGLE_DBG("Routing received from %s label:%s rank:%ld \n",node_b_hostid , rib[node_b_id].first.c_str(), rib[node_b_id].second);
		
		//HAGGLE_DBG("HAGGLE_DBG: Routing received from node:%s label:%s rank:%ld \n",id_number_to_nodeid[node_b_id].c_str(), rib[node_b_id].first.c_str(), rib[node_b_id].second);
		
		mm= m->getNextMetadata();
	
	}
	
	bubble_rib_t::iterator jt = rib.begin();
	
	while (jt != rib.end()) {

		//bool isNeighbor = getKernel()->getNodeStore()->stored(id_number_to_nodeid[jt->first], true);
		
		HAGGLE_DBG("HAGGLE_DBG: Printing node_id_num:%ld label:%s rank:%ld \n", jt->first, jt->second.first.c_str() , jt->second.second);
		jt++;
	}
		
	rib_timestamp = Timeval::now();
	
	return true;
}
예제 #21
0
bool ProtocolRFCOMM::initbase()
{
	struct sockaddr_bt localAddr;

        if (isConnected()) {
                // Nothing to do
                return true;
        }

	if (!openSocket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM, isServer())) {
		HAGGLE_ERR("Could not create RFCOMM socket\n");
                return false;
        }

	memset(&localAddr, 0, sizeof(struct sockaddr_bt));
	localAddr.bt_family = AF_BLUETOOTH;
	localAddr.bt_channel = channel & 0xff;

#ifndef OS_WINDOWS
	if (localIface) {
		BluetoothAddress *addr = localIface->getAddress<BluetoothAddress>();
		if (addr) {
                        // Binding RFCOMM sockets to a hardware address does not
                        // seem to work in Windows
			BDADDR_swap(&localAddr.bt_bdaddr, addr->getRaw());
                }
	}
#endif

	if (isServer()) {
		localAddr.bt_channel = channel & 0xff;
   
             	/* If this is a server we bing to a specific channel to listen on */
                if (!bind((struct sockaddr *)&localAddr, sizeof(localAddr))) {
                        closeSocket();
#ifdef OS_WINDOWS
                        HAGGLE_ERR("Bind failed for local address WSA error=%s\n", StrError(WSAGetLastError()));
#endif
                        
                        HAGGLE_ERR("Could not bind local address for RFCOMM socket\n");
                        
                        return false;
                }

                HAGGLE_DBG("Bound RFCOMM server to channel=%d\n", channel);
   
	} else {
		HAGGLE_DBG("Created RFCOMM client on channel=%d\n", channel);
	}

	return true;
}
예제 #22
0
ProtocolEvent ProtocolRFCOMMServer::acceptClient()
{
	SOCKET clientSock;
	struct sockaddr_bt clientAddr;
	socklen_t len;
	char btMac[BT_ALEN];

	HAGGLE_DBG("In RFCOMMServer receive\n");

	if (getMode() != PROT_MODE_LISTENING) {
		HAGGLE_DBG("Error: RFCOMMServer not in LISTEN mode\n");
		return PROT_EVENT_ERROR;
	}

	len = sizeof(clientAddr);

	clientSock = accept((struct sockaddr *) &clientAddr, &len);

	if (clientSock == INVALID_SOCKET)
		return PROT_EVENT_ERROR;

	/* Save address and channel information in client handle. */
	ProtocolManager *pm = static_cast<ProtocolManager *>(getManager());

	if (!pm) {
		HAGGLE_DBG("Error: No manager for protocol!\n");
		CLOSE_SOCKET(clientSock);
		return PROT_EVENT_ERROR;
	}

	BDADDR_swap(btMac, &clientAddr.bt_bdaddr);

	ProtocolRFCOMMClient *p = new ProtocolRFCOMMReceiver(clientSock, btMac,
							   (unsigned short) clientAddr.bt_channel,
							   this->getLocalInterface(), pm);

	if (!p || !p->init()) {
		HAGGLE_ERR("Could not create new RFCOMM receiver\n");
		CLOSE_SOCKET(clientSock);
                
                if (p)
                        delete p;

		return PROT_EVENT_ERROR;
	}

	p->registerWithManager();

	HAGGLE_DBG("Accepted client with socket %d, starting client thread\n", clientSock);

	return p->startTxRx();
}
예제 #23
0
/*
	On send events, the security manager 
 
 */
void SecurityManager::onSendDataObject(Event *e)
{
	if (!e || !e->hasData())
		return;

	DataObjectRef dObj = e->getDataObject();
	
	if (dObj->isThisNodeDescription()) {
		// This is our node description. Piggy-back our certificate.
		if (myCert) {
			Metadata *m;

			m = dObj->getMetadata()->getMetadata("Security");
			
			if (m) {
				HAGGLE_ERR("Node description already has a Security tag!\n");
			} else {
				m = dObj->getMetadata()->addMetadata("Security");
				
				if (m) {
					m->addMetadata(myCert->toMetadata());
				}
			}
		}
	}
	
	// In most cases the data object is already signed here (e.g., if it is generated by a local
	// application, or was received from another node). The only reason to check if we should
	// sign the data object here, is if a data object was generated internally by Haggle -- in
	// which case the data object might not have a signature (e.g., the data object is a node
	// description).
	InterfaceRef iface = dObj->getRemoteInterface();
	
	if (dObj->shouldSign() && !(iface && iface->getType() == Interface::TYPE_APPLICATION_PORT)) {
		// FIXME: data objects should really be signed in the SecurityHelper thread since
		// it is a potentially CPU intensive operation. But it is currently not possible
		// to ensure that the signing operation has finished in the helper thread before
		// the data object is actually sent on the wire by the protocol manager.
		// To handle this situation, we probably need to add a new public event for 
		// security related operations, after which the security manager generates the
		// real send event.
		
		if (helper->signDataObject(dObj, privKey)) {
			HAGGLE_DBG("Successfully signed data object %s\n", dObj->getIdStr());
		} else {
			HAGGLE_DBG("Signing of data object %s failed!\n", dObj->getIdStr());
		}
	}	
}
예제 #24
0
/*
	Do not stop protocols until we are in shutdown, because other managers
	may rely on protocol services while they are preparing for shutdown.
 */
void ProtocolManager::onShutdown()
{	
	HAGGLE_DBG("%lu protocols are registered.\n", protocol_registry.size());
	
	if (protocol_registry.empty()) {
		unregisterWithKernel();
	} else {
		// Go through the registered protocols
		protocol_registry_t::iterator it = protocol_registry.begin();

		for (; it != protocol_registry.end(); it++) {
			// Tell this protocol we're shutting down!
			(*it).second->shutdown();
		}
		
		// In case some protocols refuse to shutdown, launch a thread that sleeps for a while
		// before it schedules an event that forcefully kills the protocols.
		// Note that we need to use this thread to implement a timeout because in shutdown
		// the event queue executes as fast as it can, hence delayed events do not work.
		killer = new ProtocolKiller(protocol_shutdown_timeout_event, 15000, kernel);
		
		if (killer) {
			killer->start();
		}
	}
}
예제 #25
0
bool 
SocketWrapper::setListen(int backlog)
{
    if (isListening()) {
        HAGGLE_DBG("Already listening.");
        return false;
    }
    
    if (SOCKET_ERROR == listen(sock, backlog)) {
        HAGGLE_DBG("Could not set listen.");
        return false;
    }
	
    setListening(true);
    return true;
}
예제 #26
0
void DebugManager::publicEvent(Event *e)
{
	if (!e)
		return;
	
	HAGGLE_DBG("%s data=%s\n", e->getName(), e->hasData() ? "Yes" : "No");
}
예제 #27
0
// store a new block into the buffer
bool CodeTorrent::StoreBlock(CodedBlockPtr in) {

	int gen = in->gen;

	if (nc->IsHelpful(rank_vec, m_helpful, in)) {
		HAGGLE_DBG2("Block is helpful\n");
		buf.push_back(CopyCodedBlock(in));
		rank_vec[gen]++; // if helpful, raise the rank
		rank_vec_in_buf[gen]++;

		if (buf.size() >= buffer_size) { // if the buf goes above the threshold
			FlushBuf();
		}

	} else {
	    HAGGLE_DBG("Block is not helpful\n");
		return false; // if not helpful, return false
	}

	// if full-rank, this generation is complete
	if (rank_vec[gen] == GetNumBlocksGen(gen)) {

		IncrementGenCompleted();
	}

	return true;
}
예제 #28
0
void CodeTorrent::PrintFileInfo() {

	HAGGLE_DBG(" ========= File Info =========\n");
	if (identity == CT_SERVER)
		HAGGLE_DBG(" SERVER\n");
	else
		HAGGLE_DBG(" CLIENT\n");
	HAGGLE_DBG(" File name: %s\n", GetFileName());
	HAGGLE_DBG(" File Size: %d\n", GetFileSize());
	HAGGLE_DBG(" Number Generations: %d\n", GetNumGens());
	HAGGLE_DBG(" Block Size: %d\n", GetBlockSize());
	HAGGLE_DBG(" Num Blocks: %d\n", GetNumBlocks());
	//HAGGLE_DBG(" Num Blocks per Gen: %d\n", GetNumBlocksGen());
	HAGGLE_DBG(" Field Size: %d bits\n", GetFieldSize());
	HAGGLE_DBG(" ============================\n");
}
예제 #29
0
bool ResourceMonitorAndroid::run()
{
	Watch w;

	HAGGLE_DBG("Running resource monitor\n");

        if (uevent_init() == -1) {
                HAGGLE_ERR("Could not open uevent socket\n");
                return false;
        }

	while (!shouldExit()) {
		int ret;

		w.reset();
                
                int ueventIndex = w.add(uevent_fd);

		ret = w.wait();
                
		if (ret == Watch::ABANDONED) {
			break;
		} else if (ret == Watch::FAILED) {
			HAGGLE_ERR("Wait on objects failed\n");
			break;
		}

                if (w.isSet(ueventIndex)) {
                        uevent_read();
                }
	}
	return false;
}
예제 #30
0
/**
 Add routing information to a data object.
 The parameter "parent" is the location in the data object where the routing 
 information should be inserted.
 */ 
bool ForwarderRank::addRoutingInformation(DataObjectRef& dObj, Metadata *parent)
{
	if (!dObj || !parent)
		return false;
	
	// Add first our own node ID.
	parent->setParameter("node_id", kernel->getThisNode()->getIdStr());
	
	Metadata *mm = parent->addMetadata("Metric", myNodeStr);
	
	mm->setParameter("hostid",hostname);
	
	mm->setParameter("label", myLabel);
	
	char tmp[32];
	sprintf(tmp,"%ld",myRank);
	mm->setParameter("rank", tmp);
	
	HAGGLE_DBG("HAGGLE_DBG: Sending metric node:%s label:%s rank:%s \n",parent->getParameter("node_id"),
	mm->getParameter("label"),mm->getParameter("rank"));
				
	dObj->setCreateTime(rib_timestamp);
	
	return true;
}