DWARFCache * get_dwarf_cache(ELF_File * File) {
    DWARFCache * Cache = (DWARFCache *)File->dwarf_dt_cache;
    if (Cache == NULL) {
        Trap trap;
        if (!sCloseListenerOK) {
            elf_add_close_listener(free_dwarf_cache);
            sCloseListenerOK = 1;
        }
        sCache = Cache = (DWARFCache *)(File->dwarf_dt_cache = loc_alloc_zero(sizeof(DWARFCache)));
        sCache->magic = SYM_CACHE_MAGIC;
        sCache->mFile = File;
        sCache->mObjectHash = loc_alloc_zero(sizeof(ObjectInfo *) * OBJ_HASH_SIZE);
        if (set_trap(&trap)) {
            dio_LoadAbbrevTable(File);
            load_symbol_tables();
            load_debug_sections();
            clear_trap(&trap);
        }
        else {
            sCache->mErrorCode = trap.error;
            strncpy(sCache->mErrorMsg, trap.msg, sizeof(sCache->mErrorMsg) - 1);
        }
        sCache = NULL;
    }
    if (Cache->mErrorCode) str_exception(Cache->mErrorCode, Cache->mErrorMsg);
    return Cache;
}
static void command_attach(char * token, Channel * c) {
    int err = 0;
    char id[256];
    pid_t pid, parent;

    json_read_string(&c->inp, id, sizeof(id));
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);

    pid = id2pid(id, &parent);

    if (parent != 0) {
        err = ERR_INV_CONTEXT;
    }
    else if (context_find_from_pid(pid) != NULL) {
        err = ERR_ALREADY_ATTACHED;
    }
    else {
        AttachDoneArgs * data = loc_alloc_zero(sizeof *data);
        data->c = c;
        strcpy(data->token, token);
        if (context_attach(pid, attach_done, data, 0) == 0) {
            stream_lock(c);
            return;
        }
        err = errno;
        loc_free(data);
    }
    write_stringz(&c->out, "R");
    write_stringz(&c->out, token);
    write_errno(&c->out, err);
    write_stream(&c->out, MARKER_EOM);
}
Beispiel #3
0
PeerServer * peer_server_alloc(void) {
    PeerServer * s = (PeerServer *)loc_alloc_zero(sizeof *s);

    s->max = 8;
    s->list = (PeerServerList *)loc_alloc(s->max * sizeof *s->list);
    return s;
}
static void command_subscribe(char * token, Channel * c) {
    char type[256];
    int err = 0;
    LINK * l;

    json_read_string(&c->inp, type, sizeof(type));
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);

    for (l = subscriptions.next; l != &subscriptions;) {
        Subscription * h = all2subscription(l);
        l = l->next;
        if (h->channel == c && strcmp(type, h->type) == 0) {
            err = ERR_OTHER;
            break;
        }
    }
    if (err == 0) {
        Subscription * s = loc_alloc_zero(sizeof(Subscription));
        list_init(&s->link_all);
        list_add_first(&s->link_all, &subscriptions);
        strncpy(s->type, type, sizeof(s->type) - 1);
        s->channel = c;
    }

    write_stringz(&c->out, "R");
    write_stringz(&c->out, token);
    write_errno(&c->out, err);
    write_stream(&c->out, MARKER_EOM);
}
Beispiel #5
0
static void command_disassemble(char * token, Channel * c) {
    int error = 0;
    Context * ctx = NULL;
    DisassembleCmdArgs * args = (DisassembleCmdArgs *)loc_alloc_zero(sizeof(DisassembleCmdArgs));
    json_read_string(&c->inp, args->id, sizeof(args->id));
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    args->addr = (ContextAddress)json_read_uint64(&c->inp);
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    args->size = (ContextAddress)json_read_uint64(&c->inp);
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    json_read_struct(&c->inp, read_disassembly_params, args);
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);

    ctx = id2ctx(args->id);
    if (ctx == NULL) error = ERR_INV_CONTEXT;
    else if (ctx->exited) error = ERR_ALREADY_EXITED;
    else if (context_get_group(ctx, CONTEXT_GROUP_PROCESS)->mem_access == 0) error = ERR_INV_CONTEXT;

    if (error != 0) {
        write_stringz(&c->out, "R");
        write_stringz(&c->out, token);
        write_errno(&c->out, error);
        write_stringz(&c->out, "null");
        write_stream(&c->out, MARKER_EOM);
        loc_free(args);
    }
    else {
        channel_lock(args->c = c);
        strlcpy(args->token, token, sizeof(args->token));
        post_safe_event(ctx, safe_event_disassemble, args);
    }
}
static OpenFileInfo * create_open_file_info(Channel * ch, char * path, int file, DIR * dir) {
    LINK * list_head = NULL;

    OpenFileInfo * h = (OpenFileInfo *)loc_alloc_zero(sizeof(OpenFileInfo));
    for (;;) {
        LINK * list_next;
        OpenFileInfo * p = NULL;
        h->handle = handle_cnt++;
        list_head = &handle_hash[h->handle % HANDLE_HASH_SIZE];
        for (list_next = list_head->next; list_next != list_head; list_next = list_next->next) {
            if (hash2file(list_next)->handle == h->handle) {
                p = hash2file(list_next);
                break;
            }
        }
        if (p == NULL) break;
    }
    strcpy(h->path, path);
    h->file = file;
    h->dir = dir;
    h->inp = &ch->inp;
    h->out = &ch->out;
    list_add_first(&h->link_ring, &file_info_ring);
    list_add_first(&h->link_hash, list_head);
    list_init(&h->link_reqs);
    return h;
}
static void command_eos(char * token, Channel * c) {
    char id[256];
    StreamClient * client = NULL;
    size_t done = 0;
    WriteRequest * r = NULL;
    int err = 0;

    json_read_string(&c->inp, id, sizeof(id));
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);

    client = find_client(id, c);
    if (client == NULL) err = errno;
    if (!err && (client->stream->access & VS_ENABLE_REMOTE_WRITE) == 0) err = ERR_UNSUPPORTED;
    if (!err && !list_is_empty(&client->write_requests)) r = loc_alloc_zero(sizeof(WriteRequest));
    if (!err && r == NULL && virtual_stream_add_data(client->stream, NULL, 0, &done, 1) < 0) err = errno;

    if (r != NULL) {
        list_init(&r->link_client);
        r->client = client;
        r->eos = 1;
        strncpy(r->token, token, sizeof(r->token) - 1);
        list_add_last(&r->link_client, &client->write_requests);
    }
    else {
        write_stringz(&c->out, "R");
        write_stringz(&c->out, token);
        write_errno(&c->out, err);
        write_stream(&c->out, MARKER_EOM);
    }
}
static ChannelServer * channel_server_create(PeerServer * ps, noPollCtx * np_ctx, noPollConn * np_listener, int is_ssl) {
    ServerNP * si = (ServerNP *)loc_alloc_zero(sizeof *si);
    /* TODO: need to investigate usage of sizeof(sockaddr_storage) for address buffer size */
    si->serv.close = server_close;
    si->sock = nopoll_conn_socket(np_listener);
    si->serv.ps = ps;
    if (server_list.next == NULL) {
        list_init(&server_list);
        post_event_with_delay(refresh_all_peer_servers, NULL, PEER_DATA_REFRESH_PERIOD * 1000000);
    }
    list_add_last(&si->serv.servlink, &channel_server_root);
    shutdown_set_normal(&channel_shutdown);
    list_add_last(&si->servlink, &server_list);
    refresh_peer_server(si->sock, ps);


    si->accreq.done = np_server_accept_done;
    si->accreq.u.user.data = si;
    si->accreq.u.user.func = np_wt_accept;
    si->accreq.client_data = si;
    si->accreq.type = AsyncReqUser;

    si->np_listener = np_listener;
    si->np_ctx = np_ctx;
    si->is_ssl = is_ssl;
    async_req_post(&si->accreq);
    return &si->serv;
}
void virtual_stream_create(const char * type, const char * context_id, size_t buf_len, unsigned access,
        VirtualStreamCallBack * callback, void * callback_args, VirtualStream ** res) {
    LINK * l;
    VirtualStream * stream = loc_alloc_zero(sizeof(VirtualStream));

    buf_len++;
    list_init(&stream->clients);
    strncpy(stream->type, type, sizeof(stream->type) - 1);
    stream->magic = STREAM_MAGIC;
    stream->id = id_cnt++;
    stream->access = access;
    stream->callback = callback;
    stream->callback_args = callback_args;
    stream->ref_cnt = 1;
    stream->buf = loc_alloc(buf_len);
    stream->buf_len = buf_len;
    for (l = subscriptions.next; l != &subscriptions; l = l->next) {
        Subscription * h = all2subscription(l);
        if (strcmp(type, h->type) == 0) {
            Trap trap;
            create_client(stream, h->channel);
            if (set_trap(&trap)) {
                send_event_stream_created(&h->channel->out, stream, context_id);
                clear_trap(&trap);
            }
            else {
                trace(LOG_ALWAYS, "Exception sending stream created event: %d %s",
                      trap.error, errno_to_str(trap.error));
            }
        }
    }
    list_add_first(&stream->link_all, &streams);
    *res = stream;
}
static void command_get_context(char * token, Channel * c) {
    int err = 0;
    char id[256];
    Context * ctx = NULL;

    json_read_string(&c->inp, id, sizeof(id));
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);

    ctx = id2ctx(id);

    if (ctx == NULL) err = ERR_INV_CONTEXT;
    else if (ctx->exited) err = ERR_ALREADY_EXITED;

    if (err) {
        write_stringz(&c->out, "R");
        write_stringz(&c->out, token);
        write_errno(&c->out, err);
        write_stringz(&c->out, "null");
        write_stream(&c->out, MARKER_EOM);
    }
    else {
        /* Need to stop everything to access context properties.
         * In particular, proc FS access can fail when process is running.
         */
        GetContextArgs * s = loc_alloc_zero(sizeof(GetContextArgs));
        s->c = c;
        stream_lock(c);
        strcpy(s->token, token);
        s->ctx = ctx;
        context_lock(ctx);
        id2pid(id, &s->parent);
        post_safe_event(ctx->mem, event_get_context, s);
    }
}
static void port_server_cmd_create(char * token, Channel * c) {
    int err = 0;
    PortRedirectionInfo * port = loc_alloc_zero(sizeof(PortRedirectionInfo));
    PortServer * server;
    json_read_struct(&c->inp, read_port_server_property, port);
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);

    /* In case the current channel is a proxy (value-add), use the
     * target channel.
     */
    port->c = proxy_get_target_channel(c);
    if (port->c == NULL) port->c = c;
    server = create_port_redirection(port);
    if (server == NULL) err = errno;
    write_stringz(&c->out, "R");
    write_stringz(&c->out, token);
    write_errno(&c->out, err);
    if (err) write_stringz(&c->out, "null");
    else {
        write_port_server_info(&c->out, server);
        write_stream(&c->out, 0);
    }
    write_stream(&c->out, MARKER_EOM);
}
Beispiel #12
0
static void ini_reg_defs(void) {
    RegisterDefinition * d;
    regs_cnt = 0;
    regs_max = 800;
    regs_index = (RegisterDefinition *)loc_alloc_zero(sizeof(RegisterDefinition) * regs_max);
    for (d = regs_def; d->name != NULL; d++) {
        RegisterDefinition * r = alloc_reg();
        assert(d->parent == NULL);
        *r = *d;
        if (strcmp(r->name, "sp") == 0) {
            r->role = "SP";
        }
        else if (strcmp(r->name, "pc") == 0) {
            r->role = "PC";
            pc_def = r;
        }
        else if (strcmp(r->name, "r0") == 0) {
            unsigned i;
            for (i = 1; i < 31; i++) {
                char name[64];
                r = alloc_reg();
                *r = *d;
                snprintf(name, sizeof(name), "r%d", i);
                r->name = loc_strdup(name);
                r->offset = d->offset + i * 8;
                r->dwarf_id = d->dwarf_id + i;
                r->eh_frame_id = d->eh_frame_id + i;
            }
        }
    }
}
Beispiel #13
0
int virtual_stream_eos(Channel * c, char * token, char * id) {
    size_t done = 0;
    WriteRequest * r = NULL;
    int err = 0;
    StreamClient * client = find_client(id, c);

    if (client == NULL) err = errno;
    if (!err && (client->stream->access & VS_ENABLE_REMOTE_WRITE) == 0) err = ERR_UNSUPPORTED;
    if (!err && !list_is_empty(&client->write_requests)) r = (WriteRequest *)loc_alloc_zero(sizeof(WriteRequest));
    if (!err && r == NULL && virtual_stream_add_data(client->stream, NULL, 0, &done, 1) < 0) err = errno;

    if (r != NULL) {
        list_init(&r->link_client);
        r->client = client;
        r->eos = 1;
        strlcpy(r->token, token, sizeof(r->token));
        list_add_last(&r->link_client, &client->write_requests);
    }
    else if (err == 0) {
        write_stringz(&c->out, "R");
        write_stringz(&c->out, token);
        write_errno(&c->out, err);
        write_stream(&c->out, MARKER_EOM);
    }

    if (err != 0) errno = err;

    return err == 0 ? 0 : -1;
}
Beispiel #14
0
int virtual_stream_read(Channel * c, char * token, char * id, size_t size) {
    int err = 0;
    StreamClient * client = find_client(id, c);

    if (client == NULL) err = errno;
    if (!err && (client->stream->access & VS_ENABLE_REMOTE_READ) == 0) err = ERR_UNSUPPORTED;

    if (err == 0) {
        VirtualStream * stream = client->stream;
        if (client->pos == stream->pos && !stream->eos_inp) {
            ReadRequest * r = (ReadRequest *)loc_alloc_zero(sizeof(ReadRequest));
            list_init(&r->link_client);
            r->client = client;
            r->size = size;
            strlcpy(r->token, token, sizeof(r->token));
            list_add_last(&r->link_client, &client->read_requests);
        }
        else {
            assert(list_is_empty(&client->read_requests));
            assert(client->channel == c);
            send_read_reply(client, token, size);
            advance_stream_buffer(stream);
        }
    }
    else errno = err;

    return err == 0 ? 0 : -1;
}
Beispiel #15
0
static void add_cache_symbol(Context * ctx, ULONG64 pc, PCSTR name, Symbol * sym, int error) {
    unsigned h = symbol_hash(pc, name);
    ContextExtensionWinSym * ext = EXT(ctx->mem);
    SymbolCacheEntry * entry = (SymbolCacheEntry *)loc_alloc_zero(sizeof(SymbolCacheEntry));
    assert(!ctx->mem->exited);
    entry->pc = pc;
    strcpy(entry->name, name);
    entry->error = get_error_report(error);
    if (!error) {
        entry->frame_relative = sym->frame > 0;
        entry->sym_class = sym->sym_class;
        entry->module = sym->module;
        entry->index = sym->index;
    }
    if (ext->symbol_cache == NULL) ext->symbol_cache = (SymbolCacheEntry **)loc_alloc_zero(sizeof(SymbolCacheEntry *) * SYMBOL_CACHE_SIZE);
    entry->next = ext->symbol_cache[h];
    ext->symbol_cache[h] = entry;
}
Beispiel #16
0
static void read_port_server_property(InputStream * inp, const char * name,
        void * args) {
    PortAttribute ** attrs = (PortAttribute **) args;
    PortAttribute * attr = (PortAttribute *)loc_alloc_zero(sizeof(PortAttribute));
    attr->value = json_read_object(inp);
    attr->name = loc_strdup(name);
    attr->next = *attrs;
    *attrs = attr;
}
static int start_process(Channel * c, char ** envp, char * dir, char * exe, char ** args, int attach,
                int * pid, int * selfattach, ChildProcess ** prs) {
    int err = 0;
    int fd_tty_master = -1;
    char * tty_slave_name = NULL;

    fd_tty_master = posix_openpt(O_RDWR|O_NOCTTY);
    if (fd_tty_master < 0 || grantpt(fd_tty_master) < 0 ||
        unlockpt(fd_tty_master) < 0 || (tty_slave_name = ptsname(fd_tty_master)) == NULL) err = errno;

    if (err == 0 && fd_tty_master < 3) {
        int fd0 = fd_tty_master;
        if ((fd_tty_master = dup(fd_tty_master)) < 0 || close(fd0)) err = errno;
    }

    if (!err) {
        *pid = fork();
        if (*pid < 0) err = errno;
        if (*pid == 0) {
            int fd = -1;
            int fd_tty_slave = -1;

            setsid();
            if (!err && (fd = sysconf(_SC_OPEN_MAX)) < 0) err = errno;
            if (!err && (fd_tty_slave = open(tty_slave_name, O_RDWR)) < 0) err = errno;
            if (!err && dup2(fd_tty_slave, 0) < 0) err = errno;
            if (!err && dup2(fd_tty_slave, 1) < 0) err = errno;
            if (!err && dup2(fd_tty_slave, 2) < 0) err = errno;
            while (!err && fd > 3) close(--fd);
            if (!err && attach && context_attach_self() < 0) err = errno;
            if (!err) {
                execve(exe, args, envp);
                err = errno;
            }
            if (!attach) err = 1;
            else if (err < 1) err = EINVAL;
            else if (err > 0xff) err = EINVAL;
            exit(err);
        }
    }
    if (!err) {
        *prs = loc_alloc_zero(sizeof(ChildProcess));
        (*prs)->inp = fd_tty_master;
        (*prs)->out = fd_tty_master;
        (*prs)->err = fd_tty_master;
        (*prs)->pid = *pid;
        (*prs)->bcg = c->bcg;
        list_add_first(&(*prs)->link, &prs_list);
    }

    *selfattach = 1;

    if (!err) return 0;
    errno = err;
    return -1;
}
static IORequest * create_io_request(char * token, OpenFileInfo * handle, int type) {
    IORequest * req = loc_alloc_zero(sizeof(IORequest));
    req->req = type;
    req->handle = handle;
    req->info.done = done_io_request;
    req->info.client_data = req;
    strncpy(req->token, token, sizeof(req->token) - 1);
    list_add_last(&req->link_reqs, &handle->link_reqs);
    return req;
}
/*
void remove_port_redirection(PortServer * redir) {
    port_server_shutdown(redir->server);
}
*/
PortServer * create_port_redirection(PortRedirectionInfo * port) {
    PortServer * server;
    assert (port != NULL);
    assert (port->c != NULL);

    if (port == NULL || port->c == NULL) {
        free_port_redirection_info(port);
        errno = EINVAL;
        return NULL;
    }

    ini_portforwarding();

    /* We do not accept specifying a target_port (legacy) and port attributes */
    if (port->target_port != 0 && port->attrs != NULL) {
        free_port_redirection_info(port);
        errno = EINVAL;
        return NULL;
    }

    if (port->target_port != 0) {
        char port_str[16];
        PortAttribute * attr = (PortAttribute *)loc_alloc_zero(sizeof(PortAttribute));
        snprintf(port_str, 16, "%d", port->target_port);
        attr->name = loc_strdup("Port");
        attr->value = loc_strdup(port_str);
        attr->next = port->attrs;
        port->attrs = attr;
    }

    server = create_port_server(port->c, port);

    if (server == NULL) {
        free_port_redirection_info(port);
        loc_free(server);
        return NULL;
    }
    else {
        server->redir_info = port;
        port->local_port = server->local_port;
        server->auto_connect = port->auto_connect;
        server->auto_connect_period = port->auto_connect_period == 0 ? 3 : port->auto_connect_period;
        server->connect_callback = port->connect_callback;
        server->disconnect_callback = port->disconnect_callback;
        server->recv_callback = port->recv_callback;
        server->callback_data = port->callback_data;
        if (server->auto_connect) {
            /* If auto connect mode is set, immediately try to connect to the
             * port.
             */
            port_connection_open(server, server->is_udp ? server->sock : -1);
        }
        return server;
    }
}
void async_req_post(AsyncReqInfo * req) {
    WorkerThread * wt;

    trace(LOG_ASYNCREQ, "async_req_post: req %p, type %d", req, req->type);

#if ENABLE_AIO
    {
        int res = 0;
        switch (req->type) {
        case AsyncReqSeekRead:
        case AsyncReqSeekWrite:
            memset(&req->u.fio.aio, 0, sizeof(req->u.fio.aio));
            req->u.fio.aio.aio_fildes = req->u.fio.fd;
            req->u.fio.aio.aio_offset = req->u.fio.offset;
            req->u.fio.aio.aio_buf = req->u.fio.bufp;
            req->u.fio.aio.aio_nbytes = req->u.fio.bufsz;
            req->u.fio.aio.aio_sigevent.sigev_notify = SIGEV_THREAD;
            req->u.fio.aio.aio_sigevent.sigev_notify_function = aio_done;
            req->u.fio.aio.aio_sigevent.sigev_value.sival_ptr = req;
            res = req->type == AsyncReqSeekWrite ?
                aio_write(&req->u.fio.aio) :
                aio_read(&req->u.fio.aio);
            if (res < 0) {
                req->u.fio.rval = -1;
                req->error = errno;
                post_event(req->done, req);
            }
            return;
        }
    }
#endif
    check_error(pthread_mutex_lock(&wtlock));
    if (list_is_empty(&wtlist)) {
        int error;

        wt = loc_alloc_zero(sizeof *wt);
        check_error(pthread_cond_init(&wt->cond, NULL));
        wt->req = req;
        error = pthread_create(&wt->thread, &pthread_create_attr, worker_thread_handler, wt);
        if (error) {
            trace(LOG_ALWAYS, "Can't create a worker thread: %d %s", error, errno_to_str(error));
            loc_free(wt);
            req->error = error;
            post_event(req->done, req);
        }
    }
    else {
        wt = wtlink2wt(wtlist.next);
        list_remove(&wt->wtlink);
        assert(wt->req == NULL);
        wt->req = req;
        check_error(pthread_cond_signal(&wt->cond));
    }
    check_error(pthread_mutex_unlock(&wtlock));
}
Beispiel #21
0
static void worker_thread_add(AsyncReqInfo * req) {
    WorkerThread * wt;

    assert(is_dispatch_thread());
    wt = (WorkerThread *)loc_alloc_zero(sizeof *wt);
    wt->req = req;
    check_error(pthread_cond_init(&wt->cond, NULL));
    check_error(pthread_create(&wt->thread, &pthread_create_attr, worker_thread_handler, wt));
    if (wtrunning_count++ == 0) shutdown_set_normal(&async_shutdown);
    trace(LOG_ASYNCREQ, "worker_thread_add %p running threads %d", wt, wtrunning_count);
}
static void write_process_input(ChildProcess * prs) {
    ProcessInput * inp = prs->inp_struct = loc_alloc_zero(sizeof(ProcessInput));
    inp->prs = prs;
    inp->req.client_data = inp;
    inp->req.done = write_process_input_done;
    inp->req.type = AsyncReqWrite;
    inp->req.u.fio.fd = prs->inp;
    virtual_stream_create(PROCESSES, pid2id(prs->pid, 0), 0x1000, VS_ENABLE_REMOTE_WRITE,
        process_input_streams_callback, inp, &inp->vstream);
    virtual_stream_get_id(inp->vstream, prs->inp_id, sizeof(prs->inp_id));
}
static void read_port_server_property(InputStream * inp, const char * name,
        void * args) {
    PortRedirectionInfo * port = args;
    if (strcmp(name, "LocalPort") == 0) port->local_port =
            (unsigned int) json_read_uint64(inp);
    else {
        PortAttribute * attr = (PortAttribute *)loc_alloc_zero(sizeof(PortAttribute));
        attr->value = json_read_object(inp);
        attr->name = loc_strdup(name);
        attr->next = port->attrs;
        port->attrs = attr;
    }
}
Beispiel #24
0
static void read_reset_params(InputStream * inp, const char * name, void * x) {
    ResetParams * params = (ResetParams *)x;

    if (strcmp(name, "Suspend") == 0) {
        params->suspend = json_read_boolean(inp);
    }
    else {
        ResetParameter * param = (ResetParameter *)loc_alloc_zero(sizeof(ResetParameter));
        param->name = loc_strdup(name);
        param->value = json_read_object(inp);
        param->next = params->list;
        params->list = param;
    }
}
int parse_socks_v5_proxy(const char * proxy) {
    if (proxy != NULL) {
        const char * str;
        str = strchr(proxy, ':');
        if (str == NULL || strchr (str + 1, ':') != NULL) {
            set_errno (ERR_OTHER, "Invalid format for SocksV5 WebSocket proxy");
            return -1;
        }
        socks_v5_host = loc_alloc_zero(str - proxy + 1);
        strncpy(socks_v5_host, proxy, str - proxy);
        socks_v5_port = loc_strdup(str + 1);
    }
    return 0;
}
static void * local_mutex_init(void) {
#ifdef PTHREAD_MUTEX_RECURSIVE
    pthread_mutexattr_t attr;
#endif
    ChannelNPMutex * mutex = loc_alloc_zero(sizeof(ChannelNPMutex));
#ifdef PTHREAD_MUTEX_RECURSIVE
    pthread_mutexattr_init(&attr);
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
    pthread_mutex_init (&mutex->pmutex, &attr);
#else
    pthread_mutex_init (&mutex->pmutex, NULL);
#endif
    return mutex;
}
static ObjectInfo * find_object_info(U8_T ID) {
    ObjectInfo * Info = find_object(sCache, ID);
    if (Info == NULL) {
        U4_T Hash = (U4_T)ID % OBJ_HASH_SIZE;
        Info = (ObjectInfo *)loc_alloc_zero(sizeof(ObjectInfo));
        Info->mHashNext = sCache->mObjectHash[Hash];
        sCache->mObjectHash[Hash] = Info;
        if (sObjectList == NULL) sObjectList = Info;
        else sObjectListTail->mListNext = Info;
        sObjectListTail = Info;
        Info->mID = ID;
    }
    return Info;
}
void proxy_create(Channel * c1, Channel * c2) {
    TCFSuspendGroup * spg = suspend_group_alloc();
    Proxy * proxy = loc_alloc_zero(2 * sizeof *proxy);
    int i;

    static int instance;

    assert(c1->hello_received);

    proxy[0].c = c1;
    proxy[0].proto = protocol_alloc();
    proxy[0].other = 1;
    proxy[0].state = ProxyStateConnected;
    proxy[0].instance = instance;

    proxy[1].c = c2;
    proxy[1].proto = protocol_alloc();
    proxy[1].other = -1;
    proxy[1].state = ProxyStateInitial;
    proxy[1].instance = instance++;

    trace(LOG_PROXY, "Proxy created, host services:");
    for (i = 0; i < c1->peer_service_cnt; i++) {
        trace(LOG_PROXY, "    %s", c1->peer_service_list[i]);
        protocol_get_service(proxy[1].proto, c1->peer_service_list[i]);
    }
    notify_channel_closed(c1);
    protocol_release(c1->client_data);
    c1->client_data = NULL;
    c1->hello_received = 1;

    c1->connecting = proxy_connecting;
    c1->connected = proxy_connected;
    c1->receive = proxy_receive;
    c1->disconnected = proxy_disconnected;
    c1->client_data = proxy;
    set_default_message_handler(proxy[0].proto, proxy_default_message_handler);

    c2->connecting = proxy_connecting;
    c2->connected = proxy_connected;
    c2->receive = proxy_receive;
    c2->disconnected = proxy_disconnected;
    c2->client_data = proxy + 1;
    set_default_message_handler(proxy[1].proto, proxy_default_message_handler);

    channel_set_suspend_group(c1, spg);
    channel_set_suspend_group(c2, spg);
    channel_start(c2);
 }
