Example #1
0
void
ReliableSession::expire_naks()
{
  if (this->nak_requests_.empty()) return; // nothing to expire

  ACE_Time_Value deadline(ACE_OS::gettimeofday());
  deadline -= this->link_->config()->nak_timeout_;

  NakRequestMap::iterator first(this->nak_requests_.begin());
  NakRequestMap::iterator last(this->nak_requests_.upper_bound(deadline));

  if (first == last) return; // nothing to expire

  // Skip unrecoverable datagrams to
  // re-establish a baseline to detect future reception gaps.
  SequenceNumber lastSeq;
  if (last == this->nak_requests_.end()) {
    lastSeq = this->nak_requests_.rbegin()->second;
  }
  else {
    lastSeq = last->second;
  }

  if (lastSeq > this->nak_sequence_.low ()) {
    ACE_ERROR((LM_WARNING,
                ACE_TEXT("(%P|%t) WARNING: ")
                ACE_TEXT("ReliableSession::expire_naks: ")
                ACE_TEXT("timed out waiting on remote peer %d to send missing samples: %d - %d!\n"),
                this->remote_peer_, this->nak_sequence_.low ().getValue(), lastSeq.getValue()));
    this->nak_sequence_.shift(lastSeq);
  }

  // Clear expired repair requests:
  this->nak_requests_.erase(first, last);
}
void
ReliableSession::expire_naks()
{
  if (this->nak_requests_.empty()) return; // nothing to expire

  ACE_Time_Value deadline(ACE_OS::gettimeofday());
  deadline -= this->link_->config()->nak_timeout_;

  NakRequestMap::iterator first(this->nak_requests_.begin());
  NakRequestMap::iterator last(this->nak_requests_.upper_bound(deadline));

  if (first == last) return; // nothing to expire

  // Skip unrecoverable datagrams to
  // re-establish a baseline to detect future reception gaps.
  SequenceNumber lastSeq = (last == this->nak_requests_.end())
                         ? this->nak_requests_.rbegin()->second
                         : last->second;

  std::vector<SequenceRange> dropped;
  if (this->nak_sequence_.insert(SequenceRange(this->nak_sequence_.low(),
                                               lastSeq), dropped)) {

    for (size_t i = 0; i < dropped.size(); ++i) {
      this->reassembly_.data_unavailable(dropped[i]);
    }

    ACE_ERROR((LM_WARNING,
                ACE_TEXT("(%P|%t) WARNING: ")
                ACE_TEXT("ReliableSession::expire_naks: ")
                ACE_TEXT("timed out waiting on remote peer %#08x%08x to send missing samples: %q - %q!\n"),
                (unsigned int)(this->remote_peer_ >> 32),
                (unsigned int) this->remote_peer_,
                this->nak_sequence_.low().getValue(),
                lastSeq.getValue()));
  }

  // Clear expired repair requests:
  this->nak_requests_.erase(first, last);
  deliver_held_data();
}
Example #3
0
    void Ask(const TRequest& request, TReply& reply) const
    {
        CNcbiOstream& job_in = m_Grid_cli->GetOStream(); // job input stream
        auto_ptr<CObjectOStream> outstr(TConnectTraits::GetOStream(job_in));
        *outstr << request;
        if (job_in.bad()) {
            NCBI_THROW(CIOException, eWrite, "Error while writing request");
        }
        outstr.reset();
        m_Grid_cli->CloseStream();

        CNetScheduleJob& job = m_Grid_cli->GetJob();

        CDeadline deadline(m_Timeout, 0);

        CNetScheduleNotificationHandler submit_job_handler;
        submit_job_handler.SubmitJob(m_NS_api.GetSubmitter(),
                                     job,
                                     m_Timeout
                                    );
        LOG_POST(Trace << "job: " << job.job_id);

        CNetScheduleAPI::EJobStatus status(
            submit_job_handler.WaitForJobCompletion(job, deadline, m_NS_api)
        );

        // TODO The wait is over; the current job status is in the status
        // variable. CNetScheduleAPI::StatusToString(status) can convert it
        // to a human-readable string.
        if (status == CNetScheduleAPI::eDone) {
            // TODO The job has completed successfully.
            CStringOrBlobStorageReader reader(job.output, m_NC_api);
            CRStream rstr(&reader);
            auto_ptr<CObjectIStream> instr(TConnectTraits::GetIStream(rstr));
            *instr >> reply;
        }
Example #4
0
EIO_Status CConnTest::ExtraCheckOnFailure(void)
{
    static const STimeout kTimeout   = { 5,      0 };
    static const STimeout kTimeSlice = { 0, 100000 };
    static const struct {
        const char*  host;
        const char* vhost;
    } kTests[] = {
        // 0. NCBI default
        { "",                           0                      }, // NCBI
        // 1. External server(s)
        { "www.google.com",             0                      },
        //    NB: Google's public DNS (also @8.8.8.8), responds at :80 as well
        { "8.8.4.4",                    "www.google.com"       },
        // 2. NCBI servers, explicitly
        { "www.be-md.ncbi.nlm.nih.gov", "www.ncbi.nlm.nih.gov" }, // NCBI main
        { "www.st-va.ncbi.nlm.nih.gov", "www.ncbi.nlm.nih.gov" }, // NCBI colo
        { "130.14.29.110",              "www.ncbi.nlm.nih.gov" }, // NCBI main
        { "165.112.7.20",               "www.ncbi.nlm.nih.gov" }  // NCBI colo
    };

    m_CheckPoint.clear();
    PreCheck(eNone, 0/*main*/, "Failback HTTP access check");

    SConnNetInfo* net_info = ConnNetInfo_Create(0, eDebugPrintout_Data);
    if (!net_info) {
        PostCheck(eNone, 0/*main*/,
                  eIO_Unknown, "Cannot create network info structure");
        return eIO_Unknown;
    }

    net_info->req_method = eReqMethod_Head;
    net_info->timeout    = &kTimeout;
    net_info->max_try    = 0;
    m_Timeout = 0;

    CDeadline deadline(kTimeout.sec, kTimeout.usec * 1000);
    time_t           sec;
    unsigned int nanosec;
    deadline.GetExpirationTime(&sec, &nanosec);
    ::sprintf(net_info->path, "/NcbiTest%08lX%08lX",
              (unsigned long) sec, (unsigned long) nanosec);

    vector< AutoPtr<CConn_HttpStream> > http;
    for (size_t n = 0;  n < sizeof(kTests) / sizeof(kTests[0]);  ++n) {
        char user_header[80];
        _ASSERT(::strlen(kTests[n].host) < sizeof(net_info->host) - 1);
        if (kTests[n].host[0])
            ::strcpy(net_info->host, kTests[n].host);
        if (kTests[n].vhost) {
            _ASSERT(::strlen(kTests[n].vhost) + 6 < sizeof(user_header) - 1);
            ::sprintf(user_header, "Host: %s", kTests[n].vhost);
        } else
            *user_header = '\0';
        SAuxData* auxdata = new SAuxData(m_Canceled, 0);
        http.push_back(new CConn_HttpStream(net_info, user_header, s_AnyHeader,
                                            auxdata, s_Adjust, s_Cleanup));
        http.back()->SetCanceledCallback(m_Canceled);
    }

    EIO_Status status = eIO_Success;
    do {
        if (!http.size())
            break;
        ERASE_ITERATE(vector< AutoPtr<CConn_HttpStream> >, h, http) {
            CONN conn = (*h)->GetCONN();
            if (!conn) {
                VECTOR_ERASE(h, http);
                if (status == eIO_Success)
                    status  = eIO_Unknown;
                continue;
            }
            EIO_Status readst = CONN_Wait(conn, eIO_Read, &kTimeSlice);
            if (readst > eIO_Timeout) {
                if (readst == eIO_Interrupt) {
                    status  = eIO_Interrupt;
                    break;
                }
                if (status < readst  &&  (*h)->GetStatusCode() != 404)
                    status = readst;
                VECTOR_ERASE(h, http);
                continue;
            }
        }
    } while (status != eIO_Interrupt  &&  !deadline.IsExpired());

    if (status == eIO_Success  &&  http.size())
        status  = eIO_Timeout;

    PostCheck(eNone, 0/*main*/, status, kEmptyStr);

    return status;
}
Example #5
0
int main(int argc, char **argv) {

	int fd_tcp, fd_ecp, newfd, clientlen, serverlen, ret, questionnaire_number, nbytes, nleft, size, score=0;
	
	struct sockaddr_in serveraddr, clientaddr;
	struct hostent *hostptr;
	
	unsigned short int TESport = TES_PORT, ECPport = ECP_PORT;
	
	ssize_t rcvd_bytes, send_bytes, read_file_bytes, send_bytes_data, AQT_bytes, AQS_bytes;

	char *SID, *QID, dtime[18+1], *data, filename[12+1], *correctanswers, *ptr1, ECPname[MAX_BUF], recv_str[MAX_BUF], send_str[MAX_BUF];
		 SID = (char*)malloc(sizeof(char) * (5 + 1));
		 QID = (char*)malloc(sizeof(char) * (23 + 1));
		 
		 
	char usage[] = "usage: ./TES [-p TESport] [-n ECPname] [-e ECPport]";

	time_t rawtime;
  	struct tm * current_time;
  	time (&rawtime);
  	current_time = localtime (&rawtime);
 	
	pid_t pid;
	void(*old_handler)(int);//interrupt handler

							/* Avoid zombies when child processes die. */
	if ((old_handler = signal(SIGCHLD, SIG_IGN)) == SIG_ERR) exit(1);
	
	if (signal(SIGALRM, handler_alrm) == SIG_ERR) { 
		perror("Error in signal");
		exit(1); 
	}
	

	if (argc % 2 != 1 || argc > 7) {
		printf("error: Incorrect number of arguments.\n%s\n", usage);
		return 1;
	}

	if (argc == 3) {
		if (!strcmp(argv[1], "-p")) TESport = atoi(argv[2]);
		else if (!strcmp(argv[1], "-n")) strcpy(ECPname, argv[2]);
		else if (!strcmp(argv[1], "-e")) ECPport = atoi(argv[2]);
		else {
			printf("error: Invalid option.\n%s\n", usage);
			return 1;
		}
	}

	if (argc == 5) {
		if (!strcmp(argv[1], "-p")) {
			TESport = atoi(argv[2]);
			if (!strcmp(argv[3], "-n")) strcpy(ECPname, argv[4]);
			else if (!strcmp(argv[3], "-e")) ECPport = atoi(argv[4]);
			else {
				printf("error: Invalid option.\n%s\n", usage);
				return 1;
			}
		}
		if (!strcmp(argv[1], "-n")) {
			strcpy(ECPname, argv[2]);
			if (!strcmp(argv[3], "-e")) ECPport = atoi(argv[4]);
			else {
				printf("error: Invalid option.\n%s\n", usage);
				return 1;
			}
		}
		else {
			printf("error: Invalid option.\n%s\n", usage);
			return 1;
		}
	}

	if (argc == 7) {
		if (!strcmp(argv[1], "-p")) {
			TESport = atoi(argv[2]);
			if (!strcmp(argv[3], "-n")) {
				strcpy(ECPname, argv[4]);
				if (!strcmp(argv[1], "-e")) ECPport = atoi(argv[2]);
				else {
					printf("error: Invalid option.\n%s\n", usage);
					return 1;
				}
			}else {
				printf("error: Invalid option.\n%s\n", usage);
				return 1;
			}
		}else {
			printf("error: Invalid option.\n%s\n", usage);
			return 1;
		}
	}


	if ((fd_tcp = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
		perror("Error creating tcp socket.\n");
		exit(1);
	}
	if ((fd_ecp = socket(AF_INET, SOCK_DGRAM, 0)) == -1){
		perror("Error creating ecp socket.\n");
		exit(1);
	}
	memset((void*)&serveraddr, (int)'\0', sizeof(serveraddr));
	serveraddr.sin_family = AF_INET;
	serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
	serveraddr.sin_port = htons((u_short)TESport);
	if (bind(fd_tcp, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) == -1) {
		perror("Error: bind().\n");
		exit(1);
	}
	if (listen(fd_tcp, 5) == -1){
		perror("Error: listen().\n");
		exit(1);
	}

	while (1) {

		clientlen = sizeof(clientaddr);

		do newfd = accept(fd_tcp, (struct sockaddr*)&clientaddr, &clientlen);//wait for a connection
		while (newfd == -1 && errno == EINTR);
		if (newfd == -1){
			perror("Error: accept().\n");
			exit(1);
		}

								/* Create a child process for each new connection. */
		if ((pid = fork()) == -1) {
			perror("Error: fork().\n");
			exit(1);
		}
		else if (pid == 0) { //child process
			close(fd_tcp);
			printf("Sent by [%s :%hu]\n",inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port));
									
								/* USER-TES Protocol (in TCP) */
		
			ptr1 = readTCPclient(newfd);
			printf("\nReceived message:«%s»\n", ptr1);
		
			//we can use parseString() from functions.c...
			char* arr[8];
			char * ch;
			ch = strtok(strdup(ptr1), " ");
			int i = 0;
			while (ch != NULL) {
				arr[i] = ch;
				i++;
				ch = strtok(NULL, " ");
			}

			/* USER-TES: RQT SID
			TES-USER: AQT QID time size data */

			if (strcmp(arr[0], "RQT") == 0 && atoi(arr[1]) < 100000 && atoi(arr[1]) > 9999) {
				
				strcpy(SID, arr[1]);
			
				questionnaire_number = rand() % (NUM_OF_FILES + 1);//choose randomly 1 of available questionnaires
				sprintf(filename, "T%dQF%d.pdf", TES_NUMBER, questionnaire_number);
				
				sprintf(dtime, "%s",timeformat(deadline(current_time)));
				//generate QID: TES_NUMBER+questionnaire_number+deadline
				sprintf(QID, "%d_%d_%s",  TES_NUMBER, questionnaire_number, timeformat1(deadline(current_time))); 

				FILE *handler = fopen(filename, "rb");
				if (handler == NULL){
					perror("Error: fopen().\n");
					exit(1);
				}

				fseek(handler, 0, SEEK_END);
				size = ftell(handler);
				rewind(handler);

				//allocate a string that can hold it all
				data = (char*)malloc(sizeof(char) * (size + 1));
				//read it all in one operation
				read_file_bytes = fread(data, sizeof(char), size, handler);

				if (size != read_file_bytes) {
					free(data);
					perror("Error: fread().\n");
					exit(1);
				}

				//each message ends with the character '\n'
				AQT_bytes = sprintf(send_str, "AQT %s %s %d ", QID, dtime, size);

				ptr1 = send_str;

				/* write() may write a smaller number of bytes than solicited */
				nleft = AQT_bytes + read_file_bytes; // '\0' is not transmitted

				while (nleft > 0) {
					if (nleft > read_file_bytes) {
						send_bytes = write(newfd, ptr1, AQT_bytes);
						if (send_bytes <= 0) {
							perror("Error: write().\n");
							exit(1);
						}
						nleft -= send_bytes;
						ptr1 += send_bytes;
					}
					else {
						send_bytes_data = write(newfd, data, nleft);
						if (send_bytes_data <= 0) {
							perror("Error: data write().\n");
							exit(1);
						}
						nleft -= send_bytes_data;
						data += send_bytes_data;
					}
					
				}
				send_bytes_data = write(newfd, "\n", 1);
				if (send_bytes_data <= 0) {
					perror("Error: data write().\n");
					exit(1);
				}

				close (newfd); exit(0);
			}
			
			else if (strcmp(arr[0], "RQS") == 0 ) {
			  	
			  if (atoi(arr[1]) > 99999 ||  atoi(arr[1]) < 10000 || sizeof(arr[2]) > 24){
				  if ((send_bytes = write(newfd, "-2\n", 4)) <= 0)exit(1);
				  close(newfd); exit(1);
			  }
			  
			  strcpy(SID, arr[1]);
			  strcpy(QID, arr[2]);
			
			   if (checkdeadline(arr[2],current_time) == -1){
				  if ((send_bytes = write(newfd, "-1\n", 4)) <= 0)exit(1);
				  close(newfd); exit(1);
				  }
			  
			  
			  for (i = 0; i < 5; i++) {	  
				  if (strcmp(arr[i + 3], "A") == 0 ||
					  strcmp(arr[i + 3], "B") == 0 ||
					  strcmp(arr[i + 3], "C") == 0 ||
					  strcmp(arr[i + 3], "D") == 0 ||
					  strcmp(arr[i + 3], "N") == 0)continue;
				  else {
					  printf("\n----->invalid answers\n");
					  if ((send_bytes = write(newfd, "ERR\n", ERR_SIZE)) <= 0)exit(1);
				  }
			  }
			  
			  FILE *a = fopen(giveanswersfilename(QID), "r");
			  if (a == NULL) {
				  perror("Error: fopen().\n");
				  exit(1);
			  }
			  fseek(a, 0, SEEK_END);
			  size = ftell(a);
			  rewind(a);


			  //allocate a string that can hold it all
			  correctanswers = (char*)malloc(sizeof(char) * (size));
			  //read it all in one operation
			  if (fread(correctanswers, sizeof(char), size, a) <= 0) {
				  perror("Error: fread().\n");
				  exit(1);
			  }
			  

			  for (i = 0; i < 5; i++) {
				  if (*correctanswers == arr[i + 3][0]) {
					  score += 20;
					  correctanswers+=3;
				  }
			  }
			  
			  AQS_bytes = sprintf(send_str, "AQS %s %d\n", QID, score);


			  ptr1 = send_str;
			  nbytes = AQS_bytes; // '\0' is not transmitted

			  /* write() may write a smaller number of bytes than solicited */
			  nleft = nbytes;
			  while (nleft > 0) {
				  send_bytes = write(newfd, ptr1, nleft);
				  if (send_bytes <= 0) exit(1); //error
				  nleft -= send_bytes;
				  ptr1 += send_bytes;
			  }
			  printf("TEST AQS sent : «%s»", send_str);
			  close(newfd);
			  
			  /* TES-ECP Protocol (in UDP) */
				
			  memset((void*)&serveraddr, (int)'\0', sizeof(serveraddr));
			  serveraddr.sin_family = AF_INET;
			 if ((hostptr = gethostbyname(ECPname)) == NULL) exit(1);
				printf("%s", ECPname);
			 serveraddr.sin_addr.s_addr = ((struct in_addr*)(hostptr->h_addr_list[0]))->s_addr; //ECP server IP address
			 printf("%s", hostptr->h_name);
			  serveraddr.sin_port = htons((u_short)ECPport);
			 
			  serverlen = sizeof(serveraddr);

			  /* TES-ECP: IQR SID QID topic_name score
			  ECP-TES: AWI QID */

			  sprintf(send_str, "IQR %s %s %s %d\n", SID, QID, TOPIC_NAME, score);
				printf("%s\n",send_str);

			  send_bytes = sendto(fd_ecp, send_str, strlen(send_str), 0, (struct sockaddr*)&serveraddr, serverlen);
			  if (send_bytes == -1)exit(1);//error
			 
			  alarm(10);//generates the SIGALRM signal when the specified time has expired

			  rcvd_bytes = recvfrom(fd_ecp, recv_str, strlen(recv_str), 0, (struct sockaddr*)&clientaddr, &clientlen);
			  if (rcvd_bytes == -1)exit(1);//error
			 else alarm(0); //cancel currently active alarm

			  char *array[8];
			  char *c = strtok(recv_str, " ");
			  int j = 0;
			  while (c != NULL) {
				  array[j] = c;
				  j++;
				  c = strtok(NULL, " ");
			  }
			  if (strcmp(array[0], "AWI") == 0 && strcmp(array[1], QID) == 0) {
				  close(fd_ecp);
				  exit(0);
			  }
			
			  else {
				  send_bytes = sendto(fd_ecp, "ERR\n", ERR_SIZE, 0, (struct sockaddr*)&serveraddr, serverlen);
				  if (send_bytes == -1)exit(1);//error
				  exit(1);
			  }
		    }
		      
		      else {
			printf("\n----->invalid answers\n");
			send_bytes = write(newfd, "ERR\n", ERR_SIZE);
			if (send_bytes <= 0)exit(1);
				close(newfd); exit(1);
		     }
			
		}
		
		//parent process
		do ret = close(newfd);
		while (ret == -1 && errno == EINTR);
		if (ret == -1)exit(1);//error
	}
}
Example #6
0
void logger::run()
{
    utxx::signal_block block_signals(m_block_signals);

    if (m_on_before_run)
        m_on_before_run();

    if (!m_ident.empty())
        pthread_setname_np(pthread_self(), m_ident.c_str());

    int event_val;
    do
    {
        event_val = m_event.value();
        //wakeup_result rc = wakeup_result::TIMEDOUT;

        while (!m_abort && m_queue.empty()) {
            m_event.wait(&m_wait_timeout, &event_val);

            ASYNC_DEBUG_TRACE(
                ("  %s LOGGER awakened (res=%s, val=%d, futex=%d), abort=%d, head=%s\n",
                 timestamp::to_string().c_str(), to_string(rc).c_str(),
                 event_val, m_event.value(), m_abort,
                 m_queue.empty() ? "empty" : "data")
            );
        }

        // When running with maximum priority, occasionally excessive use of
        // sched_yield may use to system slowdown, so this option is
        // configurable by m_sched_yield_us:
        if (m_queue.empty() && m_sched_yield_us >= 0) {
            time_val deadline(rel_time(0, m_sched_yield_us));
            while (m_queue.empty()) {
                if (m_abort)
                    goto DONE;
                if (now_utc() > deadline)
                    break;
                sched_yield();
            }
        }

        // Get all pending items from the queue
        for (auto* item = m_queue.pop_all(), *next=item; item; item = next) {
            next = item->next();

            try   {
                dolog_msg(item->data());
            }
            catch ( std::exception const& e  )
            {
                // Unhandled error writing data to some destination
                // Print error report to stderr (can't do anything better --
                // the error happened in the m_on_error callback!)
                const msg msg(LEVEL_INFO, "",
                              std::string("Fatal exception in logger"),
                              UTXX_LOG_SRCINFO);
                detail::basic_buffered_print<1024> buf;
                char  pfx[256], sfx[256];
                char* p = format_header(msg, pfx, pfx + sizeof(pfx));
                char* q = format_footer(msg, sfx, sfx + sizeof(sfx));
                auto ps = p - pfx;
                auto qs = q - sfx;
                buf.reserve(msg.m_fun.str.size() + ps + qs + 1);
                buf.sprint(pfx, ps);
                buf.print(msg.m_fun.str);
                buf.sprint(sfx, qs);
                std::cerr << buf.str() << std::endl;

                m_abort = true;

                // TODO: implement attempt to store transient messages to some
                // other medium

                // Free all pending messages
                while (item) {
                    m_queue.free(item);
                    item = next;
                    next = item->next();
                }

                goto DONE;
            }

            m_queue.free(item);
            item = next;
        }
    } while (!m_abort);

DONE:
    if (!m_silent_finish) {
        const msg msg(LEVEL_INFO, "", std::string("Logger thread finished"),
                      UTXX_LOG_SRCINFO);
        try {
            dolog_msg(msg);
        }
        catch (...) {}
    }

    if (m_on_after_run)
        m_on_after_run();
}