Ejemplo n.º 1
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));
    }
}
Ejemplo n.º 2
0
static void checkRunningInstance(struct Allocator* allocator,
                                 struct EventBase* base,
                                 String* addr,
                                 String* password,
                                 struct Log* logger,
                                 struct Except* eh)
{
    struct Allocator* alloc = Allocator_child(allocator);
    struct Sockaddr_storage pingAddrStorage;
    if (Sockaddr_parse(addr->bytes, &pingAddrStorage)) {
        Except_raise(eh, -1, "Unable to parse [%s] as an ip address port, eg: 127.0.0.1:11234",
                     addr->bytes);
    }
    struct AdminClient* adminClient =
        AdminClient_new(&pingAddrStorage.addr, password, base, logger, alloc);

    // 100 milliseconds is plenty to wait for a process to respond on the same machine.
    adminClient->millisecondsToWait = 100;

    Dict* pingArgs = Dict_new(alloc);

    struct AdminClient_Result* pingResult =
        AdminClient_rpcCall(String_new("ping", alloc), pingArgs, adminClient, alloc);

    if (pingResult->err == AdminClient_Error_NONE) {
        Except_raise(eh, -1, "Startup failed: cjdroute is already running.");
    }
    Allocator_free(alloc);
}
Ejemplo n.º 3
0
static void sendConfToCore(struct Interface* toCoreInterface,
                           struct Allocator* tempAlloc,
                           Dict* config,
                           struct Except* eh,
                           struct Log* logger)
{
    #define CONFIG_BUFF_SIZE 1024
    uint8_t buff[CONFIG_BUFF_SIZE + 32] = {0};
    uint8_t* start = buff + 32;

    struct Writer* writer = ArrayWriter_new(start, CONFIG_BUFF_SIZE - 33, tempAlloc);
    if (StandardBencSerializer_get()->serializeDictionary(writer, config)) {
        Except_raise(eh, -1, "Failed to serialize pre-configuration for core.");
    }
    struct Message* m = &(struct Message) {
        .bytes = start,
        .length = writer->bytesWritten,
        .padding = 32
    };
    m = Message_clone(m, tempAlloc);
    Log_keys(logger, "Sent [%d] bytes to core [%s].", m->length, m->bytes);
    toCoreInterface->sendMessage(m, toCoreInterface);
}

static void setUser(char* user, struct Log* logger, struct Except* eh)
{
    struct Jmp jmp;
    Jmp_try(jmp) {
        Security_setUser(user, logger, &jmp.handler);
    } Jmp_catch {
        if (jmp.code == Security_setUser_PERMISSION) {
            return;
        }
        Except_raise(eh, jmp.code, "%s", jmp.message);
    }
}

static struct Pipe* getClientPipe(int argc,
                                  char** argv,
                                  struct EventBase* base,
                                  struct Except* eh,
                                  struct Allocator* alloc)
{
    int inFromClientNo;
    int outToClientNo;
    if (argc < 4 || (inFromClientNo = atoi(argv[2])) == 0) {
        inFromClientNo = STDIN_FILENO;
    }
    if (argc < 4 || (outToClientNo = atoi(argv[3])) == 0) {
        outToClientNo = STDOUT_FILENO;
    }

    // named pipe.
    if (argc > 2 && inFromClientNo == STDIN_FILENO) {
        return Pipe_named(argv[2], base, eh, alloc);
    }
    return Pipe_forFiles(inFromClientNo, outToClientNo, base, eh, alloc);
}
Ejemplo n.º 4
0
struct Interface* TUNInterface_new(const char* interfaceName,
                                   char assignedInterfaceName[TUNInterface_IFNAMSIZ],
                                   int isTapMode,
                                   struct EventBase* base,
                                   struct Log* logger,
                                   struct Except* eh,
                                   struct Allocator* alloc)
{
    if (isTapMode) {
        Except_throw(eh, "tap mode not supported on this platform");
    }

    // to store the tunnel device index
    int ppa = 0;
    // Open the descriptor
    int tunFd = open("/dev/tun0", O_RDWR);
    if (tunFd == -1) {
        tunFd = open("/dev/tun1", O_RDWR);
        ppa = 1;
    }
    if (tunFd == -1) {
        tunFd = open("/dev/tun2", O_RDWR);
        ppa = 2;
    }
    if (tunFd == -1) {
        tunFd = open("/dev/tun3", O_RDWR);
        ppa = 3;
    }

    if (tunFd < 0 ) {
        int err = errno;
        close(tunFd);

        char* error = NULL;
        if (tunFd < 0) {
            error = "open(\"/dev/tunX\")";
        }
        Except_raise(eh, TUNConfigurator_initTun_INTERNAL, error, strerror(err));
    }

