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(); }
/** 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; }; };