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