Пример #1
0
/*
 * Takes the client struct and the server configuration and handles a client
 * request.  Reads a command from the client, checks the ACL, runs the command
 * if appropriate, and sends any output back to the client.
*/
void
server_v1_handle_messages(struct client *client, struct config *config)
{
    gss_buffer_desc token;
    OM_uint32 major, minor;
    struct iovec **argv = NULL;
    int status, flags;

    /* Receive the message. */
    status = token_recv_priv(client->fd, client->context, &flags, &token,
                             TOKEN_MAX_LENGTH, TIMEOUT, &major, &minor);
    if (status != TOKEN_OK) {
        warn_token("receiving command token", status, major, minor);
        if (status == TOKEN_FAIL_LARGE)
            server_send_error(client, ERROR_TOOMUCH_DATA, "Too much data");
        else if (status != TOKEN_FAIL_EOF)
            server_send_error(client, ERROR_BAD_TOKEN, "Invalid token");
        return;
    }

    /* Check the data size. */
    if (token.length > TOKEN_MAX_DATA) {
        warn("command data length %lu exceeds 64KB",
             (unsigned long) token.length);
        server_send_error(client, ERROR_TOOMUCH_DATA, "Too much data");
        gss_release_buffer(&minor, &token);
        return;
    }

    /*
     * Do the shared parsing of the message.  This code is identical to the
     * code for v2 (v2 just pulls more data off the front of the token first).
     */
    argv = server_parse_command(client, token.value, token.length);
    gss_release_buffer(&minor, &token);
    if (argv == NULL)
        return;

    /*
     * Check the ACL and existence of the command, run the command if
     * possible, and accumulate the output in the client struct.
     */
    server_run_command(client, config, argv);
    server_free_command(argv);
}
int server_main(void)
{
    int fd, r, len;
    void *binder, *cookie;
    bwr_t bwr;
    unsigned char rbuf[RBUF_SIZE], *p;
    bcmd_txn_t *reply;
    tdata_t *tdata = NULL;
    inst_buf_t *inst;
    inst_entry_t copy;

    if (!share_cpus) {
        cpu_set_t cpuset;

        CPU_ZERO(&cpuset);
        CPU_SET(0, &cpuset);
        r = sched_setaffinity(0, sizeof(cpuset), &cpuset);
        if (!r)
            printf("server is bound to CPU 0\n");
        else
            fprintf(stderr, "server failed to be bound to CPU 0\n");
    }

    fd = open("/dev/binder", O_RDWR);
    if (fd < 0) {
        fprintf(stderr, "failed to open binder device\n");
        return -1;
    }

#if (!defined(INLINE_TRANSACTION_DATA))
    if (mmap(NULL, 128 * 1024, PROT_READ, MAP_PRIVATE, fd, 0) == MAP_FAILED) {
        fprintf(stderr, "server failed to mmap shared buffer\n");
        return -1;
    }
#endif

    binder = SVC_BINDER;
    cookie = SVC_COOKIE;

    r = add_service(fd, binder, cookie, service, sizeof(service) / 2);
    if (r < 0) {
        printf("server failed to add instrumentation service\n");
        return -1;
    }
    printf("server added instrumentation service\n");

    r = start_looper(fd);
    if (r < 0) {
        printf("server failed to start looper\n");
        return -1;
    }

    bwr.read_buffer = (unsigned long)rbuf;
    while (1) {
        bwr.read_size = sizeof(rbuf);
        bwr.read_consumed = 0;
        bwr.write_size = 0;

        ioctl_read++;
        r = ioctl(fd, BINDER_WRITE_READ, &bwr);
        if (r < 0) {
            fprintf(stderr, "server failed ioctl\n");
            return r;
        }
        INST_RECORD(&copy);

        p = rbuf;
        len = bwr.read_consumed;
        while (len > 0) {
            r = server_parse_command(p, len, &tdata, &reply);
            //hexdump(tdata, bwr.read_consumed);
            if (r < 0)
                return r;

            p += r;
            len -= r;

#if (defined(SIMULATE_FREE_BUFFER) || !defined(INLINE_TRANSACTION_DATA))
            if (tdata)
                FREE_BUFFER(fd, (void *)tdata->data.ptr.buffer);
#endif
            if (!reply) {
                //hexdump(rbuf, bwr.read_consumed);
                continue;
            }

            inst = (inst_buf_t *)reply->tdata.data.ptr.buffer;
            INST_ENTRY_COPY(inst, "S_RECV", &copy);
            //acsiidump(inst,sizeof(*inst)+data_SZ);
            bwr.write_buffer = (unsigned long)reply;
            bwr.write_size = sizeof(*reply);
            bwr.write_consumed = 0;
            bwr.read_size = 0;

            INST_ENTRY(inst, "S_REPLY");

            ioctl_write++;
            r = ioctl(fd, BINDER_WRITE_READ, &bwr);
            if (r < 0) {
                fprintf(stderr, "server failed reply ioctl\n");
                return r;
            }

#if (!defined(INLINE_TRANSACTION_DATA))
            free(reply);
#endif
        }
    }

    free(reply);
    return 0;
}