summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Hutchings <ben@decadent.org.uk>2016-01-22 19:34:41 +0000
committerBen Hutchings <ben@decadent.org.uk>2016-01-28 15:38:28 +0000
commitd277ddb78abd034eb0e1c088ac969cdeef10d9e2 (patch)
tree60c9bb30db4d27cdb0a29599e653bb4661d3dbc3
parent6326ab374ede4fff1e8019a50d4b9854b8db7625 (diff)
downloadodhcp6c-d277ddb78abd034eb0e1c088ac969cdeef10d9e2.tar.gz
Fix iteration after expiring a list entry
After removing an entry, the next entry will be at the same offset as the entry we just removed. Also the total length will have changed. Update the length when we remove an entry, and advance the offset only when we don't. Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
-rw-r--r--src/odhcp6c.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/src/odhcp6c.c b/src/odhcp6c.c
index 1714d62..59f6390 100644
--- a/src/odhcp6c.c
+++ b/src/odhcp6c.c
@@ -619,7 +619,7 @@ static void odhcp6c_expire_list(enum odhcp6c_state state, uint32_t elapsed)
uint8_t *start = odhcp6c_get_state(state, &len);
for (struct odhcp6c_entry *c = (struct odhcp6c_entry*)start;
(uint8_t*)c < &start[len] && &c->auxtarget[c->auxlen] <= &start[len];
- c = (struct odhcp6c_entry*)(&c->auxtarget[c->auxlen])) {
+ ) {
if (c->t1 < elapsed)
c->t1 = 0;
else if (c->t1 != UINT32_MAX)
@@ -640,8 +640,12 @@ static void odhcp6c_expire_list(enum odhcp6c_state state, uint32_t elapsed)
else if (c->valid != UINT32_MAX)
c->valid -= elapsed;
- if (!c->valid)
+ if (!c->valid) {
odhcp6c_remove_state(state, ((uint8_t*)c) - start, sizeof(*c) + c->auxlen);
+ start = odhcp6c_get_state(state, &len);
+ } else {
+ c = (struct odhcp6c_entry*)(&c->auxtarget[c->auxlen]);
+ }
}
}