diff options
author | Florian Dold <florian.dold@gmail.com> | 2015-12-07 10:45:42 +0000 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2015-12-07 10:45:42 +0000 |
commit | 9c6313641929f6dadcd53a9dc476cd166580ac0a (patch) | |
tree | a9a21458892e2e0092053e3a86f408d7d4e7c8b0 /src/consensus/gnunet-service-consensus.c | |
parent | 24573936955722b4e2c74f215e8676dc3686f58b (diff) | |
download | gnunet-9c6313641929f6dadcd53a9dc476cd166580ac0a.tar.gz gnunet-9c6313641929f6dadcd53a9dc476cd166580ac0a.zip |
More refined evil behaviour.
Diffstat (limited to 'src/consensus/gnunet-service-consensus.c')
-rw-r--r-- | src/consensus/gnunet-service-consensus.c | 139 |
1 files changed, 117 insertions, 22 deletions
diff --git a/src/consensus/gnunet-service-consensus.c b/src/consensus/gnunet-service-consensus.c index 2192df2db..b1c8466cb 100644 --- a/src/consensus/gnunet-service-consensus.c +++ b/src/consensus/gnunet-service-consensus.c | |||
@@ -1056,26 +1056,68 @@ set_result_cb (void *cls, | |||
1056 | 1056 | ||
1057 | #ifdef EVIL | 1057 | #ifdef EVIL |
1058 | 1058 | ||
1059 | enum Evilness | 1059 | enum EvilnessType |
1060 | { | 1060 | { |
1061 | EVILNESS_NONE, | 1061 | EVILNESS_NONE, |
1062 | EVILNESS_CRAM, | 1062 | EVILNESS_CRAM_ALL, |
1063 | EVILNESS_CRAM_LEAD, | ||
1064 | EVILNESS_CRAM_ECHO, | ||
1063 | EVILNESS_SLACK, | 1065 | EVILNESS_SLACK, |
1064 | }; | 1066 | }; |
1065 | 1067 | ||
1068 | enum EvilnessSubType | ||
1069 | { | ||
1070 | EVILNESS_SUB_NONE, | ||
1071 | EVILNESS_SUB_REPLACEMENT, | ||
1072 | EVILNESS_SUB_NO_REPLACEMENT, | ||
1073 | }; | ||
1074 | |||
1075 | struct Evilness | ||
1076 | { | ||
1077 | enum EvilnessType type; | ||
1078 | enum EvilnessSubType subtype; | ||
1079 | unsigned int num; | ||
1080 | }; | ||
1081 | |||
1082 | |||
1083 | static int | ||
1084 | parse_evilness_cram_subtype (const char *evil_subtype_str, struct Evilness *evil) | ||
1085 | { | ||
1086 | if (0 == strcmp ("replace", evil_subtype_str)) | ||
1087 | { | ||
1088 | evil->subtype = EVILNESS_SUB_REPLACEMENT; | ||
1089 | } | ||
1090 | else if (0 == strcmp ("noreplace", evil_subtype_str)) | ||
1091 | { | ||
1092 | evil->subtype = EVILNESS_SUB_NO_REPLACEMENT; | ||
1093 | } | ||
1094 | else | ||
1095 | { | ||
1096 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1097 | "Malformed field '%s' in EVIL_SPEC (unknown subtype), behaving like a good peer.\n", | ||
1098 | evil_subtype_str); | ||
1099 | return GNUNET_SYSERR; | ||
1100 | } | ||
1101 | return GNUNET_OK; | ||
1102 | } | ||
1103 | |||
1104 | |||
1066 | static void | 1105 | static void |
1067 | get_evilness (struct ConsensusSession *session, enum Evilness *ret_type, unsigned int *ret_num) | 1106 | get_evilness (struct ConsensusSession *session, struct Evilness *evil) |
1068 | { | 1107 | { |
1069 | char *evil_spec; | 1108 | char *evil_spec; |
1070 | char *field; | 1109 | char *field; |
1071 | char *evil_type_str = NULL; | 1110 | char *evil_type_str = NULL; |
1111 | char *evil_subtype_str = NULL; | ||
1112 | |||
1113 | GNUNET_assert (NULL != evil); | ||
1072 | 1114 | ||
1073 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, "consensus", "EVIL_SPEC", &evil_spec)) | 1115 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, "consensus", "EVIL_SPEC", &evil_spec)) |
1074 | { | 1116 | { |
1075 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1117 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1076 | "P%u: no evilness\n", | 1118 | "P%u: no evilness\n", |
1077 | session->local_peer_idx); | 1119 | session->local_peer_idx); |
1078 | *ret_type = EVILNESS_NONE; | 1120 | evil->type = EVILNESS_NONE; |
1079 | return; | 1121 | return; |
1080 | } | 1122 | } |
1081 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1123 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -1091,30 +1133,54 @@ get_evilness (struct ConsensusSession *session, enum Evilness *ret_type, unsigne | |||
1091 | int ret; | 1133 | int ret; |
1092 | 1134 | ||
1093 | evil_type_str = NULL; | 1135 | evil_type_str = NULL; |
1136 | evil_subtype_str = NULL; | ||
1094 | 1137 | ||
1095 | ret = sscanf (field, "%u;%m[a-z];%u", &peer_num, &evil_type_str, &evil_num); | 1138 | ret = sscanf (field, "%u;%m[a-z-];%m[a-z-];%u", &peer_num, &evil_type_str, &evil_subtype_str, &evil_num); |
1096 | 1139 | ||
1097 | if (ret != 3) | 1140 | if (ret != 4) |
1098 | { | 1141 | { |
1099 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Malformed field '%s' in EVIL_SPEC, behaving like a good peer.\n", | 1142 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
1100 | field); | 1143 | "Malformed field '%s' in EVIL_SPEC (expected 4 components got %d), behaving like a good peer.\n", |
1144 | field, | ||
1145 | ret); | ||
1101 | goto not_evil; | 1146 | goto not_evil; |
1102 | } | 1147 | } |
1103 | 1148 | ||
1104 | GNUNET_assert (NULL != evil_type_str); | 1149 | GNUNET_assert (NULL != evil_type_str); |
1150 | GNUNET_assert (NULL != evil_subtype_str); | ||
1105 | 1151 | ||
1106 | if (peer_num == session->local_peer_idx) | 1152 | if (peer_num == session->local_peer_idx) |
1107 | { | 1153 | { |
1108 | if (0 == strcmp ("slack", evil_type_str)) | 1154 | if (0 == strcmp ("slack", evil_type_str)) |
1109 | *ret_type = EVILNESS_SLACK; | ||
1110 | else if (0 == strcmp ("cram", evil_type_str)) | ||
1111 | { | 1155 | { |
1112 | *ret_type = EVILNESS_CRAM; | 1156 | evil->type = EVILNESS_SLACK; |
1113 | *ret_num = evil_num; | 1157 | } |
1158 | else if (0 == strcmp ("cram-all", evil_type_str)) | ||
1159 | { | ||
1160 | evil->type = EVILNESS_CRAM_ALL; | ||
1161 | evil->num = evil_num; | ||
1162 | if (GNUNET_OK != parse_evilness_cram_subtype (evil_subtype_str, evil)) | ||
1163 | goto not_evil; | ||
1164 | } | ||
1165 | else if (0 == strcmp ("cram-lead", evil_type_str)) | ||
1166 | { | ||
1167 | evil->type = EVILNESS_CRAM_LEAD; | ||
1168 | evil->num = evil_num; | ||
1169 | if (GNUNET_OK != parse_evilness_cram_subtype (evil_subtype_str, evil)) | ||
1170 | goto not_evil; | ||
1171 | } | ||
1172 | else if (0 == strcmp ("cram-echo", evil_type_str)) | ||
1173 | { | ||
1174 | evil->type = EVILNESS_CRAM_ECHO; | ||
1175 | evil->num = evil_num; | ||
1176 | if (GNUNET_OK != parse_evilness_cram_subtype (evil_subtype_str, evil)) | ||
1177 | goto not_evil; | ||
1114 | } | 1178 | } |
1115 | else | 1179 | else |
1116 | { | 1180 | { |
1117 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Malformed field '%s' in EVIL_SPEC (unknown type), behaving like a good peer.\n"); | 1181 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
1182 | "Malformed field '%s' in EVIL_SPEC (unknown type), behaving like a good peer.\n", | ||
1183 | evil_type_str); | ||
1118 | goto not_evil; | 1184 | goto not_evil; |
1119 | } | 1185 | } |
1120 | goto cleanup; | 1186 | goto cleanup; |
@@ -1122,13 +1188,18 @@ get_evilness (struct ConsensusSession *session, enum Evilness *ret_type, unsigne | |||
1122 | /* No GNUNET_free since memory was allocated by libc */ | 1188 | /* No GNUNET_free since memory was allocated by libc */ |
1123 | free (evil_type_str); | 1189 | free (evil_type_str); |
1124 | evil_type_str = NULL; | 1190 | evil_type_str = NULL; |
1191 | evil_subtype_str = NULL; | ||
1125 | } | 1192 | } |
1126 | not_evil: | 1193 | not_evil: |
1127 | *ret_type = EVILNESS_NONE; | 1194 | evil->type = EVILNESS_NONE; |
1128 | cleanup: | 1195 | cleanup: |
1129 | GNUNET_free (evil_spec); | 1196 | GNUNET_free (evil_spec); |
1197 | /* no GNUNET_free_non_null since it wasn't | ||
1198 | * allocated with GNUNET_malloc */ | ||
1130 | if (NULL != evil_type_str) | 1199 | if (NULL != evil_type_str) |
1131 | free (evil_type_str); | 1200 | free (evil_type_str); |
1201 | if (NULL != evil_subtype_str) | ||
1202 | free (evil_subtype_str); | ||
1132 | } | 1203 | } |
1133 | 1204 | ||
1134 | #endif | 1205 | #endif |
@@ -1152,13 +1223,14 @@ commit_set (struct ConsensusSession *session, | |||
1152 | #ifdef EVIL | 1223 | #ifdef EVIL |
1153 | { | 1224 | { |
1154 | unsigned int i; | 1225 | unsigned int i; |
1155 | unsigned int evil_num; | 1226 | struct Evilness evil; |
1156 | enum Evilness evilness; | ||
1157 | 1227 | ||
1158 | get_evilness (session, &evilness, &evil_num); | 1228 | get_evilness (session, &evil); |
1159 | switch (evilness) | 1229 | switch (evil.type) |
1160 | { | 1230 | { |
1161 | case EVILNESS_CRAM: | 1231 | case EVILNESS_CRAM_ALL: |
1232 | case EVILNESS_CRAM_LEAD: | ||
1233 | case EVILNESS_CRAM_ECHO: | ||
1162 | /* We're not cramming elements in the | 1234 | /* We're not cramming elements in the |
1163 | all-to-all round, since that would just | 1235 | all-to-all round, since that would just |
1164 | add more elements to the result set, but | 1236 | add more elements to the result set, but |
@@ -1168,7 +1240,17 @@ commit_set (struct ConsensusSession *session, | |||
1168 | GNUNET_SET_commit (setop->op, set->h); | 1240 | GNUNET_SET_commit (setop->op, set->h); |
1169 | break; | 1241 | break; |
1170 | } | 1242 | } |
1171 | for (i = 0; i < evil_num; i++) | 1243 | if ((EVILNESS_CRAM_LEAD == evil.type) && (PHASE_KIND_GRADECAST_LEADER != task->key.kind)) |
1244 | { | ||
1245 | GNUNET_SET_commit (setop->op, set->h); | ||
1246 | break; | ||
1247 | } | ||
1248 | if (EVILNESS_CRAM_ECHO == evil.type && (PHASE_KIND_GRADECAST_ECHO != task->key.kind)) | ||
1249 | { | ||
1250 | GNUNET_SET_commit (setop->op, set->h); | ||
1251 | break; | ||
1252 | } | ||
1253 | for (i = 0; i < evil.num; i++) | ||
1172 | { | 1254 | { |
1173 | struct GNUNET_HashCode hash; | 1255 | struct GNUNET_HashCode hash; |
1174 | struct GNUNET_SET_Element element; | 1256 | struct GNUNET_SET_Element element; |
@@ -1176,7 +1258,20 @@ commit_set (struct ConsensusSession *session, | |||
1176 | element.size = sizeof (struct GNUNET_HashCode); | 1258 | element.size = sizeof (struct GNUNET_HashCode); |
1177 | element.element_type = 0; | 1259 | element.element_type = 0; |
1178 | 1260 | ||
1179 | GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_STRONG, &hash); | 1261 | if (EVILNESS_SUB_REPLACEMENT == evil.subtype) |
1262 | { | ||
1263 | /* Always generate a new element. */ | ||
1264 | GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, &hash); | ||
1265 | } | ||
1266 | else if (EVILNESS_SUB_NO_REPLACEMENT == evil.subtype) | ||
1267 | { | ||
1268 | /* Always cram the same elements, derived from counter. */ | ||
1269 | GNUNET_CRYPTO_hash (&i, sizeof (i), &hash); | ||
1270 | } | ||
1271 | else | ||
1272 | { | ||
1273 | GNUNET_assert (0); | ||
1274 | } | ||
1180 | GNUNET_SET_add_element (set->h, &element, NULL, NULL); | 1275 | GNUNET_SET_add_element (set->h, &element, NULL, NULL); |
1181 | #ifdef GNUNET_EXTRA_LOGGING | 1276 | #ifdef GNUNET_EXTRA_LOGGING |
1182 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 1277 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
@@ -1193,7 +1288,7 @@ commit_set (struct ConsensusSession *session, | |||
1193 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 1288 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
1194 | "P%u: evil peer: slacking\n", | 1289 | "P%u: evil peer: slacking\n", |
1195 | session->local_peer_idx, | 1290 | session->local_peer_idx, |
1196 | evil_num); | 1291 | evil.num); |
1197 | /* Do nothing. */ | 1292 | /* Do nothing. */ |
1198 | break; | 1293 | break; |
1199 | case EVILNESS_NONE: | 1294 | case EVILNESS_NONE: |