aboutsummaryrefslogtreecommitdiff
path: root/src/consensus/gnunet-service-consensus.c
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2015-12-07 10:45:42 +0000
committerFlorian Dold <florian.dold@gmail.com>2015-12-07 10:45:42 +0000
commit9c6313641929f6dadcd53a9dc476cd166580ac0a (patch)
treea9a21458892e2e0092053e3a86f408d7d4e7c8b0 /src/consensus/gnunet-service-consensus.c
parent24573936955722b4e2c74f215e8676dc3686f58b (diff)
downloadgnunet-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.c139
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
1059enum Evilness 1059enum 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
1068enum EvilnessSubType
1069{
1070 EVILNESS_SUB_NONE,
1071 EVILNESS_SUB_REPLACEMENT,
1072 EVILNESS_SUB_NO_REPLACEMENT,
1073};
1074
1075struct Evilness
1076{
1077 enum EvilnessType type;
1078 enum EvilnessSubType subtype;
1079 unsigned int num;
1080};
1081
1082
1083static int
1084parse_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
1066static void 1105static void
1067get_evilness (struct ConsensusSession *session, enum Evilness *ret_type, unsigned int *ret_num) 1106get_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 }
1126not_evil: 1193not_evil:
1127 *ret_type = EVILNESS_NONE; 1194 evil->type = EVILNESS_NONE;
1128cleanup: 1195cleanup:
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: