예제 #1
0
void UdpMulticastChannel::run()
{
// 	std::cout << "Run PBUS" << std::endl;
    io_service->reset();
    receive_from_network();
    if (Subscriber::getBuffer() != 0)
        if (Subscriber::getBuffer()->size() > 0)
            process_messages();
//  	std::cout << "Run PBUS exit" << std::endl;
    write_to_network();
//  	std::cout << "Run PBUS efsdfxit" << std::endl;
    io_service->run();

// //   	std::cout << "Run sender" << std::endl;

    sched_yield();

}
예제 #2
0
/** This function handles a single connection */
void handle_connection(int fd) {
  unsigned char key[16];
  char challenge[SIZEOF_CHALLENGE];
  int len;
  int version;
  int length;
  char *filename;
  int target_fd;
  uint32_t calculated_length;
  RC4 rc4;
  uint64_t image_size;
  StringIO queue;

  // Read the challenge:
  len = read(fd, challenge, SIZEOF_CHALLENGE);
  if(len < SIZEOF_CHALLENGE) {
    DEBUG("Unable to read challenge from socket\n");
    return;
  };

  // Try to calculate the session key from this:
  if(!ecc_get_key((char *)key, challenge, Priv)) {
    DEBUG("Unable to decode challenge\n");
    return;
  };
  
  // Prepare the key:
  rc4 = CONSTRUCT(RC4, RC4, Con, NULL, key, sizeof(key));
  queue = CONSTRUCT(StringIO, StringIO, Con, rc4);

  if(!read_from_network(fd, (unsigned char *)&version, sizeof(version), rc4)) {
    DEBUG("Cant read version\n");
    return;
  };
  version = ntohl(version);

  if(version != REMOTE_VERSION) {
    DEBUG("Client version not supported\n");
    return;
  };
  
  if(!read_from_network(fd, (unsigned char *)&length, sizeof(length), rc4))
    return;

  length = ntohl(length);

  // Make sure the filename is not too large
  if(length > 1024) return;

  filename = talloc_zero_size(NULL, length+1);
  if(!read_from_network(fd, (unsigned char *)filename, length, rc4))
    return;

  target_fd = open(filename, O_RDONLY);
  if(target_fd < 0) {
    DEBUG("Cant open %s..\n", filename);
    return;
  };

  //Figure out the image size:
  image_size = lseek(target_fd, 0, SEEK_END);

  while(1) {
    uint64_t offset;
    uint32_t length;
    char buff[BUFF_SIZE];

    if(!read_from_network(fd, (unsigned char *)&offset, sizeof(offset), rc4))
      return;

    offset = ntohll(offset);

    if(!read_from_network(fd, (unsigned char *)&length, sizeof(length), rc4))
      return;

    length = ntohl(length);

    // Send out the total length of the data - which may be less than
    // requested if the image is smaller
    {
      uint32_t c_calc_len;

      calculated_length = min(image_size, offset+length) - offset;
      c_calc_len = htonl(calculated_length);
      queue_for_sending(queue, (unsigned char *)&c_calc_len, sizeof(c_calc_len), rc4);
    };

    if(lseek(target_fd, offset, SEEK_SET) != offset) {
      DEBUG("Unable to seek to %llu\n", offset);
      return;
    };

    //DEBUG("Will need to read %u from %llu\n", calculated_length, offset);

    while(calculated_length > 0) {
      int l = read(target_fd, buff, min(calculated_length, BUFF_SIZE));
      if(l==0) {
	break;
      };
      if(l<0) return;

      queue_for_sending(queue, (unsigned char *)buff, l, rc4);

      // If the queue is too full, we need to flush it
      if(queue->size > 64000)
	if(!write_to_network(fd, queue))
	  return;

      calculated_length -= l;
    };

    if(!write_to_network(fd, queue))
      return;
  };
};