xssocket.c
Go to the documentation of this file.
1 
2 // Copyright (c) 2003-2021 Xsens Technologies B.V. or subsidiaries worldwide.
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification,
6 // are permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice,
9 // this list of conditions, and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice,
12 // this list of conditions, and the following disclaimer in the documentation
13 // and/or other materials provided with the distribution.
14 //
15 // 3. Neither the names of the copyright holders nor the names of their contributors
16 // may be used to endorse or promote products derived from this software without
17 // specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22 // THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
24 // OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR
26 // TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.THE LAWS OF THE NETHERLANDS
28 // SHALL BE EXCLUSIVELY APPLICABLE AND ANY DISPUTES SHALL BE FINALLY SETTLED UNDER THE RULES
29 // OF ARBITRATION OF THE INTERNATIONAL CHAMBER OF COMMERCE IN THE HAGUE BY ONE OR MORE
30 // ARBITRATORS APPOINTED IN ACCORDANCE WITH SAID RULES.
31 //
32 
33 
34 // Copyright (c) 2003-2021 Xsens Technologies B.V. or subsidiaries worldwide.
35 // All rights reserved.
36 //
37 // Redistribution and use in source and binary forms, with or without modification,
38 // are permitted provided that the following conditions are met:
39 //
40 // 1. Redistributions of source code must retain the above copyright notice,
41 // this list of conditions, and the following disclaimer.
42 //
43 // 2. Redistributions in binary form must reproduce the above copyright notice,
44 // this list of conditions, and the following disclaimer in the documentation
45 // and/or other materials provided with the distribution.
46 //
47 // 3. Neither the names of the copyright holders nor the names of their contributors
48 // may be used to endorse or promote products derived from this software without
49 // specific prior written permission.
50 //
51 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
52 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
53 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
54 // THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 // SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
56 // OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR
58 // TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
59 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.THE LAWS OF THE NETHERLANDS
60 // SHALL BE EXCLUSIVELY APPLICABLE AND ANY DISPUTES SHALL BE FINALLY SETTLED UNDER THE RULES
61 // OF ARBITRATION OF THE INTERNATIONAL CHAMBER OF COMMERCE IN THE HAGUE BY ONE OR MORE
62 // ARBITRATORS APPOINTED IN ACCORDANCE WITH SAID RULES.
63 //
64 
65 #ifdef _WIN32
66 #include <winsock2.h>
67 #include <winerror.h>
68 #include <ws2tcpip.h>
69 #include <stdio.h>
70 #include <iphlpapi.h>
71 
72 #pragma comment(lib, "ws2_32.lib")
73 #else
74 #include <unistd.h>
75 #include <stdio.h>
76 #include <stdlib.h>
77 #include <ctype.h>
78 #include <sys/types.h>
79 #include <sys/socket.h>
80 #include <sys/time.h>
81 #include <netdb.h>
82 #include <arpa/inet.h>
83 #define SOCKET int32_t
84 #define SOCKET_ERROR -1
85 #define INVALID_SOCKET ((int32_t)-1)
86 
87 /* capture the fact that windows has a specific closesocket function */
88 static int closesocket(SOCKET s)
89 {
90  close(s);
91  return 0;
92 }
93 #endif
94 #if defined(__FreeBSD__) || defined(BSD) || defined(__APPLE__) || defined(__linux__)
95  #define USE_GETIFADDRS 1
96  #include <ifaddrs.h>
97 #endif
98 #include <errno.h>
99 
100 // MSG_NOSIGNAL is linux stuff
101 #ifndef MSG_NOSIGNAL
102  #define MSG_NOSIGNAL 0
103 #endif
104 
105 #include "xssocket.h"
106 
107 #ifndef PEEKBUFSIZE
108  #define PEEKBUFSIZE 32768
109 #endif
110 
111 /* the socket data */
113 {
115 
118 
119  struct sockaddr_storage m_remoteAddr;
120  socklen_t m_remoteAddrLen;
121 
124 
127 
128 #ifdef _WIN32
129  WSADATA m_sockData;
130 #endif
131 };
132 
133 /* Return non-zero if the native socket s is usable */
134 static int socketIsUsable(SOCKET s)
135 {
136  return (s != INVALID_SOCKET && s > 0);
137 }
138 
139 
145 static void getRemoteHostAddress(const struct sockaddr_storage* remote, XsString* address)
146 {
147  void* src;
148  socklen_t length;
149 
150  switch (remote->ss_family)
151  {
152  case AF_INET:
153  default:
154  src = &(((struct sockaddr_in*)remote)->sin_addr);
155  length = INET_ADDRSTRLEN;
156  break;
157  case AF_INET6:
158  src = &(((struct sockaddr_in6*)remote)->sin6_addr);
159  length = INET6_ADDRSTRLEN;
160  break;
161  }
162  XsString_resize(address, (XsSize)(ptrdiff_t) length);
163  if (inet_ntop(remote->ss_family, src, address->m_data, (size_t)(ptrdiff_t) length) == NULL)
164  XsString_erase(address, 0, address->m_size);
165 }
166 
167 /* Update the last result of thisPtr to retval, if thisPtr is non-null
168 
169  Returns retval for easy use in return statements.
170 */
171 static XsResultValue setLastResult(XsSocket* thisPtr, XsResultValue retval, int systemError)
172 {
173  if (thisPtr && thisPtr->d)
174  {
175  thisPtr->d->m_lastResult = retval;
176  thisPtr->d->m_lastSystemError = systemError;
177  }
178  return retval;
179 }
180 
181 /* Translate a platform error into an XsResultValue
182 
183  If thisPtr is non-null, the socket's last result will be updated.
184 */
185 static XsResultValue translateAndReturnSocketError(XsSocket* thisPtr, int functionResult)
186 {
187  XsResultValue result;
188  int err;
189  if (functionResult == 0)
190  return setLastResult(thisPtr, XRV_OK, 0);
191 #ifdef _WIN32
192  err = WSAGetLastError();
193  switch (err)
194  {
195  case WSA_INVALID_HANDLE:
196  case WSA_INVALID_PARAMETER:
197  case WSAEINVAL:
198  result = XRV_INVALIDPARAM;
199  break;
200  case WSA_NOT_ENOUGH_MEMORY:
201  result = XRV_OUTOFMEMORY;
202  break;
203  case WSA_OPERATION_ABORTED:
204  result = XRV_ABORTED;
205  break;
206  case WSAEMSGSIZE:
207  result = XRV_BUFFEROVERFLOW;
208  break;
209  case WSAETIMEDOUT:
210  result = XRV_TIMEOUTNODATA;
211  break;
212  case WSAEACCES:
213  case WSAEADDRINUSE:
214  result = XRV_IN_USE;
215  break;
216  case WSA_IO_INCOMPLETE:
217  case WSA_IO_PENDING:
218  case WSAEINTR:
219  case WSAEBADF:
220  case WSAEFAULT:
221  case WSAEMFILE:
222  case WSAEWOULDBLOCK:
223  case WSAEINPROGRESS:
224  case WSAEALREADY:
225  case WSAENOTSOCK:
226  case WSAEDESTADDRREQ:
227  case WSAEPROTOTYPE:
228  case WSAENOPROTOOPT:
229  case WSAEPROTONOSUPPORT:
230  case WSAESOCKTNOSUPPORT:
231  case WSAEOPNOTSUPP:
232  case WSAEPFNOSUPPORT:
233  case WSAEAFNOSUPPORT:
234  case WSAEADDRNOTAVAIL:
235  case WSAENETDOWN:
236  case WSAENETUNREACH:
237  case WSAENETRESET:
238  case WSAECONNABORTED:
239  case WSAECONNRESET:
240  case WSAENOBUFS:
241  case WSAEISCONN:
242  case WSAENOTCONN:
243  case WSAESHUTDOWN:
244  case WSAETOOMANYREFS:
245  case WSAECONNREFUSED:
246  case WSAELOOP:
247  case WSAENAMETOOLONG:
248  case WSAEHOSTDOWN:
249  case WSAEHOSTUNREACH:
250  case WSAENOTEMPTY:
251  case WSAEPROCLIM:
252  case WSAEUSERS:
253  case WSAEDQUOT:
254  case WSAESTALE:
255  case WSAEREMOTE:
256  case WSASYSNOTREADY:
257  case WSAVERNOTSUPPORTED:
258  case WSANOTINITIALISED:
259  case WSAEDISCON:
260  case WSAENOMORE:
261  case WSAECANCELLED:
262  case WSAEINVALIDPROCTABLE:
263  case WSAEINVALIDPROVIDER:
264  case WSAEPROVIDERFAILEDINIT:
265  case WSASYSCALLFAILURE:
266  case WSASERVICE_NOT_FOUND:
267  case WSATYPE_NOT_FOUND:
268  case WSA_E_NO_MORE:
269  case WSA_E_CANCELLED:
270  case WSAEREFUSED:
271  case WSAHOST_NOT_FOUND:
272  case WSATRY_AGAIN:
273  case WSANO_RECOVERY:
274  case WSANO_DATA:
275  default:
276  result = XRV_OTHER;
277  break;
278  }
279 #else
280  err = errno;
281  switch (err)
282  {
283  case EROFS:
284  result = XRV_READONLY;
285  break;
286  case EACCES:
287  result = XRV_INPUTCANNOTBEOPENED;
288  break;
289  case EADDRINUSE:
290  result = XRV_ALREADYOPEN;
291  break;
292  case EBADF:
293  case EINVAL:
294  case ENOTDIR:
295  case EFAULT:
296  result = XRV_INVALIDPARAM;
297  break;
298  case ENAMETOOLONG:
299  result = XRV_DATAOVERFLOW;
300  break;
301  case ENOTSOCK:
302  result = XRV_UNSUPPORTED;
303  break;
304  case EADDRNOTAVAIL:
305  case ENOENT:
306  result = XRV_NOTFOUND;
307  break;
308  case ELOOP:
309  case ENOMEM:
310  result = XRV_OUTOFMEMORY;
311  break;
312  case ETIME:
313  case ETIMEDOUT:
314  result = XRV_TIMEOUTNODATA;
315  break;
316  default:
317  result = XRV_OTHER;
318  break;
319  }
320 #endif
321  return setLastResult(thisPtr, result, err);
322 }
323 
324 static void translateSocketError(XsSocket* thisPtr, int functionResult)
325 {
326  (void)translateAndReturnSocketError(thisPtr, functionResult);
327 }
328 
329 /* Initialize the socket
330 
331  This function performs some basic initialization on the socket
332 */
333 static void XsSocket_initialize(XsSocket* thisPtr, XsDataFlags flags)
334 {
335  thisPtr->d = (struct XsSocketPrivate*)malloc(sizeof(struct XsSocketPrivate));
336  memset(thisPtr->d, 0, sizeof(*thisPtr->d));
337  thisPtr->d->m_sd = INVALID_SOCKET;
338  thisPtr->d->m_flags = flags;
339 #ifdef _WIN32
340  (void)WSAStartup(MAKEWORD(2, 0), &thisPtr->d->m_sockData);
341 #endif
342 }
343 
350 void XsSocket_create(XsSocket* thisPtr, enum NetworkLayerProtocol ip, enum IpProtocol protocol)
351 {
353 
354  thisPtr->d->m_sd = socket(
355  (ip == NLP_IPV4) ? PF_INET : PF_INET6,
356  (protocol == IP_UDP) ? SOCK_DGRAM : SOCK_STREAM,
357  (protocol == IP_UDP) ? IPPROTO_UDP : IPPROTO_TCP);
358 
359  thisPtr->d->m_ipVersion = ip;
360  thisPtr->d->m_ipProtocol = protocol;
361 }
362 
363 /* Create a socket from a native socket
364 
365  Usually we expect that theirinfo and infolen are filled in. If theirInfo is NULL though,
366  we will fetch the information from the socket. Doing so by default would add a possible
367  extra point of failure.
368 */
369 void XsSocket_createFromNativeSocket(XsSocket* thisPtr, SOCKET nativeSocket, struct sockaddr const* theirInfo, socklen_t infolen, XsDataFlags flags)
370 {
371  XsSocket_initialize(thisPtr, flags);
372  thisPtr->d->m_sd = nativeSocket;
373 
374  if (theirInfo)
375  {
376  memcpy(&thisPtr->d->m_remoteAddr, theirInfo, (size_t)(ptrdiff_t) infolen);
377  thisPtr->d->m_remoteAddrLen = infolen;
378  }
379  else
380  {
381  int rv;
382  thisPtr->d->m_remoteAddrLen = sizeof(thisPtr->d->m_remoteAddr);
383  rv = getpeername(thisPtr->d->m_sd, (struct sockaddr*)&thisPtr->d->m_remoteAddr, &thisPtr->d->m_remoteAddrLen);
384  translateSocketError(thisPtr, rv);
385  }
386 
387  switch (thisPtr->d->m_remoteAddr.ss_family)
388  {
389  case PF_INET6:
390  thisPtr->d->m_ipVersion = NLP_IPV6;
391  break;
392  case PF_INET:
393  thisPtr->d->m_ipVersion = NLP_IPV4;
394  break;
395  default:
396  // IRDA and the likes. do we need it?
397  break;
398  }
399 }
400 
410 void XsSocket_createFromFileDescriptor(XsSocket* thisPtr, int sockfd, XsDataFlags flags)
411 {
412  XsSocket_createFromNativeSocket(thisPtr, sockfd, NULL, 0, flags);
413 }
414 
423 {
424  return thisPtr->d->m_sd;
425 }
426 
434 {
435  if (thisPtr->d->m_sd == INVALID_SOCKET)
436  return XRV_OK;
437 
438  if (closesocket(thisPtr->d->m_sd) == SOCKET_ERROR)
439  return XRV_ERROR;
440 
441  thisPtr->d->m_sd = INVALID_SOCKET;
442  return XRV_OK;
443 }
444 
458 {
459  if (thisPtr->d)
460  {
461  if ((thisPtr->d->m_flags & XSDF_Managed) != 0)
462  (void)XsSocket_close(thisPtr);
463  free(thisPtr->d);
464  thisPtr->d = NULL;
465 #ifdef _WIN32
466  // decrease ref counter and possibly clean up socket dll
467  // http://msdn.microsoft.com/en-us/library/windows/desktop/ms741549%28v=vs.85%29.aspx
468  (void)WSACleanup();
469 #endif
470  }
471 }
472 
485 int XsSocket_select(XsSocket* thisPtr, int mstimeout, int* canRead, int* canWrite)
486 {
487  fd_set readfd;
488  fd_set writefd;
489  fd_set errorfd;
490  struct timeval timeout;
491  int rv;
492  FD_ZERO(&readfd);
493  FD_ZERO(&writefd);
494  FD_ZERO(&errorfd);
495  FD_SET(thisPtr->d->m_sd, &readfd);
496  FD_SET(thisPtr->d->m_sd, &writefd);
497  FD_SET(thisPtr->d->m_sd, &errorfd);
498 
499  if (canRead)
500  *canRead = 0;
501  if (canWrite)
502  *canWrite = 0;
503 
504  timeout.tv_sec = mstimeout / 1000;
505  timeout.tv_usec = (mstimeout % 1000) * 1000;
506 
507  rv = select(FD_SETSIZE, (canRead ? &readfd : NULL),
508  (canWrite ? &writefd : NULL),
509  &errorfd, mstimeout >= 0 ? &timeout : NULL);
510 
511  switch (rv)
512  {
513  case -1:
514  translateSocketError(thisPtr, rv);
515  break;
516  case 0:
517  (void)setLastResult(thisPtr, XRV_TIMEOUT, 0);
518  break;
519  default:
520  if (FD_ISSET(thisPtr->d->m_sd, &errorfd))
521  {
522  (void)setLastResult(thisPtr, XRV_ERROR, 0);
523  rv = -1;
524  break;
525  }
526 
527  if (canRead)
528  *canRead = FD_ISSET(thisPtr->d->m_sd, &readfd);
529  if (canWrite)
530  *canWrite = FD_ISSET(thisPtr->d->m_sd, &writefd);
531  break;
532  }
533  return rv;
534 }
535 
545 int XsSocket_read(XsSocket* thisPtr, void* dest, XsSize size, int timeout)
546 {
547  return XsSocket_readFrom(thisPtr, dest, size, NULL, NULL, timeout);
548 }
549 
550 /* peek at the size of the incoming data */
551 static int peekPendingDataSize(XsSocket* thisPtr)
552 {
553  int rv = recvfrom(thisPtr->d->m_sd, thisPtr->d->m_peekBuf, PEEKBUFSIZE, MSG_PEEK, NULL, NULL);
554  if (rv < 0)
555  {
556  translateSocketError(thisPtr, rv);
557  if (thisPtr->d->m_lastResult == XRV_BUFFEROVERFLOW)
558  return PEEKBUFSIZE;
559  }
560  return rv;
561 }
562 
574 int XsSocket_readFrom(XsSocket* thisPtr, void* dest, XsSize size, XsString* hostname, uint16_t* port, int timeout)
575 {
576  int rv;
577  int canRead;
578  struct sockaddr_storage sender;
579  socklen_t l = sizeof(sender);
580 
581  rv = XsSocket_select(thisPtr, timeout, &canRead, NULL);
582  (void) canRead;
583  if (rv <= 0)
584  return rv;
585 
586  if (!dest)
587  return peekPendingDataSize(thisPtr);
588 
589  rv = recvfrom(thisPtr->d->m_sd, dest, (int)size, 0, (struct sockaddr*)&sender, &l);
590 
591  if (hostname)
592  getRemoteHostAddress(&sender, hostname);
593 
594  if (port)
595  *port = ntohs(((struct sockaddr_in*)&sender)->sin_port);
596 
597  translateSocketError(thisPtr, rv);
598  return rv;
599 }
600 
609 int XsSocket_read2ByteArray(XsSocket* thisPtr, XsByteArray* dest, int timeout)
610 {
611  return XsSocket_readFrom2ByteArray(thisPtr, dest, NULL, NULL, timeout);
612 }
613 
624 int XsSocket_readFrom2ByteArray(XsSocket* thisPtr, XsByteArray* dest, XsString* hostname, uint16_t* port, int timeout)
625 {
626  int rv;
627  int canRead;
628  struct sockaddr_storage sender;
629  socklen_t l = sizeof(sender);
630 
631  rv = XsSocket_select(thisPtr, timeout, &canRead, NULL);
632  (void) canRead;
633  if (rv <= 0)
634  return rv;
635 
636  if (!dest)
637  return peekPendingDataSize(thisPtr);
638 
639  rv = recvfrom(thisPtr->d->m_sd, thisPtr->d->m_peekBuf, PEEKBUFSIZE, 0, (struct sockaddr*)&sender, &l);
640  if (rv <= 0)
641  {
642  translateSocketError(thisPtr, rv);
643  return -1;
644  }
645  XsByteArray_assign(dest, (XsSize)(ptrdiff_t) rv, thisPtr->d->m_peekBuf);
646 
647  if (hostname)
648  getRemoteHostAddress(&sender, hostname);
649 
650  if (port)
651  *port = ntohs(((struct sockaddr_in*)&sender)->sin_port);
652 
653  translateSocketError(thisPtr, 0);
654  return rv;
655 }
656 
665 int XsSocket_write(XsSocket* thisPtr, const void* data, XsSize size)
666 {
667  int canWrite;
668  int rv = XsSocket_select(thisPtr, 0, NULL, &canWrite);
669  (void) canWrite;
670  if (rv <= 0)
671  return rv;
672 
673  return send(thisPtr->d->m_sd, data, (int)(ptrdiff_t)size, MSG_NOSIGNAL);
674 }
675 
676 /* Return non-zero if the hostname is actually an IPv4 address */
677 int isIPv4Address(XsString const* hostname)
678 {
679  char* c;
680  int expectNum = 1;
681  int expectDot = 0;
682  int numbersFound = 0;
683 
684  if (!hostname || !hostname->m_data)
685  return 0;
686 
687  for (c = hostname->m_data; *c != '\0'; c++)
688  {
689  if (*c == '.')
690  {
691  if (!expectDot)
692  return 0;
693  expectNum = 1;
694  numbersFound = 0;
695  expectDot = 0;
696  }
697  else if (isdigit(*c))
698  {
699  if (!expectNum)
700  return 0;
701  expectDot = 1;
702  ++numbersFound;
703  if (numbersFound == 3)
704  expectNum = 0;
705  }
706  else
707  return 0;
708  }
709  return 1;
710 }
711 
712 /* Prefix the hostname with ::ffff: if we're on ipv6 and hostname looks like a ipv4 address */
713 void XsSocket_fixupHostname(XsSocket const* thisPtr, XsString* hostname)
714 {
715  if (!hostname || !hostname->m_data)
716  return;
717 
718  if (thisPtr->d->m_ipVersion == NLP_IPV4)
719  return;
720 
721  if (isIPv4Address(hostname))
722  {
723  const char prefix[] = "::ffff:";
724  XsArray_insert(hostname, 0, (XsSize)strlen(prefix), prefix);
725  }
726 }
727 
728 typedef int (*lookupTestFunction)(XsSocket* thisPtr, SOCKET currentSocket, struct addrinfo const* info);
729 
730 /* Do a lookup of the given hostname and port
731 
732  This is an internal function that centralizes the lookup code.
733 
734  thisPtr - the socket to use information from
735  hostname - the hostname to look up
736  port - the port to check the connection on
737  hints_flags - the flags we should put into the lookup hints, e.g. AI_PASSIVE
738  tester - a function that performs some sanity checks on the passed info
739  info - a pointer to a sockaddr buffer. Should be at least as big as sockaddr, preferably be sockaddr_storage
740  addrlen - the size of info. This function will change addrlen based on the actual size of info if necessary
741 
742  return OK or NOTFOUND
743 */
744 static XsResultValue XsSocket_internalLookup(XsSocket* thisPtr, const XsString* hostname, uint16_t port,
745  int hints_flags, lookupTestFunction tester,
746  struct sockaddr* info, socklen_t* addrlen)
747 {
748  struct addrinfo* lookupInfo, *p;
749  SOCKET s;
750  char gaport[7];
751  struct addrinfo hints;
752  int ret;
753  memset(&hints, 0, sizeof(hints));
754 
755  switch (thisPtr->d->m_ipVersion)
756  {
757  case NLP_IPV6:
758  hints.ai_family = AF_INET6;
759  break;
760  case NLP_IPV4:
761  hints.ai_family = AF_INET;
762  break;
763  case NLP_IPVX:
764  hints.ai_family = AF_UNSPEC;
765  break;
766  }
767  hints.ai_socktype = (thisPtr->d->m_ipProtocol == IP_UDP) ? SOCK_DGRAM : SOCK_STREAM;
768  hints.ai_flags = hints_flags;
769 
770  sprintf(gaport, "%u", (unsigned int) port);
771  if (hostname)
772  {
773  XsString host;
774 
775  XsString_construct(&host);
776  XsArray_copy(&host, hostname);
777 
778  XsSocket_fixupHostname(thisPtr, &host);
779 
780  ret = getaddrinfo(host.m_data, gaport, &hints, &lookupInfo);
781 
782  XsString_destruct(&host);
783  }
784  else
785  ret = getaddrinfo(NULL, gaport, &hints, &lookupInfo);
786 
787  if (ret)
788  {
789  switch (ret)
790  {
791  case EAI_BADFLAGS:
792  return setLastResult(thisPtr, XRV_INVALIDPARAM, -1);
793  case EAI_AGAIN:
794  return translateAndReturnSocketError(thisPtr, EAGAIN);
795  case EAI_FAIL:
796  return setLastResult(thisPtr, XRV_ERROR, -1);
797  case EAI_MEMORY:
798  return setLastResult(thisPtr, XRV_INSUFFICIENTSPACE, -1);
799  //case EAI_NODATA:
800  // return setLastResult(thisPtr, XRV_TIMEOUTNODATA, -1);
801  case EAI_NONAME:
802  return setLastResult(thisPtr, XRV_INSUFFICIENTDATA, -1);
803  //case EAI_ADDRFAMILY:
804  case EAI_SERVICE:
805  case EAI_FAMILY:
806  case EAI_SOCKTYPE:
807  return setLastResult(thisPtr, XRV_UNSUPPORTED, -1);
808  default:
809  return translateAndReturnSocketError(thisPtr, ret);
810  }
811  }
812 
813  setLastResult(thisPtr, XRV_NOTFOUND, -1);
814  for (p = lookupInfo; p != NULL; p = p->ai_next)
815  {
816  s = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
817  if (!socketIsUsable(s))
818  continue;
819 
820  ret = tester(thisPtr, s, p);
821  if (ret == 0)
822  {
823  (void)closesocket(s);
824  if (info && addrlen)
825  {
826  if ((socklen_t)p->ai_addrlen < *addrlen)
827  *addrlen = (socklen_t)p->ai_addrlen;
828  memcpy(info, p->ai_addr, (size_t)(ptrdiff_t) *addrlen);
829  }
830  break;
831  }
832  (void)closesocket(s);
833  }
834  freeaddrinfo(lookupInfo);
835  return setLastResult(thisPtr, (ret == 0) ? XRV_OK : thisPtr->d->m_lastResult, ret);
836 }
837 
838 /* try and see if we can connect on currentSocket to the remote host */
839 static int defaultLookupTest(XsSocket* thisPtr, SOCKET currentSocket, struct addrinfo const* info)
840 {
841  (void)thisPtr;
842  return connect(currentSocket, info->ai_addr, (int) info->ai_addrlen);
843 }
844 
846 static XsResultValue XsSocket_lookup(XsSocket* thisPtr, const XsString* hostname, uint16_t port, struct sockaddr* info, socklen_t* addrlen)
847 {
848  return XsSocket_internalLookup(thisPtr, hostname, port, 0, defaultLookupTest, info, addrlen);
849 }
850 
861 int XsSocket_writeTo(XsSocket* thisPtr, const void* data, XsSize size, const XsString* hostname, uint16_t port)
862 {
863  struct sockaddr_storage storage;
864  struct sockaddr* addr = NULL;
865  socklen_t addrlen = 0;
866  int sent;
867  int canWrite;
868  int rv;
869 
870  rv = XsSocket_select(thisPtr, 0, NULL, &canWrite);
871  (void) canWrite;
872  if (rv <= 0)
873  return rv;
874 
875  if (thisPtr->d->m_ipProtocol == IP_UDP)
876  {
877  addr = (struct sockaddr*)&storage;
878  addrlen = sizeof(storage);
879 
880  if (XsSocket_lookup(thisPtr, hostname, port, addr, &addrlen) != XRV_OK)
881  return -1;
882  }
883 
884  sent = sendto(thisPtr->d->m_sd, data, (int)size, MSG_NOSIGNAL, addr, addrlen);
885  translateSocketError(thisPtr, sent);
886  return sent;
887 }
888 
895 int XsSocket_enableBroadcasts(XsSocket* thisPtr, int enable)
896 {
897  int broadcast = enable ? 1 : 0;
898  int res = setsockopt(thisPtr->d->m_sd, SOL_SOCKET, SO_BROADCAST, (char*)&broadcast, sizeof(broadcast));
899  if (res != 0)
900  {
901  thisPtr->d->m_lastResult = translateAndReturnSocketError(thisPtr, res);
902  return 0;
903  }
904  thisPtr->d->m_lastResult = XRV_OK;
905  return 1;
906 }
907 
908 #ifdef USE_GETIFADDRS
909 static uint32_t SockAddrToUint32(struct sockaddr* a)
910 {
911  return ((a) && (a->sa_family == AF_INET)) ? ntohl(((struct sockaddr_in*)a)->sin_addr.s_addr) : 0;
912 }
913 #endif
914 
924 int XsSocket_broadcast(XsSocket* thisPtr, const void* data, XsSize size, uint16_t port)
925 {
926  struct sockaddr_in addr;
927  int sent = 0;
928  int failed = 0;
929  int ok = 0;
930  int canWrite;
931  int rv;
932 
933  rv = XsSocket_select(thisPtr, 0, NULL, &canWrite);
934  (void) canWrite;
935  if (rv <= 0)
936  return rv;
937 
938  if (thisPtr->d->m_ipProtocol == IP_UDP)
939  {
940  addr.sin_family = AF_INET;
941  addr.sin_port = htons(port);
942  addr.sin_addr.s_addr = INADDR_BROADCAST; // this is equiv to 255.255.255.255 and won't work!
943 
944 #ifdef _WIN32
945  do
946  {
947  // Windows XP style implementation
948  MIB_IPADDRTABLE* ipTable = NULL;
949  {
950  ULONG bufLen = 0;
951  for (int i = 0; i < 5; i++)
952  {
953  DWORD ipRet = GetIpAddrTable(ipTable, &bufLen, FALSE);
954  if (ipRet == ERROR_INSUFFICIENT_BUFFER)
955  {
956  free(ipTable); // in case we had previously allocated it
957  ipTable = (MIB_IPADDRTABLE*) malloc(bufLen);
958  }
959  else if (ipRet == NO_ERROR)
960  break;
961  else
962  {
963  free(ipTable);
964  ipTable = NULL;
965  break;
966  }
967  }
968  }
969 
970  if (ipTable)
971  {
972  IP_ADAPTER_INFO* pAdapterInfo = NULL;
973  {
974  ULONG bufLen = 0;
975  for (int i = 0; i < 5; i++)
976  {
977  DWORD apRet = GetAdaptersInfo(pAdapterInfo, &bufLen);
978  if (apRet == ERROR_BUFFER_OVERFLOW)
979  {
980  free(pAdapterInfo); // in case we had previously allocated it
981  pAdapterInfo = (IP_ADAPTER_INFO*) malloc(bufLen);
982  }
983  else if (apRet == ERROR_SUCCESS)
984  break;
985  else
986  {
987  free(pAdapterInfo);
988  pAdapterInfo = NULL;
989  break;
990  }
991  }
992  }
993 
994  for (DWORD i = 0; i < ipTable->dwNumEntries; i++)
995  {
996  const MIB_IPADDRROW* row = &ipTable->table[i];
997  uint32_t ad = ntohl(row->dwAddr) | ~ntohl(row->dwMask);
998  char bcastAddr[32];
999  sprintf(bcastAddr, "%u.%u.%u.%u", (ad >> 24) & 0xFF, (ad >> 16) & 0xFF, (ad >> 8) & 0xFF, ad & 0xFF);
1000  inet_pton(AF_INET, bcastAddr, &addr.sin_addr);
1001  sent = sendto(thisPtr->d->m_sd, data, (int)size, MSG_NOSIGNAL, (struct sockaddr const*) &addr, sizeof(addr));
1002  if (sent < 0)
1003  {
1004  ++failed;
1005  translateSocketError(thisPtr, sent);
1006  }
1007  else if (sent > 0)
1008  ++ok;
1009  }
1010 
1011  free(pAdapterInfo);
1012  free(ipTable);
1013  }
1014  } while (0);
1015 #elif defined(USE_GETIFADDRS)
1016  // BSD-style implementation
1017  struct ifaddrs* ifap;
1018  if (getifaddrs(&ifap) == 0)
1019  {
1020  struct ifaddrs* p = ifap;
1021  while (p)
1022  {
1023  uint32_t bcastAddr = (uint32_t)SockAddrToUint32(p->ifa_dstaddr);
1024  if (bcastAddr > 0)
1025  {
1026  char bcastAddrStr[32];
1027  sprintf(bcastAddrStr, "%u.%u.%u.%u", (bcastAddr >> 24) & 0xFF, (bcastAddr >> 16) & 0xFF, (bcastAddr >> 8) & 0xFF, bcastAddr & 0xFF);
1028  inet_pton(AF_INET, bcastAddrStr, &addr.sin_addr);
1029  sent = (int)sendto(thisPtr->d->m_sd, data, size, MSG_NOSIGNAL, (struct sockaddr const*) &addr, sizeof(addr));
1030  if (sent < 0)
1031  {
1032  ++failed;
1033  translateSocketError(thisPtr, sent);
1034  }
1035  else if (sent > 0)
1036  ++ok;
1037  }
1038  p = p->ifa_next;
1039  }
1040  freeifaddrs(ifap);
1041  }
1042 #else
1043  // just use direct local broadcast, this may or may not work depending on the system configuration
1044  sent = sendto(thisPtr->d->m_sd, data, (int)size, MSG_NOSIGNAL, (struct sockaddr const*) &addr, sizeof(addr));
1045  if (sent < 0)
1046  ++failed;
1047  else
1048  ++ok;
1049 #endif
1050  }
1051  if (failed >= ok)
1052  return -1;
1053  translateSocketError(thisPtr, sent);
1054  return sent;
1055 }
1056 
1063 void XsSocket_flush(XsSocket* thisPtr)
1064 {
1065  char buf[512];
1066 
1067  while (XsSocket_read(thisPtr, buf, sizeof(buf), 0) > 0)
1068  {
1069  /* nop */
1070  }
1071 }
1072 
1084 XsSocket* XsSocket_accept(XsSocket* thisPtr, int mstimeout)
1085 {
1086  XsSocket* ns;
1087  struct sockaddr_storage theirInfo;
1088  socklen_t infoLength = sizeof(struct sockaddr_storage);
1089  SOCKET sd;
1090 
1091  if (mstimeout >= 0)
1092  {
1093  int read;
1094  int rv = XsSocket_select(thisPtr, mstimeout, &read, NULL);
1095  (void) read;
1096  if (rv == 0)
1097  {
1098  (void)setLastResult(thisPtr, XRV_TIMEOUTNODATA, 0);
1099  return NULL;
1100  }
1101  else if (rv == -1)
1102  {
1103  translateSocketError(thisPtr, rv);
1104  return NULL;
1105  }
1106  }
1107 
1108  sd = accept(thisPtr->d->m_sd, (struct sockaddr*)&theirInfo, &infoLength);
1109  if (!socketIsUsable(sd))
1110  return NULL;
1111 
1112  ns = XsSocket_allocate();
1113  XsSocket_createFromNativeSocket(ns, sd, (struct sockaddr*)&theirInfo, infoLength, XSDF_Managed);
1114  return ns;
1115 }
1116 
1127 {
1128  return (XsSocket*)malloc(sizeof(XsSocket));
1129 }
1130 
1140 void XsSocket_free(XsSocket* thisPtr)
1141 {
1142  XsSocket_destroy(thisPtr);
1143  free(thisPtr);
1144 }
1145 
1153 XsResultValue XsSocket_setSocketOption(XsSocket* thisPtr, enum XsSocketOption option, void* valuePtr, int valueSize)
1154 {
1155  int res;
1156  int nativeOption;
1157 #ifdef _WIN32
1158  const char* valPtr = (const char*)valuePtr;
1159 #else
1160  const void* valPtr = valuePtr;
1161 #endif
1162 
1163  switch (option)
1164  {
1165  case XSO_ReuseAddress:
1166  nativeOption = SO_REUSEADDR;
1167  break;
1168 
1169 #if !defined(_WIN32) && !defined(__ANDROID__)
1170  case XSO_ReusePort:
1171  nativeOption = SO_REUSEPORT;
1172  break;
1173 #endif
1174 
1175  default:
1176  return XRV_OK;
1177  }
1178 
1179  res = setsockopt(thisPtr->d->m_sd, SOL_SOCKET, nativeOption, valPtr, valueSize);
1180  return translateAndReturnSocketError(thisPtr, res);
1181 }
1182 
1183 
1184 /* test if we can bind to info
1185 
1186  keeps the bind alive after leaving the function
1187 */
1188 static int binder(XsSocket* thisPtr, SOCKET currentSocket, struct addrinfo const* info)
1189 {
1190  int res;
1191  int yesval = 1;
1192 #ifdef _WIN32
1193  const char* yes = (const char*)&yesval;
1194 #else
1195  const void* yes = &yesval;
1196 #endif
1197 
1198  (void)currentSocket;
1199 
1200  res = setsockopt(thisPtr->d->m_sd, SOL_SOCKET, SO_REUSEADDR, yes, sizeof(yesval));
1201  if (res)
1202  {
1203  translateSocketError(thisPtr, res);
1204  return res;
1205  }
1206 
1207  res = bind(thisPtr->d->m_sd, info->ai_addr, (int)info->ai_addrlen);
1208  translateSocketError(thisPtr, res);
1209  return res;
1210 }
1211 
1220 XsResultValue XsSocket_bind(XsSocket* thisPtr, const XsString* hostname, uint16_t port)
1221 {
1222  int rv;
1223  struct sockaddr_storage s;
1224  socklen_t addrlen;
1225 
1226  if (hostname)
1227  return XsSocket_internalLookup(thisPtr, hostname, port, AI_PASSIVE, binder, NULL, NULL);
1228 
1229  memset(&s, 0, sizeof(s));
1230 
1231  if (thisPtr->d->m_ipVersion == NLP_IPV4)
1232  {
1233  struct sockaddr_in* sin = (struct sockaddr_in*)&s;
1234  sin->sin_family = AF_INET;
1235  sin->sin_port = htons(port);
1236  sin->sin_addr.s_addr = INADDR_ANY;
1237  addrlen = sizeof(*sin);
1238  }
1239  else
1240  {
1241  struct sockaddr_in6* sin6 = (struct sockaddr_in6*)&s;
1242  sin6->sin6_family = AF_INET6;
1243  sin6->sin6_port = htons(port);
1244  sin6->sin6_addr = in6addr_any;
1245  addrlen = sizeof(*sin6);
1246  }
1247 
1248  rv = bind(thisPtr->d->m_sd, (struct sockaddr*)&s, addrlen);
1249  return translateAndReturnSocketError(thisPtr, rv);
1250 }
1251 
1259 XsResultValue XsSocket_listen(XsSocket* thisPtr, int maxPending)
1260 {
1261  int r = listen(thisPtr->d->m_sd, maxPending);
1262  return translateAndReturnSocketError(thisPtr, r);
1263 }
1264 
1265 /* Connect to info
1266 
1267  Keep the connection alive
1268 */
1269 static int connector(XsSocket* thisPtr, SOCKET currentSocket, struct addrinfo const* info)
1270 {
1271  int ret;
1272  (void)currentSocket;
1273 
1274  ret = connect(thisPtr->d->m_sd, info->ai_addr, (int)info->ai_addrlen);
1275 
1276  if (ret == 0)
1277  {
1278  thisPtr->d->m_ipVersion = (info->ai_family == AF_INET ? NLP_IPV4 : NLP_IPV6);
1279  memcpy(&thisPtr->d->m_remoteAddr, info->ai_addr, info->ai_addrlen);
1280  thisPtr->d->m_remoteAddrLen = (socklen_t)(info->ai_addrlen);
1281  }
1282  else
1283  translateSocketError(thisPtr, ret);
1284 
1285  return ret;
1286 }
1287 
1296 XsResultValue XsSocket_connect(XsSocket* thisPtr, const XsString* host, uint16_t port)
1297 {
1298  return XsSocket_internalLookup(thisPtr, host, port, 0, connector, NULL, NULL);
1299 }
1300 
1306 int XsSocket_isUsable(const XsSocket* thisPtr)
1307 {
1308  return socketIsUsable(thisPtr->d->m_sd);
1309 }
1310 
1315 void XsSocket_getRemoteAddress(const XsSocket* thisPtr, XsString* address)
1316 {
1317  getRemoteHostAddress(&thisPtr->d->m_remoteAddr, address);
1318 }
1319 
1325 {
1326  return thisPtr->d->m_lastSystemError;
1327 }
INVALID_SOCKET
#define INVALID_SOCKET
Definition: xssocket.c:85
XsSocketPrivate::m_remoteAddrLen
socklen_t m_remoteAddrLen
Definition: xssocket.c:120
NLP_IPVX
@ NLP_IPVX
any IP address family
Definition: xssocket.h:89
IpProtocol
IpProtocol
the protocol on top of IP
Definition: xssocket.h:78
XsString_destruct
void XsString_destruct(XsString *thisPtr)
Clears and frees memory allocated by the XsArray.
Definition: xsstring.c:134
XsSocket_readFrom2ByteArray
int XsSocket_readFrom2ByteArray(XsSocket *thisPtr, XsByteArray *dest, XsString *hostname, uint16_t *port, int timeout)
Read size data into dest.
Definition: xssocket.c:624
MSG_NOSIGNAL
#define MSG_NOSIGNAL
Definition: xssocket.c:102
XRV_BUFFEROVERFLOW
@ XRV_BUFFEROVERFLOW
42: The sample buffer of the device was full during a communication outage
Definition: xsresultvalue.h:111
XsSocket_internalLookup
static XsResultValue XsSocket_internalLookup(XsSocket *thisPtr, const XsString *hostname, uint16_t port, int hints_flags, lookupTestFunction tester, struct sockaddr *info, socklen_t *addrlen)
Definition: xssocket.c:744
XsByteArray
A list of uint8_t values.
XSOCKET
int XSOCKET
Definition: xssocket.h:105
XsSocketPrivate::m_peekBuf
char m_peekBuf[PEEKBUFSIZE]
Definition: xssocket.c:126
XsSocket_read2ByteArray
int XsSocket_read2ByteArray(XsSocket *thisPtr, XsByteArray *dest, int timeout)
Read size data into dest.
Definition: xssocket.c:609
XRV_TIMEOUT
@ XRV_TIMEOUT
258: A timeout occurred
Definition: xsresultvalue.h:128
s
XmlRpcServer s
XsSocketPrivate
Definition: xssocket.c:112
XsSocket_broadcast
int XsSocket_broadcast(XsSocket *thisPtr, const void *data, XsSize size, uint16_t port)
Broadcast data over the socket to the port indicated by port.
Definition: xssocket.c:924
XSO_ReuseAddress
@ XSO_ReuseAddress
Allow bind to reuse a local port (using different local addresses)
Definition: xssocket.h:94
XRV_IN_USE
@ XRV_IN_USE
321: The requested device/port/address is already in use. Most likely returned by XsSocket::bind
Definition: xsresultvalue.h:198
socketIsUsable
static int socketIsUsable(SOCKET s)
Definition: xssocket.c:134
closesocket
static int closesocket(SOCKET s)
Definition: xssocket.c:88
XsSocket_fixupHostname
void XsSocket_fixupHostname(XsSocket const *thisPtr, XsString *hostname)
Definition: xssocket.c:713
XsSocket_connect
XsResultValue XsSocket_connect(XsSocket *thisPtr, const XsString *host, uint16_t port)
Connect to hostame on port.
Definition: xssocket.c:1296
peekPendingDataSize
static int peekPendingDataSize(XsSocket *thisPtr)
Definition: xssocket.c:551
XsSocket::d
struct XsSocketPrivate * d
Definition: xssocket.h:503
xssocket.h
XsArray::XsArray_copy
void XsArray_copy(void *thisPtr, void const *src)
Copy the contents of src to thisArray.
Definition: xsarray.c:305
NetworkLayerProtocol
NetworkLayerProtocol
The network layer protocol, or IP address family.
Definition: xssocket.h:85
XsSocket_nativeDescriptor
XSOCKET XsSocket_nativeDescriptor(XsSocket const *thisPtr)
Return the native file descriptor.
Definition: xssocket.c:422
XRV_NOTFOUND
@ XRV_NOTFOUND
262: The requested item was not found
Definition: xsresultvalue.h:132
XsSocket_createFromNativeSocket
void XsSocket_createFromNativeSocket(XsSocket *thisPtr, SOCKET nativeSocket, struct sockaddr const *theirInfo, socklen_t infolen, XsDataFlags flags)
Definition: xssocket.c:369
XRV_ALREADYOPEN
@ XRV_ALREADYOPEN
269: An I/O device is already opened with this object
Definition: xsresultvalue.h:139
XsSocketPrivate::m_remoteAddr
struct sockaddr_storage m_remoteAddr
Definition: xssocket.c:119
XRV_TIMEOUTNODATA
@ XRV_TIMEOUTNODATA
259: Operation aborted because of no data read
Definition: xsresultvalue.h:129
XsSocketOption
XsSocketOption
Definition: xssocket.h:92
XRV_ABORTED
@ XRV_ABORTED
302: The process was aborted by an external event, usually a user action or process termination
Definition: xsresultvalue.h:177
translateSocketError
static void translateSocketError(XsSocket *thisPtr, int functionResult)
Definition: xssocket.c:324
XRV_ERROR
@ XRV_ERROR
256: A generic error occurred
Definition: xsresultvalue.h:126
ok
ROSCPP_DECL bool ok()
data
data
XRV_OK
@ XRV_OK
0: Operation was performed successfully
Definition: xsresultvalue.h:85
XsSocket_create
void XsSocket_create(XsSocket *thisPtr, enum NetworkLayerProtocol ip, enum IpProtocol protocol)
Create socket thisPtr for IP version ip with protocol protocol.
Definition: xssocket.c:350
XsResultValue
XsResultValue
Xsens result values.
Definition: xsresultvalue.h:82
XsSocket_initialize
static void XsSocket_initialize(XsSocket *thisPtr, XsDataFlags flags)
Definition: xssocket.c:333
XsSocket_write
int XsSocket_write(XsSocket *thisPtr, const void *data, XsSize size)
Write data to the socket.
Definition: xssocket.c:665
XRV_OUTOFMEMORY
@ XRV_OUTOFMEMORY
261: No internal memory available
Definition: xsresultvalue.h:131
uint32_t
unsigned int uint32_t
Definition: pstdint.h:485
translateAndReturnSocketError
static XsResultValue translateAndReturnSocketError(XsSocket *thisPtr, int functionResult)
Definition: xssocket.c:185
XsString_construct
void XsString_construct(XsString *thisPtr)
Initializes the XsString object as an empty string.
Definition: xsstring.c:126
PEEKBUFSIZE
#define PEEKBUFSIZE
Definition: xssocket.c:108
XsSocket_bind
XsResultValue XsSocket_bind(XsSocket *thisPtr, const XsString *hostname, uint16_t port)
Bind to the hostname and port combination.
Definition: xssocket.c:1220
isIPv4Address
int isIPv4Address(XsString const *hostname)
Definition: xssocket.c:677
XsSocket
A platform independent socket implementation.
Definition: xssocket.h:160
defaultLookupTest
static int defaultLookupTest(XsSocket *thisPtr, SOCKET currentSocket, struct addrinfo const *info)
Definition: xssocket.c:839
XsSocket_isUsable
int XsSocket_isUsable(const XsSocket *thisPtr)
Return non-zero if the socket is usable for reading and writing data.
Definition: xssocket.c:1306
XsSocket::XsSocket_select
int XsSocket_select(XsSocket *thisPtr, int mstimeout, int *canRead, int *canWrite)
Wait for read or write for mstimeout milliseconds on socket thisPtr.
Definition: xssocket.c:485
binder
static int binder(XsSocket *thisPtr, SOCKET currentSocket, struct addrinfo const *info)
Definition: xssocket.c:1188
lookupTestFunction
int(* lookupTestFunction)(XsSocket *thisPtr, SOCKET currentSocket, struct addrinfo const *info)
Definition: xssocket.c:728
XsSize
size_t XsSize
XsSize must be unsigned number!
Definition: xstypedefs.h:74
XsSocket::XsSocket_close
XsResultValue XsSocket_close(XsSocket *thisPtr)
Close a socket.
Definition: xssocket.c:433
XsSocket_destroy
void XsSocket_destroy(XsSocket *thisPtr)
Destroy the given socket.
Definition: xssocket.c:457
XRV_INPUTCANNOTBEOPENED
@ XRV_INPUTCANNOTBEOPENED
267: The specified i/o device can not be opened
Definition: xsresultvalue.h:137
SOCKET_ERROR
#define SOCKET_ERROR
Definition: xssocket.c:84
XsSocket_readFrom
int XsSocket_readFrom(XsSocket *thisPtr, void *dest, XsSize size, XsString *hostname, uint16_t *port, int timeout)
Read size data into dest.
Definition: xssocket.c:574
XsSocket_allocate
XsSocket * XsSocket_allocate()
Dynamically allocate an XsSocket.
Definition: xssocket.c:1126
XsSocket_read
int XsSocket_read(XsSocket *thisPtr, void *dest, XsSize size, int timeout)
Read size data into dest.
Definition: xssocket.c:545
IP_UDP
@ IP_UDP
The UDP/IP protocol.
Definition: xssocket.h:80
XsArray::XsArray_insert
void XsArray_insert(void *thisPtr, XsSize index, XsSize count, void const *src)
Insert count items from src at index in the array.
Definition: xsarray.c:372
SOCKET
#define SOCKET
Definition: xssocket.c:83
XsString_resize
void XsString_resize(XsString *thisPtr, XsSize count)
This function resizes the contained string to the desired size, while retaining its contents.
Definition: xsstring.c:243
NLP_IPV4
@ NLP_IPV4
IPv4 address family.
Definition: xssocket.h:87
XRV_INSUFFICIENTDATA
@ XRV_INSUFFICIENTDATA
275: Insufficient data was supplied to a function
Definition: xsresultvalue.h:145
XsSocket::XsSocket_createFromFileDescriptor
void XsSocket_createFromFileDescriptor(XsSocket *thisPtr, int sockfd, XsDataFlags flags)
Create a socket from a native file descriptor.
Definition: xssocket.c:410
XRV_OTHER
@ XRV_OTHER
286: Something else was received than was requested
Definition: xsresultvalue.h:156
XsSocket_getLastSystemError
int XsSocket_getLastSystemError(const XsSocket *thisPtr)
Return the system error code of the last socket operation.
Definition: xssocket.c:1324
XRV_DATAOVERFLOW
@ XRV_DATAOVERFLOW
41: The device generates more data than the bus communication can handle (baud rate may be too low)
Definition: xsresultvalue.h:110
XsSocketPrivate::m_lastResult
XsResultValue m_lastResult
Definition: xssocket.c:122
XsByteArray_assign
#define XsByteArray_assign(thisPtr, sz, src)
Definition: xsbytearray.h:86
XsSocket_free
void XsSocket_free(XsSocket *thisPtr)
Free a socket returned from XsSocket_accept() or XsSocket_allocate()
Definition: xssocket.c:1140
connector
static int connector(XsSocket *thisPtr, SOCKET currentSocket, struct addrinfo const *info)
Definition: xssocket.c:1269
XRV_READONLY
@ XRV_READONLY
273: Tried to change a read-only value
Definition: xsresultvalue.h:143
XsSocketPrivate::m_ipProtocol
enum IpProtocol m_ipProtocol
Definition: xssocket.c:117
XsSocketPrivate::m_sd
SOCKET m_sd
Definition: xssocket.c:114
XsSocket_lookup
static XsResultValue XsSocket_lookup(XsSocket *thisPtr, const XsString *hostname, uint16_t port, struct sockaddr *info, socklen_t *addrlen)
Perform a lookup.
Definition: xssocket.c:846
XsSocket_listen
XsResultValue XsSocket_listen(XsSocket *thisPtr, int maxPending)
Start listening for incoming connections on this socket.
Definition: xssocket.c:1259
NLP_IPV6
@ NLP_IPV6
IPv6 address family.
Definition: xssocket.h:88
XsDataFlags
XsDataFlags
These flags define the behaviour of data contained by Xsens data structures.
Definition: xstypedefs.h:107
length
TF2SIMD_FORCE_INLINE tf2Scalar length(const Quaternion &q)
XSDF_Managed
@ XSDF_Managed
The contained data should be managed (freed) by the object, when false, the object assumes the memory...
Definition: xstypedefs.h:110
XRV_UNSUPPORTED
@ XRV_UNSUPPORTED
303: The requested functionality is not supported by the device
Definition: xsresultvalue.h:178
XsSocket_accept
XsSocket * XsSocket_accept(XsSocket *thisPtr, int mstimeout)
Accept an incoming connection.
Definition: xssocket.c:1084
XSO_ReusePort
@ XSO_ReusePort
Allow bind to reuse the exact local address.
Definition: xssocket.h:95
setLastResult
static XsResultValue setLastResult(XsSocket *thisPtr, XsResultValue retval, int systemError)
Definition: xssocket.c:171
XsSocketPrivate::m_lastSystemError
int m_lastSystemError
Definition: xssocket.c:123
XsSocket_getRemoteAddress
void XsSocket_getRemoteAddress(const XsSocket *thisPtr, XsString *address)
Get the numeric IP address of remote host of this socket.
Definition: xssocket.c:1315
getRemoteHostAddress
static void getRemoteHostAddress(const struct sockaddr_storage *remote, XsString *address)
Get the IP address of remote.
Definition: xssocket.c:145
XsSocket::XsSocket_enableBroadcasts
int XsSocket_enableBroadcasts(XsSocket *thisPtr, int enable)
Enable sending and receiving broadcasts on this socket.
Definition: xssocket.c:895
XsString_erase
void XsString_erase(XsString *thisPtr, XsSize index, XsSize count)
Removes a count items from the list starting at index.
Definition: xsstring.c:276
XsString
A 0-terminated managed string of characters.
XsSocketPrivate::m_flags
XsDataFlags m_flags
Definition: xssocket.c:125
XsSocket_flush
void XsSocket_flush(XsSocket *thisPtr)
Flush the incoming data.
Definition: xssocket.c:1063
XsSocket_writeTo
int XsSocket_writeTo(XsSocket *thisPtr, const void *data, XsSize size, const XsString *hostname, uint16_t port)
Write data to the socket to the host indicated by hostname, port.
Definition: xssocket.c:861
XRV_INSUFFICIENTSPACE
@ XRV_INSUFFICIENTSPACE
266: Insufficient buffer space available
Definition: xsresultvalue.h:136
XRV_INVALIDPARAM
@ XRV_INVALIDPARAM
33: An invalid parameter is supplied
Definition: xsresultvalue.h:105
XsSocket::XsSocket_setSocketOption
XsResultValue XsSocket_setSocketOption(XsSocket *thisPtr, enum XsSocketOption option, void *valuePtr, int valueSize)
Changes the value of a socket option.
Definition: xssocket.c:1153
XsSocketPrivate::m_ipVersion
enum NetworkLayerProtocol m_ipVersion
Definition: xssocket.c:116


xsens_mti_driver
Author(s):
autogenerated on Sun Sep 3 2023 02:43:20