summaryrefslogtreecommitdiffstats
path: root/daemon/packet.c
blob: c8722f81c8f86634df2bdbdbb7b99a9dc4441f89 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include <time.h>

#include "packet.h"

#define PACKET_TIMEOUT 30

typedef struct packet_wrapper {
    time_t timestamp;
    ipq_packet_msg_t m;
} packet_wrapper_t;

static GSList *packets = NULL;
static guint n_packets = 0;
static guint total_packets = 0;

guint get_queued_packets() {
    return n_packets;
}

guint get_total_packets() {
    return total_packets;
}

void packet_new(ipq_packet_msg_t *m) {
    packet_wrapper_t *w = (packet_wrapper_t*) g_malloc(sizeof(packet_wrapper_t)+ m->data_len);
    memcpy(&w->m, m, sizeof(ipq_packet_msg_t)+ m->data_len);
    time(&w->timestamp);

    packets = g_slist_prepend(packets, w);
    n_packets++;
    total_packets++;
}

static packet_wrapper_t* _find(unsigned long id) {
    GSList *l;
    
    for (l = packets; l; l = l->next) {
        packet_wrapper_t *w = (packet_wrapper_t*) l->data;
        if (w->m.packet_id == id)
            return w;
    }

    return NULL;
}

ipq_packet_msg_t* packet_find(unsigned long id) {
    packet_wrapper_t* w;

    if ((w = _find(id)))
        return &w->m;
    
    return NULL;
}

void packet_release(unsigned long id) {
    packet_wrapper_t *w;

    w = _find(id);
    g_assert(w);
    
    packets = g_slist_remove(packets, w);
    g_free(w);
    n_packets--;
}


void packet_foreach(gboolean age, gboolean (*func)(ipq_packet_msg_t*)) {
    GSList *l, *p;

    for (l = packets, p = NULL; l;) {
        gboolean remove = FALSE;
        packet_wrapper_t *w = (packet_wrapper_t*) l->data;
        
        if (!age || w->timestamp + PACKET_TIMEOUT < time(NULL))
            if (!func(&w->m))
                remove = TRUE;

        
        
        if (remove) {
            if (p)
                p->next = l->next;
            else
                packets = l->next;
            
            g_slist_free_1(l);

            l = p;
        } else
            l = l->next;
    }
}

void packets_free() {
    while (packets) {
        packet_wrapper_t *w;
        w = (packet_wrapper_t*) packets->data;
        packets = g_slist_remove(packets, w);
        g_free(w);
    }
}