aboutsummaryrefslogtreecommitdiffstats
path: root/main/strongswan/0009-shunt-manager-Add-a-lock-to-safely-access-the-list-o.patch
blob: 6fa2c339f291d0a177fc3be372c43f72233fc361 (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
102
103
104
105
106
107
108
109
110
111
112
From f3d39666e0d62fb9a790b72ee7ae2b9255b21cdd Mon Sep 17 00:00:00 2001
From: Tobias Brunner <tobias@strongswan.org>
Date: Tue, 14 Jul 2015 16:35:21 +0200
Subject: [PATCH] shunt-manager: Add a lock to safely access the list of shunt
 policies

---
 src/libcharon/sa/shunt_manager.c | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/src/libcharon/sa/shunt_manager.c b/src/libcharon/sa/shunt_manager.c
index 73e1abb..434bace 100644
--- a/src/libcharon/sa/shunt_manager.c
+++ b/src/libcharon/sa/shunt_manager.c
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2015 Tobias Brunner
  * Copyright (C) 2011 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
@@ -20,7 +21,6 @@
 #include <threading/rwlock.h>
 #include <collections/linked_list.h>
 
-
 typedef struct private_shunt_manager_t private_shunt_manager_t;
 
 /**
@@ -37,6 +37,11 @@ struct private_shunt_manager_t {
 	 * Installed shunts, as child_cfg_t
 	 */
 	linked_list_t *shunts;
+
+	/**
+	 * Lock to safely access the list of shunts
+	 */
+	rwlock_t *lock;
 };
 
 /**
@@ -120,6 +125,7 @@ METHOD(shunt_manager_t, install, bool,
 	bool found = FALSE;
 
 	/* check if not already installed */
+	this->lock->write_lock(this->lock);
 	enumerator = this->shunts->create_enumerator(this->shunts);
 	while (enumerator->enumerate(enumerator, &child_cfg))
 	{
@@ -130,14 +136,15 @@ METHOD(shunt_manager_t, install, bool,
 		}
 	}
 	enumerator->destroy(enumerator);
-
 	if (found)
 	{
 		DBG1(DBG_CFG, "shunt %N policy '%s' already installed",
 			 ipsec_mode_names, child->get_mode(child), child->get_name(child));
+		this->lock->unlock(this->lock);
 		return TRUE;
 	}
 	this->shunts->insert_last(this->shunts, child->get_ref(child));
+	this->lock->unlock(this->lock);
 
 	return install_shunt_policy(child);
 }
@@ -215,6 +222,7 @@ METHOD(shunt_manager_t, uninstall, bool,
 	enumerator_t *enumerator;
 	child_cfg_t *child, *found = NULL;
 
+	this->lock->write_lock(this->lock);
 	enumerator = this->shunts->create_enumerator(this->shunts);
 	while (enumerator->enumerate(enumerator, &child))
 	{
@@ -226,6 +234,7 @@ METHOD(shunt_manager_t, uninstall, bool,
 		}
 	}
 	enumerator->destroy(enumerator);
+	this->lock->unlock(this->lock);
 
 	if (!found)
 	{
@@ -239,7 +248,10 @@ METHOD(shunt_manager_t, uninstall, bool,
 METHOD(shunt_manager_t, create_enumerator, enumerator_t*,
 	private_shunt_manager_t *this)
 {
-	return this->shunts->create_enumerator(this->shunts);
+	this->lock->read_lock(this->lock);
+	return enumerator_create_cleaner(
+							this->shunts->create_enumerator(this->shunts),
+							(void*)this->lock->unlock, this->lock);
 }
 
 METHOD(shunt_manager_t, destroy, void,
@@ -253,6 +265,7 @@ METHOD(shunt_manager_t, destroy, void,
 		child->destroy(child);
 	}
 	this->shunts->destroy(this->shunts);
+	this->lock->destroy(this->lock);
 	free(this);
 }
 
@@ -271,6 +284,7 @@ shunt_manager_t *shunt_manager_create()
 			.destroy = _destroy,
 		},
 		.shunts = linked_list_create(),
+		.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
 	);
 
 	return &this->public;
-- 
2.4.6