summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDimitri Staessens <[email protected]>2018-02-22 22:35:29 +0100
committerSander Vrijders <[email protected]>2018-02-23 11:18:35 +0100
commit22b347b44bb2db453080b596e018669cae229e17 (patch)
treeef0561aef60c1960c9f01c95d1512e6be69a1477 /src
parentf51cea125561a2a080d05d802e8ccb2bb169320b (diff)
downloadouroboros-22b347b44bb2db453080b596e018669cae229e17.tar.gz
ouroboros-22b347b44bb2db453080b596e018669cae229e17.zip
ipcpd: Fix missing lock in link-state policy
The replication of the database was missing a lock. Now the database is first copied under lock and then sent. Signed-off-by: Dimitri Staessens <[email protected]> Signed-off-by: Sander Vrijders <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/ipcpd/normal/pol/link_state.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/src/ipcpd/normal/pol/link_state.c b/src/ipcpd/normal/pol/link_state.c
index 179a3448..61469b94 100644
--- a/src/ipcpd/normal/pol/link_state.c
+++ b/src/ipcpd/normal/pol/link_state.c
@@ -528,13 +528,40 @@ static void send_lsm(uint64_t src,
static void lsdb_replicate(int fd)
{
struct list_head * p;
+ struct list_head * h;
+ struct list_head copy;
+
+ list_head_init(&copy);
+
+ /* Lock the lsdb, copy the lsms and send outside of lock. */
+ pthread_rwlock_rdlock(&ls.db_lock);
list_for_each(p, &ls.db) {
+ struct adjacency * adj;
+ struct adjacency * cpy;
+ adj = list_entry(p, struct adjacency, next);
+ cpy = malloc(sizeof(*cpy));
+ if (cpy == NULL) {
+ log_warn("Failed to replicate full lsdb.");
+ break;
+ }
+
+ cpy->dst = adj->dst;
+ cpy->src = adj->src;
+
+ list_add_tail(&cpy->next, &copy);
+ }
+
+ pthread_rwlock_unlock(&ls.db_lock);
+
+ list_for_each_safe(p, h, &copy) {
struct lsa lsm;
struct adjacency * adj;
adj = list_entry(p, struct adjacency, next);
lsm.d_addr = hton64(adj->dst);
lsm.s_addr = hton64(adj->src);
+ list_del(&adj->next);
+ free(adj);
flow_write(fd, &lsm, sizeof(lsm));
}
}