socket.c (23038B)
1/* 2 * QEMU System Emulator 3 * 4 * Copyright (c) 2003-2008 Fabrice Bellard 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 * THE SOFTWARE. 23 */ 24#include "qemu/osdep.h" 25 26#include "net/net.h" 27#include "clients.h" 28#include "monitor/monitor.h" 29#include "qapi/error.h" 30#include "qemu-common.h" 31#include "qemu/error-report.h" 32#include "qemu/option.h" 33#include "qemu/sockets.h" 34#include "qemu/iov.h" 35#include "qemu/main-loop.h" 36 37typedef struct NetSocketState { 38 NetClientState nc; 39 int listen_fd; 40 int fd; 41 SocketReadState rs; 42 unsigned int send_index; /* number of bytes sent (only SOCK_STREAM) */ 43 struct sockaddr_in dgram_dst; /* contains inet host and port destination iff connectionless (SOCK_DGRAM) */ 44 IOHandler *send_fn; /* differs between SOCK_STREAM/SOCK_DGRAM */ 45 bool read_poll; /* waiting to receive data? */ 46 bool write_poll; /* waiting to transmit data? */ 47} NetSocketState; 48 49static void net_socket_accept(void *opaque); 50static void net_socket_writable(void *opaque); 51 52static void net_socket_update_fd_handler(NetSocketState *s) 53{ 54 qemu_set_fd_handler(s->fd, 55 s->read_poll ? s->send_fn : NULL, 56 s->write_poll ? net_socket_writable : NULL, 57 s); 58} 59 60static void net_socket_read_poll(NetSocketState *s, bool enable) 61{ 62 s->read_poll = enable; 63 net_socket_update_fd_handler(s); 64} 65 66static void net_socket_write_poll(NetSocketState *s, bool enable) 67{ 68 s->write_poll = enable; 69 net_socket_update_fd_handler(s); 70} 71 72static void net_socket_writable(void *opaque) 73{ 74 NetSocketState *s = opaque; 75 76 net_socket_write_poll(s, false); 77 78 qemu_flush_queued_packets(&s->nc); 79} 80 81static ssize_t net_socket_receive(NetClientState *nc, const uint8_t *buf, size_t size) 82{ 83 NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc); 84 uint32_t len = htonl(size); 85 struct iovec iov[] = { 86 { 87 .iov_base = &len, 88 .iov_len = sizeof(len), 89 }, { 90 .iov_base = (void *)buf, 91 .iov_len = size, 92 }, 93 }; 94 size_t remaining; 95 ssize_t ret; 96 97 remaining = iov_size(iov, 2) - s->send_index; 98 ret = iov_send(s->fd, iov, 2, s->send_index, remaining); 99 100 if (ret == -1 && errno == EAGAIN) { 101 ret = 0; /* handled further down */ 102 } 103 if (ret == -1) { 104 s->send_index = 0; 105 return -errno; 106 } 107 if (ret < (ssize_t)remaining) { 108 s->send_index += ret; 109 net_socket_write_poll(s, true); 110 return 0; 111 } 112 s->send_index = 0; 113 return size; 114} 115 116static ssize_t net_socket_receive_dgram(NetClientState *nc, const uint8_t *buf, size_t size) 117{ 118 NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc); 119 ssize_t ret; 120 121 do { 122 if (s->dgram_dst.sin_family != AF_UNIX) { 123 ret = qemu_sendto(s->fd, buf, size, 0, 124 (struct sockaddr *)&s->dgram_dst, 125 sizeof(s->dgram_dst)); 126 } else { 127 ret = send(s->fd, buf, size, 0); 128 } 129 } while (ret == -1 && errno == EINTR); 130 131 if (ret == -1 && errno == EAGAIN) { 132 net_socket_write_poll(s, true); 133 return 0; 134 } 135 return ret; 136} 137 138static void net_socket_send_completed(NetClientState *nc, ssize_t len) 139{ 140 NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc); 141 142 if (!s->read_poll) { 143 net_socket_read_poll(s, true); 144 } 145} 146 147static void net_socket_rs_finalize(SocketReadState *rs) 148{ 149 NetSocketState *s = container_of(rs, NetSocketState, rs); 150 151 if (qemu_send_packet_async(&s->nc, rs->buf, 152 rs->packet_len, 153 net_socket_send_completed) == 0) { 154 net_socket_read_poll(s, false); 155 } 156} 157 158static void net_socket_send(void *opaque) 159{ 160 NetSocketState *s = opaque; 161 int size; 162 int ret; 163 uint8_t buf1[NET_BUFSIZE]; 164 const uint8_t *buf; 165 166 size = qemu_recv(s->fd, buf1, sizeof(buf1), 0); 167 if (size < 0) { 168 if (errno != EWOULDBLOCK) 169 goto eoc; 170 } else if (size == 0) { 171 /* end of connection */ 172 eoc: 173 net_socket_read_poll(s, false); 174 net_socket_write_poll(s, false); 175 if (s->listen_fd != -1) { 176 qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s); 177 } 178 closesocket(s->fd); 179 180 s->fd = -1; 181 net_socket_rs_init(&s->rs, net_socket_rs_finalize, false); 182 s->nc.link_down = true; 183 memset(s->nc.info_str, 0, sizeof(s->nc.info_str)); 184 185 return; 186 } 187 buf = buf1; 188 189 ret = net_fill_rstate(&s->rs, buf, size); 190 191 if (ret == -1) { 192 goto eoc; 193 } 194} 195 196static void net_socket_send_dgram(void *opaque) 197{ 198 NetSocketState *s = opaque; 199 int size; 200 201 size = qemu_recv(s->fd, s->rs.buf, sizeof(s->rs.buf), 0); 202 if (size < 0) 203 return; 204 if (size == 0) { 205 /* end of connection */ 206 net_socket_read_poll(s, false); 207 net_socket_write_poll(s, false); 208 return; 209 } 210 if (qemu_send_packet_async(&s->nc, s->rs.buf, size, 211 net_socket_send_completed) == 0) { 212 net_socket_read_poll(s, false); 213 } 214} 215 216static int net_socket_mcast_create(struct sockaddr_in *mcastaddr, 217 struct in_addr *localaddr, 218 Error **errp) 219{ 220 struct ip_mreq imr; 221 int fd; 222 int val, ret; 223#ifdef __OpenBSD__ 224 unsigned char loop; 225#else 226 int loop; 227#endif 228 229 if (!IN_MULTICAST(ntohl(mcastaddr->sin_addr.s_addr))) { 230 error_setg(errp, "specified mcastaddr %s (0x%08x) " 231 "does not contain a multicast address", 232 inet_ntoa(mcastaddr->sin_addr), 233 (int)ntohl(mcastaddr->sin_addr.s_addr)); 234 return -1; 235 } 236 237 fd = qemu_socket(PF_INET, SOCK_DGRAM, 0); 238 if (fd < 0) { 239 error_setg_errno(errp, errno, "can't create datagram socket"); 240 return -1; 241 } 242 243 /* Allow multiple sockets to bind the same multicast ip and port by setting 244 * SO_REUSEADDR. This is the only situation where SO_REUSEADDR should be set 245 * on windows. Use socket_set_fast_reuse otherwise as it sets SO_REUSEADDR 246 * only on posix systems. 247 */ 248 val = 1; 249 ret = qemu_setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); 250 if (ret < 0) { 251 error_setg_errno(errp, errno, 252 "can't set socket option SO_REUSEADDR"); 253 goto fail; 254 } 255 256 ret = bind(fd, (struct sockaddr *)mcastaddr, sizeof(*mcastaddr)); 257 if (ret < 0) { 258 error_setg_errno(errp, errno, "can't bind ip=%s to socket", 259 inet_ntoa(mcastaddr->sin_addr)); 260 goto fail; 261 } 262 263 /* Add host to multicast group */ 264 imr.imr_multiaddr = mcastaddr->sin_addr; 265 if (localaddr) { 266 imr.imr_interface = *localaddr; 267 } else { 268 imr.imr_interface.s_addr = htonl(INADDR_ANY); 269 } 270 271 ret = qemu_setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, 272 &imr, sizeof(struct ip_mreq)); 273 if (ret < 0) { 274 error_setg_errno(errp, errno, 275 "can't add socket to multicast group %s", 276 inet_ntoa(imr.imr_multiaddr)); 277 goto fail; 278 } 279 280 /* Force mcast msgs to loopback (eg. several QEMUs in same host */ 281 loop = 1; 282 ret = qemu_setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, 283 &loop, sizeof(loop)); 284 if (ret < 0) { 285 error_setg_errno(errp, errno, 286 "can't force multicast message to loopback"); 287 goto fail; 288 } 289 290 /* If a bind address is given, only send packets from that address */ 291 if (localaddr != NULL) { 292 ret = qemu_setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, 293 localaddr, sizeof(*localaddr)); 294 if (ret < 0) { 295 error_setg_errno(errp, errno, 296 "can't set the default network send interface"); 297 goto fail; 298 } 299 } 300 301 qemu_set_nonblock(fd); 302 return fd; 303fail: 304 if (fd >= 0) 305 closesocket(fd); 306 return -1; 307} 308 309static void net_socket_cleanup(NetClientState *nc) 310{ 311 NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc); 312 if (s->fd != -1) { 313 net_socket_read_poll(s, false); 314 net_socket_write_poll(s, false); 315 close(s->fd); 316 s->fd = -1; 317 } 318 if (s->listen_fd != -1) { 319 qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL); 320 closesocket(s->listen_fd); 321 s->listen_fd = -1; 322 } 323} 324 325static NetClientInfo net_dgram_socket_info = { 326 .type = NET_CLIENT_DRIVER_SOCKET, 327 .size = sizeof(NetSocketState), 328 .receive = net_socket_receive_dgram, 329 .cleanup = net_socket_cleanup, 330}; 331 332static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer, 333 const char *model, 334 const char *name, 335 int fd, int is_connected, 336 const char *mcast, 337 Error **errp) 338{ 339 struct sockaddr_in saddr; 340 int newfd; 341 NetClientState *nc; 342 NetSocketState *s; 343 SocketAddress *sa; 344 SocketAddressType sa_type; 345 346 sa = socket_local_address(fd, errp); 347 if (!sa) { 348 return NULL; 349 } 350 sa_type = sa->type; 351 qapi_free_SocketAddress(sa); 352 353 /* fd passed: multicast: "learn" dgram_dst address from bound address and save it 354 * Because this may be "shared" socket from a "master" process, datagrams would be recv() 355 * by ONLY ONE process: we must "clone" this dgram socket --jjo 356 */ 357 358 if (is_connected && mcast != NULL) { 359 if (parse_host_port(&saddr, mcast, errp) < 0) { 360 goto err; 361 } 362 /* must be bound */ 363 if (saddr.sin_addr.s_addr == 0) { 364 error_setg(errp, "can't setup multicast destination address"); 365 goto err; 366 } 367 /* clone dgram socket */ 368 newfd = net_socket_mcast_create(&saddr, NULL, errp); 369 if (newfd < 0) { 370 goto err; 371 } 372 /* clone newfd to fd, close newfd */ 373 dup2(newfd, fd); 374 close(newfd); 375 376 } 377 378 nc = qemu_new_net_client(&net_dgram_socket_info, peer, model, name); 379 380 s = DO_UPCAST(NetSocketState, nc, nc); 381 382 s->fd = fd; 383 s->listen_fd = -1; 384 s->send_fn = net_socket_send_dgram; 385 net_socket_rs_init(&s->rs, net_socket_rs_finalize, false); 386 net_socket_read_poll(s, true); 387 388 /* mcast: save bound address as dst */ 389 if (is_connected && mcast != NULL) { 390 s->dgram_dst = saddr; 391 snprintf(nc->info_str, sizeof(nc->info_str), 392 "socket: fd=%d (cloned mcast=%s:%d)", 393 fd, inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port)); 394 } else { 395 if (sa_type == SOCKET_ADDRESS_TYPE_UNIX) { 396 s->dgram_dst.sin_family = AF_UNIX; 397 } 398 399 snprintf(nc->info_str, sizeof(nc->info_str), 400 "socket: fd=%d %s", fd, SocketAddressType_str(sa_type)); 401 } 402 403 return s; 404 405err: 406 closesocket(fd); 407 return NULL; 408} 409 410static void net_socket_connect(void *opaque) 411{ 412 NetSocketState *s = opaque; 413 s->send_fn = net_socket_send; 414 net_socket_read_poll(s, true); 415} 416 417static NetClientInfo net_socket_info = { 418 .type = NET_CLIENT_DRIVER_SOCKET, 419 .size = sizeof(NetSocketState), 420 .receive = net_socket_receive, 421 .cleanup = net_socket_cleanup, 422}; 423 424static NetSocketState *net_socket_fd_init_stream(NetClientState *peer, 425 const char *model, 426 const char *name, 427 int fd, int is_connected) 428{ 429 NetClientState *nc; 430 NetSocketState *s; 431 432 nc = qemu_new_net_client(&net_socket_info, peer, model, name); 433 434 snprintf(nc->info_str, sizeof(nc->info_str), "socket: fd=%d", fd); 435 436 s = DO_UPCAST(NetSocketState, nc, nc); 437 438 s->fd = fd; 439 s->listen_fd = -1; 440 net_socket_rs_init(&s->rs, net_socket_rs_finalize, false); 441 442 /* Disable Nagle algorithm on TCP sockets to reduce latency */ 443 socket_set_nodelay(fd); 444 445 if (is_connected) { 446 net_socket_connect(s); 447 } else { 448 qemu_set_fd_handler(s->fd, NULL, net_socket_connect, s); 449 } 450 return s; 451} 452 453static NetSocketState *net_socket_fd_init(NetClientState *peer, 454 const char *model, const char *name, 455 int fd, int is_connected, 456 const char *mc, Error **errp) 457{ 458 int so_type = -1, optlen=sizeof(so_type); 459 460 if(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&so_type, 461 (socklen_t *)&optlen)< 0) { 462 error_setg(errp, "can't get socket option SO_TYPE"); 463 closesocket(fd); 464 return NULL; 465 } 466 switch(so_type) { 467 case SOCK_DGRAM: 468 return net_socket_fd_init_dgram(peer, model, name, fd, is_connected, 469 mc, errp); 470 case SOCK_STREAM: 471 return net_socket_fd_init_stream(peer, model, name, fd, is_connected); 472 default: 473 error_setg(errp, "socket type=%d for fd=%d must be either" 474 " SOCK_DGRAM or SOCK_STREAM", so_type, fd); 475 closesocket(fd); 476 } 477 return NULL; 478} 479 480static void net_socket_accept(void *opaque) 481{ 482 NetSocketState *s = opaque; 483 struct sockaddr_in saddr; 484 socklen_t len; 485 int fd; 486 487 for(;;) { 488 len = sizeof(saddr); 489 fd = qemu_accept(s->listen_fd, (struct sockaddr *)&saddr, &len); 490 if (fd < 0 && errno != EINTR) { 491 return; 492 } else if (fd >= 0) { 493 qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL); 494 break; 495 } 496 } 497 498 s->fd = fd; 499 s->nc.link_down = false; 500 net_socket_connect(s); 501 snprintf(s->nc.info_str, sizeof(s->nc.info_str), 502 "socket: connection from %s:%d", 503 inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port)); 504} 505 506static int net_socket_listen_init(NetClientState *peer, 507 const char *model, 508 const char *name, 509 const char *host_str, 510 Error **errp) 511{ 512 NetClientState *nc; 513 NetSocketState *s; 514 struct sockaddr_in saddr; 515 int fd, ret; 516 517 if (parse_host_port(&saddr, host_str, errp) < 0) { 518 return -1; 519 } 520 521 fd = qemu_socket(PF_INET, SOCK_STREAM, 0); 522 if (fd < 0) { 523 error_setg_errno(errp, errno, "can't create stream socket"); 524 return -1; 525 } 526 qemu_set_nonblock(fd); 527 528 socket_set_fast_reuse(fd); 529 530 ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr)); 531 if (ret < 0) { 532 error_setg_errno(errp, errno, "can't bind ip=%s to socket", 533 inet_ntoa(saddr.sin_addr)); 534 closesocket(fd); 535 return -1; 536 } 537 ret = listen(fd, 0); 538 if (ret < 0) { 539 error_setg_errno(errp, errno, "can't listen on socket"); 540 closesocket(fd); 541 return -1; 542 } 543 544 nc = qemu_new_net_client(&net_socket_info, peer, model, name); 545 s = DO_UPCAST(NetSocketState, nc, nc); 546 s->fd = -1; 547 s->listen_fd = fd; 548 s->nc.link_down = true; 549 net_socket_rs_init(&s->rs, net_socket_rs_finalize, false); 550 551 qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s); 552 return 0; 553} 554 555static int net_socket_connect_init(NetClientState *peer, 556 const char *model, 557 const char *name, 558 const char *host_str, 559 Error **errp) 560{ 561 NetSocketState *s; 562 int fd, connected, ret; 563 struct sockaddr_in saddr; 564 565 if (parse_host_port(&saddr, host_str, errp) < 0) { 566 return -1; 567 } 568 569 fd = qemu_socket(PF_INET, SOCK_STREAM, 0); 570 if (fd < 0) { 571 error_setg_errno(errp, errno, "can't create stream socket"); 572 return -1; 573 } 574 qemu_set_nonblock(fd); 575 576 connected = 0; 577 for(;;) { 578 ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr)); 579 if (ret < 0) { 580 if (errno == EINTR || errno == EWOULDBLOCK) { 581 /* continue */ 582 } else if (errno == EINPROGRESS || 583 errno == EALREADY || 584 errno == EINVAL) { 585 break; 586 } else { 587 error_setg_errno(errp, errno, "can't connect socket"); 588 closesocket(fd); 589 return -1; 590 } 591 } else { 592 connected = 1; 593 break; 594 } 595 } 596 s = net_socket_fd_init(peer, model, name, fd, connected, NULL, errp); 597 if (!s) { 598 return -1; 599 } 600 601 snprintf(s->nc.info_str, sizeof(s->nc.info_str), 602 "socket: connect to %s:%d", 603 inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port)); 604 return 0; 605} 606 607static int net_socket_mcast_init(NetClientState *peer, 608 const char *model, 609 const char *name, 610 const char *host_str, 611 const char *localaddr_str, 612 Error **errp) 613{ 614 NetSocketState *s; 615 int fd; 616 struct sockaddr_in saddr; 617 struct in_addr localaddr, *param_localaddr; 618 619 if (parse_host_port(&saddr, host_str, errp) < 0) { 620 return -1; 621 } 622 623 if (localaddr_str != NULL) { 624 if (inet_aton(localaddr_str, &localaddr) == 0) { 625 error_setg(errp, "localaddr '%s' is not a valid IPv4 address", 626 localaddr_str); 627 return -1; 628 } 629 param_localaddr = &localaddr; 630 } else { 631 param_localaddr = NULL; 632 } 633 634 fd = net_socket_mcast_create(&saddr, param_localaddr, errp); 635 if (fd < 0) { 636 return -1; 637 } 638 639 s = net_socket_fd_init(peer, model, name, fd, 0, NULL, errp); 640 if (!s) { 641 return -1; 642 } 643 644 s->dgram_dst = saddr; 645 646 snprintf(s->nc.info_str, sizeof(s->nc.info_str), 647 "socket: mcast=%s:%d", 648 inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port)); 649 return 0; 650 651} 652 653static int net_socket_udp_init(NetClientState *peer, 654 const char *model, 655 const char *name, 656 const char *rhost, 657 const char *lhost, 658 Error **errp) 659{ 660 NetSocketState *s; 661 int fd, ret; 662 struct sockaddr_in laddr, raddr; 663 664 if (parse_host_port(&laddr, lhost, errp) < 0) { 665 return -1; 666 } 667 668 if (parse_host_port(&raddr, rhost, errp) < 0) { 669 return -1; 670 } 671 672 fd = qemu_socket(PF_INET, SOCK_DGRAM, 0); 673 if (fd < 0) { 674 error_setg_errno(errp, errno, "can't create datagram socket"); 675 return -1; 676 } 677 678 ret = socket_set_fast_reuse(fd); 679 if (ret < 0) { 680 error_setg_errno(errp, errno, 681 "can't set socket option SO_REUSEADDR"); 682 closesocket(fd); 683 return -1; 684 } 685 ret = bind(fd, (struct sockaddr *)&laddr, sizeof(laddr)); 686 if (ret < 0) { 687 error_setg_errno(errp, errno, "can't bind ip=%s to socket", 688 inet_ntoa(laddr.sin_addr)); 689 closesocket(fd); 690 return -1; 691 } 692 qemu_set_nonblock(fd); 693 694 s = net_socket_fd_init(peer, model, name, fd, 0, NULL, errp); 695 if (!s) { 696 return -1; 697 } 698 699 s->dgram_dst = raddr; 700 701 snprintf(s->nc.info_str, sizeof(s->nc.info_str), 702 "socket: udp=%s:%d", 703 inet_ntoa(raddr.sin_addr), ntohs(raddr.sin_port)); 704 return 0; 705} 706 707int net_init_socket(const Netdev *netdev, const char *name, 708 NetClientState *peer, Error **errp) 709{ 710 const NetdevSocketOptions *sock; 711 712 assert(netdev->type == NET_CLIENT_DRIVER_SOCKET); 713 sock = &netdev->u.socket; 714 715 if (sock->has_fd + sock->has_listen + sock->has_connect + sock->has_mcast + 716 sock->has_udp != 1) { 717 error_setg(errp, "exactly one of listen=, connect=, mcast= or udp=" 718 " is required"); 719 return -1; 720 } 721 722 if (sock->has_localaddr && !sock->has_mcast && !sock->has_udp) { 723 error_setg(errp, "localaddr= is only valid with mcast= or udp="); 724 return -1; 725 } 726 727 if (sock->has_fd) { 728 int fd, ret; 729 730 fd = monitor_fd_param(monitor_cur(), sock->fd, errp); 731 if (fd == -1) { 732 return -1; 733 } 734 ret = qemu_try_set_nonblock(fd); 735 if (ret < 0) { 736 error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d", 737 name, fd); 738 return -1; 739 } 740 if (!net_socket_fd_init(peer, "socket", name, fd, 1, sock->mcast, 741 errp)) { 742 return -1; 743 } 744 return 0; 745 } 746 747 if (sock->has_listen) { 748 if (net_socket_listen_init(peer, "socket", name, sock->listen, errp) 749 < 0) { 750 return -1; 751 } 752 return 0; 753 } 754 755 if (sock->has_connect) { 756 if (net_socket_connect_init(peer, "socket", name, sock->connect, errp) 757 < 0) { 758 return -1; 759 } 760 return 0; 761 } 762 763 if (sock->has_mcast) { 764 /* if sock->localaddr is missing, it has been initialized to "all bits 765 * zero" */ 766 if (net_socket_mcast_init(peer, "socket", name, sock->mcast, 767 sock->localaddr, errp) < 0) { 768 return -1; 769 } 770 return 0; 771 } 772 773 assert(sock->has_udp); 774 if (!sock->has_localaddr) { 775 error_setg(errp, "localaddr= is mandatory with udp="); 776 return -1; 777 } 778 if (net_socket_udp_init(peer, "socket", name, sock->udp, sock->localaddr, 779 errp) < 0) { 780 return -1; 781 } 782 return 0; 783}