예제 #1
0
파일: server.c 프로젝트: Nauxuron/umurmur
/* 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");
	}
}
예제 #2
0
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;
    }
}
예제 #3
0
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);
    }
}
예제 #4
0
파일: server.c 프로젝트: Nauxuron/umurmur
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);
}
예제 #5
0
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);
}
예제 #6
0
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
    }));
예제 #7
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);
    exit(0);
}
예제 #8
0
파일: Core.c 프로젝트: AdUser/cjdns
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);
}
예제 #9
0
파일: main.c 프로젝트: rindeal/umurmur
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;
	}
}
예제 #10
0
파일: Core.c 프로젝트: AdUser/cjdns
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);
}
예제 #11
0
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;
}
예제 #12
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;
}
예제 #13
0
파일: MsgCore.c 프로젝트: sssemil/cjdns
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;
}
예제 #14
0
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);
}
예제 #15
0
파일: NetDev.c 프로젝트: Erkan-Yilmaz/cjdns
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);
}
예제 #16
0
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);
	}
}
예제 #17
0
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;
}
예제 #18
0
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;
}
예제 #19
0
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));
    }
}
예제 #20
0
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
}
예제 #21
0
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));
    }
}
예제 #22
0
파일: Benchmark.c 프로젝트: FSFTN/cjdns
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);
}
예제 #23
0
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;
}
예제 #24
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));
    }
}
예제 #25
0
/**
 * 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;
}
예제 #26
0
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);
    }
}
예제 #27
0
/**
 * 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;
}
예제 #28
0
/**
 * 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);
}
예제 #29
0
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);


}
예제 #30
0
파일: Core.c 프로젝트: DevSlashNull/cjdns
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);
}