xref: /qemu/chardev/char-socket.c (revision a495eba03c31c96d6a0817b13598ce2219326691)
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-websock.h"
29  #include "qemu/error-report.h"
30  #include "qemu/module.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  #include "qemu/yank.h"
36  
37  #include "chardev/char-io.h"
38  #include "chardev/char-socket.h"
39  
40  static gboolean socket_reconnect_timeout(gpointer opaque);
41  static void tcp_chr_telnet_init(Chardev *chr);
42  
43  static void tcp_chr_change_state(SocketChardev *s, TCPChardevState state)
44  {
45      switch (state) {
46      case TCP_CHARDEV_STATE_DISCONNECTED:
47          break;
48      case TCP_CHARDEV_STATE_CONNECTING:
49          assert(s->state == TCP_CHARDEV_STATE_DISCONNECTED);
50          break;
51      case TCP_CHARDEV_STATE_CONNECTED:
52          assert(s->state == TCP_CHARDEV_STATE_CONNECTING);
53          break;
54      }
55      s->state = state;
56  }
57  
58  static void tcp_chr_reconn_timer_cancel(SocketChardev *s)
59  {
60      if (s->reconnect_timer) {
61          g_source_destroy(s->reconnect_timer);
62          g_source_unref(s->reconnect_timer);
63          s->reconnect_timer = NULL;
64      }
65  }
66  
67  static void qemu_chr_socket_restart_timer(Chardev *chr)
68  {
69      SocketChardev *s = SOCKET_CHARDEV(chr);
70      char *name;
71  
72      assert(s->state == TCP_CHARDEV_STATE_DISCONNECTED);
73      assert(!s->reconnect_timer);
74      name = g_strdup_printf("chardev-socket-reconnect-%s", chr->label);
75      s->reconnect_timer = qemu_chr_timeout_add_ms(chr,
76                                                   s->reconnect_time * 1000,
77                                                   socket_reconnect_timeout,
78                                                   chr);
79      g_source_set_name(s->reconnect_timer, name);
80      g_free(name);
81  }
82  
83  static void check_report_connect_error(Chardev *chr,
84                                         Error *err)
85  {
86      SocketChardev *s = SOCKET_CHARDEV(chr);
87  
88      if (!s->connect_err_reported) {
89          error_reportf_err(err,
90                            "Unable to connect character device %s: ",
91                            chr->label);
92          s->connect_err_reported = true;
93      } else {
94          error_free(err);
95      }
96      qemu_chr_socket_restart_timer(chr);
97  }
98  
99  static void tcp_chr_accept(QIONetListener *listener,
100                             QIOChannelSocket *cioc,
101                             void *opaque);
102  
103  static int tcp_chr_read_poll(void *opaque);
104  static void tcp_chr_disconnect_locked(Chardev *chr);
105  
106  /* Called with chr_write_lock held.  */
107  static int tcp_chr_write(Chardev *chr, const uint8_t *buf, int len)
108  {
109      SocketChardev *s = SOCKET_CHARDEV(chr);
110  
111      if (s->state == TCP_CHARDEV_STATE_CONNECTED) {
112          int ret =  io_channel_send_full(s->ioc, buf, len,
113                                          s->write_msgfds,
114                                          s->write_msgfds_num);
115  
116          /* free the written msgfds in any cases
117           * other than ret < 0 && errno == EAGAIN
118           */
119          if (!(ret < 0 && EAGAIN == errno)
120              && s->write_msgfds_num) {
121              g_free(s->write_msgfds);
122              s->write_msgfds = 0;
123              s->write_msgfds_num = 0;
124          }
125  
126          if (ret < 0 && errno != EAGAIN) {
127              if (tcp_chr_read_poll(chr) <= 0) {
128                  /* Perform disconnect and return error. */
129                  tcp_chr_disconnect_locked(chr);
130              } /* else let the read handler finish it properly */
131          }
132  
133          return ret;
134      } else {
135          /* Indicate an error. */
136          errno = EIO;
137          return -1;
138      }
139  }
140  
141  static int tcp_chr_read_poll(void *opaque)
142  {
143      Chardev *chr = CHARDEV(opaque);
144      SocketChardev *s = SOCKET_CHARDEV(opaque);
145      if (s->state != TCP_CHARDEV_STATE_CONNECTED) {
146          return 0;
147      }
148      s->max_size = qemu_chr_be_can_write(chr);
149      return s->max_size;
150  }
151  
152  static void tcp_chr_process_IAC_bytes(Chardev *chr,
153                                        SocketChardev *s,
154                                        uint8_t *buf, int *size)
155  {
156      /* Handle any telnet or tn3270 client's basic IAC options.
157       * For telnet options, it satisfies char by char mode with no echo.
158       * For tn3270 options, it satisfies binary mode with EOR.
159       * All IAC options will be removed from the buf and the do_opt
160       * pointer will be used to track the state of the width of the
161       * IAC information.
162       *
163       * RFC854: "All TELNET commands consist of at least a two byte sequence.
164       * The commands dealing with option negotiation are three byte sequences,
165       * the third byte being the code for the option referenced."
166       * "IAC BREAK", "IAC IP", "IAC NOP" and the double IAC are two bytes.
167       * "IAC SB", "IAC SE" and "IAC EOR" are saved to split up data boundary
168       * for tn3270.
169       * NOP, Break and Interrupt Process(IP) might be encountered during a TN3270
170       * session, and NOP and IP need to be done later.
171       */
172  
173      int i;
174      int j = 0;
175  
176      for (i = 0; i < *size; i++) {
177          if (s->do_telnetopt > 1) {
178              if ((unsigned char)buf[i] == IAC && s->do_telnetopt == 2) {
179                  /* Double IAC means send an IAC */
180                  if (j != i) {
181                      buf[j] = buf[i];
182                  }
183                  j++;
184                  s->do_telnetopt = 1;
185              } else {
186                  if ((unsigned char)buf[i] == IAC_BREAK
187                      && s->do_telnetopt == 2) {
188                      /* Handle IAC break commands by sending a serial break */
189                      qemu_chr_be_event(chr, CHR_EVENT_BREAK);
190                      s->do_telnetopt++;
191                  } else if (s->is_tn3270 && ((unsigned char)buf[i] == IAC_EOR
192                             || (unsigned char)buf[i] == IAC_SB
193                             || (unsigned char)buf[i] == IAC_SE)
194                             && s->do_telnetopt == 2) {
195                      buf[j++] = IAC;
196                      buf[j++] = buf[i];
197                      s->do_telnetopt++;
198                  } else if (s->is_tn3270 && ((unsigned char)buf[i] == IAC_IP
199                             || (unsigned char)buf[i] == IAC_NOP)
200                             && s->do_telnetopt == 2) {
201                      /* TODO: IP and NOP need to be implemented later. */
202                      s->do_telnetopt++;
203                  }
204                  s->do_telnetopt++;
205              }
206              if (s->do_telnetopt >= 4) {
207                  s->do_telnetopt = 1;
208              }
209          } else {
210              if ((unsigned char)buf[i] == IAC) {
211                  s->do_telnetopt = 2;
212              } else {
213                  if (j != i) {
214                      buf[j] = buf[i];
215                  }
216                  j++;
217              }
218          }
219      }
220      *size = j;
221  }
222  
223  static int tcp_get_msgfds(Chardev *chr, int *fds, int num)
224  {
225      SocketChardev *s = SOCKET_CHARDEV(chr);
226  
227      int to_copy = (s->read_msgfds_num < num) ? s->read_msgfds_num : num;
228  
229      assert(num <= TCP_MAX_FDS);
230  
231      if (to_copy) {
232          int i;
233  
234          memcpy(fds, s->read_msgfds, to_copy * sizeof(int));
235  
236          /* Close unused fds */
237          for (i = to_copy; i < s->read_msgfds_num; i++) {
238              close(s->read_msgfds[i]);
239          }
240  
241          g_free(s->read_msgfds);
242          s->read_msgfds = 0;
243          s->read_msgfds_num = 0;
244      }
245  
246      return to_copy;
247  }
248  
249  static int tcp_set_msgfds(Chardev *chr, int *fds, int num)
250  {
251      SocketChardev *s = SOCKET_CHARDEV(chr);
252  
253      /* clear old pending fd array */
254      g_free(s->write_msgfds);
255      s->write_msgfds = NULL;
256      s->write_msgfds_num = 0;
257  
258      if ((s->state != TCP_CHARDEV_STATE_CONNECTED) ||
259          !qio_channel_has_feature(s->ioc,
260                                   QIO_CHANNEL_FEATURE_FD_PASS)) {
261          return -1;
262      }
263  
264      if (num) {
265          s->write_msgfds = g_new(int, num);
266          memcpy(s->write_msgfds, fds, num * sizeof(int));
267      }
268  
269      s->write_msgfds_num = num;
270  
271      return 0;
272  }
273  
274  static ssize_t tcp_chr_recv(Chardev *chr, char *buf, size_t len)
275  {
276      SocketChardev *s = SOCKET_CHARDEV(chr);
277      struct iovec iov = { .iov_base = buf, .iov_len = len };
278      int ret;
279      size_t i;
280      int *msgfds = NULL;
281      size_t msgfds_num = 0;
282  
283      if (qio_channel_has_feature(s->ioc, QIO_CHANNEL_FEATURE_FD_PASS)) {
284          ret = qio_channel_readv_full(s->ioc, &iov, 1,
285                                       &msgfds, &msgfds_num,
286                                       NULL);
287      } else {
288          ret = qio_channel_readv_full(s->ioc, &iov, 1,
289                                       NULL, NULL,
290                                       NULL);
291      }
292  
293      if (msgfds_num) {
294          /* close and clean read_msgfds */
295          for (i = 0; i < s->read_msgfds_num; i++) {
296              close(s->read_msgfds[i]);
297          }
298  
299          if (s->read_msgfds_num) {
300              g_free(s->read_msgfds);
301          }
302  
303          s->read_msgfds = msgfds;
304          s->read_msgfds_num = msgfds_num;
305      }
306  
307      for (i = 0; i < s->read_msgfds_num; i++) {
308          int fd = s->read_msgfds[i];
309          if (fd < 0) {
310              continue;
311          }
312  
313          /* O_NONBLOCK is preserved across SCM_RIGHTS so reset it */
314          qemu_socket_set_block(fd);
315  
316  #ifndef MSG_CMSG_CLOEXEC
317          qemu_set_cloexec(fd);
318  #endif
319      }
320  
321      if (ret == QIO_CHANNEL_ERR_BLOCK) {
322          errno = EAGAIN;
323          ret = -1;
324      } else if (ret == -1) {
325          errno = EIO;
326      }
327  
328      return ret;
329  }
330  
331  static GSource *tcp_chr_add_watch(Chardev *chr, GIOCondition cond)
332  {
333      SocketChardev *s = SOCKET_CHARDEV(chr);
334      if (!s->ioc) {
335          return NULL;
336      }
337      return qio_channel_create_watch(s->ioc, cond);
338  }
339  
340  static void remove_hup_source(SocketChardev *s)
341  {
342      if (s->hup_source != NULL) {
343          g_source_destroy(s->hup_source);
344          g_source_unref(s->hup_source);
345          s->hup_source = NULL;
346      }
347  }
348  
349  static void char_socket_yank_iochannel(void *opaque)
350  {
351      QIOChannel *ioc = QIO_CHANNEL(opaque);
352  
353      qio_channel_shutdown(ioc, QIO_CHANNEL_SHUTDOWN_BOTH, NULL);
354  }
355  
356  static void tcp_chr_free_connection(Chardev *chr)
357  {
358      SocketChardev *s = SOCKET_CHARDEV(chr);
359      int i;
360  
361      if (s->read_msgfds_num) {
362          for (i = 0; i < s->read_msgfds_num; i++) {
363              close(s->read_msgfds[i]);
364          }
365          g_free(s->read_msgfds);
366          s->read_msgfds = NULL;
367          s->read_msgfds_num = 0;
368      }
369  
370      remove_hup_source(s);
371  
372      tcp_set_msgfds(chr, NULL, 0);
373      remove_fd_in_watch(chr);
374      if (s->registered_yank &&
375          (s->state == TCP_CHARDEV_STATE_CONNECTING
376          || s->state == TCP_CHARDEV_STATE_CONNECTED)) {
377          yank_unregister_function(CHARDEV_YANK_INSTANCE(chr->label),
378                                   char_socket_yank_iochannel,
379                                   QIO_CHANNEL(s->sioc));
380      }
381      object_unref(OBJECT(s->sioc));
382      s->sioc = NULL;
383      object_unref(OBJECT(s->ioc));
384      s->ioc = NULL;
385      g_free(chr->filename);
386      chr->filename = NULL;
387      tcp_chr_change_state(s, TCP_CHARDEV_STATE_DISCONNECTED);
388  }
389  
390  static const char *qemu_chr_socket_protocol(SocketChardev *s)
391  {
392      if (s->is_telnet) {
393          return "telnet";
394      }
395      return s->is_websock ? "websocket" : "tcp";
396  }
397  
398  static char *qemu_chr_socket_address(SocketChardev *s, const char *prefix)
399  {
400      switch (s->addr->type) {
401      case SOCKET_ADDRESS_TYPE_INET:
402          return g_strdup_printf("%s%s:%s:%s%s", prefix,
403                                 qemu_chr_socket_protocol(s),
404                                 s->addr->u.inet.host,
405                                 s->addr->u.inet.port,
406                                 s->is_listen ? ",server=on" : "");
407          break;
408      case SOCKET_ADDRESS_TYPE_UNIX:
409      {
410          const char *tight = "", *abstract = "";
411          UnixSocketAddress *sa = &s->addr->u.q_unix;
412  
413  #ifdef CONFIG_LINUX
414          if (sa->has_abstract && sa->abstract) {
415              abstract = ",abstract=on";
416              if (sa->has_tight && sa->tight) {
417                  tight = ",tight=on";
418              }
419          }
420  #endif
421  
422          return g_strdup_printf("%sunix:%s%s%s%s", prefix, sa->path,
423                                 abstract, tight,
424                                 s->is_listen ? ",server=on" : "");
425          break;
426      }
427      case SOCKET_ADDRESS_TYPE_FD:
428          return g_strdup_printf("%sfd:%s%s", prefix, s->addr->u.fd.str,
429                                 s->is_listen ? ",server=on" : "");
430          break;
431      case SOCKET_ADDRESS_TYPE_VSOCK:
432          return g_strdup_printf("%svsock:%s:%s", prefix,
433                                 s->addr->u.vsock.cid,
434                                 s->addr->u.vsock.port);
435      default:
436          abort();
437      }
438  }
439  
440  static void update_disconnected_filename(SocketChardev *s)
441  {
442      Chardev *chr = CHARDEV(s);
443  
444      g_free(chr->filename);
445      if (s->addr) {
446          chr->filename = qemu_chr_socket_address(s, "disconnected:");
447      } else {
448          chr->filename = g_strdup("disconnected:socket");
449      }
450  }
451  
452  /* NB may be called even if tcp_chr_connect has not been
453   * reached, due to TLS or telnet initialization failure,
454   * so can *not* assume s->state == TCP_CHARDEV_STATE_CONNECTED
455   * This must be called with chr->chr_write_lock held.
456   */
457  static void tcp_chr_disconnect_locked(Chardev *chr)
458  {
459      SocketChardev *s = SOCKET_CHARDEV(chr);
460      bool emit_close = s->state == TCP_CHARDEV_STATE_CONNECTED;
461  
462      tcp_chr_free_connection(chr);
463  
464      if (s->listener) {
465          qio_net_listener_set_client_func_full(s->listener, tcp_chr_accept,
466                                                chr, NULL, chr->gcontext);
467      }
468      update_disconnected_filename(s);
469      if (emit_close) {
470          qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
471      }
472      if (s->reconnect_time && !s->reconnect_timer) {
473          qemu_chr_socket_restart_timer(chr);
474      }
475  }
476  
477  static void tcp_chr_disconnect(Chardev *chr)
478  {
479      qemu_mutex_lock(&chr->chr_write_lock);
480      tcp_chr_disconnect_locked(chr);
481      qemu_mutex_unlock(&chr->chr_write_lock);
482  }
483  
484  static gboolean tcp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
485  {
486      Chardev *chr = CHARDEV(opaque);
487      SocketChardev *s = SOCKET_CHARDEV(opaque);
488      uint8_t buf[CHR_READ_BUF_LEN];
489      int len, size;
490  
491      if ((s->state != TCP_CHARDEV_STATE_CONNECTED) ||
492          s->max_size <= 0) {
493          return TRUE;
494      }
495      len = sizeof(buf);
496      if (len > s->max_size) {
497          len = s->max_size;
498      }
499      size = tcp_chr_recv(chr, (void *)buf, len);
500      if (size == 0 || (size == -1 && errno != EAGAIN)) {
501          /* connection closed */
502          tcp_chr_disconnect(chr);
503      } else if (size > 0) {
504          if (s->do_telnetopt) {
505              tcp_chr_process_IAC_bytes(chr, s, buf, &size);
506          }
507          if (size > 0) {
508              qemu_chr_be_write(chr, buf, size);
509          }
510      }
511  
512      return TRUE;
513  }
514  
515  static gboolean tcp_chr_hup(QIOChannel *channel,
516                                 GIOCondition cond,
517                                 void *opaque)
518  {
519      Chardev *chr = CHARDEV(opaque);
520      tcp_chr_disconnect(chr);
521      return G_SOURCE_REMOVE;
522  }
523  
524  static int tcp_chr_sync_read(Chardev *chr, const uint8_t *buf, int len)
525  {
526      SocketChardev *s = SOCKET_CHARDEV(chr);
527      int size;
528      int saved_errno;
529  
530      if (s->state != TCP_CHARDEV_STATE_CONNECTED) {
531          return 0;
532      }
533  
534      qio_channel_set_blocking(s->ioc, true, NULL);
535      size = tcp_chr_recv(chr, (void *) buf, len);
536      saved_errno = errno;
537      if (s->state != TCP_CHARDEV_STATE_DISCONNECTED) {
538          qio_channel_set_blocking(s->ioc, false, NULL);
539      }
540      if (size == 0) {
541          /* connection closed */
542          tcp_chr_disconnect(chr);
543      }
544  
545      errno = saved_errno;
546      return size;
547  }
548  
549  static char *qemu_chr_compute_filename(SocketChardev *s)
550  {
551      struct sockaddr_storage *ss = &s->sioc->localAddr;
552      struct sockaddr_storage *ps = &s->sioc->remoteAddr;
553      socklen_t ss_len = s->sioc->localAddrLen;
554      socklen_t ps_len = s->sioc->remoteAddrLen;
555      char shost[NI_MAXHOST], sserv[NI_MAXSERV];
556      char phost[NI_MAXHOST], pserv[NI_MAXSERV];
557      const char *left = "", *right = "";
558  
559      switch (ss->ss_family) {
560  #ifndef _WIN32
561      case AF_UNIX:
562          return g_strdup_printf("unix:%s%s",
563                                 ((struct sockaddr_un *)(ss))->sun_path,
564                                 s->is_listen ? ",server=on" : "");
565  #endif
566      case AF_INET6:
567          left  = "[";
568          right = "]";
569          /* fall through */
570      case AF_INET:
571          getnameinfo((struct sockaddr *) ss, ss_len, shost, sizeof(shost),
572                      sserv, sizeof(sserv), NI_NUMERICHOST | NI_NUMERICSERV);
573          getnameinfo((struct sockaddr *) ps, ps_len, phost, sizeof(phost),
574                      pserv, sizeof(pserv), NI_NUMERICHOST | NI_NUMERICSERV);
575          return g_strdup_printf("%s:%s%s%s:%s%s <-> %s%s%s:%s",
576                                 qemu_chr_socket_protocol(s),
577                                 left, shost, right, sserv,
578                                 s->is_listen ? ",server=on" : "",
579                                 left, phost, right, pserv);
580  
581      default:
582          return g_strdup_printf("unknown");
583      }
584  }
585  
586  static void update_ioc_handlers(SocketChardev *s)
587  {
588      Chardev *chr = CHARDEV(s);
589  
590      if (s->state != TCP_CHARDEV_STATE_CONNECTED) {
591          return;
592      }
593  
594      remove_fd_in_watch(chr);
595      chr->gsource = io_add_watch_poll(chr, s->ioc,
596                                       tcp_chr_read_poll,
597                                       tcp_chr_read, chr,
598                                       chr->gcontext);
599  
600      remove_hup_source(s);
601      s->hup_source = qio_channel_create_watch(s->ioc, G_IO_HUP);
602      g_source_set_callback(s->hup_source, (GSourceFunc)tcp_chr_hup,
603                            chr, NULL);
604      g_source_attach(s->hup_source, chr->gcontext);
605  }
606  
607  static void tcp_chr_connect(void *opaque)
608  {
609      Chardev *chr = CHARDEV(opaque);
610      SocketChardev *s = SOCKET_CHARDEV(opaque);
611  
612      g_free(chr->filename);
613      chr->filename = qemu_chr_compute_filename(s);
614  
615      tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTED);
616      update_ioc_handlers(s);
617      qemu_chr_be_event(chr, CHR_EVENT_OPENED);
618  }
619  
620  static void tcp_chr_telnet_destroy(SocketChardev *s)
621  {
622      if (s->telnet_source) {
623          g_source_destroy(s->telnet_source);
624          g_source_unref(s->telnet_source);
625          s->telnet_source = NULL;
626      }
627  }
628  
629  static void tcp_chr_update_read_handler(Chardev *chr)
630  {
631      SocketChardev *s = SOCKET_CHARDEV(chr);
632  
633      if (s->listener && s->state == TCP_CHARDEV_STATE_DISCONNECTED) {
634          /*
635           * It's possible that chardev context is changed in
636           * qemu_chr_be_update_read_handlers().  Reset it for QIO net
637           * listener if there is.
638           */
639          qio_net_listener_set_client_func_full(s->listener, tcp_chr_accept,
640                                                chr, NULL, chr->gcontext);
641      }
642  
643      if (s->telnet_source) {
644          tcp_chr_telnet_init(CHARDEV(s));
645      }
646  
647      update_ioc_handlers(s);
648  }
649  
650  static gboolean tcp_chr_telnet_init_io(QIOChannel *ioc,
651                                         GIOCondition cond G_GNUC_UNUSED,
652                                         gpointer user_data)
653  {
654      SocketChardev *s = user_data;
655      Chardev *chr = CHARDEV(s);
656      TCPChardevTelnetInit *init = s->telnet_init;
657      ssize_t ret;
658  
659      assert(init);
660  
661      ret = qio_channel_write(ioc, init->buf, init->buflen, NULL);
662      if (ret < 0) {
663          if (ret == QIO_CHANNEL_ERR_BLOCK) {
664              ret = 0;
665          } else {
666              tcp_chr_disconnect(chr);
667              goto end;
668          }
669      }
670      init->buflen -= ret;
671  
672      if (init->buflen == 0) {
673          tcp_chr_connect(chr);
674          goto end;
675      }
676  
677      memmove(init->buf, init->buf + ret, init->buflen);
678  
679      return G_SOURCE_CONTINUE;
680  
681  end:
682      g_free(s->telnet_init);
683      s->telnet_init = NULL;
684      g_source_unref(s->telnet_source);
685      s->telnet_source = NULL;
686      return G_SOURCE_REMOVE;
687  }
688  
689  static void tcp_chr_telnet_init(Chardev *chr)
690  {
691      SocketChardev *s = SOCKET_CHARDEV(chr);
692      TCPChardevTelnetInit *init;
693      size_t n = 0;
694  
695      /* Destroy existing task */
696      tcp_chr_telnet_destroy(s);
697  
698      if (s->telnet_init) {
699          /* We are possibly during a handshake already */
700          goto cont;
701      }
702  
703      s->telnet_init = g_new0(TCPChardevTelnetInit, 1);
704      init = s->telnet_init;
705  
706  #define IACSET(x, a, b, c)                      \
707      do {                                        \
708          x[n++] = a;                             \
709          x[n++] = b;                             \
710          x[n++] = c;                             \
711      } while (0)
712  
713      if (!s->is_tn3270) {
714          init->buflen = 12;
715          /* Prep the telnet negotion to put telnet in binary,
716           * no echo, single char mode */
717          IACSET(init->buf, 0xff, 0xfb, 0x01);  /* IAC WILL ECHO */
718          IACSET(init->buf, 0xff, 0xfb, 0x03);  /* IAC WILL Suppress go ahead */
719          IACSET(init->buf, 0xff, 0xfb, 0x00);  /* IAC WILL Binary */
720          IACSET(init->buf, 0xff, 0xfd, 0x00);  /* IAC DO Binary */
721      } else {
722          init->buflen = 21;
723          /* Prep the TN3270 negotion based on RFC1576 */
724          IACSET(init->buf, 0xff, 0xfd, 0x19);  /* IAC DO EOR */
725          IACSET(init->buf, 0xff, 0xfb, 0x19);  /* IAC WILL EOR */
726          IACSET(init->buf, 0xff, 0xfd, 0x00);  /* IAC DO BINARY */
727          IACSET(init->buf, 0xff, 0xfb, 0x00);  /* IAC WILL BINARY */
728          IACSET(init->buf, 0xff, 0xfd, 0x18);  /* IAC DO TERMINAL TYPE */
729          IACSET(init->buf, 0xff, 0xfa, 0x18);  /* IAC SB TERMINAL TYPE */
730          IACSET(init->buf, 0x01, 0xff, 0xf0);  /* SEND IAC SE */
731      }
732  
733  #undef IACSET
734  
735  cont:
736      s->telnet_source = qio_channel_add_watch_source(s->ioc, G_IO_OUT,
737                                                      tcp_chr_telnet_init_io,
738                                                      s, NULL,
739                                                      chr->gcontext);
740  }
741  
742  
743  static void tcp_chr_websock_handshake(QIOTask *task, gpointer user_data)
744  {
745      Chardev *chr = user_data;
746      SocketChardev *s = user_data;
747  
748      if (qio_task_propagate_error(task, NULL)) {
749          tcp_chr_disconnect(chr);
750      } else {
751          if (s->do_telnetopt) {
752              tcp_chr_telnet_init(chr);
753          } else {
754              tcp_chr_connect(chr);
755          }
756      }
757  }
758  
759  
760  static void tcp_chr_websock_init(Chardev *chr)
761  {
762      SocketChardev *s = SOCKET_CHARDEV(chr);
763      QIOChannelWebsock *wioc = NULL;
764      gchar *name;
765  
766      wioc = qio_channel_websock_new_server(s->ioc);
767  
768      name = g_strdup_printf("chardev-websocket-server-%s", chr->label);
769      qio_channel_set_name(QIO_CHANNEL(wioc), name);
770      g_free(name);
771      object_unref(OBJECT(s->ioc));
772      s->ioc = QIO_CHANNEL(wioc);
773  
774      qio_channel_websock_handshake(wioc, tcp_chr_websock_handshake, chr, NULL);
775  }
776  
777  
778  static void tcp_chr_tls_handshake(QIOTask *task,
779                                    gpointer user_data)
780  {
781      Chardev *chr = user_data;
782      SocketChardev *s = user_data;
783  
784      if (qio_task_propagate_error(task, NULL)) {
785          tcp_chr_disconnect(chr);
786      } else {
787          if (s->is_websock) {
788              tcp_chr_websock_init(chr);
789          } else if (s->do_telnetopt) {
790              tcp_chr_telnet_init(chr);
791          } else {
792              tcp_chr_connect(chr);
793          }
794      }
795  }
796  
797  
798  static void tcp_chr_tls_init(Chardev *chr)
799  {
800      SocketChardev *s = SOCKET_CHARDEV(chr);
801      QIOChannelTLS *tioc;
802      gchar *name;
803  
804      if (s->is_listen) {
805          tioc = qio_channel_tls_new_server(
806              s->ioc, s->tls_creds,
807              s->tls_authz,
808              NULL);
809      } else {
810          tioc = qio_channel_tls_new_client(
811              s->ioc, s->tls_creds,
812              s->addr->u.inet.host,
813              NULL);
814      }
815      if (tioc == NULL) {
816          tcp_chr_disconnect(chr);
817          return;
818      }
819      name = g_strdup_printf("chardev-tls-%s-%s",
820                             s->is_listen ? "server" : "client",
821                             chr->label);
822      qio_channel_set_name(QIO_CHANNEL(tioc), name);
823      g_free(name);
824      object_unref(OBJECT(s->ioc));
825      s->ioc = QIO_CHANNEL(tioc);
826  
827      qio_channel_tls_handshake(tioc,
828                                tcp_chr_tls_handshake,
829                                chr,
830                                NULL,
831                                chr->gcontext);
832  }
833  
834  
835  static void tcp_chr_set_client_ioc_name(Chardev *chr,
836                                          QIOChannelSocket *sioc)
837  {
838      SocketChardev *s = SOCKET_CHARDEV(chr);
839      char *name;
840      name = g_strdup_printf("chardev-tcp-%s-%s",
841                             s->is_listen ? "server" : "client",
842                             chr->label);
843      qio_channel_set_name(QIO_CHANNEL(sioc), name);
844      g_free(name);
845  
846  }
847  
848  static int tcp_chr_new_client(Chardev *chr, QIOChannelSocket *sioc)
849  {
850      SocketChardev *s = SOCKET_CHARDEV(chr);
851  
852      if (s->state != TCP_CHARDEV_STATE_CONNECTING) {
853          return -1;
854      }
855  
856      s->ioc = QIO_CHANNEL(sioc);
857      object_ref(OBJECT(sioc));
858      s->sioc = sioc;
859      object_ref(OBJECT(sioc));
860  
861      qio_channel_set_blocking(s->ioc, false, NULL);
862  
863      if (s->do_nodelay) {
864          qio_channel_set_delay(s->ioc, false);
865      }
866      if (s->listener) {
867          qio_net_listener_set_client_func_full(s->listener, NULL, NULL,
868                                                NULL, chr->gcontext);
869      }
870  
871      if (s->tls_creds) {
872          tcp_chr_tls_init(chr);
873      } else if (s->is_websock) {
874          tcp_chr_websock_init(chr);
875      } else if (s->do_telnetopt) {
876          tcp_chr_telnet_init(chr);
877      } else {
878          tcp_chr_connect(chr);
879      }
880  
881      return 0;
882  }
883  
884  
885  static int tcp_chr_add_client(Chardev *chr, int fd)
886  {
887      int ret;
888      QIOChannelSocket *sioc;
889      SocketChardev *s = SOCKET_CHARDEV(chr);
890  
891      if (s->state != TCP_CHARDEV_STATE_DISCONNECTED) {
892          return -1;
893      }
894  
895      sioc = qio_channel_socket_new_fd(fd, NULL);
896      if (!sioc) {
897          return -1;
898      }
899      tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING);
900      tcp_chr_set_client_ioc_name(chr, sioc);
901      if (s->registered_yank) {
902          yank_register_function(CHARDEV_YANK_INSTANCE(chr->label),
903                                 char_socket_yank_iochannel,
904                                 QIO_CHANNEL(sioc));
905      }
906      ret = tcp_chr_new_client(chr, sioc);
907      object_unref(OBJECT(sioc));
908      return ret;
909  }
910  
911  static void tcp_chr_accept(QIONetListener *listener,
912                             QIOChannelSocket *cioc,
913                             void *opaque)
914  {
915      Chardev *chr = CHARDEV(opaque);
916      SocketChardev *s = SOCKET_CHARDEV(chr);
917  
918      tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING);
919      tcp_chr_set_client_ioc_name(chr, cioc);
920      if (s->registered_yank) {
921          yank_register_function(CHARDEV_YANK_INSTANCE(chr->label),
922                                 char_socket_yank_iochannel,
923                                 QIO_CHANNEL(cioc));
924      }
925      tcp_chr_new_client(chr, cioc);
926  }
927  
928  
929  static int tcp_chr_connect_client_sync(Chardev *chr, Error **errp)
930  {
931      SocketChardev *s = SOCKET_CHARDEV(chr);
932      QIOChannelSocket *sioc = qio_channel_socket_new();
933      tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING);
934      tcp_chr_set_client_ioc_name(chr, sioc);
935      if (qio_channel_socket_connect_sync(sioc, s->addr, errp) < 0) {
936          tcp_chr_change_state(s, TCP_CHARDEV_STATE_DISCONNECTED);
937          object_unref(OBJECT(sioc));
938          return -1;
939      }
940      if (s->registered_yank) {
941          yank_register_function(CHARDEV_YANK_INSTANCE(chr->label),
942                                 char_socket_yank_iochannel,
943                                 QIO_CHANNEL(sioc));
944      }
945      tcp_chr_new_client(chr, sioc);
946      object_unref(OBJECT(sioc));
947      return 0;
948  }
949  
950  
951  static void tcp_chr_accept_server_sync(Chardev *chr)
952  {
953      SocketChardev *s = SOCKET_CHARDEV(chr);
954      QIOChannelSocket *sioc;
955      info_report("QEMU waiting for connection on: %s",
956                  chr->filename);
957      tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING);
958      sioc = qio_net_listener_wait_client(s->listener);
959      tcp_chr_set_client_ioc_name(chr, sioc);
960      if (s->registered_yank) {
961          yank_register_function(CHARDEV_YANK_INSTANCE(chr->label),
962                                 char_socket_yank_iochannel,
963                                 QIO_CHANNEL(sioc));
964      }
965      tcp_chr_new_client(chr, sioc);
966      object_unref(OBJECT(sioc));
967  }
968  
969  
970  static int tcp_chr_wait_connected(Chardev *chr, Error **errp)
971  {
972      SocketChardev *s = SOCKET_CHARDEV(chr);
973      const char *opts[] = { "telnet", "tn3270", "websock", "tls-creds" };
974      bool optset[] = { s->is_telnet, s->is_tn3270, s->is_websock, s->tls_creds };
975      size_t i;
976  
977      QEMU_BUILD_BUG_ON(G_N_ELEMENTS(opts) != G_N_ELEMENTS(optset));
978      for (i = 0; i < G_N_ELEMENTS(opts); i++) {
979          if (optset[i]) {
980              error_setg(errp,
981                         "'%s' option is incompatible with waiting for "
982                         "connection completion", opts[i]);
983              return -1;
984          }
985      }
986  
987      tcp_chr_reconn_timer_cancel(s);
988  
989      /*
990       * We expect states to be as follows:
991       *
992       *  - server
993       *    - wait   -> CONNECTED
994       *    - nowait -> DISCONNECTED
995       *  - client
996       *    - reconnect == 0 -> CONNECTED
997       *    - reconnect != 0 -> CONNECTING
998       *
999       */
1000      if (s->state == TCP_CHARDEV_STATE_CONNECTING) {
1001          if (!s->connect_task) {
1002              error_setg(errp,
1003                         "Unexpected 'connecting' state without connect task "
1004                         "while waiting for connection completion");
1005              return -1;
1006          }
1007          /*
1008           * tcp_chr_wait_connected should only ever be run from the
1009           * main loop thread associated with chr->gcontext, otherwise
1010           * qio_task_wait_thread has a dangerous race condition with
1011           * free'ing of the s->connect_task object.
1012           *
1013           * Acquiring the main context doesn't 100% prove we're in
1014           * the main loop thread, but it does at least guarantee
1015           * that the main loop won't be executed by another thread
1016           * avoiding the race condition with the task idle callback.
1017           */
1018          g_main_context_acquire(chr->gcontext);
1019          qio_task_wait_thread(s->connect_task);
1020          g_main_context_release(chr->gcontext);
1021  
1022          /*
1023           * The completion callback (qemu_chr_socket_connected) for
1024           * s->connect_task should have set this to NULL by the time
1025           * qio_task_wait_thread has returned.
1026           */
1027          assert(!s->connect_task);
1028  
1029          /*
1030           * NB we are *not* guaranteed to have "s->state == ..CONNECTED"
1031           * at this point as this first connect may be failed, so
1032           * allow the next loop to run regardless.
1033           */
1034      }
1035  
1036      while (s->state != TCP_CHARDEV_STATE_CONNECTED) {
1037          if (s->is_listen) {
1038              tcp_chr_accept_server_sync(chr);
1039          } else {
1040              Error *err = NULL;
1041              if (tcp_chr_connect_client_sync(chr, &err) < 0) {
1042                  if (s->reconnect_time) {
1043                      error_free(err);
1044                      g_usleep(s->reconnect_time * 1000ULL * 1000ULL);
1045                  } else {
1046                      error_propagate(errp, err);
1047                      return -1;
1048                  }
1049              }
1050          }
1051      }
1052  
1053      return 0;
1054  }
1055  
1056  static void char_socket_finalize(Object *obj)
1057  {
1058      Chardev *chr = CHARDEV(obj);
1059      SocketChardev *s = SOCKET_CHARDEV(obj);
1060  
1061      tcp_chr_free_connection(chr);
1062      tcp_chr_reconn_timer_cancel(s);
1063      qapi_free_SocketAddress(s->addr);
1064      tcp_chr_telnet_destroy(s);
1065      g_free(s->telnet_init);
1066      if (s->listener) {
1067          qio_net_listener_set_client_func_full(s->listener, NULL, NULL,
1068                                                NULL, chr->gcontext);
1069          object_unref(OBJECT(s->listener));
1070      }
1071      if (s->tls_creds) {
1072          object_unref(OBJECT(s->tls_creds));
1073      }
1074      g_free(s->tls_authz);
1075      if (s->registered_yank) {
1076          /*
1077           * In the chardev-change special-case, we shouldn't unregister the yank
1078           * instance, as it still may be needed.
1079           */
1080          if (!chr->handover_yank_instance) {
1081              yank_unregister_instance(CHARDEV_YANK_INSTANCE(chr->label));
1082          }
1083      }
1084  
1085      qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
1086  }
1087  
1088  static void qemu_chr_socket_connected(QIOTask *task, void *opaque)
1089  {
1090      QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(qio_task_get_source(task));
1091      Chardev *chr = CHARDEV(opaque);
1092      SocketChardev *s = SOCKET_CHARDEV(chr);
1093      Error *err = NULL;
1094  
1095      s->connect_task = NULL;
1096  
1097      if (qio_task_propagate_error(task, &err)) {
1098          tcp_chr_change_state(s, TCP_CHARDEV_STATE_DISCONNECTED);
1099          if (s->registered_yank) {
1100              yank_unregister_function(CHARDEV_YANK_INSTANCE(chr->label),
1101                                       char_socket_yank_iochannel,
1102                                       QIO_CHANNEL(sioc));
1103          }
1104          check_report_connect_error(chr, err);
1105          goto cleanup;
1106      }
1107  
1108      s->connect_err_reported = false;
1109      tcp_chr_new_client(chr, sioc);
1110  
1111  cleanup:
1112      object_unref(OBJECT(sioc));
1113  }
1114  
1115  
1116  static void tcp_chr_connect_client_task(QIOTask *task,
1117                                          gpointer opaque)
1118  {
1119      QIOChannelSocket *ioc = QIO_CHANNEL_SOCKET(qio_task_get_source(task));
1120      SocketAddress *addr = opaque;
1121      Error *err = NULL;
1122  
1123      qio_channel_socket_connect_sync(ioc, addr, &err);
1124  
1125      qio_task_set_error(task, err);
1126  }
1127  
1128  
1129  static void tcp_chr_connect_client_async(Chardev *chr)
1130  {
1131      SocketChardev *s = SOCKET_CHARDEV(chr);
1132      QIOChannelSocket *sioc;
1133  
1134      tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING);
1135      sioc = qio_channel_socket_new();
1136      tcp_chr_set_client_ioc_name(chr, sioc);
1137      if (s->registered_yank) {
1138          yank_register_function(CHARDEV_YANK_INSTANCE(chr->label),
1139                                 char_socket_yank_iochannel,
1140                                 QIO_CHANNEL(sioc));
1141      }
1142      /*
1143       * Normally code would use the qio_channel_socket_connect_async
1144       * method which uses a QIOTask + qio_task_set_error internally
1145       * to avoid blocking. The tcp_chr_wait_connected method, however,
1146       * needs a way to synchronize with completion of the background
1147       * connect task which can't be done with the QIOChannelSocket
1148       * async APIs. Thus we must use QIOTask directly to implement
1149       * the non-blocking concept locally.
1150       */
1151      s->connect_task = qio_task_new(OBJECT(sioc),
1152                                     qemu_chr_socket_connected,
1153                                     object_ref(OBJECT(chr)),
1154                                     (GDestroyNotify)object_unref);
1155      qio_task_run_in_thread(s->connect_task,
1156                             tcp_chr_connect_client_task,
1157                             s->addr,
1158                             NULL,
1159                             chr->gcontext);
1160  }
1161  
1162  static gboolean socket_reconnect_timeout(gpointer opaque)
1163  {
1164      Chardev *chr = CHARDEV(opaque);
1165      SocketChardev *s = SOCKET_CHARDEV(opaque);
1166  
1167      qemu_mutex_lock(&chr->chr_write_lock);
1168      g_source_unref(s->reconnect_timer);
1169      s->reconnect_timer = NULL;
1170      qemu_mutex_unlock(&chr->chr_write_lock);
1171  
1172      if (chr->be_open) {
1173          return false;
1174      }
1175  
1176      tcp_chr_connect_client_async(chr);
1177  
1178      return false;
1179  }
1180  
1181  
1182  static int qmp_chardev_open_socket_server(Chardev *chr,
1183                                            bool is_telnet,
1184                                            bool is_waitconnect,
1185                                            Error **errp)
1186  {
1187      SocketChardev *s = SOCKET_CHARDEV(chr);
1188      char *name;
1189      if (is_telnet) {
1190          s->do_telnetopt = 1;
1191      }
1192      s->listener = qio_net_listener_new();
1193  
1194      name = g_strdup_printf("chardev-tcp-listener-%s", chr->label);
1195      qio_net_listener_set_name(s->listener, name);
1196      g_free(name);
1197  
1198      if (s->addr->type == SOCKET_ADDRESS_TYPE_FD && !*s->addr->u.fd.str) {
1199          goto skip_listen;
1200      }
1201  
1202      if (qio_net_listener_open_sync(s->listener, s->addr, 1, errp) < 0) {
1203          object_unref(OBJECT(s->listener));
1204          s->listener = NULL;
1205          return -1;
1206      }
1207  
1208      qapi_free_SocketAddress(s->addr);
1209      s->addr = socket_local_address(s->listener->sioc[0]->fd, errp);
1210  
1211  skip_listen:
1212      update_disconnected_filename(s);
1213  
1214      if (is_waitconnect) {
1215          tcp_chr_accept_server_sync(chr);
1216      } else {
1217          qio_net_listener_set_client_func_full(s->listener,
1218                                                tcp_chr_accept,
1219                                                chr, NULL,
1220                                                chr->gcontext);
1221      }
1222  
1223      return 0;
1224  }
1225  
1226  
1227  static int qmp_chardev_open_socket_client(Chardev *chr,
1228                                            int64_t reconnect,
1229                                            Error **errp)
1230  {
1231      SocketChardev *s = SOCKET_CHARDEV(chr);
1232  
1233      if (reconnect > 0) {
1234          s->reconnect_time = reconnect;
1235          tcp_chr_connect_client_async(chr);
1236          return 0;
1237      } else {
1238          return tcp_chr_connect_client_sync(chr, errp);
1239      }
1240  }
1241  
1242  
1243  static bool qmp_chardev_validate_socket(ChardevSocket *sock,
1244                                          SocketAddress *addr,
1245                                          Error **errp)
1246  {
1247      /* Validate any options which have a dependency on address type */
1248      switch (addr->type) {
1249      case SOCKET_ADDRESS_TYPE_FD:
1250          if (sock->has_reconnect) {
1251              error_setg(errp,
1252                         "'reconnect' option is incompatible with "
1253                         "'fd' address type");
1254              return false;
1255          }
1256          if (sock->has_tls_creds &&
1257              !(sock->has_server && sock->server)) {
1258              error_setg(errp,
1259                         "'tls_creds' option is incompatible with "
1260                         "'fd' address type as client");
1261              return false;
1262          }
1263          break;
1264  
1265      case SOCKET_ADDRESS_TYPE_UNIX:
1266          if (sock->has_tls_creds) {
1267              error_setg(errp,
1268                         "'tls_creds' option is incompatible with "
1269                         "'unix' address type");
1270              return false;
1271          }
1272          break;
1273  
1274      case SOCKET_ADDRESS_TYPE_INET:
1275          break;
1276  
1277      case SOCKET_ADDRESS_TYPE_VSOCK:
1278          if (sock->has_tls_creds) {
1279              error_setg(errp,
1280                         "'tls_creds' option is incompatible with "
1281                         "'vsock' address type");
1282              return false;
1283          }
1284  
1285      default:
1286          break;
1287      }
1288  
1289      if (sock->has_tls_authz && !sock->has_tls_creds) {
1290          error_setg(errp, "'tls_authz' option requires 'tls_creds' option");
1291          return false;
1292      }
1293  
1294      /* Validate any options which have a dependancy on client vs server */
1295      if (!sock->has_server || sock->server) {
1296          if (sock->has_reconnect) {
1297              error_setg(errp,
1298                         "'reconnect' option is incompatible with "
1299                         "socket in server listen mode");
1300              return false;
1301          }
1302      } else {
1303          if (sock->has_websocket && sock->websocket) {
1304              error_setg(errp, "%s", "Websocket client is not implemented");
1305              return false;
1306          }
1307          if (sock->has_wait) {
1308              error_setg(errp, "%s",
1309                         "'wait' option is incompatible with "
1310                         "socket in client connect mode");
1311              return false;
1312          }
1313      }
1314  
1315      return true;
1316  }
1317  
1318  
1319  static void qmp_chardev_open_socket(Chardev *chr,
1320                                      ChardevBackend *backend,
1321                                      bool *be_opened,
1322                                      Error **errp)
1323  {
1324      SocketChardev *s = SOCKET_CHARDEV(chr);
1325      ChardevSocket *sock = backend->u.socket.data;
1326      bool do_nodelay     = sock->has_nodelay ? sock->nodelay : false;
1327      bool is_listen      = sock->has_server  ? sock->server  : true;
1328      bool is_telnet      = sock->has_telnet  ? sock->telnet  : false;
1329      bool is_tn3270      = sock->has_tn3270  ? sock->tn3270  : false;
1330      bool is_waitconnect = sock->has_wait    ? sock->wait    : false;
1331      bool is_websock     = sock->has_websocket ? sock->websocket : false;
1332      int64_t reconnect   = sock->has_reconnect ? sock->reconnect : 0;
1333      SocketAddress *addr;
1334  
1335      s->is_listen = is_listen;
1336      s->is_telnet = is_telnet;
1337      s->is_tn3270 = is_tn3270;
1338      s->is_websock = is_websock;
1339      s->do_nodelay = do_nodelay;
1340      if (sock->tls_creds) {
1341          Object *creds;
1342          creds = object_resolve_path_component(
1343              object_get_objects_root(), sock->tls_creds);
1344          if (!creds) {
1345              error_setg(errp, "No TLS credentials with id '%s'",
1346                         sock->tls_creds);
1347              return;
1348          }
1349          s->tls_creds = (QCryptoTLSCreds *)
1350              object_dynamic_cast(creds,
1351                                  TYPE_QCRYPTO_TLS_CREDS);
1352          if (!s->tls_creds) {
1353              error_setg(errp, "Object with id '%s' is not TLS credentials",
1354                         sock->tls_creds);
1355              return;
1356          }
1357          object_ref(OBJECT(s->tls_creds));
1358          if (!qcrypto_tls_creds_check_endpoint(s->tls_creds,
1359                                            is_listen
1360                                            ? QCRYPTO_TLS_CREDS_ENDPOINT_SERVER
1361                                            : QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT,
1362                                            errp)) {
1363              return;
1364          }
1365      }
1366      s->tls_authz = g_strdup(sock->tls_authz);
1367  
1368      s->addr = addr = socket_address_flatten(sock->addr);
1369  
1370      if (!qmp_chardev_validate_socket(sock, addr, errp)) {
1371          return;
1372      }
1373  
1374      qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_RECONNECTABLE);
1375      /* TODO SOCKET_ADDRESS_FD where fd has AF_UNIX */
1376      if (addr->type == SOCKET_ADDRESS_TYPE_UNIX) {
1377          qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_FD_PASS);
1378      }
1379  
1380      /*
1381       * In the chardev-change special-case, we shouldn't register a new yank
1382       * instance, as there already may be one.
1383       */
1384      if (!chr->handover_yank_instance) {
1385          if (!yank_register_instance(CHARDEV_YANK_INSTANCE(chr->label), errp)) {
1386              return;
1387          }
1388      }
1389      s->registered_yank = true;
1390  
1391      /* be isn't opened until we get a connection */
1392      *be_opened = false;
1393  
1394      update_disconnected_filename(s);
1395  
1396      if (s->is_listen) {
1397          if (qmp_chardev_open_socket_server(chr, is_telnet || is_tn3270,
1398                                             is_waitconnect, errp) < 0) {
1399              return;
1400          }
1401      } else {
1402          if (qmp_chardev_open_socket_client(chr, reconnect, errp) < 0) {
1403              return;
1404          }
1405      }
1406  }
1407  
1408  static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
1409                                    Error **errp)
1410  {
1411      const char *path = qemu_opt_get(opts, "path");
1412      const char *host = qemu_opt_get(opts, "host");
1413      const char *port = qemu_opt_get(opts, "port");
1414      const char *fd = qemu_opt_get(opts, "fd");
1415  #ifdef CONFIG_LINUX
1416      bool tight = qemu_opt_get_bool(opts, "tight", true);
1417      bool abstract = qemu_opt_get_bool(opts, "abstract", false);
1418  #endif
1419      SocketAddressLegacy *addr;
1420      ChardevSocket *sock;
1421  
1422      if ((!!path + !!fd + !!host) > 1) {
1423          error_setg(errp,
1424                     "None or one of 'path', 'fd' or 'host' option required.");
1425          return;
1426      }
1427  
1428      if (host && !port) {
1429          error_setg(errp, "chardev: socket: no port given");
1430          return;
1431      }
1432  
1433      backend->type = CHARDEV_BACKEND_KIND_SOCKET;
1434      sock = backend->u.socket.data = g_new0(ChardevSocket, 1);
1435      qemu_chr_parse_common(opts, qapi_ChardevSocket_base(sock));
1436  
1437      if (qemu_opt_get(opts, "delay") && qemu_opt_get(opts, "nodelay")) {
1438          error_setg(errp, "'delay' and 'nodelay' are mutually exclusive");
1439          return;
1440      }
1441      sock->has_nodelay =
1442          qemu_opt_get(opts, "delay") ||
1443          qemu_opt_get(opts, "nodelay");
1444      sock->nodelay =
1445          !qemu_opt_get_bool(opts, "delay", true) ||
1446          qemu_opt_get_bool(opts, "nodelay", false);
1447  
1448      /*
1449       * We have different default to QMP for 'server', hence
1450       * we can't just check for existence of 'server'
1451       */
1452      sock->has_server = true;
1453      sock->server = qemu_opt_get_bool(opts, "server", false);
1454      sock->has_telnet = qemu_opt_get(opts, "telnet");
1455      sock->telnet = qemu_opt_get_bool(opts, "telnet", false);
1456      sock->has_tn3270 = qemu_opt_get(opts, "tn3270");
1457      sock->tn3270 = qemu_opt_get_bool(opts, "tn3270", false);
1458      sock->has_websocket = qemu_opt_get(opts, "websocket");
1459      sock->websocket = qemu_opt_get_bool(opts, "websocket", false);
1460      /*
1461       * We have different default to QMP for 'wait' when 'server'
1462       * is set, hence we can't just check for existence of 'wait'
1463       */
1464      sock->has_wait = qemu_opt_find(opts, "wait") || sock->server;
1465      sock->wait = qemu_opt_get_bool(opts, "wait", true);
1466      sock->has_reconnect = qemu_opt_find(opts, "reconnect");
1467      sock->reconnect = qemu_opt_get_number(opts, "reconnect", 0);
1468      sock->has_tls_creds = qemu_opt_get(opts, "tls-creds");
1469      sock->tls_creds = g_strdup(qemu_opt_get(opts, "tls-creds"));
1470      sock->has_tls_authz = qemu_opt_get(opts, "tls-authz");
1471      sock->tls_authz = g_strdup(qemu_opt_get(opts, "tls-authz"));
1472  
1473      addr = g_new0(SocketAddressLegacy, 1);
1474      if (path) {
1475          UnixSocketAddress *q_unix;
1476          addr->type = SOCKET_ADDRESS_TYPE_UNIX;
1477          q_unix = addr->u.q_unix.data = g_new0(UnixSocketAddress, 1);
1478          q_unix->path = g_strdup(path);
1479  #ifdef CONFIG_LINUX
1480          q_unix->has_tight = true;
1481          q_unix->tight = tight;
1482          q_unix->has_abstract = true;
1483          q_unix->abstract = abstract;
1484  #endif
1485      } else if (host) {
1486          addr->type = SOCKET_ADDRESS_TYPE_INET;
1487          addr->u.inet.data = g_new(InetSocketAddress, 1);
1488          *addr->u.inet.data = (InetSocketAddress) {
1489              .host = g_strdup(host),
1490              .port = g_strdup(port),
1491              .has_to = qemu_opt_get(opts, "to"),
1492              .to = qemu_opt_get_number(opts, "to", 0),
1493              .has_ipv4 = qemu_opt_get(opts, "ipv4"),
1494              .ipv4 = qemu_opt_get_bool(opts, "ipv4", 0),
1495              .has_ipv6 = qemu_opt_get(opts, "ipv6"),
1496              .ipv6 = qemu_opt_get_bool(opts, "ipv6", 0),
1497          };
1498      } else {
1499          addr->type = SOCKET_ADDRESS_TYPE_FD;
1500          addr->u.fd.data = g_new(String, 1);
1501          addr->u.fd.data->str = g_strdup(fd);
1502      }
1503      sock->addr = addr;
1504  }
1505  
1506  static void
1507  char_socket_get_addr(Object *obj, Visitor *v, const char *name,
1508                       void *opaque, Error **errp)
1509  {
1510      SocketChardev *s = SOCKET_CHARDEV(obj);
1511  
1512      visit_type_SocketAddress(v, name, &s->addr, errp);
1513  }
1514  
1515  static bool
1516  char_socket_get_connected(Object *obj, Error **errp)
1517  {
1518      SocketChardev *s = SOCKET_CHARDEV(obj);
1519  
1520      return s->state == TCP_CHARDEV_STATE_CONNECTED;
1521  }
1522  
1523  static void char_socket_class_init(ObjectClass *oc, void *data)
1524  {
1525      ChardevClass *cc = CHARDEV_CLASS(oc);
1526  
1527      cc->supports_yank = true;
1528  
1529      cc->parse = qemu_chr_parse_socket;
1530      cc->open = qmp_chardev_open_socket;
1531      cc->chr_wait_connected = tcp_chr_wait_connected;
1532      cc->chr_write = tcp_chr_write;
1533      cc->chr_sync_read = tcp_chr_sync_read;
1534      cc->chr_disconnect = tcp_chr_disconnect;
1535      cc->get_msgfds = tcp_get_msgfds;
1536      cc->set_msgfds = tcp_set_msgfds;
1537      cc->chr_add_client = tcp_chr_add_client;
1538      cc->chr_add_watch = tcp_chr_add_watch;
1539      cc->chr_update_read_handler = tcp_chr_update_read_handler;
1540  
1541      object_class_property_add(oc, "addr", "SocketAddress",
1542                                char_socket_get_addr, NULL,
1543                                NULL, NULL);
1544  
1545      object_class_property_add_bool(oc, "connected", char_socket_get_connected,
1546                                     NULL);
1547  }
1548  
1549  static const TypeInfo char_socket_type_info = {
1550      .name = TYPE_CHARDEV_SOCKET,
1551      .parent = TYPE_CHARDEV,
1552      .instance_size = sizeof(SocketChardev),
1553      .instance_finalize = char_socket_finalize,
1554      .class_init = char_socket_class_init,
1555  };
1556  
1557  static void register_types(void)
1558  {
1559      type_register_static(&char_socket_type_info);
1560  }
1561  
1562  type_init(register_types);
1563