/* * 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(©); 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", ©); //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; }