    // Since devices are numbered rather than named, it's not possible to have tun0 and cjdns0
    // so we'll skip the pretty names and call everything tunX
    if (assignedInterfaceName) {
        snprintf(assignedInterfaceName, TUNConfigurator_IFNAMSIZ, "tun%d", ppa);
    }

    char* error = NULL;

    if (error) {
        int err = errno;
        close(tunFd);
        Except_raise(eh, TUNConfigurator_initTun_INTERNAL, "%s [%s]", error, strerror(err));
    }

    struct Pipe* p = Pipe_forFiles(tunFd, tunFd, base, eh, alloc);

    return BSDMessageTypeWrapper_new(&p->iface, logger);
}
Ejemplo n.º 5
0
/**
 * Open the tun device.
 *
 * @param interfaceName the interface name you *want* to use or NULL to let the kernel decide.
 * @param assignedInterfaceName the interface name you get.
 * @param log
 * @param eh
 * @return a file descriptor for the tunnel.
 */
void* TUNConfigurator_initTun(const char* interfaceName,
                              char assignedInterfaceName[TUNConfigurator_IFNAMSIZ],
                              struct Log* logger,
                              struct Except* eh)
{
    // Open the descriptor
    int tunFd = open("/dev/tun", O_RDWR);

    //Get the resulting device name
    const char* assignedDevname;
    assignedDevname = fdevname(tunFd);

    // Extract the number eg: 0 from tun0
    int ppa = 0;
    for (uint32_t i = 0; i < strlen(assignedDevname); i++) {
        if (isdigit(assignedDevname[i])) {
            ppa = atoi(assignedDevname);
        }
    }

    if (tunFd < 0 || ppa < 0 ) {
        enum Errno err = Errno_get();
        close(tunFd);

        char* error = NULL;
        if (tunFd < 0) {
            error = "open(\"/dev/tun\")";
        } else if (ppa < 0) {
            error = "fdevname/getting number from fdevname";
        }
        Except_raise(eh, TUNConfigurator_initTun_INTERNAL, error, Errno_strerror(err));
    }

    // Since devices are numbered rather than named, it's not possible to have tun0 and cjdns0
    // so we'll skip the pretty names and call everything tunX
    snprintf(assignedInterfaceName, TUNConfigurator_IFNAMSIZ, "tun%d", ppa);

    char* error = NULL;

    // We want to send IPv6 through our tun device, so we need to be able to specify "ethertype"
    int tunhead = 1;
    if (ioctl(tunFd,TUNSIFHEAD,&tunhead) == -1) {
        error = "TUNSIFHEAD";
    }

    if (error) {
        enum Errno err = Errno_get();
        close(tunFd);
        Except_raise(eh, TUNConfigurator_initTun_INTERNAL, "%s [%s]", error, Errno_strerror(err));
    }


