sybilsim.c 15 KB

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