Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/external/source/vncdll/winvnc/VSocket.cpp
24706 views
1
// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
2
// Copyright (C) 2001 HorizonLive.com, Inc. All Rights Reserved.
3
//
4
// This file is part of the VNC system.
5
//
6
// The VNC system is free software; you can redistribute it and/or modify
7
// it under the terms of the GNU General Public License as published by
8
// the Free Software Foundation; either version 2 of the License, or
9
// (at your option) any later version.
10
//
11
// This program is distributed in the hope that it will be useful,
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
// GNU General Public License for more details.
15
//
16
// You should have received a copy of the GNU General Public License
17
// along with this program; if not, write to the Free Software
18
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19
// USA.
20
//
21
// TightVNC distribution homepage on the Web: http://www.tightvnc.com/
22
//
23
// If the source code for the VNC system is not available from the place
24
// whence you received this file, check http://www.uk.research.att.com/vnc or contact
25
// the authors on [email protected] for information on obtaining it.
26
27
28
// VSocket.cpp
29
30
// The VSocket class provides a platform-independent socket abstraction
31
// with the simple functionality required for an RFB server.
32
33
class VSocket;
34
35
////////////////////////////////////////////////////////
36
// System includes
37
38
#include "stdhdrs.h"
39
40
// Visual C++ .NET 2003 compatibility
41
#if (_MSC_VER>= 1300)
42
#include <iostream>
43
#else
44
#include <iostream.h>
45
#endif
46
47
#include <stdio.h>
48
#ifdef __WIN32__
49
#include <io.h>
50
#include <winsock.h>
51
#else
52
#include <sys/types.h>
53
#include <sys/socket.h>
54
#include <arpa/inet.h>
55
#include <netinet/in.h>
56
#include <netdb.h>
57
#include <unistd.h>
58
#include <fcntl.h>
59
#include <errno.h>
60
#include <string.h>
61
#include <signal.h>
62
#endif
63
#include <sys/types.h>
64
65
////////////////////////////////////////////////////////
66
// Custom includes
67
68
#include "VTypes.h"
69
70
////////////////////////////////////////////////////////
71
// *** Lovely hacks to make Win32 work. Hurrah!
72
73
#if defined(__WIN32__) && !defined(EWOULDBLOCK)
74
#define EWOULDBLOCK WSAEWOULDBLOCK
75
#endif
76
77
////////////////////////////////////////////////////////
78
// Socket implementation
79
80
#include "VSocket.h"
81
82
// The socket timeout value (currently 5 seconds, for no reason...)
83
// *** THIS IS NOT CURRENTLY USED ANYWHERE
84
const VInt rfbMaxClientWait = 5000;
85
86
////////////////////////////
87
// Socket implementation initialisation
88
89
static WORD winsockVersion = 0;
90
91
VSocketSystem::VSocketSystem()
92
{
93
// Initialise the socket subsystem
94
// This is only provided for compatibility with Windows.
95
96
#ifdef __WIN32__
97
// Initialise WinPoxySockets on Win32
98
WORD wVersionRequested;
99
WSADATA wsaData;
100
101
wVersionRequested = MAKEWORD(2, 2);
102
if (WSAStartup(wVersionRequested, &wsaData) != 0)
103
{
104
m_status = VFalse;
105
return;
106
}
107
108
winsockVersion = wsaData.wVersion;
109
110
#else
111
// Disable the nasty read/write failure signals on UNIX
112
signal(SIGPIPE, SIG_IGN);
113
#endif
114
115
// If successful, or if not required, then continue!
116
m_status = VTrue;
117
}
118
119
VSocketSystem::~VSocketSystem()
120
{
121
/*if (m_status)
122
{
123
WSACleanup();
124
}*/
125
}
126
127
////////////////////////////
128
129
VSocket::VSocket()
130
{
131
// Clear out the internal socket fields
132
sock = -1;
133
hCloseEvent = NULL;
134
out_queue = NULL;
135
}
136
137
VSocket::VSocket( WSAPROTOCOL_INFO * pSocketInfo, HANDLE hClose )
138
{
139
sock = (int)WSASocket( AF_INET, SOCK_STREAM, 0, pSocketInfo, 0, 0 );
140
if( sock == INVALID_SOCKET )
141
sock = -1;
142
//BREAK_ON_WSAERROR( "[VNCDLL] vncdll_run. WSASocketA failed" );
143
144
// Clear out the internal socket fields
145
//sock = (int)socket;
146
hCloseEvent = hClose;
147
out_queue = NULL;
148
}
149
////////////////////////////
150
151
VSocket::~VSocket()
152
{
153
// Close the socket
154
Close();
155
}
156
157
////////////////////////////
158
159
VBool
160
VSocket::Create()
161
{
162
const int one = 1;
163
164
// Check that the old socket was closed
165
if (sock >= 0)
166
Close();
167
168
// Create the socket
169
if ((sock = (int)socket(AF_INET, SOCK_STREAM, 0)) < 0)
170
{
171
return VFalse;
172
}
173
174
// Set the socket options:
175
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)))
176
{
177
return VFalse;
178
}
179
if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(one)))
180
{
181
return VFalse;
182
}
183
184
return VTrue;
185
}
186
187
////////////////////////////
188
189
extern HANDLE hCloseEvent;
190
191
VBool VSocket::Close()
192
{
193
if( sock >= 0 )
194
{
195
//shutdown(sock, SD_BOTH);
196
//closesocket(sock);
197
//CloseHandle( (HANDLE)sock );
198
sock = -1;
199
SetEvent( hCloseEvent );
200
}
201
202
while (out_queue)
203
{
204
AIOBlock *next = out_queue->next;
205
delete out_queue;
206
out_queue = next;
207
}
208
209
return VTrue;
210
}
211
212
////////////////////////////
213
214
VBool
215
VSocket::Shutdown()
216
{
217
/*if (sock >= 0)
218
{
219
shutdown(sock, SD_BOTH);
220
}*/
221
while (out_queue)
222
{
223
AIOBlock *next = out_queue->next;
224
delete out_queue;
225
out_queue = next;
226
}
227
228
return VTrue;
229
}
230
231
////////////////////////////
232
233
VBool
234
VSocket::Bind(const VCard port, const VBool localOnly,
235
const VBool checkIfInUse)
236
{
237
return VFalse;
238
/*struct sockaddr_in addr;
239
240
// Check that the socket is open!
241
if (sock < 0)
242
return VFalse;
243
244
// If a specific port is being set then check it's not already used!
245
if (port != 0 && checkIfInUse)
246
{
247
VSocket dummy;
248
249
if (dummy.Create())
250
{
251
// If we're able to connect then the port number is in use...
252
if (dummy.Connect("localhost", port))
253
return VFalse;
254
}
255
}
256
257
// Set up the address to bind the socket to
258
addr.sin_family = AF_INET;
259
addr.sin_port = htons(port);
260
if (localOnly)
261
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
262
else
263
addr.sin_addr.s_addr = htonl(INADDR_ANY);
264
265
// And do the binding
266
if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0)
267
return VFalse;
268
269
return VTrue;*/
270
}
271
272
////////////////////////////
273
274
VBool
275
VSocket::Connect(VStringConst address, const VCard port)
276
{
277
return VFalse;
278
/*
279
// Check the socket
280
if (sock < 0)
281
return VFalse;
282
283
// Create an address structure and clear it
284
struct sockaddr_in addr;
285
memset(&addr, 0, sizeof(addr));
286
287
// Fill in the address if possible
288
addr.sin_family = AF_INET;
289
addr.sin_addr.s_addr = inet_addr(address);
290
291
// Was the string a valid IP address?
292
if (addr.sin_addr.s_addr == -1)
293
{
294
// No, so get the actual IP address of the host name specified
295
struct hostent *pHost;
296
pHost = gethostbyname(address);
297
if (pHost != NULL)
298
{
299
if (pHost->h_addr == NULL)
300
return VFalse;
301
addr.sin_addr.s_addr = ((struct in_addr *)pHost->h_addr)->s_addr;
302
}
303
else
304
return VFalse;
305
}
306
307
// Set the port number in the correct format
308
addr.sin_port = htons(port);
309
310
// Actually connect the socket
311
if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) != 0)
312
return VFalse;
313
314
// Put the socket into non-blocking mode
315
#ifdef __WIN32__
316
u_long arg = 1;
317
if (ioctlsocket(sock, FIONBIO, &arg) != 0)
318
return VFalse;
319
#else
320
if (fcntl(sock, F_SETFL, O_NDELAY) != 0)
321
return VFalse;
322
#endif
323
324
return VTrue;*/
325
}
326
327
////////////////////////////
328
329
VBool
330
VSocket::Listen()
331
{
332
return VFalse;
333
/*
334
// Check socket
335
if (sock < 0)
336
return VFalse;
337
338
// Set it to listen
339
if (listen(sock, 5) < 0)
340
return VFalse;
341
342
return VTrue;*/
343
}
344
345
////////////////////////////
346
347
VSocket *
348
VSocket::Accept()
349
{
350
return VFalse;
351
/*
352
const int one = 1;
353
354
int new_socket_id;
355
VSocket * new_socket;
356
357
// Check this socket
358
if (sock < 0)
359
return NULL;
360
361
// Accept an incoming connection
362
if ((new_socket_id = (int)accept(sock, NULL, 0)) < 0)
363
return NULL;
364
365
// Create a new VSocket and return it
366
new_socket = new VSocket;
367
if (new_socket != NULL)
368
{
369
new_socket->sock = new_socket_id;
370
}
371
else
372
{
373
shutdown(new_socket_id, SD_BOTH);
374
closesocket(new_socket_id);
375
return NULL;
376
}
377
378
// Attempt to set the new socket's options
379
setsockopt(new_socket->sock, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(one));
380
381
// Put the socket into non-blocking mode
382
#ifdef __WIN32__
383
u_long arg = 1;
384
if (ioctlsocket(new_socket->sock, FIONBIO, &arg) != 0) {
385
delete new_socket;
386
new_socket = NULL;
387
}
388
#else
389
if (fcntl(new_socket->sock, F_SETFL, O_NDELAY) != 0) {
390
delete new_socket;
391
new_socket = NULL;
392
}
393
#endif
394
395
return new_socket;*/
396
}
397
398
////////////////////////////
399
400
VBool
401
VSocket::TryAccept(VSocket **new_socket, long ms)
402
{
403
return VFalse;
404
/*
405
// Check this socket
406
if (sock < 0)
407
return NULL;
408
409
struct fd_set fds;
410
struct timeval tm;
411
FD_ZERO(&fds);
412
FD_SET((unsigned int)sock, &fds);
413
tm.tv_sec = ms / 1000;
414
tm.tv_usec = (ms % 1000) * 1000;
415
int ready = select(sock + 1, &fds, NULL, NULL, &tm);
416
if (ready == 0) {
417
// Timeout
418
*new_socket = NULL;
419
return VTrue;
420
} else if (ready != 1) {
421
// Error
422
return VFalse;
423
}
424
// Ready to accept new connection
425
VSocket *s = Accept();
426
if (s == NULL)
427
return VFalse;
428
// Success
429
*new_socket = s;
430
return VTrue;*/
431
}
432
433
////////////////////////////
434
435
VString VSocket::GetPeerName()
436
{
437
return "<unavailable>";
438
}
439
440
////////////////////////////
441
442
VString VSocket::GetSockName()
443
{
444
return "<unavailable>";
445
}
446
447
////////////////////////////
448
449
VCard32
450
VSocket::Resolve(VStringConst address)
451
{
452
VCard32 addr;
453
454
// Try converting the address as IP
455
addr = inet_addr(address);
456
457
// Was it a valid IP address?
458
if (addr == 0xffffffff)
459
{
460
// No, so get the actual IP address of the host name specified
461
struct hostent *pHost;
462
pHost = gethostbyname(address);
463
if (pHost != NULL)
464
{
465
if (pHost->h_addr == NULL)
466
return 0;
467
addr = ((struct in_addr *)pHost->h_addr)->s_addr;
468
}
469
else
470
return 0;
471
}
472
473
// Return the resolved IP address as an integer
474
return addr;
475
}
476
477
////////////////////////////
478
479
VBool
480
VSocket::SetTimeout(VCard32 secs)
481
{
482
//if (LOBYTE(winsockVersion) < 2)
483
// return VFalse;
484
int timeout=secs;
485
if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout)) == SOCKET_ERROR)
486
{
487
return VFalse;
488
}
489
if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof(timeout)) == SOCKET_ERROR)
490
{
491
return VFalse;
492
}
493
return VTrue;
494
}
495
496
////////////////////////////
497
498
VInt VSocket::Send(const char *buff, const VCard bufflen)
499
{
500
errno = 0;
501
502
VInt bytes = send(sock, buff, bufflen, 0);
503
if (bytes < 0)
504
{
505
int wsa_error = WSAGetLastError();
506
#ifdef __WIN32__
507
if (wsa_error == WSAEWOULDBLOCK)
508
errno = EWOULDBLOCK;
509
#endif
510
}
511
512
return bytes;
513
}
514
515
////////////////////////////
516
517
VBool
518
VSocket::SendExact(const char *buff, const VCard bufflen)
519
{
520
struct fd_set write_fds;
521
struct timeval tm;
522
int count;
523
524
// Put the data into the queue
525
SendQueued(buff, bufflen);
526
527
while (out_queue) {
528
// Wait until some data can be sent
529
do {
530
FD_ZERO(&write_fds);
531
FD_SET((unsigned int)sock, &write_fds);
532
tm.tv_sec = 1;
533
tm.tv_usec = 0;
534
count = select(sock + 1, NULL, &write_fds, NULL, &tm);
535
} while (count == 0);
536
if (count < 0 || count > 1) {
537
return VFalse;
538
}
539
// Actually send some data
540
if (FD_ISSET((unsigned int)sock, &write_fds)) {
541
if (!SendFromQueue())
542
return VFalse;
543
}
544
}
545
546
return VTrue;
547
}
548
549
////////////////////////////
550
551
VBool
552
VSocket::SendQueued(const char *buff, const VCard bufflen)
553
{
554
omni_mutex_lock l(queue_lock);
555
556
// Just append new bytes to the output queue
557
if (!out_queue) {
558
out_queue = new AIOBlock(bufflen, buff);
559
bytes_sent = 0;
560
} else {
561
AIOBlock *last = out_queue;
562
while (last->next)
563
last = last->next;
564
last->next = new AIOBlock(bufflen, buff);
565
}
566
567
return VTrue;
568
}
569
570
////////////////////////////
571
572
VBool
573
VSocket::SendFromQueue()
574
{
575
omni_mutex_lock l(queue_lock);
576
577
// Is there something to send?
578
if (!out_queue)
579
return VTrue;
580
581
// Maximum data size to send at once
582
size_t portion_size = out_queue->data_size - bytes_sent;
583
if (portion_size > 32768)
584
portion_size = 32768;
585
586
// Try to send some data
587
int bytes = Send(out_queue->data_ptr + bytes_sent, (VCard)portion_size);
588
if (bytes > 0) {
589
bytes_sent += bytes;
590
} else if (bytes < 0 && errno != EWOULDBLOCK) {
591
return VFalse;
592
}
593
594
// Remove block if all its data has been sent
595
if (bytes_sent == out_queue->data_size) {
596
AIOBlock *sent = out_queue;
597
out_queue = sent->next;
598
bytes_sent = 0;
599
delete sent;
600
}
601
602
return VTrue;
603
}
604
605
////////////////////////////
606
607
VInt
608
VSocket::Read(char *buff, const VCard bufflen)
609
{
610
errno = 0;
611
612
VInt bytes = recv(sock, buff, bufflen, 0);
613
614
#ifdef __WIN32__
615
if (bytes < 0 && WSAGetLastError() == WSAEWOULDBLOCK)
616
errno = EWOULDBLOCK;
617
#endif
618
619
return bytes;
620
}
621
622
////////////////////////////
623
624
VBool
625
VSocket::ReadExact(char *buff, const VCard bufflen)
626
{
627
int bytes;
628
VCard currlen = bufflen;
629
struct fd_set read_fds, write_fds;
630
struct timeval tm;
631
int count;
632
633
while (currlen > 0) {
634
// Wait until some data can be read or sent
635
do {
636
FD_ZERO(&read_fds);
637
FD_SET((unsigned int)sock, &read_fds);
638
FD_ZERO(&write_fds);
639
if (out_queue)
640
FD_SET((unsigned int)sock, &write_fds);
641
tm.tv_sec = 0;
642
tm.tv_usec = 50;
643
count = select(sock + 1, &read_fds, &write_fds, NULL, &tm);
644
} while (count == 0);
645
if (count < 0 || count > 2) {
646
return VFalse;
647
}
648
if (FD_ISSET((unsigned int)sock, &write_fds)) {
649
// Try to send some data
650
if (!SendFromQueue())
651
return VFalse;
652
}
653
if (FD_ISSET((unsigned int)sock, &read_fds)) {
654
// Try to read some data in
655
bytes = Read(buff, currlen);
656
if (bytes > 0) {
657
// Adjust the buffer position and size
658
buff += bytes;
659
currlen -= bytes;
660
} else if (bytes < 0 && errno != EWOULDBLOCK) {
661
return VFalse;
662
} else if (bytes == 0) {
663
return VFalse;
664
}
665
}
666
}
667
668
return VTrue;
669
}
670
671
672