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