net: dgram: move mcast specific code from net_socket_fd_init_dgram()
It is less complex to manage special cases directly in net_dgram_mcast_init() and net_dgram_udp_init(). Signed-off-by: Laurent Vivier <lvivier@redhat.com> Reviewed-by: Stefano Brivio <sbrivio@redhat.com> Acked-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Jason Wang <jasowang@redhat.com>
This commit is contained in:
parent
7c1f0c33cc
commit
8ecc7f40bc
139
net/dgram.c
139
net/dgram.c
@ -259,52 +259,11 @@ static NetClientInfo net_dgram_socket_info = {
|
|||||||
static NetDgramState *net_dgram_fd_init(NetClientState *peer,
|
static NetDgramState *net_dgram_fd_init(NetClientState *peer,
|
||||||
const char *model,
|
const char *model,
|
||||||
const char *name,
|
const char *name,
|
||||||
int fd, int is_fd,
|
int fd,
|
||||||
SocketAddress *mcast,
|
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
struct sockaddr_in *saddr = NULL;
|
|
||||||
int newfd;
|
|
||||||
NetClientState *nc;
|
NetClientState *nc;
|
||||||
NetDgramState *s;
|
NetDgramState *s;
|
||||||
SocketAddress *sa;
|
|
||||||
SocketAddressType sa_type;
|
|
||||||
|
|
||||||
sa = socket_local_address(fd, errp);
|
|
||||||
if (!sa) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
sa_type = sa->type;
|
|
||||||
qapi_free_SocketAddress(sa);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* fd passed: multicast: "learn" dest_addr address from bound address and
|
|
||||||
* save it. Because this may be "shared" socket from a "master" process,
|
|
||||||
* datagrams would be recv() by ONLY ONE process: we must "clone" this
|
|
||||||
* dgram socket --jjo
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (is_fd && mcast != NULL) {
|
|
||||||
saddr = g_new(struct sockaddr_in, 1);
|
|
||||||
|
|
||||||
if (convert_host_port(saddr, mcast->u.inet.host, mcast->u.inet.port,
|
|
||||||
errp) < 0) {
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
/* must be bound */
|
|
||||||
if (saddr->sin_addr.s_addr == 0) {
|
|
||||||
error_setg(errp, "can't setup multicast destination address");
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
/* clone dgram socket */
|
|
||||||
newfd = net_dgram_mcast_create(saddr, NULL, errp);
|
|
||||||
if (newfd < 0) {
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
/* clone newfd to fd, close newfd */
|
|
||||||
dup2(newfd, fd);
|
|
||||||
close(newfd);
|
|
||||||
}
|
|
||||||
|
|
||||||
nc = qemu_new_net_client(&net_dgram_socket_info, peer, model, name);
|
nc = qemu_new_net_client(&net_dgram_socket_info, peer, model, name);
|
||||||
|
|
||||||
@ -314,23 +273,7 @@ static NetDgramState *net_dgram_fd_init(NetClientState *peer,
|
|||||||
net_socket_rs_init(&s->rs, net_dgram_rs_finalize, false);
|
net_socket_rs_init(&s->rs, net_dgram_rs_finalize, false);
|
||||||
net_dgram_read_poll(s, true);
|
net_dgram_read_poll(s, true);
|
||||||
|
|
||||||
/* mcast: save bound address as dst */
|
|
||||||
if (saddr) {
|
|
||||||
g_assert(s->dest_addr == NULL);
|
|
||||||
s->dest_addr = (struct sockaddr *)saddr;
|
|
||||||
s->dest_len = sizeof(*saddr);
|
|
||||||
qemu_set_info_str(nc, "fd=%d (cloned mcast=%s:%d)", fd,
|
|
||||||
inet_ntoa(saddr->sin_addr), ntohs(saddr->sin_port));
|
|
||||||
} else {
|
|
||||||
qemu_set_info_str(nc, "fd=%d %s", fd, SocketAddressType_str(sa_type));
|
|
||||||
}
|
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
|
|
||||||
err:
|
|
||||||
g_free(saddr);
|
|
||||||
closesocket(fd);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int net_dgram_mcast_init(NetClientState *peer,
|
static int net_dgram_mcast_init(NetClientState *peer,
|
||||||
@ -381,7 +324,9 @@ static int net_dgram_mcast_init(NetClientState *peer,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SOCKET_ADDRESS_TYPE_FD:
|
case SOCKET_ADDRESS_TYPE_FD: {
|
||||||
|
int newfd;
|
||||||
|
|
||||||
fd = monitor_fd_param(monitor_cur(), local->u.fd.str, errp);
|
fd = monitor_fd_param(monitor_cur(), local->u.fd.str, errp);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
g_free(saddr);
|
g_free(saddr);
|
||||||
@ -394,7 +339,42 @@ static int net_dgram_mcast_init(NetClientState *peer,
|
|||||||
name, fd);
|
name, fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fd passed: multicast: "learn" dest_addr address from bound
|
||||||
|
* address and save it. Because this may be "shared" socket from a
|
||||||
|
* "master" process, datagrams would be recv() by ONLY ONE process:
|
||||||
|
* we must "clone" this dgram socket --jjo
|
||||||
|
*/
|
||||||
|
|
||||||
|
saddr = g_new(struct sockaddr_in, 1);
|
||||||
|
|
||||||
|
if (convert_host_port(saddr, local->u.inet.host, local->u.inet.port,
|
||||||
|
errp) < 0) {
|
||||||
|
g_free(saddr);
|
||||||
|
closesocket(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* must be bound */
|
||||||
|
if (saddr->sin_addr.s_addr == 0) {
|
||||||
|
error_setg(errp, "can't setup multicast destination address");
|
||||||
|
g_free(saddr);
|
||||||
|
closesocket(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* clone dgram socket */
|
||||||
|
newfd = net_dgram_mcast_create(saddr, NULL, errp);
|
||||||
|
if (newfd < 0) {
|
||||||
|
g_free(saddr);
|
||||||
|
closesocket(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* clone newfd to fd, close newfd */
|
||||||
|
dup2(newfd, fd);
|
||||||
|
close(newfd);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
g_free(saddr);
|
g_free(saddr);
|
||||||
error_setg(errp, "only support inet or fd type for local");
|
error_setg(errp, "only support inet or fd type for local");
|
||||||
@ -402,9 +382,7 @@ static int net_dgram_mcast_init(NetClientState *peer,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s = net_dgram_fd_init(peer, model, name, fd,
|
s = net_dgram_fd_init(peer, model, name, fd, errp);
|
||||||
local->type == SOCKET_ADDRESS_TYPE_FD,
|
|
||||||
remote, errp);
|
|
||||||
if (!s) {
|
if (!s) {
|
||||||
g_free(saddr);
|
g_free(saddr);
|
||||||
return -1;
|
return -1;
|
||||||
@ -414,8 +392,26 @@ static int net_dgram_mcast_init(NetClientState *peer,
|
|||||||
s->dest_addr = (struct sockaddr *)saddr;
|
s->dest_addr = (struct sockaddr *)saddr;
|
||||||
s->dest_len = sizeof(*saddr);
|
s->dest_len = sizeof(*saddr);
|
||||||
|
|
||||||
qemu_set_info_str(&s->nc, "mcast=%s:%d", inet_ntoa(saddr->sin_addr),
|
if (!local) {
|
||||||
|
qemu_set_info_str(&s->nc, "mcast=%s:%d",
|
||||||
|
inet_ntoa(saddr->sin_addr),
|
||||||
ntohs(saddr->sin_port));
|
ntohs(saddr->sin_port));
|
||||||
|
} else {
|
||||||
|
switch (local->type) {
|
||||||
|
case SOCKET_ADDRESS_TYPE_INET:
|
||||||
|
qemu_set_info_str(&s->nc, "mcast=%s:%d",
|
||||||
|
inet_ntoa(saddr->sin_addr),
|
||||||
|
ntohs(saddr->sin_port));
|
||||||
|
break;
|
||||||
|
case SOCKET_ADDRESS_TYPE_FD:
|
||||||
|
qemu_set_info_str(&s->nc, "fd=%d (cloned mcast=%s:%d)",
|
||||||
|
fd, inet_ntoa(saddr->sin_addr),
|
||||||
|
ntohs(saddr->sin_port));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_assert_not_reached();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -531,7 +527,7 @@ int net_init_dgram(const Netdev *netdev, const char *name,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
s = net_dgram_fd_init(peer, "dgram", name, fd, 0, NULL, errp);
|
s = net_dgram_fd_init(peer, "dgram", name, fd, errp);
|
||||||
if (!s) {
|
if (!s) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -550,9 +546,22 @@ int net_init_dgram(const Netdev *netdev, const char *name,
|
|||||||
inet_ntoa(raddr_in.sin_addr),
|
inet_ntoa(raddr_in.sin_addr),
|
||||||
ntohs(raddr_in.sin_port));
|
ntohs(raddr_in.sin_port));
|
||||||
break;
|
break;
|
||||||
case SOCKET_ADDRESS_TYPE_FD:
|
case SOCKET_ADDRESS_TYPE_FD: {
|
||||||
|
SocketAddress *sa;
|
||||||
|
SocketAddressType sa_type;
|
||||||
|
|
||||||
|
sa = socket_local_address(fd, errp);
|
||||||
|
if (sa) {
|
||||||
|
sa_type = sa->type;
|
||||||
|
qapi_free_SocketAddress(sa);
|
||||||
|
|
||||||
|
qemu_set_info_str(&s->nc, "fd=%d %s", fd,
|
||||||
|
SocketAddressType_str(sa_type));
|
||||||
|
} else {
|
||||||
qemu_set_info_str(&s->nc, "fd=%d", fd);
|
qemu_set_info_str(&s->nc, "fd=%d", fd);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user