    intptr_t ret = (intptr_t) tunFd;
    return (void*) ret;
}
Ejemplo n.º 6
0
void *Mem_alloc(long nbytes,const char *file,int line)
{
	struct descriptor *bp;
	void *ptr;

	assert(nbytes>0);
	//对nbytes做字节对齐扩充到合适字节,避免空间浪费
	nbytes=((nbytes+sizeof(union align)-1)/(sizeof(union align)))*(sizeof(union align));
	//从空闲块的首地址的下一块开始寻找合适的空间,freelist是一个循环链表,这里所谓的空闲块
	//并不是真正都是空闲的,其实是所有当前已经申请过的块,每一块都有至少(NALLOC)大。经过多次分别后
	//块中有的是空闲的,而有的可能已经被用满。
	for(bp=freelist.free;bp;bp=bp->free)
	{
		if(bp->size>nbytes) //如果找到合适的空闲块
		{
			bp->size-=nbytes;  
			ptr=(char *)bp->ptr+bp->size;  //得到分配空间的首地址
			if((bp=dalloc(ptr,nbytes,file,line))!=NULL)  //申请一个存储新ptr的结构体bp
			{
				unsigned h=hash(ptr,htab);               //然后将这个结构体加入到hash表中
				bp->link=htab[h];                        //表明这块内存已经被占用了。
				htab[h]=bp;
				return ptr;
			}
			else
			{
				if(file==NULL)
					RAISE(Mem_Failed);
				else
					Except_raise(&Mem_Failed,file,line);
			}
		}
		if(bp==&freelist)  //没有合适的空闲块,那么分配一个新块
		{
			struct descriptor *newptr;
			if((ptr=malloc(nbytes+NALLOC))==NULL     //新块大小由固定宏和nbytes共同决定,意味着所有的块都将有大小上的一些差异
				||(newptr=dalloc(ptr,nbytes+NALLOC,__FILE__,__LINE__))==NULL)
			{

	            if(file==NULL)
					RAISE(Mem_Failed);
				else
					Except_raise(&Mem_Failed,file,line);
			}

			newptr->free=freelist.free;
			freelist.free=newptr;
		}

	}
	assert(0);
	return NULL;
}
Ejemplo n.º 7
0
Archivo: mem.cpp Proyecto: grefen/Study
void* Mem_alloc(long nbytes, const char* file, int line)
{
   struct descriptor *bp;
   void*  ptr;
   
   assert(nbytes > 0);
   
   nbytes = (nbytes + sizeof(union align) - 1)/(sizeof(union align)) * (sizeof(union align));
   
   for (bp = freelist.free; bp; bp = bp->free)
   {
       if (bp->size > nbytes)
       {
           bp->size -= nbytes;
           ptr = (char*)bp->ptr + bp->size;
           
           if ( (bp = dalloc(ptr, nbytes, file, line)) != NULL)
           {
               unsigned h = hash(ptr, htab);
               
               bp->link = htab[h];
               htab[h]  = bp;
               
               return ptr;
           }
           else
           {
               Except_raise(&Assert_Failed, file, line);
           }
       }
       
       if (bp == &freelist)
       {
            struct descriptor *newptr;
            
			if ( (ptr = malloc(nbytes + NALLOC) ) == NULL ||
				( newptr = dalloc(ptr, nbytes + NALLOC, __FILE__, __LINE__)) == NULL
				)
			{
                Except_raise(&Assert_Failed, file, line);
			}
			
			newptr->free = freelist.free;
			freelist.free= newptr;
       }
   }
   
   assert(0);
   
   return NULL;
}
Ejemplo n.º 8
0
void QExc_free(void *ptr, int line, const char* file)
{
    MemorySuite *suite;

    if(ptr == NULL)
        Except_raise(&Mem_FreeFailed, line, file);

    suite = RemoveMemorySuite(ptr);
    if(suite == NULL)
        Except_raise(&Mem_FreeFailed, line, file);

    free(ptr);
    free(suite);
}
Ejemplo n.º 9
0
void *Arena_alloc(T arena, long nbytes,
                  const char *file, int line) {
    assert(arena);
    assert(nbytes > 0);
    nbytes = ((nbytes + sizeof (union align) - 1)/
              (sizeof (union align)))*(sizeof (union align));
    while (nbytes > arena->limit - arena->avail) {
        T ptr;
        char *limit;
        if ((ptr = freechunks) != NULL) {
            freechunks = freechunks->prev;
            nfree--;
            limit = ptr->limit;
        } else {
            long m = sizeof (union header) + nbytes + 10*1024;
            ptr = malloc(m);
            if (ptr == NULL)
            {
                if (file == NULL)
                    RAISE(Arena_Failed);
                else
                    Except_raise(&Arena_Failed, file, line);
            }
            limit = (char *)ptr + m;
        }
        *ptr = *arena;
        arena->avail = (char *)((union header *)ptr + 1);
        arena->limit = limit;
        arena->prev  = ptr;
    }
    arena->avail += nbytes;
    return arena->avail - nbytes;
}
Ejemplo n.º 10
0
struct Message* InterfaceWaiter_waitForData(struct Interface* iface,
                                            struct EventBase* eventBase,
                                            struct Allocator* alloc,
                                            struct Except* eh)
{
    struct Context ctx = {
        .eventBase = eventBase,
        .alloc = alloc
    };

    struct Allocator* tempAlloc = Allocator_child(alloc);

    iface->receiverContext = &ctx;
    iface->receiveMessage = receiveMessage;

    ctx.timeout = Timeout_setTimeout(timeout, &ctx, 2000, eventBase, tempAlloc);
    EventBase_beginLoop(eventBase);

    iface->receiveMessage = NULL;

    Allocator_free(tempAlloc);
    if (ctx.timedOut) {
        Except_raise(eh, InterfaceWaiter_waitForData_TIMEOUT,
                     "InterfaceWaiter Timed out waiting for data.");
    }

    Assert_true(ctx.message);
    return ctx.message;
}
Ejemplo n.º 11
0
void* QExc_malloc(unsigned int size, int line, const char *file)
{
    _MemoryPtr   newBlock;
    MemorySuite *newSuite;

    newSuite = (MemorySuite*)malloc(sizeof(MemorySuite));
    if(newSuite == NULL) //program routine will jump to setjmp
        Except_raise(&Mem_AllocFailed, line, file);
	
    newBlock = (_MemoryPtr)malloc(size);
    if(newBlock == NULL)
    {
        free(newSuite); 
        Except_raise(&Mem_AllocFailed, line, file);
    }
	
    SetMemorySuite(newSuite, newBlock, size, line, file);
    return newBlock;
}
Ejemplo n.º 12
0
static void initCore(char* coreBinaryPath,
                     String* corePipeName,
                     struct EventBase* base,
                     struct Allocator* alloc,
                     struct Except* eh)
{
    char* args[] = { "core", corePipeName->bytes, NULL };

