diff options
author | Andy Fiddaman <illumos@fiddaman.net> | 2022-10-14 20:39:08 +0000 |
---|---|---|
committer | Andy Fiddaman <illumos@fiddaman.net> | 2022-10-17 18:20:01 +0000 |
commit | 38864087f2024637a6b7733caa7b6fd59c9383bd (patch) | |
tree | 20047d81a0ffd210ef06bccbfb375f7ef2f4295b /usr/src | |
parent | 08f2ce59ccfd4e449c92dd87b23e756e439d4daa (diff) | |
download | illumos-gate-38864087f2024637a6b7733caa7b6fd59c9383bd.tar.gz |
15090 bhyve needs to handle disconnecting RFB clients better
Reviewed by: Marco van Wieringen <mvw@planets.elm.net>
Reviewed by: Toomas Soome <tsoome@me.com>
Approved by: Patrick Mooney <pmooney@pfmooney.com>
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/cmd/bhyve/rfb.c | 25 | ||||
-rw-r--r-- | usr/src/cmd/bhyve/sockstream.c | 8 |
2 files changed, 26 insertions, 7 deletions
diff --git a/usr/src/cmd/bhyve/rfb.c b/usr/src/cmd/bhyve/rfb.c index ab209aae36..139d75183f 100644 --- a/usr/src/cmd/bhyve/rfb.c +++ b/usr/src/cmd/bhyve/rfb.c @@ -192,8 +192,10 @@ fast_crc32(void *buf, int len, uint32_t crcval) static void rfb_send_client_status(rfb_client_t *c, uint32_t status, const char *msg) { - status = htonl(status); + rfb_printf(c, RFB_LOGDEBUG, "sending client status %u (%s)", + status, msg ? msg : "NULL"); + status = htonl(status); (void) stream_write(c->rc_fd, &status, sizeof (status)); if (msg != NULL && status != 0 && c->rc_cver == RFB_CVER_3_8) { @@ -213,7 +215,7 @@ rfb_handshake_version(rfb_client_t *c) unsigned char buf[RFB_VERSION_LEN]; ssize_t l; - rfb_printf(c, RFB_LOGDEBUG, "handshake version"); + rfb_printf(c, RFB_LOGDEBUG, "handshake version"); if (stream_write(c->rc_fd, RFB_VERSION, RFB_VERSION_LEN) != RFB_VERSION_LEN) { @@ -367,12 +369,19 @@ rfb_handshake_auth(rfb_client_t *c) /* Initialize a 16-byte random challenge. */ arc4random_buf(challenge, sizeof (challenge)); - (void) stream_write(c->rc_fd, challenge, RFBP_SECURITY_VNC_AUTH_LEN); + + /* Send the challenge to the client. */ + if (stream_write(c->rc_fd, challenge, RFBP_SECURITY_VNC_AUTH_LEN) + != RFBP_SECURITY_VNC_AUTH_LEN) { + rfb_printf(c, RFB_LOGERR, + "failed to send challenge to client"); + return (false); + } /* Receive the 16-byte challenge response. */ if (stream_read(c->rc_fd, buf, RFBP_SECURITY_VNC_AUTH_LEN) != RFBP_SECURITY_VNC_AUTH_LEN) { - rfb_send_client_status(c, 1, "response read failed"); + rfb_send_client_status(c, 1, "Challenge response read failed"); return (false); } @@ -1215,8 +1224,10 @@ rfb_client_tx_thread(void *arg) c->rc_sinfo.rsi_pixfmt = c->rc_s->rs_pixfmt; c->rc_encodings = RFB_ENCODING_RAW; - if (!rfb_handshake(c)) + if (!rfb_handshake(c)) { + rfb_printf(c, RFB_LOGWARN, "handshake failure"); goto out; + } c->rc_cells = howmany(RFB_MAX_WIDTH * RFB_MAX_HEIGHT, RFB_PIX_PER_CELL); if ((c->rc_crc = calloc(c->rc_cells, sizeof (uint32_t))) == NULL || @@ -1274,10 +1285,10 @@ rfb_client_tx_thread(void *arg) } } - rfb_printf(c, RFB_LOGWARN, "disconnected"); - out: + rfb_printf(c, RFB_LOGWARN, "disconnected"); + (void) pthread_join(c->rc_rx_tid, &status); pthread_mutex_lock(&s->rs_clientlock); s->rs_clientcount--; diff --git a/usr/src/cmd/bhyve/sockstream.c b/usr/src/cmd/bhyve/sockstream.c index b592bce9aa..d8d9966cfb 100644 --- a/usr/src/cmd/bhyve/sockstream.c +++ b/usr/src/cmd/bhyve/sockstream.c @@ -34,6 +34,10 @@ __FBSDID("$FreeBSD$"); #include <sys/types.h> #include <unistd.h> +#ifndef __FreeBSD__ +#include <sys/socket.h> +#endif + #include <errno.h> #include "sockstream.h" @@ -72,7 +76,11 @@ stream_write(int fd, const void *buf, ssize_t nbytes) p = buf; while (len < nbytes) { +#ifdef __FreeBSD__ n = write(fd, p + len, nbytes - len); +#else + n = send(fd, p + len, nbytes - len, MSG_NOSIGNAL); +#endif if (n == 0) break; if (n < 0) { |