Commit 883e4f76 authored by Marc-André Lureau's avatar Marc-André Lureau Committed by Paolo Bonzini
Browse files

Change net/socket.c to use socket_*() functions

Use socket_*() functions from include/qemu/sockets.h instead of
listen()/bind()/connect()/parse_host_port(). socket_*() fucntions are
QAPI based and this patch  performs this api conversion since
everything will be using QAPI based sockets in the future. Also add a
helper function socket_address_to_string() in util/qemu-sockets.c
which returns the string representation of socket address. The task was
listed on http://wiki.qemu.org/BiteSizedTasks

 page.

Signed-off-by: default avatarAshijeet Acharya <ashijeetacharya@gmail.com>
Signed-off-by: default avatarMarc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent d9911d14
Loading
Loading
Loading
Loading
+71 −56
Original line number Diff line number Diff line
@@ -489,90 +489,105 @@ static int net_socket_listen_init(NetClientState *peer,
{
    NetClientState *nc;
    NetSocketState *s;
    struct sockaddr_in saddr;
    int fd, ret;

    if (parse_host_port(&saddr, host_str) < 0)
        return -1;
    SocketAddress *saddr;
    int ret;
    Error *local_error = NULL;

    fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
    if (fd < 0) {
        perror("socket");
    saddr = socket_parse(host_str, &local_error);
    if (saddr == NULL) {
        error_report_err(local_error);
        return -1;
    }
    qemu_set_nonblock(fd);

    socket_set_fast_reuse(fd);

    ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
    if (ret < 0) {
        perror("bind");
        closesocket(fd);
        return -1;
    }
    ret = listen(fd, 0);
    ret = socket_listen(saddr, &local_error);
    if (ret < 0) {
        perror("listen");
        closesocket(fd);
        qapi_free_SocketAddress(saddr);
        error_report_err(local_error);
        return -1;
    }

    nc = qemu_new_net_client(&net_socket_info, peer, model, name);
    s = DO_UPCAST(NetSocketState, nc, nc);
    s->fd = -1;
    s->listen_fd = fd;
    s->listen_fd = ret;
    s->nc.link_down = true;

    qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s);
    qapi_free_SocketAddress(saddr);
    return 0;
}

static int net_socket_connect_init(NetClientState *peer,
                                   const char *model,
                                   const char *name,
                                   const char *host_str)
typedef struct {
    NetClientState *peer;
    SocketAddress *saddr;
    char *model;
    char *name;
} socket_connect_data;

static void socket_connect_data_free(socket_connect_data *c)
{
    NetSocketState *s;
    int fd, connected, ret;
    struct sockaddr_in saddr;
    qapi_free_SocketAddress(c->saddr);
    g_free(c->model);
    g_free(c->name);
    g_free(c);
}

    if (parse_host_port(&saddr, host_str) < 0)
        return -1;
static void net_socket_connected(int fd, Error *err, void *opaque)
{
    socket_connect_data *c = opaque;
    NetSocketState *s;
    char *addr_str = NULL;
    Error *local_error = NULL;

    fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
    if (fd < 0) {
        perror("socket");
        return -1;
    addr_str = socket_address_to_string(c->saddr, &local_error);
    if (addr_str == NULL) {
        error_report_err(local_error);
        closesocket(fd);
        goto end;
    }
    qemu_set_nonblock(fd);

    connected = 0;
    for(;;) {
        ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr));
        if (ret < 0) {
            if (errno == EINTR || errno == EWOULDBLOCK) {
                /* continue */
            } else if (errno == EINPROGRESS ||
                       errno == EALREADY ||
                       errno == EINVAL) {
                break;
            } else {
                perror("connect");
    s = net_socket_fd_init(c->peer, c->model, c->name, fd, true);
    if (!s) {
        closesocket(fd);
                return -1;
        goto end;
    }
        } else {
            connected = 1;
            break;

    snprintf(s->nc.info_str, sizeof(s->nc.info_str),
             "socket: connect to %s", addr_str);

end:
    g_free(addr_str);
    socket_connect_data_free(c);
}

static int net_socket_connect_init(NetClientState *peer,
                                   const char *model,
                                   const char *name,
                                   const char *host_str)
{
    socket_connect_data *c = g_new0(socket_connect_data, 1);
    int fd = -1;
    Error *local_error = NULL;

    c->peer = peer;
    c->model = g_strdup(model);
    c->name = g_strdup(name);
    c->saddr = socket_parse(host_str, &local_error);
    if (c->saddr == NULL) {
        goto err;
    }

    fd = socket_connect(c->saddr, &local_error, net_socket_connected, c);
    if (fd < 0) {
        goto err;
    }
    s = net_socket_fd_init(peer, model, name, fd, connected);
    if (!s)
        return -1;
    snprintf(s->nc.info_str, sizeof(s->nc.info_str),
             "socket: connect to %s:%d",
             inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));

    return 0;

err:
    error_report_err(local_error);
    socket_connect_data_free(c);
    return -1;
}

static int net_socket_mcast_init(NetClientState *peer,