    FILE* file;
    if ((file = fopen(coreBinaryPath, "r")) != NULL) {
        fclose(file);
    } else {
        Except_raise(eh, -1, "Can't open core executable [%s] for reading.", coreBinaryPath);
    }

    if (Process_spawn(coreBinaryPath, args, base, alloc)) {
        Except_raise(eh, -1, "Failed to spawn core process.");
    }
}
Ejemplo n.º 13
0
void * Mem_alloc(long nbytes, const char *file, int line) {
    assert(nbytes > 0);
    nbytes = ((nbytes + sizeof(union align) - 1) / (sizeof(union align))) * (sizeof(union align));
    for (struct descriptor *bp = freelist.free; bp; bp = bp->free) {
        if (bp->size > nbytes) {
            bp->size -= nbytes;
            void *ptr = (char *)bp->ptr + bp->size;
            if ((bp = dalloc(ptr, nbytes, file, line)) != NULL) {
                unsigned h = hash(ptr, htab);
                bp->link = htab[h];
                htab[h] = bp;
                return ptr;
            }
            else {
                if (file == NULL)
                    RAISE(Mem_Failed);
                else
                    Except_raise(&Mem_Failed, file, line);
            }
        }
        if (bp == &freelist) {
            void *ptr = malloc(nbytes + NALLOC);
            struct descriptor *newptr = dalloc(ptr, nbytes + NALLOC, __FILE__, __LINE__);
            if (ptr == NULL || newptr == NULL) {
                if (file == NULL)
                    RAISE(Mem_Failed);
                else
                    Except_raise(&Mem_Failed, file, line);
            }
            newptr->free = freelist.free;
            freelist.free = newptr;
        }
        // exercise 5.2
        if (bp->free->size == sizeof(union align)) {
            struct descriptor *temp = bp->free;
            bp->free = temp->free;
            temp->free = NULL;
        }
    }
    assert(0);
    return NULL;
}
Ejemplo n.º 14
0
void *Mem_alloc(long nbytes, const char *file, int line){
	void *ptr;
	assert(nbytes > 0);
	ptr = malloc(nbytes);
	if (ptr == NULL)
		{
			if (file == NULL)
				RAISE(Mem_Failed);
			else
				Except_raise(&Mem_Failed, file, line);
		}
	return ptr;
}
Ejemplo n.º 15
0
void Mem_free(void* ptr,const char *file,int line)
{
	if(ptr)
	{
		struct descriptor *bp;
		if(((unsigned long)ptr)%(sizeof(union align))!=0||(bp=find(ptr))==NULL||bp->free)
			Except_raise(&Assert_Failed,file,line);

		bp->free=freelist.free;
		freelist.free=bp;
	}

}
Ejemplo n.º 16
0
void *Mem_alloc(long nbytes, const char *file, int line)
{
	void *ptr;
	if (nbytes <= 0) {
		if (file == NULL)
			RAISE(Mem_Failed);
		else
			Except_raise(&Mem_Failed, file, line);
	}
	ptr = malloc(nbytes);

	if (ptr == NULL) {
		if (file == NULL) {
			RAISE(Mem_Failed);
		}
		else {
			Except_raise(&Mem_Failed, file, line);
		}
	}
    alt++;
	return ptr;
}
Ejemplo n.º 17
0
/**
 * Initialize the core.
 *
 * @param coreBinaryPath the path to the core binary.
 * @param toCore a pointer to an int which will be set to the
 *               file descriptor for writing to the core.
 * @param fromCore a pointer to an int which will be set to the
 *                 file descriptor for reading from the core.
 * @param eh an exception handler in case something goes wrong.
 */
static void initCore(char* coreBinaryPath,
                     int* toCore,
                     int* fromCore,
                     struct Except* eh)
{
    int pipes[2][2];
    if (Pipe_createUniPipe(pipes[0]) || Pipe_createUniPipe(pipes[1])) {
        Except_raise(eh, -1, "Failed to create pipes [%s]", Errno_getString());
    }

    // Pipes used in the core process.
    #define TO_ANGEL (pipes[1][1])
    #define FROM_ANGEL (pipes[0][0])

    // Pipes used in the angel process (here).
    #define TO_CORE (pipes[0][1])
    #define FROM_CORE (pipes[1][0])

    char toAngel[32];
    char fromAngel[32];
    snprintf(toAngel, 32, "%u", TO_ANGEL);
    snprintf(fromAngel, 32, "%u", FROM_ANGEL);
    char* args[] = { "core", toAngel, fromAngel, NULL };

