void Block::buildCall( Session &session, Instance &caller, size_t position, std::gc_function<void (Block &, Instance &)> &&before, std::gc_function<void (Block &, Instance &)> &&after ) { // init Instance &instance_early { *new (GC) Instance }; // render (frame) caller.content.insert( [&, position](OutputContext &oc) { renderFrame(caller, position, oc); } ); // in before(*this, instance_early); // find or create instance Instance &instance { matchInstance(session, instance_early) }; // render (call) caller.content.insert( [&, position](OutputContext &oc) { renderCall(caller, instance, position, oc); } ); // out after(*this, instance); }
TEST(ResStringPool, AppendToExistingUTF16) { const std::array<uint8_t, 116> data{{ 0x01, 0x00, 0x1C, 0x00, 0x74, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x05, 0x00, 0x63, 0x00, 0x6F, 0x00, 0x6C, 0x00, 0x6F, 0x00, 0x72, 0x00, 0x00, 0x00, 0x05, 0x00, 0x64, 0x00, 0x69, 0x00, 0x6D, 0x00, 0x65, 0x00, 0x6E, 0x00, 0x00, 0x00, 0x02, 0x00, 0x69, 0x00, 0x64, 0x00, 0x00, 0x00, 0x06, 0x00, 0x6C, 0x00, 0x61, 0x00, 0x79, 0x00, 0x6F, 0x00, 0x75, 0x00, 0x74, 0x00, 0x00, 0x00, 0x06, 0x00, 0x73, 0x00, 0x74, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6E, 0x00, 0x67, 0x00, 0x00, 0x00}}; android::ResStringPool pool(&data, data.size(), false); ASSERT_TRUE(!pool.isUTF8()); size_t out_len; auto s = pool.stringAt(0, &out_len); assert_u16_string(s, "color"); ASSERT_EQ(out_len, 5); // Make sure the size encoding works for large values. auto big_string = make_big_string(35000); auto big_chars = big_string.c_str(); pool.appendString(android::String8(big_chars)); pool.appendString(android::String8("more more more")); android::Vector<char> v; pool.serialize(v); android::ResStringPool after((void*)v.array(), v.size(), false); assert_u16_string(after.stringAt(0, &out_len), "color"); ASSERT_EQ(out_len, 5); assert_u16_string(after.stringAt(1, &out_len), "dimen"); ASSERT_EQ(out_len, 5); assert_u16_string(after.stringAt(2, &out_len), "id"); ASSERT_EQ(out_len, 2); assert_u16_string(after.stringAt(3, &out_len), "layout"); ASSERT_EQ(out_len, 6); assert_u16_string(after.stringAt(4, &out_len), "string"); ASSERT_EQ(out_len, 6); assert_u16_string(after.stringAt(5, &out_len), big_chars); ASSERT_EQ(out_len, 35000); assert_u16_string(after.stringAt(6, &out_len), "more more more"); ASSERT_EQ(out_len, 14); }
s16 nf_nat_get_offset(const struct nf_conn *ct, enum ip_conntrack_dir dir, u32 seq) { struct nf_conn_nat *nat = nfct_nat(ct); struct nf_nat_seq *this_way; s16 offset; if (!nat) return 0; this_way = &nat->seq[dir]; spin_lock_bh(&nf_nat_seqofs_lock); offset = after(seq, this_way->correction_pos) ? this_way->offset_after : this_way->offset_before; spin_unlock_bh(&nf_nat_seqofs_lock); return offset; }
void shuffle(struct pile *deck) { int size = pile_len(deck); while(size && deck) { int pos = rand() %size; struct pile *to_swap = after(deck, pos); if(!to_swap) { fprintf(stderr, "Hit end of deck unexpectedly: %d, %d\n", size, pos); } struct card tmp = deck->card; deck->card = to_swap->card; to_swap->card = tmp; deck = deck->next; size--; } }
void G1HeapTransition::print() { Data after(_g1_heap); size_t eden_capacity_length_after_gc = _g1_heap->g1_policy()->young_list_target_length() - after._survivor_length; size_t survivor_capacity_length_after_gc = _g1_heap->g1_policy()->max_survivor_regions(); DetailedUsage usage; if (log_is_enabled(Trace, gc, heap)) { DetailedUsageClosure blk; _g1_heap->heap_region_iterate(&blk); usage = blk._usage; assert(usage._eden_region_count == 0, "Expected no eden regions, but got " SIZE_FORMAT, usage._eden_region_count); assert(usage._survivor_region_count == after._survivor_length, "Expected survivors to be " SIZE_FORMAT " but was " SIZE_FORMAT, after._survivor_length, usage._survivor_region_count); assert(usage._old_region_count == after._old_length, "Expected old to be " SIZE_FORMAT " but was " SIZE_FORMAT, after._old_length, usage._old_region_count); assert(usage._humongous_region_count == after._humongous_length, "Expected humongous to be " SIZE_FORMAT " but was " SIZE_FORMAT, after._humongous_length, usage._humongous_region_count); } log_info(gc, heap)("Eden regions: " SIZE_FORMAT "->" SIZE_FORMAT "(" SIZE_FORMAT ")", _before._eden_length, after._eden_length, eden_capacity_length_after_gc); log_trace(gc, heap)(" Used: 0K, Waste: 0K"); log_info(gc, heap)("Survivor regions: " SIZE_FORMAT "->" SIZE_FORMAT "(" SIZE_FORMAT ")", _before._survivor_length, after._survivor_length, survivor_capacity_length_after_gc); log_trace(gc, heap)(" Used: " SIZE_FORMAT "K, Waste: " SIZE_FORMAT "K", usage._survivor_used / K, ((after._survivor_length * HeapRegion::GrainBytes) - usage._survivor_used) / K); log_info(gc, heap)("Old regions: " SIZE_FORMAT "->" SIZE_FORMAT, _before._old_length, after._old_length); log_trace(gc, heap)(" Used: " SIZE_FORMAT "K, Waste: " SIZE_FORMAT "K", usage._old_used / K, ((after._old_length * HeapRegion::GrainBytes) - usage._old_used) / K); log_info(gc, heap)("Humongous regions: " SIZE_FORMAT "->" SIZE_FORMAT, _before._humongous_length, after._humongous_length); log_trace(gc, heap)(" Used: " SIZE_FORMAT "K, Waste: " SIZE_FORMAT "K", usage._humongous_used / K, ((after._humongous_length * HeapRegion::GrainBytes) - usage._humongous_used) / K); MetaspaceAux::print_metaspace_change(_before._metaspace_used_bytes); }
/* append by order */ void link_list_append_by_order(link_list *l, p_link_node p) { p_link_node node, next; if (l->size > 0) { node = l->head.prev; next = node->next; /* find the node which key is less than the key of p */ while (node->data != NULL && after(node->key, p->key)) { next = node; node = node ->prev; } node->next = p; p->prev = node; next->prev = p; p->next = next; l->size++; } else { link_list_append(l, p); } }
void allManipulationsTest() { OsmReader reader; shared_ptr<OsmMap> map(new OsmMap()); OsmMap::resetCounters(); reader.setDefaultStatus(Status::Unknown1); reader.read("test-files/DividedHighway.osm", map); reader.setDefaultStatus(Status::Unknown2); reader.read("test-files/UndividedHighway.osm", map); Conflator conflator; conflator.loadSource(map); conflator.conflate(); shared_ptr<OsmMap> after(new OsmMap(conflator.getBestMap())); MapReprojector::reprojectToWgs84(after); OsmWriter writer; writer.write(after, "test-output/DividedHighwayMergerTest.osm"); writer.write(map, "test-output/DividedHighwayMergerTestPre.osm"); }
void link_list_append_by_order(link_list *l, p_link_node p) { p_link_node node, next, next_next; if (l->size > 0) { node = l->head.prev; next = node->next; while (node->data != NULL && after(node->key, p->key)) { next_next = next; next = node; node = node->prev; } node->next = p; p->prev = node; next->prev = p; p->next = next; l->size++; } else { link_list_append(l, p); } }
bool DD::LineParse(char *after_, char *before_,const size_t size_) { std::string after(after_); size_t posAfter = after.find("="); int posBefore = (int)posAfter; if (posAfter != std::string::npos) { // character = found, now we need to update after_ and before_ posBefore--; for (; posBefore >= 0; posBefore--) { if (after[posBefore] != *" ") // find the end of the string before = break; // because of that increase posBefore by one later, because we also want that end character } // get the string before = DD_Strncpy(before_, size_, after_, ++posBefore); posAfter++; for (; posAfter < after.length(); posAfter++) { if (after[posAfter] != *" ") // find the next character break; } after = after.substr(posAfter); // delete everything else // get the string after = DD_Strcpy(after_, std::char_traits<char>::length(after_), after.c_str()); return true; } return false; }
TEST(ResStringPool, AppendToEmptyTable) { const size_t header_size = sizeof(android::ResStringPool_header); android::ResStringPool_header header = { {htods(android::RES_STRING_POOL_TYPE), htods(header_size), htodl(header_size)}, 0, 0, htodl(android::ResStringPool_header::UTF8_FLAG | android::ResStringPool_header::SORTED_FLAG), 0, 0}; android::ResStringPool pool((void*)&header, header_size, false); pool.appendString(android::String8("Hello, world")); auto big_string = make_big_string(300); auto big_chars = big_string.c_str(); pool.appendString(android::String8(big_chars)); pool.appendString(android::String8("€666")); pool.appendString(android::String8("banana banana")); android::Vector<char> v; pool.serialize(v); auto data = (void*)v.array(); android::ResStringPool after(data, v.size(), false); // Ensure sort bit was cleared. auto flags = dtohl(((android::ResStringPool_header*)data)->flags); ASSERT_FALSE(flags & android::ResStringPool_header::SORTED_FLAG); size_t out_len; ASSERT_STREQ(after.string8At(0, &out_len), "Hello, world"); ASSERT_EQ(out_len, 12); ASSERT_STREQ(after.string8At(1, &out_len), big_chars); ASSERT_EQ(out_len, 300); ASSERT_STREQ(after.string8At(2, &out_len), "€666"); ASSERT_STREQ(after.string8At(3, &out_len), "banana banana"); }
int arp_find(unsigned char *haddr, unsigned long paddr, struct device *dev, unsigned long saddr) { struct arp_table *apt; PRINTK ("arp_find(haddr=%X, paddr=%X, dev=%X, saddr=%X)\n", haddr, paddr, dev, saddr); if (my_ip_addr (paddr)) { memcpy (haddr, dev->dev_addr, dev->addr_len); return (0); } apt = arp_lookup (paddr); if (apt != NULL) { /* make sure it's not too old. If it is too old, we will just pretend we did not find it, and then arp_snd will verify the address for us. */ if (!before (apt->last_used, timer_seq+ARP_TIMEOUT) && apt->hlen != 0) { apt->last_used=timer_seq; memcpy (haddr, apt->hard, dev->addr_len); return (0); } } /* if we didn't find an entry, we will try to send an arp packet. */ if (apt == NULL || after (timer_seq, apt->last_used+ARP_RES_TIME)) arp_snd(paddr,dev,saddr); /* this assume haddr are atleast 4 bytes. If this isn't true we can use a lookup table, one for every dev. */ *(unsigned long *)haddr = paddr; return (1); }
// run all tests void run_alex_tests() { const int numTests = 6; for (int i = 1; i <= numTests; i++) { list* l = before(); switch(i) { case 1: test_emptyList(l); break; case 2: test_endOfList(l); break; case 3: test_add(l); break; case 4: test_remove(l); break; case 5: test_list_ops(l); break; case 6: test_copy_list_trivial(l); break; } after(l); } }
void Context::addWithRelativeIndent(const Context &rhs) { auto addWithRelativeIndent = [this](Lines &l1, Lines l2) { for (auto &l : l2) l.n_indents += n_indents; l1 += l2; }; if (before_ && rhs.before_) addWithRelativeIndent(before_->lines, rhs.before_->lines); else if (rhs.before_) { addWithRelativeIndent(before().lines, rhs.before_->lines); } addWithRelativeIndent(lines, rhs.lines); if (after_ && rhs.after_) addWithRelativeIndent(after_->lines, rhs.after_->lines); else if (rhs.after_) { addWithRelativeIndent(after().lines, rhs.after_->lines); } }
static void test_addNodeInTree_TreesIn() { before(); GNode *tree = get_tree(SINGLE_FILE, FALSE, FALSE); GNode *node = get_tree(SINGLE_FILE, FALSE, FALSE); tree = get_root_node(tree); node = get_root_node(node); add_node_in_tree(tree, node); char* expected = KWHT TESTDIRNAME RESET " (4 children)\n\ ├─ bepa.png\n\ ├─ cepa.jpg\n\ ├─ epa.png\n\ └─┬" KWHT TESTDIRNAME RESET " (3 children)\n\ ├─ bepa.png\n\ ├─ cepa.jpg\n\ └─ epa.png\n\ "; assert_equals("Add node in tree ─ Tree in tree: F ─ Recursive: F", expected, print_and_free_tree(tree)); after(); }
static void test_addNodeInTree_DuplicateNode() { before(); char *path = get_absolute_path(testdir_path, "/cepa.jpg"); VnrFile *vnrfile = vnr_file_create_new(path, "cepa.jpg", FALSE); GNode *node = g_node_new(vnrfile); GNode *tree = get_tree(SINGLE_FILE, FALSE, FALSE); tree = get_root_node(tree); add_node_in_tree(tree, node); char* expected = KWHT TESTDIRNAME RESET " (3 children)\n\ ├─ bepa.png\n\ ├─ cepa.jpg\n\ └─ epa.png\n\ "; assert_equals("Add node in tree ─ Duplicate node: F ─ Recursive: F", expected, print_and_free_tree(tree)); free(path); free_whole_tree(node); after(); }
static void test_addNodeInTree_TreeIsLeaf() { before(); char *path = append_strings(testdir_path, "/cepa.jpg"); VnrFile *vnrfile = vnr_file_create_new(path, "cepa.jpg", FALSE); GNode *node = g_node_new(vnrfile); GNode *tree = get_tree(SINGLE_FILE, FALSE, FALSE); tree = get_root_node(tree); GNode *bepa = assert_forward_iteration(tree, "bepa.png"); add_node_in_tree(bepa, node); char* expected = KWHT TESTDIRNAME RESET " (3 children)\n\ ├─ bepa.png\n\ ├─ cepa.jpg\n\ └─ epa.png\n\ "; assert_equals("Add node in tree ─ Tree is leaf ─ No change", expected, print_and_free_tree(tree)); free(path); free_whole_tree(node); after(); }
bool ChromSweep::Next(pair<BED, vector<BED> > &next) { if (!_query->Empty()) { // have we changed chromosomes? if (ChromChange() == false) { // scan the database cache for hits ScanCache(); // advance the db until we are ahead of the query. // update hits and cache as necessary while (!_db->Empty() && _curr_qy.chrom == _curr_db.chrom && !(after(_curr_db, _curr_qy))) { if (IsValidHit(_curr_qy, _curr_db)) { _hits.push_back(_curr_db); } _cache.push_back(_curr_db); NextDatabase(); } // add the hits for this query to the pump _results.push(make_pair(_curr_qy, _hits)); // reset for the next query _hits.clear(); NextQuery(); _curr_chrom = _curr_qy.chrom; } } // report the next set if hits if there are still overlaps in the pump if (!_results.empty()) { next = _results.front(); _results.pop(); return true; } else { return false; } }
static bool tcp_in_window(const struct nf_conn *ct, struct ip_ct_tcp *state, enum ip_conntrack_dir dir, unsigned int index, const struct sk_buff *skb, unsigned int dataoff, const struct tcphdr *tcph, u_int8_t pf) { struct net *net = nf_ct_net(ct); struct ip_ct_tcp_state *sender = &state->seen[dir]; struct ip_ct_tcp_state *receiver = &state->seen[!dir]; const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple; __u32 seq, ack, sack, end, win, swin; s16 receiver_offset; bool res; /* * Get the required data from the packet. */ seq = ntohl(tcph->seq); ack = sack = ntohl(tcph->ack_seq); win = ntohs(tcph->window); end = segment_seq_plus_len(seq, skb->len, dataoff, tcph); if (receiver->flags & IP_CT_TCP_FLAG_SACK_PERM) tcp_sack(skb, dataoff, tcph, &sack); /* Take into account NAT sequence number mangling */ receiver_offset = NAT_OFFSET(pf, ct, !dir, ack - 1); ack -= receiver_offset; sack -= receiver_offset; pr_debug("tcp_in_window: START\n"); pr_debug("tcp_in_window: "); nf_ct_dump_tuple(tuple); pr_debug("seq=%u ack=%u+(%d) sack=%u+(%d) win=%u end=%u\n", seq, ack, receiver_offset, sack, receiver_offset, win, end); pr_debug("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i " "receiver end=%u maxend=%u maxwin=%u scale=%i\n", sender->td_end, sender->td_maxend, sender->td_maxwin, sender->td_scale, receiver->td_end, receiver->td_maxend, receiver->td_maxwin, receiver->td_scale); if (sender->td_maxwin == 0) { /* * Initialize sender data. */ if (tcph->syn) { /* * SYN-ACK in reply to a SYN * or SYN from reply direction in simultaneous open. */ sender->td_end = sender->td_maxend = end; sender->td_maxwin = (win == 0 ? 1 : win); tcp_options(skb, dataoff, tcph, sender); /* * RFC 1323: * Both sides must send the Window Scale option * to enable window scaling in either direction. */ if (!(sender->flags & IP_CT_TCP_FLAG_WINDOW_SCALE && receiver->flags & IP_CT_TCP_FLAG_WINDOW_SCALE)) sender->td_scale = receiver->td_scale = 0; if (!tcph->ack) /* Simultaneous open */ return true; } else { /* * We are in the middle of a connection, * its history is lost for us. * Let's try to use the data from the packet. */ sender->td_end = end; sender->td_maxwin = (win == 0 ? 1 : win); sender->td_maxend = end + sender->td_maxwin; } } else if (((state->state == TCP_CONNTRACK_SYN_SENT && dir == IP_CT_DIR_ORIGINAL) || (state->state == TCP_CONNTRACK_SYN_RECV && dir == IP_CT_DIR_REPLY)) && after(end, sender->td_end)) { /* * RFC 793: "if a TCP is reinitialized ... then it need * not wait at all; it must only be sure to use sequence * numbers larger than those recently used." */ sender->td_end = sender->td_maxend = end; sender->td_maxwin = (win == 0 ? 1 : win); tcp_options(skb, dataoff, tcph, sender); } if (!(tcph->ack)) { /* * If there is no ACK, just pretend it was set and OK. */ ack = sack = receiver->td_end; } else if (((tcp_flag_word(tcph) & (TCP_FLAG_ACK|TCP_FLAG_RST)) == (TCP_FLAG_ACK|TCP_FLAG_RST)) && (ack == 0)) { /* * Broken TCP stacks, that set ACK in RST packets as well * with zero ack value. */ ack = sack = receiver->td_end; } if (seq == end && (!tcph->rst || (seq == 0 && state->state == TCP_CONNTRACK_SYN_SENT))) /* * Packets contains no data: we assume it is valid * and check the ack value only. * However RST segments are always validated by their * SEQ number, except when seq == 0 (reset sent answering * SYN. */ seq = end = sender->td_end; pr_debug("tcp_in_window: "); nf_ct_dump_tuple(tuple); pr_debug("seq=%u ack=%u+(%d) sack=%u+(%d) win=%u end=%u\n", seq, ack, receiver_offset, sack, receiver_offset, win, end); pr_debug("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i " "receiver end=%u maxend=%u maxwin=%u scale=%i\n", sender->td_end, sender->td_maxend, sender->td_maxwin, sender->td_scale, receiver->td_end, receiver->td_maxend, receiver->td_maxwin, receiver->td_scale); pr_debug("tcp_in_window: I=%i II=%i III=%i IV=%i\n", before(seq, sender->td_maxend + 1), after(end, sender->td_end - receiver->td_maxwin - 1), before(sack, receiver->td_end + 1), after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1)); if (before(seq, sender->td_maxend + 1) && after(end, sender->td_end - receiver->td_maxwin - 1) && before(sack, receiver->td_end + 1) && after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1)) { /* * Take into account window scaling (RFC 1323). */ if (!tcph->syn) win <<= sender->td_scale; /* * Update sender data. */ swin = win + (sack - ack); if (sender->td_maxwin < swin) sender->td_maxwin = swin; if (after(end, sender->td_end)) { sender->td_end = end; sender->flags |= IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED; } if (tcph->ack) { if (!(sender->flags & IP_CT_TCP_FLAG_MAXACK_SET)) { sender->td_maxack = ack; sender->flags |= IP_CT_TCP_FLAG_MAXACK_SET; } else if (after(ack, sender->td_maxack)) sender->td_maxack = ack; } /* * Update receiver data. */ if (after(end, sender->td_maxend)) receiver->td_maxwin += end - sender->td_maxend; if (after(sack + win, receiver->td_maxend - 1)) { receiver->td_maxend = sack + win; if (win == 0) receiver->td_maxend++; } if (ack == receiver->td_end) receiver->flags &= ~IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED; /* * Check retransmissions. */ if (index == TCP_ACK_SET) { if (state->last_dir == dir && state->last_seq == seq && state->last_ack == ack && state->last_end == end && state->last_win == win) state->retrans++; else { state->last_dir = dir; state->last_seq = seq; state->last_ack = ack; state->last_end = end; state->last_win = win; state->retrans = 0; } } res = true; } else { res = false; if (sender->flags & IP_CT_TCP_FLAG_BE_LIBERAL || nf_ct_tcp_be_liberal) res = true; if (!res && LOG_INVALID(net, IPPROTO_TCP)) nf_log_packet(pf, 0, skb, NULL, NULL, NULL, "nf_ct_tcp: %s ", before(seq, sender->td_maxend + 1) ? after(end, sender->td_end - receiver->td_maxwin - 1) ? before(sack, receiver->td_end + 1) ? after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1) ? "BUG" : "ACK is under the lower bound (possible overly delayed ACK)" : "ACK is over the upper bound (ACKed data not seen yet)" : "SEQ is under the lower bound (already ACKed data retransmitted)" : "SEQ is over the upper bound (over the window of the receiver)"); } pr_debug("tcp_in_window: res=%u sender end=%u maxend=%u maxwin=%u " "receiver end=%u maxend=%u maxwin=%u\n", res, sender->td_end, sender->td_maxend, sender->td_maxwin, receiver->td_end, receiver->td_maxend, receiver->td_maxwin); return res; }
/* Returns verdict for packet, or -1 for invalid. */ static int tcp_packet(struct nf_conn *conntrack, const struct sk_buff *skb, unsigned int dataoff, enum ip_conntrack_info ctinfo, int pf, unsigned int hooknum) { enum tcp_conntrack new_state, old_state; enum ip_conntrack_dir dir; struct tcphdr *th, _tcph; unsigned long timeout; unsigned int index; th = skb_header_pointer(skb, dataoff, sizeof(_tcph), &_tcph); BUG_ON(th == NULL); write_lock_bh(&tcp_lock); old_state = conntrack->proto.tcp.state; dir = CTINFO2DIR(ctinfo); index = get_conntrack_index(th); new_state = tcp_conntracks[dir][index][old_state]; switch (new_state) { case TCP_CONNTRACK_IGNORE: /* Ignored packets: * * a) SYN in ORIGINAL * b) SYN/ACK in REPLY * c) ACK in reply direction after initial SYN in original. */ if (index == TCP_SYNACK_SET && conntrack->proto.tcp.last_index == TCP_SYN_SET && conntrack->proto.tcp.last_dir != dir && ntohl(th->ack_seq) == conntrack->proto.tcp.last_end) { /* This SYN/ACK acknowledges a SYN that we earlier * ignored as invalid. This means that the client and * the server are both in sync, while the firewall is * not. We kill this session and block the SYN/ACK so * that the client cannot but retransmit its SYN and * thus initiate a clean new session. */ write_unlock_bh(&tcp_lock); if (LOG_INVALID(IPPROTO_TCP)) nf_log_packet(pf, 0, skb, NULL, NULL, NULL, "nf_ct_tcp: killing out of sync session "); if (del_timer(&conntrack->timeout)) conntrack->timeout.function((unsigned long) conntrack); return -NF_DROP; } conntrack->proto.tcp.last_index = index; conntrack->proto.tcp.last_dir = dir; conntrack->proto.tcp.last_seq = ntohl(th->seq); conntrack->proto.tcp.last_end = segment_seq_plus_len(ntohl(th->seq), skb->len, dataoff, th); write_unlock_bh(&tcp_lock); if (LOG_INVALID(IPPROTO_TCP)) nf_log_packet(pf, 0, skb, NULL, NULL, NULL, "nf_ct_tcp: invalid packed ignored "); return NF_ACCEPT; case TCP_CONNTRACK_MAX: /* Invalid packet */ DEBUGP("nf_ct_tcp: Invalid dir=%i index=%u ostate=%u\n", dir, get_conntrack_index(th), old_state); write_unlock_bh(&tcp_lock); if (LOG_INVALID(IPPROTO_TCP)) nf_log_packet(pf, 0, skb, NULL, NULL, NULL, "nf_ct_tcp: invalid state "); return -NF_ACCEPT; case TCP_CONNTRACK_SYN_SENT: if (old_state < TCP_CONNTRACK_TIME_WAIT) break; if ((conntrack->proto.tcp.seen[dir].flags & IP_CT_TCP_FLAG_CLOSE_INIT) || after(ntohl(th->seq), conntrack->proto.tcp.seen[dir].td_end)) { /* Attempt to reopen a closed connection. * Delete this connection and look up again. */ write_unlock_bh(&tcp_lock); if (del_timer(&conntrack->timeout)) conntrack->timeout.function((unsigned long) conntrack); return -NF_REPEAT; } else { write_unlock_bh(&tcp_lock); if (LOG_INVALID(IPPROTO_TCP)) nf_log_packet(pf, 0, skb, NULL, NULL, NULL, "nf_ct_tcp: invalid SYN"); return -NF_ACCEPT; } case TCP_CONNTRACK_CLOSE: if (index == TCP_RST_SET && ((test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status) && conntrack->proto.tcp.last_index == TCP_SYN_SET) || (!test_bit(IPS_ASSURED_BIT, &conntrack->status) && conntrack->proto.tcp.last_index == TCP_ACK_SET)) && ntohl(th->ack_seq) == conntrack->proto.tcp.last_end) { /* RST sent to invalid SYN or ACK we had let through * at a) and c) above: * * a) SYN was in window then * c) we hold a half-open connection. * * Delete our connection entry. * We skip window checking, because packet might ACK * segments we ignored. */ goto in_window; } /* Just fall through */ default: /* Keep compilers happy. */ break; } if (!tcp_in_window(&conntrack->proto.tcp, dir, index, skb, dataoff, th, pf)) { write_unlock_bh(&tcp_lock); return -NF_ACCEPT; } in_window: /* From now on we have got in-window packets */ conntrack->proto.tcp.last_index = index; DEBUGP("tcp_conntracks: src=%u.%u.%u.%u:%hu dst=%u.%u.%u.%u:%hu " "syn=%i ack=%i fin=%i rst=%i old=%i new=%i\n", NIPQUAD(iph->saddr), ntohs(th->source), NIPQUAD(iph->daddr), ntohs(th->dest), (th->syn ? 1 : 0), (th->ack ? 1 : 0), (th->fin ? 1 : 0), (th->rst ? 1 : 0), old_state, new_state); conntrack->proto.tcp.state = new_state; if (old_state != new_state && (new_state == TCP_CONNTRACK_FIN_WAIT || new_state == TCP_CONNTRACK_CLOSE)) conntrack->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT; timeout = conntrack->proto.tcp.retrans >= nf_ct_tcp_max_retrans && *tcp_timeouts[new_state] > nf_ct_tcp_timeout_max_retrans ? nf_ct_tcp_timeout_max_retrans : *tcp_timeouts[new_state]; write_unlock_bh(&tcp_lock); nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb); if (new_state != old_state) nf_conntrack_event_cache(IPCT_PROTOINFO, skb); if (!test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) { /* If only reply is a RST, we can consider ourselves not to have an established connection: this is a fairly common problem case, so we can delete the conntrack immediately. --RR */ if (th->rst) { if (del_timer(&conntrack->timeout)) conntrack->timeout.function((unsigned long) conntrack); return NF_ACCEPT; } } else if (!test_bit(IPS_ASSURED_BIT, &conntrack->status) && (old_state == TCP_CONNTRACK_SYN_RECV || old_state == TCP_CONNTRACK_ESTABLISHED) && new_state == TCP_CONNTRACK_ESTABLISHED) { /* Set ASSURED if we see see valid ack in ESTABLISHED after SYN_RECV or a valid answer for a picked up connection. */ set_bit(IPS_ASSURED_BIT, &conntrack->status); nf_conntrack_event_cache(IPCT_STATUS, skb); } nf_ct_refresh_acct(conntrack, ctinfo, skb, timeout); return NF_ACCEPT; }
static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack, u32 acked) { struct tcp_sock *tp = tcp_sk(sk); struct vegas *vegas = inet_csk_ca(sk); if (!vegas->doing_vegas_now) { tcp_reno_cong_avoid(sk, ack, acked); return; } if (after(ack, vegas->beg_snd_nxt)) { /* Do the Vegas once-per-RTT cwnd adjustment. */ /* Save the extent of the current window so we can use this * at the end of the next RTT. */ vegas->beg_snd_nxt = tp->snd_nxt; /* We do the Vegas calculations only if we got enough RTT * samples that we can be reasonably sure that we got * at least one RTT sample that wasn't from a delayed ACK. * If we only had 2 samples total, * then that means we're getting only 1 ACK per RTT, which * means they're almost certainly delayed ACKs. * If we have 3 samples, we should be OK. */ if (vegas->cntRTT <= 2) { /* We don't have enough RTT samples to do the Vegas * calculation, so we'll behave like Reno. */ tcp_reno_cong_avoid(sk, ack, acked); } else { u32 rtt, diff; u64 target_cwnd; /* We have enough RTT samples, so, using the Vegas * algorithm, we determine if we should increase or * decrease cwnd, and by how much. */ /* Pluck out the RTT we are using for the Vegas * calculations. This is the min RTT seen during the * last RTT. Taking the min filters out the effects * of delayed ACKs, at the cost of noticing congestion * a bit later. */ rtt = vegas->minRTT; /* Calculate the cwnd we should have, if we weren't * going too fast. * * This is: * (actual rate in segments) * baseRTT */ target_cwnd = (u64)tp->snd_cwnd * vegas->baseRTT; do_div(target_cwnd, rtt); /* Calculate the difference between the window we had, * and the window we would like to have. This quantity * is the "Diff" from the Arizona Vegas papers. */ diff = tp->snd_cwnd * (rtt-vegas->baseRTT) / vegas->baseRTT; if (diff > gamma && tcp_in_slow_start(tp)) { /* Going too fast. Time to slow down * and switch to congestion avoidance. */ /* Set cwnd to match the actual rate * exactly: * cwnd = (actual rate) * baseRTT * Then we add 1 because the integer * truncation robs us of full link * utilization. */ tp->snd_cwnd = min(tp->snd_cwnd, (u32)target_cwnd+1); tp->snd_ssthresh = tcp_vegas_ssthresh(tp); } else if (tcp_in_slow_start(tp)) { /* Slow start. */ tcp_slow_start(tp, acked); } else { /* Congestion avoidance. */ /* Figure out where we would like cwnd * to be. */ if (diff > beta) { /* The old window was too fast, so * we slow down. */ tp->snd_cwnd--; tp->snd_ssthresh = tcp_vegas_ssthresh(tp); } else if (diff < alpha) { /* We don't have enough extra packets * in the network, so speed up. */ tp->snd_cwnd++; } else { /* Sending just as fast as we * should be. */ } } if (tp->snd_cwnd < 2) tp->snd_cwnd = 2; else if (tp->snd_cwnd > tp->snd_cwnd_clamp) tp->snd_cwnd = tp->snd_cwnd_clamp; tp->snd_ssthresh = tcp_current_ssthresh(sk); } /* Wipe the slate clean for the next RTT. */ vegas->cntRTT = 0; vegas->minRTT = 0x7fffffff; } /* Use normal slow start */ else if (tcp_in_slow_start(tp)) tcp_slow_start(tp, acked); }
static int rst_socket_tcp(struct cpt_sock_image *si, loff_t pos, struct sock *sk, struct cpt_context *ctx) { struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *skb; tp->pred_flags = si->cpt_pred_flags; tp->rcv_nxt = si->cpt_rcv_nxt; tp->snd_nxt = si->cpt_snd_nxt; tp->snd_una = si->cpt_snd_una; tp->snd_sml = si->cpt_snd_sml; tp->rcv_tstamp = tcp_jiffies_import(si->cpt_rcv_tstamp); tp->lsndtime = tcp_jiffies_import(si->cpt_lsndtime); tp->tcp_header_len = si->cpt_tcp_header_len; inet_csk(sk)->icsk_ack.pending = si->cpt_ack_pending; inet_csk(sk)->icsk_ack.quick = si->cpt_quick; inet_csk(sk)->icsk_ack.pingpong = si->cpt_pingpong; inet_csk(sk)->icsk_ack.blocked = si->cpt_blocked; inet_csk(sk)->icsk_ack.ato = si->cpt_ato; inet_csk(sk)->icsk_ack.timeout = jiffies_import(si->cpt_ack_timeout); inet_csk(sk)->icsk_ack.lrcvtime = tcp_jiffies_import(si->cpt_lrcvtime); inet_csk(sk)->icsk_ack.last_seg_size = si->cpt_last_seg_size; inet_csk(sk)->icsk_ack.rcv_mss = si->cpt_rcv_mss; tp->snd_wl1 = si->cpt_snd_wl1; tp->snd_wnd = si->cpt_snd_wnd; tp->max_window = si->cpt_max_window; inet_csk(sk)->icsk_pmtu_cookie = si->cpt_pmtu_cookie; tp->mss_cache = si->cpt_mss_cache; tp->rx_opt.mss_clamp = si->cpt_mss_clamp; inet_csk(sk)->icsk_ext_hdr_len = si->cpt_ext_header_len; inet_csk(sk)->icsk_ca_state = si->cpt_ca_state; inet_csk(sk)->icsk_retransmits = si->cpt_retransmits; tp->reordering = si->cpt_reordering; tp->frto_counter = si->cpt_frto_counter; tp->frto_highmark = si->cpt_frto_highmark; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) // // tp->adv_cong = si->cpt_adv_cong; #endif inet_csk(sk)->icsk_accept_queue.rskq_defer_accept = si->cpt_defer_accept; inet_csk(sk)->icsk_backoff = si->cpt_backoff; tp->srtt = si->cpt_srtt; tp->mdev = si->cpt_mdev; tp->mdev_max = si->cpt_mdev_max; tp->rttvar = si->cpt_rttvar; tp->rtt_seq = si->cpt_rtt_seq; inet_csk(sk)->icsk_rto = si->cpt_rto; tp->packets_out = si->cpt_packets_out; tp->retrans_out = si->cpt_retrans_out; tp->lost_out = si->cpt_lost_out; tp->sacked_out = si->cpt_sacked_out; tp->fackets_out = si->cpt_fackets_out; tp->snd_ssthresh = si->cpt_snd_ssthresh; tp->snd_cwnd = si->cpt_snd_cwnd; tp->snd_cwnd_cnt = si->cpt_snd_cwnd_cnt; tp->snd_cwnd_clamp = si->cpt_snd_cwnd_clamp; tp->snd_cwnd_used = si->cpt_snd_cwnd_used; tp->snd_cwnd_stamp = tcp_jiffies_import(si->cpt_snd_cwnd_stamp); inet_csk(sk)->icsk_timeout = tcp_jiffies_import(si->cpt_timeout); tp->rcv_wnd = si->cpt_rcv_wnd; tp->rcv_wup = si->cpt_rcv_wup; tp->write_seq = si->cpt_write_seq; tp->pushed_seq = si->cpt_pushed_seq; tp->copied_seq = si->cpt_copied_seq; tp->rx_opt.tstamp_ok = si->cpt_tstamp_ok; tp->rx_opt.wscale_ok = si->cpt_wscale_ok; tp->rx_opt.sack_ok = si->cpt_sack_ok; tp->rx_opt.saw_tstamp = si->cpt_saw_tstamp; tp->rx_opt.snd_wscale = si->cpt_snd_wscale; tp->rx_opt.rcv_wscale = si->cpt_rcv_wscale; tp->nonagle = si->cpt_nonagle; tp->keepalive_probes = si->cpt_keepalive_probes; tp->rx_opt.rcv_tsval = si->cpt_rcv_tsval; tp->rx_opt.rcv_tsecr = si->cpt_rcv_tsecr; tp->rx_opt.ts_recent = si->cpt_ts_recent; tp->rx_opt.ts_recent_stamp = si->cpt_ts_recent_stamp; tp->rx_opt.user_mss = si->cpt_user_mss; tp->rx_opt.dsack = si->cpt_dsack; tp->duplicate_sack[0].start_seq = si->cpt_sack_array[0]; tp->duplicate_sack[0].end_seq = si->cpt_sack_array[1]; tp->selective_acks[0].start_seq = si->cpt_sack_array[2]; tp->selective_acks[0].end_seq = si->cpt_sack_array[3]; tp->selective_acks[1].start_seq = si->cpt_sack_array[4]; tp->selective_acks[1].end_seq = si->cpt_sack_array[5]; tp->selective_acks[2].start_seq = si->cpt_sack_array[6]; tp->selective_acks[2].end_seq = si->cpt_sack_array[7]; tp->selective_acks[3].start_seq = si->cpt_sack_array[8]; tp->selective_acks[3].end_seq = si->cpt_sack_array[9]; tp->window_clamp = si->cpt_window_clamp; tp->rcv_ssthresh = si->cpt_rcv_ssthresh; inet_csk(sk)->icsk_probes_out = si->cpt_probes_out; tp->rx_opt.num_sacks = si->cpt_num_sacks; tp->advmss = si->cpt_advmss; inet_csk(sk)->icsk_syn_retries = si->cpt_syn_retries; tp->ecn_flags = si->cpt_ecn_flags; tp->prior_ssthresh = si->cpt_prior_ssthresh; tp->high_seq = si->cpt_high_seq; tp->retrans_stamp = si->cpt_retrans_stamp; tp->undo_marker = si->cpt_undo_marker; tp->undo_retrans = si->cpt_undo_retrans; tp->urg_seq = si->cpt_urg_seq; tp->urg_data = si->cpt_urg_data; inet_csk(sk)->icsk_pending = si->cpt_pending; tp->snd_up = si->cpt_snd_up; tp->keepalive_time = si->cpt_keepalive_time; tp->keepalive_intvl = si->cpt_keepalive_intvl; tp->linger2 = si->cpt_linger2; sk->sk_send_head = NULL; for (skb = skb_peek(&sk->sk_write_queue); skb && skb != (struct sk_buff*)&sk->sk_write_queue; skb = skb->next) { if (!after(tp->snd_nxt, TCP_SKB_CB(skb)->seq)) { sk->sk_send_head = skb; break; } } if (sk->sk_state != TCP_CLOSE && sk->sk_state != TCP_LISTEN) { struct inet_sock *inet = inet_sk(sk); if (inet->num == 0) { cpt_object_t *lobj = NULL; if ((int)si->cpt_parent != -1) lobj = lookup_cpt_obj_byindex(CPT_OBJ_SOCKET, si->cpt_parent, ctx); if (lobj && lobj->o_obj) { inet->num = ntohs(inet->sport); local_bh_disable(); __inet_inherit_port(lobj->o_obj, sk); local_bh_enable(); dprintk_ctx("port inherited from parent\n"); } else { struct sock *lsk = find_parent(inet->sport, ctx); if (lsk) { inet->num = ntohs(inet->sport); local_bh_disable(); __inet_inherit_port(lsk, sk); local_bh_enable(); dprintk_ctx("port inherited\n"); } else { eprintk_ctx("we are kinda lost...\n"); } } } sk->sk_prot->hash(sk); if (inet_csk(sk)->icsk_ack.pending&ICSK_ACK_TIMER) sk_reset_timer(sk, &inet_csk(sk)->icsk_delack_timer, inet_csk(sk)->icsk_ack.timeout); if (inet_csk(sk)->icsk_pending) sk_reset_timer(sk, &inet_csk(sk)->icsk_retransmit_timer, inet_csk(sk)->icsk_timeout); if (sock_flag(sk, SOCK_KEEPOPEN)) { unsigned long expires = jiffies_import(si->cpt_ka_timeout); if (time_after(jiffies, expires)) expires = jiffies + HZ; sk_reset_timer(sk, &sk->sk_timer, expires); } } if (sk->sk_family == AF_INET6) sk->sk_gso_type = SKB_GSO_TCPV6; else sk->sk_gso_type = SKB_GSO_TCPV4; return 0; }
int AbstractTwoLevelAgreement::calculateStatisticsHelper() { common_i.clear(); common_j.clear(); nameRecallList.clear(); namePrecisionList.clear(); boundaryRecallList.clear(); boundaryPrecisionList.clear(); underNameRecallList.clear(); underNamePrecisionList.clear(); underBoundaryRecallList.clear(); underBoundaryPrecisionList.clear(); qSort(tags.begin(),tags.end()); for (int i=0;i<tags.size();i++) { tags[i].setText(text); AbstractGraph * g=tags[i].getGraph(); if (g!=NULL) g->fillTextPointers(text); } if (annotatedGraph!=NULL) annotatedGraph->fillTextPointers(text); initializeAuxiliaryCountersLists(); currentTagLists.clear(); currentOutputLists.clear(); numNames=0; underNumNames=0; numWords=0; underNumWords=0; int i=0,j=0; SelectionList tagNamesOverLap, outputNamesOverLap; while (i<tags.size() && j<outputList.size()) { int start1=tags[i].getMainStart(),end1=tags[i].getMainEnd(), start2=outputList[j].getMainStart(),end2=outputList[j].getMainEnd(); if (overLaps(start1,end1,start2,end2) && start1!=end2) { const SelectionList & tagNames=tags[i].getNamesList(), & outputNames=outputList[j].getNamesList(); bool foundI=common_i.contains(i), foundJ=common_j.contains(j); if (!foundI /*&& !foundJ*/) {//so that merged parts will not be double counted common_i.append(i); tagNamesOverLap.append(tagNames); } else { currentOutputLists.append(j); } if (!foundJ) {//common_i and common_j now are not same size, bc recall and precision need different treatment for overlap common_j.append(j); outputNamesOverLap.append(outputNames); } else { currentTagLists.append(i); } //[underboundary computations overLapMainFinished(i,j,tagNames,outputNames,underNumNames); //] int progress=0; if (end1<=end2 ) { i++; progress++; } if (end2<=end1) { j++; progress++; } if (progress==2) { //[max-boundary computations overLapMainFinished(-1,-1,tagNamesOverLap,outputNamesOverLap,numNames); //] tagNamesOverLap.clear(); outputNamesOverLap.clear(); } } else if (before(start1,end1,start2,end2)) { if (hadithParameters.detailed_statistics) { theSarf->displayed_error <</*text->mid(start1,end1-start1+1)*/i<<"\t" <<"-----\n"; } //[max-boundary computations overLapMainFinished(-1,-1,tagNamesOverLap,outputNamesOverLap,numNames); //] tagNamesOverLap.clear(); outputNamesOverLap.clear(); beforeMovingToNextTag(i,j); i++; } else if (after(start1,end1,start2,end2) ) { if (hadithParameters.detailed_statistics) { theSarf->displayed_error <<"-----\t" <</*text->mid(start2,end2-start2+1)*/j<<"\n"; } //[max-boundary computations overLapMainFinished(-1,-1,tagNamesOverLap,outputNamesOverLap,numNames); //] tagNamesOverLap.clear(); outputNamesOverLap.clear(); beforeMovingToNextOutput(i,j); j++; } } if (tagNamesOverLap.size()>0 || outputNamesOverLap.size()>0) { //[max-boundary computations overLapMainFinished(-1,-1,tagNamesOverLap,outputNamesOverLap,numNames); //] tagNamesOverLap.clear(); outputNamesOverLap.clear(); } while (i<tags.size()) { if (hadithParameters.detailed_statistics) { //int start1=tags[i].getMainStart(),end1=tags[i].getMainEnd(); theSarf->displayed_error <</*text->mid(start1,end1-start1+1)*/i<<"\t" <<"-----\n"; } beforeMovingToNextTag(i,j); i++; } while (j<outputList.size()) { if (hadithParameters.detailed_statistics) { //int start2=outputList[j].getMainStart(),end2=outputList[j].getMainEnd(); theSarf->displayed_error <<"-----\t" <</*text->mid(start2,end2-start2+1)*/j<<"\n"; beforeMovingToNextOutput(i,j); } j++; } commonCount=common_i.size(); allCommonCount=common_j.size(); correctTagsCount=tags.size(); generatedTagsCount=outputList.size(); segmentationRecall=(double)commonCount/tags.size(); segmentationPrecision=(double)allCommonCount/outputList.size(); underSegmentationRatio=(double)commonCount/allCommonCount; nameRecall=sum(nameRecallList)/numNames; namePrecision=sum(namePrecisionList)/numNames; boundaryRecall=sum(boundaryRecallList)/numWords; boundaryPrecision=sum(boundaryPrecisionList)/numWords; underNameRecall=sum(underNameRecallList)/underNumNames; underNamePrecision=sum(underNamePrecisionList)/underNumNames; underBoundaryRecall=sum(underBoundaryRecallList)/underNumWords; underBoundaryPrecision=sum(underBoundaryPrecisionList)/underNumWords; return 0; }
void AbstractTwoLevelAgreement::overLapMainFinished(int i,int j,const SelectionList & tagNames, const SelectionList & outputNames,int &numNames) { bool underComputation=(&numNames==&underNumNames); assert(underComputation || (i<0 && j<0 )); //if in max-boundary, i and j have no significance QSet<int> visitedTags; int allCommonCount; int countCommon=commonNames(tagNames,outputNames,visitedTags,allCommonCount); int countCorrect=tagNames.size(); int countDetected=outputNames.size(); assert (countCommon<=countDetected); if (countCorrect>0) { numNames+=countCorrect; double recall=(double)countCommon/countCorrect * countCorrect, precision=(double)countCommon/countDetected *countCorrect; if (countDetected==0) precision=0; if (underComputation) { underNameRecallList.append(recall); underNamePrecisionList.append(precision); } else { nameRecallList.append(recall); namePrecisionList.append(precision); } int k=0,h=0; QList<int> common_k,common_h; SelectionList tagWords, outputWords; while (k<tagNames.size() && h<outputNames.size()) { int start1=tagNames[k].first,end1=tagNames[k].second, start2=outputNames[h].first,end2=outputNames[h].second; if (overLaps(start1,end1,start2,end2) && start1!=end2) { bool foundK=common_k.contains(k), foundH=common_h.contains(h); if (underComputation) startNamesOverLap(i,j,k,h,countCommon); if (!foundK /*&& !foundJ*/) {//so that merged parts will not be double counted common_k.append(k); tagWords.append(tagNames[k]); if (foundH) { //new correctnode that matches detected if (underComputation) anotherTagOverLapPreviousOutputName(i,j,k,h); } } if (!foundH) {//common_i and common_j now are not same size, bc recall and precision need different treatment for overlap common_h.append(h); outputWords.append(outputNames[h]); if (foundK) { //new detectednode that matches correct if (underComputation) anotherOutputOverLapPreviousTagName(i,j,k,h); } } if (!foundK && !foundH) { if (underComputation) firstNameOverLap(i,j,k,h); } //[underboundary computations SelectionList singleTagWords, singleOutputWords; singleTagWords.append(tagNames[k]); singleOutputWords.append(outputNames[h]); overLapNamesFinished(singleTagWords,singleOutputWords,underNumWords); //] int process=0; if (end1<=end2 ) { k++; process++; } if (end2<=end1) { h++; process++; } if (process==2) { //[max-boundary computations overLapNamesFinished(tagWords,outputWords,numWords); //] tagWords.clear(); outputWords.clear(); } } else if (before(start1,end1,start2,end2)) { if (underComputation) beforeMovingToNextTagName(i,j,k,h); //[max-boundary computations overLapNamesFinished(tagWords,outputWords,numWords); //] tagWords.clear(); outputWords.clear(); k++; } else if (after(start1,end1,start2,end2) ) { if (underComputation) beforeMovingToNextOutputName(i,j,k,h); //[max-boundary computations overLapNamesFinished(tagWords,outputWords,numWords); //] tagWords.clear(); outputWords.clear(); h++; } } if (tagWords.size()>0 || outputWords.size()>0) { //[max-boundary computations overLapNamesFinished(tagWords,outputWords,numWords); //] tagWords.clear(); outputWords.clear(); } } else { nameRecallList.append(0); namePrecisionList.append(0); } if (underComputation) { //under computation only if (hadithParameters.detailed_statistics) { theSarf->displayed_error <</*text->mid(start1,end1-start1+1)*/i<<"\t" <</*text->mid(start2,end2-start2+1)*/j<<"\t" <<countCommon<<"/"<<countCorrect<<"\t"<<allCommonCount<<"/"<<countDetected<<"\n"; } } }
static bool tcp_in_window(const struct nf_conn *ct, struct ip_ct_tcp *state, enum ip_conntrack_dir dir, unsigned int index, const struct sk_buff *skb, unsigned int dataoff, const struct tcphdr *tcph, u_int8_t pf) { struct net *net = nf_ct_net(ct); struct ip_ct_tcp_state *sender = &state->seen[dir]; struct ip_ct_tcp_state *receiver = &state->seen[!dir]; const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple; __u32 seq, ack, sack, end, win, swin; s16 receiver_offset; bool res; seq = ntohl(tcph->seq); ack = sack = ntohl(tcph->ack_seq); win = ntohs(tcph->window); end = segment_seq_plus_len(seq, skb->len, dataoff, tcph); if (receiver->flags & IP_CT_TCP_FLAG_SACK_PERM) tcp_sack(skb, dataoff, tcph, &sack); receiver_offset = NAT_OFFSET(pf, ct, !dir, ack - 1); ack -= receiver_offset; sack -= receiver_offset; pr_debug("tcp_in_window: START\n"); pr_debug("tcp_in_window: "); nf_ct_dump_tuple(tuple); pr_debug("seq=%u ack=%u+(%d) sack=%u+(%d) win=%u end=%u\n", seq, ack, receiver_offset, sack, receiver_offset, win, end); pr_debug("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i " "receiver end=%u maxend=%u maxwin=%u scale=%i\n", sender->td_end, sender->td_maxend, sender->td_maxwin, sender->td_scale, receiver->td_end, receiver->td_maxend, receiver->td_maxwin, receiver->td_scale); if (sender->td_maxwin == 0) { if (tcph->syn) { sender->td_end = sender->td_maxend = end; sender->td_maxwin = (win == 0 ? 1 : win); tcp_options(skb, dataoff, tcph, sender); if (!(sender->flags & IP_CT_TCP_FLAG_WINDOW_SCALE && receiver->flags & IP_CT_TCP_FLAG_WINDOW_SCALE)) sender->td_scale = receiver->td_scale = 0; if (!tcph->ack) return true; } else { sender->td_end = end; swin = win << sender->td_scale; sender->td_maxwin = (swin == 0 ? 1 : swin); sender->td_maxend = end + sender->td_maxwin; if (receiver->td_maxwin == 0) receiver->td_end = receiver->td_maxend = sack; } } else if (((state->state == TCP_CONNTRACK_SYN_SENT && dir == IP_CT_DIR_ORIGINAL) || (state->state == TCP_CONNTRACK_SYN_RECV && dir == IP_CT_DIR_REPLY)) && after(end, sender->td_end)) { sender->td_end = sender->td_maxend = end; sender->td_maxwin = (win == 0 ? 1 : win); tcp_options(skb, dataoff, tcph, sender); } if (!(tcph->ack)) { ack = sack = receiver->td_end; } else if (((tcp_flag_word(tcph) & (TCP_FLAG_ACK|TCP_FLAG_RST)) == (TCP_FLAG_ACK|TCP_FLAG_RST)) && (ack == 0)) { ack = sack = receiver->td_end; } if (seq == end && (!tcph->rst || (seq == 0 && state->state == TCP_CONNTRACK_SYN_SENT))) seq = end = sender->td_end; pr_debug("tcp_in_window: "); nf_ct_dump_tuple(tuple); pr_debug("seq=%u ack=%u+(%d) sack=%u+(%d) win=%u end=%u\n", seq, ack, receiver_offset, sack, receiver_offset, win, end); pr_debug("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i " "receiver end=%u maxend=%u maxwin=%u scale=%i\n", sender->td_end, sender->td_maxend, sender->td_maxwin, sender->td_scale, receiver->td_end, receiver->td_maxend, receiver->td_maxwin, receiver->td_scale); pr_debug("tcp_in_window: I=%i II=%i III=%i IV=%i\n", before(seq, sender->td_maxend + 1), after(end, sender->td_end - receiver->td_maxwin - 1), before(sack, receiver->td_end + 1), after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1)); if (before(seq, sender->td_maxend + 1) && after(end, sender->td_end - receiver->td_maxwin - 1) && before(sack, receiver->td_end + 1) && after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1)) { if (!tcph->syn) win <<= sender->td_scale; swin = win + (sack - ack); if (sender->td_maxwin < swin) sender->td_maxwin = swin; if (after(end, sender->td_end)) { sender->td_end = end; sender->flags |= IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED; } if (tcph->ack) { if (!(sender->flags & IP_CT_TCP_FLAG_MAXACK_SET)) { sender->td_maxack = ack; sender->flags |= IP_CT_TCP_FLAG_MAXACK_SET; } else if (after(ack, sender->td_maxack)) sender->td_maxack = ack; } if (receiver->td_maxwin != 0 && after(end, sender->td_maxend)) receiver->td_maxwin += end - sender->td_maxend; if (after(sack + win, receiver->td_maxend - 1)) { receiver->td_maxend = sack + win; if (win == 0) receiver->td_maxend++; } if (ack == receiver->td_end) receiver->flags &= ~IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED; if (index == TCP_ACK_SET) { if (state->last_dir == dir && state->last_seq == seq && state->last_ack == ack && state->last_end == end && state->last_win == win) state->retrans++; else { state->last_dir = dir; state->last_seq = seq; state->last_ack = ack; state->last_end = end; state->last_win = win; state->retrans = 0; } } res = true; } else { res = false; if (sender->flags & IP_CT_TCP_FLAG_BE_LIBERAL || nf_ct_tcp_be_liberal) res = true; if (!res && LOG_INVALID(net, IPPROTO_TCP)) nf_log_packet(pf, 0, skb, NULL, NULL, NULL, "nf_ct_tcp: %s ", before(seq, sender->td_maxend + 1) ? after(end, sender->td_end - receiver->td_maxwin - 1) ? before(sack, receiver->td_end + 1) ? after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1) ? "BUG" : "ACK is under the lower bound (possible overly delayed ACK)" : "ACK is over the upper bound (ACKed data not seen yet)" : "SEQ is under the lower bound (already ACKed data retransmitted)" : "SEQ is over the upper bound (over the window of the receiver)"); } pr_debug("tcp_in_window: res=%u sender end=%u maxend=%u maxwin=%u " "receiver end=%u maxend=%u maxwin=%u\n", res, sender->td_end, sender->td_maxend, sender->td_maxwin, receiver->td_end, receiver->td_maxend, receiver->td_maxwin); return res; }
void CSSSelector::extractPseudoType() const { if (m_match != PseudoClass && m_match != PseudoElement) return; AtomicString active("active"); AtomicString after("after"); AtomicString anyLink("-webkit-any-link"); AtomicString autofill("-webkit-autofill"); AtomicString before("before"); AtomicString checked("checked"); AtomicString fileUploadButton("-webkit-file-upload-button"); AtomicString disabled("disabled"); AtomicString drag("-webkit-drag"); AtomicString dragAlias("-khtml-drag"); // was documented with this name in Apple documentation, so keep an alias AtomicString empty("empty"); AtomicString enabled("enabled"); AtomicString firstChild("first-child"); AtomicString firstLetter("first-letter"); AtomicString firstLine("first-line"); AtomicString firstOfType("first-of-type"); AtomicString nthChild("nth-child("); AtomicString nthOfType("nth-of-type("); AtomicString nthLastChild("nth-last-child("); AtomicString nthLastOfType("nth-last-of-type("); AtomicString focus("focus"); AtomicString hover("hover"); AtomicString indeterminate("indeterminate"); AtomicString lastChild("last-child"); AtomicString lastOfType("last-of-type"); AtomicString link("link"); AtomicString lang("lang("); AtomicString mediaControlsPanel("-webkit-media-controls-panel"); AtomicString mediaControlsMuteButton("-webkit-media-controls-mute-button"); AtomicString mediaControlsPlayButton("-webkit-media-controls-play-button"); AtomicString mediaControlsTimeDisplay("-webkit-media-controls-time-display"); AtomicString mediaControlsTimeline("-webkit-media-controls-timeline"); AtomicString mediaControlsSeekBackButton("-webkit-media-controls-seek-back-button"); AtomicString mediaControlsSeekForwardButton("-webkit-media-controls-seek-forward-button"); AtomicString mediaControlsFullscreenButton("-webkit-media-controls-fullscreen-button"); AtomicString notStr("not("); AtomicString onlyChild("only-child"); AtomicString onlyOfType("only-of-type"); AtomicString root("root"); AtomicString searchCancelButton("-webkit-search-cancel-button"); AtomicString searchDecoration("-webkit-search-decoration"); AtomicString searchResultsDecoration("-webkit-search-results-decoration"); AtomicString searchResultsButton("-webkit-search-results-button"); AtomicString selection("selection"); AtomicString sliderThumb("-webkit-slider-thumb"); AtomicString target("target"); AtomicString visited("visited"); bool element = false; // pseudo-element bool compat = false; // single colon compatbility mode m_pseudoType = PseudoUnknown; if (m_value == active) m_pseudoType = PseudoActive; else if (m_value == after) { m_pseudoType = PseudoAfter; element = true; compat = true; } else if (m_value == anyLink) m_pseudoType = PseudoAnyLink; else if (m_value == autofill) m_pseudoType = PseudoAutofill; else if (m_value == before) { m_pseudoType = PseudoBefore; element = true; compat = true; } else if (m_value == checked) m_pseudoType = PseudoChecked; else if (m_value == fileUploadButton) { m_pseudoType = PseudoFileUploadButton; element = true; } else if (m_value == disabled) m_pseudoType = PseudoDisabled; else if (m_value == drag || m_value == dragAlias) m_pseudoType = PseudoDrag; else if (m_value == enabled) m_pseudoType = PseudoEnabled; else if (m_value == empty) m_pseudoType = PseudoEmpty; else if (m_value == firstChild) m_pseudoType = PseudoFirstChild; else if (m_value == lastChild) m_pseudoType = PseudoLastChild; else if (m_value == lastOfType) m_pseudoType = PseudoLastOfType; else if (m_value == onlyChild) m_pseudoType = PseudoOnlyChild; else if (m_value == onlyOfType) m_pseudoType = PseudoOnlyOfType; else if (m_value == firstLetter) { m_pseudoType = PseudoFirstLetter; element = true; compat = true; } else if (m_value == firstLine) { m_pseudoType = PseudoFirstLine; element = true; compat = true; } else if (m_value == firstOfType) m_pseudoType = PseudoFirstOfType; else if (m_value == focus) m_pseudoType = PseudoFocus; else if (m_value == hover) m_pseudoType = PseudoHover; else if (m_value == indeterminate) m_pseudoType = PseudoIndeterminate; else if (m_value == link) m_pseudoType = PseudoLink; else if (m_value == lang) m_pseudoType = PseudoLang; else if (m_value == mediaControlsPanel) { m_pseudoType = PseudoMediaControlsPanel; element = true; } else if (m_value == mediaControlsMuteButton) { m_pseudoType = PseudoMediaControlsMuteButton; element = true; } else if (m_value == mediaControlsPlayButton) { m_pseudoType = PseudoMediaControlsPlayButton; element = true; } else if (m_value == mediaControlsTimeDisplay) { m_pseudoType = PseudoMediaControlsTimeDisplay; element = true; } else if (m_value == mediaControlsTimeline) { m_pseudoType = PseudoMediaControlsTimeline; element = true; } else if (m_value == mediaControlsSeekBackButton) { m_pseudoType = PseudoMediaControlsSeekBackButton; element = true; } else if (m_value == mediaControlsSeekForwardButton) { m_pseudoType = PseudoMediaControlsSeekForwardButton; element = true; } else if (m_value == mediaControlsFullscreenButton) { m_pseudoType = PseudoMediaControlsFullscreenButton; element = true; } else if (m_value == notStr) m_pseudoType = PseudoNot; else if (m_value == nthChild) m_pseudoType = PseudoNthChild; else if (m_value == nthOfType) m_pseudoType = PseudoNthOfType; else if (m_value == nthLastChild) m_pseudoType = PseudoNthLastChild; else if (m_value == nthLastOfType) m_pseudoType = PseudoNthLastOfType; else if (m_value == root) m_pseudoType = PseudoRoot; else if (m_value == searchCancelButton) { m_pseudoType = PseudoSearchCancelButton; element = true; } else if (m_value == searchDecoration) { m_pseudoType = PseudoSearchDecoration; element = true; } else if (m_value == searchResultsDecoration) { m_pseudoType = PseudoSearchResultsDecoration; element = true; } else if (m_value == searchResultsButton) { m_pseudoType = PseudoSearchResultsButton; element = true; } else if (m_value == selection) { m_pseudoType = PseudoSelection; element = true; } else if (m_value == sliderThumb) { m_pseudoType = PseudoSliderThumb; element = true; } else if (m_value == target) m_pseudoType = PseudoTarget; else if (m_value == visited) m_pseudoType = PseudoVisited; if (m_match == PseudoClass && element) { if (!compat) m_pseudoType = PseudoUnknown; else m_match = PseudoElement; } else if (m_match == PseudoElement && !element) m_pseudoType = PseudoUnknown; }
static void tcp_queue(struct tcp_stream * a_tcp, struct tcphdr * this_tcphdr, struct half_stream * snd, struct half_stream * rcv, char *data, int datalen, int skblen ) { a_tcp->lasttime = time((time_t *)0); u_int this_seq = ntohl(this_tcphdr->th_seq); struct skbuff *pakiet; /* * Did we get anything new to ack? */ if (!after(this_seq, EXP_SEQ)) { if (after(this_seq + datalen + (this_tcphdr->th_flags & TH_FIN), EXP_SEQ)) { // the packet straddles our window end get_ts(this_tcphdr, &snd->curr_ts); add_from_skb(a_tcp, rcv, snd, data, datalen, this_seq, (this_tcphdr->th_flags & TH_FIN), (this_tcphdr->th_flags & TH_URG), ntohs(this_tcphdr->th_urp) + this_seq - 1); // Do we have any old packets to ack that the above // made visible? (Go forward from skb) pakiet = rcv->list; while (pakiet) { if (after(pakiet->seq, EXP_SEQ)) break; if (after(pakiet->seq + pakiet->len + pakiet->fin, EXP_SEQ)) { struct skbuff *tmp; add_from_skb(a_tcp, rcv, snd, pakiet->data, pakiet->len, pakiet->seq, pakiet->fin, pakiet->urg, pakiet->urg_ptr + pakiet->seq - 1); rcv->rmem_alloc -= pakiet->truesize; if (pakiet->prev) pakiet->prev->next = pakiet->next; else rcv->list = pakiet->next; if (pakiet->next) pakiet->next->prev = pakiet->prev; else rcv->listtail = pakiet->prev; tmp = pakiet->next; free(pakiet->data); free(pakiet); pakiet = tmp; } else pakiet = pakiet->next; } } } else if(this_tcphdr->th_flags & TH_FIN || this_tcphdr->th_flags & TH_RST ) { pakiet = rcv->list; while (pakiet) { struct skbuff *tmp; add_from_skb(a_tcp, rcv, snd, pakiet->data, pakiet->len, pakiet->seq, pakiet->fin, pakiet->urg, pakiet->urg_ptr + pakiet->seq - 1); rcv->rmem_alloc -= pakiet->truesize; if (pakiet->prev) pakiet->prev->next = pakiet->next; else rcv->list = pakiet->next; if (pakiet->next) pakiet->next->prev = pakiet->prev; else rcv->listtail = pakiet->prev; tmp = pakiet->next; free(pakiet->data); free(pakiet); pakiet = tmp; } //free_tcp(a_tcp); } else { struct skbuff *p = rcv->listtail; pakiet = mknew(struct skbuff); pakiet->truesize = skblen; rcv->rmem_alloc += pakiet->truesize; pakiet->len = datalen; pakiet->data = malloc(datalen); if (!pakiet->data) nids_params.no_mem("tcp_queue"); memcpy(pakiet->data, data, datalen); pakiet->fin = (this_tcphdr->th_flags & TH_FIN); pakiet->seq = this_seq; pakiet->urg = (this_tcphdr->th_flags & TH_URG); pakiet->urg_ptr = ntohs(this_tcphdr->th_urp); for (;;) { /* if (!p || !after(p->seq, this_seq)) break; */ if( !p ) break; if ( !after(p->seq, this_seq)) { if( p->seq != this_seq){ break; } else { if(p->len > datalen) break; }//if_else }//if p = p->prev; }//for if (!p) { pakiet->prev = 0; pakiet->next = rcv->list; if (rcv->list) rcv->list->prev = pakiet; rcv->list = pakiet; if (!rcv->listtail) rcv->listtail = pakiet; } else { pakiet->next = p->next; p->next = pakiet; pakiet->prev = p; if (pakiet->next) pakiet->next->prev = pakiet; else rcv->listtail = pakiet; } } }
void add_from_skb(struct tcp_stream * a_tcp, struct half_stream * rcv, struct half_stream * snd, u_char *data, u_int datalen, u_int this_seq, char fin, char urg, u_int urg_ptr) { u_int lost = abs(EXP_SEQ + a_tcp->totallost - this_seq); int mylost = this_seq - EXP_SEQ -a_tcp->totallost; if(mylost > 0){ a_tcp->totallost += mylost; lost = 0; } /* else if(mylost < 0){ if(datalen <= lost) return; } */ lost = 0; if(before_seq == this_seq){ return; } before_seq = this_seq; before_len = datalen; int to_copy, to_copy2; if (urg && after(urg_ptr, EXP_SEQ - 1) && (!rcv->urg_seen || after(urg_ptr, rcv->urg_ptr))) { rcv->urg_ptr = urg_ptr; rcv->urg_seen = 1; } if (after(rcv->urg_ptr + 1, this_seq + lost) && //if 2 before(rcv->urg_ptr, this_seq + datalen)) { to_copy = rcv->urg_ptr - (this_seq + lost); if (to_copy > 0) { //if 1 if (rcv->collect) { add2buf(rcv, data + lost, to_copy); notify(a_tcp, rcv); } else { rcv->count += to_copy; rcv->offset = rcv->count; // clear the buffer } }//if 1 rcv->urgdata = data[rcv->urg_ptr - this_seq]; rcv->count_new_urg = 1; notify(a_tcp, rcv); rcv->count_new_urg = 0; rcv->urg_count++; to_copy2 = this_seq + datalen - rcv->urg_ptr - 1; if (to_copy2 > 0) {// if 4 if (rcv->collect) { add2buf(rcv, data + lost + to_copy + 1, to_copy2); notify(a_tcp, rcv); } else { rcv->count += to_copy2; rcv->offset = rcv->count; // clear the buffer } }// if 4 }// if 2 else { if (datalen -lost > 0) { if (rcv->collect) { add2buf(rcv, data + lost, datalen - lost); notify(a_tcp, rcv); } else { rcv->count += datalen - lost; rcv->offset = rcv->count; // clear the buffer } } }//else 2 if (fin) snd->state = FIN_SENT; }
int Plegal_arrangement(Ppoly_t ** polys, int n_polys) { int i, j, vno, nverts, rv; struct vertex *vertex_list; struct polygon *polygon_list; struct data input; struct intersection ilist[10000]; polygon_list = (struct polygon *) malloc(n_polys * sizeof(struct polygon)); for (i = nverts = 0; i < n_polys; i++) nverts += polys[i]->pn; vertex_list = (struct vertex *) malloc(nverts * sizeof(struct vertex)); for (i = vno = 0; i < n_polys; i++) { polygon_list[i].start = &vertex_list[vno]; for (j = 0; j < polys[i]->pn; j++) { vertex_list[vno].pos.x = polys[i]->ps[j].x; vertex_list[vno].pos.y = polys[i]->ps[j].y; vertex_list[vno].poly = &polygon_list[i]; vno++; } polygon_list[i].finish = &vertex_list[vno - 1]; } input.nvertices = nverts; input.npolygons = n_polys; find_ints(vertex_list, polygon_list, &input, ilist); #define EQ_PT(v,w) (((v).x == (w).x) && ((v).y == (w).y)) rv = 1; { int i; struct position vft, vsd, avft, avsd; for (i = 0; i < input.ninters; i++) { vft = ilist[i].firstv->pos; avft = after(ilist[i].firstv)->pos; vsd = ilist[i].secondv->pos; avsd = after(ilist[i].secondv)->pos; if (((vft.x != avft.x) && (vsd.x != avsd.x)) || ((vft.x == avft.x) && !EQ_PT(vft, ilist[i]) && !EQ_PT(avft, ilist[i])) || ((vsd.x == avsd.x) && !EQ_PT(vsd, ilist[i]) && !EQ_PT(avsd, ilist[i]))) { rv = 0; fprintf(stderr, "\nintersection %d at %.3f %.3f\n", i, ilist[i].x, ilist[i].y); fprintf(stderr, "seg#1 : (%.3f, %.3f) (%.3f, %.3f)\n", (double) (ilist[i].firstv->pos.x) , (double) (ilist[i].firstv->pos.y) , (double) (after(ilist[i].firstv)->pos.x) , (double) (after(ilist[i].firstv)->pos.y)); fprintf(stderr, "seg#2 : (%.3f, %.3f) (%.3f, %.3f)\n", (double) (ilist[i].secondv->pos.x) , (double) (ilist[i].secondv->pos.y) , (double) (after(ilist[i].secondv)->pos.x) , (double) (after(ilist[i].secondv)->pos.y)); } } } free(polygon_list); free(vertex_list); return rv; }
static int tcp_in_window(struct ip_ct_tcp *state, enum ip_conntrack_dir dir, unsigned int index, const struct sk_buff *skb, unsigned int dataoff, struct tcphdr *tcph, int pf) { struct ip_ct_tcp_state *sender = &state->seen[dir]; struct ip_ct_tcp_state *receiver = &state->seen[!dir]; __u32 seq, ack, sack, end, win; #if defined (CONFIG_RA_NAT_NONE) __u32 swin; #endif int res; /* * Get the required data from the packet. */ seq = ntohl(tcph->seq); ack = sack = ntohl(tcph->ack_seq); win = ntohs(tcph->window); end = segment_seq_plus_len(seq, skb->len, dataoff, tcph); if (receiver->flags & IP_CT_TCP_FLAG_SACK_PERM) tcp_sack(skb, dataoff, tcph, &sack); DEBUGP("tcp_in_window: START\n"); DEBUGP("tcp_in_window: src=%u.%u.%u.%u:%hu dst=%u.%u.%u.%u:%hu " "seq=%u ack=%u sack=%u win=%u end=%u\n", NIPQUAD(iph->saddr), ntohs(tcph->source), NIPQUAD(iph->daddr), ntohs(tcph->dest), seq, ack, sack, win, end); DEBUGP("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i " "receiver end=%u maxend=%u maxwin=%u scale=%i\n", sender->td_end, sender->td_maxend, sender->td_maxwin, sender->td_scale, receiver->td_end, receiver->td_maxend, receiver->td_maxwin, receiver->td_scale); if (sender->td_end == 0) { /* * Initialize sender data. */ if (tcph->syn && tcph->ack) { /* * Outgoing SYN-ACK in reply to a SYN. */ sender->td_end = sender->td_maxend = end; sender->td_maxwin = (win == 0 ? 1 : win); tcp_options(skb, dataoff, tcph, sender); /* * RFC 1323: * Both sides must send the Window Scale option * to enable window scaling in either direction. */ if (!(sender->flags & IP_CT_TCP_FLAG_WINDOW_SCALE && receiver->flags & IP_CT_TCP_FLAG_WINDOW_SCALE)) sender->td_scale = receiver->td_scale = 0; } else { /* * We are in the middle of a connection, * its history is lost for us. * Let's try to use the data from the packet. */ sender->td_end = end; sender->td_maxwin = (win == 0 ? 1 : win); sender->td_maxend = end + sender->td_maxwin; } } else if (((state->state == TCP_CONNTRACK_SYN_SENT && dir == IP_CT_DIR_ORIGINAL) || (state->state == TCP_CONNTRACK_SYN_RECV && dir == IP_CT_DIR_REPLY)) && after(end, sender->td_end)) { /* * RFC 793: "if a TCP is reinitialized ... then it need * not wait at all; it must only be sure to use sequence * numbers larger than those recently used." */ sender->td_end = sender->td_maxend = end; sender->td_maxwin = (win == 0 ? 1 : win); tcp_options(skb, dataoff, tcph, sender); } if (!(tcph->ack)) { /* * If there is no ACK, just pretend it was set and OK. */ ack = sack = receiver->td_end; } else if (((tcp_flag_word(tcph) & (TCP_FLAG_ACK|TCP_FLAG_RST)) == (TCP_FLAG_ACK|TCP_FLAG_RST)) && (ack == 0)) { /* * Broken TCP stacks, that set ACK in RST packets as well * with zero ack value. */ ack = sack = receiver->td_end; } if (seq == end && (!tcph->rst || (seq == 0 && state->state == TCP_CONNTRACK_SYN_SENT))) /* * Packets contains no data: we assume it is valid * and check the ack value only. * However RST segments are always validated by their * SEQ number, except when seq == 0 (reset sent answering * SYN. */ seq = end = sender->td_end; DEBUGP("tcp_in_window: src=%u.%u.%u.%u:%hu dst=%u.%u.%u.%u:%hu " "seq=%u ack=%u sack =%u win=%u end=%u\n", NIPQUAD(iph->saddr), ntohs(tcph->source), NIPQUAD(iph->daddr), ntohs(tcph->dest), seq, ack, sack, win, end); DEBUGP("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i " "receiver end=%u maxend=%u maxwin=%u scale=%i\n", sender->td_end, sender->td_maxend, sender->td_maxwin, sender->td_scale, receiver->td_end, receiver->td_maxend, receiver->td_maxwin, receiver->td_scale); DEBUGP("tcp_in_window: I=%i II=%i III=%i IV=%i\n", before(seq, sender->td_maxend + 1), after(end, sender->td_end - receiver->td_maxwin - 1), before(sack, receiver->td_end + 1), after(ack, receiver->td_end - MAXACKWINDOW(sender))); #if defined (CONFIG_RA_NAT_NONE) if (before(seq, sender->td_maxend + 1) && after(end, sender->td_end - receiver->td_maxwin - 1) && before(sack, receiver->td_end + 1) && after(ack, receiver->td_end - MAXACKWINDOW(sender))) { /* * Take into account window scaling (RFC 1323). */ if (!tcph->syn) win <<= sender->td_scale; /* * Update sender data. */ swin = win + (sack - ack); if (sender->td_maxwin < swin) sender->td_maxwin = swin; if (after(end, sender->td_end)) sender->td_end = end; /* * Update receiver data. */ if (after(end, sender->td_maxend)) receiver->td_maxwin += end - sender->td_maxend; if (after(sack + win, receiver->td_maxend - 1)) { receiver->td_maxend = sack + win; if (win == 0) receiver->td_maxend++; } /* * Check retransmissions. */ if (index == TCP_ACK_SET) { if (state->last_dir == dir && state->last_seq == seq && state->last_ack == ack && state->last_end == end && state->last_win == win) state->retrans++; else { state->last_dir = dir; state->last_seq = seq; state->last_ack = ack; state->last_end = end; state->last_win = win; state->retrans = 0; } } res = 1; } else { res = 0; if (sender->flags & IP_CT_TCP_FLAG_BE_LIBERAL || nf_ct_tcp_be_liberal) res = 1; if (!res && LOG_INVALID(IPPROTO_TCP)) nf_log_packet(pf, 0, skb, NULL, NULL, NULL, "nf_ct_tcp: %s ", before(seq, sender->td_maxend + 1) ? after(end, sender->td_end - receiver->td_maxwin - 1) ? before(sack, receiver->td_end + 1) ? after(ack, receiver->td_end - MAXACKWINDOW(sender)) ? "BUG" : "ACK is under the lower bound (possible overly delayed ACK)" : "ACK is over the upper bound (ACKed data not seen yet)" : "SEQ is under the lower bound (already ACKed data retransmitted)" : "SEQ is over the upper bound (over the window of the receiver)"); } #else res = 1; #endif DEBUGP("tcp_in_window: res=%i sender end=%u maxend=%u maxwin=%u " "receiver end=%u maxend=%u maxwin=%u\n", res, sender->td_end, sender->td_maxend, sender->td_maxwin, receiver->td_end, receiver->td_maxend, receiver->td_maxwin); return res; }
static void tcp_sack(const struct sk_buff *skb, unsigned int dataoff, struct tcphdr *tcph, __u32 *sack) { unsigned char buff[(15 * 4) - sizeof(struct tcphdr)]; unsigned char *ptr; int length = (tcph->doff*4) - sizeof(struct tcphdr); __u32 tmp; if (!length) return; ptr = skb_header_pointer(skb, dataoff + sizeof(struct tcphdr), length, buff); BUG_ON(ptr == NULL); /* Fast path for timestamp-only option */ if (length == TCPOLEN_TSTAMP_ALIGNED*4 && *(__be32 *)ptr == __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)) return; while (length > 0) { int opcode = *ptr++; int opsize, i; switch (opcode) { case TCPOPT_EOL: return; case TCPOPT_NOP: /* Ref: RFC 793 section 3.1 */ length--; continue; default: opsize = *ptr++; if (opsize < 2) /* "silly options" */ return; if (opsize > length) break; /* don't parse partial options */ if (opcode == TCPOPT_SACK && opsize >= (TCPOLEN_SACK_BASE + TCPOLEN_SACK_PERBLOCK) && !((opsize - TCPOLEN_SACK_BASE) % TCPOLEN_SACK_PERBLOCK)) { for (i = 0; i < (opsize - TCPOLEN_SACK_BASE); i += TCPOLEN_SACK_PERBLOCK) { tmp = ntohl(*((__be32 *)(ptr+i)+1)); if (after(tmp, *sack)) *sack = tmp; } return; } ptr += opsize - 2; length -= opsize; } } }