VirtualBox

Changeset 100171 in vbox for trunk/src/VBox/Runtime


Ignore:
Timestamp:
Jun 13, 2023 9:07:56 PM (23 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
157874
Message:

IPRT: tcp.h+tcp.cpp,socket.h+socket.cpp: Add RTTcpSetKeepAlive() which
allows one to enable or disable sending periodic keep-alive messages on
a socket (SO_KEEPALIVE) as described in RFC 1122. RTTcpSetKeepAlive()
also allows one to adjust several keep-alive options on a per-socket
basis: the idle time before keep-alive probes are sent (TCP_KEEPIDLE
(TCP_KEEPALIVE on macOS)), the amount of time between keep-alive probes
(TCP_KEEPINTVL), and the number of keep-alive probes to send before
closing the connection (TCP_KEEPCNT).

Location:
trunk/src/VBox/Runtime
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/include/internal/socket.h

    r98103 r100171  
    7979
    8080DECLHIDDEN(int)         rtSocketPollGetHandle(RTSOCKET hSocket, uint32_t fEvents, PRTHCINTPTR phNative);
     81DECLHIDDEN(int)         rtSocketSetKeepAlive(RTSOCKET hSocket, bool fEnable, uint32_t cSecsIdle, uint32_t cSecsInterval);
    8182DECLHIDDEN(uint32_t)    rtSocketPollStart(RTSOCKET hSocket, RTPOLLSET hPollSet, uint32_t fEvents, bool fFinalEntry, bool fNoWait);
    8283DECLHIDDEN(uint32_t)    rtSocketPollDone(RTSOCKET hSocket, uint32_t fEvents, bool fFinalEntry, bool fHarvestEvents);
  • trunk/src/VBox/Runtime/r3/socket.cpp

    r98103 r100171  
    4242# include <iprt/win/winsock2.h>
    4343# include <iprt/win/ws2tcpip.h>
     44# include <mstcpip.h>  /* for struct tcp_keepalive */
    4445#else /* !RT_OS_WINDOWS */
    4546# include <errno.h>
     
    28832884}
    28842885
     2886
     2887DECLHIDDEN(int) rtSocketSetKeepAlive(RTSOCKET hSocket, bool fEnable, uint32_t cSecsIdle, uint32_t cSecsInterval)
     2888{
     2889    RTSOCKETINT *pThis = hSocket;
     2890    AssertPtrReturn(pThis, UINT32_MAX);
     2891    AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, UINT32_MAX);
     2892
     2893    if (!g_pfnWSAIoctl)
     2894        return VERR_NET_NOT_UNSUPPORTED;
     2895
     2896    struct tcp_keepalive keepAliveOptions;
     2897    DWORD dwBytesReturned;
     2898
     2899    keepAliveOptions.onoff = fEnable ? 1 : 0;
     2900    keepAliveOptions.keepalivetime = cSecsIdle * 1000;
     2901    keepAliveOptions.keepaliveinterval = cSecsInterval * 1000;
     2902
     2903    if (g_pfnWSAIoctl(pThis->hNative,
     2904                      SIO_KEEPALIVE_VALS,
     2905                      &keepAliveOptions, sizeof(keepAliveOptions),
     2906                      NULL, 0, &dwBytesReturned, NULL, NULL) == 0)
     2907        return VINF_SUCCESS;
     2908
     2909    int rc = rtSocketError();
     2910    AssertMsgFailed(("WSAIoctl(.., SIO_KEEPALIVE_VALS, ...) failed: rc=%Rrc\n", rc));
     2911    return rc;
     2912}
     2913
    28852914#endif  /* RT_OS_WINDOWS */
    28862915
  • trunk/src/VBox/Runtime/r3/tcp.cpp

    r99758 r100171  
    10011001
    10021002
     1003RTR3DECL(int)  RTTcpSetKeepAlive(RTSOCKET hSocket, bool fEnable, uint32_t cSecsIdle,
     1004                                 uint32_t cSecsInterval, uint32_t cFailedPktsBeforeClose)
     1005{
     1006#if !defined(RT_OS_WINDOWS)
     1007    int fFlag = fEnable ? 1 : 0;
     1008    int rc = rtSocketSetOpt(hSocket, SOL_SOCKET, SO_KEEPALIVE, &fFlag, sizeof(fFlag));
     1009    if (RT_FAILURE(rc))
     1010        return rc;
     1011
     1012# if defined(TCP_KEEPIDLE) || defined(TCP_KEEPALIVE)
     1013    rc = VINF_SUCCESS;
     1014
     1015    /* time in seconds that the connection must be idle before sending keep-alive probes */
     1016    if (cSecsIdle)
     1017    {
     1018#  if defined(TCP_KEEPALIVE) && !defined(TCP_KEEPIDLE)  /* macOS */
     1019#   define TCP_KEEPIDLE    TCP_KEEPALIVE
     1020#  endif
     1021        rc = rtSocketSetOpt(hSocket, IPPROTO_TCP, TCP_KEEPIDLE, &cSecsIdle, sizeof(cSecsIdle));
     1022        if (RT_FAILURE(rc))
     1023            return rc;
     1024    }
     1025
     1026    /* time in seconds between each keep-alive probe */
     1027    if (cSecsInterval)
     1028    {
     1029        rc = rtSocketSetOpt(hSocket, IPPROTO_TCP, TCP_KEEPINTVL, &cSecsInterval, sizeof(cSecsInterval));
     1030        if (RT_FAILURE(rc))
     1031            return rc;
     1032    }
     1033
     1034    /* count of keep-alive probes to send which don't receive a response before closing connection */
     1035    if (cFailedPktsBeforeClose)
     1036    {
     1037        rc = rtSocketSetOpt(hSocket, IPPROTO_TCP, TCP_KEEPCNT, &cFailedPktsBeforeClose, sizeof(cFailedPktsBeforeClose));
     1038        if (RT_FAILURE(rc))
     1039            return rc;
     1040    }
     1041
     1042    return rc;
     1043# else
     1044    return VERR_NOT_SUPPORTED;
     1045# endif
     1046#else
     1047    NOREF(cFailedPktsBeforeClose);
     1048    return rtSocketSetKeepAlive(hSocket, fEnable, cSecsIdle, cSecsInterval);
     1049#endif
     1050}
     1051
     1052
    10031053RTR3DECL(int)  RTTcpSelectOne(RTSOCKET Sock, RTMSINTERVAL cMillies)
    10041054{
  • trunk/src/VBox/Runtime/r3/win/init-win.cpp

    r98103 r100171  
    136136/** WSASend */
    137137DECL_HIDDEN_DATA(PFNWSASEND)                    g_pfnWSASend = NULL;
     138/** WSAIoctl */
     139DECL_HIDDEN_DATA(PFNWSAIOCTL)                   g_pfnWSAIoctl = NULL;
    138140/** socket */
    139141DECL_HIDDEN_DATA(PFNWINSOCKSOCKET)              g_pfnsocket = NULL;
     
    447449    g_pfnWSASocketW           = (decltype(g_pfnWSASocketW))         GetProcAddress(g_hModWinSock, "WSASocketW");
    448450    g_pfnWSASend              = (decltype(g_pfnWSASend))            GetProcAddress(g_hModWinSock, "WSASend");
     451    g_pfnWSAIoctl             = (decltype(g_pfnWSAIoctl))           GetProcAddress(g_hModWinSock, "WSAIoctl");
    449452    g_pfnsocket               = (decltype(g_pfnsocket))             GetProcAddress(g_hModWinSock, "socket");
    450453    g_pfnclosesocket          = (decltype(g_pfnclosesocket))        GetProcAddress(g_hModWinSock, "closesocket");
     
    478481    Assert(g_pfnWSASocketW           || g_fOldWinSock);
    479482    Assert(g_pfnWSASend              || g_fOldWinSock);
     483    Assert(g_pfnWSAIoctl             || g_fOldWinSock);
    480484    Assert(g_pfnsocket);
    481485    Assert(g_pfnclosesocket);
  • trunk/src/VBox/Runtime/r3/win/internal-r3-win.h

    r98103 r100171  
    167167/** WSASend */
    168168typedef int             (WINAPI *PFNWSASEND)(UINT_PTR, struct _WSABUF *, DWORD, LPDWORD, DWORD dwFlags,
     169                                             struct _OVERLAPPED *, uintptr_t /*LPWSAOVERLAPPED_COMPLETION_ROUTINE*/);
     170/** WSAIoctl */
     171typedef int             (WINAPI *PFNWSAIOCTL)(UINT_PTR, DWORD, LPVOID, DWORD, LPVOID, DWORD, LPDWORD,
    169172                                             struct _OVERLAPPED *, uintptr_t /*LPWSAOVERLAPPED_COMPLETION_ROUTINE*/);
    170173
     
    219222extern DECL_HIDDEN_DATA(PFNWSASOCKETW)                   g_pfnWSASocketW;
    220223extern DECL_HIDDEN_DATA(PFNWSASEND)                      g_pfnWSASend;
     224extern DECL_HIDDEN_DATA(PFNWSAIOCTL)                     g_pfnWSAIoctl;
    221225extern DECL_HIDDEN_DATA(PFNWINSOCKSOCKET)                g_pfnsocket;
    222226extern DECL_HIDDEN_DATA(PFNWINSOCKCLOSESOCKET)           g_pfnclosesocket;
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette