View | Details | Raw Unified | Return to bug 250795 | Differences between
and this patch

Collapse All | Expand All

(-)b/usr.sbin/bhyve/rfb.c (-104 / +196 lines)
Lines 39-44 __FBSDID("$FreeBSD$"); Link Here
39
#include <sys/select.h>
39
#include <sys/select.h>
40
#include <sys/time.h>
40
#include <sys/time.h>
41
#include <arpa/inet.h>
41
#include <arpa/inet.h>
42
#include <machine/atomic.h>
42
#include <machine/cpufunc.h>
43
#include <machine/cpufunc.h>
43
#include <machine/specialreg.h>
44
#include <machine/specialreg.h>
44
#include <netinet/in.h>
45
#include <netinet/in.h>
Lines 72-77 __FBSDID("$FreeBSD$"); Link Here
72
#include <openssl/des.h>
73
#include <openssl/des.h>
73
#endif
74
#endif
74
75
76
/* Delays in microseconds */
77
#define	CFD_SEL_DELAY	10000
78
#define	SCREEN_REFRESH_DELAY	33300	/* 30Hz */
79
#define	SCREEN_POLL_DELAY	(SCREEN_REFRESH_DELAY / 2)
80
75
static int rfb_debug = 0;
81
static int rfb_debug = 0;
76
#define	DPRINTF(params) if (rfb_debug) PRINTLN params
82
#define	DPRINTF(params) if (rfb_debug) PRINTLN params
77
#define	WPRINTF(params) PRINTLN params
83
#define	WPRINTF(params) PRINTLN params
Lines 80-85 static int rfb_debug = 0; Link Here
80
#define AUTH_LENGTH	16
86
#define AUTH_LENGTH	16
81
#define PASSWD_LENGTH	8
87
#define PASSWD_LENGTH	8
82
88
89
/* Protocol versions */
90
#define CVERS_3_3	'3'
91
#define CVERS_3_7	'7'
92
#define CVERS_3_8	'8'
93
94
/* Client-to-server msg types */
95
#define CS_SET_PIXEL_FORMAT	0
96
#define CS_SET_ENCODINGS	2
97
#define CS_UPDATE_MSG		3
98
#define CS_KEY_EVENT		4
99
#define CS_POINTER_EVENT	5
100
#define CS_CUT_TEXT		6
101
83
#define SECURITY_TYPE_NONE	1
102
#define SECURITY_TYPE_NONE	1
84
#define SECURITY_TYPE_VNC_AUTH	2
103
#define SECURITY_TYPE_VNC_AUTH	2
85
104
Lines 96-111 struct rfb_softc { Link Here
96
115
97
	char		*password;
116
	char		*password;
98
117
99
	bool	enc_raw_ok;
118
	bool		enc_raw_ok;
100
	bool	enc_zlib_ok;
119
	bool		enc_zlib_ok;
101
	bool	enc_resize_ok;
120
	bool		enc_resize_ok;
102
121
103
	z_stream	zstream;
122
	z_stream	zstream;
104
	uint8_t		*zbuf;
123
	uint8_t		*zbuf;
105
	int		zbuflen;
124
	int		zbuflen;
106
125
107
	int		conn_wait;
126
	int		conn_wait;
108
	int		sending;
127
	int		wrcount;
128
129
	volatile u_int	sending;
130
	volatile u_int	pending;
131
	volatile u_int	update_all;
132
	volatile u_int	input_detected;
133
109
	pthread_mutex_t mtx;
134
	pthread_mutex_t mtx;
110
	pthread_cond_t  cond;
135
	pthread_cond_t  cond;
111
136
Lines 202-208 struct rfb_cuttext_msg { Link Here
202
	uint32_t	length;
227
	uint32_t	length;
203
};
228
};
204
229
205
206
static void
230
static void
207
rfb_send_server_init_msg(int cfd)
231
rfb_send_server_init_msg(int cfd)
208
{
232
{
Lines 223-228 rfb_send_server_init_msg(int cfd) Link Here
223
	sinfo.pixfmt.red_shift = 16;
247
	sinfo.pixfmt.red_shift = 16;
224
	sinfo.pixfmt.green_shift = 8;
248
	sinfo.pixfmt.green_shift = 8;
225
	sinfo.pixfmt.blue_shift = 0;
249
	sinfo.pixfmt.blue_shift = 0;
250
	sinfo.pixfmt.pad[0] = 0;
251
	sinfo.pixfmt.pad[1] = 0;
252
	sinfo.pixfmt.pad[2] = 0;
226
	sinfo.namelen = htonl(strlen("bhyve"));
253
	sinfo.namelen = htonl(strlen("bhyve"));
227
	(void)stream_write(cfd, &sinfo, sizeof(sinfo));
254
	(void)stream_write(cfd, &sinfo, sizeof(sinfo));
228
	(void)stream_write(cfd, "bhyve", strlen("bhyve"));
255
	(void)stream_write(cfd, "bhyve", strlen("bhyve"));
Lines 265-271 rfb_recv_set_encodings_msg(struct rfb_softc *rc, int cfd) Link Here
265
	int i;
292
	int i;
266
	uint32_t encoding;
293
	uint32_t encoding;
267
294
268
	assert((sizeof(enc_msg) - 1) == 3);
269
	(void)stream_read(cfd, ((void *)&enc_msg)+1, sizeof(enc_msg)-1);
295
	(void)stream_read(cfd, ((void *)&enc_msg)+1, sizeof(enc_msg)-1);
270
296
271
	for (i = 0; i < htons(enc_msg.numencs); i++) {
297
	for (i = 0; i < htons(enc_msg.numencs); i++) {
Lines 308-319 fast_crc32(void *buf, int len, uint32_t crcval) Link Here
308
	return (crcval);
334
	return (crcval);
309
}
335
}
310
336
337
static int
338
rfb_send_update_header(struct rfb_softc *rc, int cfd, int numrects)
339
{
340
	struct rfb_srvr_updt_msg supdt_msg;
341
342
	supdt_msg.type = 0;
343
	supdt_msg.pad = 0;
344
	supdt_msg.numrects = htons(numrects);
345
346
	return stream_write(cfd, &supdt_msg,
347
	    sizeof(struct rfb_srvr_updt_msg));
348
}
311
349
312
static int
350
static int
313
rfb_send_rect(struct rfb_softc *rc, int cfd, struct bhyvegc_image *gc,
351
rfb_send_rect(struct rfb_softc *rc, int cfd, struct bhyvegc_image *gc,
314
              int x, int y, int w, int h)
352
              int x, int y, int w, int h)
315
{
353
{
316
	struct rfb_srvr_updt_msg supdt_msg;
317
	struct rfb_srvr_rect_hdr srect_hdr;
354
	struct rfb_srvr_rect_hdr srect_hdr;
318
	unsigned long zlen;
355
	unsigned long zlen;
319
	ssize_t nwrite, total;
356
	ssize_t nwrite, total;
Lines 325-340 rfb_send_rect(struct rfb_softc *rc, int cfd, struct bhyvegc_image *gc, Link Here
325
	 * Send a single rectangle of the given x, y, w h dimensions.
362
	 * Send a single rectangle of the given x, y, w h dimensions.
326
	 */
363
	 */
327
364
328
	/* Number of rectangles: 1 */
329
	supdt_msg.type = 0;
330
	supdt_msg.pad = 0;
331
	supdt_msg.numrects = htons(1);
332
	nwrite = stream_write(cfd, &supdt_msg,
333
	                      sizeof(struct rfb_srvr_updt_msg));
334
	if (nwrite <= 0)
335
		return (nwrite);
336
337
338
	/* Rectangle header */
365
	/* Rectangle header */
339
	srect_hdr.x = htons(x);
366
	srect_hdr.x = htons(x);
340
	srect_hdr.y = htons(y);
367
	srect_hdr.y = htons(y);
Lines 479-485 rfb_send_all(struct rfb_softc *rc, int cfd, struct bhyvegc_image *gc) Link Here
479
#define	PIXCELL_MASK	0x1F
506
#define	PIXCELL_MASK	0x1F
480
507
481
static int
508
static int
482
rfb_send_screen(struct rfb_softc *rc, int cfd, int all)
509
rfb_send_screen(struct rfb_softc *rc, int cfd)
483
{
510
{
484
	struct bhyvegc_image *gc_image;
511
	struct bhyvegc_image *gc_image;
485
	ssize_t nwrite;
512
	ssize_t nwrite;
Lines 493-526 rfb_send_screen(struct rfb_softc *rc, int cfd, int all) Link Here
493
	uint32_t *crc_p, *orig_crc;
520
	uint32_t *crc_p, *orig_crc;
494
	int changes;
521
	int changes;
495
522
496
	console_refresh();
523
	if (!atomic_cmpset_int(&rc->sending, 0, 1))
497
	gc_image = console_get_image();
498
499
	pthread_mutex_lock(&rc->mtx);
500
	if (rc->sending) {
501
		pthread_mutex_unlock(&rc->mtx);
502
		return (1);
524
		return (1);
503
	}
504
	rc->sending = 1;
505
	pthread_mutex_unlock(&rc->mtx);
506
525
507
	retval = 0;
526
	retval = 1;
508
527
509
	if (all) {
528
	/* Updates require a preceding update request */
510
		retval = rfb_send_all(rc, cfd, gc_image);
529
	if (!atomic_readandclear_int(&rc->pending))
511
		goto done;
530
		goto done;
531
532
	console_refresh();
533
	gc_image = console_get_image();
534
535
	/* Clear old CRC values when the size changes */
536
	if (rc->crc_width != gc_image->width ||
537
	    rc->crc_height != gc_image->height) {
538
		memset(rc->crc, 0, sizeof(uint32_t) *
539
		    howmany(RFB_MAX_WIDTH, PIX_PER_CELL) *
540
		    howmany(RFB_MAX_HEIGHT, PIX_PER_CELL));
541
		rc->crc_width = gc_image->width;
542
		rc->crc_height = gc_image->height;
512
	}
543
	}
513
544
545
       /* A size update counts as an update in itself */
546
       if (rc->width != gc_image->width ||
547
           rc->height != gc_image->height) {
548
               rc->width = gc_image->width;
549
               rc->height = gc_image->height;
550
               if (rc->enc_resize_ok) {
551
                       rfb_send_resize_update_msg(rc, cfd);
552
                       atomic_set_int(&rc->update_all, 1);
553
                       goto done;
554
               }
555
       }
556
557
       if (atomic_readandclear_int(&rc->update_all)) {
558
	       retval = rfb_send_all(rc, cfd, gc_image);
559
	       goto done;
560
       }
561
514
	/*
562
	/*
515
	 * Calculate the checksum for each 32x32 cell. Send each that
563
	 * Calculate the checksum for each 32x32 cell. Send each that
516
	 * has changed since the last scan.
564
	 * has changed since the last scan.
517
	 */
565
	 */
518
566
519
	/* Resolution changed */
520
521
	rc->crc_width = gc_image->width;
522
	rc->crc_height = gc_image->height;
523
524
	w = rc->crc_width;
567
	w = rc->crc_width;
525
	h = rc->crc_height;
568
	h = rc->crc_height;
526
	xcells = howmany(rc->crc_width, PIX_PER_CELL);
569
	xcells = howmany(rc->crc_width, PIX_PER_CELL);
Lines 580-591 rfb_send_screen(struct rfb_softc *rc, int cfd, int all) Link Here
580
		}
623
		}
581
	}
624
	}
582
625
626
       /*
627
	* We only send the update if there are changes.
628
	* Restore the pending flag since it was unconditionally cleared
629
	* above.
630
	*/
631
	if (!changes) {
632
		atomic_set_int(&rc->pending, 1);
633
		goto done;
634
	}
635
583
	/* If number of changes is > THRESH percent, send the whole screen */
636
	/* If number of changes is > THRESH percent, send the whole screen */
584
	if (((changes * 100) / (xcells * ycells)) >= RFB_SEND_ALL_THRESH) {
637
	if (((changes * 100) / (xcells * ycells)) >= RFB_SEND_ALL_THRESH) {
585
		retval = rfb_send_all(rc, cfd, gc_image);
638
		retval = rfb_send_all(rc, cfd, gc_image);
586
		goto done;
639
		goto done;
587
	}
640
	}
588
	
641
642
	rfb_send_update_header(rc, cfd, changes);
643
589
	/* Go through all cells, and send only changed ones */
644
	/* Go through all cells, and send only changed ones */
590
	crc_p = rc->crc_tmp;
645
	crc_p = rc->crc_tmp;
591
	for (y = 0; y < h; y += PIX_PER_CELL) {
646
	for (y = 0; y < h; y += PIX_PER_CELL) {
Lines 613-657 rfb_send_screen(struct rfb_softc *rc, int cfd, int all) Link Here
613
			}
668
			}
614
		}
669
		}
615
	}