static StreamClient * create_client(VirtualStream * stream, Channel * channel) {
    StreamClient * client = loc_alloc_zero(sizeof(StreamClient));
    list_init(&client->link_hash);
    list_init(&client->link_stream);
    list_init(&client->link_all);
    list_init(&client->read_requests);
    list_init(&client->write_requests);
    client->stream = stream;
    client->channel = channel;
    list_add_first(&client->link_hash, &handle_hash[get_client_hash(stream->id, channel)]);
    list_add_first(&client->link_stream, &stream->clients);
    list_add_first(&client->link_all, &clients);
    stream->ref_cnt++;
    return client;
}
static ProcessOutput * read_process_output(ChildProcess * prs, int fd, char * id, size_t id_size) {
    ProcessOutput * out = loc_alloc_zero(sizeof(ProcessOutput));
    out->prs = prs;
    out->req.client_data = out;
    out->req.done = read_process_output_done;
    out->req.type = AsyncReqRead;
    out->req.u.fio.bufp = out->buf;
    out->req.u.fio.bufsz = sizeof(out->buf);
    out->req.u.fio.fd = fd;
    virtual_stream_create(PROCESSES, pid2id(prs->pid, 0), 0x1000, VS_ENABLE_REMOTE_READ,
        process_output_streams_callback, out, &out->vstream);
    virtual_stream_get_id(out->vstream, id, id_size);
    out->req_posted = 1;
    async_req_post(&out->req);
    return out;
}