PUD: remove debug code
[olsrd.git] / lib / pud / src / dedup.c
1 #include "dedup.h"
2
3 /* Plugin includes */
4
5 /* OLSR includes */
6 #include "olsr.h"
7
8 /* System includes */
9 #include <assert.h>
10
11 /* Defines */
12
13 #define LISTSIZE(x)                     ((x)->entriesMaxCount) /* always valid */
14 #define NEWESTINDEX(x)          ((x)->newestEntryIndex) /* always valid */
15 #define WRAPINDEX(x, i)         ((i) % LISTSIZE(x)) /* always valid for i>=0 */
16 #define INCOMINGINDEX(x)        WRAPINDEX(x, (NEWESTINDEX(x) + LISTSIZE(x) - 1)) /* always valid */
17
18 /**
19  Initialise the de-duplication list: allocate memory for the entries and
20  reset fields.
21
22  @param deDupList
23  The de-duplication list
24  @param maxEntries
25  The maximum number of entries in the list (the number of messages that should
26  be tracked)
27
28  @return
29  - false on failure
30  - true otherwise
31  */
32 bool initDeDupList(DeDupList * deDupList, unsigned long long maxEntries) {
33         pthread_mutexattr_t attr;
34         void * p;
35
36         if (deDupList == NULL) {
37                 return false;
38         }
39         if (maxEntries < 1) {
40                 return false;
41         }
42
43         if (pthread_mutexattr_init(&attr)) {
44                 return false;
45         }
46         if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP)) {
47                 return false;
48         }
49         if (pthread_mutex_init(&deDupList->mutex, &attr)) {
50                 return false;
51         }
52
53         p = olsr_malloc(maxEntries * sizeof(DeDupEntry),
54                         "DeDupEntry entries for DeDupList (PUD)");
55         if (p == NULL) {
56                 return false;
57         }
58
59         deDupList->entriesMaxCount = maxEntries;
60         deDupList->entries = p;
61
62         deDupList->entriesCount = 0;
63         deDupList->newestEntryIndex = 0;
64
65         return true;
66 }
67
68 /**
69  Clean up the de-duplication list: free memory and reset fields.
70
71  @param deDupList
72  The de-duplication list
73  */
74 void destroyDeDupList(DeDupList * deDupList) {
75         assert (deDupList != NULL);
76
77         (void) pthread_mutex_lock(&deDupList->mutex);
78
79         if (deDupList->entries != NULL) {
80                 free(deDupList->entries);
81                 deDupList->entries = NULL;
82         }
83
84         deDupList->entriesMaxCount = 0;
85
86         deDupList->entriesCount = 0;
87         deDupList->newestEntryIndex = 0;
88
89         (void) pthread_mutex_unlock(&deDupList->mutex);
90
91         pthread_mutex_destroy(&deDupList->mutex);
92 }
93
94 /**
95  Add a new (incoming) message to the de-duplication list
96
97  @param deDupList
98  The de-duplication list
99  @param olsrMessage
100  The message
101  */
102 void addToDeDup(DeDupList * deDupList, union olsr_message *olsrMessage) {
103         unsigned long long incomingIndex;
104         DeDupEntry * newEntry;
105
106         assert (deDupList != NULL);
107
108         (void) pthread_mutex_lock(&deDupList->mutex);
109
110         incomingIndex = INCOMINGINDEX(deDupList);
111         newEntry = &deDupList->entries[incomingIndex];
112
113         memset(newEntry, 0, sizeof(DeDupEntry));
114         if (olsr_cnf->ip_version == AF_INET) {
115                 newEntry->seqno = olsrMessage->v4.seqno;
116                 newEntry->originator.v4.s_addr = olsrMessage->v4.originator;
117         } else {
118                 newEntry->seqno = olsrMessage->v6.seqno;
119                 newEntry->originator.v6 = olsrMessage->v6.originator;
120         }
121
122         deDupList->newestEntryIndex = incomingIndex;
123         if (deDupList->entriesCount < deDupList->entriesMaxCount) {
124                 deDupList ->entriesCount++;
125         }
126
127         (void) pthread_mutex_unlock(&deDupList->mutex);
128 }
129
130 /**
131  Determines whether a new (incoming) message is already in the de-duplication
132  list
133
134  @param deDupList
135  The de-duplication list
136  @param olsrMessage
137  The message
138
139  @return
140  - true when the message is already in the list
141  - false otherwise
142  */
143 bool isInDeDupList(DeDupList * deDupList, union olsr_message *olsrMessage) {
144         bool retval = false;
145         unsigned long long iteratedIndex;
146         unsigned long long count;
147
148         (void) pthread_mutex_lock(&deDupList->mutex);
149
150         iteratedIndex = NEWESTINDEX(deDupList);
151         count = deDupList->entriesCount;
152
153         /* we iterate from newest until oldest: we have a higher probability to
154          * match on the newest entries */
155
156         while (count > 0) {
157                 DeDupEntry * iteratedEntry = &deDupList->entries[iteratedIndex];
158                 if (olsr_cnf->ip_version == AF_INET) {
159                         if ((iteratedEntry->seqno == olsrMessage->v4.seqno) && (memcmp(
160                                         &iteratedEntry->originator.v4, &olsrMessage->v4.originator,
161                                         sizeof(iteratedEntry->originator.v4))) == 0) {
162                                 retval = true;
163                                 break;
164                         }
165                 } else {
166                         if ((iteratedEntry->seqno == olsrMessage->v6.seqno) && (memcmp(
167                                         &iteratedEntry->originator.v6, &olsrMessage->v6.originator,
168                                         sizeof(iteratedEntry->originator.v6)) == 0)) {
169                                 retval = true;
170                                 break;
171                         }
172                 }
173
174                 iteratedIndex = WRAPINDEX(deDupList, iteratedIndex + 1); /* go the the next older entry */
175                 count--;
176         }
177
178         (void) pthread_mutex_unlock(&deDupList->mutex);
179
180         return retval;
181 }