670
	}
616
	retval = 1;
617
671
618
done:
672
done:
619
	pthread_mutex_lock(&rc->mtx);
673
	atomic_clear_int(&rc->sending, 1);
620
	rc->sending = 0;
674
621
	pthread_mutex_unlock(&rc->mtx);
622
	
623
	return (retval);
675
	return (retval);
624
}
676
}
625
677
626
678
627
static void
679
static void
628
rfb_recv_update_msg(struct rfb_softc *rc, int cfd, int discardonly)
680
rfb_recv_update_msg(struct rfb_softc *rc, int cfd)
629
{
681
{
630
	struct rfb_updt_msg updt_msg;
682
	struct rfb_updt_msg updt_msg;
631
	struct bhyvegc_image *gc_image;
632
683
633
	(void)stream_read(cfd, ((void *)&updt_msg) + 1 , sizeof(updt_msg) - 1);
684
	(void)stream_read(cfd, ((void *)&updt_msg) + 1 , sizeof(updt_msg) - 1);
634
685
635
	console_refresh();
686
	atomic_set_int(&rc->pending, 1);
636
	gc_image = console_get_image();
687
	if (!updt_msg.incremental)
637
688
		atomic_set_int(&rc->update_all, 1);
638
	updt_msg.x = htons(updt_msg.x);
639
	updt_msg.y = htons(updt_msg.y);
640
	updt_msg.width = htons(updt_msg.width);
641
	updt_msg.height = htons(updt_msg.height);
642
643
	if (updt_msg.width != gc_image->width ||
644
	    updt_msg.height != gc_image->height) {
645
		rc->width = gc_image->width;
646
		rc->height = gc_image->height;
647
		if (rc->enc_resize_ok)
648
			rfb_send_resize_update_msg(rc, cfd);
649
	}
650
651
	if (discardonly)
652
		return;
653
654
	rfb_send_screen(rc, cfd, 1);
655
}
689
}
656
690
657
static void
691
static void
Lines 662-667 rfb_recv_key_msg(struct rfb_softc *rc, int cfd) Link Here
662
	(void)stream_read(cfd, ((void *)&key_msg) + 1, sizeof(key_msg) - 1);
