void send_file(int sockfd, int* clientlen, struct sockaddr_in* clientaddr, Request* req) { int last_sent = -1; FILE *fp = open_file(req->filename); int file_size = get_filesize(fp); int final_seq_num = (file_size / DATASIZE); // this accounts for 0 byte DataPkt for file_size % 512 == 0 int window_min = 0; // window_max can't be greater than final_seq_num int window_max = (req->window_size - 1 > final_seq_num) ? final_seq_num : (req->window_size - 1); int num_timeouts = 0; int n; fd_set read_set; struct timeval timeout; // printf("data size is %d and final_seq_num is %d\n", file_size, final_seq_num); // printf("window_size is %d and window_max is %d\n", req->window_size, window_max); // printf("about to send pkts\n"); last_sent = send_pkts(fp, file_size, last_sent, window_max, sockfd, clientlen, clientaddr); while (1) { DataPkt ack; bzero(ack.data, DATASIZE); FD_ZERO(&read_set); timeout.tv_sec = 0; timeout.tv_usec = TIMEOUT_USEC; FD_SET(sockfd, &read_set); n = select(sockfd + 1, &read_set, NULL, NULL, &timeout); if (n == 0) { // timed out // printf("timed out %d times\n", num_timeouts); num_timeouts++; if (num_timeouts == MAX_TIMEOUTS) { return; // stop communication } last_sent = send_pkts(fp, file_size, window_min - 1, window_max, sockfd, clientlen, clientaddr); } else { n = recvfrom(sockfd, (char *) &ack, (TYPEWINDOWSEQSIZE * 2), 0, (struct sockaddr *) clientaddr, clientlen); if (n < 0) error("ERROR in recvfrom"); // printf("got ack for pkt %d\n", ack.seq_num); if (ack.seq_num >= window_min) { // ACK is new if (ack.seq_num == final_seq_num) { // printf("TRANSFER DONE!\n"); return; // completed } // adjust window accordingly window_min = ack.seq_num + 1; window_max = (window_min + (req->window_size - 1) > final_seq_num) ? final_seq_num : (window_min + (req->window_size - 1)); // printf("window_min is now %d and window_max is now %d\n", window_min, window_max); // printf("sending next set of pkts\n"); last_sent = send_pkts(fp, file_size, last_sent, window_max, sockfd, clientlen, clientaddr); // printf("last sent %d\n", last_sent); } } } }
int main(int argc, char **argv) { // eal args int num_args = rte_eal_init(argc, argv); if (num_args < 0) rte_exit(EXIT_FAILURE, "init failed"); argc -= num_args; argv += num_args; // our args: [-s] port1 port2 uint8_t port1, port2; char opt = getopt(argc, argv, "s"); bool simple_tx = opt == 's'; if (simple_tx) { printf("Requesting simple tx path\n"); argc--; argv++; } else { printf("Requesting full-featured tx path\n"); } if (argc != 3) { printf("usage: [-s] port1 port2\n"); return -1; } port1 = atoi(argv[1]); port2 = atoi(argv[2]); printf("Using ports %d and %d\n", port1, port2); if (!config_port(port1, simple_tx)) return -1; if (!config_port(port2, simple_tx)) return -1; struct rte_mempool* pool = make_mempool(); uint64_t sent = 0; uint64_t next_print = rte_get_tsc_hz(); uint64_t last_sent = 0; while (true) { sent += send_pkts(port1, pool); sent += send_pkts(port2, pool); uint64_t time = rte_rdtsc(); if (time >= next_print) { double elapsed = (time - next_print + rte_get_tsc_hz()) / rte_get_tsc_hz(); uint64_t pkts = sent - last_sent; printf("Packet rate: %.2f Mpps\n", (double) pkts / elapsed / 1000000); next_print = time + rte_get_tsc_hz(); last_sent = sent; } } return 0; }
void *thr(void* arg) { struct node* n = arg; struct rte_mbuf* restrict pkts[32]; int i; int q = n->queue; int start_sec = cursec(); int rcvd = 0; int sent = 0; init_thread(n->tid, n->core); if (q >= 20) { printf("Somehow, queue beyond 20\n"); } while(1) { /*int recv;*/ i = mbuf_alloc_bulk(pkts, 60, 32); if (i != 0) { printf("Error allocating packets %d\n", i); break; } else { int send, recv; /* Start setting MAC address */ for (i = 0; i < 32; i++) { struct ether_hdr* hdr = rte_pktmbuf_mtod(pkts[i], struct ether_hdr*); hdr->d_addr.addr_bytes[5] = (10 * q) + 1; hdr->s_addr.addr_bytes[5] = (10 * q) + 2; hdr->ether_type = rte_cpu_to_be_16(0x0800); /*rte_mbuf_sanity_check(pkts[i], 1);*/ } send = send_pkts(PORT_OUT, q, pkts, 32); for (i = send; i < 32; i++) { mbuf_free(pkts[i]); } recv = recv_pkts(PORT_IN, q, pkts, 32); rcvd += recv; sent += send; if (cursec() != start_sec) { printf("%d %d rx=%d tx=%d\n", n->core, (cursec() - start_sec), rcvd, sent); /*printf("recv_pkt\n");*/ /*rte_pktmbuf_dump(stdout, pkts[0], 16384);*/ start_sec = cursec(); rcvd = 0; sent = 0; } for (int i = 0; i < recv; i++) { mbuf_free(pkts[i]); } } } printf("Socket ID (%d) is %d. DONE\n", n->core, rte_socket_id()); return NULL; }
static void * sender_body(void *data) { struct targ *targ = (struct targ *) data; struct pollfd fds[1]; struct netmap_if *nifp = targ->nifp; struct netmap_ring *txring; int i, n = targ->g->npackets / targ->g->nthreads, sent = 0; int options = targ->g->options | OPT_COPY; D("start"); if (setaffinity(targ->thread, targ->affinity)) goto quit; /* setup poll(2) mechanism. */ memset(fds, 0, sizeof(fds)); fds[0].fd = targ->fd; fds[0].events = (POLLOUT); /* main loop.*/ gettimeofday(&targ->tic, NULL); if (targ->g->use_pcap) { int size = targ->g->pkt_size; void *pkt = &targ->pkt; pcap_t *p = targ->g->p; for (i = 0; n == 0 || sent < n; i++) { if (pcap_inject(p, pkt, size) != -1) sent++; if (i > 10000) { targ->count = sent; i = 0; } } } else { while (n == 0 || sent < n) { /* * wait for available room in the send queue(s) */ do { i = poll(fds, 1, 2000); if (i < 0) { D("poll error/timeout on queue %d", targ->me); goto quit; } } while (i==0); /* * scan our queues and send on those with room */ if (options & OPT_COPY && sent > 100000 && !(targ->g->options & OPT_COPY) ) { D("drop copy"); options &= ~OPT_COPY; } for (i = targ->qfirst; i < targ->qlast; i++) { int m, limit = targ->g->burst; if (n > 0 && n - sent < limit) limit = n - sent; txring = NETMAP_TXRING(nifp, i); if (txring->avail == 0) continue; m = send_pkts(txring, targ->pkts, targ->g->pkt_size, limit, options, sent, targ->npkts); sent += m; targ->count = sent; } } /* flush any remaining packets */ ioctl(fds[0].fd, NIOCTXSYNC, NULL); /* final part: wait all the TX queues to be empty. */ for (i = targ->qfirst; i < targ->qlast; i++) { txring = NETMAP_TXRING(nifp, i); while (!NETMAP_TX_RING_EMPTY(txring)) { ioctl(fds[0].fd, NIOCTXSYNC, NULL); usleep(1); /* wait 1 tick */ } } } gettimeofday(&targ->toc, NULL); targ->completed = 1; targ->count = sent; quit: /* reset the ``used`` flag. */ targ->used = 0; return (NULL); }