static int ta_access_test(void) { int fd; if (!opt_silent) { printf("%s:\n", __func__); } fd = tipc_connect(dev_name, ta_only_name); if (fd >= 0) { fprintf(stderr, "Succeed to connect to '%s' service\n", "ta_only"); tipc_close(fd); } fd = tipc_connect(dev_name, ns_only_name); if (fd < 0) { fprintf(stderr, "Failed to connect to '%s' service\n", "ns_only"); return fd; } tipc_close(fd); if (!opt_silent) { printf("%s: done\n",__func__); } return 0; }
static int closer2_test(uint repeat) { uint i; int fd; if (!opt_silent) { printf("%s: repeat = %u\n", __func__, repeat); } for (i = 0; i < repeat; i++) { fd = tipc_connect(dev_name, closer2_name); if (fd < 0) { if (!opt_silent) { printf("failed to connect to '%s' service\n", "closer2"); } } else { /* this should always fail */ fprintf(stderr, "connected to '%s' service\n", "closer2"); tipc_close(fd); } } if (!opt_silent) { printf("%s: done\n", __func__); } return 0; }
static int closer1_test(uint repeat) { uint i; int fd; if (!opt_silent) { printf("%s: repeat = %u\n", __func__, repeat); } for (i = 0; i < repeat; i++) { fd = tipc_connect(dev_name, closer1_name); if (fd < 0) { fprintf(stderr, "Failed to connect to '%s' service\n", "closer1"); continue; } if (!opt_silent) { printf("%s: connected\n", __func__); } tipc_close(fd); } if (!opt_silent) { printf("%s: done\n", __func__); } return 0; }
static int dev_uuid_test(void) { int fd; ssize_t rc; uuid_t uuid; fd = tipc_connect(dev_name, uuid_name); if (fd < 0) { fprintf(stderr, "Failed to connect to '%s' service\n", "uuid"); return fd; } /* wait for test to complete */ rc = read(fd, &uuid, sizeof(uuid)); if (rc < 0) { perror("dev_uuid_test: read"); } else if (rc != sizeof(uuid)) { fprintf(stderr, "unexpected uuid size (%d vs. %d)\n", (int)rc, (int)sizeof(uuid)); } else { print_uuid(dev_name, &uuid); } tipc_close(fd); return 0; }
static int connect_test(uint repeat) { uint i; int echo_fd; int dsink_fd; if (!opt_silent) { printf("%s: repeat = %u\n", __func__, repeat); } for (i = 0; i < repeat; i++) { echo_fd = tipc_connect(dev_name, echo_name); if (echo_fd < 0) { fprintf(stderr, "Failed to connect to '%s' service\n", "echo"); } dsink_fd = tipc_connect(dev_name, datasink_name); if (dsink_fd < 0) { fprintf(stderr, "Failed to connect to '%s' service\n", "datasink"); } if (echo_fd >= 0) { tipc_close(echo_fd); } if (dsink_fd >= 0) { tipc_close(dsink_fd); } } if (!opt_silent) { printf("%s: done\n", __func__); } return 0; }
static int burst_write_test(uint repeat, uint msgburst, uint msgsz, bool var) { int fd; uint i, j; ssize_t rc; size_t msg_len; char tx_buf[msgsz]; if (!opt_silent) { printf("%s: repeat %u: burst %u: msgsz %u: variable %s\n", __func__, repeat, msgburst, msgsz, var ? "true" : "false"); } for (i = 0; i < repeat; i++) { fd = tipc_connect(dev_name, datasink_name); if (fd < 0) { fprintf(stderr, "Failed to connect to '%s' service\n", "datasink"); break; } for (j = 0; j < msgburst; j++) { msg_len = msgsz; if (var && msgsz) { msg_len = rand() % msgsz; } memset(tx_buf, i + 1, msg_len); rc = write(fd, tx_buf, msg_len); if ((size_t)rc != msg_len) { perror("burst_test: write"); break; } } tipc_close(fd); } if (!opt_silent) { printf("%s: done\n",__func__); } return 0; }
static int select_test(uint repeat, uint msgburst, uint msgsz) { int fd; uint i, j; ssize_t rc; char tx_buf[msgsz]; if (!opt_silent) { printf("%s: repeat %u\n", __func__, repeat); } fd = tipc_connect(dev_name, echo_name); if (fd < 0) { fprintf(stderr, "Failed to connect to '%s' service\n", "echo"); return fd; } for (i = 0; i < repeat; i++) { _wait_for_msg(fd, msgsz, 1); if (!opt_silent) { printf("sending burst: %u msg\n", msgburst); } for (j = 0; j < msgburst; j++) { memset(tx_buf, i + j, msgsz); rc = write(fd, tx_buf, msgsz); if ((size_t)rc != msgsz) { perror("burst_test: write"); break; } } } tipc_close(fd); if (!opt_silent) { printf("%s: done\n",__func__); } return 0; }
static int blocked_read_test(uint repeat) { int fd; uint i; ssize_t rc; char rx_buf[512]; if (!opt_silent) { printf("%s: repeat %u\n", __func__, repeat); } fd = tipc_connect(dev_name, echo_name); if (fd < 0) { fprintf(stderr, "Failed to connect to '%s' service\n", "echo"); return fd; } for (i = 0; i < repeat; i++) { rc = read(fd, rx_buf, sizeof(rx_buf)); if (rc < 0) { perror("select_test: read"); break; } else { if (!opt_silent) { printf("got %zd bytes\n", rc); } } } tipc_close(fd); if (!opt_silent) { printf("%s: done\n",__func__); } return 0; }
static int ta2ta_ipc_test(void) { int fd; char rx_buf[64]; if (!opt_silent) { printf("%s:\n", __func__); } fd = tipc_connect(dev_name, main_ctrl_name); if (fd < 0) { fprintf(stderr, "Failed to connect to '%s' service\n", "main_ctrl"); return fd; } /* wait for test to complete */ (void) read(fd, rx_buf, sizeof(rx_buf)); tipc_close(fd); return 0; }
static int connect_foo(uint repeat) { uint i; int fd; if (!opt_silent) { printf("%s: repeat = %u\n", __func__, repeat); } for (i = 0; i < repeat; i++) { fd = tipc_connect(dev_name, "foo"); if (fd >= 0) { fprintf(stderr, "succeeded to connect to '%s' service\n", "foo"); tipc_close(fd); } } if (!opt_silent) { printf("%s: done\n", __func__); } return 0; }
void trusty_keymaster_disconnect() { if (handle_ != 0) { tipc_close(handle_); } }
void trusty_gatekeeper_disconnect() { if (handle_ != 0) { tipc_close(handle_); } }
TrustyNvramImplementation::~TrustyNvramImplementation() { if (tipc_nvram_fd_ != -1) { tipc_close(tipc_nvram_fd_); tipc_nvram_fd_ = -1; } }
void net_loop(void) { int tipc_fd = -1; int tcp_fd = -1; int udp_fd = -1; int sctp_fd = -1; struct event tipc_evt, tcp_evt, udp_evt, sctp_evt, sigterm_evt, sigint_evt, sighup_evt, sigusr1_evt, sigusr2_evt; event_init(); /* ENABLE_* are preprocessor constants defined on the command line by * make. */ if (ENABLE_TIPC) { tipc_fd = tipc_init(); if (tipc_fd < 0) { errlog("Error initializing TIPC"); exit(1); } event_set(&tipc_evt, tipc_fd, EV_READ | EV_PERSIST, tipc_recv, &tipc_evt); event_add(&tipc_evt, NULL); } if (ENABLE_TCP) { tcp_fd = tcp_init(); if (tcp_fd < 0) { errlog("Error initializing TCP"); exit(1); } event_set(&tcp_evt, tcp_fd, EV_READ | EV_PERSIST, tcp_newconnection, &tcp_evt); event_add(&tcp_evt, NULL); } if (ENABLE_UDP) { udp_fd = udp_init(); if (udp_fd < 0) { errlog("Error initializing UDP"); exit(1); } event_set(&udp_evt, udp_fd, EV_READ | EV_PERSIST, udp_recv, &udp_evt); event_add(&udp_evt, NULL); } if (ENABLE_SCTP) { sctp_fd = sctp_init(); if (sctp_fd < 0) { errlog("Error initializing SCTP"); exit(1); } event_set(&sctp_evt, sctp_fd, EV_READ | EV_PERSIST, sctp_recv, &sctp_evt); event_add(&sctp_evt, NULL); } signal_set(&sigterm_evt, SIGTERM, exit_sighandler, &sigterm_evt); signal_add(&sigterm_evt, NULL); signal_set(&sigint_evt, SIGINT, exit_sighandler, &sigint_evt); signal_add(&sigint_evt, NULL); signal_set(&sighup_evt, SIGHUP, logfd_reopen_sighandler, &sighup_evt); signal_add(&sighup_evt, NULL); signal_set(&sigusr1_evt, SIGUSR1, enable_read_only_sighandler, &sigusr1_evt); signal_add(&sigusr1_evt, NULL); signal_set(&sigusr2_evt, SIGUSR2, passive_to_active_sighandler, &sigusr2_evt); signal_add(&sigusr2_evt, NULL); event_dispatch(); if (ENABLE_TIPC) event_del(&tipc_evt); if (ENABLE_TCP) event_del(&tcp_evt); if (ENABLE_UDP) event_del(&udp_evt); if (ENABLE_SCTP) event_del(&sctp_evt); signal_del(&sigterm_evt); signal_del(&sigint_evt); signal_del(&sigusr1_evt); signal_del(&sigusr2_evt); tipc_close(tipc_fd); tcp_close(tcp_fd); udp_close(udp_fd); sctp_close(sctp_fd); }
void storage_close_session(storage_session_t session) { tipc_close(session); }
int trusty_keymaster_call(uint32_t cmd, void* in, uint32_t in_size, uint8_t* out, uint32_t* out_size) { if (handle_ < 0) { ALOGE("not connected\n"); return -EINVAL; } size_t msg_size = in_size + sizeof(struct keymaster_message); struct keymaster_message* msg = reinterpret_cast<struct keymaster_message*>(malloc(msg_size)); if (!msg) { ALOGE("failed to allocate msg buffer\n"); return -EINVAL; } msg->cmd = cmd; memcpy(msg->payload, in, in_size); ssize_t rc = write(handle_, msg, msg_size); free(msg); if (rc < 0) { ALOGE("failed to send cmd (%d) to %s: %s\n", cmd, KEYMASTER_PORT, strerror(errno)); return -errno; } size_t out_max_size = *out_size; *out_size = 0; struct iovec iov[2]; struct keymaster_message header; iov[0] = {.iov_base = &header, .iov_len = sizeof(struct keymaster_message)}; while (true) { iov[1] = {.iov_base = out + *out_size, .iov_len = std::min<uint32_t>(KEYMASTER_MAX_BUFFER_LENGTH, out_max_size - *out_size)}; rc = readv(handle_, iov, 2); if (rc < 0) { ALOGE("failed to retrieve response for cmd (%d) to %s: %s\n", cmd, KEYMASTER_PORT, strerror(errno)); return -errno; } if ((size_t)rc < sizeof(struct keymaster_message)) { ALOGE("invalid response size (%d)\n", (int)rc); return -EINVAL; } if ((cmd | KEYMASTER_RESP_BIT) != (header.cmd & ~(KEYMASTER_STOP_BIT))) { ALOGE("invalid command (%d)", header.cmd); return -EINVAL; } *out_size += ((size_t)rc - sizeof(struct keymaster_message)); if (header.cmd & KEYMASTER_STOP_BIT) { break; } } return rc; } void trusty_keymaster_disconnect() { if (handle_ >= 0) { tipc_close(handle_); } handle_ = -1; } keymaster_error_t translate_error(int err) { switch (err) { case 0: return KM_ERROR_OK; case -EPERM: case -EACCES: return KM_ERROR_SECURE_HW_ACCESS_DENIED; case -ECANCELED: return KM_ERROR_OPERATION_CANCELLED; case -ENODEV: return KM_ERROR_UNIMPLEMENTED; case -ENOMEM: return KM_ERROR_MEMORY_ALLOCATION_FAILED; case -EBUSY: return KM_ERROR_SECURE_HW_BUSY; case -EIO: return KM_ERROR_SECURE_HW_COMMUNICATION_FAILED; case -EOVERFLOW: return KM_ERROR_INVALID_INPUT_LENGTH; default: return KM_ERROR_UNKNOWN_ERROR; } } keymaster_error_t trusty_keymaster_send(uint32_t command, const keymaster::Serializable& req, keymaster::KeymasterResponse* rsp) { uint32_t req_size = req.SerializedSize(); if (req_size > TRUSTY_KEYMASTER_SEND_BUF_SIZE) { ALOGE("Request too big: %u Max size: %u", req_size, TRUSTY_KEYMASTER_SEND_BUF_SIZE); return KM_ERROR_INVALID_INPUT_LENGTH; } uint8_t send_buf[TRUSTY_KEYMASTER_SEND_BUF_SIZE]; keymaster::Eraser send_buf_eraser(send_buf, TRUSTY_KEYMASTER_SEND_BUF_SIZE); req.Serialize(send_buf, send_buf + req_size); // Send it uint8_t recv_buf[TRUSTY_KEYMASTER_RECV_BUF_SIZE]; keymaster::Eraser recv_buf_eraser(recv_buf, TRUSTY_KEYMASTER_RECV_BUF_SIZE); uint32_t rsp_size = TRUSTY_KEYMASTER_RECV_BUF_SIZE; int rc = trusty_keymaster_call(command, send_buf, req_size, recv_buf, &rsp_size); if (rc < 0) { // Reset the connection on tipc error trusty_keymaster_disconnect(); trusty_keymaster_connect(); ALOGE("tipc error: %d\n", rc); // TODO(swillden): Distinguish permanent from transient errors and set error_ appropriately. return translate_error(rc); } else { ALOGV("Received %d byte response\n", rsp_size); } const uint8_t* p = recv_buf; if (!rsp->Deserialize(&p, p + rsp_size)) { ALOGE("Error deserializing response of size %d\n", (int)rsp_size); return KM_ERROR_UNKNOWN_ERROR; } else if (rsp->error != KM_ERROR_OK) { ALOGE("Response of size %d contained error code %d\n", (int)rsp_size, (int)rsp->error); return rsp->error; } return rsp->error; }
int tipc_bind(int sd, uint32_t type, uint32_t lower, uint32_t upper, tipc_domain_t scope) { struct sockaddr_tipc addr = { .family = AF_TIPC, .addrtype = TIPC_ADDR_NAMESEQ, .addr.nameseq.type = type, .addr.nameseq.lower = lower, .addr.nameseq.upper = upper }; if (tipc_own_node() == scope) addr.scope = TIPC_NODE_SCOPE; if (tipc_own_cluster() == scope) addr.scope = TIPC_CLUSTER_SCOPE; if (tipc_own_zone() == scope) addr.scope = TIPC_ZONE_SCOPE; /* TODO: introduce support for global scope in module */ if (!scope) addr.scope = TIPC_ZONE_SCOPE; if (!my_scope(scope)) return -1; return bind(sd, (struct sockaddr *)&addr, sizeof(addr)); } int tipc_unbind(int sd, uint32_t type, uint32_t lower, uint32_t upper) { struct sockaddr_tipc addr = { .family = AF_TIPC, .addrtype = TIPC_ADDR_NAMESEQ, .addr.nameseq.type = type, .addr.nameseq.lower = lower, .addr.nameseq.upper = upper, .scope = -1 }; return bind(sd, (struct sockaddr *)&addr, sizeof(addr)); } int tipc_connect(int sd, const struct tipc_addr *dst) { struct sockaddr_tipc addr; if (!dst) return -1; addr.family = AF_TIPC; addr.addrtype = TIPC_ADDR_NAME; addr.addr.name.name.type = dst->type; addr.addr.name.name.instance = dst->instance; addr.addr.name.domain = dst->domain; return connect(sd, (struct sockaddr*)&addr, sizeof(addr)); } int tipc_listen(int sd, int backlog) { return listen(sd, backlog); } int tipc_accept(int sd, struct tipc_addr *src) { struct sockaddr_tipc addr; socklen_t addrlen = sizeof(addr); int rc; rc = accept(sd, (struct sockaddr *) &addr, &addrlen); if (src) { src->type = 0; src->instance = addr.addr.id.ref; src->domain = addr.addr.id.node; } return rc; } int tipc_send(int sd, const char *msg, size_t msg_len) { return send(sd, msg, msg_len, 0); } int tipc_sendmsg(int sd, const struct msghdr *msg) { return sendmsg(sd, msg, 0); } int tipc_sendto(int sd, const char *msg, size_t msg_len, const struct tipc_addr *dst) { struct sockaddr_tipc addr; if(!dst) return -1; addr.family = AF_TIPC; if (dst->type) { addr.addrtype = TIPC_ADDR_NAME; addr.addr.name.name.type = dst->type; addr.addr.name.name.instance = dst->instance; addr.addr.name.domain = dst->domain; } else { addr.addrtype = TIPC_ADDR_ID; addr.addr.id.ref = dst->instance; addr.addr.id.node = dst->domain; } return sendto(sd, msg, msg_len, 0, (struct sockaddr*)&addr, sizeof(addr)); } int tipc_mcast(int sd, const char *msg, size_t msg_len, const struct tipc_addr *dst) { struct sockaddr_tipc addr = { .family = AF_TIPC, .addrtype = TIPC_ADDR_MCAST, .addr.name.domain = TIPC_CLUSTER_SCOPE }; if(!dst) return -1; addr.addr.nameseq.type = dst->type; addr.addr.nameseq.lower = dst->instance; addr.addr.nameseq.upper = dst->instance; if (dst->domain != tipc_own_cluster()) return -ENOTSUP; return sendto(sd, msg, msg_len, 0, (struct sockaddr*)&addr, sizeof(addr)); } int tipc_recv(int sd, char* buf, size_t buf_len, bool waitall) { int flags = waitall ? MSG_WAITALL : 0; return recv(sd, buf, buf_len, flags); } int tipc_recvfrom(int sd, char *buf, size_t len, struct tipc_addr *src, struct tipc_addr *dst, int *err) { int rc, _err = 0; struct sockaddr_tipc addr; struct iovec iov = {buf, len}; struct msghdr msg = {0, }; char anc_space[CMSG_SPACE(8) + CMSG_SPACE(1024) + CMSG_SPACE(16)]; struct cmsghdr *anc; msg.msg_name = &addr; msg.msg_namelen = sizeof(addr); msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_control = (struct cmsghdr *)anc_space; msg.msg_controllen = sizeof(anc_space); rc = recvmsg(sd ,&msg ,0); if (rc < 0) return rc; if (src) { src->type = 0; src->instance = addr.addr.id.ref; src->domain = addr.addr.id.node; } anc = CMSG_FIRSTHDR(&msg); if (anc && (anc->cmsg_type == TIPC_ERRINFO)) { _err = *(int*)(CMSG_DATA(anc)); rc = *(int*)(CMSG_DATA(anc) + 4); if (rc > len) rc = len; anc = CMSG_NXTHDR(&msg, anc); memcpy(buf, (char*)CMSG_DATA(anc), rc); anc = CMSG_NXTHDR(&msg, anc); } if (_err) tipc_sockid(sd, src); if (err) *err = _err; else if (_err) rc = 0; if (!dst) return rc; if (anc && (anc->cmsg_type == TIPC_DESTNAME)) { dst->type = *((uint32_t*)(CMSG_DATA(anc))); dst->instance = *((uint32_t*)(CMSG_DATA(anc) + 4)); dst->domain = 0; } else { tipc_sockid(sd, dst); } return rc; } int tipc_topsrv_conn(tipc_domain_t node) { int sd; struct tipc_addr srv = {TIPC_TOP_SRV, TIPC_TOP_SRV, node}; sd = tipc_socket(SOCK_SEQPACKET); if (sd <= 0) return sd; if (tipc_connect(sd, &srv) < 0) tipc_close(sd); return sd; }
static int readv_test(uint repeat, uint msgsz, bool var) { uint i; ssize_t rc; size_t msg_len; int echo_fd = -1; char tx_buf [msgsz]; char rx0_buf[msgsz]; char rx1_buf[msgsz]; struct iovec iovs[2]= {{rx0_buf, 0}, {rx1_buf, 0}}; if (!opt_silent) { printf("%s: repeat %u: msgsz %u: variable %s\n", __func__, repeat, msgsz, var ? "true" : "false"); } echo_fd = tipc_connect(dev_name, echo_name); if (echo_fd < 0) { fprintf(stderr, "Failed to connect to service\n"); return echo_fd; } for (i = 0; i < repeat; i++) { msg_len = msgsz; if (opt_variable && msgsz) { msg_len = rand() % msgsz; } iovs[0].iov_len = msg_len / 3; iovs[1].iov_len = msg_len - iovs[0].iov_len; memset(tx_buf, i + 1, sizeof(tx_buf)); memset(rx0_buf, i + 2, iovs[0].iov_len); memset(rx1_buf, i + 3, iovs[1].iov_len); rc = write(echo_fd, tx_buf, msg_len); if (rc < 0) { perror("readv_test: write"); break; } if ((size_t)rc != msg_len) { fprintf(stderr, "%s: %s: data size mismatch (%zd vs. %zd)\n", __func__, "write", (size_t)rc, msg_len); break; } rc = readv(echo_fd, iovs, 2); if (rc < 0) { perror("readv_test: readv"); break; } if ((size_t)rc != msg_len) { fprintf(stderr, "%s: %s: data size mismatch (%zd vs. %zd)\n", __func__, "write", (size_t)rc, msg_len); break; } if (memcmp(rx0_buf, tx_buf, iovs[0].iov_len)) { fprintf(stderr, "%s: data mismatch: buf 0\n", __func__); break; } if (memcmp(rx1_buf, tx_buf + iovs[0].iov_len, iovs[1].iov_len)) { fprintf(stderr, "%s: data mismatch, buf 1\n", __func__); break; } } tipc_close(echo_fd); if (!opt_silent) { printf("%s: done\n",__func__); } return 0; }
static int closer3_test(uint repeat) { uint i, j; ssize_t rc; int fd[4]; char buf[64]; if (!opt_silent) { printf("%s: repeat = %u\n", __func__, repeat); } for (i = 0; i < repeat; i++) { /* open 4 connections to closer3 service */ for (j = 0; j < 4; j++) { fd[j] = tipc_connect(dev_name, closer3_name); if (fd[j] < 0) { fprintf(stderr, "fd[%d]: failed to connect to '%s' service\n", j, "closer3"); } else { if (!opt_silent) { printf("%s: fd[%d]=%d: connected\n", __func__, j, fd[j]); } memset(buf, i + j, sizeof(buf)); rc = write(fd[j], buf, sizeof(buf)); if (rc != sizeof(buf)) { if (!opt_silent) { printf("%s: fd[%d]=%d: write returned = %zd\n", __func__, j, fd[j], rc); } perror("closer3_test: write"); } } } /* sleep a bit */ sleep(1); /* It is expected that they will be closed by remote */ for (j = 0; j < 4; j++) { if (fd[j] < 0) continue; rc = write(fd[j], buf, sizeof(buf)); if (rc != sizeof(buf)) { if (!opt_silent) { printf("%s: fd[%d]=%d: write returned = %zd\n", __func__, j, fd[j], rc); } perror("closer3_test: write"); } } /* then they have to be closed by remote */ for (j = 0; j < 4; j++) { if (fd[j] >= 0) { tipc_close(fd[j]); } } } if (!opt_silent) { printf("%s: done\n", __func__); } return 0; }
static int echo_test(uint repeat, uint msgsz, bool var) { uint i; ssize_t rc; size_t msg_len; int echo_fd =-1; char tx_buf[msgsz]; char rx_buf[msgsz]; if (!opt_silent) { printf("%s: repeat %u: msgsz %u: variable %s\n", __func__, repeat, msgsz, var ? "true" : "false"); } echo_fd = tipc_connect(dev_name, echo_name); if (echo_fd < 0) { fprintf(stderr, "Failed to connect to service\n"); return echo_fd; } for (i = 0; i < repeat; i++) { msg_len = msgsz; if (opt_variable && msgsz) { msg_len = rand() % msgsz; } memset(tx_buf, i + 1, msg_len); rc = write(echo_fd, tx_buf, msg_len); if ((size_t)rc != msg_len) { perror("echo_test: write"); break; } rc = read(echo_fd, rx_buf, msg_len); if (rc < 0) { perror("echo_test: read"); break; } if ((size_t)rc != msg_len) { fprintf(stderr, "data truncated (%zu vs. %zu)\n", rc, msg_len); continue; } if (memcmp(tx_buf, rx_buf, (size_t) rc)) { fprintf(stderr, "data mismatch\n"); continue; } } tipc_close(echo_fd); if (!opt_silent) { printf("%s: done\n",__func__); } return 0; }