bool MP1Node::recvJoinReq(void *env, char *data, int size) {
    if (size < (int)(sizeof(memberNode->addr.addr) + sizeof(long))) {
#ifdef DEBUGLOG
        log->LOG(&memberNode->addr, "Message JOINREQ received with size wrong. Ignored.");
#endif
        return false;
    }

    Address joinaddr;
    long heartbeat;

    memcpy(joinaddr.addr, data, sizeof(memberNode->addr.addr));
    memcpy(&heartbeat, data + sizeof(memberNode->addr.addr), sizeof(long));

//#ifdef DEBUGLOG
//    log->LOG(&memberNode->addr, "JOINREQ received from: %s heartbeat: %li", joinaddr.getAddress().c_str(), heartbeat);
//#endif

    int id = *(int*)(&joinaddr.addr);
    int port = *(short*)(&joinaddr.addr[4]);

    updateMember(id, port, heartbeat);

    sendMemberList("JOINREP", JOINREP, &joinaddr);
    return true;
}
예제 #2
0
/**
 * FUNCTION NAME: recvCallBack
 *
 * DESCRIPTION: Message handler for different message types
 */
bool MP1Node::recvCallBack(void *env, char *data, int size ) {
	/*
	 * Your code goes here
	*/ 
	
    #pragma pack(push,1)
	
    MessageHdr *mType = reinterpret_cast<MessageHdr*>(data);
    
    switch (mType->msgType) {
        case JOINREQ:
            {

                Address* fromAddr = reinterpret_cast<Address*>(mType + 1);
                long* heartbeat = reinterpret_cast<long*>(fromAddr + 1);
                MemberListEntry* newNode = 
						new MemberListEntry(AddrUtils::getID(*fromAddr), AddrUtils::getPort(*fromAddr), 
						*heartbeat, par->getcurrtime());
                memberNode->memberList.push_back(*newNode);
                
#ifdef DEBUGLOG
                log->logNodeAdd(&memberNode->addr, fromAddr);
#endif                

                sendMemberList(fromAddr, JOINREP);
                
                break;
            }
        case JOINREP:
            {
                memberNode->inGroup = true;
                updateMemberList((unsigned char*) data, size);
                break;
            }
        case GOSSIP:
        	{
        		updateMemberList((unsigned char*) data, size);
        		break;
        	}
        case FAIL:
        	{
                Address* failAddr = reinterpret_cast<Address*>(mType + 1);
        		handleFAILNotification(failAddr);
        		break;
        	}
        default:
            {
                cout << "in case default - " << endl;
                break;
            }
    }
    
    #pragma pack(pop)

    return 1;
}
예제 #3
0
/**
* FUNCTION NAME: nodeLoopOps
*
* DESCRIPTION: Check if any node hasn't responded within a timeout period and then delete
* the nodes
* Propagate your membership list
*/
void MP1Node::nodeLoopOps() {
if (par->getcurrtime() > 3 && memberNode->memberList.size() > 1) {
memberNode->memberList.begin()->heartbeat++;
memberNode->memberList.begin()->timestamp = par->getcurrtime();
int pos = rand() % (memberNode->memberList.size() - 1) + 1;
MemberListEntry& member = memberNode->memberList[pos];
if (par->getcurrtime() - member.timestamp > TFAIL) {
// FIXME escolher outro
return;
}
Address memberAddr;
memcpy(&memberAddr.addr[0], &member.id, sizeof(int));
memcpy(&memberAddr.addr[4], &member.port, sizeof(short));
sendMemberList("HEARTBEATREQ", HEARTBEATREQ, &memberAddr);
}
}
예제 #4
0
/**
 * FUNCTION NAME: nodeLoopOps
 *
 * DESCRIPTION: Check if any node hasn't responded within a timeout period and then delete
 * 				the nodes
 * 				Propagate your membership list
 */
void MP1Node::nodeLoopOps() {

	/*
	 * Your code goes here
	 */
    vector<MemberListEntry>::iterator myPos;

    //Check and remove node older than TREMOVE
    for (myPos = memberNode->memberList.begin();
        myPos != memberNode->memberList.end();
        ++myPos) {
            
            if (myPos->gettimestamp() < par->getcurrtime() - TREMOVE) {
            	// Older than TREMOVE -- Remove from memberlist and send FAIL message to other nodes
            	Address a = AddrUtils::initAddress(myPos->getid(), myPos->getport());
               	removeMember(myPos);
               	sendFAILNotification(&a);
            	myPos = memberNode->memberList.begin(); //reset iterator
            } 
        }
    
    //Gossip every TGOSSIP to PGOSSIPNODES
    
    if (par->getcurrtime() % TGOSSIP == 0 ) {
        int k = 0, n = 0;
        while (k < PGOSSIPNODES) {
                n = rand()%memberNode->memberList.size() ;
  
                Address a = AddrUtils::initAddress((*memberNode).memberList[n].getid(), 
					memberNode->memberList[n].getport());
#ifdef DEBUGLOG
                stringstream out;
                string s = a.getAddress();
                out << "Gossip ml to: " << s;
                log->LOG(&memberNode->addr, (char*) out.str().c_str());
#endif

                sendMemberList(&a, GOSSIP);

                k++;
        }
    }
    
    return;
}
예제 #5
0
bool MP1Node::recvJoinReq(void *env, char *data, int size) {//kiem tra kich thuoc goi tin co hop le
    if (size < (int)(sizeof(memberNode->addr.addr) + sizeof(long))) {
#ifdef DEBUGLOG
        log->LOG(&memberNode->addr, "Message JOINREQ received with wrong size. Ignored.");
#endif
        return false;
    }

    Address joinaddr;
    long heartbeat;

    memcpy(joinaddr.addr, data, sizeof(memberNode->addr.addr));
    memcpy(&heartbeat, data + sizeof(memberNode->addr.addr), sizeof(long));
    int id = *(int*)(&joinaddr.addr);
    int port = *(short*)(&joinaddr.addr[4]);

    updateMember(id, port, heartbeat);

    sendMemberList("JOINREP", JOINREP, &joinaddr);
    return true;
}