Exemple #1
0
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;
}
Exemple #5
0
/* 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;
}