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