gint sock_connect_async_cancel(gint id) { SockConnectData *conn_data = NULL; GList *cur; for (cur = sock_connect_data_list; cur != NULL; cur = cur->next) { if (((SockConnectData *)cur->data)->id == id) { conn_data = (SockConnectData *)cur->data; break; } } if (conn_data) { sock_connect_data_list = g_list_remove(sock_connect_data_list, conn_data); if (conn_data->lookup_data) sock_get_address_info_async_cancel (conn_data->lookup_data); if (conn_data->io_tag > 0) g_source_remove(conn_data->io_tag); if (conn_data->channel) { GError *err = NULL; g_io_channel_shutdown(conn_data->channel, TRUE, &err); if (err) g_error_free(err); g_io_channel_unref(conn_data->channel); } sock_address_list_free(conn_data->addr_list); g_free(conn_data->canonical_name); g_free(conn_data->hostname); g_free(conn_data); } else { g_warning("sock_connect_async_cancel: id %d not found.\n", id); return -1; } return 0; }
int inet_listen_opts(QemuOpts *opts, int port_offset) { SockAddress** list; SockAddress* e; unsigned flags = SOCKET_LIST_PASSIVE; const char *addr; char port[33]; char uaddr[256+1]; char uport[33]; int slisten,to,try_next,nn; #ifdef CONFIG_ANDROID const char* socket_fd = qemu_opt_get(opts, "socket"); if (socket_fd) { return atoi(socket_fd); } #endif if ((qemu_opt_get(opts, "host") == NULL) || (qemu_opt_get(opts, "port") == NULL)) { fprintf(stderr, "%s: host and/or port not specified\n", __FUNCTION__); return -1; } pstrcpy(port, sizeof(port), qemu_opt_get(opts, "port")); addr = qemu_opt_get(opts, "host"); to = qemu_opt_get_number(opts, "to", 0); if (qemu_opt_get_bool(opts, "ipv4", 0)) flags |= SOCKET_LIST_FORCE_INET; if (qemu_opt_get_bool(opts, "ipv6", 0)) flags |= SOCKET_LIST_FORCE_IN6; /* lookup */ if (port_offset) snprintf(port, sizeof(port), "%d", atoi(port) + port_offset); list = sock_address_list_create( strlen(addr) ? addr : NULL, port, flags ); if (list == NULL) { fprintf(stderr,"%s: getaddrinfo(%s,%s): %s\n", __FUNCTION__, addr, port, errno_str); return -1; } /* create socket + bind */ for (nn = 0; list[nn] != NULL; nn++) { SocketFamily family; e = list[nn]; family = sock_address_get_family(e); sock_address_get_numeric_info(e, uaddr, sizeof uaddr, uport, sizeof uport); slisten = socket_create(family, SOCKET_STREAM); if (slisten < 0) { fprintf(stderr,"%s: socket(%s): %s\n", __FUNCTION__, sock_address_strfamily(e), errno_str); continue; } socket_set_xreuseaddr(slisten); #ifdef IPV6_V6ONLY /* listen on both ipv4 and ipv6 */ if (family == SOCKET_IN6) { socket_set_ipv6only(slisten); } #endif for (;;) { if (socket_bind(slisten, e) == 0) { if (sockets_debug) fprintf(stderr,"%s: bind(%s,%s,%d): OK\n", __FUNCTION__, sock_address_strfamily(e), uaddr, sock_address_get_port(e)); goto listen; } socket_close(slisten); try_next = to && (sock_address_get_port(e) <= to + port_offset); if (!try_next || sockets_debug) fprintf(stderr,"%s: bind(%s,%s,%d): %s\n", __FUNCTION__, sock_address_strfamily(e), uaddr, sock_address_get_port(e), strerror(errno)); if (try_next) { sock_address_set_port(e, sock_address_get_port(e) + 1); continue; } break; } } sock_address_list_free(list); fprintf(stderr, "%s: FAILED\n", __FUNCTION__); return -1; listen: if (socket_listen(slisten,1) != 0) { perror("listen"); socket_close(slisten); return -1; } snprintf(uport, sizeof(uport), "%d", sock_address_get_port(e) - port_offset); qemu_opt_set(opts, "host", uaddr); qemu_opt_set(opts, "port", uport); qemu_opt_set(opts, "ipv6", (e->family == SOCKET_IN6) ? "on" : "off"); qemu_opt_set(opts, "ipv4", (e->family != SOCKET_IN6) ? "on" : "off"); sock_address_list_free(list); return slisten; }
int inet_dgram_opts(QemuOpts *opts) { SockAddress** peer_list = NULL; SockAddress** local_list = NULL; SockAddress* e; unsigned flags = 0; const char *addr; const char *port; char uaddr[INET6_ADDRSTRLEN+1]; char uport[33]; int sock = -1; int nn; /* lookup peer addr */ addr = qemu_opt_get(opts, "host"); port = qemu_opt_get(opts, "port"); if (addr == NULL || strlen(addr) == 0) { addr = "localhost"; } if (port == NULL || strlen(port) == 0) { fprintf(stderr, "inet_dgram: port not specified\n"); return -1; } flags = SOCKET_LIST_DGRAM; if (qemu_opt_get_bool(opts, "ipv4", 0)) { flags &= SOCKET_LIST_FORCE_IN6; flags |= SOCKET_LIST_FORCE_INET; } if (qemu_opt_get_bool(opts, "ipv6", 0)) { flags &= SOCKET_LIST_FORCE_INET; flags |= SOCKET_LIST_FORCE_IN6; } peer_list = sock_address_list_create(addr, port, flags); if (peer_list == NULL) { fprintf(stderr,"getaddrinfo(%s,%s): %s\n", addr, port, errno_str); return -1; } /* lookup local addr */ addr = qemu_opt_get(opts, "localaddr"); port = qemu_opt_get(opts, "localport"); if (addr == NULL || strlen(addr) == 0) { addr = NULL; } if (!port || strlen(port) == 0) port = "0"; flags = SOCKET_LIST_DGRAM | SOCKET_LIST_PASSIVE; local_list = sock_address_list_create(addr, port, flags); if (local_list == NULL) { fprintf(stderr,"getaddrinfo(%s,%s): %s\n", addr, port, errno_str); goto EXIT; } if (sock_address_get_numeric_info(local_list[0], uaddr, INET6_ADDRSTRLEN, uport, 32)) { fprintf(stderr, "%s: getnameinfo: oops\n", __FUNCTION__); goto EXIT; } for (nn = 0; peer_list[nn] != NULL; nn++) { SockAddress *local = local_list[0]; e = peer_list[nn]; sock = socket_create(sock_address_get_family(e), SOCKET_DGRAM); if (sock < 0) { fprintf(stderr,"%s: socket(%s): %s\n", __FUNCTION__, sock_address_strfamily(e), errno_str); continue; } socket_set_xreuseaddr(sock); /* bind socket */ if (socket_bind(sock, local) < 0) { fprintf(stderr,"%s: bind(%s,%s,%s): OK\n", __FUNCTION__, sock_address_strfamily(local), addr, port); socket_close(sock); continue; } /* connect to peer */ if (socket_connect(sock,e) < 0) { if (sockets_debug) fprintf(stderr, "%s: connect(%s,%s,%s,%s): %s\n", __FUNCTION__, sock_address_strfamily(e), sock_address_to_string(e), addr, port, strerror(errno)); socket_close(sock); continue; } if (sockets_debug) fprintf(stderr, "%s: connect(%s,%s,%s,%s): OK\n", __FUNCTION__, sock_address_strfamily(e), sock_address_to_string(e), addr, port); goto EXIT; } sock = -1; EXIT: if (local_list) sock_address_list_free(local_list); if (peer_list) sock_address_list_free(peer_list); return sock; }
int inet_connect_opts(QemuOpts *opts) { SockAddress** list; SockAddress* e; unsigned flags = 0; const char *addr; const char *port; int sock, nn; #ifdef CONFIG_ANDROID const char* socket_fd = qemu_opt_get(opts, "socket"); if (socket_fd) { return atoi(socket_fd); } #endif addr = qemu_opt_get(opts, "host"); port = qemu_opt_get(opts, "port"); if (addr == NULL || port == NULL) { fprintf(stderr, "inet_connect: host and/or port not specified\n"); return -1; } if (qemu_opt_get_bool(opts, "ipv4", 0)) { flags &= SOCKET_LIST_FORCE_IN6; flags |= SOCKET_LIST_FORCE_INET; } if (qemu_opt_get_bool(opts, "ipv6", 0)) { flags &= SOCKET_LIST_FORCE_INET; flags |= SOCKET_LIST_FORCE_IN6; } /* lookup */ list = sock_address_list_create(addr, port, flags); if (list == NULL) { fprintf(stderr,"getaddrinfo(%s,%s): %s\n", addr, port, errno_str); return -1; } for (nn = 0; list[nn] != NULL; nn++) { e = list[nn]; sock = socket_create(sock_address_get_family(e), SOCKET_STREAM); if (sock < 0) { fprintf(stderr,"%s: socket(%s): %s\n", __FUNCTION__, sock_address_strfamily(e), errno_str); continue; } socket_set_xreuseaddr(sock); /* connect to peer */ if (socket_connect(sock,e) < 0) { if (sockets_debug) fprintf(stderr, "%s: connect(%s,%s,%s,%s): %s\n", __FUNCTION__, sock_address_strfamily(e), sock_address_to_string(e), addr, port, strerror(errno)); socket_close(sock); continue; } if (sockets_debug) fprintf(stderr, "%s: connect(%s,%s,%s,%s): OK\n", __FUNCTION__, sock_address_strfamily(e), sock_address_to_string(e), addr, port); goto EXIT; } sock = -1; EXIT: sock_address_list_free(list); return sock; }
/* Attaches starting UI to a running core process. * This routine is called from main() when -attach-core parameter is set, * indicating that this UI instance should attach to a running core, rather than * start a new core process. * Param: * opts Android options containing non-NULL attach_core. * Return: * 0 on success, or -1 on failure. */ static int attach_to_core(AndroidOptions* opts) { int iter; SockAddress console_socket; SockAddress** sockaddr_list; QEmulator* emulator; // Parse attach_core param extracting the host name, and the port name. char* console_address = strdup(opts->attach_core); char* host_name = console_address; char* port_num = strchr(console_address, ':'); if (port_num == NULL) { // The host name is ommited, indicating the localhost host_name = "localhost"; port_num = console_address; } else if (port_num == console_address) { // Invalid. derror("Invalid value %s for -attach-core parameter\n", opts->attach_core); return -1; } else { *port_num = '\0'; port_num++; if (*port_num == '\0') { // Invalid. derror("Invalid value %s for -attach-core parameter\n", opts->attach_core); return -1; } } /* Create socket address list for the given address, and pull appropriate * address to use for connection. Note that we're fine copying that address * out of the list, since INET and IN6 will entirely fit into SockAddress * structure. */ sockaddr_list = sock_address_list_create(host_name, port_num, SOCKET_LIST_FORCE_INET); free(console_address); if (sockaddr_list == NULL) { derror("Unable to resolve address %s: %s\n", opts->attach_core, errno_str); return -1; } for (iter = 0; sockaddr_list[iter] != NULL; iter++) { if (sock_address_get_family(sockaddr_list[iter]) == SOCKET_INET || sock_address_get_family(sockaddr_list[iter]) == SOCKET_IN6) { memcpy(&console_socket, sockaddr_list[iter], sizeof(SockAddress)); break; } } if (sockaddr_list[iter] == NULL) { derror("Unable to resolve address %s. Note that 'port' parameter passed to -attach-core\n" "must be resolvable into an IP address.\n", opts->attach_core); sock_address_list_free(sockaddr_list); return -1; } sock_address_list_free(sockaddr_list); if (attachUiImpl_create(&console_socket)) { return -1; } // Save core's port, and set the title. android_base_port = sock_address_get_port(&console_socket); emulator = qemulator_get(); qemulator_set_title(emulator); return 0; }