void
PendingEnvelopes::discardSCPEnvelope(SCPEnvelope const& envelope)
{
    try
    {
        if (isDiscarded(envelope))
        {
            return;
        }

        auto& discardedSet =
            mEnvelopes[envelope.statement.slotIndex].mDiscardedEnvelopes;
        discardedSet.insert(envelope);

        auto& fetchingSet =
            mEnvelopes[envelope.statement.slotIndex].mFetchingEnvelopes;
        fetchingSet.erase(envelope);

        stopFetch(envelope);
    }
    catch (xdr::xdr_runtime_error& e)
    {
        CLOG(TRACE, "Herder")
            << "PendingEnvelopes::discardSCPEnvelope got corrupt message: "
            << e.what();
    }
}
// called from Peer and when an Item tracker completes
Herder::EnvelopeStatus
PendingEnvelopes::recvSCPEnvelope(SCPEnvelope const& envelope)
{
    auto const& nodeID = envelope.statement.nodeID;
    if (!isNodeInQuorum(nodeID))
    {
        CLOG(DEBUG, "Herder")
            << "Dropping envelope from "
            << mApp.getConfig().toShortString(nodeID) << " (not in quorum)";
        return Herder::ENVELOPE_STATUS_DISCARDED;
    }

    // did we discard this envelope?
    // do we already have this envelope?
    // do we have the qset
    // do we have the txset

    try
    {
        if (isDiscarded(envelope))
        {
            return Herder::ENVELOPE_STATUS_DISCARDED;
        }

        touchFetchCache(envelope);

        auto& set = mEnvelopes[envelope.statement.slotIndex].mFetchingEnvelopes;
        auto& processedList =
            mEnvelopes[envelope.statement.slotIndex].mProcessedEnvelopes;

        auto fetching = find(set.begin(), set.end(), envelope);

        if (fetching == set.end())
        { // we aren't fetching this envelope
            if (find(processedList.begin(), processedList.end(), envelope) ==
                processedList.end())
            { // we haven't seen this envelope before
                // insert it into the fetching set
                fetching = set.insert(envelope).first;
                startFetch(envelope);
            }
            else
            {
                // we already have this one
                return Herder::ENVELOPE_STATUS_PROCESSED;
            }
        }

        // we are fetching this envelope
        // check if we are done fetching it
        if (isFullyFetched(envelope))
        {
            // move the item from fetching to processed
            processedList.emplace_back(*fetching);
            set.erase(fetching);
            envelopeReady(envelope);
            return Herder::ENVELOPE_STATUS_READY;
        } // else just keep waiting for it to come in

        return Herder::ENVELOPE_STATUS_FETCHING;
    }
    catch (xdr::xdr_runtime_error& e)
    {
        CLOG(TRACE, "Herder")
            << "PendingEnvelopes::recvSCPEnvelope got corrupt message: "
            << e.what();
        return Herder::ENVELOPE_STATUS_DISCARDED;
    }
}
Example #3
0
void serviceListener(port){
	
	pthread_t thread;
	int sockfd,n,i,rc;
	struct sockaddr_in servaddr,cliaddr;
	socklen_t len;
	unsigned char buffer[500];
	unsigned char response[500] ={0};
	unsigned char command[] = {0x50,0x32,0x50};
	unsigned char ping[] = {0x0a,0x00,0x00,0x00,0x14};
	char str[INET_ADDRSTRLEN];
	int redirectPort;
	int repPos;
	struct repeater repeaterInfo;
	sqlite3_stmt *stmt;
	unsigned char SQLQUERY[200] = {0};
	fd_set fdService;
	struct timeval timeout;
	time_t timeNow;

	syslog(LOG_NOTICE,"Listener for port %i started",port);

	//Create the socket to listen to the service port
	sockfd=socket(AF_INET,SOCK_DGRAM,0);
	bzero(&servaddr,sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
	servaddr.sin_port=htons(port);
	bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
	FD_ZERO(&fdService);
	
	for (;;){
		FD_SET(sockfd, &fdService);
		timeout.tv_sec = 2;
		timeout.tv_usec = 0;
		rc = select(sockfd+1, &fdService, NULL, NULL, &timeout);
		if (FD_ISSET(sockfd,&fdService)) {
			len = sizeof(cliaddr);
			memset(&buffer,0,500);
			n = recvfrom(sockfd,buffer,500,0,(struct sockaddr *)&cliaddr,&len);
			if (memcmp(buffer,command,sizeof(command)) == 0){  //See if what is received is a command or heartbeat
				inet_ntop(AF_INET, &(cliaddr.sin_addr), str, INET_ADDRSTRLEN);
				time(&timeNow);
				switch (buffer[20]){
					int rdacPos;
					case 0x10:{  //PTPP request received
					if(isDiscarded(cliaddr)) continue;
					rdacPos = setRdacRepeater(cliaddr);
					if (rdacPos == 99) continue; //too many repeaters
					if (difftime(timeNow,rdacList[rdacPos].lastPTPPConnect) < 10) continue;  //Ignore connect request
					syslog(LOG_NOTICE,"PTPP request from repeater [%s]",str);
					memcpy(response,buffer,n);
					//Assign device ID
					response[4]++;
					response[13]=0x01;
					response[n] = 0x01;
					sendto(sockfd,response,n+1,0,(struct sockaddr *)&cliaddr,sizeof(cliaddr));
					syslog(LOG_NOTICE,"Assigned PTPP device 1 to repeater [%s]",str);
					time(&rdacList[rdacPos].lastPTPPConnect);
					break;}
				
					case 0x11:{  //Request to startup DMR received
					int rdacPos;
					//See if the repeater is already known in the RDAC list
					if(isDiscarded(cliaddr)) continue;
					rdacPos = findRdacRepeater(cliaddr);
					if (difftime(timeNow,rdacList[rdacPos].lastDMRConnect) < 10) continue;  //Ignore connect request
					time(&rdacList[rdacPos].lastDMRConnect);
					syslog(LOG_NOTICE,"DMR request from repeater [%s]",str);
					if (rdacPos == 99){  //If  not ignore the DMR request
						syslog(LOG_NOTICE,"DMR request from repeater not in RDAC list [%s], ignoring",str);
						continue;
					}
					//See if RDAC info from the repeater has already been received
					if (!rdacList[rdacPos].id > 0){ //If not ignore DMR request
						syslog(LOG_NOTICE,"RDAC info not received from repeater yet [%s], ignoring",str);
						continue;
					}
					//Now that we have repeater info, initialize the repeater
					repPos = initRepeater(rdacList[rdacPos]);
					if (repPos == 99) continue;   //If 99 returned, more repeaters then allowed
					memcpy(response,buffer,n);
					//Assign device ID
					response[4]++;
					response[13]=0x01;
					response[n] = 0x01;
					//cliaddr.sin_port=htons(port);
					cliaddr.sin_port=rdacList[rdacPos].address.sin_port;
					sendto(sockfd,response,n+1,0,(struct sockaddr *)&cliaddr,sizeof(cliaddr));
					syslog(LOG_NOTICE,"Assigned DMR device 1 to repeater [%s - %s]",str,repeaterList[repPos].callsign);
					//Assign port number
					response[4] = 0x0b;
					unsigned char rep[] = {0x00,0xff,0x01,0x00};
					memcpy(response + 12,rep,4);
					unsigned char rport[] = {0xff,0x01,0x00,0x00};
					redirectPort = baseDmrPort + repPos; 
					rport[2] = redirectPort;
					rport[3] = redirectPort >> 8;
					memcpy(response + n,rport,4);
					if (repeaterList[repPos].dmrOnline){  //If repeater is not offline, but we still get a request, just point it back to old thread
						rdacList[repPos].rdacUpdateAttempts = 0;
						rdacList[repPos].rdacUpdated = false;
						syslog(LOG_NOTICE,"DMR request from repeater [%s - %s] already assigned a DMR port, not starting thread",str,repeaterList[repPos].callsign);
					}
					else{  //Start a new DMR thread for this repeater
						struct sockInfo *param = malloc(sizeof(struct sockInfo));
						param->address = cliaddr;
						param->port = redirectPort;
						pthread_create(&thread, NULL, dmrListener,param);
					}
					sendto(sockfd,response,n+4,0,(struct sockaddr *)&cliaddr,sizeof(cliaddr));
					syslog(LOG_NOTICE,"Re-directed repeater [%s - %s] to DMR port %i",str,repeaterList[repPos].callsign,redirectPort);
					break;}

					case 0x12:{  ////Request to startup RDAC received
					int rdacPos;
					//Initialize this repeater for RDAC
					if(isDiscarded(cliaddr)) continue;
					//rdacPos = setRdacRepeater(cliaddr);
					rdacPos = findRdacRepeater(cliaddr);
					cliaddr.sin_port=rdacList[rdacPos].address.sin_port;
					if (difftime(timeNow,rdacList[rdacPos].lastRDACConnect) < 10) continue;  //Ignore connect request
					syslog(LOG_NOTICE,"RDAC request from repeater [%s]",str);
					//if (rdacPos == 99) continue;   //If 99 returned, more repeaters then allowed
					if (rdacPos == 99){
						rdacPos = setRdacRepeater(cliaddr);
						cliaddr.sin_port=htons(port);
					}
					memcpy(response,buffer,n);
					//Assign device ID
					response[4]++;
					response[13]=0x01;
					response[n] = 0x01;
					//cliaddr.sin_port=htons(port);
					sendto(sockfd,response,n+1,0,(struct sockaddr *)&cliaddr,sizeof(cliaddr));
					syslog(LOG_NOTICE,"Assigned RDAC device 1 to repeater [%s]",str);
					//Assign port number
					response[4] = 0x0b;
					unsigned char rep[] = {0xff,0xff,0x01,0x00};
					memcpy(response + 12,rep,4);
					unsigned char port[] = {0xff,0x01,0x00,0x00};
					redirectPort = baseRdacPort + (rdacPos * 2);
					port[2] = redirectPort;
					port[3] = redirectPort >> 8;
					memcpy(response + n,port,4);
					if (rdacList[rdacPos].rdacOnline){  //If repeater is not offline, but we still get a request, just point it back to old thread
						syslog(LOG_NOTICE,"RDAC request from repeater [%s - %s] already assigned a RDAC port, not starting thread",str,rdacList[rdacPos].callsign);
						rdacList[rdacPos].rdacUpdateAttempts = 0;
					}
					else{  //Start a new RDAC thread for this repeater
						struct sockInfo *param = malloc(sizeof(struct sockInfo));
						param->address = cliaddr;
						param->port = redirectPort;
						pthread_create(&thread, NULL, rdacListener,param);
					}
					sendto(sockfd,response,n+4,0,(struct sockaddr *)&cliaddr,sizeof(cliaddr));
					syslog(LOG_NOTICE,"Re-directed repeater [%s] to RDAC port %i",str,redirectPort);
					time(&rdacList[rdacPos].lastRDACConnect);
					break;}

				}
			}
		
			if ((memcmp(buffer+4,ping,sizeof(ping)) == 0) && repeaterList[findRepeater(cliaddr)].dmrOnline){//Is this a heartbeat from a repeater on the service port ? And do we know the repeater ?
				memcpy(response,buffer,n);
				response[12]++;
				sendto(sockfd,response,n,0,(struct sockaddr *)&cliaddr,sizeof(cliaddr));
			}
		}