696
	(void)stream_read(cfd, ((void *)&key_msg) + 1, sizeof(key_msg) - 1);
663
697
664
	console_key_event(key_msg.down, htonl(key_msg.code));
698
	console_key_event(key_msg.down, htonl(key_msg.code));
699
	atomic_set_int(&rc->input_detected, 1);
665
}
700
}
666
701
667
static void
702
static void
Lines 672-677 rfb_recv_ptr_msg(struct rfb_softc *rc, int cfd) Link Here
672
	(void)stream_read(cfd, ((void *)&ptr_msg) + 1, sizeof(ptr_msg) - 1);
707
	(void)stream_read(cfd, ((void *)&ptr_msg) + 1, sizeof(ptr_msg) - 1);
673
708
674
	console_ptr_event(ptr_msg.button, htons(ptr_msg.x), htons(ptr_msg.y));
709
	console_ptr_event(ptr_msg.button, htons(ptr_msg.x), htons(ptr_msg.y));
710
	atomic_set_int(&rc->input_detected, 1);
675
}
711
}
676
712
677
static void
713
static void
Lines 719-725 rfb_wr_thr(void *arg) Link Here
719
		FD_ZERO(&rfds);
755
		FD_ZERO(&rfds);
720
		FD_SET(cfd, &rfds);
