]> Git Repo - qemu.git/blob - chardev/char-socket.c
chardev: update net listener gcontext
[qemu.git] / chardev / char-socket.c
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
25 #include "qemu/osdep.h"
26 #include "chardev/char.h"
27 #include "io/channel-socket.h"
28 #include "io/channel-tls.h"
29 #include "io/net-listener.h"
30 #include "qemu/error-report.h"
31 #include "qemu/option.h"
32 #include "qapi/error.h"
33 #include "qapi/clone-visitor.h"
34 #include "qapi/qapi-visit-sockets.h"
35
36 #include "chardev/char-io.h"
37
38 /***********************************************************/
39 /* TCP Net console */
40
41 #define TCP_MAX_FDS 16
42
43 typedef struct {
44     Chardev parent;
45     QIOChannel *ioc; /* Client I/O channel */
46     QIOChannelSocket *sioc; /* Client master channel */
47     QIONetListener *listener;
48     GSource *hup_source;
49     QCryptoTLSCreds *tls_creds;
50     int connected;
51     int max_size;
52     int do_telnetopt;
53     int do_nodelay;
54     int *read_msgfds;
55     size_t read_msgfds_num;
56     int *write_msgfds;
57     size_t write_msgfds_num;
58
59     SocketAddress *addr;
60     bool is_listen;
61     bool is_telnet;
62     bool is_tn3270;
63
64     GSource *reconnect_timer;
65     int64_t reconnect_time;
66     bool connect_err_reported;
67 } SocketChardev;
68
69 #define SOCKET_CHARDEV(obj)                                     \
70     OBJECT_CHECK(SocketChardev, (obj), TYPE_CHARDEV_SOCKET)
71
72 static gboolean socket_reconnect_timeout(gpointer opaque);
73
74 static void tcp_chr_reconn_timer_cancel(SocketChardev *s)
75 {
76     if (s->reconnect_timer) {
77         g_source_destroy(s->reconnect_timer);
78         g_source_unref(s->reconnect_timer);
79         s->reconnect_timer = NULL;
80     }
81 }
82
83 static void qemu_chr_socket_restart_timer(Chardev *chr)
84 {
85     SocketChardev *s = SOCKET_CHARDEV(chr);
86     char *name;
87
88     assert(s->connected == 0);
89     name = g_strdup_printf("chardev-socket-reconnect-%s", chr->label);
90     s->reconnect_timer = qemu_chr_timeout_add_ms(chr,
91                                                  s->reconnect_time * 1000,
92                                                  socket_reconnect_timeout,
93                                                  chr);
94     g_source_set_name(s->reconnect_timer, name);
95     g_free(name);
96 }
97
98 static void check_report_connect_error(Chardev *chr,
99                                        Error *err)
100 {
101     SocketChardev *s = SOCKET_CHARDEV(chr);
102
103     if (!s->connect_err_reported) {
104         error_report("Unable to connect character device %s: %s",
105                      chr->label, error_get_pretty(err));
106         s->connect_err_reported = true;
107     }
108     qemu_chr_socket_restart_timer(chr);
109 }
110
111 static void tcp_chr_accept(QIONetListener *listener,
112                            QIOChannelSocket *cioc,
113                            void *opaque);
114
115 static int tcp_chr_read_poll(void *opaque);
116 static void tcp_chr_disconnect(Chardev *chr);
117
118 /* Called with chr_write_lock held.  */
119 static int tcp_chr_write(Chardev *chr, const uint8_t *buf, int len)
120 {
121     SocketChardev *s = SOCKET_CHARDEV(chr);
122
123     if (s->connected) {
124         int ret =  io_channel_send_full(s->ioc, buf, len,
125                                         s->write_msgfds,
126                                         s->write_msgfds_num);
127
128         /* free the written msgfds, no matter what */
129         if (s->write_msgfds_num) {
130             g_free(s->write_msgfds);
131             s->write_msgfds = 0;
132             s->write_msgfds_num = 0;
133         }
134
135         if (ret < 0 && errno != EAGAIN) {
136             if (tcp_chr_read_poll(chr) <= 0) {
137                 tcp_chr_disconnect(chr);
138                 return len;
139             } /* else let the read handler finish it properly */
140         }
141
142         return ret;
143     } else {
144         /* XXX: indicate an error ? */
145         return len;
146     }
147 }
148
149 static int tcp_chr_read_poll(void *opaque)
150 {
151     Chardev *chr = CHARDEV(opaque);
152     SocketChardev *s = SOCKET_CHARDEV(opaque);
153     if (!s->connected) {
154         return 0;
155     }
156     s->max_size = qemu_chr_be_can_write(chr);
157     return s->max_size;
158 }
159
160 static void tcp_chr_process_IAC_bytes(Chardev *chr,
161                                       SocketChardev *s,
162                                       uint8_t *buf, int *size)
163 {
164     /* Handle any telnet or tn3270 client's basic IAC options.
165      * For telnet options, it satisfies char by char mode with no echo.
166      * For tn3270 options, it satisfies binary mode with EOR.
167      * All IAC options will be removed from the buf and the do_opt
168      * pointer will be used to track the state of the width of the
169      * IAC information.
170      *
171      * RFC854: "All TELNET commands consist of at least a two byte sequence.
172      * The commands dealing with option negotiation are three byte sequences,
173      * the third byte being the code for the option referenced."
174      * "IAC BREAK", "IAC IP", "IAC NOP" and the double IAC are two bytes.
175      * "IAC SB", "IAC SE" and "IAC EOR" are saved to split up data boundary
176      * for tn3270.
177      * NOP, Break and Interrupt Process(IP) might be encountered during a TN3270
178      * session, and NOP and IP need to be done later.
179      */
180
181     int i;
182     int j = 0;
183
184     for (i = 0; i < *size; i++) {
185         if (s->do_telnetopt > 1) {
186             if ((unsigned char)buf[i] == IAC && s->do_telnetopt == 2) {
187                 /* Double IAC means send an IAC */
188                 if (j != i) {
189                     buf[j] = buf[i];
190                 }
191                 j++;
192                 s->do_telnetopt = 1;
193             } else {
194                 if ((unsigned char)buf[i] == IAC_BREAK
195                     && s->do_telnetopt == 2) {
196                     /* Handle IAC break commands by sending a serial break */
197                     qemu_chr_be_event(chr, CHR_EVENT_BREAK);
198                     s->do_telnetopt++;
199                 } else if (s->is_tn3270 && ((unsigned char)buf[i] == IAC_EOR
200                            || (unsigned char)buf[i] == IAC_SB
201                            || (unsigned char)buf[i] == IAC_SE)
202                            && s->do_telnetopt == 2) {
203                     buf[j++] = IAC;
204                     buf[j++] = buf[i];
205                     s->do_telnetopt++;
206                 } else if (s->is_tn3270 && ((unsigned char)buf[i] == IAC_IP
207                            || (unsigned char)buf[i] == IAC_NOP)
208                            && s->do_telnetopt == 2) {
209                     /* TODO: IP and NOP need to be implemented later. */
210                     s->do_telnetopt++;
211                 }
212                 s->do_telnetopt++;
213             }
214             if (s->do_telnetopt >= 4) {
215                 s->do_telnetopt = 1;
216             }
217         } else {
218             if ((unsigned char)buf[i] == IAC) {
219                 s->do_telnetopt = 2;
220             } else {
221                 if (j != i) {
222                     buf[j] = buf[i];
223                 }
224                 j++;
225             }
226         }
227     }
228     *size = j;
229 }
230
231 static int tcp_get_msgfds(Chardev *chr, int *fds, int num)
232 {
233     SocketChardev *s = SOCKET_CHARDEV(chr);
234
235     int to_copy = (s->read_msgfds_num < num) ? s->read_msgfds_num : num;
236
237     assert(num <= TCP_MAX_FDS);
238
239     if (to_copy) {
240         int i;
241
242         memcpy(fds, s->read_msgfds, to_copy * sizeof(int));
243
244         /* Close unused fds */
245         for (i = to_copy; i < s->read_msgfds_num; i++) {
246             close(s->read_msgfds[i]);
247         }
248
249         g_free(s->read_msgfds);
250         s->read_msgfds = 0;
251         s->read_msgfds_num = 0;
252     }
253
254     return to_copy;
255 }
256
257 static int tcp_set_msgfds(Chardev *chr, int *fds, int num)
258 {
259     SocketChardev *s = SOCKET_CHARDEV(chr);
260
261     /* clear old pending fd array */
262     g_free(s->write_msgfds);
263     s->write_msgfds = NULL;
264     s->write_msgfds_num = 0;
265
266     if (!s->connected ||
267         !qio_channel_has_feature(s->ioc,
268                                  QIO_CHANNEL_FEATURE_FD_PASS)) {
269         return -1;
270     }
271
272     if (num) {
273         s->write_msgfds = g_new(int, num);
274         memcpy(s->write_msgfds, fds, num * sizeof(int));
275     }
276
277     s->write_msgfds_num = num;
278
279     return 0;
280 }
281
282 static ssize_t tcp_chr_recv(Chardev *chr, char *buf, size_t len)
283 {
284     SocketChardev *s = SOCKET_CHARDEV(chr);
285     struct iovec iov = { .iov_base = buf, .iov_len = len };
286     int ret;
287     size_t i;
288     int *msgfds = NULL;
289     size_t msgfds_num = 0;
290
291     if (qio_channel_has_feature(s->ioc, QIO_CHANNEL_FEATURE_FD_PASS)) {
292         ret = qio_channel_readv_full(s->ioc, &iov, 1,
293                                      &msgfds, &msgfds_num,
294                                      NULL);
295     } else {
296         ret = qio_channel_readv_full(s->ioc, &iov, 1,
297                                      NULL, NULL,
298                                      NULL);
299     }
300
301     if (ret == QIO_CHANNEL_ERR_BLOCK) {
302         errno = EAGAIN;
303         ret = -1;
304     } else if (ret == -1) {
305         errno = EIO;
306     }
307
308     if (msgfds_num) {
309         /* close and clean read_msgfds */
310         for (i = 0; i < s->read_msgfds_num; i++) {
311             close(s->read_msgfds[i]);
312         }
313
314         if (s->read_msgfds_num) {
315             g_free(s->read_msgfds);
316         }
317
318         s->read_msgfds = msgfds;
319         s->read_msgfds_num = msgfds_num;
320     }
321
322     for (i = 0; i < s->read_msgfds_num; i++) {
323         int fd = s->read_msgfds[i];
324         if (fd < 0) {
325             continue;
326         }
327
328         /* O_NONBLOCK is preserved across SCM_RIGHTS so reset it */
329         qemu_set_block(fd);
330
331 #ifndef MSG_CMSG_CLOEXEC
332         qemu_set_cloexec(fd);
333 #endif
334     }
335
336     return ret;
337 }
338
339 static GSource *tcp_chr_add_watch(Chardev *chr, GIOCondition cond)
340 {
341     SocketChardev *s = SOCKET_CHARDEV(chr);
342     return qio_channel_create_watch(s->ioc, cond);
343 }
344
345 static void tcp_chr_free_connection(Chardev *chr)
346 {
347     SocketChardev *s = SOCKET_CHARDEV(chr);
348     int i;
349
350     if (s->read_msgfds_num) {
351         for (i = 0; i < s->read_msgfds_num; i++) {
352             close(s->read_msgfds[i]);
353         }
354         g_free(s->read_msgfds);
355         s->read_msgfds = NULL;
356         s->read_msgfds_num = 0;
357     }
358
359     if (s->hup_source != NULL) {
360         g_source_destroy(s->hup_source);
361         g_source_unref(s->hup_source);
362         s->hup_source = NULL;
363     }
364
365     tcp_set_msgfds(chr, NULL, 0);
366     remove_fd_in_watch(chr);
367     object_unref(OBJECT(s->sioc));
368     s->sioc = NULL;
369     object_unref(OBJECT(s->ioc));
370     s->ioc = NULL;
371     g_free(chr->filename);
372     chr->filename = NULL;
373     s->connected = 0;
374 }
375
376 static char *SocketAddress_to_str(const char *prefix, SocketAddress *addr,
377                                   bool is_listen, bool is_telnet)
378 {
379     switch (addr->type) {
380     case SOCKET_ADDRESS_TYPE_INET:
381         return g_strdup_printf("%s%s:%s:%s%s", prefix,
382                                is_telnet ? "telnet" : "tcp",
383                                addr->u.inet.host,
384                                addr->u.inet.port,
385                                is_listen ? ",server" : "");
386         break;
387     case SOCKET_ADDRESS_TYPE_UNIX:
388         return g_strdup_printf("%sunix:%s%s", prefix,
389                                addr->u.q_unix.path,
390                                is_listen ? ",server" : "");
391         break;
392     case SOCKET_ADDRESS_TYPE_FD:
393         return g_strdup_printf("%sfd:%s%s", prefix, addr->u.fd.str,
394                                is_listen ? ",server" : "");
395         break;
396     case SOCKET_ADDRESS_TYPE_VSOCK:
397         return g_strdup_printf("%svsock:%s:%s", prefix,
398                                addr->u.vsock.cid,
399                                addr->u.vsock.port);
400     default:
401         abort();
402     }
403 }
404
405 static void update_disconnected_filename(SocketChardev *s)
406 {
407     Chardev *chr = CHARDEV(s);
408
409     g_free(chr->filename);
410     chr->filename = SocketAddress_to_str("disconnected:", s->addr,
411                                          s->is_listen, s->is_telnet);
412 }
413
414 /* NB may be called even if tcp_chr_connect has not been
415  * reached, due to TLS or telnet initialization failure,
416  * so can *not* assume s->connected == true
417  */
418 static void tcp_chr_disconnect(Chardev *chr)
419 {
420     SocketChardev *s = SOCKET_CHARDEV(chr);
421     bool emit_close = s->connected;
422
423     tcp_chr_free_connection(chr);
424
425     if (s->listener) {
426         qio_net_listener_set_client_func_full(s->listener, tcp_chr_accept,
427                                               chr, NULL, chr->gcontext);
428     }
429     update_disconnected_filename(s);
430     if (emit_close) {
431         qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
432     }
433     if (s->reconnect_time) {
434         qemu_chr_socket_restart_timer(chr);
435     }
436 }
437
438 static gboolean tcp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
439 {
440     Chardev *chr = CHARDEV(opaque);
441     SocketChardev *s = SOCKET_CHARDEV(opaque);
442     uint8_t buf[CHR_READ_BUF_LEN];
443     int len, size;
444
445     if (!s->connected || s->max_size <= 0) {
446         return TRUE;
447     }
448     len = sizeof(buf);
449     if (len > s->max_size) {
450         len = s->max_size;
451     }
452     size = tcp_chr_recv(chr, (void *)buf, len);
453     if (size == 0 || (size == -1 && errno != EAGAIN)) {
454         /* connection closed */
455         tcp_chr_disconnect(chr);
456     } else if (size > 0) {
457         if (s->do_telnetopt) {
458             tcp_chr_process_IAC_bytes(chr, s, buf, &size);
459         }
460         if (size > 0) {
461             qemu_chr_be_write(chr, buf, size);
462         }
463     }
464
465     return TRUE;
466 }
467
468 static gboolean tcp_chr_hup(QIOChannel *channel,
469                                GIOCondition cond,
470                                void *opaque)
471 {
472     Chardev *chr = CHARDEV(opaque);
473     tcp_chr_disconnect(chr);
474     return G_SOURCE_REMOVE;
475 }
476
477 static int tcp_chr_sync_read(Chardev *chr, const uint8_t *buf, int len)
478 {
479     SocketChardev *s = SOCKET_CHARDEV(chr);
480     int size;
481
482     if (!s->connected) {
483         return 0;
484     }
485
486     qio_channel_set_blocking(s->ioc, true, NULL);
487     size = tcp_chr_recv(chr, (void *) buf, len);
488     qio_channel_set_blocking(s->ioc, false, NULL);
489     if (size == 0) {
490         /* connection closed */
491         tcp_chr_disconnect(chr);
492     }
493
494     return size;
495 }
496
497 static char *sockaddr_to_str(struct sockaddr_storage *ss, socklen_t ss_len,
498                              struct sockaddr_storage *ps, socklen_t ps_len,
499                              bool is_listen, bool is_telnet)
500 {
501     char shost[NI_MAXHOST], sserv[NI_MAXSERV];
502     char phost[NI_MAXHOST], pserv[NI_MAXSERV];
503     const char *left = "", *right = "";
504
505     switch (ss->ss_family) {
506 #ifndef _WIN32
507     case AF_UNIX:
508         return g_strdup_printf("unix:%s%s",
509                                ((struct sockaddr_un *)(ss))->sun_path,
510                                is_listen ? ",server" : "");
511 #endif
512     case AF_INET6:
513         left  = "[";
514         right = "]";
515         /* fall through */
516     case AF_INET:
517         getnameinfo((struct sockaddr *) ss, ss_len, shost, sizeof(shost),
518                     sserv, sizeof(sserv), NI_NUMERICHOST | NI_NUMERICSERV);
519         getnameinfo((struct sockaddr *) ps, ps_len, phost, sizeof(phost),
520                     pserv, sizeof(pserv), NI_NUMERICHOST | NI_NUMERICSERV);
521         return g_strdup_printf("%s:%s%s%s:%s%s <-> %s%s%s:%s",
522                                is_telnet ? "telnet" : "tcp",
523                                left, shost, right, sserv,
524                                is_listen ? ",server" : "",
525                                left, phost, right, pserv);
526
527     default:
528         return g_strdup_printf("unknown");
529     }
530 }
531
532 static void tcp_chr_connect(void *opaque)
533 {
534     Chardev *chr = CHARDEV(opaque);
535     SocketChardev *s = SOCKET_CHARDEV(opaque);
536
537     g_free(chr->filename);
538     chr->filename = sockaddr_to_str(
539         &s->sioc->localAddr, s->sioc->localAddrLen,
540         &s->sioc->remoteAddr, s->sioc->remoteAddrLen,
541         s->is_listen, s->is_telnet);
542
543     s->connected = 1;
544     if (s->ioc) {
545         chr->gsource = io_add_watch_poll(chr, s->ioc,
546                                            tcp_chr_read_poll,
547                                            tcp_chr_read,
548                                            chr, chr->gcontext);
549     }
550
551     s->hup_source = qio_channel_create_watch(s->ioc, G_IO_HUP);
552     g_source_set_callback(s->hup_source, (GSourceFunc)tcp_chr_hup,
553                           chr, NULL);
554     g_source_attach(s->hup_source, chr->gcontext);
555
556     qemu_chr_be_event(chr, CHR_EVENT_OPENED);
557 }
558
559 static void tcp_chr_update_read_handler(Chardev *chr)
560 {
561     SocketChardev *s = SOCKET_CHARDEV(chr);
562
563     if (s->listener) {
564         /*
565          * It's possible that chardev context is changed in
566          * qemu_chr_be_update_read_handlers().  Reset it for QIO net
567          * listener if there is.
568          */
569         qio_net_listener_set_client_func_full(s->listener, tcp_chr_accept,
570                                               chr, NULL, chr->gcontext);
571     }
572
573     if (!s->connected) {
574         return;
575     }
576
577     remove_fd_in_watch(chr);
578     if (s->ioc) {
579         chr->gsource = io_add_watch_poll(chr, s->ioc,
580                                            tcp_chr_read_poll,
581                                            tcp_chr_read, chr,
582                                            chr->gcontext);
583     }
584 }
585
586 typedef struct {
587     Chardev *chr;
588     char buf[21];
589     size_t buflen;
590 } TCPChardevTelnetInit;
591
592 static gboolean tcp_chr_telnet_init_io(QIOChannel *ioc,
593                                        GIOCondition cond G_GNUC_UNUSED,
594                                        gpointer user_data)
595 {
596     TCPChardevTelnetInit *init = user_data;
597     ssize_t ret;
598
599     ret = qio_channel_write(ioc, init->buf, init->buflen, NULL);
600     if (ret < 0) {
601         if (ret == QIO_CHANNEL_ERR_BLOCK) {
602             ret = 0;
603         } else {
604             tcp_chr_disconnect(init->chr);
605             goto end;
606         }
607     }
608     init->buflen -= ret;
609
610     if (init->buflen == 0) {
611         tcp_chr_connect(init->chr);
612         goto end;
613     }
614
615     memmove(init->buf, init->buf + ret, init->buflen);
616
617     return G_SOURCE_CONTINUE;
618
619 end:
620     g_free(init);
621     return G_SOURCE_REMOVE;
622 }
623
624 static void tcp_chr_telnet_init(Chardev *chr)
625 {
626     SocketChardev *s = SOCKET_CHARDEV(chr);
627     TCPChardevTelnetInit *init = g_new0(TCPChardevTelnetInit, 1);
628     size_t n = 0;
629
630 #define IACSET(x, a, b, c)                      \
631     do {                                        \
632         x[n++] = a;                             \
633         x[n++] = b;                             \
634         x[n++] = c;                             \
635     } while (0)
636
637     init->chr = chr;
638     if (!s->is_tn3270) {
639         init->buflen = 12;
640         /* Prep the telnet negotion to put telnet in binary,
641          * no echo, single char mode */
642         IACSET(init->buf, 0xff, 0xfb, 0x01);  /* IAC WILL ECHO */
643         IACSET(init->buf, 0xff, 0xfb, 0x03);  /* IAC WILL Suppress go ahead */
644         IACSET(init->buf, 0xff, 0xfb, 0x00);  /* IAC WILL Binary */
645         IACSET(init->buf, 0xff, 0xfd, 0x00);  /* IAC DO Binary */
646     } else {
647         init->buflen = 21;
648         /* Prep the TN3270 negotion based on RFC1576 */
649         IACSET(init->buf, 0xff, 0xfd, 0x19);  /* IAC DO EOR */
650         IACSET(init->buf, 0xff, 0xfb, 0x19);  /* IAC WILL EOR */
651         IACSET(init->buf, 0xff, 0xfd, 0x00);  /* IAC DO BINARY */
652         IACSET(init->buf, 0xff, 0xfb, 0x00);  /* IAC WILL BINARY */
653         IACSET(init->buf, 0xff, 0xfd, 0x18);  /* IAC DO TERMINAL TYPE */
654         IACSET(init->buf, 0xff, 0xfa, 0x18);  /* IAC SB TERMINAL TYPE */
655         IACSET(init->buf, 0x01, 0xff, 0xf0);  /* SEND IAC SE */
656     }
657
658 #undef IACSET
659
660     qio_channel_add_watch(
661         s->ioc, G_IO_OUT,
662         tcp_chr_telnet_init_io,
663         init, NULL);
664 }
665
666
667 static void tcp_chr_tls_handshake(QIOTask *task,
668                                   gpointer user_data)
669 {
670     Chardev *chr = user_data;
671     SocketChardev *s = user_data;
672
673     if (qio_task_propagate_error(task, NULL)) {
674         tcp_chr_disconnect(chr);
675     } else {
676         /* tn3270 does not support TLS yet */
677         if (s->do_telnetopt && !s->is_tn3270) {
678             tcp_chr_telnet_init(chr);
679         } else {
680             tcp_chr_connect(chr);
681         }
682     }
683 }
684
685
686 static void tcp_chr_tls_init(Chardev *chr)
687 {
688     SocketChardev *s = SOCKET_CHARDEV(chr);
689     QIOChannelTLS *tioc;
690     Error *err = NULL;
691     gchar *name;
692
693     if (s->is_listen) {
694         tioc = qio_channel_tls_new_server(
695             s->ioc, s->tls_creds,
696             NULL, /* XXX Use an ACL */
697             &err);
698     } else {
699         tioc = qio_channel_tls_new_client(
700             s->ioc, s->tls_creds,
701             s->addr->u.inet.host,
702             &err);
703     }
704     if (tioc == NULL) {
705         error_free(err);
706         tcp_chr_disconnect(chr);
707         return;
708     }
709     name = g_strdup_printf("chardev-tls-%s-%s",
710                            s->is_listen ? "server" : "client",
711                            chr->label);
712     qio_channel_set_name(QIO_CHANNEL(tioc), name);
713     g_free(name);
714     object_unref(OBJECT(s->ioc));
715     s->ioc = QIO_CHANNEL(tioc);
716
717     qio_channel_tls_handshake(tioc,
718                               tcp_chr_tls_handshake,
719                               chr,
720                               NULL,
721                               NULL);
722 }
723
724
725 static void tcp_chr_set_client_ioc_name(Chardev *chr,
726                                         QIOChannelSocket *sioc)
727 {
728     SocketChardev *s = SOCKET_CHARDEV(chr);
729     char *name;
730     name = g_strdup_printf("chardev-tcp-%s-%s",
731                            s->is_listen ? "server" : "client",
732                            chr->label);
733     qio_channel_set_name(QIO_CHANNEL(sioc), name);
734     g_free(name);
735
736 }
737
738 static int tcp_chr_new_client(Chardev *chr, QIOChannelSocket *sioc)
739 {
740     SocketChardev *s = SOCKET_CHARDEV(chr);
741
742     if (s->ioc != NULL) {
743         return -1;
744     }
745
746     s->ioc = QIO_CHANNEL(sioc);
747     object_ref(OBJECT(sioc));
748     s->sioc = sioc;
749     object_ref(OBJECT(sioc));
750
751     qio_channel_set_blocking(s->ioc, false, NULL);
752
753     if (s->do_nodelay) {
754         qio_channel_set_delay(s->ioc, false);
755     }
756     if (s->listener) {
757         qio_net_listener_set_client_func_full(s->listener, NULL, NULL,
758                                               NULL, chr->gcontext);
759     }
760
761     if (s->tls_creds) {
762         tcp_chr_tls_init(chr);
763     } else {
764         if (s->do_telnetopt) {
765             tcp_chr_telnet_init(chr);
766         } else {
767             tcp_chr_connect(chr);
768         }
769     }
770
771     return 0;
772 }
773
774
775 static int tcp_chr_add_client(Chardev *chr, int fd)
776 {
777     int ret;
778     QIOChannelSocket *sioc;
779
780     sioc = qio_channel_socket_new_fd(fd, NULL);
781     if (!sioc) {
782         return -1;
783     }
784     tcp_chr_set_client_ioc_name(chr, sioc);
785     ret = tcp_chr_new_client(chr, sioc);
786     object_unref(OBJECT(sioc));
787     return ret;
788 }
789
790 static void tcp_chr_accept(QIONetListener *listener,
791                            QIOChannelSocket *cioc,
792                            void *opaque)
793 {
794     Chardev *chr = CHARDEV(opaque);
795
796     tcp_chr_set_client_ioc_name(chr, cioc);
797     tcp_chr_new_client(chr, cioc);
798 }
799
800 static int tcp_chr_wait_connected(Chardev *chr, Error **errp)
801 {
802     SocketChardev *s = SOCKET_CHARDEV(chr);
803     QIOChannelSocket *sioc;
804
805     /* It can't wait on s->connected, since it is set asynchronously
806      * in TLS and telnet cases, only wait for an accepted socket */
807     while (!s->ioc) {
808         if (s->is_listen) {
809             info_report("QEMU waiting for connection on: %s",
810                         chr->filename);
811             sioc = qio_net_listener_wait_client(s->listener);
812             tcp_chr_set_client_ioc_name(chr, sioc);
813             tcp_chr_new_client(chr, sioc);
814             object_unref(OBJECT(sioc));
815         } else {
816             sioc = qio_channel_socket_new();
817             tcp_chr_set_client_ioc_name(chr, sioc);
818             if (qio_channel_socket_connect_sync(sioc, s->addr, errp) < 0) {
819                 object_unref(OBJECT(sioc));
820                 return -1;
821             }
822             tcp_chr_new_client(chr, sioc);
823             object_unref(OBJECT(sioc));
824         }
825     }
826
827     return 0;
828 }
829
830 static void char_socket_finalize(Object *obj)
831 {
832     Chardev *chr = CHARDEV(obj);
833     SocketChardev *s = SOCKET_CHARDEV(obj);
834
835     tcp_chr_free_connection(chr);
836     tcp_chr_reconn_timer_cancel(s);
837     qapi_free_SocketAddress(s->addr);
838     if (s->listener) {
839         qio_net_listener_set_client_func_full(s->listener, NULL, NULL,
840                                               NULL, chr->gcontext);
841         object_unref(OBJECT(s->listener));
842     }
843     if (s->tls_creds) {
844         object_unref(OBJECT(s->tls_creds));
845     }
846
847     qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
848 }
849
850 static void qemu_chr_socket_connected(QIOTask *task, void *opaque)
851 {
852     QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(qio_task_get_source(task));
853     Chardev *chr = CHARDEV(opaque);
854     SocketChardev *s = SOCKET_CHARDEV(chr);
855     Error *err = NULL;
856
857     if (qio_task_propagate_error(task, &err)) {
858         check_report_connect_error(chr, err);
859         error_free(err);
860         goto cleanup;
861     }
862
863     s->connect_err_reported = false;
864     tcp_chr_new_client(chr, sioc);
865
866 cleanup:
867     object_unref(OBJECT(sioc));
868 }
869
870 static gboolean socket_reconnect_timeout(gpointer opaque)
871 {
872     Chardev *chr = CHARDEV(opaque);
873     SocketChardev *s = SOCKET_CHARDEV(opaque);
874     QIOChannelSocket *sioc;
875
876     g_source_unref(s->reconnect_timer);
877     s->reconnect_timer = NULL;
878
879     if (chr->be_open) {
880         return false;
881     }
882
883     sioc = qio_channel_socket_new();
884     tcp_chr_set_client_ioc_name(chr, sioc);
885     qio_channel_socket_connect_async(sioc, s->addr,
886                                      qemu_chr_socket_connected,
887                                      chr, NULL, NULL);
888
889     return false;
890 }
891
892 static void qmp_chardev_open_socket(Chardev *chr,
893                                     ChardevBackend *backend,
894                                     bool *be_opened,
895                                     Error **errp)
896 {
897     SocketChardev *s = SOCKET_CHARDEV(chr);
898     ChardevSocket *sock = backend->u.socket.data;
899     bool do_nodelay     = sock->has_nodelay ? sock->nodelay : false;
900     bool is_listen      = sock->has_server  ? sock->server  : true;
901     bool is_telnet      = sock->has_telnet  ? sock->telnet  : false;
902     bool is_tn3270      = sock->has_tn3270  ? sock->tn3270  : false;
903     bool is_waitconnect = sock->has_wait    ? sock->wait    : false;
904     int64_t reconnect   = sock->has_reconnect ? sock->reconnect : 0;
905     QIOChannelSocket *sioc = NULL;
906     SocketAddress *addr;
907
908     s->is_listen = is_listen;
909     s->is_telnet = is_telnet;
910     s->is_tn3270 = is_tn3270;
911     s->do_nodelay = do_nodelay;
912     if (sock->tls_creds) {
913         Object *creds;
914         creds = object_resolve_path_component(
915             object_get_objects_root(), sock->tls_creds);
916         if (!creds) {
917             error_setg(errp, "No TLS credentials with id '%s'",
918                        sock->tls_creds);
919             goto error;
920         }
921         s->tls_creds = (QCryptoTLSCreds *)
922             object_dynamic_cast(creds,
923                                 TYPE_QCRYPTO_TLS_CREDS);
924         if (!s->tls_creds) {
925             error_setg(errp, "Object with id '%s' is not TLS credentials",
926                        sock->tls_creds);
927             goto error;
928         }
929         object_ref(OBJECT(s->tls_creds));
930         if (is_listen) {
931             if (s->tls_creds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
932                 error_setg(errp, "%s",
933                            "Expected TLS credentials for server endpoint");
934                 goto error;
935             }
936         } else {
937             if (s->tls_creds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT) {
938                 error_setg(errp, "%s",
939                            "Expected TLS credentials for client endpoint");
940                 goto error;
941             }
942         }
943     }
944
945     s->addr = addr = socket_address_flatten(sock->addr);
946
947     qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_RECONNECTABLE);
948     /* TODO SOCKET_ADDRESS_FD where fd has AF_UNIX */
949     if (addr->type == SOCKET_ADDRESS_TYPE_UNIX) {
950         qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_FD_PASS);
951     }
952
953     /* be isn't opened until we get a connection */
954     *be_opened = false;
955
956     update_disconnected_filename(s);
957
958     if (is_listen) {
959         if (is_telnet || is_tn3270) {
960             s->do_telnetopt = 1;
961         }
962     } else if (reconnect > 0) {
963         s->reconnect_time = reconnect;
964     }
965
966     if (s->reconnect_time) {
967         sioc = qio_channel_socket_new();
968         tcp_chr_set_client_ioc_name(chr, sioc);
969         qio_channel_socket_connect_async(sioc, s->addr,
970                                          qemu_chr_socket_connected,
971                                          chr, NULL, NULL);
972     } else {
973         if (s->is_listen) {
974             char *name;
975             s->listener = qio_net_listener_new();
976
977             name = g_strdup_printf("chardev-tcp-listener-%s", chr->label);
978             qio_net_listener_set_name(s->listener, name);
979             g_free(name);
980
981             if (qio_net_listener_open_sync(s->listener, s->addr, errp) < 0) {
982                 object_unref(OBJECT(s->listener));
983                 s->listener = NULL;
984                 goto error;
985             }
986
987             qapi_free_SocketAddress(s->addr);
988             s->addr = socket_local_address(s->listener->sioc[0]->fd, errp);
989             update_disconnected_filename(s);
990
991             if (is_waitconnect &&
992                 qemu_chr_wait_connected(chr, errp) < 0) {
993                 return;
994             }
995             if (!s->ioc) {
996                 qio_net_listener_set_client_func_full(s->listener,
997                                                       tcp_chr_accept,
998                                                       chr, NULL,
999                                                       chr->gcontext);
1000             }
1001         } else if (qemu_chr_wait_connected(chr, errp) < 0) {
1002             goto error;
1003         }
1004     }
1005
1006     return;
1007
1008 error:
1009     if (sioc) {
1010         object_unref(OBJECT(sioc));
1011     }
1012 }
1013
1014 static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
1015                                   Error **errp)
1016 {
1017     bool is_listen      = qemu_opt_get_bool(opts, "server", false);
1018     bool is_waitconnect = is_listen && qemu_opt_get_bool(opts, "wait", true);
1019     bool is_telnet      = qemu_opt_get_bool(opts, "telnet", false);
1020     bool is_tn3270      = qemu_opt_get_bool(opts, "tn3270", false);
1021     bool do_nodelay     = !qemu_opt_get_bool(opts, "delay", true);
1022     int64_t reconnect   = qemu_opt_get_number(opts, "reconnect", 0);
1023     const char *path = qemu_opt_get(opts, "path");
1024     const char *host = qemu_opt_get(opts, "host");
1025     const char *port = qemu_opt_get(opts, "port");
1026     const char *tls_creds = qemu_opt_get(opts, "tls-creds");
1027     SocketAddressLegacy *addr;
1028     ChardevSocket *sock;
1029
1030     backend->type = CHARDEV_BACKEND_KIND_SOCKET;
1031     if (!path) {
1032         if (!host) {
1033             error_setg(errp, "chardev: socket: no host given");
1034             return;
1035         }
1036         if (!port) {
1037             error_setg(errp, "chardev: socket: no port given");
1038             return;
1039         }
1040     } else {
1041         if (tls_creds) {
1042             error_setg(errp, "TLS can only be used over TCP socket");
1043             return;
1044         }
1045     }
1046
1047     sock = backend->u.socket.data = g_new0(ChardevSocket, 1);
1048     qemu_chr_parse_common(opts, qapi_ChardevSocket_base(sock));
1049
1050     sock->has_nodelay = true;
1051     sock->nodelay = do_nodelay;
1052     sock->has_server = true;
1053     sock->server = is_listen;
1054     sock->has_telnet = true;
1055     sock->telnet = is_telnet;
1056     sock->has_tn3270 = true;
1057     sock->tn3270 = is_tn3270;
1058     sock->has_wait = true;
1059     sock->wait = is_waitconnect;
1060     sock->has_reconnect = true;
1061     sock->reconnect = reconnect;
1062     sock->tls_creds = g_strdup(tls_creds);
1063
1064     addr = g_new0(SocketAddressLegacy, 1);
1065     if (path) {
1066         UnixSocketAddress *q_unix;
1067         addr->type = SOCKET_ADDRESS_LEGACY_KIND_UNIX;
1068         q_unix = addr->u.q_unix.data = g_new0(UnixSocketAddress, 1);
1069         q_unix->path = g_strdup(path);
1070     } else {
1071         addr->type = SOCKET_ADDRESS_LEGACY_KIND_INET;
1072         addr->u.inet.data = g_new(InetSocketAddress, 1);
1073         *addr->u.inet.data = (InetSocketAddress) {
1074             .host = g_strdup(host),
1075             .port = g_strdup(port),
1076             .has_to = qemu_opt_get(opts, "to"),
1077             .to = qemu_opt_get_number(opts, "to", 0),
1078             .has_ipv4 = qemu_opt_get(opts, "ipv4"),
1079             .ipv4 = qemu_opt_get_bool(opts, "ipv4", 0),
1080             .has_ipv6 = qemu_opt_get(opts, "ipv6"),
1081             .ipv6 = qemu_opt_get_bool(opts, "ipv6", 0),
1082         };
1083     }
1084     sock->addr = addr;
1085 }
1086
1087 static void
1088 char_socket_get_addr(Object *obj, Visitor *v, const char *name,
1089                      void *opaque, Error **errp)
1090 {
1091     SocketChardev *s = SOCKET_CHARDEV(obj);
1092
1093     visit_type_SocketAddress(v, name, &s->addr, errp);
1094 }
1095
1096 static bool
1097 char_socket_get_connected(Object *obj, Error **errp)
1098 {
1099     SocketChardev *s = SOCKET_CHARDEV(obj);
1100
1101     return s->connected;
1102 }
1103
1104 static void char_socket_class_init(ObjectClass *oc, void *data)
1105 {
1106     ChardevClass *cc = CHARDEV_CLASS(oc);
1107
1108     cc->parse = qemu_chr_parse_socket;
1109     cc->open = qmp_chardev_open_socket;
1110     cc->chr_wait_connected = tcp_chr_wait_connected;
1111     cc->chr_write = tcp_chr_write;
1112     cc->chr_sync_read = tcp_chr_sync_read;
1113     cc->chr_disconnect = tcp_chr_disconnect;
1114     cc->get_msgfds = tcp_get_msgfds;
1115     cc->set_msgfds = tcp_set_msgfds;
1116     cc->chr_add_client = tcp_chr_add_client;
1117     cc->chr_add_watch = tcp_chr_add_watch;
1118     cc->chr_update_read_handler = tcp_chr_update_read_handler;
1119
1120     object_class_property_add(oc, "addr", "SocketAddress",
1121                               char_socket_get_addr, NULL,
1122                               NULL, NULL, &error_abort);
1123
1124     object_class_property_add_bool(oc, "connected", char_socket_get_connected,
1125                                    NULL, &error_abort);
1126 }
1127
1128 static const TypeInfo char_socket_type_info = {
1129     .name = TYPE_CHARDEV_SOCKET,
1130     .parent = TYPE_CHARDEV,
1131     .instance_size = sizeof(SocketChardev),
1132     .instance_finalize = char_socket_finalize,
1133     .class_init = char_socket_class_init,
1134 };
1135
1136 static void register_types(void)
1137 {
1138     type_register_static(&char_socket_type_info);
1139 }
1140
1141 type_init(register_types);
This page took 0.085282 seconds and 4 git commands to generate.