Esempio n. 1
0
ProcessorData *init_processor(TableStateMachine *machine, pcap_t *pcap_in, pcap_t *pcap_out, int linkHdrLen, int num_workers, int no_report, int batch) {
	int i;
	ProcessorData *processor;

	processor = (ProcessorData*)malloc(sizeof(ProcessorData));

	processor->counter = 0;
	processor->machine = machine;
	processor->pcap_in = pcap_in;
	processor->pcap_out = pcap_out;
	processor->linkHdrLen = linkHdrLen;
	processor->no_report = no_report;
	processor->terminated = 0;
	processor->next_queue = 0;
	processor->batch_mode = batch;

	processor->num_workers = num_workers;
	for (i = 0; i < num_workers; i++) {
		packet_buffer_init(&(processor->queues[i]));
		processor->started[i] = 0;
		processor->bytes[i] = 0;
		processor->total_reports[i] = 0;
		processor->workerData[i].id = i;
		processor->workerData[i].processor = processor;
		processor->workerData[i].queue = &(processor->queues[i]);
#ifdef __linux__
		CPU_ZERO(&(processor->workerData[i].cpuset));
		CPU_SET(i, &(processor->workerData[i].cpuset));
		pthread_attr_init(&(processor->workerData[i].attr));
		pthread_attr_setaffinity_np(&(processor->workerData[i].attr), sizeof(cpu_set_t), &(processor->workerData[i].cpuset));
		pthread_attr_setscope(&(processor->workerData[i].attr), PTHREAD_SCOPE_SYSTEM);
		pthread_create(&(processor->workers[i]), &(processor->workerData[i].attr), worker_start, &(processor->workerData[i]));
#else
		pthread_create(&(processor->workers[i]), NULL, worker_start, &(processor->workerData[i]));
#endif
	}

	return processor;
}
Esempio n. 2
0
int main(int argc, char *argv[]) {
  int sockfd_snd, sockfd_rcv_sender, sockfd_rcv_monitor, sockfd_monitor=-1;
  struct sockaddr_in my_addr;   // my address information
  struct sockaddr_in their_addr; // connector's address information
  fd_set read_fds_copy, write_fds_copy;
  socklen_t sin_size;
  struct timeval start_tv, left_tv;
  int yes=1;//, flag_send_monitor=0;
  struct timeval packet_deadline;
  struct in_addr addr;
  int flag_measure=0;
  char ch;
  unsigned short standalone_port = SENDER_PORT;
  // Do we use live data? Or previously recorded data?
  FILE * logfile = NULL;
  unsigned long quantum_no=0;
  int logflags = LOG_NOTHING;
  int select_count = 0;

  gettimeofday(&packet_deadline, NULL);

  init();

  //set up debug flag
  if (getenv("Debug")!=NULL)
    flag_debug=1;
  else
    flag_debug=0;
  flag_standalone = 0;

  /*
   * Process command-line arguments
   */
  while ((ch = getopt(argc,argv,"df:l:b:rst")) != -1) {
    switch (ch) {
      case 'd':
        flag_debug = 1; break;
      case 'f':
        if (logfile == NULL)
        {
          logfile = fopen(optarg, "a");
          if (logfile == NULL)
          {
            perror("Log fopen()");
            exit(1);
          }
        }
        break;
      case 'b':
        if (strcmp(optarg, "average") == 0)
        {
          bandwidth_method = BANDWIDTH_AVERAGE;
        } else if (strcmp(optarg, "max") == 0) {
          bandwidth_method = BANDWIDTH_MAX;
        } else if (strcmp(optarg, "vegas") == 0) {
          bandwidth_method = BANDWIDTH_VEGAS;
        } else if (strcmp(optarg, "buffer") == 0) {
          bandwidth_method = BANDWIDTH_BUFFER;
        } else {
          fprintf(stderr, "Unknown bandwidth method\n");
          usage();
          exit(1);
        }
        break;
      case 'l':
        if (strcmp(optarg, "everything") == 0)
        {
          logflags = LOG_EVERYTHING;
        }
        else if (strcmp(optarg, "nothing") == 0)
        {
          logflags = LOG_NOTHING;
        }
        else if (strcmp(optarg, "control-send") == 0)
        {
          logflags = logflags | CONTROL_SEND;
        }
        else if (strcmp(optarg, "control-receive") == 0)
        {
          logflags = logflags | CONTROL_RECEIVE;
        }
        else if (strcmp(optarg, "tcptrace-send") == 0)
        {
          logflags = logflags | TCPTRACE_SEND;
        }
        else if (strcmp(optarg, "tcptrace-receive") == 0)
        {
          logflags = logflags | TCPTRACE_RECEIVE;
        }
        else if (strcmp(optarg, "sniff-send") == 0)
        {
          logflags = logflags | SNIFF_SEND;
        }
        else if (strcmp(optarg, "sniff-receive") == 0)
        {
          logflags = logflags | SNIFF_RECEIVE;
        }
        else if (strcmp(optarg, "peer-write") == 0)
        {
          logflags = logflags | PEER_WRITE;
        }
        else if (strcmp(optarg, "peer-read") == 0)
        {
          logflags = logflags | PEER_READ;
        }
        else if (strcmp(optarg, "main-loop") == 0)
        {
          logflags = logflags | MAIN_LOOP;
        }
        else if (strcmp(optarg, "lookup-db") == 0)
        {
          logflags = logflags | LOOKUP_DB;
        }
        else if (strcmp(optarg, "delay-detail") == 0)
        {
            logflags = logflags | DELAY_DETAIL;
        }
        else if (strcmp(optarg, "packet-buffer-detail") == 0)
        {
            logflags = logflags | PACKET_BUFFER_DETAIL;
        }
        else
        {
            fprintf(stderr, "Unknown logging option %s\n", optarg);
            usage();
            exit(1);
        }
        break;
      case 's':
        flag_standalone = 1; break;
      case 'r':
        flag_standalone = 1;
        is_live = 0;
        break;
      case 't':
        flag_testmode = 1; break;
      default:
        fprintf(stderr,"Unknown option %c\n",ch);
        usage(); exit(1);
    }
  }
  argc -= optind;
  argv += optind;

  if (logfile == NULL)
  {
    logfile = stderr;
  }

  logInit(logfile, logflags, 1);

  if (flag_standalone) {
    if (argc != 3) {
      fprintf(stderr,"Wrong number of options for standalone: %i\n",argc);
      usage();
      exit(1);
    } else {
      flag_measure = 1;
//      rcvdb[0].valid = 1;
      standalone_port = atoi(argv[2]);
      inet_aton(argv[1], &addr);
      insert_fake(addr.s_addr, standalone_port);
//      rcvdb[0].ip    =  addr.s_addr;
//      rcvdb[0].sockfd= -1; //show error if used
//      rcvdb[0].last_usetime = time(NULL);
    }
    printf("Running in standalone mode\n");
  } else {
    if (argc != 1) {
      fprintf(stderr,"Wrong number of options: %i\n",argc);
      usage();
      exit(1);
    }
  }

  if (flag_testmode) {
      printf("Running in testmode\n");
      test_state = TEST_NOTSTARTED;
  }

  if (strlen(argv[0]) > 127) {
    fprintf(stderr,"Error: the <sniff-interface> name must be less than 127 characters \n");
    exit(1);
  }

//  strcpy(sniff_interface, argv[0]);


  //set up the sender connection listener
  if ((sockfd_rcv_sender = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    perror("socket");
    exit(1);
  }
  if (setsockopt(sockfd_rcv_sender, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
    perror("setsockopt");
    exit(1);
  }
  my_addr.sin_family = AF_INET;           // host byte order
  my_addr.sin_port = htons(SENDER_PORT);  // short, network byte order
  my_addr.sin_addr.s_addr = INADDR_ANY;   // automatically fill with my IP
//  memset(&(my_addr.sin_zero), '\0', 8);   // zero the rest of the struct
  if (flag_debug) printf("Listen on %s\n",inet_ntoa(my_addr.sin_addr));
  if (bind(sockfd_rcv_sender, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) {
    perror("bind");
    exit(1);
  }
  if (listen(sockfd_rcv_sender, PENDING_CONNECTIONS) == -1) {
    perror("listen");
    exit(1);
  }

  //set up the monitor connection listener
  if ((sockfd_rcv_monitor = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    perror("socket");
    exit(1);
  }
  if (setsockopt(sockfd_rcv_monitor, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
    perror("setsockopt");
    exit(1);
  }
  my_addr.sin_family = AF_INET;           // host byte order
  my_addr.sin_port = htons(MONITOR_PORT); // short, network byte order
  my_addr.sin_addr.s_addr = INADDR_ANY;   // automatically fill with my IP
//  memset(&(my_addr.sin_zero), '\0', 8);   // zero the rest of the struct
  if (flag_debug) printf("Listen on %s\n",inet_ntoa(my_addr.sin_addr));
  if (bind(sockfd_rcv_monitor, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) {
    perror("bind");
    exit(1);
  }
  if (listen(sockfd_rcv_monitor, 1) == -1) {
    perror("listen");
    exit(1);
  }

  //initialization
  packet_buffer_init();
  init_random_buffer();
  init_pcap(SNIFF_TIMEOUT, standalone_port, argv[0]);
  FD_ZERO(&read_fds);
  FD_ZERO(&read_fds_copy);
  FD_ZERO(&write_fds);
  FD_ZERO(&write_fds_copy);
  FD_SET(pcapfd,  &read_fds);
  FD_SET(sockfd_rcv_sender,  &read_fds);
  FD_SET(sockfd_rcv_monitor, &read_fds);
  maxfd = pcapfd; //socket order
  sin_size = sizeof(struct sockaddr_in);

  //main loop - the stubd runs forever
  while (1) {
//    flag_send_monitor=0; //reset flag for each quanta
    gettimeofday(&start_tv, NULL); //reset start time for each quanta

//    printf("Total: %d\n", total_size);
//    printf("========== Quantum %lu ==========\n", quantum_no);
    logWrite(MAIN_LOOP, NULL, "Quantum %lu", quantum_no);
    if (is_live)
    {
        update_stats();
        logWrite(MAIN_LOOP, NULL, "PCAP Received: %u Dropped: %u",
                 received_stat(), dropped_stat());
    }
    quantum_no++;

    //while in a quanta
    while(have_time(&start_tv, &left_tv)) {
      read_fds_copy  = read_fds;
      write_fds_copy = write_fds;

      select_count = select(maxfd+1, &read_fds_copy, &write_fds_copy, NULL,
                            &left_tv);
      if (select_count == -1)
      {
        perror("select");
        clean_exit(1);
      }
//      fprintf(stderr, "Select count: %d\n", select_count);
      // Send out packets to our peers if the deadline has passed.
//      logWrite(MAIN_LOOP, NULL, "Send normal packets to peers");
      handle_packet_buffer(&packet_deadline, &write_fds_copy);

      // send to destinations which are writeable and are behind.
//      logWrite(MAIN_LOOP, NULL, "Send pending packets to peers");
#ifdef USE_PACKET_BUFFER
      for_each_pending(try_pending, &write_fds_copy);
#endif

      // receive from existing senders
//      logWrite(MAIN_LOOP, NULL, "Receive packets from peers");
      for_each_readable_sender(receive_sender, &read_fds_copy);

/*
      //receive from existent senders
      for (i=0; i<CONCURRENT_SENDERS; i++){
        // Send pending data if it exists.
        if (snddb[i].valid==1 && FD_ISSET(snddb[i].sockfd, &read_fds_copy)) {
          receive_sender(i);
        }
      }
*/
      //handle new senders
      if (FD_ISSET(sockfd_rcv_sender, &read_fds_copy)) {
        if ((sockfd_snd = accept(sockfd_rcv_sender, (struct sockaddr *)&their_addr, &sin_size)) == -1) {
          perror("accept");
          continue;
        } else {
          logWrite(MAIN_LOOP, NULL, "Accept new peer (%s)",
                   inet_ntoa(their_addr.sin_addr));
          replace_sender_by_stub_port(their_addr.sin_addr.s_addr,
                                      ntohs(their_addr.sin_port), sockfd_snd,
                                      &read_fds);
//        insert_db(their_addr.sin_addr.s_addr, their_addr.sin_port,
//                  SENDER_PORT, sockfd_snd, 1); //insert snddb
//        FD_SET(sockfd_snd, &read_fds); // add to master set
//        if (sockfd_snd > maxfd) { // keep track of the maximum
//          maxfd = sockfd_snd;
//        }
          if (flag_debug) printf("server: got connection from %s\n",inet_ntoa(their_addr.sin_addr));
        }
      }

      //handle the new monitor
      if (FD_ISSET(sockfd_rcv_monitor, &read_fds_copy)) {
        if ((sockfd_monitor = accept(sockfd_rcv_monitor, (struct sockaddr *)&their_addr, &sin_size)) == -1) {
          perror("accept");
          continue;
        } else {
          int nodelay = 1;
          int nodelay_error = setsockopt(sockfd_monitor, IPPROTO_TCP,
                                         TCP_NODELAY, &nodelay,
                                         sizeof(nodelay));
          if (nodelay_error == -1)
          {
            perror("setsockopt (TCP_NODELAY)");
            clean_exit(1);
          }
          logWrite(MAIN_LOOP, NULL, "Accept new monitor (%s)",
                   inet_ntoa(their_addr.sin_addr));

          FD_CLR(sockfd_rcv_monitor, &read_fds);  //allow only one monitor connection
          FD_SET(sockfd_monitor, &read_fds);  //check the monitor connection for read
//        FD_SET(sockfd_monitor, &write_fds); //check the monitor connection for write
          if (sockfd_monitor > maxfd) { //keep track of the maximum
            maxfd = sockfd_monitor;
          }
          if (flag_debug) printf("server: got connection from %s\n",inet_ntoa(their_addr.sin_addr));
        }
      }

      //receive from the monitor
      if (sockfd_monitor!=-1 && FD_ISSET(sockfd_monitor, &read_fds_copy)) {
        logWrite(MAIN_LOOP, NULL, "Receive control message from monitor");
        if (receive_monitor(sockfd_monitor, &packet_deadline) == 0) { //socket_monitor closed by peer
          FD_CLR(sockfd_monitor, &read_fds); //stop checking the monitor socket
//        FD_CLR(sockfd_monitor, &write_fds);
          sockfd_monitor = -1;
          FD_SET(sockfd_rcv_monitor, &read_fds); //start checking the receiver control socket
          if (sockfd_rcv_monitor > maxfd) { // keep track of the maximum
            maxfd = sockfd_rcv_monitor;
          }
        }
      }

      //sniff packets
      if (FD_ISSET(pcapfd, &read_fds_copy)) {
        logWrite(MAIN_LOOP, NULL, "Sniff packet stream");
        sniff();
      }

    } //while in quanta

    //send measurements to the monitor once in each quanta
    if (sockfd_monitor!=-1)
// && FD_ISSET(sockfd_monitor, &write_fds_copy)) {
    {
        logWrite(MAIN_LOOP, NULL, "Send control message to monitor");
        if (send_monitor(sockfd_monitor) == 0) { //socket_monitor closed by peer
            logWrite(MAIN_LOOP, NULL, "Message to monitor failed");
            FD_CLR(sockfd_monitor, &read_fds); //stop checking the monitor socket
//        FD_CLR(sockfd_monitor, &write_fds);
            sockfd_monitor = -1;
            FD_SET(sockfd_rcv_monitor, &read_fds); //start checking the receiver control socket
            if (sockfd_rcv_monitor > maxfd) { // keep track of the maximum
                maxfd = sockfd_rcv_monitor;
            }
        } else {
            logWrite(MAIN_LOOP, NULL, "Message to monitor succeeded");
//        flag_send_monitor=1;
        }
    }

    // In testmode, we only start printing in the quanta we first see a packet
    if (flag_standalone) {
      print_measurements();
    }

    // If running in testmode, and the test is over, exit!
    if (flag_testmode && test_state == TEST_DONE) {
      printf("Test done - total bytes transmitted: %llu\n",total_bytes);
      break;
    }
  } //while forever

  packet_buffer_cleanup();

  return 0;
}