Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/usermode/usermode Implement safe_recv() in analog t...
details: https://anonhg.NetBSD.org/src/rev/ba87db187a7d
branches: trunk
changeset: 772367:ba87db187a7d
user: reinoud <reinoud%NetBSD.org@localhost>
date: Sat Dec 31 12:38:56 2011 +0000
description:
Implement safe_recv() in analog to save_send() to make sure we don't miss
bytes along and mess up the protocol.
diffstat:
sys/arch/usermode/usermode/thunk.c | 114 +++++++++++++++++++++++++-----------
1 files changed, 78 insertions(+), 36 deletions(-)
diffs (219 lines):
diff -r 12976d204bbe -r ba87db187a7d sys/arch/usermode/usermode/thunk.c
--- a/sys/arch/usermode/usermode/thunk.c Sat Dec 31 08:34:49 2011 +0000
+++ b/sys/arch/usermode/usermode/thunk.c Sat Dec 31 12:38:56 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: thunk.c,v 1.68 2011/12/30 21:14:58 reinoud Exp $ */
+/* $NetBSD: thunk.c,v 1.69 2011/12/31 12:38:56 reinoud Exp $ */
/*-
* Copyright (c) 2011 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -28,7 +28,7 @@
#include <sys/cdefs.h>
#ifdef __NetBSD__
-__RCSID("$NetBSD: thunk.c,v 1.68 2011/12/30 21:14:58 reinoud Exp $");
+__RCSID("$NetBSD: thunk.c,v 1.69 2011/12/31 12:38:56 reinoud Exp $");
#endif
#include <sys/types.h>
@@ -897,7 +897,7 @@
return 0;
}
-static int
+static ssize_t
safe_send(int s, const void *msg, size_t len)
{
const uint8_t *p;
@@ -916,6 +916,25 @@
return 0;
}
+static ssize_t
+safe_recv(int s, void *buf, size_t len)
+{
+ uint8_t *p;
+ int recv_len;
+
+ p = buf;
+ while (len) {
+ assert(len >= 0);
+ recv_len = recv(s, p, len, MSG_NOSIGNAL);
+ if (recv_len < 0)
+ return -1;
+
+ p += recv_len;
+ len -= recv_len;
+ }
+ return 0;
+}
+
static int
thunk_rfb_server_init(thunk_rfb_t *rfb)
{
@@ -960,11 +979,9 @@
/* receive client protocol version */
do {
- len = recv(rfb->clientfd, &dummy, sizeof(dummy), MSG_NOSIGNAL);
+ len = safe_recv(rfb->clientfd, &dummy, sizeof(dummy));
if (len < 0)
return errno;
- if (len == 0)
- return EIO;
} while (dummy != '\n');
/* send security capabilities */
@@ -974,9 +991,8 @@
return errno;
/* receive client init message */
- len = recv(rfb->clientfd, &shared_flag, sizeof(shared_flag),
- MSG_NOSIGNAL);
- if (len <= 0)
+ len = safe_recv(rfb->clientfd, &shared_flag, sizeof(shared_flag));
+ if (len < 0)
return errno;
/* send server init message */
@@ -1168,11 +1184,11 @@
if (rfb->clientfd == -1)
return -1;
- thunk_rfb_send_pending(rfb);
-
if (event == NULL)
return 0;
+ thunk_rfb_send_pending(rfb);
+
if (rfb->schedule_bell) {
uint8_t msg_type = 2; /* bell */
safe_send(rfb->clientfd, &msg_type, sizeof(msg_type));
@@ -1180,16 +1196,14 @@
}
error = ioctl(rfb->clientfd, FIONREAD, &len);
- if (error) {
- //printf("rfb: FIONREAD failed: %s\n", strerror(errno));
- close(rfb->clientfd);
- rfb->clientfd = -1;
- return -1;
- }
+ if (error)
+ goto discon;
if (len == 0)
return 0;
- recv(rfb->clientfd, &ch, sizeof(ch), MSG_NOSIGNAL);
+ len = safe_recv(rfb->clientfd, &ch, sizeof(ch));
+ if (len < 0)
+ goto discon;
event->message_type = ch;
switch (ch) {
@@ -1197,25 +1211,39 @@
msg_len = sizeof(set_pixel_format);
break;
case THUNK_RFB_SET_ENCODINGS:
- recv(rfb->clientfd, set_encodings, sizeof(set_encodings),
- MSG_NOSIGNAL);
+ len = safe_recv(rfb->clientfd,
+ set_encodings, sizeof(set_encodings));
+ if (len < 0)
+ goto discon;
msg_len = 4 * ntohs(*(uint16_t *)&set_encodings[1]);
break;
case THUNK_RFB_FRAMEBUFFER_UPDATE_REQUEST:
- recv(rfb->clientfd, framebuffer_update_request,
- sizeof(framebuffer_update_request), MSG_NOSIGNAL);
-#if 0
+ len = safe_recv(rfb->clientfd,
+ framebuffer_update_request,
+ sizeof(framebuffer_update_request));
+ if (len < 0)
+ goto discon;
+#ifdef RFB_DEBUG
+ fprintf(stdout, "framebuffer update request: ");
+ fprintf(stdout, "[%d, %d] + [%d, %d] %s\n",
+ framebuffer_update_request[1],
+ framebuffer_update_request[2],
+ framebuffer_update_request[3],
+ framebuffer_update_request[4],
+ framebuffer_update_request[0]?"Incrmental":"Complete");
+#endif
+
if (framebuffer_update_request[0] == 0) {
-fprintf(stdout, "complete update request\n");
/* complete redraw request -> buffer full */
- rfb->nupdates = __arraycount(rfb->update);
+ rfb->nupdates = __arraycount(rfb->update) + 1;
}
- thunk_rfb_send_pending(rfb);
-#endif
+// thunk_rfb_send_pending(rfb);
msg_len = 0;
break;
case THUNK_RFB_KEY_EVENT:
- recv(rfb->clientfd, key_event, sizeof(key_event), MSG_NOSIGNAL);
+ len = safe_recv(rfb->clientfd, key_event, sizeof(key_event));
+ if (len < 0)
+ goto discon;
event->data.key_event.down_flag = key_event[0];
event->data.key_event.keysym =
ntohl(*(uint32_t *)&key_event[3]);
@@ -1227,8 +1255,10 @@
msg_len = 0;
break;
case THUNK_RFB_POINTER_EVENT:
- recv(rfb->clientfd, pointer_event, sizeof(pointer_event),
- MSG_NOSIGNAL);
+ len = safe_recv(rfb->clientfd,
+ pointer_event, sizeof(pointer_event));
+ if (len < 0)
+ goto discon;
event->data.pointer_event.button_mask = pointer_event[0];
event->data.pointer_event.absx =
ntohs(*(uint16_t *)&pointer_event[1]);
@@ -1243,23 +1273,35 @@
msg_len = 0;
break;
case THUNK_RFB_CLIENT_CUT_TEXT:
- recv(rfb->clientfd, client_cut_text, sizeof(client_cut_text),
- MSG_NOSIGNAL);
+ len = safe_recv(rfb->clientfd,
+ client_cut_text, sizeof(client_cut_text));
+ if (len < 0)
+ goto discon;
msg_len = ntohl(*(uint32_t *)&client_cut_text[3]);
break;
default:
fprintf(stdout, "rfb: unknown message type %d\n", ch);
- close(rfb->clientfd);
- rfb->clientfd = -1;
- return -1;
+ goto discon;
}
+ if (len < 0)
+ goto discon;
+
/* discard any remaining bytes */
while (msg_len-- > 0) {
- recv(rfb->clientfd, &ch, sizeof(ch), MSG_NOSIGNAL);
+ len = safe_recv(rfb->clientfd, &ch, sizeof(ch));
+ if (len < 0)
+ goto discon;
}
return 1;
+
+discon:
+ //printf("rfb: safe_recv failed: %s\n", strerror(errno));
+ close(rfb->clientfd);
+ rfb->clientfd = -1;
+
+ return -1;
}
void
Home |
Main Index |
Thread Index |
Old Index