/* Check which IP versions are supported by the system. */ void checkIPversions() { int testsocket = -1; testsocket = socket(PF_INET, SOCK_STREAM, 0); hasv4 = (errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT) ? false : true; if (!(testsocket < 0)) close(testsocket); testsocket = socket(PF_INET6, SOCK_STREAM, 0); hasv6 = (errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT) ? false : true; if (!(testsocket < 0)) close(testsocket); if(!hasv4) { Log_info("IPv4 is not supported by this system"); nofServerSocks -= 2; } if(!hasv6) { Log_info("IPv6 is not supported by this system"); nofServerSocks -= 2; } if(nofServerSocks == 0) { Log_fatal("Neither IPv4 nor IPv6 are supported by this system"); } }
static int get(struct RandomSeed* rs, uint64_t buffer[8]) { struct RandomSeed_pvt* ctx = Identity_check((struct RandomSeed_pvt*) rs); Log_info(ctx->logger, "Attempting to seed random number generator"); // each provider overwrites input and output is a rolling hash. struct RandomSeed_Buffer buff = { .output = {0} }; int successCount = 0; for (int i = 0; i < ctx->rsCount; i++) { if (!ctx->rsList[i]->get(ctx->rsList[i], buff.input)) { Log_info(ctx->logger, "Trying random seed [%s] Success", ctx->rsList[i]->name); crypto_hash_sha512((uint8_t*)buff.output, (uint8_t*)&buff, RandomSeed_Buffer_SIZE); successCount++; } else { Log_info(ctx->logger, "Trying random seed [%s] Failed", ctx->rsList[i]->name); } } Assert_true(sizeof(buff.output) == 64); Bits_memcpy(buffer, buff.output, 64); if (successCount > 0) { Log_info(ctx->logger, "Seeding random number generator succeeded with [%d] sources", successCount); return 0; } else { Log_error(ctx->logger, "Seeding random number generator failed"); return -1; } }
static void authorizedPasswords(List* list, struct Context* ctx) { uint32_t count = List_size(list); for (uint32_t i = 0; i < count; i++) { Dict* d = List_getDict(list, i); Log_info(ctx->logger, "Checking authorized password %d.", i); if (!d) { Log_critical(ctx->logger, "Not a dictionary type %d.", i); exit(-1); } String* passwd = Dict_getString(d, String_CONST("password")); if (!passwd) { Log_critical(ctx->logger, "Must specify a password %d.", i); exit(-1); } } Log_info(ctx->logger, "Flushing existing authorized passwords"); rpcCall(String_CONST("AuthorizedPasswords_flush"), NULL, ctx, ctx->alloc); for (uint32_t i = 0; i < count; i++) { Dict* d = List_getDict(list, i); String* passwd = Dict_getString(d, String_CONST("password")); Log_info(ctx->logger, "Adding authorized password #[%d].", i); Dict args = Dict_CONST( String_CONST("authType"), Int_OBJ(1), Dict_CONST( String_CONST("password"), String_OBJ(passwd), NULL )); struct Allocator* child = ctx->alloc->child(ctx->alloc); rpcCall(String_CONST("AuthorizedPasswords_add"), &args, ctx, child); child->free(child); } }
void Server_run() { struct pollfd *pollfds; checkIPversions(); /* max clients + server sokets + client connecting that will be disconnected */ pollfds = Memory_safeCalloc((getIntConf(MAX_CLIENTS) + nofServerSocks + 1) , sizeof(struct pollfd)); /* Figure out bind address and port */ struct sockaddr_storage** addresses = Server_setupAddressesAndPorts(); /* Prepare TCP sockets */ Server_setupTCPSockets(addresses, pollfds); /* Prepare UDP sockets */ Server_setupUDPSockets(addresses, pollfds); Log_info("uMurmur version %s ('%s') protocol version %d.%d.%d", UMURMUR_VERSION, UMURMUR_CODENAME, PROTVER_MAJOR, PROTVER_MINOR, PROTVER_PATCH); Log_info("Visit http://code.google.com/p/umurmur/"); /* Main server loop */ Server_runLoop(pollfds); /* Disconnect clients and cleanup memory */ Client_disconnect_all(); free(pollfds); free(addresses[0]); free(addresses[1]); free(addresses); free(udpsocks); }
void Engine_print_hardware_info() { // Print graphics info. const GLubyte* renderer = glGetString(GL_RENDERER); const GLubyte* version = glGetString(GL_VERSION); Log_info("Renderer: %s", renderer); Log_info("OpenGL version supported %s\n", version); }
struct AdminTestFramework* AdminTestFramework_setUp(int argc, char** argv, char* testName) { if (argc > 2 && !strcmp(testName, argv[1]) && !strcmp("angel", argv[2])) { exit(AngelInit_main(argc-1, &argv[1])); } struct Allocator* alloc = MallocAllocator_new(1<<20); struct Writer* logwriter = FileWriter_new(stdout, alloc); Assert_true(logwriter); struct Log* logger = WriterLog_new(logwriter, alloc); struct EventBase* eventBase = EventBase_new(alloc); struct Random* rand = Random_new(alloc, logger, NULL); char asClientPipeName[32] = {0}; Random_base32(rand, (uint8_t*)asClientPipeName, 31); struct Pipe* asClientPipe = Pipe_named(asClientPipeName, eventBase, NULL, alloc); asClientPipe->logger = logger; char asCorePipeName[32] = {0}; Random_base32(rand, (uint8_t*)asCorePipeName, 31); struct Pipe* asCorePipe = Pipe_named(asCorePipeName, eventBase, NULL, alloc); asCorePipe->logger = logger; struct Interface* asCoreIface = FramingInterface_new(65535, &asCorePipe->iface, alloc); spawnAngel(testName, asClientPipeName, eventBase, alloc); Log_info(logger, "Initializing Angel"); initAngel(asClientPipe, asCoreIface, (char*)asCorePipe->name, eventBase, logger, alloc, rand); struct Sockaddr_storage addr; Assert_true(!Sockaddr_parse("127.0.0.1", &addr)); Log_info(logger, "Binding UDP admin socket"); struct AddrInterface* udpAdmin = UDPAddrInterface_new(eventBase, &addr.addr, alloc, NULL, logger); String* password = String_new("abcd", alloc); struct Admin* admin = Admin_new(udpAdmin, alloc, logger, eventBase, password); // Now setup the client. struct AdminClient* client = AdminClient_new(udpAdmin->addr, password, eventBase, logger, alloc); Assert_true(client); return Allocator_clone(alloc, (&(struct AdminTestFramework) { .admin = admin, .client = client, .alloc = alloc, .eventBase = eventBase, .logger = logger, .addr = Sockaddr_clone(udpAdmin->addr, alloc), .angelInterface = asCoreIface }));
static void onAngelExitResponse(Dict* message, void* vcontext) { struct Context* context = vcontext; Log_info(context->logger, "Angel stopped"); Log_info(context->logger, "Exiting"); Dict d = Dict_CONST(String_CONST("error"), String_OBJ(String_CONST("none")), NULL); Admin_sendMessage(&d, context->exitTxid, context->admin); exit(0); }
static void onAngelExitResponse(Dict* message, void* vcontext) { struct Context* context = vcontext; Log_info(context->logger, "Angel stopped"); Log_info(context->logger, "Exiting"); Dict d = Dict_CONST(String_CONST("error"), String_OBJ(String_CONST("none")), NULL); Admin_sendMessage(&d, context->exitTxid, context->admin); Timeout_setTimeout(shutdown, context, 1, context->base, context->allocator); }
void signal_handler(int sig) { switch(sig) { case SIGHUP: Log_info("HUP signal received."); Log_reset(); break; case SIGTERM: Log_info("TERM signal. Shutting down."); Server_shutdown(); break; } }
static void adminExit(Dict* input, void* vcontext, String* txid, struct Allocator* requestAlloc) { struct Context* context = vcontext; Log_info(context->logger, "Got request to exit"); Log_info(context->logger, "Stopping angel"); context->exitTxid = String_clone(txid, context->allocator); Dict angelExit = Dict_CONST(String_CONST("q"), String_OBJ(String_CONST("Angel_exit")), NULL); Hermes_callAngel(&angelExit, onAngelExitResponse, context, context->allocator, NULL, context->hermes); }
static int handle_var_request(struct upnp_device *priv, struct Upnp_State_Var_Request *var_event) { struct service *srv = find_service(priv->upnp_device_descriptor, var_event->ServiceID); if (srv == NULL) { var_event->ErrCode = UPNP_SOAP_E_INVALID_ARGS; return -1; } ithread_mutex_lock(srv->service_mutex); char *result = NULL; const int var_count = VariableContainer_get_num_vars(srv->variable_container); for (int i = 0; i < var_count; ++i) { const char *name; const char *value = VariableContainer_get(srv->variable_container, i, &name); if (value && strcmp(var_event->StateVarName, name) == 0) { result = strdup(value); break; } } ithread_mutex_unlock(srv->service_mutex); var_event->CurrentVal = result; var_event->ErrCode = (result == NULL) ? UPNP_SOAP_E_INVALID_VAR : UPNP_E_SUCCESS; Log_info("upnp", "Variable request %s -> %s (%s)", var_event->StateVarName, result, var_event->ServiceID); return 0; }
static uint8_t sendMessage(struct Message* message, struct Interface* iface) { struct UDPAddrInterface_pvt* context = Identity_cast((struct UDPAddrInterface_pvt*) iface->senderContext); struct Sockaddr_storage addrStore; Message_pop(message, &addrStore, context->pub.addr->addrLen); Assert_true(addrStore.addr.addrLen == context->pub.addr->addrLen); if (Socket_sendto(context->socket, message->bytes, message->length, 0, &addrStore.addr) < 0) { switch (Errno_get()) { case Errno_EMSGSIZE: return Error_OVERSIZE_MESSAGE; case Errno_ENOBUFS: case Errno_EAGAIN: return Error_LINK_LIMIT_EXCEEDED; default:; Log_info(context->logger, "Got error sending to socket [%s]", Errno_getString()); } } return 0; }
static Iface_DEFUN queryMsg(struct MsgCore_pvt* mcp, Dict* content, struct Address* src, struct Message* msg) { String* q = Dict_getStringC(content, "q"); struct QueryHandler* qh = NULL; for (int i = 0; i < mcp->qh->length; i++) { struct QueryHandler* qhx = ArrayList_OfQueryHandlers_get(mcp->qh, i); Identity_check(qhx); if (String_equals(qhx->queryType, q)) { qh = qhx; break; } } if (!qh) { Log_debug(mcp->log, "Unhandled query type [%s]", q->bytes); return NULL; } if (!qh->pub.cb) { Log_info(mcp->log, "Query handler for [%s] not setup", q->bytes); return NULL; } qh->pub.cb(content, src, msg->alloc, &qh->pub); return NULL; }
void upnp_control_init(struct upnp_device *device) { upnp_control_get_service(); // Set initial volume. float volume_fraction = 0; if (output_get_volume(&volume_fraction) == 0) { Log_info("control", "Output inital volume is %f; setting " "control variables accordingly.", volume_fraction); change_volume_decibel(20 * log(volume_fraction) / log(10)); } assert(control_service_.last_change == NULL); control_service_.last_change = UPnPLastChangeCollector_new(state_variables_, CONTROL_EVENT_XML_NS, device, CONTROL_SERVICE_ID); // According to UPnP-av-RenderingControl-v3-Service-20101231.pdf, 2.3.1 // page 51, the A_ARG_TYPE* variables are not evented. UPnPLastChangeCollector_add_ignore(control_service_.last_change, CONTROL_VAR_AAT_CHANNEL); UPnPLastChangeCollector_add_ignore(control_service_.last_change, CONTROL_VAR_AAT_INSTANCE_ID); UPnPLastChangeCollector_add_ignore(control_service_.last_change, CONTROL_VAR_AAT_PRESET_NAME); }
void NetDev_addAddress(const char* ifName, struct Sockaddr* sa, int prefixLen, struct Log* logger, struct Except* eh) { int addrFam = Sockaddr_getFamily(sa); struct Allocator* alloc; BufferAllocator_STACK(alloc, 4096); char* printedAddr = Sockaddr_print(sa, alloc); if (addrFam != Sockaddr_AF_INET && addrFam != Sockaddr_AF_INET6) { Except_throw(eh, "Unknown address type for address [%s]", printedAddr); } int prefixMax = (addrFam == Sockaddr_AF_INET6) ? 128 : 32; if (prefixLen < 0 || prefixLen > prefixMax) { Except_throw(eh, "prefixLen [%d] must be greater than 0 and less than %d", prefixLen, prefixMax); } void* addr; int len = Sockaddr_getAddress(sa, &addr); if (len < 0 || len != prefixMax / 8) { Except_throw(eh, "Invalid sockaddr [%s]", printedAddr); } Log_info(logger, "Setting IP address [%s/%d] on interface [%s]", printedAddr, prefixLen, ifName); NetPlatform_addAddress(ifName, addr, prefixLen, addrFam, logger, eh); }
static void init_logging(const char *log_file) { char version[1024]; #ifdef HAVE_GST snprintf(version, sizeof(version), "[ gmediarender %s " "(libupnp-%s; glib-%d.%d.%d; gstreamer-%d.%d.%d) ]", GM_COMPILE_VERSION, UPNP_VERSION_STRING, GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION, GLIB_MICRO_VERSION, GST_VERSION_MAJOR, GST_VERSION_MINOR, GST_VERSION_MICRO); #else snprintf(version, sizeof(version), "[ gmediarender %s " "(libupnp-%s; glib-%d.%d.%d; without gstreamer.) ]", GM_COMPILE_VERSION, UPNP_VERSION_STRING, GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION, GLIB_MICRO_VERSION); #endif if (log_file != NULL) { Log_init(log_file); Log_info("main", "%s log started %s", PACKAGE_STRING, version); } else { fprintf(stderr, "%s started %s.\nLogging switched off. " "Enable with --logfile=<filename> " "(e.g. --logfile=/dev/stdout for console)\n", PACKAGE_STRING, version); } }
static void sendMessageInternal(struct Message* message, struct sockaddr_ll* addr, struct ETHInterface_pvt* context, struct Except* exHandler) { /* Cut down on the noise uint8_t buff[sizeof(*addr) * 2 + 1] = {0}; Hex_encode(buff, sizeof(buff), (uint8_t*)addr, sizeof(*addr)); Log_debug(context->logger, "Sending ethernet frame to [%s]", buff); */ if (sendto(context->socket, message->bytes, message->length, 0, (struct sockaddr*) addr, sizeof(struct sockaddr_ll)) < 0) { switch (errno) { default:; Log_info(context->logger, "[%s] Got error sending to socket [%s]", context->ifName->bytes, strerror(errno)); Except_throw(exHandler, "Interface %s removed: [%s]", context->ifName->bytes, strerror(errno)); case EMSGSIZE: case ENOBUFS: case EAGAIN:; // todo: care } } return; }
struct Interface* TUNInterface_new(const char* interfaceName, char assignedInterfaceName[TUNInterface_IFNAMSIZ], struct EventBase* base, struct Log* logger, struct Except* eh, struct Allocator* alloc) { uint32_t maxNameSize = (IFNAMSIZ < TUNInterface_IFNAMSIZ) ? IFNAMSIZ : TUNInterface_IFNAMSIZ; Log_info(logger, "Initializing tun device [%s]", ((interfaceName) ? interfaceName : "auto")); struct ifreq ifRequest = { .ifr_flags = IFF_TUN }; if (interfaceName) { if (strlen(interfaceName) > maxNameSize) { Except_throw(eh, "tunnel name too big, limit is [%d] characters", maxNameSize); } strncpy(ifRequest.ifr_name, interfaceName, maxNameSize); } int fileno = open(DEVICE_PATH, O_RDWR); if (fileno < 0) { Except_throw(eh, "open(\"%s\") [%s]", DEVICE_PATH, strerror(errno)); } if (ioctl(fileno, TUNSETIFF, &ifRequest) < 0) { int err = errno; close(fileno); Except_throw(eh, "ioctl(TUNSETIFF) [%s]", strerror(err)); } strncpy(assignedInterfaceName, ifRequest.ifr_name, maxNameSize); struct Pipe* p = Pipe_forFiles(fileno, fileno, base, eh, alloc); return &p->iface; }
void TUNConfigurator_setMTU(const char* interfaceName, uint32_t mtu, struct Log* logger, struct Except* eh) { int s = socket(AF_INET6, SOCK_DGRAM, 0); if (s < 0) { Except_raise(eh, TUNConfigurator_ERROR_GETTING_ADMIN_SOCKET, "socket() failed [%s]", Errno_getString()); } struct ifreq ifRequest; strncpy(ifRequest.ifr_name, interfaceName, IFNAMSIZ); ifRequest.ifr_mtu = mtu; Log_info(logger, "Setting MTU for device [%s] to [%u] bytes.", interfaceName, mtu); if (ioctl(s, SIOCSIFMTU, &ifRequest) < 0) { enum Errno err = Errno_get(); close(s); Except_raise(eh, TUNConfigurator_setMTU_INTERNAL, "ioctl(SIOCSIFMTU) failed [%s]", Errno_strerror(err)); } }
int setup_sighandler (void (*func) (int) ) { #ifndef __WIN32__ struct sigaction a; Log_info ("setting up signal handler"); sigemptyset (&a.sa_mask); a.sa_flags = 0; a.sa_handler = func; sigaction (SIGTERM, &a, 0); sigaction (SIGINT, &a, 0); a.sa_handler = SIG_IGN; sigaction (SIGPIPE, &a, 0); return 0; #else //__WIN32__ signal (SIGINT, func); signal (SIGTERM, func); //signal (SIGPIPE, SIG_IGN); How comes? return 0; #endif }
static void checkInterfaceUp(int socket, struct ifreq* ifRequest, struct Log* logger, struct Except* eh) { if (ioctl(socket, SIOCGIFFLAGS, ifRequest) < 0) { int err = errno; close(socket); Except_throw(eh, "ioctl(SIOCGIFFLAGS) [%s]", strerror(err)); } if (ifRequest->ifr_flags & IFF_UP & IFF_RUNNING) { // already up. return; } Log_info(logger, "Bringing up interface [%s]", ifRequest->ifr_name); ifRequest->ifr_flags |= IFF_UP | IFF_RUNNING; if (ioctl(socket, SIOCSIFFLAGS, ifRequest) < 0) { int err = errno; close(socket); Except_throw(eh, "ioctl(SIOCSIFFLAGS) [%s]", strerror(err)); } }
static void cryptoAuth(struct Context* ctx) { Log_info(ctx->log, "Setting up salsa20/poly1305 benchmark (encryption and decryption only)"); struct Allocator* alloc = Allocator_child(ctx->alloc); struct CryptoAuth* ca1 = CryptoAuth_new(alloc, NULL, ctx->base, ctx->log, ctx->rand); struct CryptoAuth* ca2 = CryptoAuth_new(alloc, NULL, ctx->base, ctx->log, ctx->rand); struct CryptoAuth_Session* sess1 = CryptoAuth_newSession(ca1, alloc, ca2->publicKey, NULL, false, "bench"); struct CryptoAuth_Session* sess2 = CryptoAuth_newSession(ca2, alloc, ca1->publicKey, NULL, false, "bench"); int size = 1500; int count = 100000; struct Message* msg = Message_new(size, 256, alloc); Random_bytes(ctx->rand, msg->bytes, msg->length); // setup session for (int i = 0; i < 2; i++) { Assert_true(!CryptoAuth_encrypt(sess1, msg)); Assert_true(!CryptoAuth_decrypt(sess2, msg)); Assert_true(!CryptoAuth_encrypt(sess2, msg)); Assert_true(!CryptoAuth_decrypt(sess1, msg)); } begin(ctx, "salsa20/poly1305", (count * size * 8) / 1024, "kilobits"); for (int i = 0; i < count; i++) { Assert_true(!CryptoAuth_encrypt(sess1, msg)); Assert_true(!CryptoAuth_decrypt(sess2, msg)); } done(ctx); Allocator_free(alloc); }
int webserver_register_buf(const char *path, const char *contents, const char *content_type) { struct virtual_file *entry; Log_info("webserver", "Provide %s (%s) from buffer", path, content_type); assert(path != NULL); assert(contents != NULL); assert(content_type != NULL); entry = malloc(sizeof(struct virtual_file)); if (entry == NULL) { return -1; } entry->len = strlen(contents); entry->contents = contents; entry->virtual_fname = path; entry->content_type = content_type; entry->next = virtual_files; virtual_files = entry; return 0; }
void NetPlatform_setMTU(const char* interfaceName, uint32_t mtu, struct Log* logger, struct Except* eh) { int s = socket(AF_INET6, SOCK_DGRAM, 0); if (s < 0) { Except_throw(eh, "socket() [%s]", strerror(errno)); } struct ifreq ifRequest; strncpy(ifRequest.ifr_name, interfaceName, IFNAMSIZ); ifRequest.ifr_mtu = mtu; Log_info(logger, "Setting MTU for device [%s] to [%u] bytes.", interfaceName, mtu); if (ioctl(s, SIOCSIFMTU, &ifRequest) < 0) { int err = errno; close(s); Except_throw(eh, "ioctl(SIOCSIFMTU) failed [%s]", strerror(err)); } }
/** * Handle an incoming control message from a switch. * * @param context the ducttape context. * @param message the control message, this should be alligned on the beginning of the content, * that is to say, after the end of the switch header. * @param switchHeader the header. * @param switchIf the interface which leads to the switch. * @param isFormV8 true if the control message is in the form specified by protocol version 8+ */ static Iface_DEFUN incomingFromCore(struct Message* msg, struct Iface* coreIf) { struct ControlHandler_pvt* ch = Identity_check((struct ControlHandler_pvt*) coreIf); struct SwitchHeader switchHeader; Message_pop(msg, &switchHeader, SwitchHeader_SIZE, NULL); uint8_t labelStr[20]; uint64_t label = Endian_bigEndianToHost64(switchHeader.label_be); AddrTools_printPath(labelStr, label); Log_debug(ch->log, "ctrl packet from [%s]", labelStr); if (msg->length < 4 + Control_Header_SIZE) { Log_info(ch->log, "DROP runt ctrl packet from [%s]", labelStr); return NULL; } Assert_true(Message_pop32(msg, NULL) == 0xffffffff); if (Checksum_engine(msg->bytes, msg->length)) { Log_info(ch->log, "DROP ctrl packet from [%s] with invalid checksum", labelStr); return NULL; } struct Control* ctrl = (struct Control*) msg->bytes; if (ctrl->header.type_be == Control_ERROR_be) { return handleError(msg, ch, label, labelStr); } else if (ctrl->header.type_be == Control_KEYPING_be || ctrl->header.type_be == Control_PING_be) { return handlePing(msg, ch, label, labelStr, ctrl->header.type_be); } else if (ctrl->header.type_be == Control_KEYPONG_be || ctrl->header.type_be == Control_PONG_be) { Log_debug(ch->log, "got switch pong from [%s]", labelStr); // Shift back over the header Message_shift(msg, 4 + SwitchHeader_SIZE, NULL); return Iface_next(&ch->pub.switchPingerIf, msg); } Log_info(ch->log, "DROP control packet of unknown type from [%s], type [%d]", labelStr, Endian_bigEndianToHost16(ctrl->header.type_be)); return NULL; }
static void authorizedPasswords(List* list, struct Context* ctx) { uint32_t count = List_size(list); for (uint32_t i = 0; i < count; i++) { Dict* d = List_getDict(list, i); Log_info(ctx->logger, "Checking authorized password %d.", i); if (!d) { Log_critical(ctx->logger, "Not a dictionary type %d.", i); exit(-1); } String* passwd = Dict_getString(d, String_CONST("password")); if (!passwd) { Log_critical(ctx->logger, "Must specify a password %d.", i); exit(-1); } } for (uint32_t i = 0; i < count; i++) { struct Allocator* child = Allocator_child(ctx->alloc); Dict* d = List_getDict(list, i); String* passwd = Dict_getString(d, String_CONST("password")); String* user = Dict_getString(d, String_CONST("user")); String* displayName = user; if (!displayName) { displayName = String_printf(child, "password [%d]", i); } //String* publicKey = Dict_getString(d, String_CONST("publicKey")); String* ipv6 = Dict_getString(d, String_CONST("ipv6")); Log_info(ctx->logger, "Adding authorized password #[%d] for user [%s].", i, displayName->bytes); Dict *args = Dict_new(child); uint32_t i = 1; Dict_putInt(args, String_CONST("authType"), i, child); Dict_putString(args, String_CONST("password"), passwd, child); if (user) { Dict_putString(args, String_CONST("user"), user, child); } Dict_putString(args, String_CONST("displayName"), displayName, child); if (ipv6) { Log_info(ctx->logger, " This connection password restricted to [%s] only.", ipv6->bytes); Dict_putString(args, String_CONST("ipv6"), ipv6, child); } rpcCall(String_CONST("AuthorizedPasswords_add"), args, ctx, child); Allocator_free(child); } }
/** * Handle an incoming control message from a switch. * * @param context the ducttape context. * @param message the control message, this should be alligned on the beginning of the content, * that is to say, after the end of the switch header. * @param switchHeader the header. * @param switchIf the interface which leads to the switch. * @param isFormV8 true if the control message is in the form specified by protocol version 8+ */ static Iface_DEFUN incomingFromCore(struct Message* msg, struct Iface* coreIf) { struct ControlHandler_pvt* ch = Identity_check((struct ControlHandler_pvt*) coreIf); struct RouteHeader routeHdr; Message_pop(msg, &routeHdr, RouteHeader_SIZE, NULL); uint8_t labelStr[20]; uint64_t label = Endian_bigEndianToHost64(routeHdr.sh.label_be); AddrTools_printPath(labelStr, label); // happens in benchmark // Log_debug(ch->log, "ctrl packet from [%s]", labelStr); if (msg->length < 4 + Control_Header_SIZE) { Log_info(ch->log, "DROP runt ctrl packet from [%s]", labelStr); return NULL; } Assert_true(routeHdr.flags & RouteHeader_flags_CTRLMSG); if (Checksum_engine(msg->bytes, msg->length)) { Log_info(ch->log, "DROP ctrl packet from [%s] with invalid checksum", labelStr); return NULL; } struct Control* ctrl = (struct Control*) msg->bytes; if (ctrl->header.type_be == Control_ERROR_be) { return handleError(msg, ch, label, labelStr); } else if (ctrl->header.type_be == Control_KEYPING_be || ctrl->header.type_be == Control_PING_be) { return handlePing(msg, ch, label, labelStr, ctrl->header.type_be); } else if (ctrl->header.type_be == Control_KEYPONG_be || ctrl->header.type_be == Control_PONG_be) { Log_debug(ch->log, "got switch pong from [%s]", labelStr); Message_push(msg, &routeHdr, RouteHeader_SIZE, NULL); return Iface_next(&ch->pub.switchPingerIf, msg); } Log_info(ch->log, "DROP control packet of unknown type from [%s], type [%d]", labelStr, Endian_bigEndianToHost16(ctrl->header.type_be)); return NULL; }
/** * Incoming message from someone we don't know, maybe someone responding to a beacon? * expects: [ struct LLAddress ][ content ] */ static Iface_DEFUN handleUnexpectedIncoming(struct Message* msg, struct InterfaceController_Iface_pvt* ici) { struct InterfaceController_pvt* ic = ici->ic; struct Sockaddr* lladdr = (struct Sockaddr*) msg->bytes; Message_shift(msg, -lladdr->addrLen, NULL); if (msg->length < CryptoHeader_SIZE) { return NULL; } struct Allocator* epAlloc = Allocator_child(ici->alloc); lladdr = Sockaddr_clone(lladdr, epAlloc); Assert_true(!((uintptr_t)msg->bytes % 4) && "alignment fault"); struct Peer* ep = Allocator_calloc(epAlloc, sizeof(struct Peer), 1); Identity_set(ep); ep->alloc = epAlloc; ep->ici = ici; ep->lladdr = lladdr; ep->alloc = epAlloc; ep->peerLink = PeerLink_new(ic->eventBase, epAlloc); struct CryptoHeader* ch = (struct CryptoHeader*) msg->bytes; ep->caSession = CryptoAuth_newSession(ic->ca, epAlloc, ch->publicKey, true, "outer"); if (CryptoAuth_decrypt(ep->caSession, msg)) { // If the first message is a dud, drop all state for this peer. // probably some random crap that wandered in the socket. Allocator_free(epAlloc); return NULL; } Assert_true(!Bits_isZero(ep->caSession->herPublicKey, 32)); Assert_true(Map_EndpointsBySockaddr_indexForKey(&lladdr, &ici->peerMap) == -1); int index = Map_EndpointsBySockaddr_put(&lladdr, &ep, &ici->peerMap); Assert_true(index >= 0); ep->handle = ici->peerMap.handles[index]; Allocator_onFree(epAlloc, closeInterface, ep); ep->state = InterfaceController_PeerState_UNAUTHENTICATED; ep->isIncomingConnection = true; ep->switchIf.send = sendFromSwitch; if (SwitchCore_addInterface(ic->switchCore, &ep->switchIf, epAlloc, &ep->addr.path)) { Log_debug(ic->logger, "handleUnexpectedIncoming() SwitchCore out of space"); Allocator_free(epAlloc); return NULL; } // We want the node to immedietly be pinged but we don't want it to appear unresponsive because // the pinger will only ping every (PING_INTERVAL * 8) so we set timeOfLastMessage to // (now - pingAfterMilliseconds - 1) so it will be considered a "lazy node". ep->timeOfLastMessage = Time_currentTimeMilliseconds(ic->eventBase) - ic->pingAfterMilliseconds - 1; Bits_memcpy(ep->addr.key, ep->caSession->herPublicKey, 32); Bits_memcpy(ep->addr.ip6.bytes, ep->caSession->herIp6, 16); Log_info(ic->logger, "Added peer [%s] from incoming message", Address_toString(&ep->addr, msg->alloc)->bytes); return receivedPostCryptoAuth(msg, ep, ic); }
static void addIp4Address(const char* interfaceName, const uint8_t address[4], int prefixLen, struct Log* logger, struct Except* eh) { struct ifaliasreq ifaliasreq; struct sockaddr_in* in; memset(&ifaliasreq, 0, sizeof(ifaliasreq)); snprintf(ifaliasreq.ifra_name,IFNAMSIZ, "%s",interfaceName); char myIp[40]; snprintf(myIp, 40, "%u.%u.%u.%u", address[0], address[1], address[2], address[3]); in_addr_t nmask = ( ~((1 << (32 - prefixLen)) - 1) ); char myMask[40]; snprintf(myMask,40,"%u",nmask); in = (struct sockaddr_in *) &ifaliasreq.ifra_addr; in->sin_family = AF_INET; in->sin_len = sizeof(ifaliasreq.ifra_addr); int err = inet_aton(myIp, &in->sin_addr); if (err == 0){ Except_throw(eh, "inet_aton(myIp) failed"); } in = (struct sockaddr_in *) &ifaliasreq.ifra_mask; in->sin_family = AF_INET; in->sin_len = sizeof(ifaliasreq.ifra_mask); err = inet_aton(myMask, &in->sin_addr); if (err == 0){ Except_throw(eh, "inet_aton(myMask) failed"); } in = (struct sockaddr_in *) &ifaliasreq.ifra_broadaddr; in->sin_family = AF_INET; in->sin_len = sizeof(ifaliasreq.ifra_broadaddr); in->sin_addr.s_addr = ((struct sockaddr_in *) &ifaliasreq.ifra_addr)->sin_addr.s_addr | ~ ((struct sockaddr_in *) &ifaliasreq.ifra_mask)->sin_addr.s_addr; int s = socket(PF_INET, SOCK_STREAM, 0); if (ioctl(s, SIOCAIFADDR, &ifaliasreq) == -1){ int err = errno; close(s); Except_throw(eh, "ioctl(SIOCAIFADDR) [%s]",strerror(err)); } Log_info(logger, "Configured IPv4 [%s/%s] for [%s]", myIp, myMask, interfaceName); close(s); }
static void adminExit(Dict* input, void* vcontext, String* txid, struct Allocator* requestAlloc) { struct Context* context = Identity_check((struct Context*) vcontext); Log_info(context->logger, "Got request to exit"); Dict d = Dict_CONST(String_CONST("error"), String_OBJ(String_CONST("none")), NULL); Admin_sendMessage(&d, txid, context->admin); Timeout_setTimeout(shutdown, context, 1, context->base, context->alloc); }