1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkSocket.cxx
5
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the above copyright notice for more information.
13
14 =========================================================================*/
15 #include "vtkSocket.h"
16
17 #include "vtkObjectFactory.h"
18
19 // The VTK_SOCKET_FAKE_API definition is given to the compiler
20 // command line by CMakeLists.txt if there is no real sockets
21 // interface available. When this macro is defined we simply make
22 // every method return failure.
23 //
24 // Perhaps we should add a method to query at runtime whether a real
25 // sockets interface is available.
26
27 #ifndef VTK_SOCKET_FAKE_API
28 #if defined(_WIN32) && !defined(__CYGWIN__)
29 #define VTK_WINDOWS_FULL
30 #include "vtkWindows.h"
31 #include "vtksys/Encoding.hxx"
32 #else
33 #include <arpa/inet.h>
34 #include <cerrno>
35 #include <cstdio>
36 #include <cstring>
37 #include <netdb.h>
38 #include <netinet/in.h>
39 #include <netinet/tcp.h>
40 #include <sys/socket.h>
41 #include <sys/time.h>
42 #include <sys/types.h>
43 #include <unistd.h>
44 #endif
45 #endif
46
47 #if defined(_WIN32) && !defined(__CYGWIN__)
48
49 // TODO : document why we restrict to v1.1
50 #define WSA_VERSION MAKEWORD(1, 1)
51
52 #define vtkCloseSocketMacro(sock) (closesocket(sock))
53 #define vtkErrnoMacro (WSAGetLastError())
54 #define vtkStrerrorMacro(_num) (wsaStrerror(_num))
55 #define vtkSocketErrorIdMacro(_id) (WSA##_id)
56 #define vtkSocketErrorReturnMacro (SOCKET_ERROR)
57
58 #else
59
60 #define vtkCloseSocketMacro(sock) (close(sock))
61 #define vtkErrnoMacro (errno)
62 #define vtkStrerrorMacro(_num) (strerror(_num))
63 #define vtkSocketErrorIdMacro(_id) (_id)
64 #define vtkSocketErrorReturnMacro (-1)
65
66 #endif
67
68 // This macro wraps a system function call(_call),
69 // restarting the call in case it was interrupted
70 // by a signal (EINTR).
71 #define vtkRestartInterruptedSystemCallMacro(_call, _ret) \
72 do \
73 { \
74 (_ret) = (_call); \
75 } while ( \
76 ((_ret) == vtkSocketErrorReturnMacro) && (vtkErrnoMacro == vtkSocketErrorIdMacro(EINTR)));
77
78 // use when _str may be a null pointer but _fallback is not.
79 #define vtkSafeStrMacro(_str, _fallback) ((_str) ? (_str) : (_fallback))
80
81 // convert error number to string and report via vtkErrorMacro.
82 #define vtkSocketErrorMacro(_eno, _message) \
83 vtkErrorMacro(<< (_message) << " " << vtkSafeStrMacro(vtkStrerrorMacro(_eno), "unknown error") \
84 << ".");
85
86 // convert error number to string and report via vtkGenericWarningMacro
87 #define vtkSocketGenericErrorMacro(_message) \
88 vtkGenericWarningMacro(<< (_message) << " " \
89 << vtkSafeStrMacro(vtkStrerrorMacro(vtkErrnoMacro), "unknown error") \
90 << ".");
91
92 // on windows strerror doesn't handle socket error codes
93 #if defined(_WIN32) && !defined(__CYGWIN__)
wsaStrerror(int wsaeid)94 static const char* wsaStrerror(int wsaeid)
95 {
96 wchar_t wbuf[256];
97 int ok = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, 0, wsaeid, 0, wbuf, sizeof(wbuf), 0);
98 if (!ok)
99 {
100 return nullptr;
101 }
102
103 std::string result = vtksys::Encoding::ToNarrow(wbuf);
104 size_t count = result.length();
105
106 static char buf[256];
107 if (count >= sizeof(buf))
108 {
109 count = sizeof(buf) - 1;
110 }
111 strncpy(buf, result.c_str(), count);
112 buf[count + 1] = '\0';
113
114 return buf;
115 }
116 #endif
117
118 //------------------------------------------------------------------------------
vtkSocket()119 vtkSocket::vtkSocket()
120 {
121 this->SocketDescriptor = -1;
122 }
123
124 //------------------------------------------------------------------------------
~vtkSocket()125 vtkSocket::~vtkSocket()
126 {
127 if (this->SocketDescriptor != -1)
128 {
129 this->CloseSocket(this->SocketDescriptor);
130 this->SocketDescriptor = -1;
131 }
132 }
133
134 //------------------------------------------------------------------------------
CreateSocket()135 int vtkSocket::CreateSocket()
136 {
137 #ifndef VTK_SOCKET_FAKE_API
138 int sock;
139 vtkRestartInterruptedSystemCallMacro(socket(AF_INET, SOCK_STREAM, 0), sock);
140 if (sock == vtkSocketErrorReturnMacro)
141 {
142 vtkSocketErrorMacro(vtkErrnoMacro, "Socket error in call to socket.");
143 return -1;
144 }
145
146 // Elimate windows 0.2 second delay sending (buffering) data.
147 int on = 1;
148 int iErr;
149 vtkRestartInterruptedSystemCallMacro(
150 setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on, sizeof(on)), iErr);
151 if (iErr == vtkSocketErrorReturnMacro)
152 {
153 vtkSocketErrorMacro(vtkErrnoMacro, "Socket error in call to setsockopt.");
154 return -1;
155 }
156
157 return sock;
158 #else
159 return -1;
160 #endif
161 }
162
163 //------------------------------------------------------------------------------
CloseSocket()164 void vtkSocket::CloseSocket()
165 {
166 this->CloseSocket(this->SocketDescriptor);
167 this->SocketDescriptor = -1;
168 }
169
170 //------------------------------------------------------------------------------
BindSocket(int socketdescriptor,int port)171 int vtkSocket::BindSocket(int socketdescriptor, int port)
172 {
173 #ifndef VTK_SOCKET_FAKE_API
174 struct sockaddr_in server;
175
176 server.sin_family = AF_INET;
177 server.sin_addr.s_addr = INADDR_ANY;
178 server.sin_port = htons(port);
179 // Allow the socket to be bound to an address that is already in use
180 int opt = 1;
181 int iErr = ~vtkSocketErrorReturnMacro;
182 #ifdef _WIN32
183 vtkRestartInterruptedSystemCallMacro(
184 setsockopt(socketdescriptor, SOL_SOCKET, SO_REUSEADDR, (char*)&opt, sizeof(int)), iErr);
185 #elif defined(VTK_HAVE_SO_REUSEADDR)
186 vtkRestartInterruptedSystemCallMacro(
187 setsockopt(socketdescriptor, SOL_SOCKET, SO_REUSEADDR, (char*)&opt, sizeof(int)), iErr);
188 #endif
189 if (iErr == vtkSocketErrorReturnMacro)
190 {
191 vtkSocketErrorMacro(vtkErrnoMacro, "Socket error in call to setsockopt.");
192 return -1;
193 }
194
195 vtkRestartInterruptedSystemCallMacro(
196 bind(socketdescriptor, reinterpret_cast<sockaddr*>(&server), sizeof(server)), iErr);
197 if (iErr == vtkSocketErrorReturnMacro)
198 {
199 vtkSocketErrorMacro(vtkErrnoMacro, "Socket error in call to bind.");
200 return -1;
201 }
202
203 return 0;
204 #else
205 static_cast<void>(socketdescriptor);
206 static_cast<void>(port);
207 return -1;
208 #endif
209 }
210
211 //------------------------------------------------------------------------------
Accept(int socketdescriptor)212 int vtkSocket::Accept(int socketdescriptor)
213 {
214 #ifndef VTK_SOCKET_FAKE_API
215 if (socketdescriptor < 0)
216 {
217 vtkErrorMacro("Invalid descriptor.");
218 return -1;
219 }
220
221 int newDescriptor;
222 vtkRestartInterruptedSystemCallMacro(accept(socketdescriptor, nullptr, nullptr), newDescriptor);
223 if (newDescriptor == vtkSocketErrorReturnMacro)
224 {
225 vtkSocketErrorMacro(vtkErrnoMacro, "Socket error in call to accept.");
226 return -1;
227 }
228
229 return newDescriptor;
230 #else
231 static_cast<void>(socketdescriptor);
232 return -1;
233 #endif
234 }
235
236 //------------------------------------------------------------------------------
Listen(int socketdescriptor)237 int vtkSocket::Listen(int socketdescriptor)
238 {
239 #ifndef VTK_SOCKET_FAKE_API
240 if (socketdescriptor < 0)
241 {
242 vtkErrorMacro("Invalid descriptor.");
243 return -1;
244 }
245
246 int iErr;
247 vtkRestartInterruptedSystemCallMacro(listen(socketdescriptor, 1), iErr);
248 if (iErr == vtkSocketErrorReturnMacro)
249 {
250 vtkSocketErrorMacro(vtkErrnoMacro, "Socket error in call to listen.");
251 return -1;
252 }
253
254 return 0;
255 #else
256 static_cast<void>(socketdescriptor);
257 return -1;
258 #endif
259 }
260
261 //------------------------------------------------------------------------------
SelectSocket(int socketdescriptor,unsigned long msec)262 int vtkSocket::SelectSocket(int socketdescriptor, unsigned long msec)
263 {
264 #ifndef VTK_SOCKET_FAKE_API
265 if (socketdescriptor < 0)
266 {
267 vtkErrorMacro("Invalid descriptor.");
268 return -1;
269 }
270
271 fd_set rset;
272 int res;
273 do
274 {
275 struct timeval tval;
276 struct timeval* tvalptr = nullptr;
277 if (msec > 0)
278 {
279 tval.tv_sec = msec / 1000;
280 tval.tv_usec = (msec % 1000) * 1000;
281 tvalptr = &tval;
282 }
283
284 FD_ZERO(&rset);
285 FD_SET(socketdescriptor, &rset);
286
287 // block until socket is readable.
288 res = select(socketdescriptor + 1, &rset, nullptr, nullptr, tvalptr);
289 } while ((res == vtkSocketErrorReturnMacro) && (vtkErrnoMacro == vtkSocketErrorIdMacro(EINTR)));
290
291 if (res == 0)
292 {
293 // time out
294 return 0;
295 }
296 else if (res == vtkSocketErrorReturnMacro)
297 {
298 // error in the call
299 vtkSocketErrorMacro(vtkErrnoMacro, "Socket error in call to select.");
300 return -1;
301 }
302 else if (!FD_ISSET(socketdescriptor, &rset))
303 {
304 vtkErrorMacro("Socket error in select. Descriptor not selected.");
305 return -1;
306 }
307
308 // NOTE: not checking for pending errors,these will be handled
309 // in the next call to read/recv
310
311 // The indicated socket has some activity on it.
312 return 1;
313 #else
314 static_cast<void>(socketdescriptor);
315 static_cast<void>(msec);
316 return -1;
317 #endif
318 }
319
320 //------------------------------------------------------------------------------
SelectSockets(const int * sockets_to_select,int size,unsigned long msec,int * selected_index)321 int vtkSocket::SelectSockets(
322 const int* sockets_to_select, int size, unsigned long msec, int* selected_index)
323 {
324 #ifndef VTK_SOCKET_FAKE_API
325
326 *selected_index = -1;
327
328 if (size < 0)
329 {
330 vtkGenericWarningMacro("Can't select fewer than 0.");
331 return -1;
332 }
333
334 fd_set rset;
335 int res = -1;
336 do
337 {
338 struct timeval tval;
339 struct timeval* tvalptr = nullptr;
340 if (msec > 0)
341 {
342 tval.tv_sec = msec / 1000;
343 tval.tv_usec = (msec % 1000) * 1000;
344 tvalptr = &tval;
345 }
346
347 FD_ZERO(&rset);
348 int max_fd = -1;
349 for (int i = 0; i < size; i++)
350 {
351 FD_SET(sockets_to_select[i], &rset);
352 max_fd = (sockets_to_select[i] > max_fd ? sockets_to_select[i] : max_fd);
353 }
354
355 // block until one socket is ready to read.
356 res = select(max_fd + 1, &rset, nullptr, nullptr, tvalptr);
357 } while ((res == vtkSocketErrorReturnMacro) && (vtkErrnoMacro == vtkSocketErrorIdMacro(EINTR)));
358
359 if (res == 0)
360 {
361 // time out
362 return 0;
363 }
364 else if (res == vtkSocketErrorReturnMacro)
365 {
366 // error in the call
367 vtkSocketGenericErrorMacro("Socket error in call to select.");
368 return -1;
369 }
370
371 // find the first socket which has some activity.
372 for (int i = 0; i < size; i++)
373 {
374 if (FD_ISSET(sockets_to_select[i], &rset))
375 {
376 // NOTE: not checking for pending errors, these
377 // will be handled in the next call to read/recv
378
379 *selected_index = i;
380 return 1;
381 }
382 }
383
384 // no activity on any of the sockets
385 vtkGenericWarningMacro("Socket error in select. No descriptor selected.");
386 return -1;
387 #else
388 static_cast<void>(sockets_to_select);
389 static_cast<void>(size);
390 static_cast<void>(msec);
391 static_cast<void>(selected_index);
392 return -1;
393 #endif
394 }
395
396 //------------------------------------------------------------------------------
Connect(int socketdescriptor,const char * hostName,int port)397 int vtkSocket::Connect(int socketdescriptor, const char* hostName, int port)
398 {
399 #ifndef VTK_SOCKET_FAKE_API
400 if (socketdescriptor < 0)
401 {
402 vtkErrorMacro("Invalid descriptor.");
403 return -1;
404 }
405
406 struct hostent* hp;
407 hp = gethostbyname(hostName);
408 if (!hp)
409 {
410 unsigned long addr = inet_addr(hostName);
411 hp = gethostbyaddr((char*)&addr, sizeof(addr), AF_INET);
412 }
413 if (!hp)
414 {
415 vtkErrorMacro("Unknown host: " << hostName);
416 return -1;
417 }
418
419 struct sockaddr_in name;
420 name.sin_family = AF_INET;
421 memcpy(&name.sin_addr, hp->h_addr, hp->h_length);
422 name.sin_port = htons(port);
423
424 int iErr = connect(socketdescriptor, reinterpret_cast<sockaddr*>(&name), sizeof(name));
425 if ((iErr == vtkSocketErrorReturnMacro) && (vtkErrnoMacro == vtkSocketErrorIdMacro(EINTR)))
426 {
427 // Restarting an interrupted connect call only works on linux,
428 // other unix require a call to select which blocks until the
429 // connection is complete.
430 // See Stevens 2d ed, 15.4 p413, "interrupted connect"
431 iErr = this->SelectSocket(socketdescriptor, 0);
432 if (iErr == -1)
433 {
434 // SelectSocket doesn't test for pending errors.
435 int pendingErr;
436 #if defined(VTK_HAVE_GETSOCKNAME_WITH_SOCKLEN_T)
437 socklen_t pendingErrLen = sizeof(pendingErr);
438 #else
439 int pendingErrLen = sizeof(pendingErr);
440 #endif
441
442 vtkRestartInterruptedSystemCallMacro(
443 getsockopt(socketdescriptor, SOL_SOCKET, SO_ERROR, (char*)&pendingErr, &pendingErrLen),
444 iErr);
445 if (iErr == vtkSocketErrorReturnMacro)
446 {
447 vtkSocketErrorMacro(vtkErrnoMacro, "Socket error in call to getsockopt.");
448 return -1;
449 }
450 else if (pendingErr)
451 {
452 vtkSocketErrorMacro(pendingErr, "Socket error pending from call to connect.");
453 return -1;
454 }
455 }
456 }
457 else if (iErr == vtkSocketErrorReturnMacro)
458 {
459 vtkSocketErrorMacro(vtkErrnoMacro, "Socket error in call to connect.");
460 return -1;
461 }
462
463 return 0;
464 #else
465 static_cast<void>(socketdescriptor);
466 static_cast<void>(hostName);
467 static_cast<void>(port);
468 return -1;
469 #endif
470 }
471
472 //------------------------------------------------------------------------------
GetPort(int sock)473 int vtkSocket::GetPort(int sock)
474 {
475 #ifndef VTK_SOCKET_FAKE_API
476 struct sockaddr_in sockinfo;
477 memset(&sockinfo, 0, sizeof(sockinfo));
478 #if defined(VTK_HAVE_GETSOCKNAME_WITH_SOCKLEN_T)
479 socklen_t sizebuf = sizeof(sockinfo);
480 #else
481 int sizebuf = sizeof(sockinfo);
482 #endif
483
484 int iErr;
485 vtkRestartInterruptedSystemCallMacro(
486 getsockname(sock, reinterpret_cast<sockaddr*>(&sockinfo), &sizebuf), iErr);
487 if (iErr == vtkSocketErrorReturnMacro)
488 {
489 vtkSocketErrorMacro(vtkErrnoMacro, "Socket error in call to getsockname.");
490 return 0;
491 }
492 return ntohs(sockinfo.sin_port);
493 #else
494 static_cast<void>(sock);
495 return -1;
496 #endif
497 }
498
499 //------------------------------------------------------------------------------
CloseSocket(int socketdescriptor)500 void vtkSocket::CloseSocket(int socketdescriptor)
501 {
502 #ifndef VTK_SOCKET_FAKE_API
503 if (socketdescriptor < 0)
504 {
505 vtkErrorMacro("Invalid descriptor.");
506 return;
507 }
508 int iErr;
509 vtkRestartInterruptedSystemCallMacro(vtkCloseSocketMacro(socketdescriptor), iErr);
510 if (iErr == vtkSocketErrorReturnMacro)
511 {
512 vtkSocketErrorMacro(vtkErrnoMacro, "Socket error in call to close/closesocket.");
513 }
514 #else
515 static_cast<void>(socketdescriptor);
516 return;
517 #endif
518 }
519
520 //------------------------------------------------------------------------------
Send(const void * data,int length)521 int vtkSocket::Send(const void* data, int length)
522 {
523 #ifndef VTK_SOCKET_FAKE_API
524 if (!this->GetConnected())
525 {
526 vtkErrorMacro("Not connected.");
527 return 0;
528 }
529 if (length == 0)
530 {
531 // nothing to send.
532 return 1;
533 }
534 const char* buffer = reinterpret_cast<const char*>(data);
535 int total = 0;
536 do
537 {
538 int flags = 0;
539 int nSent;
540 vtkRestartInterruptedSystemCallMacro(
541 send(this->SocketDescriptor, buffer + total, length - total, flags), nSent);
542 if (nSent == vtkSocketErrorReturnMacro)
543 {
544 vtkSocketErrorMacro(vtkErrnoMacro, "Socket error in call to send.");
545 return 0;
546 }
547 total += nSent;
548 } while (total < length);
549
550 return 1;
551 #else
552 static_cast<void>(data);
553 static_cast<void>(length);
554 return 0;
555 #endif
556 }
557
558 //------------------------------------------------------------------------------
Receive(void * data,int length,int readFully)559 int vtkSocket::Receive(void* data, int length, int readFully /*=1*/)
560 {
561 #ifndef VTK_SOCKET_FAKE_API
562 if (!this->GetConnected())
563 {
564 vtkErrorMacro("Not connected.");
565 return 0;
566 }
567
568 #if defined(_WIN32) && !defined(__CYGWIN__)
569 int tries = 0;
570 #endif
571
572 char* buffer = reinterpret_cast<char*>(data);
573 int total = 0;
574 do
575 {
576 int nRecvd;
577 vtkRestartInterruptedSystemCallMacro(
578 recv(this->SocketDescriptor, buffer + total, length - total, 0), nRecvd);
579
580 if (nRecvd == 0)
581 {
582 // peer shut down
583 return 0;
584 }
585
586 #if defined(_WIN32) && !defined(__CYGWIN__)
587 if ((nRecvd == vtkSocketErrorReturnMacro) && (WSAGetLastError() == WSAENOBUFS))
588 {
589 // On long messages, Windows recv sometimes fails with WSAENOBUFS, but
590 // will work if you try again.
591 if ((tries++ < 1000))
592 {
593 Sleep(1);
594 continue;
595 }
596 vtkSocketErrorMacro(vtkErrnoMacro, "Socket error in call to recv.");
597 return 0;
598 }
599 #endif
600
601 total += nRecvd;
602 } while (readFully && (total < length));
603
604 return total;
605 #else
606 static_cast<void>(data);
607 static_cast<void>(length);
608 static_cast<void>(readFully);
609 return 0;
610 #endif
611 }
612
613 //------------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)614 void vtkSocket::PrintSelf(ostream& os, vtkIndent indent)
615 {
616 this->Superclass::PrintSelf(os, indent);
617 os << indent << "SocketDescriptor: " << this->SocketDescriptor << endl;
618 }
619