Changeset 27497 in vbox
- Timestamp:
- Mar 18, 2010 6:59:08 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 6 edited
-
include/iprt/err.h (modified) (1 diff)
-
include/iprt/tcp.h (modified) (1 diff)
-
include/iprt/types.h (modified) (1 diff)
-
src/VBox/Devices/Serial/DrvNamedPipe.cpp (modified) (9 diffs)
-
src/VBox/Runtime/include/internal/magics.h (modified) (1 diff)
-
src/VBox/Runtime/r3/tcp.cpp (modified) (25 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/err.h
r27431 r27497 611 611 /** Status code, typically given as a parameter, that isn't supposed to be used. */ 612 612 #define VERR_IGNORED (-91) 613 /** Concurrent access to the object is not allowed. */ 614 #define VERR_CONCURRENT_ACCESS (-92) 613 615 /** @} */ 614 616 -
trunk/include/iprt/tcp.h
r26915 r27497 195 195 196 196 /** 197 * Send data froma socket.197 * Send data to a socket. 198 198 * 199 199 * @returns iprt status code. -
trunk/include/iprt/types.h
r26734 r27497 1249 1249 1250 1250 /** Socket handle. */ 1251 typedef intRTSOCKET;1251 typedef R3R0PTRTYPE(struct RTSOCKETINT *) RTSOCKET; 1252 1252 /** Pointer to socket handle. */ 1253 typedef RTSOCKET *PRTSOCKET;1253 typedef RTSOCKET *PRTSOCKET; 1254 1254 /** Nil socket handle. */ 1255 #define NIL_RTSOCKET ( ~(RTSOCKET)0)1255 #define NIL_RTSOCKET ((RTSOCKET)0) 1256 1256 1257 1257 /** Thread handle.*/ -
trunk/src/VBox/Devices/Serial/DrvNamedPipe.cpp
r26173 r27497 86 86 #else /* !RT_OS_WINDOWS */ 87 87 /** Socket handle of the local socket for server. */ 88 RTSOCKETLocalSocketServer;88 int LocalSocketServer; 89 89 /** Socket handle of the local socket. */ 90 RTSOCKETLocalSocket;90 int LocalSocket; 91 91 #endif /* !RT_OS_WINDOWS */ 92 92 /** Thread for listening for new connections. */ … … 170 170 } 171 171 #else /* !RT_OS_WINDOWS */ 172 if (pThis->LocalSocket != NIL_RTSOCKET)172 if (pThis->LocalSocket != -1) 173 173 { 174 174 ssize_t cbReallyRead; … … 176 176 if (cbReallyRead == 0) 177 177 { 178 RTSOCKETtmp = pThis->LocalSocket;179 pThis->LocalSocket = NIL_RTSOCKET;178 int tmp = pThis->LocalSocket; 179 pThis->LocalSocket = -1; 180 180 close(tmp); 181 181 } … … 256 256 } 257 257 #else /* !RT_OS_WINDOWS */ 258 if (pThis->LocalSocket != NIL_RTSOCKET)258 if (pThis->LocalSocket != -1) 259 259 { 260 260 ssize_t cbWritten; … … 262 262 if (cbWritten == 0) 263 263 { 264 RTSOCKETtmp = pThis->LocalSocket;265 pThis->LocalSocket = NIL_RTSOCKET;264 int tmp = pThis->LocalSocket; 265 pThis->LocalSocket = -1; 266 266 close(tmp); 267 267 } … … 365 365 else 366 366 { 367 if (pThis->LocalSocket != NIL_RTSOCKET)367 if (pThis->LocalSocket != -1) 368 368 { 369 369 LogRel(("NamedPipe%d: only single connection supported\n", pThis->pDrvIns->iInstance)); … … 422 422 if (pThis->fIsServer) 423 423 { 424 if (pThis->LocalSocketServer != NIL_RTSOCKET) 424 if (pThis->LocalSocketServer != -1) 425 { 425 426 close(pThis->LocalSocketServer); 427 pThis->LocalSocketServer = -1; 428 } 426 429 if (pThis->pszLocation) 427 430 RTFileDelete(pThis->pszLocation); … … 429 432 else 430 433 { 431 if (pThis->LocalSocket != NIL_RTSOCKET) 434 if (pThis->LocalSocket != -1) 435 { 432 436 close(pThis->LocalSocket); 437 pThis->LocalSocket = -1; 438 } 433 439 } 434 440 #endif /* !RT_OS_WINDOWS */ … … 482 488 pThis->NamedPipe = INVALID_HANDLE_VALUE; 483 489 #else /* !RT_OS_WINDOWS */ 484 pThis->LocalSocketServer = NIL_RTSOCKET;485 pThis->LocalSocket = NIL_RTSOCKET;490 pThis->LocalSocketServer = -1; 491 pThis->LocalSocket = -1; 486 492 #endif /* !RT_OS_WINDOWS */ 487 493 pThis->ListenThread = NIL_RTTHREAD; -
trunk/src/VBox/Runtime/include/internal/magics.h
r26801 r27497 127 127 /** RTSEMXROADSINTERNAL::u32Magic value after RTSemXRoadsDestroy. */ 128 128 #define RTSEMXROADS_MAGIC_DEAD UINT32_C(0x20011110) 129 /** The magic value for RTSOCKETINT::u32Magic. (Stanislaw Lem) */ 130 #define RTSOCKET_MAGIC UINT32_C(0x19210912) 131 /** The magic value for RTSOCKETINT::u32Magic after destruction. */ 132 #define RTSOCKET_MAGIC_DEAD UINT32_C(0x20060326) 129 133 /** Magic value for RTSPINLOCKINTERNAL::u32Magic. (Terry Pratchett) */ 130 134 #define RTSPINLOCK_MAGIC UINT32_C(0x19480428) -
trunk/src/VBox/Runtime/r3/tcp.cpp
r27288 r27497 59 59 #include <iprt/err.h> 60 60 #include <iprt/mempool.h> 61 #include <iprt/mem.h> 61 62 #include <iprt/string.h> 62 63 #include <iprt/thread.h> … … 100 101 * Structures and Typedefs * 101 102 *******************************************************************************/ 103 /** 104 * Socket handle data. 105 * 106 * This is mainly required for implementing RTPollSet on Windows. 107 */ 108 typedef struct RTSOCKETINT 109 { 110 /** Magic number (RTTCPSOCKET_MAGIC). */ 111 uint32_t u32Magic; 112 /** Usage count. This is used to prevent two threads from accessing the 113 * handle concurrently. */ 114 uint32_t volatile cUsers; 115 #ifdef RT_OS_WINDOWS 116 /** The native socket handle. */ 117 SOCKET hNative; 118 /** The event semaphore we've associated with the socket handle. 119 * This is INVALID_HANDLE_VALUE if not done. */ 120 WSAEVENT hEvent; 121 /** The pollset currently polling this socket. This is NIL if no one is 122 * polling. */ 123 RTPOLLSET hPollSet; 124 /** The events we're polling for. */ 125 uint32_t fPollEvts; 126 #else 127 /** The native socket handle. */ 128 int hNative; 129 #endif 130 } RTSOCKETINT; 131 132 133 /** 134 * Address union used internally for things like getpeername and getsockname. 135 */ 136 typedef union RTSOCKADDRUNION 137 { 138 struct sockaddr Addr; 139 struct sockaddr_in Ipv4; 140 #ifdef IPRT_WITH_TCPIP_V6 141 struct sockaddr_in6 Ipv6; 142 #endif 143 } RTSOCKADDRUNION; 144 145 146 102 147 /** 103 148 * TCP Server state. … … 145 190 } RTTCPSERVER; 146 191 147 typedef union RTSOCKADDRUNION148 {149 struct sockaddr Addr;150 struct sockaddr_in Ipv4;151 #ifdef IPRT_WITH_TCPIP_V6152 struct sockaddr_in6 Ipv6;153 #endif154 } RTSOCKADDRUNION;155 192 156 193 /******************************************************************************* … … 162 199 static int rtTcpServerDestroySocket(RTSOCKET volatile *pSockClient, const char *pszMsg); 163 200 static int rtTcpClose(RTSOCKET Sock, const char *pszMsg, bool fTryGracefulShutdown); 164 static int rtTcpConvertAddress(RTSOCKADDRUNION *pSrc, size_t cbSrc, PRTNETADDR pAddr);165 201 166 202 … … 169 205 * Get the last error as an iprt status code. 170 206 * 171 * @returns iprtstatus code.172 */ 173 DECLINLINE(int) rt TcpError(void)207 * @returns IPRT status code. 208 */ 209 DECLINLINE(int) rtSocketError(void) 174 210 { 175 211 #ifdef RT_OS_WINDOWS … … 184 220 * Resets the last error. 185 221 */ 186 DECLINLINE(void) rt TcpErrorReset(void)222 DECLINLINE(void) rtSocketErrorReset(void) 187 223 { 188 224 #ifdef RT_OS_WINDOWS … … 199 235 * @returns iprt status code. 200 236 */ 201 DECLINLINE(int) rt TcpResolverError(void)237 DECLINLINE(int) rtSocketResolverError(void) 202 238 { 203 239 #ifdef RT_OS_WINDOWS … … 223 259 224 260 /** 261 * Tries to lock the socket for exclusive usage by the calling thread. 262 * 263 * Call rtSocketUnlock() to unlock. 264 * 265 * @returns @c true if locked, @c false if not. 266 * @param pThis The socket structure. 267 */ 268 DECLINLINE(bool) rtSocketTryLock(RTSOCKETINT *pThis) 269 { 270 return ASMAtomicCmpXchgU32(&pThis->cUsers, 1, 0); 271 } 272 273 274 /** 275 * Unlocks the socket. 276 * 277 * @param pThis The socket structure. 278 */ 279 DECLINLINE(void) rtSocketUnlock(RTSOCKETINT *pThis) 280 { 281 ASMAtomicCmpXchgU32(&pThis->cUsers, 0, 1); 282 } 283 284 285 /** 286 * Creates an IPRT socket handle for a native one. 287 * 288 * @returns IPRT status code. 289 * @param ppSocket Where to return the IPRT socket handle. 290 * @param hNative The native handle. 291 */ 292 int rtSocketCreateForNative(RTSOCKETINT **ppSocket, 293 #ifdef RT_OS_WINDOWS 294 HANDLE hNative 295 #else 296 int hNative 297 #endif 298 ) 299 { 300 RTSOCKETINT *pThis = (RTSOCKETINT *)RTMemAlloc(sizeof(*pThis)); 301 if (!pThis) 302 return VERR_NO_MEMORY; 303 pThis->u32Magic = RTSOCKET_MAGIC; 304 pThis->cUsers = 0; 305 pThis->hNative = hNative; 306 #ifdef RT_OS_WINDOWS 307 pThis->hEvent = INVALID_HANDLE_VALUE; 308 pThis->hPollSet = 0; 309 pThis->fPollEvts = 0; 310 #endif 311 *ppSocket = pThis; 312 return VINF_SUCCESS; 313 } 314 315 316 /** 317 * Wrapper around socket(). 318 * 319 * @returns IPRT status code. 320 * @param phSocket Where to store the handle to the socket on 321 * success. 322 * @param iDomain The protocol family (PF_XXX). 323 * @param iType The socket type (SOCK_XXX). 324 * @param iProtocol Socket parameter, usually 0. 325 */ 326 static int rtSocketCreate(PRTSOCKET phSocket, int iDomain, int iType, int iProtocol) 327 { 328 /* 329 * Create the socket. 330 */ 331 #ifdef RT_OS_WINDOWS 332 SOCKET hNative = socket(iDomain, iType, iProtocol); 333 if (hNative == INVALID_SOCKET) 334 return rtSocketError(); 335 #else 336 int hNative = socket(iDomain, iType, iProtocol); 337 if (hNative == -1) 338 return rtSocketError(); 339 #endif 340 341 /* 342 * Wrap it. 343 */ 344 int rc = rtSocketCreateForNative(phSocket, hNative); 345 if (RT_FAILURE(rc)) 346 { 347 #ifdef RT_OS_WINDOWS 348 closesocket(hNative); 349 #else 350 close(hNative); 351 #endif 352 } 353 return rc; 354 } 355 356 357 /** 358 * Destroys the specified handle, freeing associated resources and closing the 359 * socket. 360 * 361 * @returns IPRT status code. 362 * @param hSocket The socket handle. NIL is ignored. 363 * 364 * @remarks This will not perform a graceful shutdown of the socket, it will 365 * just destroy it. Use the protocol specific close method if this is 366 * desired. 367 */ 368 int rtSocketDestroy(RTSOCKET hSocket) 369 { 370 RTSOCKETINT *pThis = hSocket; 371 if (pThis == NIL_RTSOCKET) 372 return VINF_SUCCESS; 373 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 374 AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE); 375 376 Assert(pThis->cUsers == 0); 377 AssertReturn(ASMAtomicCmpXchgU32(&pThis->u32Magic, RTSOCKET_MAGIC_DEAD, RTSOCKET_MAGIC), VERR_INVALID_HANDLE); 378 379 /* 380 * Do the cleanup. 381 */ 382 int rc = VINF_SUCCESS; 383 #ifdef RT_OS_WINDOWS 384 if (pThis->hEvent == INVALID_HANDLE_VALUE) 385 { 386 CloseHandle(pThis->hEvent); 387 pThis->hEvent = INVALID_HANDLE_VALUE; 388 } 389 390 if (pThis->hNative != INVALID_HANDLE_VALUE) 391 { 392 rc = closesocket(pThis->hNative); 393 if (!rc) 394 rc = VINF_SUCCESS; 395 else 396 { 397 rc = rtSocketError(); 398 AssertMsgFailed(("\"%s\": closesocket(%p) -> %Rrc\n", pThis->hNative, rc)); 399 } 400 pThis->hNative = INVALID_HANDLE_VALUE; 401 } 402 403 #else 404 if (pThis->hNative != -1) 405 { 406 if (close(pThis->hNative)) 407 { 408 rc = rtSocketError(); 409 AssertMsgFailed(("\"%s\": close(%d) -> %Rrc\n", pThis->hNative, rc)); 410 } 411 pThis->hNative = -1; 412 } 413 #endif 414 415 return rc; 416 } 417 418 419 /** 420 * Gets the native socket handle. 421 * 422 * @returns The native socket handle or RTHCUINTPTR_MAX if not invalid. 423 * @param hSocket The socket handle. 424 */ 425 RTHCUINTPTR rtSocketNative(RTSOCKET hSocket) 426 { 427 RTSOCKETINT *pThis = hSocket; 428 AssertPtrReturn(pThis, RTHCUINTPTR_MAX); 429 AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, RTHCUINTPTR_MAX); 430 return (RTHCUINTPTR)pThis->hNative; 431 } 432 433 434 /** 225 435 * Helper that ensures the correct inheritability of a socket. 226 436 * 227 437 * We're currently ignoring failures. 228 438 * 229 * @param Socket The socket handle. 439 * @returns IPRT status code 440 * @param hSocket The socket handle. 230 441 * @param fInheritable The desired inheritability state. 231 442 */ 232 static void rtTcpSetInheritance(RTSOCKET Socket, bool fInheritable) 233 { 234 #ifdef RT_OS_WINDOWS 235 /** @todo Find some magic way to change this... Worst case we have to use 236 * DuplicateHandle w/bInheritable=FALSE and replace the original 237 * handles... */ 443 int rtSocketSetInheritance(RTSOCKET hSocket, bool fInheritable) 444 { 445 RTSOCKETINT *pThis = hSocket; 446 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 447 AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE); 448 AssertReturn(rtSocketTryLock(pThis), VERR_CONCURRENT_ACCESS); 449 450 int rc = VINF_SUCCESS; 451 #ifdef RT_OS_WINDOWS 452 if (!SetHandleInformation(pThis->hNative, HANDLE_FLAG_INHERIT, fInheritable ? HANDLE_FLAG_INHERIT : 0)) 453 rc = RTErrConvertFromWin32(GetLastError()); 238 454 #else 239 fcntl(Socket, F_SETFD, fInheritable ? 0 : FD_CLOEXEC); 240 #endif 241 } 455 if (fcntl(pThis->hNative, F_SETFD, fInheritable ? 0 : FD_CLOEXEC) < 0) 456 rc = RTErrConvertFromErrno(errno); 457 #endif 458 AssertRC(rc); /// @todo remove later. 459 460 rtSocketUnlock(pThis); 461 return rc; 462 } 463 464 465 /** 466 * Receive data from a socket. 467 * 468 * @returns IPRT status code. 469 * @param hSocket The socket handle. 470 * @param pvBuffer Where to put the data we read. 471 * @param cbBuffer Read buffer size. 472 * @param pcbRead Number of bytes read. If NULL the entire buffer 473 * will be filled upon successful return. If not NULL a 474 * partial read can be done successfully. 475 */ 476 int rtSocketRead(RTSOCKET hSocket, void *pvBuffer, size_t cbBuffer, size_t *pcbRead) 477 { 478 /* 479 * Validate input. 480 */ 481 RTSOCKETINT *pThis = hSocket; 482 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 483 AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE); 484 AssertReturn(cbBuffer > 0, VERR_INVALID_PARAMETER); 485 AssertPtr(pvBuffer); 486 AssertReturn(rtSocketTryLock(pThis), VERR_CONCURRENT_ACCESS); 487 488 /* 489 * Read loop. 490 * If pcbRead is NULL we have to fill the entire buffer! 491 */ 492 int rc = VINF_SUCCESS; 493 size_t cbRead = 0; 494 size_t cbToRead = cbBuffer; 495 for (;;) 496 { 497 rtSocketErrorReset(); 498 #ifdef RT_OS_WINDOWS 499 int cbNow = cbToRead >= INT_MAX/2 ? INT_MAX/2 : (int)cbToRead; 500 #else 501 size_t cbNow = cbToRead; 502 #endif 503 ssize_t cbBytesRead = recv(pThis->hNative, (char *)pvBuffer + cbRead, cbNow, MSG_NOSIGNAL); 504 if (cbBytesRead <= 0) 505 { 506 rc = rtSocketError(); 507 Assert(RT_FAILURE_NP(rc) || cbBytesRead == 0); 508 if (RT_SUCCESS_NP(rc)) 509 { 510 if (!pcbRead) 511 rc = VERR_NET_SHUTDOWN; 512 else 513 { 514 *pcbRead = 0; 515 rc = VINF_SUCCESS; 516 } 517 } 518 break; 519 } 520 if (pcbRead) 521 { 522 /* return partial data */ 523 *pcbRead = cbBytesRead; 524 break; 525 } 526 527 /* read more? */ 528 cbRead += cbBytesRead; 529 if (cbRead == cbBuffer) 530 break; 531 532 /* next */ 533 cbToRead = cbBuffer - cbRead; 534 } 535 536 rtSocketUnlock(pThis); 537 return rc; 538 } 539 540 541 /** 542 * Send data to a socket. 543 * 544 * @returns IPRT status code. 545 * @retval VERR_INTERRUPTED if interrupted before anything was written. 546 * 547 * @param hSocket The socket handle. 548 * @param pvBuffer Buffer to write data to socket. 549 * @param cbBuffer How much to write. 550 */ 551 int rtSocketWrite(RTSOCKET hSocket, const void *pvBuffer, size_t cbBuffer) 552 { 553 /* 554 * Validate input. 555 */ 556 RTSOCKETINT *pThis = hSocket; 557 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 558 AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE); 559 AssertReturn(rtSocketTryLock(pThis), VERR_CONCURRENT_ACCESS); 560 561 /* 562 * Try write all at once. 563 */ 564 int rc = VINF_SUCCESS; 565 #ifdef RT_OS_WINDOWS 566 int cbNow = cbBuffer >= INT_MAX / 2 ? INT_MAX / 2 : (int)cbBuffer; 567 #else 568 size_t cbNow = cbBuffer >= SSIZE_MAX ? SSIZE_MAX : cbBuffer; 569 #endif 570 ssize_t cbWritten = send(pThis->hNative, (const char *)pvBuffer, cbNow, MSG_NOSIGNAL); 571 if (RT_LIKELY((size_t)cbWritten == cbBuffer && cbWritten >= 0)) 572 rc = VINF_SUCCESS; 573 else if (cbWritten < 0) 574 rc = rtSocketError(); 575 else 576 { 577 /* 578 * Unfinished business, write the remainder of the request. Must ignore 579 * VERR_INTERRUPTED here if we've managed to send something. 580 */ 581 size_t cbSentSoFar = 0; 582 for (;;) 583 { 584 /* advance */ 585 cbBuffer -= (size_t)cbWritten; 586 if (!cbBuffer) 587 break; 588 cbSentSoFar += (size_t)cbWritten; 589 pvBuffer = (char const *)pvBuffer + cbWritten; 590 591 /* send */ 592 #ifdef RT_OS_WINDOWS 593 cbNow = cbBuffer >= INT_MAX / 2 ? INT_MAX / 2 : (int)cbBuffer; 594 #else 595 cbNow = cbBuffer >= SSIZE_MAX ? SSIZE_MAX : cbBuffer; 596 #endif 597 cbWritten = send(pThis->hNative, (const char *)pvBuffer, cbNow, MSG_NOSIGNAL); 598 if (cbWritten >= 0) 599 AssertMsg(cbBuffer >= (size_t)cbWritten, ("Wrote more than we requested!!! cbWritten=%zu cbBuffer=%zu rtSocketError()=%d\n", 600 cbWritten, cbBuffer, rtSocketError())); 601 else 602 { 603 rc = rtSocketError(); 604 if (rc != VERR_INTERNAL_ERROR || cbSentSoFar == 0) 605 break; 606 cbWritten = 0; 607 rc = VINF_SUCCESS; 608 } 609 } 610 } 611 612 rtSocketUnlock(pThis); 613 return rc; 614 } 615 616 617 /** 618 * Checks if the socket is ready for reading (for I/O multiplexing). 619 * 620 * @returns IPRT status code. 621 * @param hSocket The socket handle. 622 * @param cMillies Number of milliseconds to wait for the socket. Use 623 * RT_INDEFINITE_WAIT to wait for ever. 624 */ 625 int rtSocketSelectOne(RTSOCKET hSocket, RTMSINTERVAL cMillies) 626 { 627 /* 628 * Validate input. 629 */ 630 RTSOCKETINT *pThis = hSocket; 631 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 632 AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE); 633 AssertReturn(rtSocketTryLock(pThis), VERR_CONCURRENT_ACCESS); 634 635 /* 636 * Set up the file descriptor sets and do the select. 637 */ 638 fd_set fdsetR; 639 FD_ZERO(&fdsetR); 640 FD_SET(pThis->hNative, &fdsetR); 641 642 fd_set fdsetE = fdsetR; 643 644 int rc; 645 if (cMillies == RT_INDEFINITE_WAIT) 646 rc = select(pThis->hNative + 1, &fdsetR, NULL, &fdsetE, NULL); 647 else 648 { 649 struct timeval timeout; 650 timeout.tv_sec = cMillies / 1000; 651 timeout.tv_usec = (cMillies % 1000) * 1000; 652 rc = select(pThis->hNative + 1, &fdsetR, NULL, &fdsetE, &timeout); 653 } 654 if (rc > 0) 655 rc = VINF_SUCCESS; 656 else if (rc == 0) 657 rc = VERR_TIMEOUT; 658 else 659 rc = rtSocketError(); 660 661 rtSocketUnlock(pThis); 662 return rc; 663 } 664 665 666 /** 667 * Shuts down one or both directions of communciation. 668 * 669 * @returns IPRT status code. 670 * @param hSocket The socket handle. 671 * @param fRead Whether to shutdown our read direction. 672 * @param fWrite Whether to shutdown our write direction. 673 */ 674 static int rtSocketShutdown(RTSOCKET hSocket, bool fRead, bool fWrite) 675 { 676 /* 677 * Validate input. 678 */ 679 RTSOCKETINT *pThis = hSocket; 680 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 681 AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE); 682 AssertReturn(fRead || fWrite, VERR_INVALID_PARAMETER); 683 AssertReturn(rtSocketTryLock(pThis), VERR_CONCURRENT_ACCESS); 684 685 /* 686 * Do the job. 687 */ 688 int rc = VINF_SUCCESS; 689 int fHow; 690 if (fRead && fWrite) 691 fHow = SHUT_RDWR; 692 else if (fRead) 693 fHow = SHUT_RD; 694 else 695 fHow = SHUT_WR; 696 if (shutdown(pThis->hNative, fHow) == -1) 697 rc = rtSocketError(); 698 699 rtSocketUnlock(pThis); 700 return rc; 701 } 702 703 704 /** 705 * Converts from a native socket address to a generic IPRT network address. 706 * 707 * @returns IPRT status code. 708 * @param pSrc The source address. 709 * @param cbSrc The size of the source address. 710 * @param pAddr Where to return the generic IPRT network 711 * address. 712 */ 713 static int rtSocketConvertAddress(RTSOCKADDRUNION const *pSrc, size_t cbSrc, PRTNETADDR pAddr) 714 { 715 /* 716 * Convert the address. 717 */ 718 if ( cbSrc == sizeof(struct sockaddr_in) 719 && pSrc->Addr.sa_family == AF_INET) 720 { 721 RT_ZERO(*pAddr); 722 pAddr->enmType = RTNETADDRTYPE_IPV4; 723 pAddr->uPort = RT_N2H_U16(pSrc->Ipv4.sin_port); 724 pAddr->uAddr.IPv4.u = pSrc->Ipv4.sin_addr.s_addr; 725 } 726 #ifdef IPRT_WITH_TCPIP_V6 727 else if ( cbSrc == sizeof(struct sockaddr_in6) 728 && pSrc->Addr.sa_family == AF_INET6) 729 { 730 RT_ZERO(*pAddr); 731 pAddr->enmType = RTNETADDRTYPE_IPV6; 732 pAddr->uPort = RT_N2H_U16(pSrc->Ipv6.sin6_port); 733 pAddr->uAddr.IPv6.au32[0] = pSrc->Ipv6.sin6_addr.s6_addr32[0]; 734 pAddr->uAddr.IPv6.au32[1] = pSrc->Ipv6.sin6_addr.s6_addr32[1]; 735 pAddr->uAddr.IPv6.au32[2] = pSrc->Ipv6.sin6_addr.s6_addr32[2]; 736 pAddr->uAddr.IPv6.au32[3] = pSrc->Ipv6.sin6_addr.s6_addr32[3]; 737 } 738 #endif 739 else 740 return VERR_NET_ADDRESS_FAMILY_NOT_SUPPORTED; 741 return VINF_SUCCESS; 742 } 743 744 745 /** 746 * Gets the address of the local side. 747 * 748 * @returns IPRT status code. 749 * @param Sock Socket descriptor. 750 * @param pAddr Where to store the local address on success. 751 */ 752 int rtSocketGetLocalAddress(RTSOCKET hSocket, PRTNETADDR pAddr) 753 { 754 /* 755 * Validate input. 756 */ 757 RTSOCKETINT *pThis = hSocket; 758 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 759 AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE); 760 AssertReturn(rtSocketTryLock(pThis), VERR_CONCURRENT_ACCESS); 761 762 /* 763 * Get the address and convert it. 764 */ 765 int rc; 766 RTSOCKADDRUNION u; 767 #ifdef RT_OS_WINDOWS 768 int cbAddr = sizeof(u); 769 #else 770 socklen_t cbAddr = sizeof(u); 771 #endif 772 RT_ZERO(u); 773 if (getsockname(pThis->hNative, &u.Addr, &cbAddr) == 0) 774 rc = rtSocketConvertAddress(&u, cbAddr, pAddr); 775 else 776 rc = rtSocketError(); 777 778 rtSocketUnlock(pThis); 779 return rc; 780 } 781 782 783 /** 784 * Gets the address of the other party. 785 * 786 * @returns IPRT status code. 787 * @param Sock Socket descriptor. 788 * @param pAddr Where to store the peer address on success. 789 */ 790 int rtSocketGetPeerAddress(RTSOCKET hSocket, PRTNETADDR pAddr) 791 { 792 /* 793 * Validate input. 794 */ 795 RTSOCKETINT *pThis = hSocket; 796 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 797 AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE); 798 AssertReturn(rtSocketTryLock(pThis), VERR_CONCURRENT_ACCESS); 799 800 /* 801 * Get the address and convert it. 802 */ 803 int rc; 804 RTSOCKADDRUNION u; 805 #ifdef RT_OS_WINDOWS 806 int cbAddr = sizeof(u); 807 #else 808 socklen_t cbAddr = sizeof(u); 809 #endif 810 RT_ZERO(u); 811 if (getpeername(pThis->hNative, &u.Addr, &cbAddr) == 0) 812 rc = rtSocketConvertAddress(&u, cbAddr, pAddr); 813 else 814 rc = rtSocketError(); 815 816 rtSocketUnlock(pThis); 817 return rc; 818 } 819 820 821 ///////////////////////////////////////////////////////////////////////////////// 822 823 824 /** 825 * Wrapper around bind. 826 * 827 * @returns IPRT status code. 828 * @param hSocket The socket handle. 829 * @param pAddr The socket address to bind to. 830 * @param cbAddr The size of the address structure @a pAddr 831 * points to. 832 */ 833 int rtSocketBind(RTSOCKET hSocket, const struct sockaddr *pAddr, int cbAddr) 834 { 835 /* 836 * Validate input. 837 */ 838 RTSOCKETINT *pThis = hSocket; 839 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 840 AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE); 841 AssertReturn(rtSocketTryLock(pThis), VERR_CONCURRENT_ACCESS); 842 843 int rc = VINF_SUCCESS; 844 if (bind(pThis->hNative, pAddr, cbAddr) != 0) 845 rc = rtSocketError(); 846 847 rtSocketUnlock(pThis); 848 return rc; 849 } 850 851 852 /** 853 * Wrapper around listen. 854 * 855 * @returns IPRT status code. 856 * @param hSocket The socket handle. 857 * @param cMaxPending The max number of pending connections. 858 */ 859 int rtSocketListen(RTSOCKET hSocket, int cMaxPending) 860 { 861 /* 862 * Validate input. 863 */ 864 RTSOCKETINT *pThis = hSocket; 865 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 866 AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE); 867 AssertReturn(rtSocketTryLock(pThis), VERR_CONCURRENT_ACCESS); 868 869 int rc = VINF_SUCCESS; 870 if (listen(pThis->hNative, cMaxPending) != 0) 871 rc = rtSocketError(); 872 873 rtSocketUnlock(pThis); 874 return rc; 875 } 876 877 878 /** 879 * Wrapper around accept. 880 * 881 * @returns IPRT status code. 882 * @param hSocket The socket handle. 883 * @param phClient Where to return the client socket handle on 884 * success. 885 * @param pAddr Where to return the client address. 886 * @param pcbAddr On input this gives the size buffer size of what 887 * @a pAddr point to. On return this contains the 888 * size of what's stored at @a pAddr. 889 */ 890 int rtSocketAccept(RTSOCKET hSocket, PRTSOCKET phClient, struct sockaddr *pAddr, size_t *pcbAddr) 891 { 892 /* 893 * Validate input. 894 */ 895 RTSOCKETINT *pThis = hSocket; 896 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 897 AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE); 898 AssertReturn(rtSocketTryLock(pThis), VERR_CONCURRENT_ACCESS); 899 900 /* 901 * Call accept(). 902 */ 903 rtSocketErrorReset(); 904 int rc = VINF_SUCCESS; 905 #ifdef RT_OS_WINDOWS 906 int cbAddr = (int)*pcbAddr; 907 SOCKET hNative = accept(pThis->hNative, pAddr, &cbAddr); 908 if (hNative != INVALID_SOCKET) 909 #else 910 socklen_t cbAddr = *pcbAddr; 911 int hNative = accept(pThis->hNative, pAddr, &cbAddr); 912 if (hNative != -1) 913 #endif 914 { 915 *pcbAddr = cbAddr; 916 917 /* 918 * Wrap the client socket. 919 */ 920 rc = rtSocketCreateForNative(phClient, hNative); 921 if (RT_FAILURE(rc)) 922 { 923 #ifdef RT_OS_WINDOWS 924 closesocket(hNative); 925 #else 926 close(hNative); 927 #endif 928 } 929 } 930 else 931 rc = rtSocketError(); 932 933 rtSocketUnlock(pThis); 934 return rc; 935 } 936 937 938 /** 939 * Wrapper around connect. 940 * 941 * @returns IPRT status code. 942 * @param hSocket The socket handle. 943 * @param pAddr The socket address to connect to. 944 * @param cbAddr The size of the address structure @a pAddr 945 * points to. 946 */ 947 int rtSocketConnect(RTSOCKET hSocket, const struct sockaddr *pAddr, int cbAddr) 948 { 949 /* 950 * Validate input. 951 */ 952 RTSOCKETINT *pThis = hSocket; 953 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 954 AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE); 955 AssertReturn(rtSocketTryLock(pThis), VERR_CONCURRENT_ACCESS); 956 957 int rc = VINF_SUCCESS; 958 if (connect(pThis->hNative, pAddr, cbAddr) != 0) 959 rc = rtSocketError(); 960 961 rtSocketUnlock(pThis); 962 return rc; 963 } 964 965 966 /** 967 * Wrapper around setsockopt. 968 * 969 * @returns IPRT status code. 970 * @param hSocket The socket handle. 971 * @param iLevel The protocol level, e.g. IPPORTO_TCP. 972 * @param iOption The option, e.g. TCP_NODELAY. 973 * @param pvValue The value buffer. 974 * @param cbValue The size of the value pointed to by pvValue. 975 */ 976 int rtSocketSetOpt(RTSOCKET hSocket, int iLevel, int iOption, void const *pvValue, int cbValue) 977 { 978 /* 979 * Validate input. 980 */ 981 RTSOCKETINT *pThis = hSocket; 982 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 983 AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE); 984 AssertReturn(rtSocketTryLock(pThis), VERR_CONCURRENT_ACCESS); 985 986 int rc = VINF_SUCCESS; 987 if (setsockopt(pThis->hNative, iLevel, iOption, (const char *)pvValue, cbValue) != 0) 988 rc = rtSocketError(); 989 990 rtSocketUnlock(pThis); 991 return rc; 992 } 993 994 995 996 ///////////////////////////////////////////////////////////////////////////////// 997 ///////////////////////////////////////////////////////////////////////////////// 998 ///////////////////////////////////////////////////////////////////////////////// 999 ///////////////////////////////////////////////////////////////////////////////// 1000 ///////////////////////////////////////////////////////////////////////////////// 1001 242 1002 243 1003 … … 280 1040 } 281 1041 1042 282 1043 /** 283 1044 * Closes the a socket (client or server). … … 287 1048 static int rtTcpServerDestroySocket(RTSOCKET volatile *pSock, const char *pszMsg, bool fTryGracefulShutdown) 288 1049 { 289 RTSOCKET Sock= rtTcpAtomicXchgSock(pSock, NIL_RTSOCKET);290 if ( Sock!= NIL_RTSOCKET)1050 RTSOCKET hSocket = rtTcpAtomicXchgSock(pSock, NIL_RTSOCKET); 1051 if (hSocket != NIL_RTSOCKET) 291 1052 { 292 1053 if (!fTryGracefulShutdown) 293 shutdown(Sock, SHUT_RDWR);294 return rtTcpClose( Sock, pszMsg, fTryGracefulShutdown);1054 rtSocketShutdown(hSocket, true /*fRead*/, true /*fWrite*/); 1055 return rtTcpClose(hSocket, pszMsg, fTryGracefulShutdown); 295 1056 } 296 1057 return VINF_TCP_SERVER_NO_CLIENT; … … 433 1194 if (!pHostEnt) 434 1195 { 435 rc = rt TcpResolverError();1196 rc = rtSocketResolverError(); 436 1197 AssertMsgFailed(("Could not get host address rc=%Rrc\n", rc)); 437 1198 return rc; … … 443 1204 * Setting up socket. 444 1205 */ 445 RTSOCKET WaitSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 446 if (WaitSock != -1) 447 { 448 rtTcpSetInheritance(WaitSock, false /*fInheritable*/); 1206 RTSOCKET WaitSock; 1207 rc = rtSocketCreate(&WaitSock, AF_INET, SOCK_STREAM, IPPROTO_TCP); 1208 if (RT_SUCCESS(rc)) 1209 { 1210 rtSocketSetInheritance(WaitSock, false /*fInheritable*/); 449 1211 450 1212 /* … … 452 1214 */ 453 1215 int fFlag = 1; 454 if (! setsockopt(WaitSock, SOL_SOCKET, SO_REUSEADDR, (const char *)&fFlag, sizeof(fFlag)))1216 if (!rtSocketSetOpt(WaitSock, SOL_SOCKET, SO_REUSEADDR, &fFlag, sizeof(fFlag))) 455 1217 { 456 1218 /* … … 468 1230 469 1231 /* 470 * Bind a name to a socket .1232 * Bind a name to a socket and set it listening for connections. 471 1233 */ 472 if (bind(WaitSock, (struct sockaddr *)&LocalAddr, sizeof(LocalAddr)) != -1) 1234 rc = rtSocketBind(WaitSock, (struct sockaddr *)&LocalAddr, sizeof(LocalAddr)); 1235 if (RT_SUCCESS(rc)) 1236 rc = rtSocketListen(WaitSock, RTTCP_SERVER_BACKLOG); 1237 if (RT_SUCCESS(rc)) 473 1238 { 474 1239 /* 475 * Listen for connections on a socket.1240 * Create the server handle. 476 1241 */ 477 if (listen(WaitSock, RTTCP_SERVER_BACKLOG) != -1) 1242 PRTTCPSERVER pServer = (PRTTCPSERVER)RTMemPoolAlloc(RTMEMPOOL_DEFAULT, sizeof(*pServer)); 1243 if (pServer) 478 1244 { 479 /* 480 * Create the server handle. 481 */ 482 PRTTCPSERVER pServer = (PRTTCPSERVER)RTMemPoolAlloc(RTMEMPOOL_DEFAULT, sizeof(*pServer)); 483 if (pServer) 484 { 485 pServer->u32Magic = RTTCPSERVER_MAGIC; 486 pServer->enmState = RTTCPSERVERSTATE_CREATED; 487 pServer->Thread = NIL_RTTHREAD; 488 pServer->SockServer = WaitSock; 489 pServer->SockClient = NIL_RTSOCKET; 490 pServer->pfnServe = NULL; 491 pServer->pvUser = NULL; 492 *ppServer = pServer; 493 return VINF_SUCCESS; 494 } 495 496 /* bail out */ 497 rc = VERR_NO_MEMORY; 1245 pServer->u32Magic = RTTCPSERVER_MAGIC; 1246 pServer->enmState = RTTCPSERVERSTATE_CREATED; 1247 pServer->Thread = NIL_RTTHREAD; 1248 pServer->SockServer = WaitSock; 1249 pServer->SockClient = NIL_RTSOCKET; 1250 pServer->pfnServe = NULL; 1251 pServer->pvUser = NULL; 1252 *ppServer = pServer; 1253 return VINF_SUCCESS; 498 1254 } 499 else 500 { 501 rc = rtTcpError(); 502 AssertMsgFailed(("listen() %Rrc\n", rc)); 503 } 1255 1256 /* bail out */ 1257 rc = VERR_NO_MEMORY; 504 1258 } 505 else506 {507 rc = rtTcpError();508 }509 1259 } 510 1260 else 511 { 512 rc = rtTcpError(); 513 AssertMsgFailed(("setsockopt() %Rrc\n", rc)); 514 } 1261 AssertMsgFailed(("rtSocketSetOpt: %Rrc\n", rc)); 515 1262 rtTcpClose(WaitSock, "RTServerCreateEx", false /*fTryGracefulShutdown*/); 516 }517 else518 {519 rc = rtTcpError();520 AssertMsgFailed(("socket() %Rrc\n", rc));521 1263 } 522 1264 … … 604 1346 */ 605 1347 struct sockaddr_in RemoteAddr; 1348 size_t cbRemoteAddr = sizeof(RemoteAddr); 1349 RTSOCKET Socket; 606 1350 RT_ZERO(RemoteAddr); 607 socklen_t cbRemoteAddr = sizeof(RemoteAddr); 608 RTSOCKET Socket = accept(SockServer, (struct sockaddr *)&RemoteAddr, &cbRemoteAddr); 609 if (Socket == -1) 610 { 611 #ifndef RT_OS_WINDOWS 1351 int rc = rtSocketAccept(SockServer, &Socket, (struct sockaddr *)&RemoteAddr, &cbRemoteAddr); 1352 if (RT_FAILURE(rc)) 1353 { 612 1354 /* These are typical for what can happen during destruction. */ 613 if (errno == EBADF || errno == EINVAL || errno == ENOTSOCK) 1355 if ( rc == VERR_INVALID_HANDLE 1356 || rc == VERR_INVALID_PARAMETER 1357 || rc == VERR_NET_NOT_SOCKET) 614 1358 return rtTcpServerListenCleanup(pServer); 615 #endif616 1359 continue; 617 1360 } 618 rt TcpSetInheritance(Socket, false /*fInheritable*/);1361 rtSocketSetInheritance(Socket, false /*fInheritable*/); 619 1362 620 1363 /* … … 627 1370 } 628 1371 rtTcpAtomicXchgSock(&pServer->SockClient, Socket); 629 intrc = pServer->pfnServe(Socket, pServer->pvUser);1372 rc = pServer->pfnServe(Socket, pServer->pvUser); 630 1373 rtTcpServerDestroySocket(&pServer->SockClient, "Listener: client", true /*fTryGracefulShutdown*/); 631 1374 … … 744 1487 */ 745 1488 struct sockaddr_in RemoteAddr; 746 s ocklen_tcbRemoteAddr = sizeof(RemoteAddr);1489 size_t cbRemoteAddr = sizeof(RemoteAddr); 747 1490 RTSOCKET Socket; 748 1491 RT_ZERO(RemoteAddr); 749 rtTcpErrorReset(); 750 Socket = accept(SockServer, (struct sockaddr *)&RemoteAddr, &cbRemoteAddr); 751 if (Socket == -1) 752 { 753 rc = rtTcpError(); 1492 rc = rtSocketAccept(SockServer, &Socket, (struct sockaddr *)&RemoteAddr, &cbRemoteAddr); 1493 if (RT_FAILURE(rc)) 1494 { 754 1495 if (!rtTcpServerTrySetState(pServer, RTTCPSERVERSTATE_CREATED, RTTCPSERVERSTATE_ACCEPTING)) 755 1496 rc = rtTcpServerListenCleanup(pServer); … … 758 1499 continue; 759 1500 } 760 rt TcpSetInheritance(Socket, false /*fInheritable*/);1501 rtSocketSetInheritance(Socket, false /*fInheritable*/); 761 1502 762 1503 /* … … 924 1665 925 1666 926 RTR3DECL(int) RTTcpRead(RTSOCKET Sock, void *pvBuffer, size_t cbBuffer, size_t *pcbRead)927 {928 /*929 * Validate input.930 */931 AssertReturn(cbBuffer > 0, VERR_INVALID_PARAMETER);932 AssertPtr(pvBuffer);933 934 /*935 * Read loop.936 * If pcbRead is NULL we have to fill the entire buffer!937 */938 size_t cbRead = 0;939 size_t cbToRead = cbBuffer;940 for (;;)941 {942 rtTcpErrorReset();943 #ifdef RT_OS_WINDOWS944 int cbNow = cbToRead >= INT_MAX/2 ? INT_MAX/2 : (int)cbToRead;945 #else946 size_t cbNow = cbToRead;947 #endif948 ssize_t cbBytesRead = recv(Sock, (char *)pvBuffer + cbRead, cbNow, MSG_NOSIGNAL);949 if (cbBytesRead <= 0)950 {951 int rc = rtTcpError();952 Assert(RT_FAILURE_NP(rc) || cbBytesRead == 0);953 if (RT_FAILURE_NP(rc))954 return rc;955 if (pcbRead)956 {957 *pcbRead = 0;958 return VINF_SUCCESS;959 }960 return VERR_NET_SHUTDOWN;961 }962 if (pcbRead)963 {964 /* return partial data */965 *pcbRead = cbBytesRead;966 break;967 }968 969 /* read more? */970 cbRead += cbBytesRead;971 if (cbRead == cbBuffer)972 break;973 974 /* next */975 cbToRead = cbBuffer - cbRead;976 }977 978 return VINF_SUCCESS;979 }980 981 982 RTR3DECL(int) RTTcpWrite(RTSOCKET Sock, const void *pvBuffer, size_t cbBuffer)983 {984 /*985 * Try write all at once.986 */987 #ifdef RT_OS_WINDOWS988 int cbNow = cbBuffer >= INT_MAX / 2 ? INT_MAX / 2 : (int)cbBuffer;989 #else990 size_t cbNow = cbBuffer >= SSIZE_MAX ? SSIZE_MAX : cbBuffer;991 #endif992 ssize_t cbWritten = send(Sock, (const char *)pvBuffer, cbNow, MSG_NOSIGNAL);993 if (RT_LIKELY((size_t)cbWritten == cbBuffer && cbWritten >= 0))994 return VINF_SUCCESS;995 if (cbWritten < 0)996 return rtTcpError();997 998 /*999 * Unfinished business, write the remainder of the request. Must ignore1000 * VERR_INTERRUPTED here if we've managed to send something.1001 */1002 size_t cbSentSoFar = 0;1003 for (;;)1004 {1005 /* advance */1006 cbBuffer -= (size_t)cbWritten;1007 if (!cbBuffer)1008 return VINF_SUCCESS;1009 cbSentSoFar += (size_t)cbWritten;1010 pvBuffer = (char const *)pvBuffer + cbWritten;1011 1012 /* send */1013 #ifdef RT_OS_WINDOWS1014 cbNow = cbBuffer >= INT_MAX / 2 ? INT_MAX / 2 : (int)cbBuffer;1015 #else1016 cbNow = cbBuffer >= SSIZE_MAX ? SSIZE_MAX : cbBuffer;1017 #endif1018 cbWritten = send(Sock, (const char *)pvBuffer, cbNow, MSG_NOSIGNAL);1019 if (cbWritten >= 0)1020 AssertMsg(cbBuffer >= (size_t)cbWritten, ("Wrote more than we requested!!! cbWritten=%zu cbBuffer=%zu rtTcpError()=%d\n",1021 cbWritten, cbBuffer, rtTcpError()));1022 else1023 {1024 int rc = rtTcpError();1025 if (rc != VERR_INTERNAL_ERROR || cbSentSoFar == 0)1026 return rc;1027 cbWritten = 0;1028 }1029 }1030 }1031 1032 1033 RTR3DECL(int) RTTcpFlush(RTSOCKET Sock)1034 {1035 int fFlag = 1;1036 setsockopt(Sock, IPPROTO_TCP, TCP_NODELAY, (const char *)&fFlag, sizeof(fFlag));1037 fFlag = 0;1038 setsockopt(Sock, IPPROTO_TCP, TCP_NODELAY, (const char *)&fFlag, sizeof(fFlag));1039 1040 return VINF_SUCCESS;1041 }1042 1043 1044 RTR3DECL(int) RTTcpSelectOne(RTSOCKET Sock, RTMSINTERVAL cMillies)1045 {1046 fd_set fdsetR;1047 FD_ZERO(&fdsetR);1048 FD_SET(Sock, &fdsetR);1049 1050 fd_set fdsetE = fdsetR;1051 1052 int rc;1053 if (cMillies == RT_INDEFINITE_WAIT)1054 rc = select(Sock + 1, &fdsetR, NULL, &fdsetE, NULL);1055 else1056 {1057 struct timeval timeout;1058 timeout.tv_sec = cMillies / 1000;1059 timeout.tv_usec = (cMillies % 1000) * 1000;1060 rc = select(Sock + 1, &fdsetR, NULL, &fdsetE, &timeout);1061 }1062 if (rc > 0)1063 return VINF_SUCCESS;1064 if (rc == 0)1065 return VERR_TIMEOUT;1066 return rtTcpError();1067 }1068 1069 1070 static int rtTcpConvertAddress(RTSOCKADDRUNION *pSrc, size_t cbSrc, PRTNETADDR pAddr)1071 {1072 /*1073 * Convert the address.1074 */1075 if ( cbSrc == sizeof(struct sockaddr_in)1076 && pSrc->Addr.sa_family == AF_INET)1077 {1078 RT_ZERO(*pAddr);1079 pAddr->enmType = RTNETADDRTYPE_IPV4;1080 pAddr->uPort = RT_N2H_U16(pSrc->Ipv4.sin_port);1081 pAddr->uAddr.IPv4.u = pSrc->Ipv4.sin_addr.s_addr;1082 }1083 #ifdef IPRT_WITH_TCPIP_V61084 else if ( cbSrc == sizeof(struct sockaddr_in6)1085 && pSrc->Addr.sa_family == AF_INET6)1086 {1087 RT_ZERO(*pAddr);1088 pAddr->enmType = RTNETADDRTYPE_IPV6;1089 pAddr->uPort = RT_N2H_U16(pSrc->Ipv6.sin6_port);1090 pAddr->uAddr.IPv6.au32[0] = pSrc->Ipv6.sin6_addr.s6_addr32[0];1091 pAddr->uAddr.IPv6.au32[1] = pSrc->Ipv6.sin6_addr.s6_addr32[1];1092 pAddr->uAddr.IPv6.au32[2] = pSrc->Ipv6.sin6_addr.s6_addr32[2];1093 pAddr->uAddr.IPv6.au32[3] = pSrc->Ipv6.sin6_addr.s6_addr32[3];1094 }1095 #endif1096 else1097 return VERR_NET_ADDRESS_FAMILY_NOT_SUPPORTED;1098 return VINF_SUCCESS;1099 }1100 1101 1102 RTR3DECL(int) RTTcpGetLocalAddress(RTSOCKET Sock, PRTNETADDR pAddr)1103 {1104 RTSOCKADDRUNION u;1105 #ifdef RT_OS_WINDOWS1106 int cbAddr = sizeof(u);1107 #else1108 socklen_t cbAddr = sizeof(u);1109 #endif1110 RT_ZERO(u);1111 if (!getsockname(Sock, &u.Addr, &cbAddr))1112 return rtTcpConvertAddress(&u, cbAddr, pAddr);1113 return rtTcpError();1114 }1115 1116 1117 RTR3DECL(int) RTTcpGetPeerAddress(RTSOCKET Sock, PRTNETADDR pAddr)1118 {1119 RTSOCKADDRUNION u;1120 #ifdef RT_OS_WINDOWS1121 int cbAddr = sizeof(u);1122 #else1123 socklen_t cbAddr = sizeof(u);1124 #endif1125 RT_ZERO(u);1126 if (!getpeername(Sock, &u.Addr, &cbAddr))1127 return rtTcpConvertAddress(&u, cbAddr, pAddr);1128 return rtTcpError();1129 }1130 1131 1132 1667 RTR3DECL(int) RTTcpClientConnect(const char *pszAddress, uint32_t uPort, PRTSOCKET pSock) 1133 1668 { … … 1166 1701 if (!pHostEnt) 1167 1702 { 1168 rc = rt TcpError();1703 rc = rtSocketError(); 1169 1704 AssertMsgFailed(("Could not resolve '%s', rc=%Rrc\n", pszAddress, rc)); 1170 1705 return rc; … … 1175 1710 * Create the socket and connect. 1176 1711 */ 1177 RTSOCKET Sock = socket(PF_INET, SOCK_STREAM, 0); 1178 if (Sock != -1) 1179 { 1180 rtTcpSetInheritance(Sock, false /*fInheritable*/); 1712 RTSOCKET Sock; 1713 rc = rtSocketCreate(&Sock, PF_INET, SOCK_STREAM, 0); 1714 if (RT_SUCCESS(rc)) 1715 { 1716 rtSocketSetInheritance(Sock, false /*fInheritable*/); 1181 1717 1182 1718 struct sockaddr_in InAddr; … … 1185 1721 InAddr.sin_port = htons(uPort); 1186 1722 InAddr.sin_addr = *((struct in_addr *)pHostEnt->h_addr); 1187 if (!connect(Sock, (struct sockaddr *)&InAddr, sizeof(InAddr))) 1723 rc = rtSocketConnect(Sock, (struct sockaddr *)&InAddr, sizeof(InAddr)); 1724 if (RT_SUCCESS(rc)) 1188 1725 { 1189 1726 *pSock = Sock; 1190 1727 return VINF_SUCCESS; 1191 1728 } 1192 rc = rtTcpError(); 1729 1193 1730 rtTcpClose(Sock, "RTTcpClientConnect", false /*fTryGracefulShutdown*/); 1194 1731 } 1195 else1196 rc = rtTcpError();1197 1732 return rc; 1198 1733 } … … 1221 1756 if (fTryGracefulShutdown) 1222 1757 { 1223 rc = shutdown(Sock, SHUT_WR);1224 if ( !rc)1758 rc = rtSocketShutdown(Sock, false /*fRead*/, true /*fWrite*/); 1759 if (RT_SUCCESS(rc)) 1225 1760 { 1226 1761 uint64_t u64Start = RTTimeMilliTS(); 1227 1762 for (;;) 1228 1763 { 1229 rc = RTTcpSelectOne(Sock, 1000);1764 rc = rtSocketSelectOne(Sock, 1000); 1230 1765 if (rc == VERR_TIMEOUT) 1231 1766 { … … 1237 1772 { 1238 1773 char abBitBucket[16*_1K]; 1239 ssize_t cbBytesRead = recv( Sock, &abBitBucket[0], sizeof(abBitBucket), MSG_NOSIGNAL);1774 ssize_t cbBytesRead = recv(rtSocketNative(Sock), &abBitBucket[0], sizeof(abBitBucket), MSG_NOSIGNAL); 1240 1775 if (cbBytesRead == 0) 1241 1776 break; /* orderly shutdown in progress */ … … 1248 1783 1249 1784 /* 1250 * Attempt to close it. 1251 */ 1252 #ifdef RT_OS_WINDOWS 1253 rc = closesocket(Sock); 1254 #else 1255 rc = close(Sock); 1256 #endif 1257 if (!rc) 1258 return VINF_SUCCESS; 1259 rc = rtTcpError(); 1260 AssertMsgFailed(("\"%s\": close(%d) -> %Rrc\n", pszMsg, Sock, rc)); 1261 return rc; 1262 } 1263 1785 * Destroy the socket handle. 1786 */ 1787 return rtSocketDestroy(Sock); 1788 } 1789 1790 1791 RTR3DECL(int) RTTcpRead(RTSOCKET Sock, void *pvBuffer, size_t cbBuffer, size_t *pcbRead) 1792 { 1793 return rtSocketRead(Sock, pvBuffer, cbBuffer, pcbRead); 1794 } 1795 1796 1797 RTR3DECL(int) RTTcpWrite(RTSOCKET Sock, const void *pvBuffer, size_t cbBuffer) 1798 { 1799 return rtSocketWrite(Sock, pvBuffer, cbBuffer); 1800 } 1801 1802 1803 RTR3DECL(int) RTTcpFlush(RTSOCKET Sock) 1804 { 1805 1806 int fFlag = 1; 1807 int rc = rtSocketSetOpt(Sock, IPPROTO_TCP, TCP_NODELAY, &fFlag, sizeof(fFlag)); 1808 if (RT_SUCCESS(rc)) 1809 { 1810 fFlag = 0; 1811 rc = rtSocketSetOpt(Sock, IPPROTO_TCP, TCP_NODELAY, &fFlag, sizeof(fFlag)); 1812 } 1813 return rc; 1814 } 1815 1816 1817 RTR3DECL(int) RTTcpSelectOne(RTSOCKET Sock, RTMSINTERVAL cMillies) 1818 { 1819 return rtSocketSelectOne(Sock, cMillies); 1820 } 1821 1822 1823 RTR3DECL(int) RTTcpGetLocalAddress(RTSOCKET Sock, PRTNETADDR pAddr) 1824 { 1825 return rtSocketGetLocalAddress(Sock, pAddr); 1826 } 1827 1828 1829 RTR3DECL(int) RTTcpGetPeerAddress(RTSOCKET Sock, PRTNETADDR pAddr) 1830 { 1831 return rtSocketGetPeerAddress(Sock, pAddr); 1832 } 1833
Note:
See TracChangeset
for help on using the changeset viewer.

