blob: b4d914b767921a6187c91c8705a391f4382eb35e [file] [log] [blame]
Daniel P. Berrange559607e2015-02-27 16:19:33 +00001/*
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 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
Peter Maydellcae9fc52016-01-29 17:50:03 +000021#include "qemu/osdep.h"
Markus Armbrusterda34e652016-03-14 09:01:28 +010022#include "qapi/error.h"
Markus Armbruster9af23982018-02-11 10:36:01 +010023#include "qapi/qapi-visit-sockets.h"
Daniel P. Berrange559607e2015-02-27 16:19:33 +000024#include "io/channel-socket.h"
25#include "io/channel-watch.h"
26#include "trace.h"
Eric Blake37f9e0a2016-06-09 10:48:45 -060027#include "qapi/clone-visitor.h"
Daniel P. Berrange559607e2015-02-27 16:19:33 +000028
29#define SOCKET_MAX_FDS 16
30
31SocketAddress *
32qio_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
40SocketAddress *
41qio_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
49QIOChannelSocket *
50qio_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);
Felipe Franciosid8d3c7c2016-09-29 08:52:37 -070059 qio_channel_set_feature(ioc, QIO_CHANNEL_FEATURE_SHUTDOWN);
Daniel P. Berrange559607e2015-02-27 16:19:33 +000060
Paolo Bonzinia5897202016-03-07 12:12:36 +010061#ifdef WIN32
62 ioc->event = CreateEvent(NULL, FALSE, FALSE, NULL);
63#endif
64
Daniel P. Berrange559607e2015-02-27 16:19:33 +000065 trace_qio_channel_socket_new(sioc);
66
67 return sioc;
68}
69
70
71static int
72qio_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) {
Daniel P. Berrangeb16a44e2016-03-07 20:36:03 +000088 if (errno == ENOTCONN) {
Daniel P. Berrange559607e2015-02-27 16:19:33 +000089 memset(&sioc->remoteAddr, 0, sizeof(sioc->remoteAddr));
90 sioc->remoteAddrLen = sizeof(sioc->remoteAddr);
91 } else {
Daniel P. Berrangeb16a44e2016-03-07 20:36:03 +000092 error_setg_errno(errp, errno,
Daniel P. Berrange559607e2015-02-27 16:19:33 +000093 "Unable to query remote socket address");
94 goto error;
95 }
96 }
97
98 if (getsockname(fd, (struct sockaddr *)&sioc->localAddr,
99 &sioc->localAddrLen) < 0) {
Daniel P. Berrangeb16a44e2016-03-07 20:36:03 +0000100 error_setg_errno(errp, errno,
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000101 "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);
Felipe Franciosid8d3c7c2016-09-29 08:52:37 -0700108 qio_channel_set_feature(ioc, QIO_CHANNEL_FEATURE_FD_PASS);
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000109 }
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
119QIOChannelSocket *
120qio_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
137int 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);
Cao jinb2587932017-06-16 16:54:45 +0800144 fd = socket_connect(addr, errp);
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000145 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
Daniel P. Berrange59de5172016-08-11 17:38:07 +0100160static void qio_channel_socket_connect_worker(QIOTask *task,
161 gpointer opaque)
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000162{
163 QIOChannelSocket *ioc = QIO_CHANNEL_SOCKET(qio_task_get_source(task));
164 SocketAddress *addr = opaque;
Daniel P. Berrange59de5172016-08-11 17:38:07 +0100165 Error *err = NULL;
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000166
Daniel P. Berrange59de5172016-08-11 17:38:07 +0100167 qio_channel_socket_connect_sync(ioc, addr, &err);
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000168
Daniel P. Berrange59de5172016-08-11 17:38:07 +0100169 qio_task_set_error(task, err);
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000170}
171
172
173void qio_channel_socket_connect_async(QIOChannelSocket *ioc,
174 SocketAddress *addr,
175 QIOTaskFunc callback,
176 gpointer opaque,
177 GDestroyNotify destroy)
178{
179 QIOTask *task = qio_task_new(
180 OBJECT(ioc), callback, opaque, destroy);
181 SocketAddress *addrCopy;
182
Eric Blake37f9e0a2016-06-09 10:48:45 -0600183 addrCopy = QAPI_CLONE(SocketAddress, addr);
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000184
185 /* socket_connect() does a non-blocking connect(), but it
186 * still blocks in DNS lookups, so we must use a thread */
187 trace_qio_channel_socket_connect_async(ioc, addr);
188 qio_task_run_in_thread(task,
189 qio_channel_socket_connect_worker,
190 addrCopy,
Peter Xua17536c2018-03-05 14:43:22 +0800191 (GDestroyNotify)qapi_free_SocketAddress,
192 NULL);
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000193}
194
195
196int qio_channel_socket_listen_sync(QIOChannelSocket *ioc,
197 SocketAddress *addr,
198 Error **errp)
199{
200 int fd;
201
202 trace_qio_channel_socket_listen_sync(ioc, addr);
203 fd = socket_listen(addr, errp);
204 if (fd < 0) {
205 trace_qio_channel_socket_listen_fail(ioc);
206 return -1;
207 }
208
209 trace_qio_channel_socket_listen_complete(ioc, fd);
210 if (qio_channel_socket_set_fd(ioc, fd, errp) < 0) {
211 close(fd);
212 return -1;
213 }
Daniel P. Berrangebf535202016-10-26 18:20:20 +0200214 qio_channel_set_feature(QIO_CHANNEL(ioc), QIO_CHANNEL_FEATURE_LISTEN);
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000215
216 return 0;
217}
218
219
Daniel P. Berrange59de5172016-08-11 17:38:07 +0100220static void qio_channel_socket_listen_worker(QIOTask *task,
221 gpointer opaque)
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000222{
223 QIOChannelSocket *ioc = QIO_CHANNEL_SOCKET(qio_task_get_source(task));
224 SocketAddress *addr = opaque;
Daniel P. Berrange59de5172016-08-11 17:38:07 +0100225 Error *err = NULL;
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000226
Daniel P. Berrange59de5172016-08-11 17:38:07 +0100227 qio_channel_socket_listen_sync(ioc, addr, &err);
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000228
Daniel P. Berrange59de5172016-08-11 17:38:07 +0100229 qio_task_set_error(task, err);
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000230}
231
232
233void qio_channel_socket_listen_async(QIOChannelSocket *ioc,
234 SocketAddress *addr,
235 QIOTaskFunc callback,
236 gpointer opaque,
237 GDestroyNotify destroy)
238{
239 QIOTask *task = qio_task_new(
240 OBJECT(ioc), callback, opaque, destroy);
241 SocketAddress *addrCopy;
242
Eric Blake37f9e0a2016-06-09 10:48:45 -0600243 addrCopy = QAPI_CLONE(SocketAddress, addr);
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000244
245 /* socket_listen() blocks in DNS lookups, so we must use a thread */
246 trace_qio_channel_socket_listen_async(ioc, addr);
247 qio_task_run_in_thread(task,
248 qio_channel_socket_listen_worker,
249 addrCopy,
Peter Xua17536c2018-03-05 14:43:22 +0800250 (GDestroyNotify)qapi_free_SocketAddress,
251 NULL);
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000252}
253
254
255int qio_channel_socket_dgram_sync(QIOChannelSocket *ioc,
256 SocketAddress *localAddr,
257 SocketAddress *remoteAddr,
258 Error **errp)
259{
260 int fd;
261
262 trace_qio_channel_socket_dgram_sync(ioc, localAddr, remoteAddr);
Paolo Bonzini150dcd12016-02-09 11:59:15 +0100263 fd = socket_dgram(remoteAddr, localAddr, errp);
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000264 if (fd < 0) {
265 trace_qio_channel_socket_dgram_fail(ioc);
266 return -1;
267 }
268
269 trace_qio_channel_socket_dgram_complete(ioc, fd);
270 if (qio_channel_socket_set_fd(ioc, fd, errp) < 0) {
271 close(fd);
272 return -1;
273 }
274
275 return 0;
276}
277
278
279struct QIOChannelSocketDGramWorkerData {
280 SocketAddress *localAddr;
281 SocketAddress *remoteAddr;
282};
283
284
285static void qio_channel_socket_dgram_worker_free(gpointer opaque)
286{
287 struct QIOChannelSocketDGramWorkerData *data = opaque;
288 qapi_free_SocketAddress(data->localAddr);
289 qapi_free_SocketAddress(data->remoteAddr);
290 g_free(data);
291}
292
Daniel P. Berrange59de5172016-08-11 17:38:07 +0100293static void qio_channel_socket_dgram_worker(QIOTask *task,
294 gpointer opaque)
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000295{
296 QIOChannelSocket *ioc = QIO_CHANNEL_SOCKET(qio_task_get_source(task));
297 struct QIOChannelSocketDGramWorkerData *data = opaque;
Daniel P. Berrange59de5172016-08-11 17:38:07 +0100298 Error *err = NULL;
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000299
300 /* socket_dgram() blocks in DNS lookups, so we must use a thread */
Daniel P. Berrange59de5172016-08-11 17:38:07 +0100301 qio_channel_socket_dgram_sync(ioc, data->localAddr,
302 data->remoteAddr, &err);
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000303
Daniel P. Berrange59de5172016-08-11 17:38:07 +0100304 qio_task_set_error(task, err);
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000305}
306
307
308void qio_channel_socket_dgram_async(QIOChannelSocket *ioc,
309 SocketAddress *localAddr,
310 SocketAddress *remoteAddr,
311 QIOTaskFunc callback,
312 gpointer opaque,
313 GDestroyNotify destroy)
314{
315 QIOTask *task = qio_task_new(
316 OBJECT(ioc), callback, opaque, destroy);
317 struct QIOChannelSocketDGramWorkerData *data = g_new0(
318 struct QIOChannelSocketDGramWorkerData, 1);
319
Eric Blake37f9e0a2016-06-09 10:48:45 -0600320 data->localAddr = QAPI_CLONE(SocketAddress, localAddr);
321 data->remoteAddr = QAPI_CLONE(SocketAddress, remoteAddr);
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000322
323 trace_qio_channel_socket_dgram_async(ioc, localAddr, remoteAddr);
324 qio_task_run_in_thread(task,
325 qio_channel_socket_dgram_worker,
326 data,
Peter Xua17536c2018-03-05 14:43:22 +0800327 qio_channel_socket_dgram_worker_free,
328 NULL);
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000329}
330
331
332QIOChannelSocket *
333qio_channel_socket_accept(QIOChannelSocket *ioc,
334 Error **errp)
335{
336 QIOChannelSocket *cioc;
337
Wang guang0e5d6322017-04-03 12:05:21 +0100338 cioc = qio_channel_socket_new();
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000339 cioc->remoteAddrLen = sizeof(ioc->remoteAddr);
340 cioc->localAddrLen = sizeof(ioc->localAddr);
341
342 retry:
343 trace_qio_channel_socket_accept(ioc);
Daniel P. Berrangede7971f2016-03-10 17:07:27 +0000344 cioc->fd = qemu_accept(ioc->fd, (struct sockaddr *)&cioc->remoteAddr,
345 &cioc->remoteAddrLen);
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000346 if (cioc->fd < 0) {
Daniel P. Berrangeb16a44e2016-03-07 20:36:03 +0000347 if (errno == EINTR) {
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000348 goto retry;
349 }
Peter Xu8bd9c4e2017-08-02 17:41:20 +0800350 error_setg_errno(errp, errno, "Unable to accept connection");
351 trace_qio_channel_socket_accept_fail(ioc);
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000352 goto error;
353 }
354
Daniel P. Berrangebead5992015-12-21 12:04:21 +0000355 if (getsockname(cioc->fd, (struct sockaddr *)&cioc->localAddr,
356 &cioc->localAddrLen) < 0) {
Daniel P. Berrangeb16a44e2016-03-07 20:36:03 +0000357 error_setg_errno(errp, errno,
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000358 "Unable to query local socket address");
359 goto error;
360 }
361
Daniel P. Berrangebead5992015-12-21 12:04:21 +0000362#ifndef WIN32
363 if (cioc->localAddr.ss_family == AF_UNIX) {
Felipe Franciosid8d3c7c2016-09-29 08:52:37 -0700364 QIOChannel *ioc_local = QIO_CHANNEL(cioc);
365 qio_channel_set_feature(ioc_local, QIO_CHANNEL_FEATURE_FD_PASS);
Daniel P. Berrangebead5992015-12-21 12:04:21 +0000366 }
367#endif /* WIN32 */
368
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000369 trace_qio_channel_socket_accept_complete(ioc, cioc, cioc->fd);
370 return cioc;
371
372 error:
373 object_unref(OBJECT(cioc));
374 return NULL;
375}
376
377static void qio_channel_socket_init(Object *obj)
378{
379 QIOChannelSocket *ioc = QIO_CHANNEL_SOCKET(obj);
380 ioc->fd = -1;
381}
382
383static void qio_channel_socket_finalize(Object *obj)
384{
385 QIOChannelSocket *ioc = QIO_CHANNEL_SOCKET(obj);
Marc-André Lureau74b6ce42016-06-16 21:28:52 +0200386
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000387 if (ioc->fd != -1) {
Felipe Franciosie413ae02016-09-29 08:52:36 -0700388 QIOChannel *ioc_local = QIO_CHANNEL(ioc);
389 if (qio_channel_has_feature(ioc_local, QIO_CHANNEL_FEATURE_LISTEN)) {
Marc-André Lureau74b6ce42016-06-16 21:28:52 +0200390 Error *err = NULL;
391
392 socket_listen_cleanup(ioc->fd, &err);
393 if (err) {
394 error_report_err(err);
395 err = NULL;
396 }
397 }
Paolo Bonzinia5897202016-03-07 12:12:36 +0100398#ifdef WIN32
399 WSAEventSelect(ioc->fd, NULL, 0);
400#endif
401 closesocket(ioc->fd);
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000402 ioc->fd = -1;
403 }
404}
405
406
407#ifndef WIN32
408static void qio_channel_socket_copy_fds(struct msghdr *msg,
409 int **fds, size_t *nfds)
410{
411 struct cmsghdr *cmsg;
412
413 *nfds = 0;
414 *fds = NULL;
415
416 for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
417 int fd_size, i;
418 int gotfds;
419
420 if (cmsg->cmsg_len < CMSG_LEN(sizeof(int)) ||
421 cmsg->cmsg_level != SOL_SOCKET ||
422 cmsg->cmsg_type != SCM_RIGHTS) {
423 continue;
424 }
425
426 fd_size = cmsg->cmsg_len - CMSG_LEN(0);
427
428 if (!fd_size) {
429 continue;
430 }
431
432 gotfds = fd_size / sizeof(int);
433 *fds = g_renew(int, *fds, *nfds + gotfds);
434 memcpy(*fds + *nfds, CMSG_DATA(cmsg), fd_size);
435
436 for (i = 0; i < gotfds; i++) {
437 int fd = (*fds)[*nfds + i];
438 if (fd < 0) {
439 continue;
440 }
441
442 /* O_NONBLOCK is preserved across SCM_RIGHTS so reset it */
443 qemu_set_block(fd);
444
445#ifndef MSG_CMSG_CLOEXEC
446 qemu_set_cloexec(fd);
447#endif
448 }
449 *nfds += gotfds;
450 }
451}
452
453
454static ssize_t qio_channel_socket_readv(QIOChannel *ioc,
455 const struct iovec *iov,
456 size_t niov,
457 int **fds,
458 size_t *nfds,
459 Error **errp)
460{
461 QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
462 ssize_t ret;
463 struct msghdr msg = { NULL, };
464 char control[CMSG_SPACE(sizeof(int) * SOCKET_MAX_FDS)];
465 int sflags = 0;
466
Daniel P. Berrangeccf1e2d2016-01-18 10:37:21 +0000467 memset(control, 0, CMSG_SPACE(sizeof(int) * SOCKET_MAX_FDS));
468
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000469#ifdef MSG_CMSG_CLOEXEC
470 sflags |= MSG_CMSG_CLOEXEC;
471#endif
472
473 msg.msg_iov = (struct iovec *)iov;
474 msg.msg_iovlen = niov;
475 if (fds && nfds) {
476 msg.msg_control = control;
477 msg.msg_controllen = sizeof(control);
478 }
479
480 retry:
481 ret = recvmsg(sioc->fd, &msg, sflags);
482 if (ret < 0) {
Daniel P. Berrangeb16a44e2016-03-07 20:36:03 +0000483 if (errno == EAGAIN) {
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000484 return QIO_CHANNEL_ERR_BLOCK;
485 }
Daniel P. Berrangeb16a44e2016-03-07 20:36:03 +0000486 if (errno == EINTR) {
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000487 goto retry;
488 }
489
Daniel P. Berrangeb16a44e2016-03-07 20:36:03 +0000490 error_setg_errno(errp, errno,
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000491 "Unable to read from socket");
492 return -1;
493 }
494
495 if (fds && nfds) {
496 qio_channel_socket_copy_fds(&msg, fds, nfds);
497 }
498
499 return ret;
500}
501
502static ssize_t qio_channel_socket_writev(QIOChannel *ioc,
503 const struct iovec *iov,
504 size_t niov,
505 int *fds,
506 size_t nfds,
507 Error **errp)
508{
509 QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
510 ssize_t ret;
511 struct msghdr msg = { NULL, };
Daniel P. Berrangeccf1e2d2016-01-18 10:37:21 +0000512 char control[CMSG_SPACE(sizeof(int) * SOCKET_MAX_FDS)];
Daniel P. Berrange7b3c6182015-12-21 11:58:51 +0000513 size_t fdsize = sizeof(int) * nfds;
514 struct cmsghdr *cmsg;
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000515
Daniel P. Berrangeccf1e2d2016-01-18 10:37:21 +0000516 memset(control, 0, CMSG_SPACE(sizeof(int) * SOCKET_MAX_FDS));
517
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000518 msg.msg_iov = (struct iovec *)iov;
519 msg.msg_iovlen = niov;
520
521 if (nfds) {
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000522 if (nfds > SOCKET_MAX_FDS) {
Daniel P. Berrangecc75a502016-01-11 12:59:44 +0000523 error_setg_errno(errp, EINVAL,
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000524 "Only %d FDs can be sent, got %zu",
525 SOCKET_MAX_FDS, nfds);
526 return -1;
527 }
528
529 msg.msg_control = control;
530 msg.msg_controllen = CMSG_SPACE(sizeof(int) * nfds);
531
532 cmsg = CMSG_FIRSTHDR(&msg);
533 cmsg->cmsg_len = CMSG_LEN(fdsize);
534 cmsg->cmsg_level = SOL_SOCKET;
535 cmsg->cmsg_type = SCM_RIGHTS;
536 memcpy(CMSG_DATA(cmsg), fds, fdsize);
537 }
538
539 retry:
540 ret = sendmsg(sioc->fd, &msg, 0);
541 if (ret <= 0) {
Daniel P. Berrangeb16a44e2016-03-07 20:36:03 +0000542 if (errno == EAGAIN) {
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000543 return QIO_CHANNEL_ERR_BLOCK;
544 }
Daniel P. Berrangeb16a44e2016-03-07 20:36:03 +0000545 if (errno == EINTR) {
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000546 goto retry;
547 }
Daniel P. Berrangeb16a44e2016-03-07 20:36:03 +0000548 error_setg_errno(errp, errno,
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000549 "Unable to write to socket");
550 return -1;
551 }
552 return ret;
553}
554#else /* WIN32 */
555static ssize_t qio_channel_socket_readv(QIOChannel *ioc,
556 const struct iovec *iov,
557 size_t niov,
558 int **fds,
559 size_t *nfds,
560 Error **errp)
561{
562 QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
563 ssize_t done = 0;
564 ssize_t i;
565
566 for (i = 0; i < niov; i++) {
567 ssize_t ret;
568 retry:
569 ret = recv(sioc->fd,
570 iov[i].iov_base,
571 iov[i].iov_len,
572 0);
573 if (ret < 0) {
Daniel P. Berrangeb16a44e2016-03-07 20:36:03 +0000574 if (errno == EAGAIN) {
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000575 if (done) {
576 return done;
577 } else {
578 return QIO_CHANNEL_ERR_BLOCK;
579 }
Daniel P. Berrangeb16a44e2016-03-07 20:36:03 +0000580 } else if (errno == EINTR) {
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000581 goto retry;
582 } else {
Daniel P. Berrangeb16a44e2016-03-07 20:36:03 +0000583 error_setg_errno(errp, errno,
Daniel P. Berrange5151d232016-03-08 12:06:30 +0000584 "Unable to read from socket");
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000585 return -1;
586 }
587 }
588 done += ret;
589 if (ret < iov[i].iov_len) {
590 return done;
591 }
592 }
593
594 return done;
595}
596
597static ssize_t qio_channel_socket_writev(QIOChannel *ioc,
598 const struct iovec *iov,
599 size_t niov,
600 int *fds,
601 size_t nfds,
602 Error **errp)
603{
604 QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
605 ssize_t done = 0;
606 ssize_t i;
607
608 for (i = 0; i < niov; i++) {
609 ssize_t ret;
610 retry:
611 ret = send(sioc->fd,
612 iov[i].iov_base,
613 iov[i].iov_len,
614 0);
615 if (ret < 0) {
Daniel P. Berrangeb16a44e2016-03-07 20:36:03 +0000616 if (errno == EAGAIN) {
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000617 if (done) {
618 return done;
619 } else {
620 return QIO_CHANNEL_ERR_BLOCK;
621 }
Daniel P. Berrangeb16a44e2016-03-07 20:36:03 +0000622 } else if (errno == EINTR) {
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000623 goto retry;
624 } else {
Daniel P. Berrangeb16a44e2016-03-07 20:36:03 +0000625 error_setg_errno(errp, errno,
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000626 "Unable to write to socket");
627 return -1;
628 }
629 }
630 done += ret;
631 if (ret < iov[i].iov_len) {
632 return done;
633 }
634 }
635
636 return done;
637}
638#endif /* WIN32 */
639
640static int
641qio_channel_socket_set_blocking(QIOChannel *ioc,
642 bool enabled,
643 Error **errp)
644{
645 QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
646
647 if (enabled) {
648 qemu_set_block(sioc->fd);
649 } else {
650 qemu_set_nonblock(sioc->fd);
651 }
652 return 0;
653}
654
655
656static void
657qio_channel_socket_set_delay(QIOChannel *ioc,
658 bool enabled)
659{
660 QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
661 int v = enabled ? 0 : 1;
662
663 qemu_setsockopt(sioc->fd,
664 IPPROTO_TCP, TCP_NODELAY,
665 &v, sizeof(v));
666}
667
668
669static void
670qio_channel_socket_set_cork(QIOChannel *ioc,
671 bool enabled)
672{
673 QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
674 int v = enabled ? 1 : 0;
675
676 socket_set_cork(sioc->fd, v);
677}
678
679
680static int
681qio_channel_socket_close(QIOChannel *ioc,
682 Error **errp)
683{
684 QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
685
Paolo Bonzinia5897202016-03-07 12:12:36 +0100686 if (sioc->fd != -1) {
687#ifdef WIN32
688 WSAEventSelect(sioc->fd, NULL, 0);
689#endif
690 if (closesocket(sioc->fd) < 0) {
691 sioc->fd = -1;
Daniel P. Berrangeb16a44e2016-03-07 20:36:03 +0000692 error_setg_errno(errp, errno,
Paolo Bonzinia5897202016-03-07 12:12:36 +0100693 "Unable to close socket");
694 return -1;
695 }
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000696 sioc->fd = -1;
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000697 }
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000698 return 0;
699}
700
701static int
702qio_channel_socket_shutdown(QIOChannel *ioc,
703 QIOChannelShutdown how,
704 Error **errp)
705{
706 QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
707 int sockhow;
708
709 switch (how) {
710 case QIO_CHANNEL_SHUTDOWN_READ:
711 sockhow = SHUT_RD;
712 break;
713 case QIO_CHANNEL_SHUTDOWN_WRITE:
714 sockhow = SHUT_WR;
715 break;
716 case QIO_CHANNEL_SHUTDOWN_BOTH:
717 default:
718 sockhow = SHUT_RDWR;
719 break;
720 }
721
722 if (shutdown(sioc->fd, sockhow) < 0) {
Daniel P. Berrangeb16a44e2016-03-07 20:36:03 +0000723 error_setg_errno(errp, errno,
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000724 "Unable to shutdown socket");
725 return -1;
726 }
727 return 0;
728}
729
Paolo Bonzinibf88c122017-02-13 14:52:22 +0100730static void qio_channel_socket_set_aio_fd_handler(QIOChannel *ioc,
731 AioContext *ctx,
732 IOHandler *io_read,
733 IOHandler *io_write,
734 void *opaque)
735{
736 QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
737 aio_set_fd_handler(ctx, sioc->fd, false, io_read, io_write, NULL, opaque);
738}
739
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000740static GSource *qio_channel_socket_create_watch(QIOChannel *ioc,
741 GIOCondition condition)
742{
743 QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
Paolo Bonzinib83b68a2016-03-07 11:16:39 +0100744 return qio_channel_create_socket_watch(ioc,
745 sioc->fd,
746 condition);
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000747}
748
749static void qio_channel_socket_class_init(ObjectClass *klass,
750 void *class_data G_GNUC_UNUSED)
751{
752 QIOChannelClass *ioc_klass = QIO_CHANNEL_CLASS(klass);
753
754 ioc_klass->io_writev = qio_channel_socket_writev;
755 ioc_klass->io_readv = qio_channel_socket_readv;
756 ioc_klass->io_set_blocking = qio_channel_socket_set_blocking;
757 ioc_klass->io_close = qio_channel_socket_close;
758 ioc_klass->io_shutdown = qio_channel_socket_shutdown;
759 ioc_klass->io_set_cork = qio_channel_socket_set_cork;
760 ioc_klass->io_set_delay = qio_channel_socket_set_delay;
761 ioc_klass->io_create_watch = qio_channel_socket_create_watch;
Paolo Bonzinibf88c122017-02-13 14:52:22 +0100762 ioc_klass->io_set_aio_fd_handler = qio_channel_socket_set_aio_fd_handler;
Daniel P. Berrange559607e2015-02-27 16:19:33 +0000763}
764
765static const TypeInfo qio_channel_socket_info = {
766 .parent = TYPE_QIO_CHANNEL,
767 .name = TYPE_QIO_CHANNEL_SOCKET,
768 .instance_size = sizeof(QIOChannelSocket),
769 .instance_init = qio_channel_socket_init,
770 .instance_finalize = qio_channel_socket_finalize,
771 .class_init = qio_channel_socket_class_init,
772};
773
774static void qio_channel_socket_register_types(void)
775{
776 type_register_static(&qio_channel_socket_info);
777}
778
779type_init(qio_channel_socket_register_types);