    FILE* file;
    if ((file = fopen(coreBinaryPath, "r")) != NULL) {
        fclose(file);
    } else {
        Except_raise(eh, -1, "Can't open core executable [%s] for reading.", coreBinaryPath);
    }

    if (Process_spawn(coreBinaryPath, args)) {
        Except_raise(eh, -1, "Failed to spawn core process.");
    }

    *toCore = TO_CORE;
    *fromCore = FROM_CORE;
}
Ejemplo n.º 18
0
void *Mem_copy( void* destination, void* source, long nbytes, const char *file, int line ) {
	assert(nbytes > 0);

    void *ptr;
	ptr = memcpy( destination, source, nbytes );
	if (ptr == NULL) {
        if (file == NULL)
            RAISE(Mem_Failed);
        else
	        Except_raise(&Mem_Failed, file, line);
    }
    
    return ptr; 
}
Ejemplo n.º 19
0
void *Mem_resize(void *ptr, long nbytes, const char *file, int line) {
    assert( ptr );
    assert( nbytes > 0 );
    
    ptr = realloc( ptr, nbytes );
	if( ptr == NULL ) {
        if (file == NULL)
            RAISE(Mem_Failed);
        else
	        Except_raise(&Mem_Failed, file, line);
    }
    
    return ptr;
}
Ejemplo n.º 20
0
void *Mem_resize(void *ptr,long nbytes,const char *file,int line)
{
	struct descriptor *bp;
	void *newptr;
	assert(ptr);
	assert(nbytes>0);
	if(((unsigned long)ptr)%(sizeof(union align))!=0||(bp=find(ptr))==NULL||bp->free)
		Except_raise(&Assert_Failed,file,line);

	newptr=Mem_alloc(nbytes,file,line);
	memcpy(newptr,ptr,nbytes<bp->size? nbytes:bp->size);
	Mem_free(ptr,file,line);
	return newptr;
}
Ejemplo n.º 21
0
static Dict* getInitialConfig(struct Interface* iface,
                              struct EventBase* eventBase,
                              struct Allocator* alloc,
                              struct Except* eh)
{
    struct Message* m = InterfaceWaiter_waitForData(iface, eventBase, alloc, eh);
    struct Reader* reader = ArrayReader_new(m->bytes, m->length, alloc);
    Dict* config = Dict_new(alloc);
    if (StandardBencSerializer_get()->parseDictionary(reader, alloc, config)) {
        Except_raise(eh, -1, "Failed to parse initial configuration.");
    }

