static void newInterface2(struct Context* ctx, struct Sockaddr* addr, String* txid) { struct Allocator* const alloc = Allocator_child(ctx->allocator); struct UDPInterface* udpIf = NULL; struct Jmp jmp; Jmp_try(jmp) { udpIf = UDPInterface_new(ctx->eventBase, addr, alloc, &jmp.handler, ctx->logger, ctx->ic); } Jmp_catch { String* errStr = String_CONST(jmp.message); Dict out = Dict_CONST(String_CONST("error"), String_OBJ(errStr), NULL); Admin_sendMessage(&out, txid, ctx->admin); Allocator_free(alloc); } // sizeof(struct UDPInterface*) the size of a pointer. ctx->ifaces = Allocator_realloc(ctx->allocator, ctx->ifaces, sizeof(struct UDPInterface*) * (ctx->ifCount + 1)); ctx->ifaces[ctx->ifCount] = udpIf; Dict out = Dict_CONST( String_CONST("error"), String_OBJ(String_CONST("none")), Dict_CONST( String_CONST("interfaceNumber"), Int_OBJ(ctx->ifCount), NULL )); Admin_sendMessage(&out, txid, ctx->admin); ctx->ifCount++; }
int main(int argc, char** argv) { struct Allocator* alloc = MallocAllocator_new(1<<20); struct EventBase* base = EventBase_new(alloc); struct Writer* logWriter = FileWriter_new(stdout, alloc); struct Log* logger = WriterLog_new(logWriter, alloc); // mock interface controller. struct InterfaceController ic = { .registerPeer = registerPeer }; struct Sockaddr_storage addr; Assert_always(!Sockaddr_parse("127.0.0.1", &addr)); struct UDPInterface* udpA = UDPInterface_new(base, &addr.addr, alloc, NULL, logger, &ic); struct UDPInterface* udpB = UDPInterface_new(base, &addr.addr, alloc, NULL, logger, &ic); struct Message* msg; Message_STACK(msg, 0, 128); Message_push(msg, "Hello World", 12, NULL); Message_push(msg, udpA->addr, udpA->addr->addrLen, NULL); struct Interface* ifA = &((struct UDPInterface_pvt*) udpA)->udpBase->generic; struct Interface* ifB = &((struct UDPInterface_pvt*) udpB)->udpBase->generic; ifA->receiveMessage = receiveMessageA; ifB->receiveMessage = receiveMessageB; ifB->receiverContext = alloc; struct Allocator* child = Allocator_child(alloc); msg = Message_clone(msg, child); ifB->sendMessage(msg, ifB); Allocator_free(child); Timeout_setTimeout(fail, NULL, 1000, base, alloc); EventBase_beginLoop(base); return 0; }
static void newInterface(Dict* args, void* vcontext, String* txid) { struct Context* const ctx = vcontext; String* const bindAddress = Dict_getString(args, String_CONST("bindAddress")); struct Allocator* const alloc = ctx->allocator->child(ctx->allocator); struct UDPInterface* udpIf = NULL; struct Jmp jmp; Jmp_try(jmp) { char* const bindBytes = (bindAddress) ? bindAddress->bytes : NULL; udpIf = UDPInterface_new( ctx->eventBase, bindBytes, alloc, &jmp.handler, ctx->logger, ctx->ic); } Jmp_catch { String* errStr = String_CONST(jmp.message); Dict out = Dict_CONST(String_CONST("error"), String_OBJ(errStr), NULL); if (jmp.code == UDPInterface_new_SOCKET_FAILED || jmp.code == UDPInterface_new_BIND_FAILED) { char* err = strerror(EVUTIL_SOCKET_ERROR()); Dict out2 = Dict_CONST(String_CONST("cause"), String_OBJ(String_CONST(err)), out); Admin_sendMessage(&out2, txid, ctx->admin); } else { Admin_sendMessage(&out, txid, ctx->admin); } alloc->free(alloc); return; } // sizeof(struct UDPInterface*) the size of a pointer. ctx->ifaces = ctx->allocator->realloc(ctx->ifaces, sizeof(struct UDPInterface*) * (ctx->ifCount + 1), ctx->allocator); ctx->ifaces[ctx->ifCount] = udpIf; Dict out = Dict_CONST( String_CONST("error"), String_OBJ(String_CONST("none")), Dict_CONST( String_CONST("interfaceNumber"), Int_OBJ(ctx->ifCount), NULL )); Admin_sendMessage(&out, txid, ctx->admin); ctx->ifCount++; }
static void configureUDP(Dict* config, struct Context* ctx) { String* bindStr = Dict_getString(config, BSTR("bind")); char* bindAddress = bindStr ? bindStr->bytes : NULL; struct UDPInterface* udpContext = UDPInterface_new(ctx->base, bindAddress, ctx->allocator, ctx->eHandler, ctx->logger); if (bindStr) { struct Interface* udpDefault = UDPInterface_getDefaultInterface(udpContext); struct Interface* authedDef = CryptoAuth_wrapInterface(udpDefault, NULL, true, true, ctx->ca); struct UDPInterfaceContext* uictx = ctx->allocator->malloc(sizeof(struct UDPInterfaceContext), ctx->allocator); uictx->context = ctx; uictx->udpContext = udpContext; authedDef->receiveMessage = serverFirstIncoming; authedDef->receiverContext = uictx; } Dict* connectTo = Dict_getDict(config, BSTR("connectTo")); if (connectTo) { struct Dict_Entry* entry = *connectTo; while (entry != NULL) { String* key = (String*) entry->key; if (entry->val->type != Object_DICT) { fprintf(stderr, "interfaces.UDPInterface.connectTo: entry %s is not a dictionary type.\n", key->bytes); abort(); } Dict* value = entry->val->as.dictionary; udpConnectTo(key, value, udpContext, ctx); entry = entry->next; } } }