static int toxenet_socket_receive(ENetSocket socket, ENetAddress *address, ENetBuffer *buffers, size_t bufferCount, ENetEvent *event, void *user_data) { Tunneld *tund = (Tunneld*)user_data; QToxKit *toxkit = tund->m_toxkit; // ToxTunChannel *chan = tund->m_enpeer_chans[event->peer]; // qDebug()<<event; // qDebug()<<event->peer; // qDebug()<<event->peer->connectID; ToxTunChannel *chan = NULL; // ToxTunChannel *chan = tund->m_conid_chans[event->peer->connectID]; // qDebug()<<bufferCount<<toxkit<<event->peer<<chan; if (event->peer == NULL) {} if (chan == NULL) {} QMutexLocker mtlck(&tund->m_pkts_mutex); if (tund->m_inpkts.count() == 0) { return 0; } if (bufferCount != 1) { qDebug()<<"not supported >1:" << bufferCount; } struct sockaddr_in sin = {0}; QString pubkey = tund->m_inpkts.begin().key(); if (tund->m_inpkts[pubkey].count() > 0) { // qDebug()<<tund<<socket<<bufferCount; int recvLength = 0; // QByteArray pkt = tund->m_pkts[pubkey].takeAt(0); // QByteArray pkt = tund->m_pkts[pubkey].at(0); // tund->m_pkts[pubkey].remove(0); QByteArray pkt = tund->m_inpkts[pubkey].dequeue(); // deserialize recvLength = deserialize_packet(pkt, address, &buffers[0]); if (address != NULL) { address->vaddr = toxkit->friendByPublicKey(pubkey); /* if (strlen(address->toxid) == 0 || strcmp(address->toxid, pubkey.toLatin1().data()) != 0) { qDebug()<<"need reset unsame toxid:" <<address->toxid<<"->"<<pubkey; strcpy(address->toxid, pubkey.toLatin1().data()); } else { // strcpy(address->toxid, pubkey.toLatin1().data()); } */ } // qDebug()<<tund<<socket<<bufferCount<<recvLength; return recvLength; } return 0; }
static int toxenet_socket_receive(ENetSocket socket, ENetAddress *address, ENetBuffer *buffers, size_t bufferCount, ENetEvent *event, void *user_data) { Tunnelc *tunc = (Tunnelc*)user_data; QToxKit *toxkit = tunc->m_toxkit; ToxTunChannel *chan = NULL; // ToxTunChannel *chan = tunc->m_enpeer_chans[event->peer]; // ToxTunChannel *chan = tunc->m_conid_chans[event->peer->connectID]; // qDebug()<<bufferCount<<toxkit<<event->peer<<chan; if (event->peer == NULL) {} if (chan == NULL) {} QMutexLocker mtlck(&tunc->m_pkts_mutex); if (tunc->m_inpkts.count() == 0) { return 0; } if (bufferCount != 1) { qDebug()<<"not supported >1:" << bufferCount; } struct sockaddr_in sin = {0}; QString pubkey = tunc->m_inpkts.begin().key(); if (tunc->m_inpkts[pubkey].count() > 0) { // qDebug()<<tunc<<socket<<bufferCount; int recvLength = 0; // QByteArray pkt = tunc->m_pkts[pubkey].takeAt(0); // QByteArray pkt = tunc->m_pkts[pubkey].at(0); // tunc->m_pkts[pubkey].remove(0); QByteArray pkt = tunc->m_inpkts[pubkey].dequeue(); // deserialize recvLength = deserialize_packet(pkt, address, &buffers[0]); // qDebug()<<tunc<<socket<<bufferCount<<recvLength; return recvLength; } return 0; }
int main(int argc, char *argv[]) { if(argc != 7) { printf("usage: host port R stream_id window_size filename\n"); exit(0); } char *endptr; long R = strtol(argv[3], &endptr, 10); char *stream_id = argv[4]; int window_size = strtol(argv[5], NULL, 10); if(endptr != (argv[3] + strlen(argv[3]))) { fprintf(stderr, "R must be an integer (milliseconds).\n"); exit(1); } struct addrinfo* p; int send_sock = send_port(argv[1], argv[2], &p); int recv_sock = recv_port(NULL, argv[2]);// TODO fix printf("Stream id = %s\n", stream_id); ee122_packet pkt; pkt.R = R; pkt.stream = *stream_id; printf("pkt.stream = %c\n", pkt.stream); pkt.avg_len = 0; pkt.window_size = window_size; int read_count; char fbuff[sizeof(pkt.payload)]; memset(fbuff,0,sizeof(fbuff)); FILE *fd = fopen(argv[6], "rb"); if(NULL == fd) { fprintf(stderr, "fopen() error\n"); return 1; } ee122_packet rcv_pkt; struct timespec sleep_spec; sleep_spec.tv_sec = 0; struct timeval curr_time, start_time, last_generated, diff_time; gettimeofday(&start_time, NULL); gettimeofday(&last_generated, NULL); int seq_no = 0; int available_window = window_size; struct timeval timeouts[window_size+1]; ee122_packet packets[window_size+1]; int i; struct timeval zero_timeout; zero_timeout.tv_usec = 0; zero_timeout.tv_sec = 0; for(i = 0; i < window_size+1; i++) { memcpy(&timeouts[i], &zero_timeout, sizeof(zero_timeout)); } bytequeue q; bytequeue_init(&q, sizeof(ee122_packet), window_size); float rtt = 400*1000; char buff[sizeof(ee122_packet)]; float next_wait = rand_poisson(R); printf("next wait: %f\n", next_wait); int bytes_read; struct sockaddr src_addr; int src_len = sizeof(src_addr); int last_received = -1; unsigned total_attempts = 0; unsigned seconds = 0; unsigned errors = 0; while (1) { gettimeofday(&curr_time, NULL); timeval_subtract(&diff_time, &curr_time, &start_time); if (diff_time.tv_sec * 1000000 + diff_time.tv_usec > seconds * 1000000) { printf("%f,%d\n", rtt, seconds); seconds++; } // Stop sending after 60 seconds if(diff_time.tv_sec * 1000000 + diff_time.tv_usec > 60*1000000) { break; } // Check timeouts. If timeout reached, retransmit that packet and all following. int retransmitting = -1; int i; for(i=0; i < window_size+1; i++) { struct timeval timeout = timeouts[i]; if(timeout.tv_sec == 0 && timeout.tv_usec == 0) continue; timeval_subtract(&diff_time, &curr_time, &timeouts[i]); if(diff_time.tv_sec * 1000000 + diff_time.tv_usec > rtt) { retransmitting = i; break; } } if(retransmitting != -1) { i = retransmitting; do { struct timeval timeout = timeouts[i]; if(timeout.tv_sec == 0 && timeout.tv_usec == 0) { i = (i + 1) % (window_size+1); continue; } //printf("Retransmitting seq_no == %d, stream == %c, rtt == %f\n", packets[i].seq_number, packets[i].stream, rtt); // Reset the timeout for this packet and send. gettimeofday(&(timeouts[i]), NULL); serialize_packet(buff, packets[i]); sendto(send_sock, buff, sizeof(packets[i]), 0, p->ai_addr, p->ai_addrlen); i = (i + 1) % (window_size+1); total_attempts++; errors++; } while (i != retransmitting); } // Check if new packet should be generated by now timeval_subtract(&diff_time, &curr_time, &last_generated); if(diff_time.tv_sec * 1000000 + diff_time.tv_usec > next_wait * 1000) { // Enqueue the packet. bytequeue_push(&q, &pkt); next_wait = rand_poisson(R); } // Read from socket. Increase available window for each ack received int bytes_read = recvfrom(recv_sock, buff, sizeof(ee122_packet), 0, &src_addr, &src_len); if(bytes_read > 0) { rcv_pkt = deserialize_packet(buff); if(rcv_pkt.stream == 'Z' && rcv_pkt.seq_number == (last_received + 1) % (window_size+1)) { struct timeval timeout_start = rcv_pkt.timestamp; // Learn RTT timeval_subtract(&diff_time, &curr_time, &timeout_start); //printf("RTT difftime, tv_sec == %d, tv_usec == %d\n", diff_time.tv_sec, diff_time.tv_usec); rtt = (0.6 * (diff_time.tv_sec * 1000000 + diff_time.tv_usec)) + 0.4*rtt; // Reset this timeout timeouts[rcv_pkt.seq_number].tv_usec = 0; timeouts[rcv_pkt.seq_number].tv_sec = 0; available_window += 1; last_received = rcv_pkt.seq_number % (window_size+1); } else { //printf("Received ACK with seq = %d, expecting = %d\n", rcv_pkt.seq_number, (last_received + 1) % window_size); } } // Check available window. If available, dequeue and send a packet. if(available_window > 0 && q.filled != 0) { bytequeue_pop(&q, &pkt); total_attempts++; pkt.seq_number = (seq_no) % (window_size+1); pkt.timestamp = curr_time; pkt.total_attempts = total_attempts; pkt.timeout = rtt; read_count = fread(pkt.payload, sizeof(char), sizeof(pkt.payload), fd); //printf("Sending. Seq_no == %d, stream == %c\n", pkt.seq_number, pkt.stream); serialize_packet(buff, pkt); //Store the packet into the packets buffer for possible transmission memcpy(&packets[pkt.seq_number], &pkt, sizeof(pkt)); sendto(send_sock, buff, sizeof(pkt), 0, p->ai_addr, p->ai_addrlen); pkt = deserialize_packet(buff); available_window -= 1; if (feof(fd)) break; if(ferror(fd)) { fprintf(stderr, "error: %s\n", strerror(errno)); exit(3); } // Set this timeout gettimeofday(&timeouts[pkt.seq_number], NULL); seq_no++; } } printf("Total errors: %d. Total total:%d\n", errors, total_attempts); close(send_sock); close(recv_sock); exit(0); }
int main(int argc, char *argv[]){ if(argc != 5){ printf("usage: port sender_hostname ack_port filename\n"); exit(0); } srand(time(0)); // init random int status; int sockfd; struct addrinfo hints; memset(&hints, 0, sizeof hints); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = AI_PASSIVE; struct addrinfo *res, *p; if ((status = getaddrinfo(NULL, argv[1], &hints, &res)) != 0) { fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status)); exit(1); } for(p = res; p != NULL; p = p->ai_next) { if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { perror("listener: socket"); continue; } if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) { close(sockfd); perror("listener: bind"); continue; } break; } if (p == NULL) { fprintf(stderr, "listener: failed to bind socket\n"); return 2; } struct addrinfo* send_p; int outsock = send_port(argv[2], argv[3], &send_p); struct timeval timeout; timeout.tv_sec = 4; timeout.tv_usec = 0; setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO,(struct timeval *)&timeout, sizeof(struct timeval)); struct sockaddr src_addr; int src_len = sizeof src_addr; ee122_packet pkt; int write_count; char fbuff[sizeof(pkt.payload)]; memset(fbuff,0,sizeof(fbuff)); FILE *fd = fopen(argv[4], "wb"); if(NULL == fd) { fprintf(stderr, "fopen() error\n"); return 1; } int num_rcv = 0; int bytes_read = 0; unsigned long attempted = 0; float avg_len ; unsigned char buff[sizeof(ee122_packet)]; long R; int delay; struct timespec sleep_spec; sleep_spec.tv_sec = 0; struct timeval last_time, curr_time, diff_time, last_print; gettimeofday(&last_print, NULL); double sum = 0.0; int seq_expected = 0; int gotten = 0; float efficiency = 0; while(bytes_read = recvfrom(sockfd, buff, sizeof(ee122_packet), 0, &src_addr, &src_len)){ if(bytes_read == -1){ if(num_rcv > 0){ break; } } else { if(bytes_read == 0){ break; } pkt = deserialize_packet(buff); //printf("Received packet with seq no: %d\n", ntohl(*((uint32_t*) buff))); if(num_rcv == 0) { R = pkt.R; } else { } if (flip_state) { delay = rand() % 15; } else { delay = rand() % 5; } sleep_spec.tv_nsec = delay * 1000000; nanosleep(&sleep_spec, &sleep_spec); if(pkt.seq_number == seq_expected){ write_count = fwrite(pkt.payload, sizeof(char), sizeof(pkt.payload), fd); if (ferror(fd)) { fprintf(stderr, "error: %s\n", strerror(errno)); exit(3); } seq_expected = (seq_expected + 1) % (MAX_WINDOW + 1); // Do the calcs num_rcv++; attempted = pkt.total_attempts; avg_len = pkt.avg_len; gettimeofday(&curr_time, NULL); last_time = pkt.timestamp; timeval_subtract(&diff_time, &curr_time, &last_time); sum += ((double)(diff_time.tv_sec)) + (diff_time.tv_usec / 1000000.0); timeval_subtract(&diff_time, &curr_time, &last_print); if (diff_time.tv_sec * 1000000 + diff_time.tv_usec > 1000000) { printf("%f\n", ((float) num_rcv)/attempted); gettimeofday(&last_print, NULL); } } gotten = pkt.total_attempts; // Send ACK ee122_packet ack; ack = pkt; ack.stream = 'Z'; unsigned char buff[sizeof(ack)]; serialize_packet(buff, ack); sendto(outsock, buff, sizeof(ack), 0, send_p->ai_addr, send_p->ai_addrlen); } } printf("%d,%f,%lf\n", pkt.R, ((float) num_rcv)/attempted, avg_len); freeaddrinfo(res); close(sockfd); exit(0); }