void handle_trigger_io() { struct msg_header hdr; struct trigger_service_params params; int ret; int client_fd; client_fd = do_accept(trigger_fd); if (client_fd < 0) return; hdr.len = sizeof(params); ret = read(client_fd, ¶ms, sizeof(params)); if (ret == sizeof(params)) { hdr.type = MSG_TRIGGER_SERVICE; snprintf(params.request_id.ident, sizeof(params.request_id), "SOCKET%d", client_fd); if (libvchan_send(ctrl_vchan, &hdr, sizeof(hdr)) < 0) handle_vchan_error("write hdr"); if (libvchan_send(ctrl_vchan, ¶ms, sizeof(params)) < 0) handle_vchan_error("write params"); } if (ret <= 0) { close(client_fd); } /* do not close client_fd - we'll need it to send the connection details * later (when dom0 accepts the request) */ }
void release_connection(int id) { struct msg_header hdr; struct exec_params params; hdr.type = MSG_CONNECTION_TERMINATED; hdr.len = sizeof(struct exec_params); params.connect_domain = connection_info[id].connect_domain; params.connect_port = connection_info[id].connect_port; if (libvchan_send(ctrl_vchan, &hdr, sizeof(hdr)) < 0) handle_vchan_error("send"); if (libvchan_send(ctrl_vchan, ¶ms, sizeof(params)) < 0) handle_vchan_error("send"); connection_info[id].pid = 0; }
static void send_exit_code(libvchan_t *vchan, int status) { struct msg_header hdr; hdr.type = MSG_DATA_EXIT_CODE; hdr.len = sizeof(int); if (libvchan_send(vchan, &hdr, sizeof(hdr)) != sizeof(hdr)) { fprintf(stderr, "Failed to write exit code to the agent\n"); do_exit(1); } if (libvchan_send(vchan, &status, sizeof(status)) != sizeof(status)) { fprintf(stderr, "Failed to write exit code(2) to the agent\n"); do_exit(1); } }
static void rec_packet(libvchan_t * con) { char done = 1; int data[4]; struct camera_data ca; libvchan_wait(con); int readSize = libvchan_recv(con, data, 4*sizeof(int)); assert(readSize == 4*sizeof(int)); DVM("received bounding box packet\n"); //here are your corners Lee! ca.bbox_l = data[0]; ca.bbox_r = data[1]; ca.bbox_t = data[2]; ca.bbox_b = data[3]; /* int xmid = ((r + l) / 2) - 160; */ /* int ymid = ((b + t) / 2) - 100; */ /* ymid = -1.0*ymid; //sign change (based on how the camera is oriented) */ /* //here are your angles Lee! */ /* ca.angle_x = ((float) xmid)*(0.00410666); */ /* ca.angle_y = ((float) ymid)*(0.00410666); */ if (camera_vm_Output_from_vm_0_write_camera_data(&ca)) { DVM("wrote bounding box\n"); } else { DVM("failed to write bouding box\n"); } DVM("camera_vm: sending ack\n"); libvchan_send(con, &done, sizeof(char)); }
static void handle_input(libvchan_t *vchan) { char buf[MAX_DATA_CHUNK]; int ret; size_t max_len; struct msg_header hdr; max_len = libvchan_buffer_space(vchan)-sizeof(hdr); if (max_len > sizeof(buf)) max_len = sizeof(buf); if (max_len == 0) return; ret = read(local_stdout_fd, buf, max_len); if (ret < 0) { perror("read"); do_exit(1); } hdr.type = is_service ? MSG_DATA_STDOUT : MSG_DATA_STDIN; hdr.len = ret; if (libvchan_send(vchan, &hdr, sizeof(hdr)) != sizeof(hdr)) { fprintf(stderr, "Failed to write STDIN data to the agent\n"); do_exit(1); } if (ret == 0) { close(local_stdout_fd); local_stdout_fd = -1; if (local_stdin_fd == -1) { // if not a remote end of service call, wait for exit status if (is_service) { // if pipe in opposite direction already closed, no need to stay alive if (local_pid == 0) { /* if this is "remote" service end and no real local process * exists (using own stdin/out) send also fake exit code */ send_exit_code(vchan, 0); do_exit(0); } } } } if (!write_vchan_all(vchan, buf, ret)) { if (!libvchan_is_open(vchan)) { // agent disconnected its end of socket, so no future data will be // send there; there is no sense to read from child stdout // // since vchan socket is buffered it doesn't mean all data was // received from the agent close(local_stdout_fd); local_stdout_fd = -1; if (local_stdin_fd == -1) { // since child does no longer accept data on its stdin, doesn't // make sense to process the data from the daemon // // we don't know real exit VM process code (exiting here, before // MSG_DATA_EXIT_CODE message) do_exit(1); } } else perror("write agent"); } }
static void send_service_refused(libvchan_t *vchan, struct service_params *params) { struct msg_header hdr; hdr.type = MSG_SERVICE_REFUSED; hdr.len = sizeof(*params); if (libvchan_send(vchan, &hdr, sizeof(hdr)) != sizeof(hdr)) { fprintf(stderr, "Failed to send MSG_SERVICE_REFUSED hdr to agent\n"); exit(1); } if (libvchan_send(vchan, params, sizeof(*params)) != sizeof(*params)) { fprintf(stderr, "Failed to send MSG_SERVICE_REFUSED to agent\n"); exit(1); } }
int handle_agent_hello(libvchan_t *ctrl, const char *domain_name) { struct msg_header hdr; struct peer_info info; if (libvchan_recv(ctrl, &hdr, sizeof(hdr)) != sizeof(hdr)) { fprintf(stderr, "Failed to read agent HELLO hdr\n"); return -1; } if (hdr.type != MSG_HELLO || hdr.len != sizeof(info)) { fprintf(stderr, "Invalid HELLO packet received: type %d, len %d\n", hdr.type, hdr.len); return -1; } if (libvchan_recv(ctrl, &info, sizeof(info)) != sizeof(info)) { fprintf(stderr, "Failed to read agent HELLO body\n"); return -1; } if (info.version != QREXEC_PROTOCOL_VERSION) { fprintf(stderr, "Incompatible agent protocol version (remote %d, local %d)\n", info.version, QREXEC_PROTOCOL_VERSION); incompatible_protocol_error_message(domain_name, info.version); return -1; } /* send own HELLO */ /* those messages are the same as received from agent, but set it again for * readability */ hdr.type = MSG_HELLO; hdr.len = sizeof(info); info.version = QREXEC_PROTOCOL_VERSION; if (libvchan_send(ctrl, &hdr, sizeof(hdr)) != sizeof(hdr)) { fprintf(stderr, "Failed to send HELLO hdr to agent\n"); return -1; } if (libvchan_send(ctrl, &info, sizeof(info)) != sizeof(info)) { fprintf(stderr, "Failed to send HELLO hdr to agent\n"); return -1; } return 0; }
static int source_process_msg(pa_msgobject * o, int code, void *data, int64_t offset, pa_memchunk * chunk) { int r; struct userdata *u = PA_SOURCE(o)->userdata; int state; switch (code) { case PA_SOURCE_MESSAGE_SET_STATE: state = PA_PTR_TO_UINT(data); r = pa_source_process_msg(o, code, data, offset, chunk); if (r >= 0) { pa_log("source cork req state =%d, now state=%d\n", state, (int) (u->source->state)); uint32_t cmd = 0; if (u->source->state != PA_SOURCE_RUNNING && state == PA_SOURCE_RUNNING) cmd = QUBES_PA_SOURCE_START_CMD; else if (u->source->state == PA_SOURCE_RUNNING && state != PA_SOURCE_RUNNING) cmd = QUBES_PA_SOURCE_STOP_CMD; if (cmd != 0) { if (libvchan_send(u->rec_ctrl, (char*)&cmd, sizeof(cmd)) < 0) { pa_log("vchan: failed to send record cmd"); /* This is a problem in case of enabling recording, in case * of QUBES_PA_SOURCE_STOP_CMD it can happen that remote end * is already disconnected, so indeed will not send further data. * This can happen for example when we terminate the * process because of pacat in dom0 has disconnected. */ if (state == PA_SOURCE_RUNNING) return -1; else return r; } } } return r; case PA_SOURCE_MESSAGE_GET_LATENCY: { size_t n = 0; n += u->memchunk_source.length; *((pa_usec_t *) data) = pa_bytes_to_usec(n, &u->source->sample_spec); return 0; } } return pa_source_process_msg(o, code, data, offset, chunk); }
static int handle_cmdline_body_from_client(int fd, struct msg_header *hdr) { struct exec_params params; int len = hdr->len-sizeof(params); char buf[len]; int use_default_user = 0; int i; if (!read_all(fd, ¶ms, sizeof(params))) { terminate_client(fd); return 0; } if (!read_all(fd, buf, len)) { terminate_client(fd); return 0; } if (hdr->type == MSG_SERVICE_CONNECT) { /* if the service was accepted, do not send spurious * MSG_SERVICE_REFUSED when service process itself exit with non-zero * code */ for (i = 0; i <= policy_pending_max; i++) { if (policy_pending[i].pid && strncmp(policy_pending[i].params.ident, buf, len) == 0) { policy_pending[i].pid = 0; while (policy_pending_max > 0 && policy_pending[policy_pending_max].pid == 0) policy_pending_max--; break; } } } if (!params.connect_port) { struct exec_params client_params; /* allocate port and send it to the client */ params.connect_port = allocate_vchan_port(params.connect_domain); if (params.connect_port <= 0) { fprintf(stderr, "Failed to allocate new vchan port, too many clients?\n"); terminate_client(fd); return 0; } /* notify the client when this connection got terminated */ vchan_port_notify_client[params.connect_port-VCHAN_BASE_DATA_PORT] = fd; client_params.connect_port = params.connect_port; client_params.connect_domain = remote_domain_id; hdr->len = sizeof(client_params); if (!write_all(fd, hdr, sizeof(*hdr))) { terminate_client(fd); release_vchan_port(params.connect_port, params.connect_domain); return 0; } if (!write_all(fd, &client_params, sizeof(client_params))) { terminate_client(fd); release_vchan_port(params.connect_port, params.connect_domain); return 0; } /* restore original len value */ hdr->len = len+sizeof(params); } else { assert(params.connect_port >= VCHAN_BASE_DATA_PORT); assert(params.connect_port < VCHAN_BASE_DATA_PORT+MAX_CLIENTS); } if (!strncmp(buf, default_user_keyword, default_user_keyword_len_without_colon+1)) { use_default_user = 1; hdr->len -= default_user_keyword_len_without_colon; hdr->len += strlen(default_user); } if (libvchan_send(vchan, hdr, sizeof(*hdr)) < 0) handle_vchan_error("send"); if (libvchan_send(vchan, ¶ms, sizeof(params)) < 0) handle_vchan_error("send params"); if (use_default_user) { if (libvchan_send(vchan, default_user, strlen(default_user)) < 0) handle_vchan_error("send default_user"); if (libvchan_send(vchan, buf+default_user_keyword_len_without_colon, len-default_user_keyword_len_without_colon) < 0) handle_vchan_error("send buf"); } else if (libvchan_send(vchan, buf, len) < 0) handle_vchan_error("send buf"); return 1; }