<commit_before>/* KallistiOS ##version##

   kernel/net/net_ipv4_frag.c
   Copyright (C) 2009 <NAME>

*/

#include <string.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <arpa/inet.h>

#include <kos/net.h>
#include <kos/mutex.h>
#include <arch/timer.h>
#include <arch/irq.h>

#include "net_ipv4.h"
#include "net_thd.h"

#define MAX(a, b) a > b ? a : b;

struct ip_frag {
    TAILQ_ENTRY(ip_frag) listhnd;

    uint32 src;
    uint32 dst;
    uint16 ident;
    uint8 proto;

    ip_hdr_t hdr;
    uint8 *data;
    uint8 bitfield[8192];
    int cur_length;
    int total_length;
    uint64 death_time;
};

TAILQ_HEAD(ip_frag_list, ip_frag);

static struct ip_frag_list frags;
static mutex_t *frag_mutex = NULL;
static int cbid = -1;

/* IP fragment "thread" -- this thread is set up to delete fragments for which
   the "death_time" has passed. This is run approximately once every two
   seconds (since death_time is always on the order of seconds). */
static void frag_thd_cb(void *data __attribute__((unused))) {
    struct ip_frag *f, *n;
    uint64 now = timer_ms_gettime64();

    mutex_lock(frag_mutex);

    /* Look at each fragment item, and see if the timer has expired. If so,
       remvoe it. */
    TAILQ_FOREACH(f, &frags, listhnd) {
        n = TAILQ_NEXT(f, listhnd);

        if(f->death_time < now) {
            TAILQ_REMOVE(&frags, f, listhnd);
            free(f->data);
            free(f);
            f = n;
        }
    }

    mutex_unlock(frag_mutex);
}

/* Set the bits in the bitfield for the given set of fragment blocks. */
static inline void set_bits(uint8 *bitfield, int start, int end) {
    /* Use a slightly more efficient method when dealing with an end that is not
       in the same byte as the start. */
    if((end >> 3) > (start >> 3)) {
        int bits = start & 0x07;

        /* Finish off anything in the start byte... */
        while(bits && bits < 8) {
            bitfield[start >> 3] |= (1 << bits);
            ++bits;
        }

        /* ...and the start of the end byte. */
        bits = end & 0x07;
        bitfield[end >> 3] |= (1 << bits) - 1;
<commit_msg>Fix stupid possible bug in cleaning up the fragment list.<commit_after>/* KallistiOS ##version##

   kernel/net/net_ipv4_frag.c
   Copyright (C) 2009 <NAME>

*/

#include <string.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <arpa/inet.h>

#include <kos/net.h>
#include <kos/mutex.h>
#include <arch/timer.h>
#include <arch/irq.h>

#include "net_ipv4.h"
#include "net_thd.h"

#define MAX(a, b) a > b ? a : b;

struct ip_frag {
    TAILQ_ENTRY(ip_frag) listhnd;

    uint32 src;
    uint32 dst;
    uint16 ident;
    uint8 proto;

    ip_hdr_t hdr;
    uint8 *data;
    uint8 bitfield[8192];
    int cur_length;
    int total_length;
    uint64 death_time;
};

TAILQ_HEAD(ip_frag_list, ip_frag);

static struct ip_frag_list frags;
static mutex_t *frag_mutex = NULL;
static int cbid = -1;

/* IP fragment "thread" -- this thread is set up to delete fragments for which
   the "death_time" has passed. This is run approximately once every two
   seconds (since death_time is always on the order of seconds). */
static void frag_thd_cb(void *data __attribute__((unused))) {
    struct ip_frag *f, *n;
    uint64 now = timer_ms_gettime64();

    mutex_lock(frag_mutex);

    /* Look at each fragment item, and see if the timer has expired. If so,
       remvoe it. */
    f = TAILQ_FIRST(&frags);
    while(f) {
        n = TAILQ_NEXT(f, listhnd);

        if(f->death_time < now) {
            TAILQ_REMOVE(&frags, f, listhnd);
            free(f->data);
            free(f);
        }

        f = n;
    }

    mutex_unlock(frag_mutex);
}

/* Set the bits in the bitfield for the given set of fragment blocks. */
static inline void set_bits(uint8 *bitfield, int start, int end) {
    /* Use a slightly more efficient method when dealing with an end that is not
       in the same byte as the start. */
    if((end >> 3) > (start >> 3)) {
        int bits = start & 0x07;

        /* Finish off anything in the start byte... */
        while(bits && bits < 8) {
            bitfield[start >> 3] |= (1 << bits);
            ++bits;
        }

        /* ...and the start of the end byte. */
        bits = end & 0x07;
        bitfield[end >> 3] |= (1 << bits) - 1;

{'fraction_non_alphanumeric': 0.12416184971098265, 'fraction_numerical': 0.018959537572254336, 'mean_word_length': 2.4802896218825423, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 47, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3277750', 'n_tokens_mistral': 1587, 'n_tokens_neox': 1509, 'n_words': 479}