diff options
Diffstat (limited to 'src/testbed/testbed_api.c')
-rw-r--r-- | src/testbed/testbed_api.c | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/src/testbed/testbed_api.c b/src/testbed/testbed_api.c index 90b0e06c8..d946b7082 100644 --- a/src/testbed/testbed_api.c +++ b/src/testbed/testbed_api.c | |||
@@ -36,6 +36,7 @@ | |||
36 | 36 | ||
37 | #include "testbed.h" | 37 | #include "testbed.h" |
38 | #include "testbed_api.h" | 38 | #include "testbed_api.h" |
39 | #include "testbed_api_barriers.h" | ||
39 | #include "testbed_api_hosts.h" | 40 | #include "testbed_api_hosts.h" |
40 | #include "testbed_api_peers.h" | 41 | #include "testbed_api_peers.h" |
41 | #include "testbed_api_operations.h" | 42 | #include "testbed_api_operations.h" |
@@ -1047,6 +1048,118 @@ handle_link_controllers_result (void *cls, | |||
1047 | 1048 | ||
1048 | 1049 | ||
1049 | /** | 1050 | /** |
1051 | * Validate #GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS message. | ||
1052 | * | ||
1053 | * @param cls the controller handle to determine the connection this message | ||
1054 | * belongs to | ||
1055 | * @param msg the barrier status message | ||
1056 | * @return #GNUNET_OK if the message is valid; #GNUNET_SYSERR to tear it | ||
1057 | * down signalling an error (message malformed) | ||
1058 | */ | ||
1059 | static int | ||
1060 | check_barrier_status_ (struct GNUNET_TESTBED_Controller *c, | ||
1061 | const struct GNUNET_TESTBED_BarrierStatusMsg *msg) | ||
1062 | { | ||
1063 | uint16_t msize; | ||
1064 | uint16_t name_len; | ||
1065 | int status; | ||
1066 | const char *name; | ||
1067 | size_t emsg_len; | ||
1068 | |||
1069 | msize = ntohs (msg->header.size); | ||
1070 | name = msg->data; | ||
1071 | name_len = ntohs (msg->name_len); | ||
1072 | |||
1073 | if (sizeof (struct GNUNET_TESTBED_BarrierStatusMsg) + name_len + 1 > msize) | ||
1074 | { | ||
1075 | GNUNET_break_op (0); | ||
1076 | return GNUNET_SYSERR; | ||
1077 | } | ||
1078 | if ('\0' != name[name_len]) | ||
1079 | { | ||
1080 | GNUNET_break_op (0); | ||
1081 | return GNUNET_SYSERR; | ||
1082 | } | ||
1083 | status = ntohs (msg->status); | ||
1084 | if (GNUNET_TESTBED_BARRIERSTATUS_ERROR == status) | ||
1085 | { | ||
1086 | emsg_len = msize - (sizeof (struct GNUNET_TESTBED_BarrierStatusMsg) + name_len | ||
1087 | + 1); /* +1!? */ | ||
1088 | if (0 == emsg_len) | ||
1089 | { | ||
1090 | GNUNET_break_op (0); | ||
1091 | return GNUNET_SYSERR; | ||
1092 | } | ||
1093 | } | ||
1094 | return GNUNET_OK; | ||
1095 | } | ||
1096 | |||
1097 | |||
1098 | /** | ||
1099 | * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS messages | ||
1100 | * | ||
1101 | * @param c the controller handle to determine the connection this message | ||
1102 | * belongs to | ||
1103 | * @param msg the barrier status message | ||
1104 | */ | ||
1105 | static void | ||
1106 | handle_barrier_status_ (struct GNUNET_TESTBED_Controller *c, | ||
1107 | const struct GNUNET_TESTBED_BarrierStatusMsg *msg) | ||
1108 | { | ||
1109 | struct GNUNET_TESTBED_Barrier *barrier; | ||
1110 | char *emsg; | ||
1111 | const char *name; | ||
1112 | struct GNUNET_HashCode key; | ||
1113 | size_t emsg_len; | ||
1114 | int status; | ||
1115 | uint16_t msize; | ||
1116 | uint16_t name_len; | ||
1117 | |||
1118 | emsg = NULL; | ||
1119 | barrier = NULL; | ||
1120 | msize = ntohs (msg->header.size); | ||
1121 | name = msg->data; | ||
1122 | name_len = ntohs (msg->name_len); | ||
1123 | LOG_DEBUG ("Received BARRIER_STATUS msg\n"); | ||
1124 | status = ntohs (msg->status); | ||
1125 | if (GNUNET_TESTBED_BARRIERSTATUS_ERROR == status) | ||
1126 | { | ||
1127 | status = -1; | ||
1128 | emsg_len = msize - (sizeof (struct GNUNET_TESTBED_BarrierStatusMsg) + name_len | ||
1129 | + 1); | ||
1130 | emsg = GNUNET_malloc (emsg_len + 1); | ||
1131 | memcpy (emsg, | ||
1132 | msg->data + name_len + 1, | ||
1133 | emsg_len); | ||
1134 | } | ||
1135 | if (NULL == c->barrier_map) | ||
1136 | { | ||
1137 | GNUNET_break_op (0); | ||
1138 | goto cleanup; | ||
1139 | } | ||
1140 | GNUNET_CRYPTO_hash (name, name_len, &key); | ||
1141 | barrier = GNUNET_CONTAINER_multihashmap_get (c->barrier_map, &key); | ||
1142 | if (NULL == barrier) | ||
1143 | { | ||
1144 | GNUNET_break_op (0); | ||
1145 | goto cleanup; | ||
1146 | } | ||
1147 | GNUNET_assert (NULL != barrier->cb); | ||
1148 | if ((GNUNET_YES == barrier->echo) && | ||
1149 | (GNUNET_TESTBED_BARRIERSTATUS_CROSSED == status)) | ||
1150 | GNUNET_TESTBED_queue_message_ (c, GNUNET_copy_message (&msg->header)); | ||
1151 | barrier->cb (barrier->cls, name, barrier, status, emsg); | ||
1152 | if (GNUNET_TESTBED_BARRIERSTATUS_INITIALISED == status) | ||
1153 | return; /* just initialised; skip cleanup */ | ||
1154 | |||
1155 | cleanup: | ||
1156 | GNUNET_free_non_null (emsg); | ||
1157 | if (NULL != barrier) | ||
1158 | GNUNET_TESTBED_barrier_remove_ (barrier); | ||
1159 | } | ||
1160 | |||
1161 | |||
1162 | /** | ||
1050 | * Handler for messages from controller (testbed service) | 1163 | * Handler for messages from controller (testbed service) |
1051 | * | 1164 | * |
1052 | * @param cls the controller handler | 1165 | * @param cls the controller handler |