コード例 #1
0
ファイル: socket.c プロジェクト: AlexWWW/qemu-linaro-clone
static int net_socket_udp_init(NetClientState *peer,
                                 const char *model,
                                 const char *name,
                                 const char *rhost,
                                 const char *lhost)
{
    NetSocketState *s;
    int fd, val, ret;
    struct sockaddr_in laddr, raddr;

    if (parse_host_port(&laddr, lhost) < 0) {
        return -1;
    }

    if (parse_host_port(&raddr, rhost) < 0) {
        return -1;
    }

    fd = qemu_socket(PF_INET, SOCK_DGRAM, 0);
    if (fd < 0) {
        perror("socket(PF_INET, SOCK_DGRAM)");
        return -1;
    }
    val = 1;
    ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
                   (const char *)&val, sizeof(val));
    if (ret < 0) {
        perror("setsockopt(SOL_SOCKET, SO_REUSEADDR)");
        closesocket(fd);
        return -1;
    }
    ret = bind(fd, (struct sockaddr *)&laddr, sizeof(laddr));
    if (ret < 0) {
        perror("bind");
        closesocket(fd);
        return -1;
    }

    s = net_socket_fd_init(peer, model, name, fd, 0);
    if (!s) {
        return -1;
    }

    s->dgram_dst = raddr;

    snprintf(s->nc.info_str, sizeof(s->nc.info_str),
             "socket: udp=%s:%d",
             inet_ntoa(raddr.sin_addr), ntohs(raddr.sin_port));
    return 0;
}
コード例 #2
0
ファイル: socket.c プロジェクト: AlexWWW/qemu-linaro-clone
static int net_socket_connect_init(NetClientState *peer,
                                   const char *model,
                                   const char *name,
                                   const char *host_str)
{
    NetSocketState *s;
    int fd, connected, ret, err;
    struct sockaddr_in saddr;

    if (parse_host_port(&saddr, host_str) < 0)
        return -1;

    fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
    if (fd < 0) {
        perror("socket");
        return -1;
    }
    socket_set_nonblock(fd);

    connected = 0;
    for(;;) {
        ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr));
        if (ret < 0) {
            err = socket_error();
            if (err == EINTR || err == EWOULDBLOCK) {
            } else if (err == EINPROGRESS) {
                break;
#ifdef _WIN32
            } else if (err == WSAEALREADY || err == WSAEINVAL) {
                break;
#endif
            } else {
                perror("connect");
                closesocket(fd);
                return -1;
            }
        } else {
            connected = 1;
            break;
        }
    }
    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;
}
コード例 #3
0
ファイル: socket.c プロジェクト: AlexWWW/qemu-linaro-clone
static int net_socket_mcast_init(NetClientState *peer,
                                 const char *model,
                                 const char *name,
                                 const char *host_str,
                                 const char *localaddr_str)
{
    NetSocketState *s;
    int fd;
    struct sockaddr_in saddr;
    struct in_addr localaddr, *param_localaddr;

    if (parse_host_port(&saddr, host_str) < 0)
        return -1;

    if (localaddr_str != NULL) {
        if (inet_aton(localaddr_str, &localaddr) == 0)
            return -1;
        param_localaddr = &localaddr;
    } else {
        param_localaddr = NULL;
    }

    fd = net_socket_mcast_create(&saddr, param_localaddr);
    if (fd < 0)
        return -1;

    s = net_socket_fd_init(peer, model, name, fd, 0);
    if (!s)
        return -1;

    s->dgram_dst = saddr;

    snprintf(s->nc.info_str, sizeof(s->nc.info_str),
             "socket: mcast=%s:%d",
             inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
    return 0;

}
コード例 #4
0
ファイル: socket.c プロジェクト: MatzeB/qemu-fixes
static void net_socket_accept(void *opaque)
{
    NetSocketListenState *s = opaque;
    NetSocketState *s1;
    struct sockaddr_in saddr;
    socklen_t len;
    int fd;

    for(;;) {
        len = sizeof(saddr);
        fd = qemu_accept(s->fd, (struct sockaddr *)&saddr, &len);
        if (fd < 0 && errno != EINTR) {
            return;
        } else if (fd >= 0) {
            break;
        }
    }
    s1 = net_socket_fd_init(s->vlan, s->model, s->name, fd, 1);
    if (s1) {
        snprintf(s1->nc.info_str, sizeof(s1->nc.info_str),
                 "socket: connection from %s:%d",
                 inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
    }
}
コード例 #5
0
ファイル: socket.c プロジェクト: AlexWWW/qemu-linaro-clone
int net_init_socket(const NetClientOptions *opts, const char *name,
                    NetClientState *peer)
{
    const NetdevSocketOptions *sock;

    assert(opts->kind == NET_CLIENT_OPTIONS_KIND_SOCKET);
    sock = opts->socket;

    if (sock->has_fd + sock->has_listen + sock->has_connect + sock->has_mcast +
        sock->has_udp != 1) {
        error_report("exactly one of fd=, listen=, connect=, mcast= or udp="
                     " is required");
        return -1;
    }

    if (sock->has_localaddr && !sock->has_mcast && !sock->has_udp) {
        error_report("localaddr= is only valid with mcast= or udp=");
        return -1;
    }

    if (sock->has_fd) {
        int fd;

        fd = net_handle_fd_param(cur_mon, sock->fd);
        if (fd == -1 || !net_socket_fd_init(peer, "socket", name, fd, 1)) {
            return -1;
        }
        return 0;
    }

    if (sock->has_listen) {
        if (net_socket_listen_init(peer, "socket", name, sock->listen) == -1) {
            return -1;
        }
        return 0;
    }

    if (sock->has_connect) {
        if (net_socket_connect_init(peer, "socket", name, sock->connect) ==
            -1) {
            return -1;
        }
        return 0;
    }

    if (sock->has_mcast) {
        /* if sock->localaddr is missing, it has been initialized to "all bits
         * zero" */
        if (net_socket_mcast_init(peer, "socket", name, sock->mcast,
            sock->localaddr) == -1) {
            return -1;
        }
        return 0;
    }

    assert(sock->has_udp);
    if (!sock->has_localaddr) {
        error_report("localaddr= is mandatory with udp=");
        return -1;
    }
    if (net_socket_udp_init(peer, "udp", name, sock->udp, sock->localaddr) ==
        -1) {
        return -1;
    }
    return 0;
}
コード例 #6
0
ファイル: socket.c プロジェクト: MatzeB/qemu-fixes
int net_init_socket(QemuOpts *opts,
                    Monitor *mon,
                    const char *name,
                    VLANState *vlan)
{
    if (qemu_opt_get(opts, "fd")) {
        int fd;

        if (qemu_opt_get(opts, "listen") ||
            qemu_opt_get(opts, "connect") ||
            qemu_opt_get(opts, "mcast") ||
            qemu_opt_get(opts, "localaddr")) {
            error_report("listen=, connect=, mcast= and localaddr= is invalid with fd=");
            return -1;
        }

        fd = net_handle_fd_param(mon, qemu_opt_get(opts, "fd"));
        if (fd == -1) {
            return -1;
        }

        if (!net_socket_fd_init(vlan, "socket", name, fd, 1)) {
            return -1;
        }
    } else if (qemu_opt_get(opts, "listen")) {
        const char *listen;

        if (qemu_opt_get(opts, "fd") ||
            qemu_opt_get(opts, "connect") ||
            qemu_opt_get(opts, "mcast") ||
            qemu_opt_get(opts, "localaddr")) {
            error_report("fd=, connect=, mcast= and localaddr= is invalid with listen=");
            return -1;
        }

        listen = qemu_opt_get(opts, "listen");

        if (net_socket_listen_init(vlan, "socket", name, listen) == -1) {
            return -1;
        }
    } else if (qemu_opt_get(opts, "connect")) {
        const char *connect;

        if (qemu_opt_get(opts, "fd") ||
            qemu_opt_get(opts, "listen") ||
            qemu_opt_get(opts, "mcast") ||
            qemu_opt_get(opts, "localaddr")) {
            error_report("fd=, listen=, mcast= and localaddr= is invalid with connect=");
            return -1;
        }

        connect = qemu_opt_get(opts, "connect");

        if (net_socket_connect_init(vlan, "socket", name, connect) == -1) {
            return -1;
        }
    } else if (qemu_opt_get(opts, "mcast")) {
        const char *mcast, *localaddr;

        if (qemu_opt_get(opts, "fd") ||
            qemu_opt_get(opts, "connect") ||
            qemu_opt_get(opts, "listen")) {
            error_report("fd=, connect= and listen= is invalid with mcast=");
            return -1;
        }

        mcast = qemu_opt_get(opts, "mcast");
        localaddr = qemu_opt_get(opts, "localaddr");

        if (net_socket_mcast_init(vlan, "socket", name, mcast, localaddr) == -1) {
            return -1;
        }
    } else if (qemu_opt_get(opts, "udp")) {
        const char *udp, *localaddr;

        if (qemu_opt_get(opts, "fd") ||
            qemu_opt_get(opts, "connect") ||
            qemu_opt_get(opts, "listen") ||
            qemu_opt_get(opts, "mcast")) {
            error_report("fd=, connect=, listen=\
                         and mcast= is invalid with udp=");
            return -1;
        }

        udp = qemu_opt_get(opts, "udp");
        localaddr = qemu_opt_get(opts, "localaddr");
        if (localaddr == NULL) {
                error_report("localaddr= is mandatory with udp=");
                return -1;
        }

        if (net_socket_udp_init(vlan, "udp", name, udp, localaddr) == -1) {
            return -1;
        }
    } else {