756
		FD_SET(cfd, &rfds);
721
		tv.tv_sec = 0;
757
		tv.tv_sec = 0;
722
		tv.tv_usec = 10000;
758
		tv.tv_usec = CFD_SEL_DELAY;
723
759
724
		err = select(cfd+1, &rfds, NULL, NULL, &tv);
760
		err = select(cfd+1, &rfds, NULL, NULL, &tv);
725
		if (err < 0)
761
		if (err < 0)
Lines 728-742 rfb_wr_thr(void *arg) Link Here
728
		/* Determine if its time to push screen; ~24hz */
764
		/* Determine if its time to push screen; ~24hz */
729
		gettimeofday(&tv, NULL);
765
		gettimeofday(&tv, NULL);
730
		tdiff = timeval_delta(&prev_tv, &tv);
766
		tdiff = timeval_delta(&prev_tv, &tv);
731
		if (tdiff > 40000) {
767
		if (tdiff >= SCREEN_POLL_DELAY) {
768
			u_int input;
732
			prev_tv.tv_sec = tv.tv_sec;
769
			prev_tv.tv_sec = tv.tv_sec;
733
			prev_tv.tv_usec = tv.tv_usec;
770
			prev_tv.tv_usec = tv.tv_usec;
734
			if (rfb_send_screen(rc, cfd, 0) <= 0) {
771
			input = atomic_readandclear_int(&rc->input_detected);
735
				return (NULL);
772
			/*
773
			 * Refresh the screen on every second trip through the loop,
774
			 * or if keyboard/mouse input has been detected.
775
			 */
776
			if ((++rc->wrcount & 1) || input) {
777
				if (rfb_send_screen(rc, cfd) <= 0) {
778
					return (NULL);
779
				}
736
			}
780
			}
737
		} else {
781
		} else {
738
			/* sleep */
782
			/* sleep */
739
			usleep(40000 - tdiff);
783
			usleep(SCREEN_POLL_DELAY - tdiff);
740
		}
784
		}
