aboutsummaryrefslogtreecommitdiffstats
path: root/src/libhydra/plugins/attr_sql
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2013-09-13 13:25:49 +0200
committerTobias Brunner <tobias@strongswan.org>2013-10-11 15:16:05 +0200
commit5abe3c52d396339f3e1ac5f5a63cb8a4dfa0209d (patch)
tree920eed6c686d2b71b88974fa25a45b5e0c1a1819 /src/libhydra/plugins/attr_sql
parent4b8b1354cea559844d7cbf2e460e90dab3655fad (diff)
downloadstrongswan-5abe3c52d396339f3e1ac5f5a63cb8a4dfa0209d.tar.bz2
strongswan-5abe3c52d396339f3e1ac5f5a63cb8a4dfa0209d.tar.xz
attr-sql: Handle concurrent insertion of identities
If the same identity is added concurrently by two threads (or by the pool utility) INSERT might fail even though the SELECT was unsuccessful before. We are currently not able to lock the identities table in a portable way (something like SELECT ... FOR UPDATE on MySQL).
Diffstat (limited to 'src/libhydra/plugins/attr_sql')
-rw-r--r--src/libhydra/plugins/attr_sql/sql_attribute.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/src/libhydra/plugins/attr_sql/sql_attribute.c b/src/libhydra/plugins/attr_sql/sql_attribute.c
index cad5bfae3..20c606ef3 100644
--- a/src/libhydra/plugins/attr_sql/sql_attribute.c
+++ b/src/libhydra/plugins/attr_sql/sql_attribute.c
@@ -50,19 +50,24 @@ static u_int get_identity(private_sql_attribute_t *this, identification_t *id)
{
enumerator_t *e;
u_int row;
+ int try = 0;
+retry:
/* look for peer identity in the identities table */
e = this->db->query(this->db,
"SELECT id FROM identities WHERE type = ? AND data = ?",
DB_INT, id->get_type(id), DB_BLOB, id->get_encoding(id),
DB_UINT);
-
if (e && e->enumerate(e, &row))
{
e->destroy(e);
return row;
}
DESTROY_IF(e);
+ if (try > 0)
+ {
+ return 0;
+ }
/* not found, insert new one */
if (this->db->execute(this->db, &row,
"INSERT INTO identities (type, data) VALUES (?, ?)",
@@ -70,7 +75,12 @@ static u_int get_identity(private_sql_attribute_t *this, identification_t *id)
{
return row;
}
- return 0;
+ /* the INSERT could fail due to the UNIQUE constraint, if the identity was
+ * added concurrently by another thread or the pool utility,
+ * therefore try finding it again. a nicer fix would be to use locking
+ * on the database, but our API currently not supports that */
+ try++;
+ goto retry;
}
/**