예제 #1
0
void *pingUnknownAgents(void *args) {
    
    AgentList* agentList = (AgentList*) args;
    const int PING_INTERVAL_USECS = 1 * 1000000;
    
    timeval lastSend;
    
    while (!pingUnknownAgentThreadStopFlag) {
        gettimeofday(&lastSend, NULL);
        
        for(AgentList::iterator agent = agentList->begin();
            agent != agentList->end();
            agent++) {
            if (!agent->getActiveSocket() && agent->getPublicSocket() && agent->getLocalSocket()) {
                // ping both of the sockets for the agent so we can figure out
                // which socket we can use
                agentList->getAgentSocket()->send(agent->getPublicSocket(), &PACKET_HEADER_PING, 1);
                agentList->getAgentSocket()->send(agent->getLocalSocket(), &PACKET_HEADER_PING, 1);
            }
        }
        
        long long usecToSleep = PING_INTERVAL_USECS - (usecTimestampNow() - usecTimestamp(&lastSend));
        
        if (usecToSleep > 0) {
            usleep(usecToSleep);
        }
    }
    
    return NULL;
}
예제 #2
0
int main(int argc, const char * argv[])
{
	// If user asks to run in "local" mode then we do NOT replace the IP
	// with the EC2 IP. Otherwise, we will replace the IP like we used to
	// this allows developers to run a local domain without recompiling the
	// domain server
	bool useLocal = cmdOptionExists(argc, argv, "--local");
	if (useLocal) {
		printf("NOTE: Running in Local Mode!\n");
	} else {
		printf("--------------------------------------------------\n");
		printf("NOTE: Running in EC2 Mode. \n");
		printf("If you're a developer testing a local system, you\n");
		printf("probably want to include --local on command line.\n");
		printf("--------------------------------------------------\n");
	}

    setvbuf(stdout, NULL, _IOLBF, 0);
    
    ssize_t receivedBytes = 0;
    char agentType;
    
    unsigned char *broadcastPacket = new unsigned char[MAX_PACKET_SIZE];
    *broadcastPacket = 'D';
    
    unsigned char *currentBufferPos;
    unsigned char *startPointer;
    int packetBytesWithoutLeadingChar;
    
    sockaddr_in agentPublicAddress, agentLocalAddress;
    agentLocalAddress.sin_family = AF_INET;
    
    in_addr_t serverLocalAddress = getLocalAddress();
    
    agentList.startSilentAgentRemovalThread();
    
    while (true) {
        if (agentList.getAgentSocket().receive((sockaddr *)&agentPublicAddress, packetData, &receivedBytes)) {
            std::map<char, Agent *> newestSoloAgents;
            
            agentType = packetData[0];
            unpackSocket(&packetData[1], (sockaddr *)&agentLocalAddress);
            
            // check the agent public address
            // if it matches our local address we're on the same box
            // so hardcode the EC2 public address for now
            if (agentPublicAddress.sin_addr.s_addr == serverLocalAddress) {
            	// If we're not running "local" then we do replace the IP
            	// with the EC2 IP. Otherwise, we use our normal public IP
            	if (!useLocal) {
	                agentPublicAddress.sin_addr.s_addr = 895283510; // local IP in this format...
	            }
            }
            
            if (agentList.addOrUpdateAgent((sockaddr *)&agentPublicAddress,
                                           (sockaddr *)&agentLocalAddress,
                                           agentType,
                                           agentList.getLastAgentId())) {
                
                agentList.increaseAgentId();
            
            }
            
            currentBufferPos = broadcastPacket + 1;
            startPointer = currentBufferPos;
            
            for(std::vector<Agent>::iterator agent = agentList.getAgents().begin(); agent != agentList.getAgents().end(); agent++) {
                
                if (DEBUG_TO_SELF || !agent->matches((sockaddr *)&agentPublicAddress, (sockaddr *)&agentLocalAddress, agentType)) {
                    if (strchr(SOLO_AGENT_TYPES_STRING, (int) agent->getType()) == NULL) {
                        // this is an agent of which there can be multiple, just add them to the packet
                        currentBufferPos = addAgentToBroadcastPacket(currentBufferPos, &(*agent));
                    } else {
                        // solo agent, we need to only send newest
                        if (newestSoloAgents[agent->getType()] == NULL ||
                            newestSoloAgents[agent->getType()]->getFirstRecvTimeUsecs() < agent->getFirstRecvTimeUsecs()) {
                            // we have to set the newer solo agent to add it to the broadcast later
                            newestSoloAgents[agent->getType()] = &(*agent);
                        }
                    }
                } else {
                    // this is the agent, just update last receive to now
                    agent->setLastRecvTimeUsecs(usecTimestampNow());
                }
            }
            
            for (std::map<char, Agent *>::iterator agentIterator = newestSoloAgents.begin();
                 agentIterator != newestSoloAgents.end();
                 agentIterator++) {
                // this is the newest alive solo agent, add them to the packet
                currentBufferPos = addAgentToBroadcastPacket(currentBufferPos, agentIterator->second);
            }
            
            if ((packetBytesWithoutLeadingChar = (currentBufferPos - startPointer))) {
                agentList.getAgentSocket().send((sockaddr *)&agentPublicAddress, broadcastPacket, packetBytesWithoutLeadingChar + 1);
            }
        }
    }

    return 0;
}