    return config;
}
Ejemplo n.º 22
0
Archivo: mem.c Proyecto: shihyu/cii
//<functions 54>
void *Mem_alloc(long nbytes, const char *file, int line)
{
    void *ptr;

    assert(nbytes > 0);
    ptr = malloc(nbytes);
    if (ptr == NULL) {
        //<raise Mem_Failed 54>
        if (file == NULL) {
            RAISE(Mem_Failed);
        } else {
            Except_raise(&Mem_Failed, file, line);
        }
    }
}
Ejemplo n.º 23
0
void *Mem_calloc( long count, long nbytes, const char *file, int line ) {
    assert(count > 0);
    assert(nbytes > 0);

    void *ptr;
    ptr = calloc(count, nbytes);
    if (ptr == NULL) {
        if (file == NULL)
            RAISE(Mem_Failed);
        else
	        Except_raise(&Mem_Failed, file, line);
    }

    return ptr;
}
Ejemplo n.º 24
0
static
void *align_alloc(size_t nbytes, const char *file, int line){
    void *ptr;
    assert(nbytes > 0);

    ptr = Aligned_malloc(nbytes, ALIGNMENT);
    if (ptr == NULL)
        {
            if (file == NULL)
                RAISE(Mem_Failed);
            else
                Except_raise(&Mem_Failed, file, line);
        }

    return ptr;
}
Ejemplo n.º 25
0
static
void *align_realloc(void *ptr, size_t nbytes, const char *file, int line) {
    assert(ptr);
    assert(nbytes > 0);

    ptr = Aligned_realloc(ptr, nbytes, ALIGNMENT);
    if (ptr == NULL)
        {
            if (file == NULL)
                RAISE(Mem_Failed);
            else
                Except_raise(&Mem_Failed, file, line);
        }

    log_dbg("%p realloc %lu bytes", ptr, (unsigned long) nbytes);
    return ptr;
}
Ejemplo n.º 26
0
void Mem_free(void *ptr, const char *file, int line) {
    if (ptr) {
        struct descriptor *bp = find(ptr);
        if (((unsigned long long)ptr) % (sizeof(union align)) != 0 || bp == NULL || bp->free) {
            if (log_file) {
                fprintf(log_file, "** freeing free memory\n"
                    "Mem_free(0x%p) called from %s:%d\n"
                    "This block is %d bytes long and was allocated from %s:%d\n", \
                    ptr, file, line, bp->size, bp->file, bp->line);
            }
            else
                Except_raise(&Assert_Failed, file, line);
        }
        bp->free = freelist.free;
        freelist.free = bp;
    }
}
Ejemplo n.º 27
0
void * Mem_resize(void *ptr, long nbytes, const char *file, int line) {
    assert(ptr);
    assert(nbytes > 0);

    struct descriptor *bp = find(ptr);
    if (((unsigned long long)ptr) % (sizeof(union align)) != 0 || bp == NULL || bp->free) {
        if (log_file) {
            fprintf(log_file, "** resizing unallocated memory\n"
                "Mem_resize(0x%p, %ld) called from %s:%d\n", \
                ptr, nbytes, file, line);
        }
        else
            Except_raise(&Assert_Failed, file, line);
    }
    void *newptr = Mem_alloc(nbytes, file, line);
    memcpy(newptr, ptr, nbytes < bp->size ? nbytes : bp->size);
    Mem_free(ptr, file, line);
    return newptr;
}
Ejemplo n.º 28
0
LONG(CALLBACK win_exception_handler)(LPEXCEPTION_POINTERS ep) {

    HMODULE hm;
    MODULEINFO mi;
    WCHAR fn[MAX_PATH];
    char message[512];
    unsigned int code;

    code = ep->ExceptionRecord->ExceptionCode;

    GetModuleHandleEx(
        GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)(ep->ExceptionRecord->ExceptionAddress), &hm );
    GetModuleInformation(GetCurrentProcess(), hm, &mi, sizeof(mi) );
    GetModuleFileNameEx(GetCurrentProcess(), hm, fn, MAX_PATH );

    sprintf(message, "SE %s at address %p inside %s loaded at base address %p\n",
        seDescription(code), ep->ExceptionRecord->ExceptionAddress, fn,
        mi.lpBaseOfDll);

    if(code == EXCEPTION_ACCESS_VIOLATION || code == EXCEPTION_IN_PAGE_ERROR ) {
        sprintf("%sInvalid operation: %s at address %p\n", message,
            opDescription(ep->ExceptionRecord->ExceptionInformation[0]),
            ep->ExceptionRecord->ExceptionInformation[1]);
    }

    if(code == EXCEPTION_IN_PAGE_ERROR) {
        sprintf("%sUnderlying NTSTATUS code that resulted in the exception %i", message,
            ep->ExceptionRecord->ExceptionInformation[2]);
    }

    Native_Exception.reason = message;

    SetUnhandledExceptionFilter(win_exception_handler);

    Except_raise(&Native_Exception, "", 0);
    return 0;
}
Ejemplo n.º 29
0
/*
 * This process is started with 2 parameters, they must all be numeric in base 10.
 * toAngel the pipe which is used to send data back to the angel process.
 * fromAngel the pipe which is used to read incoming data from the angel.
 *
 * Upon initialization, this process will wait for an initial configuration to be sent to
 * it and then it will send an initial response.
 */
