2 * QEMU VNC display driver
4 * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
5 * Copyright (C) 2006 Fabrice Bellard
6 * Copyright (C) 2009 Red Hat, Inc
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 #include "qemu/osdep.h"
31 #include "sysemu/sysemu.h"
32 #include "qemu/error-report.h"
33 #include "qemu/sockets.h"
34 #include "qemu/timer.h"
36 #include "qemu/config-file.h"
37 #include "qapi/qmp/qerror.h"
38 #include "qapi/qmp/types.h"
39 #include "qmp-commands.h"
41 #include "qapi-event.h"
42 #include "crypto/hash.h"
43 #include "crypto/tlscredsanon.h"
44 #include "crypto/tlscredsx509.h"
45 #include "qom/object_interfaces.h"
46 #include "qemu/cutils.h"
47 #include "io/dns-resolver.h"
49 #define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT
50 #define VNC_REFRESH_INTERVAL_INC 50
51 #define VNC_REFRESH_INTERVAL_MAX GUI_REFRESH_INTERVAL_IDLE
52 static const struct timeval VNC_REFRESH_STATS
= { 0, 500000 };
53 static const struct timeval VNC_REFRESH_LOSSY
= { 2, 0 };
55 #include "vnc_keysym.h"
56 #include "crypto/cipher.h"
58 static QTAILQ_HEAD(, VncDisplay
) vnc_displays
=
59 QTAILQ_HEAD_INITIALIZER(vnc_displays
);
61 static int vnc_cursor_define(VncState
*vs
);
62 static void vnc_release_modifiers(VncState
*vs
);
63 static void vnc_update_throttle_offset(VncState
*vs
);
65 static void vnc_set_share_mode(VncState
*vs
, VncShareMode mode
)
68 static const char *mn
[] = {
70 [VNC_SHARE_MODE_CONNECTING
] = "connecting",
71 [VNC_SHARE_MODE_SHARED
] = "shared",
72 [VNC_SHARE_MODE_EXCLUSIVE
] = "exclusive",
73 [VNC_SHARE_MODE_DISCONNECTED
] = "disconnected",
75 fprintf(stderr
, "%s/%p: %s -> %s\n", __func__
,
76 vs
->ioc
, mn
[vs
->share_mode
], mn
[mode
]);
79 switch (vs
->share_mode
) {
80 case VNC_SHARE_MODE_CONNECTING
:
81 vs
->vd
->num_connecting
--;
83 case VNC_SHARE_MODE_SHARED
:
86 case VNC_SHARE_MODE_EXCLUSIVE
:
87 vs
->vd
->num_exclusive
--;
93 vs
->share_mode
= mode
;
95 switch (vs
->share_mode
) {
96 case VNC_SHARE_MODE_CONNECTING
:
97 vs
->vd
->num_connecting
++;
99 case VNC_SHARE_MODE_SHARED
:
100 vs
->vd
->num_shared
++;
102 case VNC_SHARE_MODE_EXCLUSIVE
:
103 vs
->vd
->num_exclusive
++;
111 static void vnc_init_basic_info(SocketAddress
*addr
,
115 switch (addr
->type
) {
116 case SOCKET_ADDRESS_TYPE_INET
:
117 info
->host
= g_strdup(addr
->u
.inet
.host
);
118 info
->service
= g_strdup(addr
->u
.inet
.port
);
119 if (addr
->u
.inet
.ipv6
) {
120 info
->family
= NETWORK_ADDRESS_FAMILY_IPV6
;
122 info
->family
= NETWORK_ADDRESS_FAMILY_IPV4
;
126 case SOCKET_ADDRESS_TYPE_UNIX
:
127 info
->host
= g_strdup("");
128 info
->service
= g_strdup(addr
->u
.q_unix
.path
);
129 info
->family
= NETWORK_ADDRESS_FAMILY_UNIX
;
132 case SOCKET_ADDRESS_TYPE_VSOCK
:
133 case SOCKET_ADDRESS_TYPE_FD
:
134 error_setg(errp
, "Unsupported socket address type %s",
135 SocketAddressType_str(addr
->type
));
144 static void vnc_init_basic_info_from_server_addr(QIOChannelSocket
*ioc
,
148 SocketAddress
*addr
= NULL
;
151 error_setg(errp
, "No listener socket available");
155 addr
= qio_channel_socket_get_local_address(ioc
, errp
);
160 vnc_init_basic_info(addr
, info
, errp
);
161 qapi_free_SocketAddress(addr
);
164 static void vnc_init_basic_info_from_remote_addr(QIOChannelSocket
*ioc
,
168 SocketAddress
*addr
= NULL
;
170 addr
= qio_channel_socket_get_remote_address(ioc
, errp
);
175 vnc_init_basic_info(addr
, info
, errp
);
176 qapi_free_SocketAddress(addr
);
179 static const char *vnc_auth_name(VncDisplay
*vd
) {
181 case VNC_AUTH_INVALID
:
197 case VNC_AUTH_VENCRYPT
:
198 switch (vd
->subauth
) {
199 case VNC_AUTH_VENCRYPT_PLAIN
:
200 return "vencrypt+plain";
201 case VNC_AUTH_VENCRYPT_TLSNONE
:
202 return "vencrypt+tls+none";
203 case VNC_AUTH_VENCRYPT_TLSVNC
:
204 return "vencrypt+tls+vnc";
205 case VNC_AUTH_VENCRYPT_TLSPLAIN
:
206 return "vencrypt+tls+plain";
207 case VNC_AUTH_VENCRYPT_X509NONE
:
208 return "vencrypt+x509+none";
209 case VNC_AUTH_VENCRYPT_X509VNC
:
210 return "vencrypt+x509+vnc";
211 case VNC_AUTH_VENCRYPT_X509PLAIN
:
212 return "vencrypt+x509+plain";
213 case VNC_AUTH_VENCRYPT_TLSSASL
:
214 return "vencrypt+tls+sasl";
215 case VNC_AUTH_VENCRYPT_X509SASL
:
216 return "vencrypt+x509+sasl";
226 static VncServerInfo
*vnc_server_info_get(VncDisplay
*vd
)
231 if (!vd
->listener
|| !vd
->listener
->nsioc
) {
235 info
= g_malloc0(sizeof(*info
));
236 vnc_init_basic_info_from_server_addr(vd
->listener
->sioc
[0],
237 qapi_VncServerInfo_base(info
), &err
);
238 info
->has_auth
= true;
239 info
->auth
= g_strdup(vnc_auth_name(vd
));
241 qapi_free_VncServerInfo(info
);
248 static void vnc_client_cache_auth(VncState
*client
)
255 client
->info
->x509_dname
=
256 qcrypto_tls_session_get_peer_name(client
->tls
);
257 client
->info
->has_x509_dname
=
258 client
->info
->x509_dname
!= NULL
;
260 #ifdef CONFIG_VNC_SASL
261 if (client
->sasl
.conn
&&
262 client
->sasl
.username
) {
263 client
->info
->has_sasl_username
= true;
264 client
->info
->sasl_username
= g_strdup(client
->sasl
.username
);
269 static void vnc_client_cache_addr(VncState
*client
)
273 client
->info
= g_malloc0(sizeof(*client
->info
));
274 vnc_init_basic_info_from_remote_addr(client
->sioc
,
275 qapi_VncClientInfo_base(client
->info
),
278 qapi_free_VncClientInfo(client
->info
);
284 static void vnc_qmp_event(VncState
*vs
, QAPIEvent event
)
292 si
= vnc_server_info_get(vs
->vd
);
298 case QAPI_EVENT_VNC_CONNECTED
:
299 qapi_event_send_vnc_connected(si
, qapi_VncClientInfo_base(vs
->info
),
302 case QAPI_EVENT_VNC_INITIALIZED
:
303 qapi_event_send_vnc_initialized(si
, vs
->info
, &error_abort
);
305 case QAPI_EVENT_VNC_DISCONNECTED
:
306 qapi_event_send_vnc_disconnected(si
, vs
->info
, &error_abort
);
312 qapi_free_VncServerInfo(si
);
315 static VncClientInfo
*qmp_query_vnc_client(const VncState
*client
)
320 info
= g_malloc0(sizeof(*info
));
322 vnc_init_basic_info_from_remote_addr(client
->sioc
,
323 qapi_VncClientInfo_base(info
),
327 qapi_free_VncClientInfo(info
);
331 info
->websocket
= client
->websocket
;
334 info
->x509_dname
= qcrypto_tls_session_get_peer_name(client
->tls
);
335 info
->has_x509_dname
= info
->x509_dname
!= NULL
;
337 #ifdef CONFIG_VNC_SASL
338 if (client
->sasl
.conn
&& client
->sasl
.username
) {
339 info
->has_sasl_username
= true;
340 info
->sasl_username
= g_strdup(client
->sasl
.username
);
347 static VncDisplay
*vnc_display_find(const char *id
)
352 return QTAILQ_FIRST(&vnc_displays
);
354 QTAILQ_FOREACH(vd
, &vnc_displays
, next
) {
355 if (strcmp(id
, vd
->id
) == 0) {
362 static VncClientInfoList
*qmp_query_client_list(VncDisplay
*vd
)
364 VncClientInfoList
*cinfo
, *prev
= NULL
;
367 QTAILQ_FOREACH(client
, &vd
->clients
, next
) {
368 cinfo
= g_new0(VncClientInfoList
, 1);
369 cinfo
->value
= qmp_query_vnc_client(client
);
376 VncInfo
*qmp_query_vnc(Error
**errp
)
378 VncInfo
*info
= g_malloc0(sizeof(*info
));
379 VncDisplay
*vd
= vnc_display_find(NULL
);
380 SocketAddress
*addr
= NULL
;
382 if (vd
== NULL
|| !vd
->listener
|| !vd
->listener
->nsioc
) {
383 info
->enabled
= false;
385 info
->enabled
= true;
387 /* for compatibility with the original command */
388 info
->has_clients
= true;
389 info
->clients
= qmp_query_client_list(vd
);
391 addr
= qio_channel_socket_get_local_address(vd
->listener
->sioc
[0],
397 switch (addr
->type
) {
398 case SOCKET_ADDRESS_TYPE_INET
:
399 info
->host
= g_strdup(addr
->u
.inet
.host
);
400 info
->service
= g_strdup(addr
->u
.inet
.port
);
401 if (addr
->u
.inet
.ipv6
) {
402 info
->family
= NETWORK_ADDRESS_FAMILY_IPV6
;
404 info
->family
= NETWORK_ADDRESS_FAMILY_IPV4
;
408 case SOCKET_ADDRESS_TYPE_UNIX
:
409 info
->host
= g_strdup("");
410 info
->service
= g_strdup(addr
->u
.q_unix
.path
);
411 info
->family
= NETWORK_ADDRESS_FAMILY_UNIX
;
414 case SOCKET_ADDRESS_TYPE_VSOCK
:
415 case SOCKET_ADDRESS_TYPE_FD
:
416 error_setg(errp
, "Unsupported socket address type %s",
417 SocketAddressType_str(addr
->type
));
423 info
->has_host
= true;
424 info
->has_service
= true;
425 info
->has_family
= true;
427 info
->has_auth
= true;
428 info
->auth
= g_strdup(vnc_auth_name(vd
));
431 qapi_free_SocketAddress(addr
);
435 qapi_free_SocketAddress(addr
);
436 qapi_free_VncInfo(info
);
441 static void qmp_query_auth(int auth
, int subauth
,
442 VncPrimaryAuth
*qmp_auth
,
443 VncVencryptSubAuth
*qmp_vencrypt
,
444 bool *qmp_has_vencrypt
);
446 static VncServerInfo2List
*qmp_query_server_entry(QIOChannelSocket
*ioc
,
450 VncServerInfo2List
*prev
)
452 VncServerInfo2List
*list
;
453 VncServerInfo2
*info
;
457 addr
= qio_channel_socket_get_local_address(ioc
, &err
);
463 info
= g_new0(VncServerInfo2
, 1);
464 vnc_init_basic_info(addr
, qapi_VncServerInfo2_base(info
), &err
);
465 qapi_free_SocketAddress(addr
);
467 qapi_free_VncServerInfo2(info
);
471 info
->websocket
= websocket
;
473 qmp_query_auth(auth
, subauth
, &info
->auth
,
474 &info
->vencrypt
, &info
->has_vencrypt
);
476 list
= g_new0(VncServerInfo2List
, 1);
482 static void qmp_query_auth(int auth
, int subauth
,
483 VncPrimaryAuth
*qmp_auth
,
484 VncVencryptSubAuth
*qmp_vencrypt
,
485 bool *qmp_has_vencrypt
)
489 *qmp_auth
= VNC_PRIMARY_AUTH_VNC
;
492 *qmp_auth
= VNC_PRIMARY_AUTH_RA2
;
495 *qmp_auth
= VNC_PRIMARY_AUTH_RA2NE
;
498 *qmp_auth
= VNC_PRIMARY_AUTH_TIGHT
;
501 *qmp_auth
= VNC_PRIMARY_AUTH_ULTRA
;
504 *qmp_auth
= VNC_PRIMARY_AUTH_TLS
;
506 case VNC_AUTH_VENCRYPT
:
507 *qmp_auth
= VNC_PRIMARY_AUTH_VENCRYPT
;
508 *qmp_has_vencrypt
= true;
510 case VNC_AUTH_VENCRYPT_PLAIN
:
511 *qmp_vencrypt
= VNC_VENCRYPT_SUB_AUTH_PLAIN
;
513 case VNC_AUTH_VENCRYPT_TLSNONE
:
514 *qmp_vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_NONE
;
516 case VNC_AUTH_VENCRYPT_TLSVNC
:
517 *qmp_vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_VNC
;
519 case VNC_AUTH_VENCRYPT_TLSPLAIN
:
520 *qmp_vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN
;
522 case VNC_AUTH_VENCRYPT_X509NONE
:
523 *qmp_vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_NONE
;
525 case VNC_AUTH_VENCRYPT_X509VNC
:
526 *qmp_vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_VNC
;
528 case VNC_AUTH_VENCRYPT_X509PLAIN
:
529 *qmp_vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_PLAIN
;
531 case VNC_AUTH_VENCRYPT_TLSSASL
:
532 *qmp_vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_SASL
;
534 case VNC_AUTH_VENCRYPT_X509SASL
:
535 *qmp_vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_SASL
;
538 *qmp_has_vencrypt
= false;
543 *qmp_auth
= VNC_PRIMARY_AUTH_SASL
;
547 *qmp_auth
= VNC_PRIMARY_AUTH_NONE
;
552 VncInfo2List
*qmp_query_vnc_servers(Error
**errp
)
554 VncInfo2List
*item
, *prev
= NULL
;
560 QTAILQ_FOREACH(vd
, &vnc_displays
, next
) {
561 info
= g_new0(VncInfo2
, 1);
562 info
->id
= g_strdup(vd
->id
);
563 info
->clients
= qmp_query_client_list(vd
);
564 qmp_query_auth(vd
->auth
, vd
->subauth
, &info
->auth
,
565 &info
->vencrypt
, &info
->has_vencrypt
);
567 dev
= DEVICE(object_property_get_link(OBJECT(vd
->dcl
.con
),
569 info
->has_display
= true;
570 info
->display
= g_strdup(dev
->id
);
572 for (i
= 0; vd
->listener
!= NULL
&& i
< vd
->listener
->nsioc
; i
++) {
573 info
->server
= qmp_query_server_entry(
574 vd
->listener
->sioc
[i
], false, vd
->auth
, vd
->subauth
,
577 for (i
= 0; vd
->wslistener
!= NULL
&& i
< vd
->wslistener
->nsioc
; i
++) {
578 info
->server
= qmp_query_server_entry(
579 vd
->wslistener
->sioc
[i
], true, vd
->ws_auth
,
580 vd
->ws_subauth
, info
->server
);
583 item
= g_new0(VncInfo2List
, 1);
592 1) Get the queue working for IO.
593 2) there is some weirdness when using the -S option (the screen is grey
594 and not totally invalidated
595 3) resolutions > 1024
598 static int vnc_update_client(VncState
*vs
, int has_dirty
);
599 static void vnc_disconnect_start(VncState
*vs
);
601 static void vnc_colordepth(VncState
*vs
);
602 static void framebuffer_update_request(VncState
*vs
, int incremental
,
603 int x_position
, int y_position
,
605 static void vnc_refresh(DisplayChangeListener
*dcl
);
606 static int vnc_refresh_server_surface(VncDisplay
*vd
);
608 static int vnc_width(VncDisplay
*vd
)
610 return MIN(VNC_MAX_WIDTH
, ROUND_UP(surface_width(vd
->ds
),
611 VNC_DIRTY_PIXELS_PER_BIT
));
614 static int vnc_height(VncDisplay
*vd
)
616 return MIN(VNC_MAX_HEIGHT
, surface_height(vd
->ds
));
619 static void vnc_set_area_dirty(DECLARE_BITMAP(dirty
[VNC_MAX_HEIGHT
],
620 VNC_MAX_WIDTH
/ VNC_DIRTY_PIXELS_PER_BIT
),
622 int x
, int y
, int w
, int h
)
624 int width
= vnc_width(vd
);
625 int height
= vnc_height(vd
);
627 /* this is needed this to ensure we updated all affected
628 * blocks if x % VNC_DIRTY_PIXELS_PER_BIT != 0 */
629 w
+= (x
% VNC_DIRTY_PIXELS_PER_BIT
);
630 x
-= (x
% VNC_DIRTY_PIXELS_PER_BIT
);
634 w
= MIN(x
+ w
, width
) - x
;
635 h
= MIN(y
+ h
, height
);
638 bitmap_set(dirty
[y
], x
/ VNC_DIRTY_PIXELS_PER_BIT
,
639 DIV_ROUND_UP(w
, VNC_DIRTY_PIXELS_PER_BIT
));
643 static void vnc_dpy_update(DisplayChangeListener
*dcl
,
644 int x
, int y
, int w
, int h
)
646 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
647 struct VncSurface
*s
= &vd
->guest
;
649 vnc_set_area_dirty(s
->dirty
, vd
, x
, y
, w
, h
);
652 void vnc_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
,
655 vnc_write_u16(vs
, x
);
656 vnc_write_u16(vs
, y
);
657 vnc_write_u16(vs
, w
);
658 vnc_write_u16(vs
, h
);
660 vnc_write_s32(vs
, encoding
);
664 static void vnc_desktop_resize(VncState
*vs
)
666 if (vs
->ioc
== NULL
|| !vnc_has_feature(vs
, VNC_FEATURE_RESIZE
)) {
669 if (vs
->client_width
== pixman_image_get_width(vs
->vd
->server
) &&
670 vs
->client_height
== pixman_image_get_height(vs
->vd
->server
)) {
674 assert(pixman_image_get_width(vs
->vd
->server
) < 65536 &&
675 pixman_image_get_width(vs
->vd
->server
) >= 0);
676 assert(pixman_image_get_height(vs
->vd
->server
) < 65536 &&
677 pixman_image_get_height(vs
->vd
->server
) >= 0);
678 vs
->client_width
= pixman_image_get_width(vs
->vd
->server
);
679 vs
->client_height
= pixman_image_get_height(vs
->vd
->server
);
681 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
683 vnc_write_u16(vs
, 1); /* number of rects */
684 vnc_framebuffer_update(vs
, 0, 0, vs
->client_width
, vs
->client_height
,
685 VNC_ENCODING_DESKTOPRESIZE
);
686 vnc_unlock_output(vs
);
690 static void vnc_abort_display_jobs(VncDisplay
*vd
)
694 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
697 vnc_unlock_output(vs
);
699 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
702 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
705 vnc_unlock_output(vs
);
709 int vnc_server_fb_stride(VncDisplay
*vd
)
711 return pixman_image_get_stride(vd
->server
);
714 void *vnc_server_fb_ptr(VncDisplay
*vd
, int x
, int y
)
718 ptr
= (uint8_t *)pixman_image_get_data(vd
->server
);
719 ptr
+= y
* vnc_server_fb_stride(vd
);
720 ptr
+= x
* VNC_SERVER_FB_BYTES
;
724 static void vnc_update_server_surface(VncDisplay
*vd
)
728 qemu_pixman_image_unref(vd
->server
);
731 if (QTAILQ_EMPTY(&vd
->clients
)) {
735 width
= vnc_width(vd
);
736 height
= vnc_height(vd
);
737 vd
->server
= pixman_image_create_bits(VNC_SERVER_FB_FORMAT
,
741 memset(vd
->guest
.dirty
, 0x00, sizeof(vd
->guest
.dirty
));
742 vnc_set_area_dirty(vd
->guest
.dirty
, vd
, 0, 0,
746 static void vnc_dpy_switch(DisplayChangeListener
*dcl
,
747 DisplaySurface
*surface
)
749 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
752 vnc_abort_display_jobs(vd
);
756 vnc_update_server_surface(vd
);
759 qemu_pixman_image_unref(vd
->guest
.fb
);
760 vd
->guest
.fb
= pixman_image_ref(surface
->image
);
761 vd
->guest
.format
= surface
->format
;
763 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
765 vnc_desktop_resize(vs
);
766 if (vs
->vd
->cursor
) {
767 vnc_cursor_define(vs
);
769 memset(vs
->dirty
, 0x00, sizeof(vs
->dirty
));
770 vnc_set_area_dirty(vs
->dirty
, vd
, 0, 0,
773 vnc_update_throttle_offset(vs
);
778 static void vnc_write_pixels_copy(VncState
*vs
,
779 void *pixels
, int size
)
781 vnc_write(vs
, pixels
, size
);
784 /* slowest but generic code. */
785 void vnc_convert_pixel(VncState
*vs
, uint8_t *buf
, uint32_t v
)
789 #if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
790 r
= (((v
& 0x00ff0000) >> 16) << vs
->client_pf
.rbits
) >> 8;
791 g
= (((v
& 0x0000ff00) >> 8) << vs
->client_pf
.gbits
) >> 8;
792 b
= (((v
& 0x000000ff) >> 0) << vs
->client_pf
.bbits
) >> 8;
794 # error need some bits here if you change VNC_SERVER_FB_FORMAT
796 v
= (r
<< vs
->client_pf
.rshift
) |
797 (g
<< vs
->client_pf
.gshift
) |
798 (b
<< vs
->client_pf
.bshift
);
799 switch (vs
->client_pf
.bytes_per_pixel
) {
829 static void vnc_write_pixels_generic(VncState
*vs
,
830 void *pixels1
, int size
)
834 if (VNC_SERVER_FB_BYTES
== 4) {
835 uint32_t *pixels
= pixels1
;
838 for (i
= 0; i
< n
; i
++) {
839 vnc_convert_pixel(vs
, buf
, pixels
[i
]);
840 vnc_write(vs
, buf
, vs
->client_pf
.bytes_per_pixel
);
845 int vnc_raw_send_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
)
849 VncDisplay
*vd
= vs
->vd
;
851 row
= vnc_server_fb_ptr(vd
, x
, y
);
852 for (i
= 0; i
< h
; i
++) {
853 vs
->write_pixels(vs
, row
, w
* VNC_SERVER_FB_BYTES
);
854 row
+= vnc_server_fb_stride(vd
);
859 int vnc_send_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
)
862 bool encode_raw
= false;
863 size_t saved_offs
= vs
->output
.offset
;
865 switch(vs
->vnc_encoding
) {
866 case VNC_ENCODING_ZLIB
:
867 n
= vnc_zlib_send_framebuffer_update(vs
, x
, y
, w
, h
);
869 case VNC_ENCODING_HEXTILE
:
870 vnc_framebuffer_update(vs
, x
, y
, w
, h
, VNC_ENCODING_HEXTILE
);
871 n
= vnc_hextile_send_framebuffer_update(vs
, x
, y
, w
, h
);
873 case VNC_ENCODING_TIGHT
:
874 n
= vnc_tight_send_framebuffer_update(vs
, x
, y
, w
, h
);
876 case VNC_ENCODING_TIGHT_PNG
:
877 n
= vnc_tight_png_send_framebuffer_update(vs
, x
, y
, w
, h
);
879 case VNC_ENCODING_ZRLE
:
880 n
= vnc_zrle_send_framebuffer_update(vs
, x
, y
, w
, h
);
882 case VNC_ENCODING_ZYWRLE
:
883 n
= vnc_zywrle_send_framebuffer_update(vs
, x
, y
, w
, h
);
890 /* If the client has the same pixel format as our internal buffer and
891 * a RAW encoding would need less space fall back to RAW encoding to
892 * save bandwidth and processing power in the client. */
893 if (!encode_raw
&& vs
->write_pixels
== vnc_write_pixels_copy
&&
894 12 + h
* w
* VNC_SERVER_FB_BYTES
<= (vs
->output
.offset
- saved_offs
)) {
895 vs
->output
.offset
= saved_offs
;
900 vnc_framebuffer_update(vs
, x
, y
, w
, h
, VNC_ENCODING_RAW
);
901 n
= vnc_raw_send_framebuffer_update(vs
, x
, y
, w
, h
);
907 static void vnc_mouse_set(DisplayChangeListener
*dcl
,
908 int x
, int y
, int visible
)
910 /* can we ask the client(s) to move the pointer ??? */
913 static int vnc_cursor_define(VncState
*vs
)
915 QEMUCursor
*c
= vs
->vd
->cursor
;
918 if (vnc_has_feature(vs
, VNC_FEATURE_RICH_CURSOR
)) {
920 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
921 vnc_write_u8(vs
, 0); /* padding */
922 vnc_write_u16(vs
, 1); /* # of rects */
923 vnc_framebuffer_update(vs
, c
->hot_x
, c
->hot_y
, c
->width
, c
->height
,
924 VNC_ENCODING_RICH_CURSOR
);
925 isize
= c
->width
* c
->height
* vs
->client_pf
.bytes_per_pixel
;
926 vnc_write_pixels_generic(vs
, c
->data
, isize
);
927 vnc_write(vs
, vs
->vd
->cursor_mask
, vs
->vd
->cursor_msize
);
928 vnc_unlock_output(vs
);
934 static void vnc_dpy_cursor_define(DisplayChangeListener
*dcl
,
937 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
940 cursor_put(vd
->cursor
);
941 g_free(vd
->cursor_mask
);
944 cursor_get(vd
->cursor
);
945 vd
->cursor_msize
= cursor_get_mono_bpl(c
) * c
->height
;
946 vd
->cursor_mask
= g_malloc0(vd
->cursor_msize
);
947 cursor_get_mono_mask(c
, 0, vd
->cursor_mask
);
949 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
950 vnc_cursor_define(vs
);
954 static int find_and_clear_dirty_height(VncState
*vs
,
955 int y
, int last_x
, int x
, int height
)
959 for (h
= 1; h
< (height
- y
); h
++) {
960 if (!test_bit(last_x
, vs
->dirty
[y
+ h
])) {
963 bitmap_clear(vs
->dirty
[y
+ h
], last_x
, x
- last_x
);
970 * Figure out how much pending data we should allow in the output
971 * buffer before we throttle incremental display updates, and/or
972 * drop audio samples.
974 * We allow for equiv of 1 full display's worth of FB updates,
975 * and 1 second of audio samples. If audio backlog was larger
976 * than that the client would already suffering awful audio
977 * glitches, so dropping samples is no worse really).
979 static void vnc_update_throttle_offset(VncState
*vs
)
982 vs
->client_width
* vs
->client_height
* vs
->client_pf
.bytes_per_pixel
;
985 int freq
= vs
->as
.freq
;
986 /* We don't limit freq when reading settings from client, so
987 * it could be upto MAX_INT in size. 48khz is a sensible
988 * upper bound for trustworthy clients */
993 switch (vs
->as
.fmt
) {
1008 offset
+= freq
* bps
* vs
->as
.nchannels
;
1011 /* Put a floor of 1MB on offset, so that if we have a large pending
1012 * buffer and the display is resized to a small size & back again
1013 * we don't suddenly apply a tiny send limit
1015 offset
= MAX(offset
, 1024 * 1024);
1017 if (vs
->throttle_output_offset
!= offset
) {
1018 trace_vnc_client_throttle_threshold(
1019 vs
, vs
->ioc
, vs
->throttle_output_offset
, offset
, vs
->client_width
,
1020 vs
->client_height
, vs
->client_pf
.bytes_per_pixel
, vs
->audio_cap
);
1023 vs
->throttle_output_offset
= offset
;
1026 static bool vnc_should_update(VncState
*vs
)
1028 switch (vs
->update
) {
1029 case VNC_STATE_UPDATE_NONE
:
1031 case VNC_STATE_UPDATE_INCREMENTAL
:
1032 /* Only allow incremental updates if the pending send queue
1033 * is less than the permitted threshold, and the job worker
1034 * is completely idle.
1036 if (vs
->output
.offset
< vs
->throttle_output_offset
&&
1037 vs
->job_update
== VNC_STATE_UPDATE_NONE
) {
1040 trace_vnc_client_throttle_incremental(
1041 vs
, vs
->ioc
, vs
->job_update
, vs
->output
.offset
);
1043 case VNC_STATE_UPDATE_FORCE
:
1044 /* Only allow forced updates if the pending send queue
1045 * does not contain a previous forced update, and the
1046 * job worker is completely idle.
1048 * Note this means we'll queue a forced update, even if
1049 * the output buffer size is otherwise over the throttle
1052 if (vs
->force_update_offset
== 0 &&
1053 vs
->job_update
== VNC_STATE_UPDATE_NONE
) {
1056 trace_vnc_client_throttle_forced(
1057 vs
, vs
->ioc
, vs
->job_update
, vs
->force_update_offset
);
1063 static int vnc_update_client(VncState
*vs
, int has_dirty
)
1065 VncDisplay
*vd
= vs
->vd
;
1071 if (vs
->disconnecting
) {
1072 vnc_disconnect_finish(vs
);
1076 vs
->has_dirty
+= has_dirty
;
1077 if (!vnc_should_update(vs
)) {
1081 if (!vs
->has_dirty
&& vs
->update
!= VNC_STATE_UPDATE_FORCE
) {
1086 * Send screen updates to the vnc client using the server
1087 * surface and server dirty map. guest surface updates
1088 * happening in parallel don't disturb us, the next pass will
1089 * send them to the client.
1091 job
= vnc_job_new(vs
);
1093 height
= pixman_image_get_height(vd
->server
);
1094 width
= pixman_image_get_width(vd
->server
);
1100 unsigned long offset
= find_next_bit((unsigned long *) &vs
->dirty
,
1101 height
* VNC_DIRTY_BPL(vs
),
1102 y
* VNC_DIRTY_BPL(vs
));
1103 if (offset
== height
* VNC_DIRTY_BPL(vs
)) {
1104 /* no more dirty bits */
1107 y
= offset
/ VNC_DIRTY_BPL(vs
);
1108 x
= offset
% VNC_DIRTY_BPL(vs
);
1109 x2
= find_next_zero_bit((unsigned long *) &vs
->dirty
[y
],
1110 VNC_DIRTY_BPL(vs
), x
);
1111 bitmap_clear(vs
->dirty
[y
], x
, x2
- x
);
1112 h
= find_and_clear_dirty_height(vs
, y
, x
, x2
, height
);
1113 x2
= MIN(x2
, width
/ VNC_DIRTY_PIXELS_PER_BIT
);
1115 n
+= vnc_job_add_rect(job
, x
* VNC_DIRTY_PIXELS_PER_BIT
, y
,
1116 (x2
- x
) * VNC_DIRTY_PIXELS_PER_BIT
, h
);
1118 if (!x
&& x2
== width
/ VNC_DIRTY_PIXELS_PER_BIT
) {
1126 vs
->job_update
= vs
->update
;
1127 vs
->update
= VNC_STATE_UPDATE_NONE
;
1134 static void audio_capture_notify(void *opaque
, audcnotification_e cmd
)
1136 VncState
*vs
= opaque
;
1139 case AUD_CNOTIFY_DISABLE
:
1140 vnc_lock_output(vs
);
1141 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1142 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1143 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_END
);
1144 vnc_unlock_output(vs
);
1148 case AUD_CNOTIFY_ENABLE
:
1149 vnc_lock_output(vs
);
1150 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1151 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1152 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN
);
1153 vnc_unlock_output(vs
);
1159 static void audio_capture_destroy(void *opaque
)
1163 static void audio_capture(void *opaque
, void *buf
, int size
)
1165 VncState
*vs
= opaque
;
1167 vnc_lock_output(vs
);
1168 if (vs
->output
.offset
< vs
->throttle_output_offset
) {
1169 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1170 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1171 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_DATA
);
1172 vnc_write_u32(vs
, size
);
1173 vnc_write(vs
, buf
, size
);
1175 trace_vnc_client_throttle_audio(vs
, vs
->ioc
, vs
->output
.offset
);
1177 vnc_unlock_output(vs
);
1181 static void audio_add(VncState
*vs
)
1183 struct audio_capture_ops ops
;
1185 if (vs
->audio_cap
) {
1186 error_report("audio already running");
1190 ops
.notify
= audio_capture_notify
;
1191 ops
.destroy
= audio_capture_destroy
;
1192 ops
.capture
= audio_capture
;
1194 vs
->audio_cap
= AUD_add_capture(&vs
->as
, &ops
, vs
);
1195 if (!vs
->audio_cap
) {
1196 error_report("Failed to add audio capture");
1200 static void audio_del(VncState
*vs
)
1202 if (vs
->audio_cap
) {
1203 AUD_del_capture(vs
->audio_cap
, vs
);
1204 vs
->audio_cap
= NULL
;
1208 static void vnc_disconnect_start(VncState
*vs
)
1210 if (vs
->disconnecting
) {
1213 trace_vnc_client_disconnect_start(vs
, vs
->ioc
);
1214 vnc_set_share_mode(vs
, VNC_SHARE_MODE_DISCONNECTED
);
1216 g_source_remove(vs
->ioc_tag
);
1219 qio_channel_close(vs
->ioc
, NULL
);
1220 vs
->disconnecting
= TRUE
;
1223 void vnc_disconnect_finish(VncState
*vs
)
1227 trace_vnc_client_disconnect_finish(vs
, vs
->ioc
);
1229 vnc_jobs_join(vs
); /* Wait encoding jobs */
1231 vnc_lock_output(vs
);
1232 vnc_qmp_event(vs
, QAPI_EVENT_VNC_DISCONNECTED
);
1234 buffer_free(&vs
->input
);
1235 buffer_free(&vs
->output
);
1237 qapi_free_VncClientInfo(vs
->info
);
1240 vnc_tight_clear(vs
);
1243 #ifdef CONFIG_VNC_SASL
1244 vnc_sasl_client_cleanup(vs
);
1245 #endif /* CONFIG_VNC_SASL */
1247 vnc_release_modifiers(vs
);
1249 if (vs
->mouse_mode_notifier
.notify
!= NULL
) {
1250 qemu_remove_mouse_mode_change_notifier(&vs
->mouse_mode_notifier
);
1252 QTAILQ_REMOVE(&vs
->vd
->clients
, vs
, next
);
1253 if (QTAILQ_EMPTY(&vs
->vd
->clients
)) {
1254 /* last client gone */
1255 vnc_update_server_surface(vs
->vd
);
1258 vnc_unlock_output(vs
);
1260 qemu_mutex_destroy(&vs
->output_mutex
);
1261 if (vs
->bh
!= NULL
) {
1262 qemu_bh_delete(vs
->bh
);
1264 buffer_free(&vs
->jobs_buffer
);
1266 for (i
= 0; i
< VNC_STAT_ROWS
; ++i
) {
1267 g_free(vs
->lossy_rect
[i
]);
1269 g_free(vs
->lossy_rect
);
1271 object_unref(OBJECT(vs
->ioc
));
1273 object_unref(OBJECT(vs
->sioc
));
1278 size_t vnc_client_io_error(VncState
*vs
, ssize_t ret
, Error
**errp
)
1282 trace_vnc_client_eof(vs
, vs
->ioc
);
1283 vnc_disconnect_start(vs
);
1284 } else if (ret
!= QIO_CHANNEL_ERR_BLOCK
) {
1285 trace_vnc_client_io_error(vs
, vs
->ioc
,
1286 errp
? error_get_pretty(*errp
) :
1288 vnc_disconnect_start(vs
);
1301 void vnc_client_error(VncState
*vs
)
1303 VNC_DEBUG("Closing down client sock: protocol error\n");
1304 vnc_disconnect_start(vs
);
1309 * Called to write a chunk of data to the client socket. The data may
1310 * be the raw data, or may have already been encoded by SASL.
1311 * The data will be written either straight onto the socket, or
1312 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1314 * NB, it is theoretically possible to have 2 layers of encryption,
1315 * both SASL, and this TLS layer. It is highly unlikely in practice
1316 * though, since SASL encryption will typically be a no-op if TLS
1319 * Returns the number of bytes written, which may be less than
1320 * the requested 'datalen' if the socket would block. Returns
1321 * 0 on I/O error, and disconnects the client socket.
1323 size_t vnc_client_write_buf(VncState
*vs
, const uint8_t *data
, size_t datalen
)
1327 ret
= qio_channel_write(
1328 vs
->ioc
, (const char *)data
, datalen
, &err
);
1329 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data
, datalen
, ret
);
1330 return vnc_client_io_error(vs
, ret
, &err
);
1335 * Called to write buffered data to the client socket, when not
1336 * using any SASL SSF encryption layers. Will write as much data
1337 * as possible without blocking. If all buffered data is written,
1338 * will switch the FD poll() handler back to read monitoring.
1340 * Returns the number of bytes written, which may be less than
1341 * the buffered output data if the socket would block. Returns
1342 * 0 on I/O error, and disconnects the client socket.
1344 static size_t vnc_client_write_plain(VncState
*vs
)
1349 #ifdef CONFIG_VNC_SASL
1350 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1351 vs
->output
.buffer
, vs
->output
.capacity
, vs
->output
.offset
,
1352 vs
->sasl
.waitWriteSSF
);
1354 if (vs
->sasl
.conn
&&
1356 vs
->sasl
.waitWriteSSF
) {
1357 ret
= vnc_client_write_buf(vs
, vs
->output
.buffer
, vs
->sasl
.waitWriteSSF
);
1359 vs
->sasl
.waitWriteSSF
-= ret
;
1361 #endif /* CONFIG_VNC_SASL */
1362 ret
= vnc_client_write_buf(vs
, vs
->output
.buffer
, vs
->output
.offset
);
1366 if (ret
>= vs
->force_update_offset
) {
1367 if (vs
->force_update_offset
!= 0) {
1368 trace_vnc_client_unthrottle_forced(vs
, vs
->ioc
);
1370 vs
->force_update_offset
= 0;
1372 vs
->force_update_offset
-= ret
;
1374 offset
= vs
->output
.offset
;
1375 buffer_advance(&vs
->output
, ret
);
1376 if (offset
>= vs
->throttle_output_offset
&&
1377 vs
->output
.offset
< vs
->throttle_output_offset
) {
1378 trace_vnc_client_unthrottle_incremental(vs
, vs
->ioc
, vs
->output
.offset
);
1381 if (vs
->output
.offset
== 0) {
1383 g_source_remove(vs
->ioc_tag
);
1385 vs
->ioc_tag
= qio_channel_add_watch(
1386 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
1394 * First function called whenever there is data to be written to
1395 * the client socket. Will delegate actual work according to whether
1396 * SASL SSF layers are enabled (thus requiring encryption calls)
1398 static void vnc_client_write_locked(VncState
*vs
)
1400 #ifdef CONFIG_VNC_SASL
1401 if (vs
->sasl
.conn
&&
1403 !vs
->sasl
.waitWriteSSF
) {
1404 vnc_client_write_sasl(vs
);
1406 #endif /* CONFIG_VNC_SASL */
1408 vnc_client_write_plain(vs
);
1412 static void vnc_client_write(VncState
*vs
)
1415 vnc_lock_output(vs
);
1416 if (vs
->output
.offset
) {
1417 vnc_client_write_locked(vs
);
1418 } else if (vs
->ioc
!= NULL
) {
1420 g_source_remove(vs
->ioc_tag
);
1422 vs
->ioc_tag
= qio_channel_add_watch(
1423 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
1425 vnc_unlock_output(vs
);
1428 void vnc_read_when(VncState
*vs
, VncReadEvent
*func
, size_t expecting
)
1430 vs
->read_handler
= func
;
1431 vs
->read_handler_expect
= expecting
;
1436 * Called to read a chunk of data from the client socket. The data may
1437 * be the raw data, or may need to be further decoded by SASL.
1438 * The data will be read either straight from to the socket, or
1439 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1441 * NB, it is theoretically possible to have 2 layers of encryption,
1442 * both SASL, and this TLS layer. It is highly unlikely in practice
1443 * though, since SASL encryption will typically be a no-op if TLS
1446 * Returns the number of bytes read, which may be less than
1447 * the requested 'datalen' if the socket would block. Returns
1448 * 0 on I/O error or EOF, and disconnects the client socket.
1450 size_t vnc_client_read_buf(VncState
*vs
, uint8_t *data
, size_t datalen
)
1454 ret
= qio_channel_read(
1455 vs
->ioc
, (char *)data
, datalen
, &err
);
1456 VNC_DEBUG("Read wire %p %zd -> %ld\n", data
, datalen
, ret
);
1457 return vnc_client_io_error(vs
, ret
, &err
);
1462 * Called to read data from the client socket to the input buffer,
1463 * when not using any SASL SSF encryption layers. Will read as much
1464 * data as possible without blocking.
1466 * Returns the number of bytes read, which may be less than
1467 * the requested 'datalen' if the socket would block. Returns
1468 * 0 on I/O error or EOF, and disconnects the client socket.
1470 static size_t vnc_client_read_plain(VncState
*vs
)
1473 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1474 vs
->input
.buffer
, vs
->input
.capacity
, vs
->input
.offset
);
1475 buffer_reserve(&vs
->input
, 4096);
1476 ret
= vnc_client_read_buf(vs
, buffer_end(&vs
->input
), 4096);
1479 vs
->input
.offset
+= ret
;
1483 static void vnc_jobs_bh(void *opaque
)
1485 VncState
*vs
= opaque
;
1487 vnc_jobs_consume_buffer(vs
);
1491 * First function called whenever there is more data to be read from
1492 * the client socket. Will delegate actual work according to whether
1493 * SASL SSF layers are enabled (thus requiring decryption calls)
1494 * Returns 0 on success, -1 if client disconnected
1496 static int vnc_client_read(VncState
*vs
)
1500 #ifdef CONFIG_VNC_SASL
1501 if (vs
->sasl
.conn
&& vs
->sasl
.runSSF
)
1502 ret
= vnc_client_read_sasl(vs
);
1504 #endif /* CONFIG_VNC_SASL */
1505 ret
= vnc_client_read_plain(vs
);
1507 if (vs
->disconnecting
) {
1508 vnc_disconnect_finish(vs
);
1514 while (vs
->read_handler
&& vs
->input
.offset
>= vs
->read_handler_expect
) {
1515 size_t len
= vs
->read_handler_expect
;
1518 ret
= vs
->read_handler(vs
, vs
->input
.buffer
, len
);
1519 if (vs
->disconnecting
) {
1520 vnc_disconnect_finish(vs
);
1525 buffer_advance(&vs
->input
, len
);
1527 vs
->read_handler_expect
= ret
;
1533 gboolean
vnc_client_io(QIOChannel
*ioc G_GNUC_UNUSED
,
1534 GIOCondition condition
, void *opaque
)
1536 VncState
*vs
= opaque
;
1537 if (condition
& G_IO_IN
) {
1538 if (vnc_client_read(vs
) < 0) {
1542 if (condition
& G_IO_OUT
) {
1543 vnc_client_write(vs
);
1550 * Scale factor to apply to vs->throttle_output_offset when checking for
1551 * hard limit. Worst case normal usage could be x2, if we have a complete
1552 * incremental update and complete forced update in the output buffer.
1553 * So x3 should be good enough, but we pick x5 to be conservative and thus
1554 * (hopefully) never trigger incorrectly.
1556 #define VNC_THROTTLE_OUTPUT_LIMIT_SCALE 5
1558 void vnc_write(VncState
*vs
, const void *data
, size_t len
)
1560 if (vs
->disconnecting
) {
1563 /* Protection against malicious client/guest to prevent our output
1564 * buffer growing without bound if client stops reading data. This
1565 * should rarely trigger, because we have earlier throttling code
1566 * which stops issuing framebuffer updates and drops audio data
1567 * if the throttle_output_offset value is exceeded. So we only reach
1568 * this higher level if a huge number of pseudo-encodings get
1569 * triggered while data can't be sent on the socket.
1571 * NB throttle_output_offset can be zero during early protocol
1572 * handshake, or from the job thread's VncState clone
1574 if (vs
->throttle_output_offset
!= 0 &&
1575 vs
->output
.offset
> (vs
->throttle_output_offset
*
1576 VNC_THROTTLE_OUTPUT_LIMIT_SCALE
)) {
1577 trace_vnc_client_output_limit(vs
, vs
->ioc
, vs
->output
.offset
,
1578 vs
->throttle_output_offset
);
1579 vnc_disconnect_start(vs
);
1582 buffer_reserve(&vs
->output
, len
);
1584 if (vs
->ioc
!= NULL
&& buffer_empty(&vs
->output
)) {
1586 g_source_remove(vs
->ioc_tag
);
1588 vs
->ioc_tag
= qio_channel_add_watch(
1589 vs
->ioc
, G_IO_IN
| G_IO_OUT
, vnc_client_io
, vs
, NULL
);
1592 buffer_append(&vs
->output
, data
, len
);
1595 void vnc_write_s32(VncState
*vs
, int32_t value
)
1597 vnc_write_u32(vs
, *(uint32_t *)&value
);
1600 void vnc_write_u32(VncState
*vs
, uint32_t value
)
1604 buf
[0] = (value
>> 24) & 0xFF;
1605 buf
[1] = (value
>> 16) & 0xFF;
1606 buf
[2] = (value
>> 8) & 0xFF;
1607 buf
[3] = value
& 0xFF;
1609 vnc_write(vs
, buf
, 4);
1612 void vnc_write_u16(VncState
*vs
, uint16_t value
)
1616 buf
[0] = (value
>> 8) & 0xFF;
1617 buf
[1] = value
& 0xFF;
1619 vnc_write(vs
, buf
, 2);
1622 void vnc_write_u8(VncState
*vs
, uint8_t value
)
1624 vnc_write(vs
, (char *)&value
, 1);
1627 void vnc_flush(VncState
*vs
)
1629 vnc_lock_output(vs
);
1630 if (vs
->ioc
!= NULL
&& vs
->output
.offset
) {
1631 vnc_client_write_locked(vs
);
1633 vnc_unlock_output(vs
);
1636 static uint8_t read_u8(uint8_t *data
, size_t offset
)
1638 return data
[offset
];
1641 static uint16_t read_u16(uint8_t *data
, size_t offset
)
1643 return ((data
[offset
] & 0xFF) << 8) | (data
[offset
+ 1] & 0xFF);
1646 static int32_t read_s32(uint8_t *data
, size_t offset
)
1648 return (int32_t)((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
1649 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
1652 uint32_t read_u32(uint8_t *data
, size_t offset
)
1654 return ((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
1655 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
1658 static void client_cut_text(VncState
*vs
, size_t len
, uint8_t *text
)
1662 static void check_pointer_type_change(Notifier
*notifier
, void *data
)
1664 VncState
*vs
= container_of(notifier
, VncState
, mouse_mode_notifier
);
1665 int absolute
= qemu_input_is_absolute();
1667 if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
) && vs
->absolute
!= absolute
) {
1668 vnc_lock_output(vs
);
1669 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1670 vnc_write_u8(vs
, 0);
1671 vnc_write_u16(vs
, 1);
1672 vnc_framebuffer_update(vs
, absolute
, 0,
1673 pixman_image_get_width(vs
->vd
->server
),
1674 pixman_image_get_height(vs
->vd
->server
),
1675 VNC_ENCODING_POINTER_TYPE_CHANGE
);
1676 vnc_unlock_output(vs
);
1679 vs
->absolute
= absolute
;
1682 static void pointer_event(VncState
*vs
, int button_mask
, int x
, int y
)
1684 static uint32_t bmap
[INPUT_BUTTON__MAX
] = {
1685 [INPUT_BUTTON_LEFT
] = 0x01,
1686 [INPUT_BUTTON_MIDDLE
] = 0x02,
1687 [INPUT_BUTTON_RIGHT
] = 0x04,
1688 [INPUT_BUTTON_WHEEL_UP
] = 0x08,
1689 [INPUT_BUTTON_WHEEL_DOWN
] = 0x10,
1691 QemuConsole
*con
= vs
->vd
->dcl
.con
;
1692 int width
= pixman_image_get_width(vs
->vd
->server
);
1693 int height
= pixman_image_get_height(vs
->vd
->server
);
1695 if (vs
->last_bmask
!= button_mask
) {
1696 qemu_input_update_buttons(con
, bmap
, vs
->last_bmask
, button_mask
);
1697 vs
->last_bmask
= button_mask
;
1701 qemu_input_queue_abs(con
, INPUT_AXIS_X
, x
, 0, width
);
1702 qemu_input_queue_abs(con
, INPUT_AXIS_Y
, y
, 0, height
);
1703 } else if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
)) {
1704 qemu_input_queue_rel(con
, INPUT_AXIS_X
, x
- 0x7FFF);
1705 qemu_input_queue_rel(con
, INPUT_AXIS_Y
, y
- 0x7FFF);
1707 if (vs
->last_x
!= -1) {
1708 qemu_input_queue_rel(con
, INPUT_AXIS_X
, x
- vs
->last_x
);
1709 qemu_input_queue_rel(con
, INPUT_AXIS_Y
, y
- vs
->last_y
);
1714 qemu_input_event_sync();
1717 static void reset_keys(VncState
*vs
)
1720 for(i
= 0; i
< 256; i
++) {
1721 if (vs
->modifiers_state
[i
]) {
1722 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, i
, false);
1723 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1724 vs
->modifiers_state
[i
] = 0;
1729 static void press_key(VncState
*vs
, int keysym
)
1731 int keycode
= keysym2scancode(vs
->vd
->kbd_layout
, keysym
) & SCANCODE_KEYMASK
;
1732 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, true);
1733 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1734 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, false);
1735 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1738 static void vnc_led_state_change(VncState
*vs
)
1740 if (!vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
)) {
1744 vnc_lock_output(vs
);
1745 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1746 vnc_write_u8(vs
, 0);
1747 vnc_write_u16(vs
, 1);
1748 vnc_framebuffer_update(vs
, 0, 0, 1, 1, VNC_ENCODING_LED_STATE
);
1749 vnc_write_u8(vs
, vs
->vd
->ledstate
);
1750 vnc_unlock_output(vs
);
1754 static void kbd_leds(void *opaque
, int ledstate
)
1756 VncDisplay
*vd
= opaque
;
1759 trace_vnc_key_guest_leds((ledstate
& QEMU_CAPS_LOCK_LED
),
1760 (ledstate
& QEMU_NUM_LOCK_LED
),
1761 (ledstate
& QEMU_SCROLL_LOCK_LED
));
1763 if (ledstate
== vd
->ledstate
) {
1767 vd
->ledstate
= ledstate
;
1769 QTAILQ_FOREACH(client
, &vd
->clients
, next
) {
1770 vnc_led_state_change(client
);
1774 static void do_key_event(VncState
*vs
, int down
, int keycode
, int sym
)
1776 /* QEMU console switch */
1778 case 0x2a: /* Left Shift */
1779 case 0x36: /* Right Shift */
1780 case 0x1d: /* Left CTRL */
1781 case 0x9d: /* Right CTRL */
1782 case 0x38: /* Left ALT */
1783 case 0xb8: /* Right ALT */
1785 vs
->modifiers_state
[keycode
] = 1;
1787 vs
->modifiers_state
[keycode
] = 0;
1789 case 0x02 ... 0x0a: /* '1' to '9' keys */
1790 if (vs
->vd
->dcl
.con
== NULL
&&
1791 down
&& vs
->modifiers_state
[0x1d] && vs
->modifiers_state
[0x38]) {
1792 /* Reset the modifiers sent to the current console */
1794 console_select(keycode
- 0x02);
1798 case 0x3a: /* CapsLock */
1799 case 0x45: /* NumLock */
1801 vs
->modifiers_state
[keycode
] ^= 1;
1805 /* Turn off the lock state sync logic if the client support the led
1808 if (down
&& vs
->vd
->lock_key_sync
&&
1809 !vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
) &&
1810 keycode_is_keypad(vs
->vd
->kbd_layout
, keycode
)) {
1811 /* If the numlock state needs to change then simulate an additional
1812 keypress before sending this one. This will happen if the user
1813 toggles numlock away from the VNC window.
1815 if (keysym_is_numlock(vs
->vd
->kbd_layout
, sym
& 0xFFFF)) {
1816 if (!vs
->modifiers_state
[0x45]) {
1817 trace_vnc_key_sync_numlock(true);
1818 vs
->modifiers_state
[0x45] = 1;
1819 press_key(vs
, 0xff7f);
1822 if (vs
->modifiers_state
[0x45]) {
1823 trace_vnc_key_sync_numlock(false);
1824 vs
->modifiers_state
[0x45] = 0;
1825 press_key(vs
, 0xff7f);
1830 if (down
&& vs
->vd
->lock_key_sync
&&
1831 !vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
) &&
1832 ((sym
>= 'A' && sym
<= 'Z') || (sym
>= 'a' && sym
<= 'z'))) {
1833 /* If the capslock state needs to change then simulate an additional
1834 keypress before sending this one. This will happen if the user
1835 toggles capslock away from the VNC window.
1837 int uppercase
= !!(sym
>= 'A' && sym
<= 'Z');
1838 int shift
= !!(vs
->modifiers_state
[0x2a] | vs
->modifiers_state
[0x36]);
1839 int capslock
= !!(vs
->modifiers_state
[0x3a]);
1841 if (uppercase
== shift
) {
1842 trace_vnc_key_sync_capslock(false);
1843 vs
->modifiers_state
[0x3a] = 0;
1844 press_key(vs
, 0xffe5);
1847 if (uppercase
!= shift
) {
1848 trace_vnc_key_sync_capslock(true);
1849 vs
->modifiers_state
[0x3a] = 1;
1850 press_key(vs
, 0xffe5);
1855 if (qemu_console_is_graphic(NULL
)) {
1856 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, down
);
1857 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1859 bool numlock
= vs
->modifiers_state
[0x45];
1860 bool control
= (vs
->modifiers_state
[0x1d] ||
1861 vs
->modifiers_state
[0x9d]);
1862 /* QEMU console emulation */
1865 case 0x2a: /* Left Shift */
1866 case 0x36: /* Right Shift */
1867 case 0x1d: /* Left CTRL */
1868 case 0x9d: /* Right CTRL */
1869 case 0x38: /* Left ALT */
1870 case 0xb8: /* Right ALT */
1873 kbd_put_keysym(QEMU_KEY_UP
);
1876 kbd_put_keysym(QEMU_KEY_DOWN
);
1879 kbd_put_keysym(QEMU_KEY_LEFT
);
1882 kbd_put_keysym(QEMU_KEY_RIGHT
);
1885 kbd_put_keysym(QEMU_KEY_DELETE
);
1888 kbd_put_keysym(QEMU_KEY_HOME
);
1891 kbd_put_keysym(QEMU_KEY_END
);
1894 kbd_put_keysym(QEMU_KEY_PAGEUP
);
1897 kbd_put_keysym(QEMU_KEY_PAGEDOWN
);
1901 kbd_put_keysym(numlock
? '7' : QEMU_KEY_HOME
);
1904 kbd_put_keysym(numlock
? '8' : QEMU_KEY_UP
);
1907 kbd_put_keysym(numlock
? '9' : QEMU_KEY_PAGEUP
);
1910 kbd_put_keysym(numlock
? '4' : QEMU_KEY_LEFT
);
1913 kbd_put_keysym('5');
1916 kbd_put_keysym(numlock
? '6' : QEMU_KEY_RIGHT
);
1919 kbd_put_keysym(numlock
? '1' : QEMU_KEY_END
);
1922 kbd_put_keysym(numlock
? '2' : QEMU_KEY_DOWN
);
1925 kbd_put_keysym(numlock
? '3' : QEMU_KEY_PAGEDOWN
);
1928 kbd_put_keysym('0');
1931 kbd_put_keysym(numlock
? '.' : QEMU_KEY_DELETE
);
1935 kbd_put_keysym('/');
1938 kbd_put_keysym('*');
1941 kbd_put_keysym('-');
1944 kbd_put_keysym('+');
1947 kbd_put_keysym('\n');
1952 kbd_put_keysym(sym
& 0x1f);
1954 kbd_put_keysym(sym
);
1962 static void vnc_release_modifiers(VncState
*vs
)
1964 static const int keycodes
[] = {
1965 /* shift, control, alt keys, both left & right */
1966 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
1970 if (!qemu_console_is_graphic(NULL
)) {
1973 for (i
= 0; i
< ARRAY_SIZE(keycodes
); i
++) {
1974 keycode
= keycodes
[i
];
1975 if (!vs
->modifiers_state
[keycode
]) {
1978 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, false);
1979 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1983 static const char *code2name(int keycode
)
1985 return QKeyCode_str(qemu_input_key_number_to_qcode(keycode
));
1988 static void key_event(VncState
*vs
, int down
, uint32_t sym
)
1993 if (lsym
>= 'A' && lsym
<= 'Z' && qemu_console_is_graphic(NULL
)) {
1994 lsym
= lsym
- 'A' + 'a';
1997 keycode
= keysym2scancode(vs
->vd
->kbd_layout
, lsym
& 0xFFFF) & SCANCODE_KEYMASK
;
1998 trace_vnc_key_event_map(down
, sym
, keycode
, code2name(keycode
));
1999 do_key_event(vs
, down
, keycode
, sym
);
2002 static void ext_key_event(VncState
*vs
, int down
,
2003 uint32_t sym
, uint16_t keycode
)
2005 /* if the user specifies a keyboard layout, always use it */
2006 if (keyboard_layout
) {
2007 key_event(vs
, down
, sym
);
2009 trace_vnc_key_event_ext(down
, sym
, keycode
, code2name(keycode
));
2010 do_key_event(vs
, down
, keycode
, sym
);
2014 static void framebuffer_update_request(VncState
*vs
, int incremental
,
2015 int x
, int y
, int w
, int h
)
2018 if (vs
->update
!= VNC_STATE_UPDATE_FORCE
) {
2019 vs
->update
= VNC_STATE_UPDATE_INCREMENTAL
;
2022 vs
->update
= VNC_STATE_UPDATE_FORCE
;
2023 vnc_set_area_dirty(vs
->dirty
, vs
->vd
, x
, y
, w
, h
);
2027 static void send_ext_key_event_ack(VncState
*vs
)
2029 vnc_lock_output(vs
);
2030 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
2031 vnc_write_u8(vs
, 0);
2032 vnc_write_u16(vs
, 1);
2033 vnc_framebuffer_update(vs
, 0, 0,
2034 pixman_image_get_width(vs
->vd
->server
),
2035 pixman_image_get_height(vs
->vd
->server
),
2036 VNC_ENCODING_EXT_KEY_EVENT
);
2037 vnc_unlock_output(vs
);
2041 static void send_ext_audio_ack(VncState
*vs
)
2043 vnc_lock_output(vs
);
2044 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
2045 vnc_write_u8(vs
, 0);
2046 vnc_write_u16(vs
, 1);
2047 vnc_framebuffer_update(vs
, 0, 0,
2048 pixman_image_get_width(vs
->vd
->server
),
2049 pixman_image_get_height(vs
->vd
->server
),
2050 VNC_ENCODING_AUDIO
);
2051 vnc_unlock_output(vs
);
2055 static void set_encodings(VncState
*vs
, int32_t *encodings
, size_t n_encodings
)
2058 unsigned int enc
= 0;
2061 vs
->vnc_encoding
= 0;
2062 vs
->tight
.compression
= 9;
2063 vs
->tight
.quality
= -1; /* Lossless by default */
2067 * Start from the end because the encodings are sent in order of preference.
2068 * This way the preferred encoding (first encoding defined in the array)
2069 * will be set at the end of the loop.
2071 for (i
= n_encodings
- 1; i
>= 0; i
--) {
2074 case VNC_ENCODING_RAW
:
2075 vs
->vnc_encoding
= enc
;
2077 case VNC_ENCODING_COPYRECT
:
2078 vs
->features
|= VNC_FEATURE_COPYRECT_MASK
;
2080 case VNC_ENCODING_HEXTILE
:
2081 vs
->features
|= VNC_FEATURE_HEXTILE_MASK
;
2082 vs
->vnc_encoding
= enc
;
2084 case VNC_ENCODING_TIGHT
:
2085 vs
->features
|= VNC_FEATURE_TIGHT_MASK
;
2086 vs
->vnc_encoding
= enc
;
2088 #ifdef CONFIG_VNC_PNG
2089 case VNC_ENCODING_TIGHT_PNG
:
2090 vs
->features
|= VNC_FEATURE_TIGHT_PNG_MASK
;
2091 vs
->vnc_encoding
= enc
;
2094 case VNC_ENCODING_ZLIB
:
2095 vs
->features
|= VNC_FEATURE_ZLIB_MASK
;
2096 vs
->vnc_encoding
= enc
;
2098 case VNC_ENCODING_ZRLE
:
2099 vs
->features
|= VNC_FEATURE_ZRLE_MASK
;
2100 vs
->vnc_encoding
= enc
;
2102 case VNC_ENCODING_ZYWRLE
:
2103 vs
->features
|= VNC_FEATURE_ZYWRLE_MASK
;
2104 vs
->vnc_encoding
= enc
;
2106 case VNC_ENCODING_DESKTOPRESIZE
:
2107 vs
->features
|= VNC_FEATURE_RESIZE_MASK
;
2109 case VNC_ENCODING_POINTER_TYPE_CHANGE
:
2110 vs
->features
|= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK
;
2112 case VNC_ENCODING_RICH_CURSOR
:
2113 vs
->features
|= VNC_FEATURE_RICH_CURSOR_MASK
;
2114 if (vs
->vd
->cursor
) {
2115 vnc_cursor_define(vs
);
2118 case VNC_ENCODING_EXT_KEY_EVENT
:
2119 send_ext_key_event_ack(vs
);
2121 case VNC_ENCODING_AUDIO
:
2122 send_ext_audio_ack(vs
);
2124 case VNC_ENCODING_WMVi
:
2125 vs
->features
|= VNC_FEATURE_WMVI_MASK
;
2127 case VNC_ENCODING_LED_STATE
:
2128 vs
->features
|= VNC_FEATURE_LED_STATE_MASK
;
2130 case VNC_ENCODING_COMPRESSLEVEL0
... VNC_ENCODING_COMPRESSLEVEL0
+ 9:
2131 vs
->tight
.compression
= (enc
& 0x0F);
2133 case VNC_ENCODING_QUALITYLEVEL0
... VNC_ENCODING_QUALITYLEVEL0
+ 9:
2134 if (vs
->vd
->lossy
) {
2135 vs
->tight
.quality
= (enc
& 0x0F);
2139 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i
, enc
, enc
);
2143 vnc_desktop_resize(vs
);
2144 check_pointer_type_change(&vs
->mouse_mode_notifier
, NULL
);
2145 vnc_led_state_change(vs
);
2148 static void set_pixel_conversion(VncState
*vs
)
2150 pixman_format_code_t fmt
= qemu_pixman_get_format(&vs
->client_pf
);
2152 if (fmt
== VNC_SERVER_FB_FORMAT
) {
2153 vs
->write_pixels
= vnc_write_pixels_copy
;
2154 vnc_hextile_set_pixel_conversion(vs
, 0);
2156 vs
->write_pixels
= vnc_write_pixels_generic
;
2157 vnc_hextile_set_pixel_conversion(vs
, 1);
2161 static void send_color_map(VncState
*vs
)
2165 vnc_write_u8(vs
, VNC_MSG_SERVER_SET_COLOUR_MAP_ENTRIES
);
2166 vnc_write_u8(vs
, 0); /* padding */
2167 vnc_write_u16(vs
, 0); /* first color */
2168 vnc_write_u16(vs
, 256); /* # of colors */
2170 for (i
= 0; i
< 256; i
++) {
2171 PixelFormat
*pf
= &vs
->client_pf
;
2173 vnc_write_u16(vs
, (((i
>> pf
->rshift
) & pf
->rmax
) << (16 - pf
->rbits
)));
2174 vnc_write_u16(vs
, (((i
>> pf
->gshift
) & pf
->gmax
) << (16 - pf
->gbits
)));
2175 vnc_write_u16(vs
, (((i
>> pf
->bshift
) & pf
->bmax
) << (16 - pf
->bbits
)));
2179 static void set_pixel_format(VncState
*vs
, int bits_per_pixel
,
2180 int big_endian_flag
, int true_color_flag
,
2181 int red_max
, int green_max
, int blue_max
,
2182 int red_shift
, int green_shift
, int blue_shift
)
2184 if (!true_color_flag
) {
2185 /* Expose a reasonable default 256 color map */
2195 switch (bits_per_pixel
) {
2201 vnc_client_error(vs
);
2205 vs
->client_pf
.rmax
= red_max
? red_max
: 0xFF;
2206 vs
->client_pf
.rbits
= ctpopl(red_max
);
2207 vs
->client_pf
.rshift
= red_shift
;
2208 vs
->client_pf
.rmask
= red_max
<< red_shift
;
2209 vs
->client_pf
.gmax
= green_max
? green_max
: 0xFF;
2210 vs
->client_pf
.gbits
= ctpopl(green_max
);
2211 vs
->client_pf
.gshift
= green_shift
;
2212 vs
->client_pf
.gmask
= green_max
<< green_shift
;
2213 vs
->client_pf
.bmax
= blue_max
? blue_max
: 0xFF;
2214 vs
->client_pf
.bbits
= ctpopl(blue_max
);
2215 vs
->client_pf
.bshift
= blue_shift
;
2216 vs
->client_pf
.bmask
= blue_max
<< blue_shift
;
2217 vs
->client_pf
.bits_per_pixel
= bits_per_pixel
;
2218 vs
->client_pf
.bytes_per_pixel
= bits_per_pixel
/ 8;
2219 vs
->client_pf
.depth
= bits_per_pixel
== 32 ? 24 : bits_per_pixel
;
2220 vs
->client_be
= big_endian_flag
;
2222 if (!true_color_flag
) {
2226 set_pixel_conversion(vs
);
2228 graphic_hw_invalidate(vs
->vd
->dcl
.con
);
2229 graphic_hw_update(vs
->vd
->dcl
.con
);
2232 static void pixel_format_message (VncState
*vs
) {
2233 char pad
[3] = { 0, 0, 0 };
2235 vs
->client_pf
= qemu_default_pixelformat(32);
2237 vnc_write_u8(vs
, vs
->client_pf
.bits_per_pixel
); /* bits-per-pixel */
2238 vnc_write_u8(vs
, vs
->client_pf
.depth
); /* depth */
2240 #ifdef HOST_WORDS_BIGENDIAN
2241 vnc_write_u8(vs
, 1); /* big-endian-flag */
2243 vnc_write_u8(vs
, 0); /* big-endian-flag */
2245 vnc_write_u8(vs
, 1); /* true-color-flag */
2246 vnc_write_u16(vs
, vs
->client_pf
.rmax
); /* red-max */
2247 vnc_write_u16(vs
, vs
->client_pf
.gmax
); /* green-max */
2248 vnc_write_u16(vs
, vs
->client_pf
.bmax
); /* blue-max */
2249 vnc_write_u8(vs
, vs
->client_pf
.rshift
); /* red-shift */
2250 vnc_write_u8(vs
, vs
->client_pf
.gshift
); /* green-shift */
2251 vnc_write_u8(vs
, vs
->client_pf
.bshift
); /* blue-shift */
2252 vnc_write(vs
, pad
, 3); /* padding */
2254 vnc_hextile_set_pixel_conversion(vs
, 0);
2255 vs
->write_pixels
= vnc_write_pixels_copy
;
2258 static void vnc_colordepth(VncState
*vs
)
2260 if (vnc_has_feature(vs
, VNC_FEATURE_WMVI
)) {
2261 /* Sending a WMVi message to notify the client*/
2262 vnc_lock_output(vs
);
2263 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
2264 vnc_write_u8(vs
, 0);
2265 vnc_write_u16(vs
, 1); /* number of rects */
2266 vnc_framebuffer_update(vs
, 0, 0,
2267 pixman_image_get_width(vs
->vd
->server
),
2268 pixman_image_get_height(vs
->vd
->server
),
2270 pixel_format_message(vs
);
2271 vnc_unlock_output(vs
);
2274 set_pixel_conversion(vs
);
2278 static int protocol_client_msg(VncState
*vs
, uint8_t *data
, size_t len
)
2282 VncDisplay
*vd
= vs
->vd
;
2285 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2289 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT
:
2293 set_pixel_format(vs
, read_u8(data
, 4),
2294 read_u8(data
, 6), read_u8(data
, 7),
2295 read_u16(data
, 8), read_u16(data
, 10),
2296 read_u16(data
, 12), read_u8(data
, 14),
2297 read_u8(data
, 15), read_u8(data
, 16));
2299 case VNC_MSG_CLIENT_SET_ENCODINGS
:
2304 limit
= read_u16(data
, 2);
2306 return 4 + (limit
* 4);
2308 limit
= read_u16(data
, 2);
2310 for (i
= 0; i
< limit
; i
++) {
2311 int32_t val
= read_s32(data
, 4 + (i
* 4));
2312 memcpy(data
+ 4 + (i
* 4), &val
, sizeof(val
));
2315 set_encodings(vs
, (int32_t *)(data
+ 4), limit
);
2317 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST
:
2321 framebuffer_update_request(vs
,
2322 read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4),
2323 read_u16(data
, 6), read_u16(data
, 8));
2325 case VNC_MSG_CLIENT_KEY_EVENT
:
2329 key_event(vs
, read_u8(data
, 1), read_u32(data
, 4));
2331 case VNC_MSG_CLIENT_POINTER_EVENT
:
2335 pointer_event(vs
, read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4));
2337 case VNC_MSG_CLIENT_CUT_TEXT
:
2342 uint32_t dlen
= read_u32(data
, 4);
2343 if (dlen
> (1 << 20)) {
2344 error_report("vnc: client_cut_text msg payload has %u bytes"
2345 " which exceeds our limit of 1MB.", dlen
);
2346 vnc_client_error(vs
);
2354 client_cut_text(vs
, read_u32(data
, 4), data
+ 8);
2356 case VNC_MSG_CLIENT_QEMU
:
2360 switch (read_u8(data
, 1)) {
2361 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT
:
2365 ext_key_event(vs
, read_u16(data
, 2),
2366 read_u32(data
, 4), read_u32(data
, 8));
2368 case VNC_MSG_CLIENT_QEMU_AUDIO
:
2372 switch (read_u16 (data
, 2)) {
2373 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE
:
2376 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE
:
2379 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT
:
2382 switch (read_u8(data
, 4)) {
2383 case 0: vs
->as
.fmt
= AUD_FMT_U8
; break;
2384 case 1: vs
->as
.fmt
= AUD_FMT_S8
; break;
2385 case 2: vs
->as
.fmt
= AUD_FMT_U16
; break;
2386 case 3: vs
->as
.fmt
= AUD_FMT_S16
; break;
2387 case 4: vs
->as
.fmt
= AUD_FMT_U32
; break;
2388 case 5: vs
->as
.fmt
= AUD_FMT_S32
; break;
2390 VNC_DEBUG("Invalid audio format %d\n", read_u8(data
, 4));
2391 vnc_client_error(vs
);
2394 vs
->as
.nchannels
= read_u8(data
, 5);
2395 if (vs
->as
.nchannels
!= 1 && vs
->as
.nchannels
!= 2) {
2396 VNC_DEBUG("Invalid audio channel count %d\n",
2398 vnc_client_error(vs
);
2401 vs
->as
.freq
= read_u32(data
, 6);
2404 VNC_DEBUG("Invalid audio message %d\n", read_u8(data
, 4));
2405 vnc_client_error(vs
);
2411 VNC_DEBUG("Msg: %d\n", read_u16(data
, 0));
2412 vnc_client_error(vs
);
2417 VNC_DEBUG("Msg: %d\n", data
[0]);
2418 vnc_client_error(vs
);
2422 vnc_update_throttle_offset(vs
);
2423 vnc_read_when(vs
, protocol_client_msg
, 1);
2427 static int protocol_client_init(VncState
*vs
, uint8_t *data
, size_t len
)
2433 mode
= data
[0] ? VNC_SHARE_MODE_SHARED
: VNC_SHARE_MODE_EXCLUSIVE
;
2434 switch (vs
->vd
->share_policy
) {
2435 case VNC_SHARE_POLICY_IGNORE
:
2437 * Ignore the shared flag. Nothing to do here.
2439 * Doesn't conform to the rfb spec but is traditional qemu
2440 * behavior, thus left here as option for compatibility
2444 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
:
2446 * Policy: Allow clients ask for exclusive access.
2448 * Implementation: When a client asks for exclusive access,
2449 * disconnect all others. Shared connects are allowed as long
2450 * as no exclusive connection exists.
2452 * This is how the rfb spec suggests to handle the shared flag.
2454 if (mode
== VNC_SHARE_MODE_EXCLUSIVE
) {
2456 QTAILQ_FOREACH(client
, &vs
->vd
->clients
, next
) {
2460 if (client
->share_mode
!= VNC_SHARE_MODE_EXCLUSIVE
&&
2461 client
->share_mode
!= VNC_SHARE_MODE_SHARED
) {
2464 vnc_disconnect_start(client
);
2467 if (mode
== VNC_SHARE_MODE_SHARED
) {
2468 if (vs
->vd
->num_exclusive
> 0) {
2469 vnc_disconnect_start(vs
);
2474 case VNC_SHARE_POLICY_FORCE_SHARED
:
2476 * Policy: Shared connects only.
2477 * Implementation: Disallow clients asking for exclusive access.
2479 * Useful for shared desktop sessions where you don't want
2480 * someone forgetting to say -shared when running the vnc
2481 * client disconnect everybody else.
2483 if (mode
== VNC_SHARE_MODE_EXCLUSIVE
) {
2484 vnc_disconnect_start(vs
);
2489 vnc_set_share_mode(vs
, mode
);
2491 if (vs
->vd
->num_shared
> vs
->vd
->connections_limit
) {
2492 vnc_disconnect_start(vs
);
2496 assert(pixman_image_get_width(vs
->vd
->server
) < 65536 &&
2497 pixman_image_get_width(vs
->vd
->server
) >= 0);
2498 assert(pixman_image_get_height(vs
->vd
->server
) < 65536 &&
2499 pixman_image_get_height(vs
->vd
->server
) >= 0);
2500 vs
->client_width
= pixman_image_get_width(vs
->vd
->server
);
2501 vs
->client_height
= pixman_image_get_height(vs
->vd
->server
);
2502 vnc_write_u16(vs
, vs
->client_width
);
2503 vnc_write_u16(vs
, vs
->client_height
);
2505 pixel_format_message(vs
);
2508 size
= snprintf(buf
, sizeof(buf
), "QEMU (%s)", qemu_name
);
2509 if (size
> sizeof(buf
)) {
2513 size
= snprintf(buf
, sizeof(buf
), "QEMU");
2516 vnc_write_u32(vs
, size
);
2517 vnc_write(vs
, buf
, size
);
2520 vnc_client_cache_auth(vs
);
2521 vnc_qmp_event(vs
, QAPI_EVENT_VNC_INITIALIZED
);
2523 vnc_read_when(vs
, protocol_client_msg
, 1);
2528 void start_client_init(VncState
*vs
)
2530 vnc_read_when(vs
, protocol_client_init
, 1);
2533 static void make_challenge(VncState
*vs
)
2537 srand(time(NULL
)+getpid()+getpid()*987654+rand());
2539 for (i
= 0 ; i
< sizeof(vs
->challenge
) ; i
++)
2540 vs
->challenge
[i
] = (int) (256.0*rand()/(RAND_MAX
+1.0));
2543 static int protocol_client_auth_vnc(VncState
*vs
, uint8_t *data
, size_t len
)
2545 unsigned char response
[VNC_AUTH_CHALLENGE_SIZE
];
2547 unsigned char key
[8];
2548 time_t now
= time(NULL
);
2549 QCryptoCipher
*cipher
= NULL
;
2552 if (!vs
->vd
->password
) {
2553 trace_vnc_auth_fail(vs
, vs
->auth
, "password is not set", "");
2556 if (vs
->vd
->expires
< now
) {
2557 trace_vnc_auth_fail(vs
, vs
->auth
, "password is expired", "");
2561 memcpy(response
, vs
->challenge
, VNC_AUTH_CHALLENGE_SIZE
);
2563 /* Calculate the expected challenge response */
2564 pwlen
= strlen(vs
->vd
->password
);
2565 for (i
=0; i
<sizeof(key
); i
++)
2566 key
[i
] = i
<pwlen
? vs
->vd
->password
[i
] : 0;
2568 cipher
= qcrypto_cipher_new(
2569 QCRYPTO_CIPHER_ALG_DES_RFB
,
2570 QCRYPTO_CIPHER_MODE_ECB
,
2571 key
, G_N_ELEMENTS(key
),
2574 trace_vnc_auth_fail(vs
, vs
->auth
, "cannot create cipher",
2575 error_get_pretty(err
));
2580 if (qcrypto_cipher_encrypt(cipher
,
2583 VNC_AUTH_CHALLENGE_SIZE
,
2585 trace_vnc_auth_fail(vs
, vs
->auth
, "cannot encrypt challenge response",
2586 error_get_pretty(err
));
2591 /* Compare expected vs actual challenge response */
2592 if (memcmp(response
, data
, VNC_AUTH_CHALLENGE_SIZE
) != 0) {
2593 trace_vnc_auth_fail(vs
, vs
->auth
, "mis-matched challenge response", "");
2596 trace_vnc_auth_pass(vs
, vs
->auth
);
2597 vnc_write_u32(vs
, 0); /* Accept auth */
2600 start_client_init(vs
);
2603 qcrypto_cipher_free(cipher
);
2607 vnc_write_u32(vs
, 1); /* Reject auth */
2608 if (vs
->minor
>= 8) {
2609 static const char err
[] = "Authentication failed";
2610 vnc_write_u32(vs
, sizeof(err
));
2611 vnc_write(vs
, err
, sizeof(err
));
2614 vnc_client_error(vs
);
2615 qcrypto_cipher_free(cipher
);
2619 void start_auth_vnc(VncState
*vs
)
2622 /* Send client a 'random' challenge */
2623 vnc_write(vs
, vs
->challenge
, sizeof(vs
->challenge
));
2626 vnc_read_when(vs
, protocol_client_auth_vnc
, sizeof(vs
->challenge
));
2630 static int protocol_client_auth(VncState
*vs
, uint8_t *data
, size_t len
)
2632 /* We only advertise 1 auth scheme at a time, so client
2633 * must pick the one we sent. Verify this */
2634 if (data
[0] != vs
->auth
) { /* Reject auth */
2635 trace_vnc_auth_reject(vs
, vs
->auth
, (int)data
[0]);
2636 vnc_write_u32(vs
, 1);
2637 if (vs
->minor
>= 8) {
2638 static const char err
[] = "Authentication failed";
2639 vnc_write_u32(vs
, sizeof(err
));
2640 vnc_write(vs
, err
, sizeof(err
));
2642 vnc_client_error(vs
);
2643 } else { /* Accept requested auth */
2644 trace_vnc_auth_start(vs
, vs
->auth
);
2647 if (vs
->minor
>= 8) {
2648 vnc_write_u32(vs
, 0); /* Accept auth completion */
2651 trace_vnc_auth_pass(vs
, vs
->auth
);
2652 start_client_init(vs
);
2659 case VNC_AUTH_VENCRYPT
:
2660 start_auth_vencrypt(vs
);
2663 #ifdef CONFIG_VNC_SASL
2665 start_auth_sasl(vs
);
2667 #endif /* CONFIG_VNC_SASL */
2669 default: /* Should not be possible, but just in case */
2670 trace_vnc_auth_fail(vs
, vs
->auth
, "Unhandled auth method", "");
2671 vnc_write_u8(vs
, 1);
2672 if (vs
->minor
>= 8) {
2673 static const char err
[] = "Authentication failed";
2674 vnc_write_u32(vs
, sizeof(err
));
2675 vnc_write(vs
, err
, sizeof(err
));
2677 vnc_client_error(vs
);
2683 static int protocol_version(VncState
*vs
, uint8_t *version
, size_t len
)
2687 memcpy(local
, version
, 12);
2690 if (sscanf(local
, "RFB %03d.%03d\n", &vs
->major
, &vs
->minor
) != 2) {
2691 VNC_DEBUG("Malformed protocol version %s\n", local
);
2692 vnc_client_error(vs
);
2695 VNC_DEBUG("Client request protocol version %d.%d\n", vs
->major
, vs
->minor
);
2696 if (vs
->major
!= 3 ||
2702 VNC_DEBUG("Unsupported client version\n");
2703 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2705 vnc_client_error(vs
);
2708 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2709 * as equivalent to v3.3 by servers
2711 if (vs
->minor
== 4 || vs
->minor
== 5)
2714 if (vs
->minor
== 3) {
2715 trace_vnc_auth_start(vs
, vs
->auth
);
2716 if (vs
->auth
== VNC_AUTH_NONE
) {
2717 vnc_write_u32(vs
, vs
->auth
);
2719 trace_vnc_auth_pass(vs
, vs
->auth
);
2720 start_client_init(vs
);
2721 } else if (vs
->auth
== VNC_AUTH_VNC
) {
2722 VNC_DEBUG("Tell client VNC auth\n");
2723 vnc_write_u32(vs
, vs
->auth
);
2727 trace_vnc_auth_fail(vs
, vs
->auth
,
2728 "Unsupported auth method for v3.3", "");
2729 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2731 vnc_client_error(vs
);
2734 vnc_write_u8(vs
, 1); /* num auth */
2735 vnc_write_u8(vs
, vs
->auth
);
2736 vnc_read_when(vs
, protocol_client_auth
, 1);
2743 static VncRectStat
*vnc_stat_rect(VncDisplay
*vd
, int x
, int y
)
2745 struct VncSurface
*vs
= &vd
->guest
;
2747 return &vs
->stats
[y
/ VNC_STAT_RECT
][x
/ VNC_STAT_RECT
];
2750 void vnc_sent_lossy_rect(VncState
*vs
, int x
, int y
, int w
, int h
)
2754 w
= (x
+ w
) / VNC_STAT_RECT
;
2755 h
= (y
+ h
) / VNC_STAT_RECT
;
2759 for (j
= y
; j
<= h
; j
++) {
2760 for (i
= x
; i
<= w
; i
++) {
2761 vs
->lossy_rect
[j
][i
] = 1;
2766 static int vnc_refresh_lossy_rect(VncDisplay
*vd
, int x
, int y
)
2769 int sty
= y
/ VNC_STAT_RECT
;
2770 int stx
= x
/ VNC_STAT_RECT
;
2773 y
= QEMU_ALIGN_DOWN(y
, VNC_STAT_RECT
);
2774 x
= QEMU_ALIGN_DOWN(x
, VNC_STAT_RECT
);
2776 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2779 /* kernel send buffers are full -> refresh later */
2780 if (vs
->output
.offset
) {
2784 if (!vs
->lossy_rect
[sty
][stx
]) {
2788 vs
->lossy_rect
[sty
][stx
] = 0;
2789 for (j
= 0; j
< VNC_STAT_RECT
; ++j
) {
2790 bitmap_set(vs
->dirty
[y
+ j
],
2791 x
/ VNC_DIRTY_PIXELS_PER_BIT
,
2792 VNC_STAT_RECT
/ VNC_DIRTY_PIXELS_PER_BIT
);
2800 static int vnc_update_stats(VncDisplay
*vd
, struct timeval
* tv
)
2802 int width
= MIN(pixman_image_get_width(vd
->guest
.fb
),
2803 pixman_image_get_width(vd
->server
));
2804 int height
= MIN(pixman_image_get_height(vd
->guest
.fb
),
2805 pixman_image_get_height(vd
->server
));
2810 for (y
= 0; y
< height
; y
+= VNC_STAT_RECT
) {
2811 for (x
= 0; x
< width
; x
+= VNC_STAT_RECT
) {
2812 VncRectStat
*rect
= vnc_stat_rect(vd
, x
, y
);
2814 rect
->updated
= false;
2818 qemu_timersub(tv
, &VNC_REFRESH_STATS
, &res
);
2820 if (timercmp(&vd
->guest
.last_freq_check
, &res
, >)) {
2823 vd
->guest
.last_freq_check
= *tv
;
2825 for (y
= 0; y
< height
; y
+= VNC_STAT_RECT
) {
2826 for (x
= 0; x
< width
; x
+= VNC_STAT_RECT
) {
2827 VncRectStat
*rect
= vnc_stat_rect(vd
, x
, y
);
2828 int count
= ARRAY_SIZE(rect
->times
);
2829 struct timeval min
, max
;
2831 if (!timerisset(&rect
->times
[count
- 1])) {
2835 max
= rect
->times
[(rect
->idx
+ count
- 1) % count
];
2836 qemu_timersub(tv
, &max
, &res
);
2838 if (timercmp(&res
, &VNC_REFRESH_LOSSY
, >)) {
2840 has_dirty
+= vnc_refresh_lossy_rect(vd
, x
, y
);
2841 memset(rect
->times
, 0, sizeof (rect
->times
));
2845 min
= rect
->times
[rect
->idx
];
2846 max
= rect
->times
[(rect
->idx
+ count
- 1) % count
];
2847 qemu_timersub(&max
, &min
, &res
);
2849 rect
->freq
= res
.tv_sec
+ res
.tv_usec
/ 1000000.;
2850 rect
->freq
/= count
;
2851 rect
->freq
= 1. / rect
->freq
;
2857 double vnc_update_freq(VncState
*vs
, int x
, int y
, int w
, int h
)
2863 x
= QEMU_ALIGN_DOWN(x
, VNC_STAT_RECT
);
2864 y
= QEMU_ALIGN_DOWN(y
, VNC_STAT_RECT
);
2866 for (j
= y
; j
<= y
+ h
; j
+= VNC_STAT_RECT
) {
2867 for (i
= x
; i
<= x
+ w
; i
+= VNC_STAT_RECT
) {
2868 total
+= vnc_stat_rect(vs
->vd
, i
, j
)->freq
;
2880 static void vnc_rect_updated(VncDisplay
*vd
, int x
, int y
, struct timeval
* tv
)
2884 rect
= vnc_stat_rect(vd
, x
, y
);
2885 if (rect
->updated
) {
2888 rect
->times
[rect
->idx
] = *tv
;
2889 rect
->idx
= (rect
->idx
+ 1) % ARRAY_SIZE(rect
->times
);
2890 rect
->updated
= true;
2893 static int vnc_refresh_server_surface(VncDisplay
*vd
)
2895 int width
= MIN(pixman_image_get_width(vd
->guest
.fb
),
2896 pixman_image_get_width(vd
->server
));
2897 int height
= MIN(pixman_image_get_height(vd
->guest
.fb
),
2898 pixman_image_get_height(vd
->server
));
2899 int cmp_bytes
, server_stride
, line_bytes
, guest_ll
, guest_stride
, y
= 0;
2900 uint8_t *guest_row0
= NULL
, *server_row0
;
2903 pixman_image_t
*tmpbuf
= NULL
;
2905 struct timeval tv
= { 0, 0 };
2907 if (!vd
->non_adaptive
) {
2908 gettimeofday(&tv
, NULL
);
2909 has_dirty
= vnc_update_stats(vd
, &tv
);
2913 * Walk through the guest dirty map.
2914 * Check and copy modified bits from guest to server surface.
2915 * Update server dirty map.
2917 server_row0
= (uint8_t *)pixman_image_get_data(vd
->server
);
2918 server_stride
= guest_stride
= guest_ll
=
2919 pixman_image_get_stride(vd
->server
);
2920 cmp_bytes
= MIN(VNC_DIRTY_PIXELS_PER_BIT
* VNC_SERVER_FB_BYTES
,
2922 if (vd
->guest
.format
!= VNC_SERVER_FB_FORMAT
) {
2923 int width
= pixman_image_get_width(vd
->server
);
2924 tmpbuf
= qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT
, width
);
2927 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd
->guest
.fb
));
2928 guest_row0
= (uint8_t *)pixman_image_get_data(vd
->guest
.fb
);
2929 guest_stride
= pixman_image_get_stride(vd
->guest
.fb
);
2930 guest_ll
= pixman_image_get_width(vd
->guest
.fb
) * (DIV_ROUND_UP(guest_bpp
, 8));
2932 line_bytes
= MIN(server_stride
, guest_ll
);
2936 uint8_t *guest_ptr
, *server_ptr
;
2937 unsigned long offset
= find_next_bit((unsigned long *) &vd
->guest
.dirty
,
2938 height
* VNC_DIRTY_BPL(&vd
->guest
),
2939 y
* VNC_DIRTY_BPL(&vd
->guest
));
2940 if (offset
== height
* VNC_DIRTY_BPL(&vd
->guest
)) {
2941 /* no more dirty bits */
2944 y
= offset
/ VNC_DIRTY_BPL(&vd
->guest
);
2945 x
= offset
% VNC_DIRTY_BPL(&vd
->guest
);
2947 server_ptr
= server_row0
+ y
* server_stride
+ x
* cmp_bytes
;
2949 if (vd
->guest
.format
!= VNC_SERVER_FB_FORMAT
) {
2950 qemu_pixman_linebuf_fill(tmpbuf
, vd
->guest
.fb
, width
, 0, y
);
2951 guest_ptr
= (uint8_t *)pixman_image_get_data(tmpbuf
);
2953 guest_ptr
= guest_row0
+ y
* guest_stride
;
2955 guest_ptr
+= x
* cmp_bytes
;
2957 for (; x
< DIV_ROUND_UP(width
, VNC_DIRTY_PIXELS_PER_BIT
);
2958 x
++, guest_ptr
+= cmp_bytes
, server_ptr
+= cmp_bytes
) {
2959 int _cmp_bytes
= cmp_bytes
;
2960 if (!test_and_clear_bit(x
, vd
->guest
.dirty
[y
])) {
2963 if ((x
+ 1) * cmp_bytes
> line_bytes
) {
2964 _cmp_bytes
= line_bytes
- x
* cmp_bytes
;
2966 assert(_cmp_bytes
>= 0);
2967 if (memcmp(server_ptr
, guest_ptr
, _cmp_bytes
) == 0) {
2970 memcpy(server_ptr
, guest_ptr
, _cmp_bytes
);
2971 if (!vd
->non_adaptive
) {
2972 vnc_rect_updated(vd
, x
* VNC_DIRTY_PIXELS_PER_BIT
,
2975 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2976 set_bit(x
, vs
->dirty
[y
]);
2983 qemu_pixman_image_unref(tmpbuf
);
2987 static void vnc_refresh(DisplayChangeListener
*dcl
)
2989 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
2991 int has_dirty
, rects
= 0;
2993 if (QTAILQ_EMPTY(&vd
->clients
)) {
2994 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_MAX
);
2998 graphic_hw_update(vd
->dcl
.con
);
3000 if (vnc_trylock_display(vd
)) {
3001 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
3005 has_dirty
= vnc_refresh_server_surface(vd
);
3006 vnc_unlock_display(vd
);
3008 QTAILQ_FOREACH_SAFE(vs
, &vd
->clients
, next
, vn
) {
3009 rects
+= vnc_update_client(vs
, has_dirty
);
3010 /* vs might be free()ed here */
3013 if (has_dirty
&& rects
) {
3014 vd
->dcl
.update_interval
/= 2;
3015 if (vd
->dcl
.update_interval
< VNC_REFRESH_INTERVAL_BASE
) {
3016 vd
->dcl
.update_interval
= VNC_REFRESH_INTERVAL_BASE
;
3019 vd
->dcl
.update_interval
+= VNC_REFRESH_INTERVAL_INC
;
3020 if (vd
->dcl
.update_interval
> VNC_REFRESH_INTERVAL_MAX
) {
3021 vd
->dcl
.update_interval
= VNC_REFRESH_INTERVAL_MAX
;
3026 static void vnc_connect(VncDisplay
*vd
, QIOChannelSocket
*sioc
,
3027 bool skipauth
, bool websocket
)
3029 VncState
*vs
= g_new0(VncState
, 1);
3030 bool first_client
= QTAILQ_EMPTY(&vd
->clients
);
3033 trace_vnc_client_connect(vs
, sioc
);
3035 object_ref(OBJECT(vs
->sioc
));
3036 vs
->ioc
= QIO_CHANNEL(sioc
);
3037 object_ref(OBJECT(vs
->ioc
));
3040 buffer_init(&vs
->input
, "vnc-input/%p", sioc
);
3041 buffer_init(&vs
->output
, "vnc-output/%p", sioc
);
3042 buffer_init(&vs
->jobs_buffer
, "vnc-jobs_buffer/%p", sioc
);
3044 buffer_init(&vs
->tight
.tight
, "vnc-tight/%p", sioc
);
3045 buffer_init(&vs
->tight
.zlib
, "vnc-tight-zlib/%p", sioc
);
3046 buffer_init(&vs
->tight
.gradient
, "vnc-tight-gradient/%p", sioc
);
3047 #ifdef CONFIG_VNC_JPEG
3048 buffer_init(&vs
->tight
.jpeg
, "vnc-tight-jpeg/%p", sioc
);
3050 #ifdef CONFIG_VNC_PNG
3051 buffer_init(&vs
->tight
.png
, "vnc-tight-png/%p", sioc
);
3053 buffer_init(&vs
->zlib
.zlib
, "vnc-zlib/%p", sioc
);
3054 buffer_init(&vs
->zrle
.zrle
, "vnc-zrle/%p", sioc
);
3055 buffer_init(&vs
->zrle
.fb
, "vnc-zrle-fb/%p", sioc
);
3056 buffer_init(&vs
->zrle
.zlib
, "vnc-zrle-zlib/%p", sioc
);
3059 vs
->auth
= VNC_AUTH_NONE
;
3060 vs
->subauth
= VNC_AUTH_INVALID
;
3063 vs
->auth
= vd
->ws_auth
;
3064 vs
->subauth
= VNC_AUTH_INVALID
;
3066 vs
->auth
= vd
->auth
;
3067 vs
->subauth
= vd
->subauth
;
3070 VNC_DEBUG("Client sioc=%p ws=%d auth=%d subauth=%d\n",
3071 sioc
, websocket
, vs
->auth
, vs
->subauth
);
3073 vs
->lossy_rect
= g_malloc0(VNC_STAT_ROWS
* sizeof (*vs
->lossy_rect
));
3074 for (i
= 0; i
< VNC_STAT_ROWS
; ++i
) {
3075 vs
->lossy_rect
[i
] = g_new0(uint8_t, VNC_STAT_COLS
);
3078 VNC_DEBUG("New client on socket %p\n", vs
->sioc
);
3079 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
3080 qio_channel_set_blocking(vs
->ioc
, false, NULL
);
3082 g_source_remove(vs
->ioc_tag
);
3087 vs
->ioc_tag
= qio_channel_add_watch(
3088 vs
->ioc
, G_IO_IN
, vncws_tls_handshake_io
, vs
, NULL
);
3090 vs
->ioc_tag
= qio_channel_add_watch(
3091 vs
->ioc
, G_IO_IN
, vncws_handshake_io
, vs
, NULL
);
3094 vs
->ioc_tag
= qio_channel_add_watch(
3095 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
3098 vnc_client_cache_addr(vs
);
3099 vnc_qmp_event(vs
, QAPI_EVENT_VNC_CONNECTED
);
3100 vnc_set_share_mode(vs
, VNC_SHARE_MODE_CONNECTING
);
3105 vs
->as
.freq
= 44100;
3106 vs
->as
.nchannels
= 2;
3107 vs
->as
.fmt
= AUD_FMT_S16
;
3108 vs
->as
.endianness
= 0;
3110 qemu_mutex_init(&vs
->output_mutex
);
3111 vs
->bh
= qemu_bh_new(vnc_jobs_bh
, vs
);
3113 QTAILQ_INSERT_TAIL(&vd
->clients
, vs
, next
);
3115 vnc_update_server_surface(vd
);
3118 graphic_hw_update(vd
->dcl
.con
);
3120 if (!vs
->websocket
) {
3121 vnc_start_protocol(vs
);
3124 if (vd
->num_connecting
> vd
->connections_limit
) {
3125 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
3126 if (vs
->share_mode
== VNC_SHARE_MODE_CONNECTING
) {
3127 vnc_disconnect_start(vs
);
3134 void vnc_start_protocol(VncState
*vs
)
3136 vnc_write(vs
, "RFB 003.008\n", 12);
3138 vnc_read_when(vs
, protocol_version
, 12);
3140 vs
->mouse_mode_notifier
.notify
= check_pointer_type_change
;
3141 qemu_add_mouse_mode_change_notifier(&vs
->mouse_mode_notifier
);
3144 static void vnc_listen_io(QIONetListener
*listener
,
3145 QIOChannelSocket
*cioc
,
3148 VncDisplay
*vd
= opaque
;
3149 bool isWebsock
= listener
== vd
->wslistener
;
3151 qio_channel_set_name(QIO_CHANNEL(cioc
),
3152 isWebsock
? "vnc-ws-server" : "vnc-server");
3153 qio_channel_set_delay(QIO_CHANNEL(cioc
), false);
3154 vnc_connect(vd
, cioc
, false, isWebsock
);
3155 object_unref(OBJECT(cioc
));
3158 static const DisplayChangeListenerOps dcl_ops
= {
3160 .dpy_refresh
= vnc_refresh
,
3161 .dpy_gfx_update
= vnc_dpy_update
,
3162 .dpy_gfx_switch
= vnc_dpy_switch
,
3163 .dpy_gfx_check_format
= qemu_pixman_check_format
,
3164 .dpy_mouse_set
= vnc_mouse_set
,
3165 .dpy_cursor_define
= vnc_dpy_cursor_define
,
3168 void vnc_display_init(const char *id
)
3172 if (vnc_display_find(id
) != NULL
) {
3175 vd
= g_malloc0(sizeof(*vd
));
3177 vd
->id
= strdup(id
);
3178 QTAILQ_INSERT_TAIL(&vnc_displays
, vd
, next
);
3180 QTAILQ_INIT(&vd
->clients
);
3181 vd
->expires
= TIME_MAX
;
3183 if (keyboard_layout
) {
3184 trace_vnc_key_map_init(keyboard_layout
);
3185 vd
->kbd_layout
= init_keyboard_layout(name2keysym
, keyboard_layout
);
3187 vd
->kbd_layout
= init_keyboard_layout(name2keysym
, "en-us");
3190 if (!vd
->kbd_layout
) {
3194 vd
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3195 vd
->connections_limit
= 32;
3197 qemu_mutex_init(&vd
->mutex
);
3198 vnc_start_worker_thread();
3200 vd
->dcl
.ops
= &dcl_ops
;
3201 register_displaychangelistener(&vd
->dcl
);
3205 static void vnc_display_close(VncDisplay
*vd
)
3210 vd
->is_unix
= false;
3213 qio_net_listener_disconnect(vd
->listener
);
3214 object_unref(OBJECT(vd
->listener
));
3216 vd
->listener
= NULL
;
3218 if (vd
->wslistener
) {
3219 qio_net_listener_disconnect(vd
->wslistener
);
3220 object_unref(OBJECT(vd
->wslistener
));
3222 vd
->wslistener
= NULL
;
3224 vd
->auth
= VNC_AUTH_INVALID
;
3225 vd
->subauth
= VNC_AUTH_INVALID
;
3227 object_unparent(OBJECT(vd
->tlscreds
));
3228 vd
->tlscreds
= NULL
;
3230 g_free(vd
->tlsaclname
);
3231 vd
->tlsaclname
= NULL
;
3232 if (vd
->lock_key_sync
) {
3233 qemu_remove_led_event_handler(vd
->led
);
3238 int vnc_display_password(const char *id
, const char *password
)
3240 VncDisplay
*vd
= vnc_display_find(id
);
3245 if (vd
->auth
== VNC_AUTH_NONE
) {
3246 error_printf_unless_qmp("If you want use passwords please enable "
3247 "password auth using '-vnc ${dpy},password'.\n");
3251 g_free(vd
->password
);
3252 vd
->password
= g_strdup(password
);
3257 int vnc_display_pw_expire(const char *id
, time_t expires
)
3259 VncDisplay
*vd
= vnc_display_find(id
);
3265 vd
->expires
= expires
;
3269 static void vnc_display_print_local_addr(VncDisplay
*vd
)
3271 SocketAddress
*addr
;
3274 if (!vd
->listener
|| !vd
->listener
->nsioc
) {
3278 addr
= qio_channel_socket_get_local_address(vd
->listener
->sioc
[0], &err
);
3283 if (addr
->type
!= SOCKET_ADDRESS_TYPE_INET
) {
3284 qapi_free_SocketAddress(addr
);
3287 error_printf_unless_qmp("VNC server running on %s:%s\n",
3290 qapi_free_SocketAddress(addr
);
3293 static QemuOptsList qemu_vnc_opts
= {
3295 .head
= QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts
.head
),
3296 .implied_opt_name
= "vnc",
3300 .type
= QEMU_OPT_STRING
,
3302 .name
= "websocket",
3303 .type
= QEMU_OPT_STRING
,
3305 .name
= "tls-creds",
3306 .type
= QEMU_OPT_STRING
,
3308 /* Deprecated in favour of tls-creds */
3310 .type
= QEMU_OPT_STRING
,
3313 .type
= QEMU_OPT_STRING
,
3316 .type
= QEMU_OPT_STRING
,
3319 .type
= QEMU_OPT_NUMBER
,
3321 .name
= "connections",
3322 .type
= QEMU_OPT_NUMBER
,
3325 .type
= QEMU_OPT_NUMBER
,
3328 .type
= QEMU_OPT_BOOL
,
3331 .type
= QEMU_OPT_BOOL
,
3334 .type
= QEMU_OPT_BOOL
,
3337 .type
= QEMU_OPT_BOOL
,
3339 .name
= "lock-key-sync",
3340 .type
= QEMU_OPT_BOOL
,
3342 .name
= "key-delay-ms",
3343 .type
= QEMU_OPT_NUMBER
,
3346 .type
= QEMU_OPT_BOOL
,
3348 /* Deprecated in favour of tls-creds */
3350 .type
= QEMU_OPT_BOOL
,
3352 /* Deprecated in favour of tls-creds */
3353 .name
= "x509verify",
3354 .type
= QEMU_OPT_STRING
,
3357 .type
= QEMU_OPT_BOOL
,
3360 .type
= QEMU_OPT_BOOL
,
3362 .name
= "non-adaptive",
3363 .type
= QEMU_OPT_BOOL
,
3365 { /* end of list */ }
3371 vnc_display_setup_auth(int *auth
,
3373 QCryptoTLSCreds
*tlscreds
,
3380 * We have a choice of 3 authentication options
3386 * The channel can be run in 2 modes
3391 * And TLS can use 2 types of credentials
3396 * We thus have 9 possible logical combinations
3401 * 4. tls + anon + none
3402 * 5. tls + anon + vnc
3403 * 6. tls + anon + sasl
3404 * 7. tls + x509 + none
3405 * 8. tls + x509 + vnc
3406 * 9. tls + x509 + sasl
3408 * These need to be mapped into the VNC auth schemes
3409 * in an appropriate manner. In regular VNC, all the
3410 * TLS options get mapped into VNC_AUTH_VENCRYPT
3413 * In websockets, the https:// protocol already provides
3414 * TLS support, so there is no need to make use of the
3415 * VeNCrypt extension. Furthermore, websockets browser
3416 * clients could not use VeNCrypt even if they wanted to,
3417 * as they cannot control when the TLS handshake takes
3418 * place. Thus there is no option but to rely on https://,
3419 * meaning combinations 4->6 and 7->9 will be mapped to
3420 * VNC auth schemes in the same way as combos 1->3.
3422 * Regardless of fact that we have a different mapping to
3423 * VNC auth mechs for plain VNC vs websockets VNC, the end
3424 * result has the same security characteristics.
3426 if (websocket
|| !tlscreds
) {
3428 VNC_DEBUG("Initializing VNC server with password auth\n");
3429 *auth
= VNC_AUTH_VNC
;
3431 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3432 *auth
= VNC_AUTH_SASL
;
3434 VNC_DEBUG("Initializing VNC server with no auth\n");
3435 *auth
= VNC_AUTH_NONE
;
3437 *subauth
= VNC_AUTH_INVALID
;
3439 bool is_x509
= object_dynamic_cast(OBJECT(tlscreds
),
3440 TYPE_QCRYPTO_TLS_CREDS_X509
) != NULL
;
3441 bool is_anon
= object_dynamic_cast(OBJECT(tlscreds
),
3442 TYPE_QCRYPTO_TLS_CREDS_ANON
) != NULL
;
3444 if (!is_x509
&& !is_anon
) {
3446 "Unsupported TLS cred type %s",
3447 object_get_typename(OBJECT(tlscreds
)));
3450 *auth
= VNC_AUTH_VENCRYPT
;
3453 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3454 *subauth
= VNC_AUTH_VENCRYPT_X509VNC
;
3456 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3457 *subauth
= VNC_AUTH_VENCRYPT_TLSVNC
;
3462 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3463 *subauth
= VNC_AUTH_VENCRYPT_X509SASL
;
3465 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3466 *subauth
= VNC_AUTH_VENCRYPT_TLSSASL
;
3470 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3471 *subauth
= VNC_AUTH_VENCRYPT_X509NONE
;
3473 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3474 *subauth
= VNC_AUTH_VENCRYPT_TLSNONE
;
3483 * Handle back compat with old CLI syntax by creating some
3484 * suitable QCryptoTLSCreds objects
3486 static QCryptoTLSCreds
*
3487 vnc_display_create_creds(bool x509
,
3493 gchar
*credsid
= g_strdup_printf("tlsvnc%s", id
);
3494 Object
*parent
= object_get_objects_root();
3499 creds
= object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_X509
,
3503 "endpoint", "server",
3505 "verify-peer", x509verify
? "yes" : "no",
3508 creds
= object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_ANON
,
3512 "endpoint", "server",
3519 error_propagate(errp
, err
);
3523 return QCRYPTO_TLS_CREDS(creds
);
3527 static int vnc_display_get_address(const char *addrstr
,
3536 SocketAddress
**retaddr
,
3540 SocketAddress
*addr
= NULL
;
3542 addr
= g_new0(SocketAddress
, 1);
3544 if (strncmp(addrstr
, "unix:", 5) == 0) {
3545 addr
->type
= SOCKET_ADDRESS_TYPE_UNIX
;
3546 addr
->u
.q_unix
.path
= g_strdup(addrstr
+ 5);
3549 error_setg(errp
, "UNIX sockets not supported with websock");
3554 error_setg(errp
, "Port range not support with UNIX socket");
3561 unsigned long long baseport
= 0;
3562 InetSocketAddress
*inet
;
3564 port
= strrchr(addrstr
, ':');
3570 error_setg(errp
, "no vnc port specified");
3574 hostlen
= port
- addrstr
;
3576 if (*port
== '\0') {
3577 error_setg(errp
, "vnc port cannot be empty");
3582 addr
->type
= SOCKET_ADDRESS_TYPE_INET
;
3583 inet
= &addr
->u
.inet
;
3584 if (addrstr
[0] == '[' && addrstr
[hostlen
- 1] == ']') {
3585 inet
->host
= g_strndup(addrstr
+ 1, hostlen
- 2);
3587 inet
->host
= g_strndup(addrstr
, hostlen
);
3589 /* plain VNC port is just an offset, for websocket
3590 * port is absolute */
3592 if (g_str_equal(addrstr
, "") ||
3593 g_str_equal(addrstr
, "on")) {
3594 if (displaynum
== -1) {
3595 error_setg(errp
, "explicit websocket port is required");
3598 inet
->port
= g_strdup_printf(
3599 "%d", displaynum
+ 5700);
3601 inet
->has_to
= true;
3602 inet
->to
= to
+ 5700;
3605 inet
->port
= g_strdup(port
);
3608 int offset
= reverse
? 0 : 5900;
3609 if (parse_uint_full(port
, &baseport
, 10) < 0) {
3610 error_setg(errp
, "can't convert to a number: %s", port
);
3613 if (baseport
> 65535 ||
3614 baseport
+ offset
> 65535) {
3615 error_setg(errp
, "port %s out of range", port
);
3618 inet
->port
= g_strdup_printf(
3619 "%d", (int)baseport
+ offset
);
3622 inet
->has_to
= true;
3623 inet
->to
= to
+ offset
;
3628 inet
->has_ipv4
= has_ipv4
;
3630 inet
->has_ipv6
= has_ipv6
;
3639 qapi_free_SocketAddress(addr
);
3644 static void vnc_free_addresses(SocketAddress
***retsaddr
,
3649 for (i
= 0; i
< *retnsaddr
; i
++) {
3650 qapi_free_SocketAddress((*retsaddr
)[i
]);
3658 static int vnc_display_get_addresses(QemuOpts
*opts
,
3660 SocketAddress
***retsaddr
,
3662 SocketAddress
***retwsaddr
,
3666 SocketAddress
*saddr
= NULL
;
3667 SocketAddress
*wsaddr
= NULL
;
3668 QemuOptsIter addriter
;
3670 int to
= qemu_opt_get_number(opts
, "to", 0);
3671 bool has_ipv4
= qemu_opt_get(opts
, "ipv4");
3672 bool has_ipv6
= qemu_opt_get(opts
, "ipv6");
3673 bool ipv4
= qemu_opt_get_bool(opts
, "ipv4", false);
3674 bool ipv6
= qemu_opt_get_bool(opts
, "ipv6", false);
3675 int displaynum
= -1;
3683 addr
= qemu_opt_get(opts
, "vnc");
3684 if (addr
== NULL
|| g_str_equal(addr
, "none")) {
3688 if (qemu_opt_get(opts
, "websocket") &&
3689 !qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1
)) {
3691 "SHA1 hash support is required for websockets");
3695 qemu_opt_iter_init(&addriter
, opts
, "vnc");
3696 while ((addr
= qemu_opt_iter_next(&addriter
)) != NULL
) {
3698 rv
= vnc_display_get_address(addr
, false, reverse
, 0, to
,
3705 /* Historical compat - first listen address can be used
3706 * to set the default websocket port
3708 if (displaynum
== -1) {
3711 *retsaddr
= g_renew(SocketAddress
*, *retsaddr
, *retnsaddr
+ 1);
3712 (*retsaddr
)[(*retnsaddr
)++] = saddr
;
3715 /* If we had multiple primary displays, we don't do defaults
3716 * for websocket, and require explicit config instead. */
3717 if (*retnsaddr
> 1) {
3721 qemu_opt_iter_init(&addriter
, opts
, "websocket");
3722 while ((addr
= qemu_opt_iter_next(&addriter
)) != NULL
) {
3723 if (vnc_display_get_address(addr
, true, reverse
, displaynum
, to
,
3726 &wsaddr
, errp
) < 0) {
3730 /* Historical compat - if only a single listen address was
3731 * provided, then this is used to set the default listen
3732 * address for websocket too
3734 if (*retnsaddr
== 1 &&
3735 (*retsaddr
)[0]->type
== SOCKET_ADDRESS_TYPE_INET
&&
3736 wsaddr
->type
== SOCKET_ADDRESS_TYPE_INET
&&
3737 g_str_equal(wsaddr
->u
.inet
.host
, "") &&
3738 !g_str_equal((*retsaddr
)[0]->u
.inet
.host
, "")) {
3739 g_free(wsaddr
->u
.inet
.host
);
3740 wsaddr
->u
.inet
.host
= g_strdup((*retsaddr
)[0]->u
.inet
.host
);
3743 *retwsaddr
= g_renew(SocketAddress
*, *retwsaddr
, *retnwsaddr
+ 1);
3744 (*retwsaddr
)[(*retnwsaddr
)++] = wsaddr
;
3750 vnc_free_addresses(retsaddr
, retnsaddr
);
3751 vnc_free_addresses(retwsaddr
, retnwsaddr
);
3756 static int vnc_display_connect(VncDisplay
*vd
,
3757 SocketAddress
**saddr
,
3759 SocketAddress
**wsaddr
,
3763 /* connect to viewer */
3764 QIOChannelSocket
*sioc
= NULL
;
3766 error_setg(errp
, "Cannot use websockets in reverse mode");
3770 error_setg(errp
, "Expected a single address in reverse mode");
3773 /* TODO SOCKET_ADDRESS_TYPE_FD when fd has AF_UNIX */
3774 vd
->is_unix
= saddr
[0]->type
== SOCKET_ADDRESS_TYPE_UNIX
;
3775 sioc
= qio_channel_socket_new();
3776 qio_channel_set_name(QIO_CHANNEL(sioc
), "vnc-reverse");
3777 if (qio_channel_socket_connect_sync(sioc
, saddr
[0], errp
) < 0) {
3780 vnc_connect(vd
, sioc
, false, false);
3781 object_unref(OBJECT(sioc
));
3786 static int vnc_display_listen(VncDisplay
*vd
,
3787 SocketAddress
**saddr
,
3789 SocketAddress
**wsaddr
,
3796 vd
->listener
= qio_net_listener_new();
3797 qio_net_listener_set_name(vd
->listener
, "vnc-listen");
3798 for (i
= 0; i
< nsaddr
; i
++) {
3799 if (qio_net_listener_open_sync(vd
->listener
,
3806 qio_net_listener_set_client_func(vd
->listener
,
3807 vnc_listen_io
, vd
, NULL
);
3811 vd
->wslistener
= qio_net_listener_new();
3812 qio_net_listener_set_name(vd
->wslistener
, "vnc-ws-listen");
3813 for (i
= 0; i
< nwsaddr
; i
++) {
3814 if (qio_net_listener_open_sync(vd
->wslistener
,
3821 qio_net_listener_set_client_func(vd
->wslistener
,
3822 vnc_listen_io
, vd
, NULL
);
3829 void vnc_display_open(const char *id
, Error
**errp
)
3831 VncDisplay
*vd
= vnc_display_find(id
);
3832 QemuOpts
*opts
= qemu_opts_find(&qemu_vnc_opts
, id
);
3833 SocketAddress
**saddr
= NULL
, **wsaddr
= NULL
;
3834 size_t nsaddr
, nwsaddr
;
3835 const char *share
, *device_id
;
3837 bool password
= false;
3838 bool reverse
= false;
3841 #ifdef CONFIG_VNC_SASL
3845 int lock_key_sync
= 1;
3849 error_setg(errp
, "VNC display not active");
3852 vnc_display_close(vd
);
3858 reverse
= qemu_opt_get_bool(opts
, "reverse", false);
3859 if (vnc_display_get_addresses(opts
, reverse
, &saddr
, &nsaddr
,
3860 &wsaddr
, &nwsaddr
, errp
) < 0) {
3864 password
= qemu_opt_get_bool(opts
, "password", false);
3866 if (fips_get_state()) {
3868 "VNC password auth disabled due to FIPS mode, "
3869 "consider using the VeNCrypt or SASL authentication "
3870 "methods as an alternative");
3873 if (!qcrypto_cipher_supports(
3874 QCRYPTO_CIPHER_ALG_DES_RFB
, QCRYPTO_CIPHER_MODE_ECB
)) {
3876 "Cipher backend does not support DES RFB algorithm");
3881 lock_key_sync
= qemu_opt_get_bool(opts
, "lock-key-sync", true);
3882 key_delay_ms
= qemu_opt_get_number(opts
, "key-delay-ms", 10);
3883 sasl
= qemu_opt_get_bool(opts
, "sasl", false);
3884 #ifndef CONFIG_VNC_SASL
3886 error_setg(errp
, "VNC SASL auth requires cyrus-sasl support");
3889 #endif /* CONFIG_VNC_SASL */
3890 credid
= qemu_opt_get(opts
, "tls-creds");
3893 if (qemu_opt_get(opts
, "tls") ||
3894 qemu_opt_get(opts
, "x509") ||
3895 qemu_opt_get(opts
, "x509verify")) {
3897 "'tls-creds' parameter is mutually exclusive with "
3898 "'tls', 'x509' and 'x509verify' parameters");
3902 creds
= object_resolve_path_component(
3903 object_get_objects_root(), credid
);
3905 error_setg(errp
, "No TLS credentials with id '%s'",
3909 vd
->tlscreds
= (QCryptoTLSCreds
*)
3910 object_dynamic_cast(creds
,
3911 TYPE_QCRYPTO_TLS_CREDS
);
3912 if (!vd
->tlscreds
) {
3913 error_setg(errp
, "Object with id '%s' is not TLS credentials",
3917 object_ref(OBJECT(vd
->tlscreds
));
3919 if (vd
->tlscreds
->endpoint
!= QCRYPTO_TLS_CREDS_ENDPOINT_SERVER
) {
3921 "Expecting TLS credentials with a server endpoint");
3926 bool tls
= false, x509
= false, x509verify
= false;
3927 tls
= qemu_opt_get_bool(opts
, "tls", false);
3929 path
= qemu_opt_get(opts
, "x509");
3934 path
= qemu_opt_get(opts
, "x509verify");
3940 vd
->tlscreds
= vnc_display_create_creds(x509
,
3945 if (!vd
->tlscreds
) {
3950 acl
= qemu_opt_get_bool(opts
, "acl", false);
3952 share
= qemu_opt_get(opts
, "share");
3954 if (strcmp(share
, "ignore") == 0) {
3955 vd
->share_policy
= VNC_SHARE_POLICY_IGNORE
;
3956 } else if (strcmp(share
, "allow-exclusive") == 0) {
3957 vd
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3958 } else if (strcmp(share
, "force-shared") == 0) {
3959 vd
->share_policy
= VNC_SHARE_POLICY_FORCE_SHARED
;
3961 error_setg(errp
, "unknown vnc share= option");
3965 vd
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3967 vd
->connections_limit
= qemu_opt_get_number(opts
, "connections", 32);
3969 #ifdef CONFIG_VNC_JPEG
3970 vd
->lossy
= qemu_opt_get_bool(opts
, "lossy", false);
3972 vd
->non_adaptive
= qemu_opt_get_bool(opts
, "non-adaptive", false);
3973 /* adaptive updates are only used with tight encoding and
3974 * if lossy updates are enabled so we can disable all the
3975 * calculations otherwise */
3977 vd
->non_adaptive
= true;
3981 if (strcmp(vd
->id
, "default") == 0) {
3982 vd
->tlsaclname
= g_strdup("vnc.x509dname");
3984 vd
->tlsaclname
= g_strdup_printf("vnc.%s.x509dname", vd
->id
);
3986 qemu_acl_init(vd
->tlsaclname
);
3988 #ifdef CONFIG_VNC_SASL
3992 if (strcmp(vd
->id
, "default") == 0) {
3993 aclname
= g_strdup("vnc.username");
3995 aclname
= g_strdup_printf("vnc.%s.username", vd
->id
);
3997 vd
->sasl
.acl
= qemu_acl_init(aclname
);
4002 if (vnc_display_setup_auth(&vd
->auth
, &vd
->subauth
,
4003 vd
->tlscreds
, password
,
4004 sasl
, false, errp
) < 0) {
4007 trace_vnc_auth_init(vd
, 0, vd
->auth
, vd
->subauth
);
4009 if (vnc_display_setup_auth(&vd
->ws_auth
, &vd
->ws_subauth
,
4010 vd
->tlscreds
, password
,
4011 sasl
, true, errp
) < 0) {
4014 trace_vnc_auth_init(vd
, 1, vd
->ws_auth
, vd
->ws_subauth
);
4016 #ifdef CONFIG_VNC_SASL
4017 if ((saslErr
= sasl_server_init(NULL
, "qemu")) != SASL_OK
) {
4018 error_setg(errp
, "Failed to initialize SASL auth: %s",
4019 sasl_errstring(saslErr
, NULL
, NULL
));
4023 vd
->lock_key_sync
= lock_key_sync
;
4024 if (lock_key_sync
) {
4025 vd
->led
= qemu_add_led_event_handler(kbd_leds
, vd
);
4028 vd
->key_delay_ms
= key_delay_ms
;
4030 device_id
= qemu_opt_get(opts
, "display");
4032 int head
= qemu_opt_get_number(opts
, "head", 0);
4035 con
= qemu_console_lookup_by_device_name(device_id
, head
, &err
);
4037 error_propagate(errp
, err
);
4044 if (con
!= vd
->dcl
.con
) {
4045 unregister_displaychangelistener(&vd
->dcl
);
4047 register_displaychangelistener(&vd
->dcl
);
4050 if (saddr
== NULL
) {
4055 if (vnc_display_connect(vd
, saddr
, nsaddr
, wsaddr
, nwsaddr
, errp
) < 0) {
4059 if (vnc_display_listen(vd
, saddr
, nsaddr
, wsaddr
, nwsaddr
, errp
) < 0) {
4064 if (qemu_opt_get(opts
, "to")) {
4065 vnc_display_print_local_addr(vd
);
4069 vnc_free_addresses(&saddr
, &nsaddr
);
4070 vnc_free_addresses(&wsaddr
, &nwsaddr
);
4074 vnc_display_close(vd
);
4078 void vnc_display_add_client(const char *id
, int csock
, bool skipauth
)
4080 VncDisplay
*vd
= vnc_display_find(id
);
4081 QIOChannelSocket
*sioc
;
4087 sioc
= qio_channel_socket_new_fd(csock
, NULL
);
4089 qio_channel_set_name(QIO_CHANNEL(sioc
), "vnc-server");
4090 vnc_connect(vd
, sioc
, skipauth
, false);
4091 object_unref(OBJECT(sioc
));
4095 static void vnc_auto_assign_id(QemuOptsList
*olist
, QemuOpts
*opts
)
4100 id
= g_strdup("default");
4101 while (qemu_opts_find(olist
, id
)) {
4103 id
= g_strdup_printf("vnc%d", i
++);
4105 qemu_opts_set_id(opts
, id
);
4108 QemuOpts
*vnc_parse(const char *str
, Error
**errp
)
4110 QemuOptsList
*olist
= qemu_find_opts("vnc");
4111 QemuOpts
*opts
= qemu_opts_parse(olist
, str
, true, errp
);
4118 id
= qemu_opts_id(opts
);
4120 /* auto-assign id if not present */
4121 vnc_auto_assign_id(olist
, opts
);
4126 int vnc_init_func(void *opaque
, QemuOpts
*opts
, Error
**errp
)
4128 Error
*local_err
= NULL
;
4129 char *id
= (char *)qemu_opts_id(opts
);
4132 vnc_display_init(id
);
4133 vnc_display_open(id
, &local_err
);
4134 if (local_err
!= NULL
) {
4135 error_reportf_err(local_err
, "Failed to start VNC server: ");
4141 static void vnc_register_config(void)
4143 qemu_add_opts(&qemu_vnc_opts
);
4145 opts_init(vnc_register_config
);