741
	}
785
	}
742
786
Lines 758-764 rfb_handle(struct rfb_softc *rc, int cfd) Link Here
758
	DES_key_schedule ks;
802
	DES_key_schedule ks;
759
	int i;
803
	int i;
760
#endif
804
#endif
761
805
	uint8_t client_ver;
806
	uint8_t auth_type;
762
	pthread_t tid;
807
	pthread_t tid;
763
	uint32_t sres = 0;
808
	uint32_t sres = 0;
764
	int len;
809
	int len;
Lines 771-797 rfb_handle(struct rfb_softc *rc, int cfd) Link Here
771
816
772
	/* 1b. Read client version */
817
	/* 1b. Read client version */
773
	len = stream_read(cfd, buf, VERSION_LENGTH);
818
	len = stream_read(cfd, buf, VERSION_LENGTH);
819
	if (len == VERSION_LENGTH && !strncmp(vbuf, buf, VERSION_LENGTH - 2)) {
820
		client_ver = buf[VERSION_LENGTH - 2];
821
	}
822
	if (client_ver != CVERS_3_8 && client_ver != CVERS_3_7) {
823
		/* only recognize 3.3, 3.7 & 3.8. Others dflt to 3.3 */
824
		client_ver = CVERS_3_3;
825
	}
774
826
775
	/* 2a. Send security type */
827
	/* 2a. Send security type */
776
	buf[0] = 1;
828
	buf[0] = 1;
829
830
	/* In versions 3.7 & 3.8, it's 2-way handshake */
831
	/* For version 3.3, server says what the authentication type must be */
777
#ifndef NO_OPENSSL
832
#ifndef NO_OPENSSL
778
	if (rc->password) 
