KeySync: pEpEngine.c : surrounded sequence value generation and checking with SQL BEGIN and COMMIT, to ensure atomicity of operations. sync_impl.c : ensure that incomming keysync message sequence value isn't zero, otherwise always accepted
authorEdouard Tisserant <edouard@pep-project.org>
Mon, 06 Feb 2017 21:07:12 +0100
changeset 15684af26e1915f1
parent 1567 7e51ef02ab31
child 1569 01285fc24d20
child 1570 d03c8137e926
KeySync: pEpEngine.c : surrounded sequence value generation and checking with SQL BEGIN and COMMIT, to ensure atomicity of operations. sync_impl.c : ensure that incomming keysync message sequence value isn't zero, otherwise always accepted
src/pEpEngine.c
src/sync_impl.c
     1.1 --- a/src/pEpEngine.c	Tue Jan 31 16:10:48 2017 +0100
     1.2 +++ b/src/pEpEngine.c	Mon Feb 06 21:07:12 2017 +0100
     1.3 @@ -2004,6 +2004,7 @@
     1.4      )
     1.5  {
     1.6      PEP_STATUS status = PEP_STATUS_OK;
     1.7 +    int result;
     1.8  
     1.9      assert(session);
    1.10      assert(name && value && *value >= 0);
    1.11 @@ -2024,27 +2025,52 @@
    1.12      }
    1.13  
    1.14      if (*value) {
    1.15 +        sqlite3_exec(session->db, "BEGIN ;", NULL, NULL, NULL);
    1.16          int32_t old_value = 0;
    1.17          status = _get_sequence_value(session, name, &old_value);
    1.18          if (status != PEP_STATUS_OK && status != PEP_RECORD_NOT_FOUND)
    1.19 +        {
    1.20 +            sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
    1.21              return status;
    1.22 +        }
    1.23  
    1.24          if (old_value >= *value) {
    1.25 +            sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
    1.26              return PEP_SEQUENCE_VIOLATED;
    1.27          }
    1.28          else {
    1.29              status = _set_sequence_value(session, name, *value, own);
    1.30 -            return status;
    1.31 +            if (status == PEP_STATUS_OK) {
    1.32 +                result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
    1.33 +                if (result == SQLITE_OK)
    1.34 +                    return PEP_STATUS_OK;
    1.35 +                else
    1.36 +                    return PEP_COMMIT_FAILED;
    1.37 +            } else {
    1.38 +                sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
    1.39 +                return status;
    1.40 +            }
    1.41          }
    1.42      }
    1.43  
    1.44      assert(*value == 0);
    1.45 +    sqlite3_exec(session->db, "BEGIN ;", NULL, NULL, NULL);
    1.46      status = _increment_sequence_value(session, name, own);
    1.47      if (status == PEP_STATUS_OK) {
    1.48          status = _get_sequence_value(session, name, value);
    1.49 -        assert(*value < INT32_MAX);
    1.50 -        if (*value == INT32_MAX)
    1.51 -            return PEP_CANNOT_INCREASE_SEQUENCE;
    1.52 +        result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
    1.53 +        if (result == SQLITE_OK){
    1.54 +            assert(*value < INT32_MAX);
    1.55 +            if (*value == INT32_MAX){
    1.56 +                return PEP_CANNOT_INCREASE_SEQUENCE;
    1.57 +            }
    1.58 +            return PEP_STATUS_OK;
    1.59 +        } else {
    1.60 +            return PEP_COMMIT_FAILED;
    1.61 +        }
    1.62 +    } else {
    1.63 +        sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
    1.64 +        return status;
    1.65      }
    1.66      return status;
    1.67  }
     2.1 --- a/src/sync_impl.c	Tue Jan 31 16:10:48 2017 +0100
     2.2 +++ b/src/sync_impl.c	Mon Feb 06 21:07:12 2017 +0100
     2.3 @@ -346,8 +346,12 @@
     2.4                  }
     2.5  
     2.6                  int32_t value = (int32_t) msg->header.sequence;
     2.7 -                status = sequence_value(session, (char *) user_id,
     2.8 -                        &value);
     2.9 +                if (value < 1) {
    2.10 +                    status = PEP_SEQUENCE_VIOLATED;
    2.11 +                } else {
    2.12 +                    status = sequence_value(session, (char *) user_id,
    2.13 +                            &value);
    2.14 +                }
    2.15  
    2.16                  if (status == PEP_STATUS_OK) {
    2.17                      switch (msg->payload.present) {