PageRenderTime 80ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 1ms

/src/VBox/Runtime/r3/socket.cpp

https://bitbucket.org/diagiman/vbox-trunk
C++ | 2036 lines | 1352 code | 244 blank | 440 comment | 278 complexity | 53a8c695f10fb5c9e049e93532ec6b55 MD5 | raw file
Possible License(s): BSD-3-Clause, MIT, GPL-3.0, GPL-2.0, MPL-2.0-no-copyleft-exception, LGPL-3.0, LGPL-2.1

Large files files are truncated, but you can click here to view the full file

  1. /* $Id$ */
  2. /** @file
  3. * IPRT - Network Sockets.
  4. */
  5. /*
  6. * Copyright (C) 2006-2012 Oracle Corporation
  7. *
  8. * This file is part of VirtualBox Open Source Edition (OSE), as
  9. * available from http://www.virtualbox.org. This file is free software;
  10. * you can redistribute it and/or modify it under the terms of the GNU
  11. * General Public License (GPL) as published by the Free Software
  12. * Foundation, in version 2 as it comes in the "COPYING" file of the
  13. * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
  14. * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
  15. *
  16. * The contents of this file may alternatively be used under the terms
  17. * of the Common Development and Distribution License Version 1.0
  18. * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
  19. * VirtualBox OSE distribution, in which case the provisions of the
  20. * CDDL are applicable instead of those of the GPL.
  21. *
  22. * You may elect to license modified versions of this file under the
  23. * terms and conditions of either the GPL or the CDDL or both.
  24. */
  25. /*******************************************************************************
  26. * Header Files *
  27. *******************************************************************************/
  28. #ifdef RT_OS_WINDOWS
  29. # include <winsock2.h>
  30. # include <ws2tcpip.h>
  31. #else /* !RT_OS_WINDOWS */
  32. # include <errno.h>
  33. # include <sys/select.h>
  34. # include <sys/stat.h>
  35. # include <sys/socket.h>
  36. # include <netinet/in.h>
  37. # include <netinet/tcp.h>
  38. # include <arpa/inet.h>
  39. # ifdef IPRT_WITH_TCPIP_V6
  40. # include <netinet6/in6.h>
  41. # endif
  42. # include <sys/un.h>
  43. # include <netdb.h>
  44. # include <unistd.h>
  45. # include <fcntl.h>
  46. # include <sys/uio.h>
  47. #endif /* !RT_OS_WINDOWS */
  48. #include <limits.h>
  49. #include "internal/iprt.h"
  50. #include <iprt/socket.h>
  51. #include <iprt/alloca.h>
  52. #include <iprt/asm.h>
  53. #include <iprt/assert.h>
  54. #include <iprt/ctype.h>
  55. #include <iprt/err.h>
  56. #include <iprt/mempool.h>
  57. #include <iprt/poll.h>
  58. #include <iprt/string.h>
  59. #include <iprt/thread.h>
  60. #include <iprt/time.h>
  61. #include <iprt/mem.h>
  62. #include <iprt/sg.h>
  63. #include <iprt/log.h>
  64. #include "internal/magics.h"
  65. #include "internal/socket.h"
  66. #include "internal/string.h"
  67. /*******************************************************************************
  68. * Defined Constants And Macros *
  69. *******************************************************************************/
  70. /* non-standard linux stuff (it seems). */
  71. #ifndef MSG_NOSIGNAL
  72. # define MSG_NOSIGNAL 0
  73. #endif
  74. /* Windows has different names for SHUT_XXX. */
  75. #ifndef SHUT_RDWR
  76. # ifdef SD_BOTH
  77. # define SHUT_RDWR SD_BOTH
  78. # else
  79. # define SHUT_RDWR 2
  80. # endif
  81. #endif
  82. #ifndef SHUT_WR
  83. # ifdef SD_SEND
  84. # define SHUT_WR SD_SEND
  85. # else
  86. # define SHUT_WR 1
  87. # endif
  88. #endif
  89. #ifndef SHUT_RD
  90. # ifdef SD_RECEIVE
  91. # define SHUT_RD SD_RECEIVE
  92. # else
  93. # define SHUT_RD 0
  94. # endif
  95. #endif
  96. /* fixup backlevel OSes. */
  97. #if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS)
  98. # define socklen_t int
  99. #endif
  100. /** How many pending connection. */
  101. #define RTTCP_SERVER_BACKLOG 10
  102. /*******************************************************************************
  103. * Structures and Typedefs *
  104. *******************************************************************************/
  105. /**
  106. * Socket handle data.
  107. *
  108. * This is mainly required for implementing RTPollSet on Windows.
  109. */
  110. typedef struct RTSOCKETINT
  111. {
  112. /** Magic number (RTSOCKET_MAGIC). */
  113. uint32_t u32Magic;
  114. /** Exclusive user count.
  115. * This is used to prevent two threads from accessing the handle concurrently.
  116. * It can be higher than 1 if this handle is reference multiple times in a
  117. * polling set (Windows). */
  118. uint32_t volatile cUsers;
  119. /** The native socket handle. */
  120. RTSOCKETNATIVE hNative;
  121. /** Indicates whether the handle has been closed or not. */
  122. bool volatile fClosed;
  123. /** Indicates whether the socket is operating in blocking or non-blocking mode
  124. * currently. */
  125. bool fBlocking;
  126. #ifdef RT_OS_WINDOWS
  127. /** The event semaphore we've associated with the socket handle.
  128. * This is WSA_INVALID_EVENT if not done. */
  129. WSAEVENT hEvent;
  130. /** The pollset currently polling this socket. This is NIL if no one is
  131. * polling. */
  132. RTPOLLSET hPollSet;
  133. /** The events we're polling for. */
  134. uint32_t fPollEvts;
  135. /** The events we're currently subscribing to with WSAEventSelect.
  136. * This is ZERO if we're currently not subscribing to anything. */
  137. uint32_t fSubscribedEvts;
  138. /** Saved events which are only posted once. */
  139. uint32_t fEventsSaved;
  140. #endif /* RT_OS_WINDOWS */
  141. } RTSOCKETINT;
  142. /**
  143. * Address union used internally for things like getpeername and getsockname.
  144. */
  145. typedef union RTSOCKADDRUNION
  146. {
  147. struct sockaddr Addr;
  148. struct sockaddr_in IPv4;
  149. #ifdef IPRT_WITH_TCPIP_V6
  150. struct sockaddr_in6 IPv6;
  151. #endif
  152. } RTSOCKADDRUNION;
  153. /**
  154. * Get the last error as an iprt status code.
  155. *
  156. * @returns IPRT status code.
  157. */
  158. DECLINLINE(int) rtSocketError(void)
  159. {
  160. #ifdef RT_OS_WINDOWS
  161. return RTErrConvertFromWin32(WSAGetLastError());
  162. #else
  163. return RTErrConvertFromErrno(errno);
  164. #endif
  165. }
  166. /**
  167. * Resets the last error.
  168. */
  169. DECLINLINE(void) rtSocketErrorReset(void)
  170. {
  171. #ifdef RT_OS_WINDOWS
  172. WSASetLastError(0);
  173. #else
  174. errno = 0;
  175. #endif
  176. }
  177. /**
  178. * Get the last resolver error as an iprt status code.
  179. *
  180. * @returns iprt status code.
  181. */
  182. int rtSocketResolverError(void)
  183. {
  184. #ifdef RT_OS_WINDOWS
  185. return RTErrConvertFromWin32(WSAGetLastError());
  186. #else
  187. switch (h_errno)
  188. {
  189. case HOST_NOT_FOUND:
  190. return VERR_NET_HOST_NOT_FOUND;
  191. case NO_DATA:
  192. return VERR_NET_ADDRESS_NOT_AVAILABLE;
  193. case NO_RECOVERY:
  194. return VERR_IO_GEN_FAILURE;
  195. case TRY_AGAIN:
  196. return VERR_TRY_AGAIN;
  197. default:
  198. return VERR_UNRESOLVED_ERROR;
  199. }
  200. #endif
  201. }
  202. /**
  203. * Converts from a native socket address to a generic IPRT network address.
  204. *
  205. * @returns IPRT status code.
  206. * @param pSrc The source address.
  207. * @param cbSrc The size of the source address.
  208. * @param pAddr Where to return the generic IPRT network
  209. * address.
  210. */
  211. static int rtSocketNetAddrFromAddr(RTSOCKADDRUNION const *pSrc, size_t cbSrc, PRTNETADDR pAddr)
  212. {
  213. /*
  214. * Convert the address.
  215. */
  216. if ( cbSrc == sizeof(struct sockaddr_in)
  217. && pSrc->Addr.sa_family == AF_INET)
  218. {
  219. RT_ZERO(*pAddr);
  220. pAddr->enmType = RTNETADDRTYPE_IPV4;
  221. pAddr->uPort = RT_N2H_U16(pSrc->IPv4.sin_port);
  222. pAddr->uAddr.IPv4.u = pSrc->IPv4.sin_addr.s_addr;
  223. }
  224. #ifdef IPRT_WITH_TCPIP_V6
  225. else if ( cbSrc == sizeof(struct sockaddr_in6)
  226. && pSrc->Addr.sa_family == AF_INET6)
  227. {
  228. RT_ZERO(*pAddr);
  229. pAddr->enmType = RTNETADDRTYPE_IPV6;
  230. pAddr->uPort = RT_N2H_U16(pSrc->IPv6.sin6_port);
  231. pAddr->uAddr.IPv6.au32[0] = pSrc->IPv6.sin6_addr.s6_addr32[0];
  232. pAddr->uAddr.IPv6.au32[1] = pSrc->IPv6.sin6_addr.s6_addr32[1];
  233. pAddr->uAddr.IPv6.au32[2] = pSrc->IPv6.sin6_addr.s6_addr32[2];
  234. pAddr->uAddr.IPv6.au32[3] = pSrc->IPv6.sin6_addr.s6_addr32[3];
  235. }
  236. #endif
  237. else
  238. return VERR_NET_ADDRESS_FAMILY_NOT_SUPPORTED;
  239. return VINF_SUCCESS;
  240. }
  241. /**
  242. * Converts from a generic IPRT network address to a native socket address.
  243. *
  244. * @returns IPRT status code.
  245. * @param pAddr Pointer to the generic IPRT network address.
  246. * @param pDst The source address.
  247. * @param cbSrc The size of the source address.
  248. * @param pcbAddr Where to store the size of the returned address.
  249. * Optional
  250. */
  251. static int rtSocketAddrFromNetAddr(PCRTNETADDR pAddr, RTSOCKADDRUNION *pDst, size_t cbDst, int *pcbAddr)
  252. {
  253. RT_BZERO(pDst, cbDst);
  254. if ( pAddr->enmType == RTNETADDRTYPE_IPV4
  255. && cbDst >= sizeof(struct sockaddr_in))
  256. {
  257. pDst->Addr.sa_family = AF_INET;
  258. pDst->IPv4.sin_port = RT_H2N_U16(pAddr->uPort);
  259. pDst->IPv4.sin_addr.s_addr = pAddr->uAddr.IPv4.u;
  260. if (pcbAddr)
  261. *pcbAddr = sizeof(pDst->IPv4);
  262. }
  263. #ifdef IPRT_WITH_TCPIP_V6
  264. else if ( pAddr->enmType == RTNETADDRTYPE_IPV6
  265. && cbDst >= sizeof(struct sockaddr_in6))
  266. {
  267. pDst->Addr.sa_family = AF_INET6;
  268. pDst->IPv6.sin6_port = RT_H2N_U16(pAddr->uPort);
  269. pSrc->IPv6.sin6_addr.s6_addr32[0] = pAddr->uAddr.IPv6.au32[0];
  270. pSrc->IPv6.sin6_addr.s6_addr32[1] = pAddr->uAddr.IPv6.au32[1];
  271. pSrc->IPv6.sin6_addr.s6_addr32[2] = pAddr->uAddr.IPv6.au32[2];
  272. pSrc->IPv6.sin6_addr.s6_addr32[3] = pAddr->uAddr.IPv6.au32[3];
  273. if (pcbAddr)
  274. *pcbAddr = sizeof(pDst->IPv6);
  275. }
  276. #endif
  277. else
  278. return VERR_NET_ADDRESS_FAMILY_NOT_SUPPORTED;
  279. return VINF_SUCCESS;
  280. }
  281. /**
  282. * Tries to lock the socket for exclusive usage by the calling thread.
  283. *
  284. * Call rtSocketUnlock() to unlock.
  285. *
  286. * @returns @c true if locked, @c false if not.
  287. * @param pThis The socket structure.
  288. */
  289. DECLINLINE(bool) rtSocketTryLock(RTSOCKETINT *pThis)
  290. {
  291. return ASMAtomicCmpXchgU32(&pThis->cUsers, 1, 0);
  292. }
  293. /**
  294. * Unlocks the socket.
  295. *
  296. * @param pThis The socket structure.
  297. */
  298. DECLINLINE(void) rtSocketUnlock(RTSOCKETINT *pThis)
  299. {
  300. ASMAtomicCmpXchgU32(&pThis->cUsers, 0, 1);
  301. }
  302. /**
  303. * The slow path of rtSocketSwitchBlockingMode that does the actual switching.
  304. *
  305. * @returns IPRT status code.
  306. * @param pThis The socket structure.
  307. * @param fBlocking The desired mode of operation.
  308. * @remarks Do not call directly.
  309. */
  310. static int rtSocketSwitchBlockingModeSlow(RTSOCKETINT *pThis, bool fBlocking)
  311. {
  312. #ifdef RT_OS_WINDOWS
  313. u_long uBlocking = fBlocking ? 0 : 1;
  314. if (ioctlsocket(pThis->hNative, FIONBIO, &uBlocking))
  315. return rtSocketError();
  316. #else
  317. int fFlags = fcntl(pThis->hNative, F_GETFL, 0);
  318. if (fFlags == -1)
  319. return rtSocketError();
  320. if (fBlocking)
  321. fFlags &= ~O_NONBLOCK;
  322. else
  323. fFlags |= O_NONBLOCK;
  324. if (fcntl(pThis->hNative, F_SETFL, fFlags) == -1)
  325. return rtSocketError();
  326. #endif
  327. pThis->fBlocking = fBlocking;
  328. return VINF_SUCCESS;
  329. }
  330. /**
  331. * Switches the socket to the desired blocking mode if necessary.
  332. *
  333. * The socket must be locked.
  334. *
  335. * @returns IPRT status code.
  336. * @param pThis The socket structure.
  337. * @param fBlocking The desired mode of operation.
  338. */
  339. DECLINLINE(int) rtSocketSwitchBlockingMode(RTSOCKETINT *pThis, bool fBlocking)
  340. {
  341. if (pThis->fBlocking != fBlocking)
  342. return rtSocketSwitchBlockingModeSlow(pThis, fBlocking);
  343. return VINF_SUCCESS;
  344. }
  345. /**
  346. * Creates an IPRT socket handle for a native one.
  347. *
  348. * @returns IPRT status code.
  349. * @param ppSocket Where to return the IPRT socket handle.
  350. * @param hNative The native handle.
  351. */
  352. int rtSocketCreateForNative(RTSOCKETINT **ppSocket, RTSOCKETNATIVE hNative)
  353. {
  354. RTSOCKETINT *pThis = (RTSOCKETINT *)RTMemPoolAlloc(RTMEMPOOL_DEFAULT, sizeof(*pThis));
  355. if (!pThis)
  356. return VERR_NO_MEMORY;
  357. pThis->u32Magic = RTSOCKET_MAGIC;
  358. pThis->cUsers = 0;
  359. pThis->hNative = hNative;
  360. pThis->fClosed = false;
  361. pThis->fBlocking = true;
  362. #ifdef RT_OS_WINDOWS
  363. pThis->hEvent = WSA_INVALID_EVENT;
  364. pThis->hPollSet = NIL_RTPOLLSET;
  365. pThis->fPollEvts = 0;
  366. pThis->fSubscribedEvts = 0;
  367. #endif
  368. *ppSocket = pThis;
  369. return VINF_SUCCESS;
  370. }
  371. RTDECL(int) RTSocketFromNative(PRTSOCKET phSocket, RTHCINTPTR uNative)
  372. {
  373. AssertReturn(uNative != NIL_RTSOCKETNATIVE, VERR_INVALID_PARAMETER);
  374. #ifndef RT_OS_WINDOWS
  375. AssertReturn(uNative >= 0, VERR_INVALID_PARAMETER);
  376. #endif
  377. AssertPtrReturn(phSocket, VERR_INVALID_POINTER);
  378. return rtSocketCreateForNative(phSocket, uNative);
  379. }
  380. /**
  381. * Wrapper around socket().
  382. *
  383. * @returns IPRT status code.
  384. * @param phSocket Where to store the handle to the socket on
  385. * success.
  386. * @param iDomain The protocol family (PF_XXX).
  387. * @param iType The socket type (SOCK_XXX).
  388. * @param iProtocol Socket parameter, usually 0.
  389. */
  390. int rtSocketCreate(PRTSOCKET phSocket, int iDomain, int iType, int iProtocol)
  391. {
  392. /*
  393. * Create the socket.
  394. */
  395. RTSOCKETNATIVE hNative = socket(iDomain, iType, iProtocol);
  396. if (hNative == NIL_RTSOCKETNATIVE)
  397. return rtSocketError();
  398. /*
  399. * Wrap it.
  400. */
  401. int rc = rtSocketCreateForNative(phSocket, hNative);
  402. if (RT_FAILURE(rc))
  403. {
  404. #ifdef RT_OS_WINDOWS
  405. closesocket(hNative);
  406. #else
  407. close(hNative);
  408. #endif
  409. }
  410. return rc;
  411. }
  412. RTDECL(uint32_t) RTSocketRetain(RTSOCKET hSocket)
  413. {
  414. RTSOCKETINT *pThis = hSocket;
  415. AssertPtrReturn(pThis, UINT32_MAX);
  416. AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, UINT32_MAX);
  417. return RTMemPoolRetain(pThis);
  418. }
  419. /**
  420. * Worker for RTSocketRelease and RTSocketClose.
  421. *
  422. * @returns IPRT status code.
  423. * @param pThis The socket handle instance data.
  424. * @param fDestroy Whether we're reaching ref count zero.
  425. */
  426. static int rtSocketCloseIt(RTSOCKETINT *pThis, bool fDestroy)
  427. {
  428. /*
  429. * Invalidate the handle structure on destroy.
  430. */
  431. if (fDestroy)
  432. {
  433. Assert(ASMAtomicReadU32(&pThis->u32Magic) == RTSOCKET_MAGIC);
  434. ASMAtomicWriteU32(&pThis->u32Magic, RTSOCKET_MAGIC_DEAD);
  435. }
  436. int rc = VINF_SUCCESS;
  437. if (ASMAtomicCmpXchgBool(&pThis->fClosed, true, false))
  438. {
  439. /*
  440. * Close the native handle.
  441. */
  442. RTSOCKETNATIVE hNative = pThis->hNative;
  443. if (hNative != NIL_RTSOCKETNATIVE)
  444. {
  445. pThis->hNative = NIL_RTSOCKETNATIVE;
  446. #ifdef RT_OS_WINDOWS
  447. if (closesocket(hNative))
  448. #else
  449. if (close(hNative))
  450. #endif
  451. {
  452. rc = rtSocketError();
  453. #ifdef RT_OS_WINDOWS
  454. AssertMsgFailed(("\"%s\": closesocket(%p) -> %Rrc\n", (uintptr_t)hNative, rc));
  455. #else
  456. AssertMsgFailed(("\"%s\": close(%d) -> %Rrc\n", hNative, rc));
  457. #endif
  458. }
  459. }
  460. #ifdef RT_OS_WINDOWS
  461. /*
  462. * Close the event.
  463. */
  464. WSAEVENT hEvent = pThis->hEvent;
  465. if (hEvent == WSA_INVALID_EVENT)
  466. {
  467. pThis->hEvent = WSA_INVALID_EVENT;
  468. WSACloseEvent(hEvent);
  469. }
  470. #endif
  471. }
  472. return rc;
  473. }
  474. RTDECL(uint32_t) RTSocketRelease(RTSOCKET hSocket)
  475. {
  476. RTSOCKETINT *pThis = hSocket;
  477. if (pThis == NIL_RTSOCKET)
  478. return 0;
  479. AssertPtrReturn(pThis, UINT32_MAX);
  480. AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, UINT32_MAX);
  481. /* get the refcount without killing it... */
  482. uint32_t cRefs = RTMemPoolRefCount(pThis);
  483. AssertReturn(cRefs != UINT32_MAX, UINT32_MAX);
  484. if (cRefs == 1)
  485. rtSocketCloseIt(pThis, true);
  486. return RTMemPoolRelease(RTMEMPOOL_DEFAULT, pThis);
  487. }
  488. RTDECL(int) RTSocketClose(RTSOCKET hSocket)
  489. {
  490. RTSOCKETINT *pThis = hSocket;
  491. if (pThis == NIL_RTSOCKET)
  492. return VINF_SUCCESS;
  493. AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
  494. AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE);
  495. uint32_t cRefs = RTMemPoolRefCount(pThis);
  496. AssertReturn(cRefs != UINT32_MAX, UINT32_MAX);
  497. int rc = rtSocketCloseIt(pThis, cRefs == 1);
  498. RTMemPoolRelease(RTMEMPOOL_DEFAULT, pThis);
  499. return rc;
  500. }
  501. RTDECL(RTHCUINTPTR) RTSocketToNative(RTSOCKET hSocket)
  502. {
  503. RTSOCKETINT *pThis = hSocket;
  504. AssertPtrReturn(pThis, RTHCUINTPTR_MAX);
  505. AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, RTHCUINTPTR_MAX);
  506. return (RTHCUINTPTR)pThis->hNative;
  507. }
  508. RTDECL(int) RTSocketSetInheritance(RTSOCKET hSocket, bool fInheritable)
  509. {
  510. RTSOCKETINT *pThis = hSocket;
  511. AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
  512. AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE);
  513. AssertReturn(RTMemPoolRefCount(pThis) >= (pThis->cUsers ? 2U : 1U), VERR_CALLER_NO_REFERENCE);
  514. int rc = VINF_SUCCESS;
  515. #ifdef RT_OS_WINDOWS
  516. if (!SetHandleInformation((HANDLE)pThis->hNative, HANDLE_FLAG_INHERIT, fInheritable ? HANDLE_FLAG_INHERIT : 0))
  517. rc = RTErrConvertFromWin32(GetLastError());
  518. #else
  519. if (fcntl(pThis->hNative, F_SETFD, fInheritable ? 0 : FD_CLOEXEC) < 0)
  520. rc = RTErrConvertFromErrno(errno);
  521. #endif
  522. return rc;
  523. }
  524. static bool rtSocketIsIPv4Numerical(const char *pszAddress, PRTNETADDRIPV4 pAddr)
  525. {
  526. /* Empty address resolves to the INADDR_ANY address (good for bind). */
  527. if (!pszAddress || !*pszAddress)
  528. {
  529. pAddr->u = INADDR_ANY;
  530. return true;
  531. }
  532. /* Four quads? */
  533. char *psz = (char *)pszAddress;
  534. for (int i = 0; i < 4; i++)
  535. {
  536. uint8_t u8;
  537. int rc = RTStrToUInt8Ex(psz, &psz, 0, &u8);
  538. if (rc != VINF_SUCCESS && rc != VWRN_TRAILING_CHARS)
  539. return false;
  540. if (*psz != (i < 3 ? '.' : '\0'))
  541. return false;
  542. psz++;
  543. pAddr->au8[i] = u8; /* big endian */
  544. }
  545. return true;
  546. }
  547. RTDECL(int) RTSocketParseInetAddress(const char *pszAddress, unsigned uPort, PRTNETADDR pAddr)
  548. {
  549. int rc;
  550. /*
  551. * Validate input.
  552. */
  553. AssertReturn(uPort > 0, VERR_INVALID_PARAMETER);
  554. AssertPtrNullReturn(pszAddress, VERR_INVALID_POINTER);
  555. #ifdef RT_OS_WINDOWS
  556. /*
  557. * Initialize WinSock and check version.
  558. */
  559. WORD wVersionRequested = MAKEWORD(1, 1);
  560. WSADATA wsaData;
  561. rc = WSAStartup(wVersionRequested, &wsaData);
  562. if (wsaData.wVersion != wVersionRequested)
  563. {
  564. AssertMsgFailed(("Wrong winsock version\n"));
  565. return VERR_NOT_SUPPORTED;
  566. }
  567. #endif
  568. /*
  569. * Resolve the address. Pretty crude at the moment, but we have to make
  570. * sure to not ask the NT 4 gethostbyname about an IPv4 address as it may
  571. * give a wrong answer.
  572. */
  573. /** @todo this only supports IPv4, and IPv6 support needs to be added.
  574. * It probably needs to be converted to getaddrinfo(). */
  575. RTNETADDRIPV4 IPv4Quad;
  576. if (rtSocketIsIPv4Numerical(pszAddress, &IPv4Quad))
  577. {
  578. Log3(("rtSocketIsIPv4Numerical: %#x (%RTnaipv4)\n", pszAddress, IPv4Quad.u, IPv4Quad));
  579. RT_ZERO(*pAddr);
  580. pAddr->enmType = RTNETADDRTYPE_IPV4;
  581. pAddr->uPort = uPort;
  582. pAddr->uAddr.IPv4 = IPv4Quad;
  583. return VINF_SUCCESS;
  584. }
  585. struct hostent *pHostEnt;
  586. pHostEnt = gethostbyname(pszAddress);
  587. if (!pHostEnt)
  588. {
  589. rc = rtSocketResolverError();
  590. AssertMsgFailed(("Could not resolve '%s', rc=%Rrc\n", pszAddress, rc));
  591. return rc;
  592. }
  593. if (pHostEnt->h_addrtype == AF_INET)
  594. {
  595. RT_ZERO(*pAddr);
  596. pAddr->enmType = RTNETADDRTYPE_IPV4;
  597. pAddr->uPort = uPort;
  598. pAddr->uAddr.IPv4.u = ((struct in_addr *)pHostEnt->h_addr)->s_addr;
  599. Log3(("gethostbyname: %s -> %#x (%RTnaipv4)\n", pszAddress, pAddr->uAddr.IPv4.u, pAddr->uAddr.IPv4));
  600. }
  601. else
  602. return VERR_NET_ADDRESS_FAMILY_NOT_SUPPORTED;
  603. return VINF_SUCCESS;
  604. }
  605. /*
  606. * New function to allow both ipv4 and ipv6 addresses to be resolved.
  607. * Breaks compatibility with windows before 2000.
  608. */
  609. RTDECL(int) RTSocketQueryAddressStr(const char *pszHost, char *pszResult, size_t *pcbResult, PRTNETADDRTYPE penmAddrType)
  610. {
  611. AssertPtrReturn(pszHost, VERR_INVALID_POINTER);
  612. AssertPtrReturn(pcbResult, VERR_INVALID_POINTER);
  613. AssertPtrNullReturn(penmAddrType, VERR_INVALID_POINTER);
  614. AssertPtrNullReturn(pszResult, VERR_INVALID_POINTER);
  615. #if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS) /** @todo dynamically resolve the APIs not present in NT4! */
  616. return VERR_NOT_SUPPORTED;
  617. #else
  618. int rc;
  619. if (*pcbResult < 16)
  620. return VERR_NET_ADDRESS_NOT_AVAILABLE;
  621. /* Setup the hint. */
  622. struct addrinfo grHints;
  623. RT_ZERO(grHints);
  624. grHints.ai_socktype = 0;
  625. grHints.ai_flags = 0;
  626. grHints.ai_protocol = 0;
  627. grHints.ai_family = AF_UNSPEC;
  628. if (penmAddrType)
  629. {
  630. switch (*penmAddrType)
  631. {
  632. case RTNETADDRTYPE_INVALID:
  633. /*grHints.ai_family = AF_UNSPEC;*/
  634. break;
  635. case RTNETADDRTYPE_IPV4:
  636. grHints.ai_family = AF_INET;
  637. break;
  638. case RTNETADDRTYPE_IPV6:
  639. grHints.ai_family = AF_INET6;
  640. break;
  641. default:
  642. AssertFailedReturn(VERR_INVALID_PARAMETER);
  643. }
  644. }
  645. # ifdef RT_OS_WINDOWS
  646. /*
  647. * Winsock2 init
  648. */
  649. /** @todo someone should check if we really need 2, 2 here */
  650. WORD wVersionRequested = MAKEWORD(2, 2);
  651. WSADATA wsaData;
  652. rc = WSAStartup(wVersionRequested, &wsaData);
  653. if (wsaData.wVersion != wVersionRequested)
  654. {
  655. AssertMsgFailed(("Wrong winsock version\n"));
  656. return VERR_NOT_SUPPORTED;
  657. }
  658. # endif
  659. /** @todo r=bird: getaddrinfo and freeaddrinfo breaks the additions on NT4. */
  660. struct addrinfo *pgrResults = NULL;
  661. rc = getaddrinfo(pszHost, "", &grHints, &pgrResults);
  662. if (rc != 0)
  663. return VERR_NET_ADDRESS_NOT_AVAILABLE;
  664. // return data
  665. // on multiple matches return only the first one
  666. if (!pgrResults)
  667. return VERR_NET_ADDRESS_NOT_AVAILABLE;
  668. struct addrinfo const *pgrResult = pgrResults->ai_next;
  669. if (!pgrResult)
  670. {
  671. freeaddrinfo(pgrResults);
  672. return VERR_NET_ADDRESS_NOT_AVAILABLE;
  673. }
  674. uint8_t const *pbDummy;
  675. RTNETADDRTYPE enmAddrType = RTNETADDRTYPE_INVALID;
  676. size_t cchIpAddress;
  677. char szIpAddress[48];
  678. if (pgrResult->ai_family == AF_INET)
  679. {
  680. struct sockaddr_in const *pgrSa = (struct sockaddr_in const *)pgrResult->ai_addr;
  681. pbDummy = (uint8_t const *)&pgrSa->sin_addr;
  682. cchIpAddress = RTStrPrintf(szIpAddress, sizeof(szIpAddress), "%u.%u.%u.%u",
  683. pbDummy[0], pbDummy[1], pbDummy[2], pbDummy[3]);
  684. Assert(cchIpAddress >= 7 && cchIpAddress < sizeof(szIpAddress) - 1);
  685. enmAddrType = RTNETADDRTYPE_IPV4;
  686. rc = VINF_SUCCESS;
  687. }
  688. else if (pgrResult->ai_family == AF_INET6)
  689. {
  690. struct sockaddr_in6 const *pgrSa6 = (struct sockaddr_in6 const *)pgrResult->ai_addr;
  691. pbDummy = (uint8_t const *) &pgrSa6->sin6_addr;
  692. char szTmp[32+1];
  693. size_t cchTmp = RTStrPrintf(szTmp, sizeof(szTmp),
  694. "%02x%02x%02x%02x"
  695. "%02x%02x%02x%02x"
  696. "%02x%02x%02x%02x"
  697. "%02x%02x%02x%02x",
  698. pbDummy[0], pbDummy[1], pbDummy[2], pbDummy[3],
  699. pbDummy[4], pbDummy[5], pbDummy[6], pbDummy[7],
  700. pbDummy[8], pbDummy[9], pbDummy[10], pbDummy[11],
  701. pbDummy[12], pbDummy[13], pbDummy[14], pbDummy[15]);
  702. Assert(cchTmp == 32);
  703. rc = rtStrToIpAddr6Str(szTmp, szIpAddress, sizeof(szIpAddress), NULL, 0, true);
  704. if (RT_SUCCESS(rc))
  705. cchIpAddress = strlen(szIpAddress);
  706. else
  707. {
  708. szIpAddress[0] = '\0';
  709. cchIpAddress = 0;
  710. }
  711. enmAddrType = RTNETADDRTYPE_IPV6;
  712. }
  713. else
  714. {
  715. rc = VERR_NET_ADDRESS_NOT_AVAILABLE;
  716. szIpAddress[0] = '\0';
  717. cchIpAddress = 0;
  718. }
  719. freeaddrinfo(pgrResults);
  720. /*
  721. * Copy out the result.
  722. */
  723. size_t const cbResult = *pcbResult;
  724. *pcbResult = cchIpAddress + 1;
  725. if (cchIpAddress < cbResult)
  726. memcpy(pszResult, szIpAddress, cchIpAddress + 1);
  727. else
  728. {
  729. RT_BZERO(pszResult, cbResult);
  730. if (RT_SUCCESS(rc))
  731. rc = VERR_BUFFER_OVERFLOW;
  732. }
  733. if (penmAddrType && RT_SUCCESS(rc))
  734. *penmAddrType = enmAddrType;
  735. return rc;
  736. #endif /* !RT_OS_OS2 */
  737. }
  738. RTDECL(int) RTSocketRead(RTSOCKET hSocket, void *pvBuffer, size_t cbBuffer, size_t *pcbRead)
  739. {
  740. /*
  741. * Validate input.
  742. */
  743. RTSOCKETINT *pThis = hSocket;
  744. AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
  745. AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE);
  746. AssertReturn(cbBuffer > 0, VERR_INVALID_PARAMETER);
  747. AssertPtr(pvBuffer);
  748. AssertReturn(rtSocketTryLock(pThis), VERR_CONCURRENT_ACCESS);
  749. int rc = rtSocketSwitchBlockingMode(pThis, true /* fBlocking */);
  750. if (RT_FAILURE(rc))
  751. return rc;
  752. /*
  753. * Read loop.
  754. * If pcbRead is NULL we have to fill the entire buffer!
  755. */
  756. size_t cbRead = 0;
  757. size_t cbToRead = cbBuffer;
  758. for (;;)
  759. {
  760. rtSocketErrorReset();
  761. #ifdef RT_OS_WINDOWS
  762. int cbNow = cbToRead >= INT_MAX/2 ? INT_MAX/2 : (int)cbToRead;
  763. #else
  764. size_t cbNow = cbToRead;
  765. #endif
  766. ssize_t cbBytesRead = recv(pThis->hNative, (char *)pvBuffer + cbRead, cbNow, MSG_NOSIGNAL);
  767. if (cbBytesRead <= 0)
  768. {
  769. rc = rtSocketError();
  770. Assert(RT_FAILURE_NP(rc) || cbBytesRead == 0);
  771. if (RT_SUCCESS_NP(rc))
  772. {
  773. if (!pcbRead)
  774. rc = VERR_NET_SHUTDOWN;
  775. else
  776. {
  777. *pcbRead = 0;
  778. rc = VINF_SUCCESS;
  779. }
  780. }
  781. break;
  782. }
  783. if (pcbRead)
  784. {
  785. /* return partial data */
  786. *pcbRead = cbBytesRead;
  787. break;
  788. }
  789. /* read more? */
  790. cbRead += cbBytesRead;
  791. if (cbRead == cbBuffer)
  792. break;
  793. /* next */
  794. cbToRead = cbBuffer - cbRead;
  795. }
  796. rtSocketUnlock(pThis);
  797. return rc;
  798. }
  799. RTDECL(int) RTSocketReadFrom(RTSOCKET hSocket, void *pvBuffer, size_t cbBuffer, size_t *pcbRead, PRTNETADDR pSrcAddr)
  800. {
  801. /*
  802. * Validate input.
  803. */
  804. RTSOCKETINT *pThis = hSocket;
  805. AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
  806. AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE);
  807. AssertReturn(cbBuffer > 0, VERR_INVALID_PARAMETER);
  808. AssertPtr(pvBuffer);
  809. AssertPtr(pcbRead);
  810. AssertReturn(rtSocketTryLock(pThis), VERR_CONCURRENT_ACCESS);
  811. int rc = rtSocketSwitchBlockingMode(pThis, true /* fBlocking */);
  812. if (RT_FAILURE(rc))
  813. return rc;
  814. /*
  815. * Read data.
  816. */
  817. size_t cbRead = 0;
  818. size_t cbToRead = cbBuffer;
  819. rtSocketErrorReset();
  820. RTSOCKADDRUNION u;
  821. #ifdef RT_OS_WINDOWS
  822. int cbNow = cbToRead >= INT_MAX/2 ? INT_MAX/2 : (int)cbToRead;
  823. int cbAddr = sizeof(u);
  824. #else
  825. size_t cbNow = cbToRead;
  826. socklen_t cbAddr = sizeof(u);
  827. #endif
  828. ssize_t cbBytesRead = recvfrom(pThis->hNative, (char *)pvBuffer + cbRead, cbNow, MSG_NOSIGNAL, &u.Addr, &cbAddr);
  829. if (cbBytesRead <= 0)
  830. {
  831. rc = rtSocketError();
  832. Assert(RT_FAILURE_NP(rc) || cbBytesRead == 0);
  833. if (RT_SUCCESS_NP(rc))
  834. {
  835. *pcbRead = 0;
  836. rc = VINF_SUCCESS;
  837. }
  838. }
  839. else
  840. {
  841. if (pSrcAddr)
  842. rc = rtSocketNetAddrFromAddr(&u, cbAddr, pSrcAddr);
  843. *pcbRead = cbBytesRead;
  844. }
  845. rtSocketUnlock(pThis);
  846. return rc;
  847. }
  848. RTDECL(int) RTSocketWrite(RTSOCKET hSocket, const void *pvBuffer, size_t cbBuffer)
  849. {
  850. /*
  851. * Validate input.
  852. */
  853. RTSOCKETINT *pThis = hSocket;
  854. AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
  855. AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE);
  856. AssertReturn(rtSocketTryLock(pThis), VERR_CONCURRENT_ACCESS);
  857. int rc = rtSocketSwitchBlockingMode(pThis, true /* fBlocking */);
  858. if (RT_FAILURE(rc))
  859. return rc;
  860. /*
  861. * Try write all at once.
  862. */
  863. #ifdef RT_OS_WINDOWS
  864. int cbNow = cbBuffer >= INT_MAX / 2 ? INT_MAX / 2 : (int)cbBuffer;
  865. #else
  866. size_t cbNow = cbBuffer >= SSIZE_MAX ? SSIZE_MAX : cbBuffer;
  867. #endif
  868. ssize_t cbWritten = send(pThis->hNative, (const char *)pvBuffer, cbNow, MSG_NOSIGNAL);
  869. if (RT_LIKELY((size_t)cbWritten == cbBuffer && cbWritten >= 0))
  870. rc = VINF_SUCCESS;
  871. else if (cbWritten < 0)
  872. rc = rtSocketError();
  873. else
  874. {
  875. /*
  876. * Unfinished business, write the remainder of the request. Must ignore
  877. * VERR_INTERRUPTED here if we've managed to send something.
  878. */
  879. size_t cbSentSoFar = 0;
  880. for (;;)
  881. {
  882. /* advance */
  883. cbBuffer -= (size_t)cbWritten;
  884. if (!cbBuffer)
  885. break;
  886. cbSentSoFar += (size_t)cbWritten;
  887. pvBuffer = (char const *)pvBuffer + cbWritten;
  888. /* send */
  889. #ifdef RT_OS_WINDOWS
  890. cbNow = cbBuffer >= INT_MAX / 2 ? INT_MAX / 2 : (int)cbBuffer;
  891. #else
  892. cbNow = cbBuffer >= SSIZE_MAX ? SSIZE_MAX : cbBuffer;
  893. #endif
  894. cbWritten = send(pThis->hNative, (const char *)pvBuffer, cbNow, MSG_NOSIGNAL);
  895. if (cbWritten >= 0)
  896. AssertMsg(cbBuffer >= (size_t)cbWritten, ("Wrote more than we requested!!! cbWritten=%zu cbBuffer=%zu rtSocketError()=%d\n",
  897. cbWritten, cbBuffer, rtSocketError()));
  898. else
  899. {
  900. rc = rtSocketError();
  901. if (rc != VERR_INTERNAL_ERROR || cbSentSoFar == 0)
  902. break;
  903. cbWritten = 0;
  904. rc = VINF_SUCCESS;
  905. }
  906. }
  907. }
  908. rtSocketUnlock(pThis);
  909. return rc;
  910. }
  911. RTDECL(int) RTSocketWriteTo(RTSOCKET hSocket, const void *pvBuffer, size_t cbBuffer, PCRTNETADDR pAddr)
  912. {
  913. /*
  914. * Validate input.
  915. */
  916. RTSOCKETINT *pThis = hSocket;
  917. AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
  918. AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE);
  919. /* no locking since UDP reads may be done concurrently to writes, and
  920. * this is the normal use case of this code. */
  921. int rc = rtSocketSwitchBlockingMode(pThis, true /* fBlocking */);
  922. if (RT_FAILURE(rc))
  923. return rc;
  924. /* Figure out destination address. */
  925. struct sockaddr *pSA = NULL;
  926. #ifdef RT_OS_WINDOWS
  927. int cbSA = 0;
  928. #else
  929. socklen_t cbSA = 0;
  930. #endif
  931. RTSOCKADDRUNION u;
  932. if (pAddr)
  933. {
  934. rc = rtSocketAddrFromNetAddr(pAddr, &u, sizeof(u), NULL);
  935. if (RT_FAILURE(rc))
  936. return rc;
  937. pSA = &u.Addr;
  938. cbSA = sizeof(u);
  939. }
  940. /*
  941. * Must write all at once, otherwise it is a failure.
  942. */
  943. #ifdef RT_OS_WINDOWS
  944. int cbNow = cbBuffer >= INT_MAX / 2 ? INT_MAX / 2 : (int)cbBuffer;
  945. #else
  946. size_t cbNow = cbBuffer >= SSIZE_MAX ? SSIZE_MAX : cbBuffer;
  947. #endif
  948. ssize_t cbWritten = sendto(pThis->hNative, (const char *)pvBuffer, cbNow, MSG_NOSIGNAL, pSA, cbSA);
  949. if (RT_LIKELY((size_t)cbWritten == cbBuffer && cbWritten >= 0))
  950. rc = VINF_SUCCESS;
  951. else if (cbWritten < 0)
  952. rc = rtSocketError();
  953. else
  954. rc = VERR_TOO_MUCH_DATA;
  955. rtSocketUnlock(pThis);
  956. return rc;
  957. }
  958. RTDECL(int) RTSocketSgWrite(RTSOCKET hSocket, PCRTSGBUF pSgBuf)
  959. {
  960. /*
  961. * Validate input.
  962. */
  963. RTSOCKETINT *pThis = hSocket;
  964. AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
  965. AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE);
  966. AssertPtrReturn(pSgBuf, VERR_INVALID_PARAMETER);
  967. AssertReturn(pSgBuf->cSegs > 0, VERR_INVALID_PARAMETER);
  968. AssertReturn(rtSocketTryLock(pThis), VERR_CONCURRENT_ACCESS);
  969. int rc = rtSocketSwitchBlockingMode(pThis, true /* fBlocking */);
  970. if (RT_FAILURE(rc))
  971. return rc;
  972. /*
  973. * Construct message descriptor (translate pSgBuf) and send it.
  974. */
  975. rc = VERR_NO_TMP_MEMORY;
  976. #ifdef RT_OS_WINDOWS
  977. AssertCompileSize(WSABUF, sizeof(RTSGSEG));
  978. AssertCompileMemberSize(WSABUF, buf, RT_SIZEOFMEMB(RTSGSEG, pvSeg));
  979. LPWSABUF paMsg = (LPWSABUF)RTMemTmpAllocZ(pSgBuf->cSegs * sizeof(WSABUF));
  980. if (paMsg)
  981. {
  982. for (unsigned i = 0; i < pSgBuf->cSegs; i++)
  983. {
  984. paMsg[i].buf = (char *)pSgBuf->paSegs[i].pvSeg;
  985. paMsg[i].len = (u_long)pSgBuf->paSegs[i].cbSeg;
  986. }
  987. DWORD dwSent;
  988. int hrc = WSASend(pThis->hNative, paMsg, pSgBuf->cSegs, &dwSent,
  989. MSG_NOSIGNAL, NULL, NULL);
  990. if (!hrc)
  991. rc = VINF_SUCCESS;
  992. /** @todo check for incomplete writes */
  993. else
  994. rc = rtSocketError();
  995. RTMemTmpFree(paMsg);
  996. }
  997. #else /* !RT_OS_WINDOWS */
  998. AssertCompileSize(struct iovec, sizeof(RTSGSEG));
  999. AssertCompileMemberSize(struct iovec, iov_base, RT_SIZEOFMEMB(RTSGSEG, pvSeg));
  1000. AssertCompileMemberSize(struct iovec, iov_len, RT_SIZEOFMEMB(RTSGSEG, cbSeg));
  1001. struct iovec *paMsg = (struct iovec *)RTMemTmpAllocZ(pSgBuf->cSegs * sizeof(struct iovec));
  1002. if (paMsg)
  1003. {
  1004. for (unsigned i = 0; i < pSgBuf->cSegs; i++)
  1005. {
  1006. paMsg[i].iov_base = pSgBuf->paSegs[i].pvSeg;
  1007. paMsg[i].iov_len = pSgBuf->paSegs[i].cbSeg;
  1008. }
  1009. struct msghdr msgHdr;
  1010. RT_ZERO(msgHdr);
  1011. msgHdr.msg_iov = paMsg;
  1012. msgHdr.msg_iovlen = pSgBuf->cSegs;
  1013. ssize_t cbWritten = sendmsg(pThis->hNative, &msgHdr, MSG_NOSIGNAL);
  1014. if (RT_LIKELY(cbWritten >= 0))
  1015. rc = VINF_SUCCESS;
  1016. /** @todo check for incomplete writes */
  1017. else
  1018. rc = rtSocketError();
  1019. RTMemTmpFree(paMsg);
  1020. }
  1021. #endif /* !RT_OS_WINDOWS */
  1022. rtSocketUnlock(pThis);
  1023. return rc;
  1024. }
  1025. RTDECL(int) RTSocketSgWriteL(RTSOCKET hSocket, size_t cSegs, ...)
  1026. {
  1027. va_list va;
  1028. va_start(va, cSegs);
  1029. int rc = RTSocketSgWriteLV(hSocket, cSegs, va);
  1030. va_end(va);
  1031. return rc;
  1032. }
  1033. RTDECL(int) RTSocketSgWriteLV(RTSOCKET hSocket, size_t cSegs, va_list va)
  1034. {
  1035. /*
  1036. * Set up a S/G segment array + buffer on the stack and pass it
  1037. * on to RTSocketSgWrite.
  1038. */
  1039. Assert(cSegs <= 16);
  1040. PRTSGSEG paSegs = (PRTSGSEG)alloca(cSegs * sizeof(RTSGSEG));
  1041. AssertReturn(paSegs, VERR_NO_TMP_MEMORY);
  1042. for (size_t i = 0; i < cSegs; i++)
  1043. {
  1044. paSegs[i].pvSeg = va_arg(va, void *);
  1045. paSegs[i].cbSeg = va_arg(va, size_t);
  1046. }
  1047. RTSGBUF SgBuf;
  1048. RTSgBufInit(&SgBuf, paSegs, cSegs);
  1049. return RTSocketSgWrite(hSocket, &SgBuf);
  1050. }
  1051. RTDECL(int) RTSocketReadNB(RTSOCKET hSocket, void *pvBuffer, size_t cbBuffer, size_t *pcbRead)
  1052. {
  1053. /*
  1054. * Validate input.
  1055. */
  1056. RTSOCKETINT *pThis = hSocket;
  1057. AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
  1058. AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE);
  1059. AssertReturn(cbBuffer > 0, VERR_INVALID_PARAMETER);
  1060. AssertPtr(pvBuffer);
  1061. AssertPtrReturn(pcbRead, VERR_INVALID_PARAMETER);
  1062. AssertReturn(rtSocketTryLock(pThis), VERR_CONCURRENT_ACCESS);
  1063. int rc = rtSocketSwitchBlockingMode(pThis, false /* fBlocking */);
  1064. if (RT_FAILURE(rc))
  1065. return rc;
  1066. rtSocketErrorReset();
  1067. #ifdef RT_OS_WINDOWS
  1068. int cbNow = cbBuffer >= INT_MAX/2 ? INT_MAX/2 : (int)cbBuffer;
  1069. int cbRead = recv(pThis->hNative, (char *)pvBuffer, cbNow, MSG_NOSIGNAL);
  1070. if (cbRead >= 0)
  1071. {
  1072. *pcbRead = cbRead;
  1073. rc = VINF_SUCCESS;
  1074. }
  1075. else
  1076. rc = rtSocketError();
  1077. if (rc == VERR_TRY_AGAIN)
  1078. rc = VINF_TRY_AGAIN;
  1079. #else
  1080. ssize_t cbRead = recv(pThis->hNative, pvBuffer, cbBuffer, MSG_NOSIGNAL);
  1081. if (cbRead >= 0)
  1082. *pcbRead = cbRead;
  1083. else if (errno == EAGAIN)
  1084. {
  1085. *pcbRead = 0;
  1086. rc = VINF_TRY_AGAIN;
  1087. }
  1088. else
  1089. rc = rtSocketError();
  1090. #endif
  1091. rtSocketUnlock(pThis);
  1092. return rc;
  1093. }
  1094. RTDECL(int) RTSocketWriteNB(RTSOCKET hSocket, const void *pvBuffer, size_t cbBuffer, size_t *pcbWritten)
  1095. {
  1096. /*
  1097. * Validate input.
  1098. */
  1099. RTSOCKETINT *pThis = hSocket;
  1100. AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
  1101. AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE);
  1102. AssertPtrReturn(pcbWritten, VERR_INVALID_PARAMETER);
  1103. AssertReturn(rtSocketTryLock(pThis), VERR_CONCURRENT_ACCESS);
  1104. int rc = rtSocketSwitchBlockingMode(pThis, false /* fBlocking */);
  1105. if (RT_FAILURE(rc))
  1106. return rc;
  1107. rtSocketErrorReset();
  1108. #ifdef RT_OS_WINDOWS
  1109. int cbNow = RT_MIN((int)cbBuffer, INT_MAX/2);
  1110. int cbWritten = send(pThis->hNative, (const char *)pvBuffer, cbNow, MSG_NOSIGNAL);
  1111. if (cbWritten >= 0)
  1112. {
  1113. *pcbWritten = cbWritten;
  1114. rc = VINF_SUCCESS;
  1115. }
  1116. else
  1117. rc = rtSocketError();
  1118. if (rc == VERR_TRY_AGAIN)
  1119. rc = VINF_TRY_AGAIN;
  1120. #else
  1121. ssize_t cbWritten = send(pThis->hNative, pvBuffer, cbBuffer, MSG_NOSIGNAL);
  1122. if (cbWritten >= 0)
  1123. *pcbWritten = cbWritten;
  1124. else if (errno == EAGAIN)
  1125. {
  1126. *pcbWritten = 0;
  1127. rc = VINF_TRY_AGAIN;
  1128. }
  1129. else
  1130. rc = rtSocketError();
  1131. #endif
  1132. rtSocketUnlock(pThis);
  1133. return rc;
  1134. }
  1135. RTDECL(int) RTSocketSgWriteNB(RTSOCKET hSocket, PCRTSGBUF pSgBuf, size_t *pcbWritten)
  1136. {
  1137. /*
  1138. * Validate input.
  1139. */
  1140. RTSOCKETINT *pThis = hSocket;
  1141. AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
  1142. AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE);
  1143. AssertPtrReturn(pSgBuf, VERR_INVALID_PARAMETER);
  1144. AssertPtrReturn(pcbWritten, VERR_INVALID_PARAMETER);
  1145. AssertReturn(pSgBuf->cSegs > 0, VERR_INVALID_PARAMETER);
  1146. AssertReturn(rtSocketTryLock(pThis), VERR_CONCURRENT_ACCESS);
  1147. int rc = rtSocketSwitchBlockingMode(pThis, false /* fBlocking */);
  1148. if (RT_FAILURE(rc))
  1149. return rc;
  1150. unsigned cSegsToSend = 0;
  1151. rc = VERR_NO_TMP_MEMORY;
  1152. #ifdef RT_OS_WINDOWS
  1153. LPWSABUF paMsg = NULL;
  1154. RTSgBufMapToNative(paMsg, pSgBuf, WSABUF, buf, char *, len, u_long, cSegsToSend);
  1155. if (paMsg)
  1156. {
  1157. DWORD dwSent = 0;
  1158. int hrc = WSASend(pThis->hNative, paMsg, cSegsToSend, &dwSent,
  1159. MSG_NOSIGNAL, NULL, NULL);
  1160. if (!hrc)
  1161. rc = VINF_SUCCESS;
  1162. else
  1163. rc = rtSocketError();
  1164. *pcbWritten = dwSent;
  1165. RTMemTmpFree(paMsg);
  1166. }
  1167. #else /* !RT_OS_WINDOWS */
  1168. struct iovec *paMsg = NULL;
  1169. RTSgBufMapToNative(paMsg, pSgBuf, struct iovec, iov_base, void *, iov_len, size_t, cSegsToSend);
  1170. if (paMsg)
  1171. {
  1172. struct msghdr msgHdr;
  1173. RT_ZERO(msgHdr);
  1174. msgHdr.msg_iov = paMsg;
  1175. msgHdr.msg_iovlen = cSegsToSend;
  1176. ssize_t cbWritten = sendmsg(pThis->hNative, &msgHdr, MSG_NOSIGNAL);
  1177. if (RT_LIKELY(cbWritten >= 0))
  1178. {
  1179. rc = VINF_SUCCESS;
  1180. *pcbWritten = cbWritten;
  1181. }
  1182. else
  1183. rc = rtSocketError();
  1184. RTMemTmpFree(paMsg);
  1185. }
  1186. #endif /* !RT_OS_WINDOWS */
  1187. rtSocketUnlock(pThis);
  1188. return rc;
  1189. }
  1190. RTDECL(int) RTSocketSgWriteLNB(RTSOCKET hSocket, size_t cSegs, size_t *pcbWritten, ...)
  1191. {
  1192. va_list va;
  1193. va_start(va, pcbWritten);
  1194. int rc = RTSocketSgWriteLVNB(hSocket, cSegs, pcbWritten, va);
  1195. va_end(va);
  1196. return rc;
  1197. }
  1198. RTDECL(int) RTSocketSgWriteLVNB(RTSOCKET hSocket, size_t cSegs, size_t *pcbWritten, va_list va)
  1199. {
  1200. /*
  1201. * Set up a S/G segment array + buffer on the stack and pass it
  1202. * on to RTSocketSgWrite.
  1203. */
  1204. Assert(cSegs <= 16);
  1205. PRTSGSEG paSegs = (PRTSGSEG)alloca(cSegs * sizeof(RTSGSEG));
  1206. AssertReturn(paSegs, VERR_NO_TMP_MEMORY);
  1207. for (size_t i = 0; i < cSegs; i++)
  1208. {
  1209. paSegs[i].pvSeg = va_arg(va, void *);
  1210. paSegs[i].cbSeg = va_arg(va, size_t);
  1211. }
  1212. RTSGBUF SgBuf;
  1213. RTSgBufInit(&SgBuf, paSegs, cSegs);
  1214. return RTSocketSgWriteNB(hSocket, &SgBuf, pcbWritten);
  1215. }
  1216. RTDECL(int) RTSocketSelectOne(RTSOCKET hSocket, RTMSINTERVAL cMillies)
  1217. {
  1218. /*
  1219. * Validate input.
  1220. */
  1221. RTSOCKETINT *pThis = hSocket;
  1222. AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
  1223. AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE);
  1224. AssertReturn(RTMemPoolRefCount(pThis) >= (pThis->cUsers ? 2U : 1U), VERR_CALLER_NO_REFERENCE);
  1225. int const fdMax = (int)pThis->hNative + 1;
  1226. AssertReturn(fdMax - 1 == pThis->hNative, VERR_INTERNAL_ERROR_5);
  1227. /*
  1228. * Set up the file descriptor sets and do the select.
  1229. */
  1230. fd_set fdsetR;
  1231. FD_ZERO(&fdsetR);
  1232. FD_SET(pThis->hNative, &fdsetR);
  1233. fd_set fdsetE = fdsetR;
  1234. int rc;
  1235. if (cMillies == RT_INDEFINITE_WAIT)
  1236. rc = select(fdMax, &fdsetR, NULL, &fdsetE, NULL);
  1237. else
  1238. {
  1239. struct timeval timeout;
  1240. timeout.tv_sec = cMillies / 1000;
  1241. timeout.tv_usec = (cMillies % 1000) * 1000;
  1242. rc = select(fdMax, &fdsetR, NULL, &fdsetE, &timeout);
  1243. }
  1244. if (rc > 0)
  1245. rc = VINF_SUCCESS;
  1246. else if (rc == 0)
  1247. rc = VERR_TIMEOUT;
  1248. else
  1249. rc = rtSocketError();
  1250. return rc;
  1251. }
  1252. RTDECL(int) RTSocketSelectOneEx(RTSOCKET hSocket, uint32_t fEvents, uint32_t *pfEvents,
  1253. RTMSINTERVAL cMillies)
  1254. {
  1255. /*
  1256. * Validate input.
  1257. */
  1258. RTSOCKETINT *pThis = hSocket;
  1259. AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
  1260. AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE);
  1261. AssertPtrReturn(pfEvents, VERR_INVALID_PARAMETER);
  1262. AssertReturn(!(fEvents & ~RTSOCKET_EVT_VALID_MASK), VERR_INVALID_PARAMETER);
  1263. AssertReturn(RTMemPoolRefCount(pThis) >= (pThis->cUsers ? 2U : 1U), VERR_CALLER_NO_REFERENCE);
  1264. int const fdMax = (int)pThis->hNative + 1;
  1265. AssertReturn(fdMax - 1 == pThis->hNative, VERR_INTERNAL_ERROR_5);
  1266. *pfEvents = 0;
  1267. /*
  1268. * Set up the file descriptor sets and do the select.
  1269. */
  1270. fd_set fdsetR;
  1271. fd_set fdsetW;
  1272. fd_set fdsetE;
  1273. FD_ZERO(&fdsetR);
  1274. FD_ZERO(&fdsetW);
  1275. FD_ZERO(&fdsetE);
  1276. if (fEvents & RTSOCKET_EVT_READ)
  1277. FD_SET(pThis->hNative, &fdsetR);
  1278. if (fEvents & RTSOCKET_EVT_WRITE)
  1279. FD_SET(pThis->hNative, &fdsetW);
  1280. if (fEvents & RTSOCKET_EVT_ERROR)
  1281. FD_SET(pThis->hNative, &fdsetE);
  1282. int rc;
  1283. if (cMillies == RT_INDEFINITE_WAIT)
  1284. rc = select(fdMax, &fdsetR, &fdsetW, &fdsetE, NULL);
  1285. else
  1286. {
  1287. struct timeval timeout;
  1288. timeout.tv_sec = cMillies / 1000;
  1289. timeout.tv_usec = (cMillies % 1000) * 1000;
  1290. rc = select(fdMax, &fdsetR, &fdsetW, &fdsetE, &timeout);
  1291. }
  1292. if (rc > 0)
  1293. {
  1294. if (FD_ISSET(pThis->hNative, &fdsetR))
  1295. *pfEvents |= RTSOCKET_EVT_READ;
  1296. if (FD_ISSET(pThis->hNative, &fdsetW))
  1297. *pfEvents |= RTSOCKET_EVT_WRITE;
  1298. if (FD_ISSET(pThis->hNative, &fdsetE))
  1299. *pfEvents |= RTSOCKET_EVT_ERROR;
  1300. rc = VINF_SUCCESS;
  1301. }
  1302. else if (rc == 0)
  1303. rc = VERR_TIMEOUT;
  1304. else
  1305. rc = rtSocketError();
  1306. return rc;
  1307. }
  1308. RTDECL(int) RTSocketShutdown(RTSOCKET hSocket, bool fRead, bool fWrite)
  1309. {
  1310. /*
  1311. * Validate input, don't lock it because we might want to interrupt a call
  1312. * active on a different thread.
  1313. */
  1314. RTSOCKETINT *pThis = hSocket;
  1315. AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
  1316. AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE);
  1317. AssertReturn(RTMemPoolRefCount(pThis) >= (pThis->cUsers ? 2U : 1U), VERR_CALLER_NO_REFERENCE);
  1318. AssertReturn(fRead || fWrite, VERR_INVALID_PARAMETER);
  1319. /*
  1320. * Do the job.
  1321. */
  1322. int rc = VINF_SUCCESS;
  1323. int fHow;
  1324. if (fRead && fWrite)
  1325. fHow = SHUT_RDWR;
  1326. else if (fRead)
  1327. fHow = SHUT_RD;
  1328. else
  1329. fHow = SHUT_WR;
  1330. if (shutdown(pThis->hNative, fHow) == -1)
  1331. rc = rtSocketError();
  1332. return rc;
  1333. }
  1334. RTDECL(int) RTSocketGetLocalAddress(RTSOCKET hSocket, PRTNETADDR pAddr)
  1335. {
  1336. /*
  1337. * Validate input.
  1338. */
  1339. RTSOCKETINT *pThis = hSocket;
  1340. AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
  1341. AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE);
  1342. AssertReturn(RTMemPoolRefCount(pThis) >= (pThis->cUsers ? 2U : 1U), VERR_CALLER_NO_REFERENCE);
  1343. /*
  1344. * Get the address and convert it.
  1345. */
  1346. int rc;
  1347. RTSOCKADDRUNION u;
  1348. #ifdef RT_OS_WINDOWS
  1349. int cbAddr = sizeof(u);
  1350. #else
  1351. socklen_t cbAddr = sizeof(u);
  1352. #endif
  1353. RT_ZERO(u);
  1354. if (getsockname(pThis->hNative, &u.Addr, &cbAddr) == 0)
  1355. rc = rtSocketNetAddrFromAddr(&u, cbAddr, pAddr);
  1356. else
  1357. rc = rtSocketError();
  1358. return rc;
  1359. }
  1360. RTDECL(int) RTSocketGetPeerAddress(RTSOCKET hSocket, PRTNETADDR pAddr)
  1361. {
  1362. /*
  1363. * Validate input.
  1364. */
  1365. RTSOCKETINT *pThis = hSocket;
  1366. AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
  1367. AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE);
  1368. AssertReturn(RTMemPoolRefCount(pThis) >= (pThis->cUsers ? 2U : 1U), VERR_CALLER_NO_REFERENCE);
  1369. /*
  1370. * Get the address and convert it.
  1371. */
  1372. int rc;
  1373. RTSOCKADDRUNION u;
  1374. #ifdef RT_OS_WINDOWS
  1375. int cbAddr = sizeof(u);
  1376. #else
  1377. socklen_t cbAddr = sizeof(u);
  1378. #endif
  1379. RT_ZERO(u);
  1380. if (getpeername(pThis->hNative, &u.Addr, &cbAddr) == 0)
  1381. rc = rtSocketNetAddrFromAddr(&u, cbAddr, pAddr);
  1382. else
  1383. rc = rtSocketError();
  1384. return rc;
  1385. }
  1386. /**
  1387. * Wrapper around bind.
  1388. *
  1389. * @returns IPRT status code.
  1390. * @param hSocket The socket handle.
  1391. * @param pAddr The address to bind to.
  1392. */
  1393. int rtSocketBind(RTSOCKET hSocket, PCRTNETADDR pAddr)
  1394. {
  1395. /*
  1396. * Validate input.
  1397. */
  1398. RTSOCKETINT *pThis = hSocket;
  1399. AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
  1400. AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE);
  1401. AssertReturn(rtSocketTryLock(pThis), VERR_CONCURRENT_ACCESS);
  1402. RTSOCKADDRUNION u;
  1403. int cbAddr;
  1404. int rc = rtSocketAddrFromNetAddr(pAddr, &u, sizeof(u), &cbAddr);
  1405. if (RT_SUCCESS(rc))
  1406. {
  1407. if (bind(pThis->hNative, &u.Addr, cbAddr) != 0)
  1408. rc = rtSocketError();
  1409. }
  1410. rtSocketUnlock(pThis);
  1411. return rc;
  1412. }
  1413. /**
  1414. * Wrapper around listen.
  1415. *
  1416. * @returns IPRT status code.
  1417. * @param hSocket The socket handle.
  1418. * @param cMaxPending The max number of pending connections.
  1419. */
  1420. int rtSocketListen(RTSOCKET hSocket, int cMaxPending)
  1421. {
  1422. /*
  1423. * Validate input.
  1424. */
  1425. RTSOCKETINT *pThis = hSocket;
  1426. AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
  1427. AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE);
  1428. AssertReturn(rtSocketTryLock(pThis), VERR_CONCURRENT_ACCESS);
  1429. int rc = VINF_SUCCESS;
  1430. if (listen(pThis->hNative, cMaxPending) != 0)
  1431. rc = rtSocketError();
  1432. rtSocketUnlock(pThis);
  1433. return rc;
  1434. }
  1435. /**
  1436. * Wrapper around accept.
  1437. *
  1438. * @returns IPRT status code.
  1439. * @param hSocket The socket handle.
  1440. * @param phClient Where to return the client socket handle on
  1441. * success.
  1442. * @param pAddr Where to return the client address.
  1443. * @param pcbAddr On input this gives the size buffer size of what
  1444. * @a pAddr point to. On return this contains the
  1445. * size of what's stored at @a pAddr.
  1446. */
  1447. int rtSocketAccept(RTSOCKET hSocket, PRTSOCKET phClient, struct sockaddr *pAddr, size_t *pcbAddr)
  1448. {
  1449. /*
  1450. * Validate input.
  1451. * Only lock the socket temporarily while we get the native handle, so that
  1452. * we can safely shutdown and destroy the socket from a different thread.
  1453. */
  1454. RTSOCKETINT *pThis = hSocket;
  1455. AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
  1456. AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE);
  1457. AssertReturn(rtSocketTryLock(pThis), VERR_CONCURRENT_ACCESS);
  1458. /*
  1459. * Call accept().
  1460. */
  1461. rtSocketErrorReset();
  1462. int rc = VINF_SUCCESS;
  1463. #ifdef RT_OS_WINDOWS
  1464. int cbAddr = (int)*pcbAddr;
  1465. #else
  1466. socklen_t cbAddr = *pcbAddr;
  1467. #endif
  1468. RTSOCKETNATIVE hNativeClient = accept(pThis->hNative, pAddr, &cbAddr);
  1469. if (hNativeClient != NIL_RTSOCKETNATIVE)
  1470. {
  1471. *pcbAddr = cbAddr;
  1472. /*
  1473. * Wrap the client socket.
  1474. */
  1475. rc = rtSocketCreateForNative(phClient, hNativeClient);
  1476. if (RT_FAILURE(rc))
  1477. {
  1478. #ifdef RT_OS_WINDOWS
  1479. closesocket(hNativeClient);
  1480. #else
  1481. close(hNativeClient);
  1482. #endif
  1483. }
  1484. }
  1485. else
  1486. rc = rtSocketError();
  1487. rtSocketUnlock(pThis);
  1488. return rc;
  1489. }
  1490. /**
  1491. * Wrapper around connect.
  1492. *
  1493. * @returns IPRT status code.
  1494. * @param hSocket The socket handle.
  1495. * @param pAddr The socket address to connect to.
  1496. */
  1497. int rtSocketConnect(RTSOCKET hSocket, PCRTNETADDR pAddr)
  1498. {
  1499. /*
  1500. * Validate input.
  1501. */
  1502. RTSOCKETINT *pThis = hSocket;
  1503. AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
  1504. AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE);
  1505. AssertReturn(rtSocketTryLock(pThis), VERR_CONCURRENT_ACCESS);
  1506. RTSOCKADDRUNION u;
  1507. int cbAddr;
  1508. int rc = rtSocketAddrFromNetAddr(pAddr, &u, sizeof(u), &cbAddr);
  1509. if (RT_SUCCESS(rc))
  1510. {
  1511. if (connect(pThis->hNative, &u.Addr, cbAddr) != 0)
  1512. rc = rtSocketError();
  1513. }
  1514. rtSocketUnlock(pThis);
  1515. return rc;
  1516. }
  1517. /**
  1518. * Wrapper around setsockopt.
  1519. *
  1520. * @returns IPRT status code.
  1521. * @param hSocket The socket handle.
  1522. * @param iLevel The protocol level, e.g. IPPORTO_TCP.
  1523. * @param iOption The option, e.g. TCP_NODELAY.
  1524. * @param pvValue The value buffer.
  1525. * @param cbValue The size of the value pointed to by pvValue.
  1526. */
  1527. int rtSocketSetOpt(RTSOCKET hSocket, int iLevel, int iOption, void const *pvValue, int cbValue)
  1528. {
  1529. /*
  1530. * Validate input.
  1531. */
  1532. RTSOCKETINT *pThis = hSocket;
  1533. AssertPtrReturn(pThis, VERR_INVALID_HANDLE);

Large files files are truncated, but you can click here to view the full file