xref: /qemu/io/channel-socket.c (revision b88651cb)
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                                          int flags,
528                                          Error **errp)
529 {
530     QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
531     ssize_t ret;
532     struct msghdr msg = { NULL, };
533     char control[CMSG_SPACE(sizeof(int) * SOCKET_MAX_FDS)];
534     size_t fdsize = sizeof(int) * nfds;
535     struct cmsghdr *cmsg;
536 
537     memset(control, 0, CMSG_SPACE(sizeof(int) * SOCKET_MAX_FDS));
538 
539     msg.msg_iov = (struct iovec *)iov;
540     msg.msg_iovlen = niov;
541 
542     if (nfds) {
543         if (nfds > SOCKET_MAX_FDS) {
544             error_setg_errno(errp, EINVAL,
545                              "Only %d FDs can be sent, got %zu",
546                              SOCKET_MAX_FDS, nfds);
547             return -1;
548         }
549 
550         msg.msg_control = control;
551         msg.msg_controllen = CMSG_SPACE(sizeof(int) * nfds);
552 
553         cmsg = CMSG_FIRSTHDR(&msg);
554         cmsg->cmsg_len = CMSG_LEN(fdsize);
555         cmsg->cmsg_level = SOL_SOCKET;
556         cmsg->cmsg_type = SCM_RIGHTS;
557         memcpy(CMSG_DATA(cmsg), fds, fdsize);
558     }
559 
560  retry:
561     ret = sendmsg(sioc->fd, &msg, 0);
562     if (ret <= 0) {
563         if (errno == EAGAIN) {
564             return QIO_CHANNEL_ERR_BLOCK;
565         }
566         if (errno == EINTR) {
567             goto retry;
568         }
569         error_setg_errno(errp, errno,
570                          "Unable to write to socket");
571         return -1;
572     }
573     return ret;
574 }
575 #else /* WIN32 */
576 static ssize_t qio_channel_socket_readv(QIOChannel *ioc,
577                                         const struct iovec *iov,
578                                         size_t niov,
579                                         int **fds,
580                                         size_t *nfds,
581                                         Error **errp)
582 {
583     QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
584     ssize_t done = 0;
585     ssize_t i;
586 
587     for (i = 0; i < niov; i++) {
588         ssize_t ret;
589     retry:
590         ret = recv(sioc->fd,
591                    iov[i].iov_base,
592                    iov[i].iov_len,
593                    0);
594         if (ret < 0) {
595             if (errno == EAGAIN) {
596                 if (done) {
597                     return done;
598                 } else {
599                     return QIO_CHANNEL_ERR_BLOCK;
600                 }
601             } else if (errno == EINTR) {
602                 goto retry;
603             } else {
604                 error_setg_errno(errp, errno,
605                                  "Unable to read from socket");
606                 return -1;
607             }
608         }
609         done += ret;
610         if (ret < iov[i].iov_len) {
611             return done;
612         }
613     }
614 
615     return done;
616 }
617 
618 static ssize_t qio_channel_socket_writev(QIOChannel *ioc,
619                                          const struct iovec *iov,
620                                          size_t niov,
621                                          int *fds,
622                                          size_t nfds,
623                                          int flags,
624                                          Error **errp)
625 {
626     QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
627     ssize_t done = 0;
628     ssize_t i;
629 
630     for (i = 0; i < niov; i++) {
631         ssize_t ret;
632     retry:
633         ret = send(sioc->fd,
634                    iov[i].iov_base,
635                    iov[i].iov_len,
636                    0);
637         if (ret < 0) {
638             if (errno == EAGAIN) {
639                 if (done) {
640                     return done;
641                 } else {
642                     return QIO_CHANNEL_ERR_BLOCK;
643                 }
644             } else if (errno == EINTR) {
645                 goto retry;
646             } else {
647                 error_setg_errno(errp, errno,
648                                  "Unable to write to socket");
649                 return -1;
650             }
651         }
652         done += ret;
653         if (ret < iov[i].iov_len) {
654             return done;
655         }
656     }
657 
658     return done;
659 }
660 #endif /* WIN32 */
661 
662 static int
663 qio_channel_socket_set_blocking(QIOChannel *ioc,
664                                 bool enabled,
665                                 Error **errp)
666 {
667     QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
668 
669     if (enabled) {
670         qemu_socket_set_block(sioc->fd);
671     } else {
672         qemu_socket_set_nonblock(sioc->fd);
673     }
674     return 0;
675 }
676 
677 
678 static void
679 qio_channel_socket_set_delay(QIOChannel *ioc,
680                              bool enabled)
681 {
682     QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
683     int v = enabled ? 0 : 1;
684 
685     setsockopt(sioc->fd,
686                IPPROTO_TCP, TCP_NODELAY,
687                &v, sizeof(v));
688 }
689 
690 
691 static void
692 qio_channel_socket_set_cork(QIOChannel *ioc,
693                             bool enabled)
694 {
695     QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
696     int v = enabled ? 1 : 0;
697 
698     socket_set_cork(sioc->fd, v);
699 }
700 
701 
702 static int
703 qio_channel_socket_close(QIOChannel *ioc,
704                          Error **errp)
705 {
706     QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
707     int rc = 0;
708     Error *err = NULL;
709 
710     if (sioc->fd != -1) {
711 #ifdef WIN32
712         WSAEventSelect(sioc->fd, NULL, 0);
713 #endif
714         if (qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_LISTEN)) {
715             socket_listen_cleanup(sioc->fd, errp);
716         }
717 
718         if (closesocket(sioc->fd) < 0) {
719             sioc->fd = -1;
720             error_setg_errno(&err, errno, "Unable to close socket");
721             error_propagate(errp, err);
722             return -1;
723         }
724         sioc->fd = -1;
725     }
726     return rc;
727 }
728 
729 static int
730 qio_channel_socket_shutdown(QIOChannel *ioc,
731                             QIOChannelShutdown how,
732                             Error **errp)
733 {
734     QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
735     int sockhow;
736 
737     switch (how) {
738     case QIO_CHANNEL_SHUTDOWN_READ:
739         sockhow = SHUT_RD;
740         break;
741     case QIO_CHANNEL_SHUTDOWN_WRITE:
742         sockhow = SHUT_WR;
743         break;
744     case QIO_CHANNEL_SHUTDOWN_BOTH:
745     default:
746         sockhow = SHUT_RDWR;
747         break;
748     }
749 
750     if (shutdown(sioc->fd, sockhow) < 0) {
751         error_setg_errno(errp, errno,
752                          "Unable to shutdown socket");
753         return -1;
754     }
755     return 0;
756 }
757 
758 static void qio_channel_socket_set_aio_fd_handler(QIOChannel *ioc,
759                                                   AioContext *ctx,
760                                                   IOHandler *io_read,
761                                                   IOHandler *io_write,
762                                                   void *opaque)
763 {
764     QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
765     aio_set_fd_handler(ctx, sioc->fd, false,
766                        io_read, io_write, NULL, NULL, opaque);
767 }
768 
769 static GSource *qio_channel_socket_create_watch(QIOChannel *ioc,
770                                                 GIOCondition condition)
771 {
772     QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
773     return qio_channel_create_socket_watch(ioc,
774                                            sioc->fd,
775                                            condition);
776 }
777 
778 static void qio_channel_socket_class_init(ObjectClass *klass,
779                                           void *class_data G_GNUC_UNUSED)
780 {
781     QIOChannelClass *ioc_klass = QIO_CHANNEL_CLASS(klass);
782 
783     ioc_klass->io_writev = qio_channel_socket_writev;
784     ioc_klass->io_readv = qio_channel_socket_readv;
785     ioc_klass->io_set_blocking = qio_channel_socket_set_blocking;
786     ioc_klass->io_close = qio_channel_socket_close;
787     ioc_klass->io_shutdown = qio_channel_socket_shutdown;
788     ioc_klass->io_set_cork = qio_channel_socket_set_cork;
789     ioc_klass->io_set_delay = qio_channel_socket_set_delay;
790     ioc_klass->io_create_watch = qio_channel_socket_create_watch;
791     ioc_klass->io_set_aio_fd_handler = qio_channel_socket_set_aio_fd_handler;
792 }
793 
794 static const TypeInfo qio_channel_socket_info = {
795     .parent = TYPE_QIO_CHANNEL,
796     .name = TYPE_QIO_CHANNEL_SOCKET,
797     .instance_size = sizeof(QIOChannelSocket),
798     .instance_init = qio_channel_socket_init,
799     .instance_finalize = qio_channel_socket_finalize,
800     .class_init = qio_channel_socket_class_init,
801 };
802 
803 static void qio_channel_socket_register_types(void)
804 {
805     type_register_static(&qio_channel_socket_info);
806 }
807 
808 type_init(qio_channel_socket_register_types);
809