833
	if (rc->password) {
779
		buf[1] = SECURITY_TYPE_VNC_AUTH;
834
		auth_type = SECURITY_TYPE_VNC_AUTH;
780
	else
835
	} else {
781
		buf[1] = SECURITY_TYPE_NONE;
836
		auth_type = SECURITY_TYPE_NONE;
837
	}
782
#else
838
#else
783
	buf[1] = SECURITY_TYPE_NONE;
839
	auth_type = SECURITY_TYPE_NONE;
784
#endif
840
#endif
785
841
786
	stream_write(cfd, buf, 2);
842
	switch (client_ver) {
787
843
	case CVERS_3_7:
788
	/* 2b. Read agreed security type */
844
	case CVERS_3_8:
789
	len = stream_read(cfd, buf, 1);
845
		buf[0] = 1;
846
		buf[1] = auth_type;
847
		stream_write(cfd, buf, 2);
848
849
		/* 2b. Read agreed security type */
850
		len = stream_read(cfd, buf, 1);
851
		if (buf[0] != auth_type) {
852
			/* deny */
853
			sres = htonl(1);
854
			message = "Auth failed: authentication type mismatch";
855
			goto report_and_done;
856
		}
857
		break;
858
	case CVERS_3_3:
859
	default:
860
		be32enc(buf, auth_type);
861
		stream_write(cfd, buf, 4);
862
		break;
863
	}
790
864
791
	/* 2c. Do VNC authentication */
865
	/* 2c. Do VNC authentication */
792
	switch (buf[0]) {
866
	switch (auth_type) {
793
	case SECURITY_TYPE_NONE:
867
	case SECURITY_TYPE_NONE:
794
		sres = 0;
795
		break;
868
		break;
796
	case SECURITY_TYPE_VNC_AUTH:
869
	case SECURITY_TYPE_VNC_AUTH:
797
		/*
870
		/*
Lines 839-864 rfb_handle(struct rfb_softc *rc, int cfd) Link Here
839
		if (memcmp(crypt_expected, buf, AUTH_LENGTH) != 0) {
912
		if (memcmp(crypt_expected, buf, AUTH_LENGTH) != 0) {
840
			message = "Auth Failed: Invalid Password.";
913
			message = "Auth Failed: Invalid Password.";
841
			sres = htonl(1);
914
			sres = htonl(1);
842
		} else
915
		} else {
843
			sres = 0;
916
			sres = 0;
917
		}
844
#else
918
#else
845
		sres = 0;
919
		sres = htonl(1);
846
		WPRINTF(("Auth not supported, no OpenSSL in your system"));
920
		WPRINTF(("Auth not supported, no OpenSSL in your system"));
847
#endif
921
#endif
848
922
849
		break;
923
		break;
850
	}
924
	}
851
925
852
	/* 2d. Write back a status */
926
	switch (client_ver) {
853
	stream_write(cfd, &sres, 4);
927
	case CVERS_3_7:
854
928
	case CVERS_3_8:
855
	if (sres) {
929
report_and_done:
856
		be32enc(buf, strlen(message));
930
		/* 2d. Write back a status */
857
		stream_write(cfd, buf, 4);
931
		stream_write(cfd, &sres, 4);
858
		stream_write(cfd, message, strlen(message));
932
859
		goto done;
933
		if (sres) {
934
			/* 3.7 does not want string explaining cause */
935
			if (client_ver == CVERS_3_8) {
936
				be32enc(buf, strlen(message));
937
				stream_write(cfd, buf, 4);
938
				stream_write(cfd, message, strlen(message));
939
			}
940
			goto done;
941
		}
942
		break;
943
	case CVERS_3_3:
944
	default:
945
		/* for VNC auth case send status */
946
		if (auth_type == SECURITY_TYPE_VNC_AUTH) {
947
			/* 2d. Write back a status */
948
			stream_write(cfd, &sres, 4);
949
		}
950
		if (sres) {
951
			goto done;
952
		}
953
		break;
860
	}
954
	}
861
862
	/* 3a. Read client shared-flag byte */
955
	/* 3a. Read client shared-flag byte */
863
	len = stream_read(cfd, buf, 1);
956
	len = stream_read(cfd, buf, 1);
864
957
Lines 870-877 rfb_handle(struct rfb_softc *rc, int cfd) Link Here
870
		assert(rc->zbuf != NULL);
963
		assert(rc->zbuf != NULL);
871
	}
964
	}