int Core_main(int argc, char** argv)
{
    struct Except* eh = NULL;
    int toAngel;
    int fromAngel;
    if (argc != 4
        || !(toAngel = atoi(argv[2]))
        || !(fromAngel = atoi(argv[3])))
    {
        Except_raise(eh, -1, "This is internal to cjdns and shouldn't started manually.");
    }

    struct Allocator* alloc = MallocAllocator_new(ALLOCATOR_FAILSAFE);
    struct EventBase* eventBase = EventBase_new(alloc);
    struct Random* rand = Random_new(alloc, eh);

    // -------------------- Setup the Pre-Logger ---------------------- //
    struct Writer* logWriter = FileWriter_new(stdout, alloc);
    struct Log* preLogger = WriterLog_new(logWriter, alloc);
    struct IndirectLog* indirectLogger = IndirectLog_new(alloc);
    indirectLogger->wrappedLog = preLogger;
    struct Log* logger = &indirectLogger->pub;

    // The first read inside of getInitialConfig() will begin it waiting.
    struct PipeInterface* pi =
        PipeInterface_new(fromAngel, toAngel, eventBase, logger, alloc, rand);

    Dict* config = getInitialConfig(&pi->generic, eventBase, alloc, eh);
    String* privateKeyHex = Dict_getString(config, String_CONST("privateKey"));
    Dict* adminConf = Dict_getDict(config, String_CONST("admin"));
    String* pass = Dict_getString(adminConf, String_CONST("pass"));
    if (!pass || !privateKeyHex) {
        Except_raise(eh, -1, "Expected 'pass' and 'privateKey' in configuration.");
    }
    Log_keys(logger, "Starting core with admin password [%s]", pass->bytes);
    uint8_t privateKey[32];
    if (privateKeyHex->len != 64
        || Hex_decode(privateKey, 32, (uint8_t*) privateKeyHex->bytes, 64) != 32)
    {
        Except_raise(eh, -1, "privateKey must be 64 bytes of hex.");
    }

    struct Admin* admin = Admin_new(&pi->generic, alloc, logger, eventBase, pass);

    Dict adminResponse = Dict_CONST(String_CONST("error"), String_OBJ(String_CONST("none")), NULL);
    Admin_sendMessageToAngel(&adminResponse, admin);

    // --------------------- Setup the Logger --------------------- //
    // the prelogger will nolonger be used.
    struct Log* adminLogger = AdminLog_registerNew(admin, alloc, rand);
    indirectLogger->wrappedLog = adminLogger;
    logger = adminLogger;


    // CryptoAuth
    struct Address addr;
    parsePrivateKey(privateKey, &addr, eh);
    struct CryptoAuth* cryptoAuth = CryptoAuth_new(alloc, privateKey, eventBase, logger, rand);

    struct SwitchCore* switchCore = SwitchCore_new(logger, alloc);
    struct DHTModuleRegistry* registry = DHTModuleRegistry_new(alloc);
    ReplyModule_register(registry, alloc);

    // Router
    struct RouterModule* router = RouterModule_register(registry,
                                                        alloc,
                                                        addr.key,
                                                        eventBase,
                                                        logger,
                                                        admin,
                                                        rand);

    SerializationModule_register(registry, logger, alloc);

    struct IpTunnel* ipTun = IpTunnel_new(logger, eventBase, alloc, rand);

    struct Ducttape* dt = Ducttape_register(privateKey,
                                            registry,
                                            router,
                                            switchCore,
                                            eventBase,
                                            alloc,
                                            logger,
                                            admin,
                                            ipTun,
                                            rand);

    struct SwitchPinger* sp =
        SwitchPinger_new(&dt->switchPingerIf, eventBase, logger, alloc);

    // Interfaces.
    struct InterfaceController* ifController =
        DefaultInterfaceController_new(cryptoAuth,
                                       switchCore,
                                       router,
                                       logger,
                                       eventBase,
                                       sp,
                                       alloc);

    // ------------------- Register RPC functions ----------------------- //
    SwitchPinger_admin_register(sp, admin, alloc);
    UDPInterface_admin_register(eventBase, alloc, logger, admin, ifController);
#ifdef HAS_ETH_INTERFACE
    ETHInterface_admin_register(eventBase, alloc, logger, admin, ifController);
#endif
    RouterModule_admin_register(router, admin, alloc);
    AuthorizedPasswords_init(admin, cryptoAuth, alloc);
    Admin_registerFunction("ping", adminPing, admin, false, NULL, admin);
    Admin_registerFunction("Core_exit", adminExit, logger, true, NULL, admin);
    Core_admin_register(addr.ip6.bytes, dt, logger, alloc, admin, eventBase);
    Security_admin_register(alloc, logger, admin);
    IpTunnel_admin_register(ipTun, admin, alloc);

    struct MemoryContext* mc =
        alloc->clone(sizeof(struct MemoryContext), alloc,
            &(struct MemoryContext) {
                .allocator = alloc,
                .admin = admin
            });
Ejemplo n.º 30
0
/** @return a string representing the address and port to connect to. */
static String* initAngel(int fromAngel,
                         int toAngel,
                         int corePipes[2][2],
                         struct PipeInterface** piOut,
                         struct EventBase* eventBase,
                         struct Log* logger,
                         struct Allocator* alloc,
                         struct Random* rand)
{
    #define TO_CORE (corePipes[0][1])
    #define FROM_CORE (corePipes[1][0])
    #define TO_ANGEL_AS_CORE (corePipes[1][1])
    #define FROM_ANGEL_AS_CORE (corePipes[0][0])

    Dict core = Dict_CONST(
        String_CONST("fromCore"), Int_OBJ(FROM_CORE), Dict_CONST(
        String_CONST("toCore"), Int_OBJ(TO_CORE), NULL
    ));
    Dict admin = Dict_CONST(
        String_CONST("bind"), String_OBJ(String_CONST("127.0.0.1")), Dict_CONST(
        String_CONST("core"), Dict_OBJ(&core), Dict_CONST(
        String_CONST("pass"), String_OBJ(String_CONST("abcd")), NULL
    )));
    Dict message = Dict_CONST(
        String_CONST("admin"), Dict_OBJ(&admin), NULL
    );

    struct Allocator* tempAlloc;
    BufferAllocator_STACK(tempAlloc, 1024);

    #define BUFFER_SZ 1023
    uint8_t buff[BUFFER_SZ + 1] = {0};
    struct Writer* w = ArrayWriter_new(buff, BUFFER_SZ, tempAlloc);
    StandardBencSerializer_get()->serializeDictionary(w, &message);

    Log_info(logger, "Writing intial configuration to angel on [%d] config: [%s]", toAngel, buff);
    write(toAngel, buff, w->bytesWritten(w));

    // This is angel->core data, we can throw this away.
    //Waiter_getData(buff, BUFFER_SZ, fromAngel, eventBase, NULL);
    //Log_info(logger, "Init message from angel to core: [%s]", buff);
    Bits_memset(buff, 0, BUFFER_SZ);

    struct PipeInterface* pi =
        PipeInterface_new(FROM_ANGEL_AS_CORE, TO_ANGEL_AS_CORE, eventBase, logger, alloc, rand);
    *piOut = pi;

    Log_info(logger, "PipeInterface [%p] is now ready.", (void*)pi);

    // Make sure the angel sends data to the core.
    InterfaceWaiter_waitForData(&pi->generic, eventBase, alloc, NULL);

    // Send response on behalf of core.
    char coreToAngelResponse[128] = "           PADDING              "
        "\xff\xff\xff\xff"
        "d"
          "5:error" "4:none"
        "e";

    char* start = strchr(coreToAngelResponse, '\xff');
    struct Message m = {
        .bytes = (uint8_t*) start,
        .length = strlen(start),
        .padding = start - coreToAngelResponse
    };
    pi->generic.sendMessage(&m, &pi->generic);

    // This is angel->client data, it will tell us which port was bound.
    Waiter_getData(buff, BUFFER_SZ, fromAngel, eventBase, NULL);

    printf("Response from angel to client: [%s]\n", buff);

    struct Reader* reader = ArrayReader_new(buff, BUFFER_SZ, tempAlloc);
    Dict configStore;
    Dict* config = &configStore;
    Assert_true(!StandardBencSerializer_get()->parseDictionary(reader, tempAlloc, config));

    Dict* responseAdmin = Dict_getDict(config, String_CONST("admin"));
    String* bind = Dict_getString(responseAdmin, String_CONST("bind"));
    Assert_true(bind);

    return String_clone(bind, alloc);
}

/**
 * This spawns itself as the Angel process which spawns itself again as the core process.
 * The "core process" pipes all of its inputs back to the originating process
 */

struct AdminTestFramework* AdminTestFramework_setUp(int argc, char** argv)
{
    if (argc > 1 && !strcmp("angel", argv[1])) {
        exit(AngelInit_main(argc, argv));
    }

    struct Allocator* alloc = CanaryAllocator_new(MallocAllocator_new(1<<20), NULL);

    struct Writer* logwriter = FileWriter_new(stdout, alloc);
    Assert_always(logwriter);
    struct Log* logger = WriterLog_new(logwriter, alloc);

    struct EventBase* eventBase = EventBase_new(alloc);
    struct Random* rand = Random_new(alloc, NULL);

    int fromAngel;
    int toAngel;
    int corePipes[2][2];
    if (Pipe_createUniPipe(corePipes[0]) || Pipe_createUniPipe(corePipes[1])) {
        Except_raise(NULL, -1, "Failed to create pipes [%s]", Errno_getString());
    }
    spawnAngel(&fromAngel, &toAngel);

    struct PipeInterface* pi;
    String* addrStr =
        initAngel(fromAngel, toAngel, corePipes, &pi, eventBase, logger, alloc, rand);

    Log_info(logger, "Angel initialized.");

    String* password = String_new("abcd", alloc);
    struct Admin* admin =
        Admin_new(&pi->generic, alloc, logger, eventBase, password);


    // Now setup the client.

    struct sockaddr_storage addr;
    int addrLen = sizeof(struct sockaddr_storage);
    Bits_memset(&addr, 0, sizeof(struct sockaddr_storage));
    Assert_true(!evutil_parse_sockaddr_port(addrStr->bytes, (struct sockaddr*) &addr, &addrLen));

    struct AdminClient* client =
        AdminClient_new((uint8_t*) &addr, addrLen, password, eventBase, logger, alloc);

    Assert_always(client);

    return alloc->clone(sizeof(struct AdminTestFramework), alloc, &(struct AdminTestFramework) {
        .admin = admin,
        .client = client,
        .alloc = alloc,
        .eventBase = eventBase,
        .logger = logger,
        .addr = alloc->clone(addrLen, alloc, &addr),
        .addrLen = addrLen,
        .angelInterface = &pi->generic
    });
}