xref: /qemu/io/channel-socket.c (revision 2a3129a3)
1 /*
2  * QEMU I/O channels sockets driver
3  *
4  * Copyright (c) 2015 Red Hat, Inc.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include "qemu/osdep.h"
21 #include "qapi/error.h"
22 #include "qapi/qapi-visit-sockets.h"
23 #include "qemu/module.h"
24 #include "io/channel-socket.h"
25 #include "io/channel-watch.h"
26 #include "trace.h"
27 #include "qapi/clone-visitor.h"
28 
29 #define SOCKET_MAX_FDS 16
30 
31 SocketAddress *
32 qio_channel_socket_get_local_address(QIOChannelSocket *ioc,
33                                      Error **errp)
34 {
35     return socket_sockaddr_to_address(&ioc->localAddr,
36                                       ioc->localAddrLen,
37                                       errp);
38 }
39 
40 SocketAddress *
41 qio_channel_socket_get_remote_address(QIOChannelSocket *ioc,
42                                       Error **errp)
43 {
44     return socket_sockaddr_to_address(&ioc->remoteAddr,
45                                       ioc->remoteAddrLen,
46                                       errp);
47 }
48 
49 QIOChannelSocket *
50 qio_channel_socket_new(void)
51 {
52     QIOChannelSocket *sioc;
53     QIOChannel *ioc;
54 
55     sioc = QIO_CHANNEL_SOCKET(object_new(TYPE_QIO_CHANNEL_SOCKET));
56     sioc->fd = -1;
57 
58     ioc = QIO_CHANNEL(sioc);
59     qio_channel_set_feature(ioc, QIO_CHANNEL_FEATURE_SHUTDOWN);
60 
61 #ifdef WIN32
62     ioc->event = CreateEvent(NULL, FALSE, FALSE, NULL);
63 #endif
64 
65     trace_qio_channel_socket_new(sioc);
66 
67     return sioc;
68 }
69 
70 
71 static int
72 qio_channel_socket_set_fd(QIOChannelSocket *sioc,
73                           int fd,
74                           Error **errp)
75 {
76     if (sioc->fd != -1) {
77         error_setg(errp, "Socket is already open");
78         return -1;
79     }
80 
81     sioc->fd = fd;
82     sioc->remoteAddrLen = sizeof(sioc->remoteAddr);
83     sioc->localAddrLen = sizeof(sioc->localAddr);
84 
85 
86     if (getpeername(fd, (struct sockaddr *)&sioc->remoteAddr,
87                     &sioc->remoteAddrLen) < 0) {
88         if (errno == ENOTCONN) {
89             memset(&sioc->remoteAddr, 0, sizeof(sioc->remoteAddr));
90             sioc->remoteAddrLen = sizeof(sioc->remoteAddr);
91         } else {
92             error_setg_errno(errp, errno,
93                              "Unable to query remote socket address");
94             goto error;
95         }
96     }
97 
98     if (getsockname(fd, (struct sockaddr *)&sioc->localAddr,
99                     &sioc->localAddrLen) < 0) {
100         error_setg_errno(errp, errno,
101                          "Unable to query local socket address");
102         goto error;
103     }
104 
105 #ifndef WIN32
106     if (sioc->localAddr.ss_family == AF_UNIX) {
107         QIOChannel *ioc = QIO_CHANNEL(sioc);
108         qio_channel_set_feature(ioc, QIO_CHANNEL_FEATURE_FD_PASS);
109     }
110 #endif /* WIN32 */
111 
112     return 0;
113 
114  error:
115     sioc->fd = -1; /* Let the caller close FD on failure */
116     return -1;
117 }
118 
119 QIOChannelSocket *
120 qio_channel_socket_new_fd(int fd,
121                           Error **errp)
122 {
123     QIOChannelSocket *ioc;
124 
125     ioc = qio_channel_socket_new();
126     if (qio_channel_socket_set_fd(ioc, fd, errp) < 0) {
127         object_unref(OBJECT(ioc));
128         return NULL;
129     }
130 
131     trace_qio_channel_socket_new_fd(ioc, fd);
132 
133     return ioc;
134 }
135 
136 
137 int qio_channel_socket_connect_sync(QIOChannelSocket *ioc,
138                                     SocketAddress *addr,
139                                     Error **errp)
140 {
141     int fd;
142 
143     trace_qio_channel_socket_connect_sync(ioc, addr);
144     fd = socket_connect(addr, errp);
145     if (fd < 0) {
146         trace_qio_channel_socket_connect_fail(ioc);
147         return -1;
148     }
149 
150     trace_qio_channel_socket_connect_complete(ioc, fd);
151     if (qio_channel_socket_set_fd(ioc, fd, errp) < 0) {
152         close(fd);
153         return -1;
154     }
155 
156     return 0;
157 }
158 
159 
160 static void qio_channel_socket_connect_worker(QIOTask *task,
161                                               gpointer opaque)
162 {
163     QIOChannelSocket *ioc = QIO_CHANNEL_SOCKET(qio_task_get_source(task));
164     SocketAddress *addr = opaque;
165     Error *err = NULL;
166 
167     qio_channel_socket_connect_sync(ioc, addr, &err);
168 
169     qio_task_set_error(task, err);
170 }
171 
172 
173 void qio_channel_socket_connect_async(QIOChannelSocket *ioc,
174                                       SocketAddress *addr,
175                                       QIOTaskFunc callback,
176                                       gpointer opaque,
177                                       GDestroyNotify destroy,
178                                       GMainContext *context)
179 {
180     QIOTask *task = qio_task_new(
181         OBJECT(ioc), callback, opaque, destroy);
182     SocketAddress *addrCopy;
183 
184     addrCopy = QAPI_CLONE(SocketAddress, addr);
185 
186     /* socket_connect() does a non-blocking connect(), but it
187      * still blocks in DNS lookups, so we must use a thread */
188     trace_qio_channel_socket_connect_async(ioc, addr);
189     qio_task_run_in_thread(task,
190                            qio_channel_socket_connect_worker,
191                            addrCopy,
192                            (GDestroyNotify)qapi_free_SocketAddress,
193                            context);
194 }
195 
196 
197 int qio_channel_socket_listen_sync(QIOChannelSocket *ioc,
198                                    SocketAddress *addr,
199                                    int num,
200                                    Error **errp)
201 {
202     int fd;
203 
204     trace_qio_channel_socket_listen_sync(ioc, addr, num);
205     fd = socket_listen(addr, num, errp);
206     if (fd < 0) {
207         trace_qio_channel_socket_listen_fail(ioc);
208         return -1;
209     }
210 
211     trace_qio_channel_socket_listen_complete(ioc, fd);
212     if (qio_channel_socket_set_fd(ioc, fd, errp) < 0) {
213         close(fd);
214         return -1;
215     }
216     qio_channel_set_feature(QIO_CHANNEL(ioc), QIO_CHANNEL_FEATURE_LISTEN);
217 
218     return 0;
219 }
220 
221 
222 struct QIOChannelListenWorkerData {
223     SocketAddress *addr;
224     int num; /* amount of expected connections */
225 };
226 
227 static void qio_channel_listen_worker_free(gpointer opaque)
228 {
229     struct QIOChannelListenWorkerData *data = opaque;
230 
231     qapi_free_SocketAddress(data->addr);
232     g_free(data);
233 }
234 
235 static void qio_channel_socket_listen_worker(QIOTask *task,
236                                              gpointer opaque)
237 {
238     QIOChannelSocket *ioc = QIO_CHANNEL_SOCKET(qio_task_get_source(task));
239     struct QIOChannelListenWorkerData *data = opaque;
240     Error *err = NULL;
241 
242     qio_channel_socket_listen_sync(ioc, data->addr, data->num, &err);
243 
244     qio_task_set_error(task, err);
245 }
246 
247 
248 void qio_channel_socket_listen_async(QIOChannelSocket *ioc,
249                                      SocketAddress *addr,
250                                      int num,
251                                      QIOTaskFunc callback,
252                                      gpointer opaque,
253                                      GDestroyNotify destroy,
254                                      GMainContext *context)
255 {
256     QIOTask *task = qio_task_new(
257         OBJECT(ioc), callback, opaque, destroy);
258     struct QIOChannelListenWorkerData *data;
259 
260     data = g_new0(struct QIOChannelListenWorkerData, 1);
261     data->addr = QAPI_CLONE(SocketAddress, addr);
262     data->num = num;
263 
264     /* socket_listen() blocks in DNS lookups, so we must use a thread */
265     trace_qio_channel_socket_listen_async(ioc, addr, num);
266     qio_task_run_in_thread(task,
267                            qio_channel_socket_listen_worker,
268                            data,
269                            qio_channel_listen_worker_free,
270                            context);
271 }
272 
273 
274 int qio_channel_socket_dgram_sync(QIOChannelSocket *ioc,
275                                   SocketAddress *localAddr,
276                                   SocketAddress *remoteAddr,
277                                   Error **errp)
278 {
279     int fd;
280 
281     trace_qio_channel_socket_dgram_sync(ioc, localAddr, remoteAddr);
282     fd = socket_dgram(remoteAddr, localAddr, errp);
283     if (fd < 0) {
284         trace_qio_channel_socket_dgram_fail(ioc);
285         return -1;
286     }
287 
288     trace_qio_channel_socket_dgram_complete(ioc, fd);
289     if (qio_channel_socket_set_fd(ioc, fd, errp) < 0) {
290         close(fd);
291         return -1;
292     }
293 
294     return 0;
295 }
296 
297 
298 struct QIOChannelSocketDGramWorkerData {
299     SocketAddress *localAddr;
300     SocketAddress *remoteAddr;
301 };
302 
303 
304 static void qio_channel_socket_dgram_worker_free(gpointer opaque)
305 {
306     struct QIOChannelSocketDGramWorkerData *data = opaque;
307     qapi_free_SocketAddress(data->localAddr);
308     qapi_free_SocketAddress(data->remoteAddr);
309     g_free(data);
310 }
311 
312 static void qio_channel_socket_dgram_worker(QIOTask *task,
313                                             gpointer opaque)
314 {
315     QIOChannelSocket *ioc = QIO_CHANNEL_SOCKET(qio_task_get_source(task));
316     struct QIOChannelSocketDGramWorkerData *data = opaque;
317     Error *err = NULL;
318 
319     /* socket_dgram() blocks in DNS lookups, so we must use a thread */
320     qio_channel_socket_dgram_sync(ioc, data->localAddr,
321                                   data->remoteAddr, &err);
322 
323     qio_task_set_error(task, err);
324 }
325 
326 
327 void qio_channel_socket_dgram_async(QIOChannelSocket *ioc,
328                                     SocketAddress *localAddr,
329                                     SocketAddress *remoteAddr,
330                                     QIOTaskFunc callback,
331                                     gpointer opaque,
332                                     GDestroyNotify destroy,
333                                     GMainContext *context)
334 {
335     QIOTask *task = qio_task_new(
336         OBJECT(ioc), callback, opaque, destroy);
337     struct QIOChannelSocketDGramWorkerData *data = g_new0(
338         struct QIOChannelSocketDGramWorkerData, 1);
339 
340     data->localAddr = QAPI_CLONE(SocketAddress, localAddr);
341     data->remoteAddr = QAPI_CLONE(SocketAddress, remoteAddr);
342 
343     trace_qio_channel_socket_dgram_async(ioc, localAddr, remoteAddr);
344     qio_task_run_in_thread(task,
345                            qio_channel_socket_dgram_worker,
346                            data,
347                            qio_channel_socket_dgram_worker_free,
348                            context);
349 }
350 
351 
352 QIOChannelSocket *
353 qio_channel_socket_accept(QIOChannelSocket *ioc,
354                           Error **errp)
355 {
356     QIOChannelSocket *cioc;
357 
358     cioc = qio_channel_socket_new();
359     cioc->remoteAddrLen = sizeof(ioc->remoteAddr);
360     cioc->localAddrLen = sizeof(ioc->localAddr);
361 
362  retry:
363     trace_qio_channel_socket_accept(ioc);
364     cioc->fd = qemu_accept(ioc->fd, (struct sockaddr *)&cioc->remoteAddr,
365                            &cioc->remoteAddrLen);
366     if (cioc->fd < 0) {
367         if (errno == EINTR) {
368             goto retry;
369         }
370         error_setg_errno(errp, errno, "Unable to accept connection");
371         trace_qio_channel_socket_accept_fail(ioc);
372         goto error;
373     }
374 
375     if (getsockname(cioc->fd, (struct sockaddr *)&cioc->localAddr,
376                     &cioc->localAddrLen) < 0) {
377         error_setg_errno(errp, errno,
378                          "Unable to query local socket address");
379         goto error;
380     }
381 
382 #ifndef WIN32
383     if (cioc->localAddr.ss_family == AF_UNIX) {
384         QIOChannel *ioc_local = QIO_CHANNEL(cioc);
385         qio_channel_set_feature(ioc_local, QIO_CHANNEL_FEATURE_FD_PASS);
386     }
387 #endif /* WIN32 */
388 
389     trace_qio_channel_socket_accept_complete(ioc, cioc, cioc->fd);
390     return cioc;
391 
392  error:
393     object_unref(OBJECT(cioc));
394     return NULL;
395 }
396 
397 static void qio_channel_socket_init(Object *obj)
398 {
399     QIOChannelSocket *ioc = QIO_CHANNEL_SOCKET(obj);
400     ioc->fd = -1;
401 }
402 
403 static void qio_channel_socket_finalize(Object *obj)
404 {
405     QIOChannelSocket *ioc = QIO_CHANNEL_SOCKET(obj);
406 
407     if (ioc->fd != -1) {
408         QIOChannel *ioc_local = QIO_CHANNEL(ioc);
409         if (qio_channel_has_feature(ioc_local, QIO_CHANNEL_FEATURE_LISTEN)) {
410             Error *err = NULL;
411 
412             socket_listen_cleanup(ioc->fd, &err);
413             if (err) {
414                 error_report_err(err);
415                 err = NULL;
416             }
417         }
418 #ifdef WIN32
419         WSAEventSelect(ioc->fd, NULL, 0);
420 #endif
421         closesocket(ioc->fd);
422         ioc->fd = -1;
423     }
424 }
425 
426 
427 #ifndef WIN32
428 static void qio_channel_socket_copy_fds(struct msghdr *msg,
429                                         int **fds, size_t *nfds)
430 {
431     struct cmsghdr *cmsg;
432 
433     *nfds = 0;
434     *fds = NULL;
435 
436     for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
437         int fd_size, i;
438         int gotfds;
439 
440         if (cmsg->cmsg_len < CMSG_LEN(sizeof(int)) ||
441             cmsg->cmsg_level != SOL_SOCKET ||
442             cmsg->cmsg_type != SCM_RIGHTS) {
443             continue;
444         }
445 
446         fd_size = cmsg->cmsg_len - CMSG_LEN(0);
447 
448         if (!fd_size) {
449             continue;
450         }
451 
452         gotfds = fd_size / sizeof(int);
453         *fds = g_renew(int, *fds, *nfds + gotfds);
454         memcpy(*fds + *nfds, CMSG_DATA(cmsg), fd_size);
455 
456         for (i = 0; i < gotfds; i++) {
457             int fd = (*fds)[*nfds + i];
458             if (fd < 0) {
459                 continue;
460             }
461 
462             /* O_NONBLOCK is preserved across SCM_RIGHTS so reset it */
463             qemu_socket_set_block(fd);
464 
465 #ifndef MSG_CMSG_CLOEXEC
466             qemu_set_cloexec(fd);
467 #endif
468         }
469         *nfds += gotfds;
470     }
471 }
472 
473 
474 static ssize_t qio_channel_socket_readv(QIOChannel *ioc,
475                                         const struct iovec *iov,
476                                         size_t niov,
477                                         int **fds,
478                                         size_t *nfds,
479                                         Error **errp)
480 {
481     QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
482     ssize_t ret;
483     struct msghdr msg = { NULL, };
484     char control[CMSG_SPACE(sizeof(int) * SOCKET_MAX_FDS)];
485     int sflags = 0;
486 
487     memset(control, 0, CMSG_SPACE(sizeof(int) * SOCKET_MAX_FDS));
488 
489     msg.msg_iov = (struct iovec *)iov;
490     msg.msg_iovlen = niov;
491     if (fds && nfds) {
492         msg.msg_control = control;
493         msg.msg_controllen = sizeof(control);
494 #ifdef MSG_CMSG_CLOEXEC
495         sflags |= MSG_CMSG_CLOEXEC;
496 #endif
497 
498     }
499 
500  retry:
501     ret = recvmsg(sioc->fd, &msg, sflags);
502     if (ret < 0) {
503         if (errno == EAGAIN) {
504             return QIO_CHANNEL_ERR_BLOCK;
505         }
506         if (errno == EINTR) {
507             goto retry;
508         }
509 
510         error_setg_errno(errp, errno,
511                          "Unable to read from socket");
512         return -1;
513     }
514 
515     if (fds && nfds) {
516         qio_channel_socket_copy_fds(&msg, fds, nfds);
517     }
518 
519     return ret;
520 }
521 
522 static ssize_t qio_channel_socket_writev(QIOChannel *ioc,
523                                          const struct iovec *iov,
524                                          size_t niov,
525                                          int *fds,
526                                          size_t nfds,
527                                          Error **errp)
528 {
529     QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
530     ssize_t ret;
531     struct msghdr msg = { NULL, };
532     char control[CMSG_SPACE(sizeof(int) * SOCKET_MAX_FDS)];
533     size_t fdsize = sizeof(int) * nfds;
534     struct cmsghdr *cmsg;
535 
536     memset(control, 0, CMSG_SPACE(sizeof(int) * SOCKET_MAX_FDS));
537 
538     msg.msg_iov = (struct iovec *)iov;
539     msg.msg_iovlen = niov;
540 
541     if (nfds) {
542         if (nfds > SOCKET_MAX_FDS) {
543             error_setg_errno(errp, EINVAL,
544                              "Only %d FDs can be sent, got %zu",
545                              SOCKET_MAX_FDS, nfds);
546             return -1;
547         }
548 
549         msg.msg_control = control;
550         msg.msg_controllen = CMSG_SPACE(sizeof(int) * nfds);
551 
552         cmsg = CMSG_FIRSTHDR(&msg);
553         cmsg->cmsg_len = CMSG_LEN(fdsize);
554         cmsg->cmsg_level = SOL_SOCKET;
555         cmsg->cmsg_type = SCM_RIGHTS;
556         memcpy(CMSG_DATA(cmsg), fds, fdsize);
557     }
558 
559  retry:
560     ret = sendmsg(sioc->fd, &msg, 0);
561     if (ret <= 0) {
562         if (errno == EAGAIN) {
563             return QIO_CHANNEL_ERR_BLOCK;
564         }
565         if (errno == EINTR) {
566             goto retry;
567         }
568         error_setg_errno(errp, errno,
569                          "Unable to write to socket");
570         return -1;
571     }
572     return ret;
573 }
574 #else /* WIN32 */
575 static ssize_t qio_channel_socket_readv(QIOChannel *ioc,
576                                         const struct iovec *iov,
577                                         size_t niov,
578                                         int **fds,
579                                         size_t *nfds,
580                                         Error **errp)
581 {
582     QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
583     ssize_t done = 0;
584     ssize_t i;
585 
586     for (i = 0; i < niov; i++) {
587         ssize_t ret;
588     retry:
589         ret = recv(sioc->fd,
590                    iov[i].iov_base,
591                    iov[i].iov_len,
592                    0);
593         if (ret < 0) {
594             if (errno == EAGAIN) {
595                 if (done) {
596                     return done;
597                 } else {
598                     return QIO_CHANNEL_ERR_BLOCK;
599                 }
600             } else if (errno == EINTR) {
601                 goto retry;
602             } else {
603                 error_setg_errno(errp, errno,
604                                  "Unable to read from socket");
605                 return -1;
606             }
607         }
608         done += ret;
609         if (ret < iov[i].iov_len) {
610             return done;
611         }
612     }
613 
614     return done;
615 }
616 
617 static ssize_t qio_channel_socket_writev(QIOChannel *ioc,
618                                          const struct iovec *iov,
619                                          size_t niov,
620                                          int *fds,
621                                          size_t nfds,
622                                          Error **errp)
623 {
624     QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
625     ssize_t done = 0;
626     ssize_t i;
627 
628     for (i = 0; i < niov; i++) {
629         ssize_t ret;
630     retry:
631         ret = send(sioc->fd,
632                    iov[i].iov_base,
633                    iov[i].iov_len,
634                    0);
635         if (ret < 0) {
636             if (errno == EAGAIN) {
637                 if (done) {
638                     return done;
639                 } else {
640                     return QIO_CHANNEL_ERR_BLOCK;
641                 }
642             } else if (errno == EINTR) {
643                 goto retry;
644             } else {
645                 error_setg_errno(errp, errno,
646                                  "Unable to write to socket");
647                 return -1;
648             }
649         }
650         done += ret;
651         if (ret < iov[i].iov_len) {
652             return done;
653         }
654     }
655 
656     return done;
657 }
658 #endif /* WIN32 */
659 
660 static int
661 qio_channel_socket_set_blocking(QIOChannel *ioc,
662                                 bool enabled,
663                                 Error **errp)
664 {
665     QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
666 
667     if (enabled) {
668         qemu_socket_set_block(sioc->fd);
669     } else {
670         qemu_socket_set_nonblock(sioc->fd);
671     }
672     return 0;
673 }
674 
675 
676 static void
677 qio_channel_socket_set_delay(QIOChannel *ioc,
678                              bool enabled)
679 {
680     QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
681     int v = enabled ? 0 : 1;
682 
683     setsockopt(sioc->fd,
684                IPPROTO_TCP, TCP_NODELAY,
685                &v, sizeof(v));
686 }
687 
688 
689 static void
690 qio_channel_socket_set_cork(QIOChannel *ioc,
691                             bool enabled)
692 {
693     QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
694     int v = enabled ? 1 : 0;
695 
696     socket_set_cork(sioc->fd, v);
697 }
698 
699 
700 static int
701 qio_channel_socket_close(QIOChannel *ioc,
702                          Error **errp)
703 {
704     QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
705     int rc = 0;
706     Error *err = NULL;
707 
708     if (sioc->fd != -1) {
709 #ifdef WIN32
710         WSAEventSelect(sioc->fd, NULL, 0);
711 #endif
712         if (qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_LISTEN)) {
713             socket_listen_cleanup(sioc->fd, errp);
714         }
715 
716         if (closesocket(sioc->fd) < 0) {
717             sioc->fd = -1;
718             error_setg_errno(&err, errno, "Unable to close socket");
719             error_propagate(errp, err);
720             return -1;
721         }
722         sioc->fd = -1;
723     }
724     return rc;
725 }
726 
727 static int
728 qio_channel_socket_shutdown(QIOChannel *ioc,
729                             QIOChannelShutdown how,
730                             Error **errp)
731 {
732     QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
733     int sockhow;
734 
735     switch (how) {
736     case QIO_CHANNEL_SHUTDOWN_READ:
737         sockhow = SHUT_RD;
738         break;
739     case QIO_CHANNEL_SHUTDOWN_WRITE:
740         sockhow = SHUT_WR;
741         break;
742     case QIO_CHANNEL_SHUTDOWN_BOTH:
743     default:
744         sockhow = SHUT_RDWR;
745         break;
746     }
747 
748     if (shutdown(sioc->fd, sockhow) < 0) {
749         error_setg_errno(errp, errno,
750                          "Unable to shutdown socket");
751         return -1;
752     }
753     return 0;
754 }
755 
756 static void qio_channel_socket_set_aio_fd_handler(QIOChannel *ioc,
757                                                   AioContext *ctx,
758                                                   IOHandler *io_read,
759                                                   IOHandler *io_write,
760                                                   void *opaque)
761 {
762     QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
763     aio_set_fd_handler(ctx, sioc->fd, false,
764                        io_read, io_write, NULL, NULL, opaque);
765 }
766 
767 static GSource *qio_channel_socket_create_watch(QIOChannel *ioc,
768                                                 GIOCondition condition)
769 {
770     QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
771     return qio_channel_create_socket_watch(ioc,
772                                            sioc->fd,
773                                            condition);
774 }
775 
776 static void qio_channel_socket_class_init(ObjectClass *klass,
777                                           void *class_data G_GNUC_UNUSED)
778 {
779     QIOChannelClass *ioc_klass = QIO_CHANNEL_CLASS(klass);
780 
781     ioc_klass->io_writev = qio_channel_socket_writev;
782     ioc_klass->io_readv = qio_channel_socket_readv;
783     ioc_klass->io_set_blocking = qio_channel_socket_set_blocking;
784     ioc_klass->io_close = qio_channel_socket_close;
785     ioc_klass->io_shutdown = qio_channel_socket_shutdown;
786     ioc_klass->io_set_cork = qio_channel_socket_set_cork;
787     ioc_klass->io_set_delay = qio_channel_socket_set_delay;
788     ioc_klass->io_create_watch = qio_channel_socket_create_watch;
789     ioc_klass->io_set_aio_fd_handler = qio_channel_socket_set_aio_fd_handler;
790 }
791 
792 static const TypeInfo qio_channel_socket_info = {
793     .parent = TYPE_QIO_CHANNEL,
794     .name = TYPE_QIO_CHANNEL_SOCKET,
795     .instance_size = sizeof(QIOChannelSocket),
796     .instance_init = qio_channel_socket_init,
797     .instance_finalize = qio_channel_socket_finalize,
798     .class_init = qio_channel_socket_class_init,
799 };
800 
801 static void qio_channel_socket_register_types(void)
802 {
803     type_register_static(&qio_channel_socket_info);
804 }
805 
806 type_init(qio_channel_socket_register_types);
807