872
965
873
	rfb_send_screen(rc, cfd, 1);
874
875
	perror = pthread_create(&tid, NULL, rfb_wr_thr, rc);
966
	perror = pthread_create(&tid, NULL, rfb_wr_thr, rc);
876
	if (perror == 0)
967
	if (perror == 0)
877
		pthread_set_name_np(tid, "rfbout");
968
		pthread_set_name_np(tid, "rfbout");
Lines 885-906 rfb_handle(struct rfb_softc *rc, int cfd) Link Here
885
		}
976
		}
886
977
887
		switch (buf[0]) {
978
		switch (buf[0]) {
888
		case 0:
979
		case CS_SET_PIXEL_FORMAT:
889
			rfb_recv_set_pixfmt_msg(rc, cfd);
980
			rfb_recv_set_pixfmt_msg(rc, cfd);
890
			break;
981
			break;
891
		case 2:
982
		case CS_SET_ENCODINGS:
892
			rfb_recv_set_encodings_msg(rc, cfd);
983
			rfb_recv_set_encodings_msg(rc, cfd);
893
			break;
984
			break;
894
		case 3:
985
		case CS_UPDATE_MSG:
895
			rfb_recv_update_msg(rc, cfd, 1);
986
			rfb_recv_update_msg(rc, cfd);
896
			break;
987
			break;
897
		case 4:
988
		case CS_KEY_EVENT:
898
			rfb_recv_key_msg(rc, cfd);
989
			rfb_recv_key_msg(rc, cfd);
899
			break;
990
			break;
900
		case 5:
991
		case CS_POINTER_EVENT:
901
			rfb_recv_ptr_msg(rc, cfd);
992
			rfb_recv_ptr_msg(rc, cfd);
902
			break;
993
			break;
903
		case 6:
994
		case CS_CUT_TEXT:
904
			rfb_recv_cuttext_msg(rc, cfd);
995
			rfb_recv_cuttext_msg(rc, cfd);
905
			break;
996
			break;
906
		default:
997
		default:
Lines 974-989 rfb_init(char *hostname, int port, int wait, char *password) Link Here
974
	struct addrinfo *ai = NULL;
1065
	struct addrinfo *ai = NULL;
975
	struct addrinfo hints;
1066
	struct addrinfo hints;
976
	int on = 1;
1067
	int on = 1;
1068
	int cnt;
977
#ifndef WITHOUT_CAPSICUM
1069
#ifndef WITHOUT_CAPSICUM
978
	cap_rights_t rights;
1070
	cap_rights_t rights;
979
#endif
1071
#endif
980
1072
981
	rc = calloc(1, sizeof(struct rfb_softc));
1073
	rc = calloc(1, sizeof(struct rfb_softc));
982
1074
983
	rc->crc = calloc(howmany(RFB_MAX_WIDTH * RFB_MAX_HEIGHT, 32),
1075
	cnt = howmany(RFB_MAX_WIDTH, PIX_PER_CELL) *
984
	                 sizeof(uint32_t));
1076
	    howmany(RFB_MAX_HEIGHT, PIX_PER_CELL);
985
	rc->crc_tmp = calloc(howmany(RFB_MAX_WIDTH * RFB_MAX_HEIGHT, 32),
1077
	rc->crc = calloc(cnt, sizeof(uint32_t));
986
	                     sizeof(uint32_t));
1078
	rc->crc_tmp = calloc(cnt, sizeof(uint32_t));
987
	rc->crc_width = RFB_MAX_WIDTH;
1079
	rc->crc_width = RFB_MAX_WIDTH;
988
	rc->crc_height = RFB_MAX_HEIGHT;
1080
	rc->crc_height = RFB_MAX_HEIGHT;
989
	rc->sfd = -1;
1081
	rc->sfd = -1;

Return to bug 250795