sybilsim.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. /* vim: set expandtab ts=4 sw=4: */
  2. /*
  3. * You may redistribute this program and/or modify it under the terms of
  4. * the GNU General Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. */
  15. #include "benc/serialization/standard/BencMessageReader.h"
  16. #include "benc/serialization/standard/BencMessageWriter.h"
  17. #include "benc/serialization/json/JsonBencSerializer.h"
  18. #include "benc/serialization/BencSerializer.h"
  19. #include "benc/List.h"
  20. #include "io/ArrayReader.h"
  21. #include "admin/angel/Core.h"
  22. #include "client/AdminClient.h"
  23. #include "interface/ASynchronizer.h"
  24. #include "interface/addressable/AddrIfaceAdapter.h"
  25. #include "memory/Allocator.h"
  26. #include "util/log/FileWriterLog.h"
  27. #include "wire/Message.h"
  28. #include "util/events/EventBase.h"
  29. #include "crypto/random/Random.h"
  30. #include "crypto/random/nanotime/NanotimeEntropyProvider.h"
  31. #include "exception/Except.h"
  32. #include "util/events/Timeout.h"
  33. #include "crypto/Key.h"
  34. #include "util/log/Log_impl.h"
  35. #include "io/FileReader.h"
  36. #include "io/ArrayWriter.h"
  37. #include "util/Hex.h"
  38. #include "util/events/FakeNetwork.h"
  39. #include "util/Hash.h"
  40. #include <sodium/crypto_scalarmult_curve25519.h>
  41. #include <unistd.h> // isatty()
  42. struct NodeContext {
  43. struct Sockaddr* boundAddr;
  44. struct Allocator* alloc;
  45. struct EventBase* base;
  46. uint8_t privateKey[32];
  47. String* publicKey;
  48. struct AdminClient* adminClient;
  49. struct Admin* admin;
  50. char* nodeName;
  51. /** Admin socket to bind */
  52. String* bind;
  53. /** Admin password */
  54. String* pass;
  55. /** UDPInterface */
  56. int ifNum;
  57. struct Sockaddr* udpAddr;
  58. struct Log nodeLog;
  59. struct Log* parentLogger;
  60. List* peers;
  61. Identity
  62. };
  63. struct RPCCall;
  64. typedef void (* RPCCallback)(struct RPCCall* call, struct AdminClient_Result* res);
  65. struct RPCCall
  66. {
  67. String* func;
  68. Dict* args;
  69. struct NodeContext* node;
  70. RPCCallback callback;
  71. };
  72. #define Map_KEY_TYPE String*
  73. #define Map_VALUE_TYPE struct NodeContext*
  74. #define Map_NAME OfNodes
  75. #define Map_USE_COMPARATOR
  76. #define Map_USE_HASH
  77. #include "util/Map.h"
  78. static inline int Map_OfNodes_compare(String** a, String** b)
  79. {
  80. return String_compare(*a, *b);
  81. }
  82. static inline uint32_t Map_OfNodes_hash(String** a)
  83. {
  84. return Hash_compute(a[0]->bytes, a[0]->len);
  85. }
  86. struct Context
  87. {
  88. struct RPCCall* rpcCalls;
  89. int rpcCallCount;
  90. int nextCall;
  91. struct Allocator* rpcAlloc;
  92. struct Random* rand;
  93. struct EventBase* base;
  94. struct Log* logger;
  95. struct Allocator* alloc;
  96. struct Map_OfNodes nodeMap;
  97. Dict* confNodes;
  98. Identity
  99. };
  100. static String* pubKeyForPriv(uint8_t* privateKey, struct Allocator* alloc)
  101. {
  102. uint8_t publicKey[32];
  103. crypto_scalarmult_curve25519_base(publicKey, privateKey);
  104. return Key_stringify(publicKey, alloc);
  105. }
  106. static void printLog(struct Log* log,
  107. enum Log_Level logLevel,
  108. const char* file,
  109. int line,
  110. const char* format,
  111. va_list args)
  112. {
  113. struct NodeContext* ctx = Identity_check(
  114. (struct NodeContext*) (((char*)log) - offsetof(struct NodeContext, nodeLog))
  115. );
  116. struct Allocator* alloc = Allocator_child(ctx->alloc);
  117. String* str = String_printf(alloc, "[%s] %s", ctx->nodeName, file);
  118. ctx->parentLogger->print(ctx->parentLogger, logLevel, str->bytes, line, format, args);
  119. Allocator_free(alloc);
  120. }
  121. static struct RPCCall* pushCall(struct Context* ctx)
  122. {
  123. ctx->rpcCalls = Allocator_realloc(ctx->rpcAlloc,
  124. ctx->rpcCalls,
  125. sizeof(struct RPCCall) * (ctx->rpcCallCount+1));
  126. Bits_memset(&ctx->rpcCalls[ctx->rpcCallCount], 0, sizeof(struct RPCCall));
  127. return &ctx->rpcCalls[ctx->rpcCallCount++];
  128. }
  129. static void bindUDPCallback(struct RPCCall* call, struct AdminClient_Result* res)
  130. {
  131. Assert_true(!res->err);
  132. // Indirection to shutup clang warning
  133. struct Log* logger = &call->node->nodeLog;
  134. Log_debug(logger, "UDPInterface_new() -> [%s]", res->messageBytes);
  135. String* addr = Dict_getStringC(res->responseDict, "bindAddress");
  136. int64_t* ifNum = Dict_getIntC(res->responseDict, "interfaceNumber");
  137. struct Sockaddr_storage ss;
  138. Assert_true(!Sockaddr_parse(addr->bytes, &ss));
  139. call->node->ifNum = *ifNum;
  140. call->node->udpAddr = Sockaddr_clone(&ss.addr, call->node->alloc);
  141. }
  142. static void bindUDP(struct Context* ctx, struct NodeContext* node)
  143. {
  144. struct RPCCall* call = pushCall(ctx);
  145. call->func = String_new("UDPInterface_new", ctx->rpcAlloc);
  146. call->args = Dict_new(ctx->rpcAlloc);
  147. call->node = node;
  148. call->callback = bindUDPCallback;
  149. }
  150. static void securitySetupComplete(struct Context* ctx, struct NodeContext* node)
  151. {
  152. struct RPCCall* call = pushCall(ctx);
  153. call->func = String_new("Security_setupComplete", ctx->rpcAlloc);
  154. call->args = Dict_new(ctx->rpcAlloc);
  155. call->node = node;
  156. }
  157. static struct NodeContext* startNode(char* nodeName,
  158. char* privateKeyHex,
  159. Dict* admin,
  160. struct Context* ctx,
  161. struct Except* eh,
  162. struct FakeNetwork* fakeNet)
  163. {
  164. struct Allocator* alloc = Allocator_child(ctx->alloc);
  165. struct NodeContext* node = Allocator_clone(alloc, (&(struct NodeContext) {
  166. .alloc = alloc,
  167. .base = ctx->base,
  168. .nodeLog = {
  169. .print = printLog
  170. },
  171. .parentLogger = ctx->logger,
  172. .nodeName = nodeName
  173. }));
  174. Identity_set(node);
  175. node->bind = Dict_getStringC(admin, "bind");
  176. if (!node->bind) {
  177. node->bind = String_new("127.0.0.1:0", alloc);
  178. }
  179. node->pass = Dict_getStringC(admin, "password");
  180. if (!node->pass) {
  181. node->pass = String_new("x", alloc);
  182. }
  183. Assert_true(Hex_decode(node->privateKey, 32, privateKeyHex, 64) == 32);
  184. struct AddrIfaceAdapter* adminClientIface = AddrIfaceAdapter_new(node->alloc);
  185. struct AddrIfaceAdapter* adminIface = AddrIfaceAdapter_new(node->alloc);
  186. struct ASynchronizer* asyncer = ASynchronizer_new(node->alloc, ctx->base, ctx->logger);
  187. Iface_plumb(&asyncer->ifA, &adminClientIface->inputIf);
  188. Iface_plumb(&asyncer->ifB, &adminIface->inputIf);
  189. String* pass = String_new("12345", node->alloc);
  190. node->adminClient = AdminClient_new(&adminClientIface->generic,
  191. Sockaddr_clone(Sockaddr_LOOPBACK, node->alloc),
  192. pass,
  193. ctx->base,
  194. &node->nodeLog,
  195. node->alloc);
  196. node->admin = Admin_new(&adminIface->generic, &node->nodeLog, ctx->base, pass);
  197. Core_init(node->alloc,
  198. &node->nodeLog,
  199. ctx->base,
  200. node->privateKey,
  201. node->admin,
  202. ctx->rand,
  203. eh,
  204. fakeNet,
  205. true);
  206. securitySetupComplete(ctx, node);
  207. bindUDP(ctx, node);
  208. node->publicKey = pubKeyForPriv(node->privateKey, node->alloc);
  209. return node;
  210. }
  211. static void beginConnectionCallback(struct RPCCall* call, struct AdminClient_Result* res)
  212. {
  213. Assert_true(!res->err);
  214. // Indirection to shutup clang warning
  215. struct Log* logger = &call->node->nodeLog;
  216. Log_debug(logger, "UDPInterface_beginConnection() -> [%s]", res->messageBytes);
  217. }
  218. static void linkNodes(struct Context* ctx, struct NodeContext* client, struct NodeContext* server)
  219. {
  220. Dict* addPasswordArgs = Dict_new(ctx->rpcAlloc);
  221. String* clientStr = String_printf(ctx->rpcAlloc, "%ld", (long) (uintptr_t) client);
  222. Dict_putString(addPasswordArgs,
  223. String_new("password", ctx->rpcAlloc),
  224. clientStr,
  225. ctx->rpcAlloc);
  226. Dict_putString(addPasswordArgs,
  227. String_new("user", ctx->rpcAlloc),
  228. clientStr,
  229. ctx->rpcAlloc);
  230. struct RPCCall* addPasswordCall = pushCall(ctx);
  231. addPasswordCall->func = String_new("AuthorizedPasswords_add", ctx->rpcAlloc);
  232. addPasswordCall->args = addPasswordArgs;
  233. addPasswordCall->node = server;
  234. // client
  235. Dict* beginConnectionArgs = Dict_new(ctx->rpcAlloc);
  236. Dict_putInt(beginConnectionArgs,
  237. String_new("interfaceNumber", ctx->rpcAlloc),
  238. client->ifNum,
  239. ctx->rpcAlloc);
  240. Dict_putString(beginConnectionArgs,
  241. String_new("password", ctx->rpcAlloc),
  242. clientStr,
  243. ctx->rpcAlloc);
  244. Dict_putString(beginConnectionArgs,
  245. String_new("publicKey", ctx->rpcAlloc),
  246. server->publicKey,
  247. ctx->rpcAlloc);
  248. char* udpAddr = Sockaddr_print(server->udpAddr, ctx->rpcAlloc);
  249. Dict_putString(beginConnectionArgs,
  250. String_new("address", ctx->rpcAlloc),
  251. String_new(udpAddr, ctx->rpcAlloc),
  252. ctx->rpcAlloc);
  253. Log_info(ctx->logger, "Linking [%s] with [%s/%s]",
  254. client->nodeName, server->nodeName, udpAddr);
  255. struct RPCCall* connectCall = pushCall(ctx);
  256. connectCall->func = String_new("UDPInterface_beginConnection", ctx->rpcAlloc);
  257. connectCall->args = beginConnectionArgs;
  258. connectCall->node = client;
  259. connectCall->callback = beginConnectionCallback;
  260. }
  261. static void linkAllNodes(struct Context* ctx)
  262. {
  263. int i = 0;
  264. String* key = NULL;
  265. Dict_forEach(ctx->confNodes, key) {
  266. int nodeIdx = Map_OfNodes_indexForKey(&key, &ctx->nodeMap);
  267. Assert_true(nodeIdx >= 0);
  268. struct NodeContext* nc = ctx->nodeMap.values[nodeIdx];
  269. List* connectTo = nc->peers;
  270. for (int j = 0; j < List_size(connectTo); j++) {
  271. String* server = List_getString(connectTo, j);
  272. Assert_true(server);
  273. int nodeIdxB = Map_OfNodes_indexForKey(&server, &ctx->nodeMap);
  274. Assert_true(nodeIdxB >= 0);
  275. struct NodeContext* ncB = ctx->nodeMap.values[nodeIdxB];
  276. linkNodes(ctx, nc, ncB);
  277. }
  278. i++;
  279. }
  280. ctx->confNodes = NULL;
  281. }
  282. static void startRpc(void* vcontext);
  283. static void rpcCallback(struct AdminClient_Promise* promise, struct AdminClient_Result* res)
  284. {
  285. struct Context* ctx = promise->userData;
  286. Identity_check(ctx);
  287. struct RPCCall* thisCall = &ctx->rpcCalls[ctx->nextCall];
  288. if (thisCall->callback) {
  289. thisCall->callback(thisCall, res);
  290. }
  291. ctx->nextCall++;
  292. startRpc(ctx);
  293. }
  294. static void startRpc(void* vcontext)
  295. {
  296. struct Context* ctx = vcontext;
  297. Identity_check(ctx);
  298. if (ctx->nextCall >= ctx->rpcCallCount) {
  299. if (ctx->confNodes) {
  300. linkAllNodes(ctx);
  301. }
  302. }
  303. if (ctx->nextCall >= ctx->rpcCallCount) {
  304. Log_info(ctx->logger, "\n\nCompleted setting up simulation\n\n");
  305. Allocator_free(ctx->rpcAlloc);
  306. ctx->rpcAlloc = NULL;
  307. ctx->rpcCalls = NULL;
  308. ctx->rpcCallCount = 0;
  309. return;
  310. }
  311. struct RPCCall* nextCall = &ctx->rpcCalls[ctx->nextCall];
  312. struct AdminClient_Promise* promise = AdminClient_rpcCall(nextCall->func,
  313. nextCall->args,
  314. nextCall->node->adminClient,
  315. ctx->rpcAlloc);
  316. promise->callback = rpcCallback;
  317. promise->userData = ctx;
  318. }
  319. static void letErRip(Dict* config, struct Allocator* alloc)
  320. {
  321. struct Except* eh = NULL;
  322. struct Log* logger = FileWriterLog_new(stdout, alloc);
  323. struct EventBase* base = EventBase_new(alloc);
  324. struct Random* rand = NanotimeEntropyProvider_newDefaultRandom(base, logger, eh, alloc);
  325. Allocator_setCanary(alloc, (uintptr_t)Random_uint64(rand));
  326. struct Context sctx = {
  327. .rpcAlloc = Allocator_child(alloc),
  328. .logger = logger,
  329. .base = base,
  330. .rand = rand,
  331. .alloc = alloc,
  332. .nodeMap = {
  333. .allocator = alloc
  334. }
  335. };
  336. struct Context* ctx = &sctx;
  337. Identity_set(ctx);
  338. ctx->confNodes = Dict_getDictC(config, "nodes");
  339. struct FakeNetwork* fakeNet = FakeNetwork_new(base, alloc, logger);
  340. String* key = NULL;
  341. Dict_forEach(ctx->confNodes, key) {
  342. Dict* val = Dict_getDict(ctx->confNodes, key);
  343. String* privateKeyHex = Dict_getStringC(val, "privateKey");
  344. Dict* admin = Dict_getDictC(val, "admin");
  345. struct NodeContext* nc =
  346. startNode(key->bytes, privateKeyHex->bytes, admin, ctx, eh, fakeNet);
  347. nc->peers = Dict_getListC(val, "peers");
  348. Map_OfNodes_put(&key, &nc, &ctx->nodeMap);
  349. }
  350. Log_info(ctx->logger, "\n\nAll nodes initialized\n\n");
  351. // begin the chain of RPC calls which sets up the net
  352. Timeout_setTimeout(startRpc, ctx, 0, base, ctx->rpcAlloc);
  353. EventBase_beginLoop(base);
  354. Allocator_free(alloc);
  355. }
  356. static int usage(char* appName)
  357. {
  358. printf("Example usage: %s < config.json\n"
  359. "Example config:\n"
  360. "{\n"
  361. " \"nodes\": {\n"
  362. " \"alice\": {\n"
  363. " \"privateKey\": "
  364. "\"5e2295679394e5e1db67c238abbc10292ad9b127904394c52cc5fff39383e920\",\n"
  365. " \"peers\": []\n"
  366. " },\n"
  367. " \"bob\": {\n"
  368. " \"privateKey\": "
  369. "\"6569bf3f0d168faa6dfb2912f8ee5ee9b938319e97618fdf06caed73b1aad1cc\",\n"
  370. " \"peers\": [\n"
  371. " \"alice\"\n"
  372. " ]\n"
  373. " }\n"
  374. " }\n"
  375. "}\n", appName);
  376. return 0;
  377. }
  378. // This is invoked from sybilsim.rs
  379. int sybilsim_main(int argc, char** argv);
  380. int sybilsim_main(int argc, char** argv)
  381. {
  382. Assert_true(argc > 0);
  383. if (isatty(STDIN_FILENO)) {
  384. return usage(argv[0]);
  385. }
  386. struct Allocator* alloc = Allocator_new(1LL<<31);
  387. struct Reader* stdinReader = FileReader_new(stdin, alloc);
  388. Dict config;
  389. if (JsonBencSerializer_get()->parseDictionary(stdinReader, alloc, &config)) {
  390. fprintf(stderr, "Failed to parse configuration.\n");
  391. return -1;
  392. }
  393. letErRip(&config, alloc);
  394. return 0;
  395. }