constexpr static bool is_valid_entry(V v, H const & head, T const &... tail) { return ((int)head.value() == v) ? true : (sizeof...(T) > 0) ? is_valid_entry(v, tail...) : false; }
/* *************************************************** * Function: add_to_recv_buffer * *************************************************** * This function simply adds a packet (if its a valid packet, defined * by the next function) to the receiver buffer. It searches the receiver * buffer for the right place to put the file. The receive buffer is always * kept in anscending order of sequence numbers. */ static void add_to_recv_buffer(context_t *ctx, char* pkt, size_t len) { tcp_seq target_seq = ((struct tcphdr *)pkt)->th_seq; size_t data_len = len - TCP_DATA_START(pkt); if (!is_valid_entry(ctx,target_seq, data_len)){ our_dprintf("Invalid incoming packet - dropping!\n"); return; } struct window* win = &(ctx->rbuffer); assert((win->end->next==NULL) || !DEBUG); /* Create a new link list entry */ struct p_entry* new_entry = (struct p_entry*)calloc(1,sizeof(struct p_entry)); new_entry->packet = (char *)calloc(1, len); memcpy(new_entry->packet, pkt, len); new_entry->packet_size = len; tcp_seq curr_seq; struct p_entry* prev = win->start; struct p_entry* curr = win->start->next; bool inserted = false; /* Search for the right place to add this sequence */ while(curr) { curr_seq = ((struct tcphdr *)curr->packet)->th_seq; if (target_seq < curr_seq) { /* Place found */ inserted = true; new_entry->next = curr; prev->next = new_entry; break; } prev = curr; curr = curr->next; } /* Add to the end of the list if not added before */ if (!inserted){ new_entry->next = NULL; win->end->next = new_entry; win->end = win->end->next; } win->num_entries+=1; our_dprintf("Added Recv: %d to receive buffer\n", ((struct tcphdr*)pkt)->th_seq); }