VirtualBox

Changeset 37196 in vbox for trunk/src/VBox/Runtime/r3


Ignore:
Timestamp:
May 24, 2011 2:50:05 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
71892
Message:

Runtime/socket+udp: new socket functions needed to provide UDP as part of the runtime

Location:
trunk/src/VBox/Runtime/r3
Files:
1 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/socket.cpp

    r34507 r37196  
    55
    66/*
    7  * Copyright (C) 2006-2010 Oracle Corporation
     7 * Copyright (C) 2006-2011 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    221221
    222222/**
     223 * Converts from a native socket address to a generic IPRT network address.
     224 *
     225 * @returns IPRT status code.
     226 * @param   pSrc                The source address.
     227 * @param   cbSrc               The size of the source address.
     228 * @param   pAddr               Where to return the generic IPRT network
     229 *                              address.
     230 */
     231static int rtSocketNetAddrFromAddr(RTSOCKADDRUNION const *pSrc, size_t cbSrc, PRTNETADDR pAddr)
     232{
     233    /*
     234     * Convert the address.
     235     */
     236    if (   cbSrc == sizeof(struct sockaddr_in)
     237        && pSrc->Addr.sa_family == AF_INET)
     238    {
     239        RT_ZERO(*pAddr);
     240        pAddr->enmType      = RTNETADDRTYPE_IPV4;
     241        pAddr->uPort        = RT_N2H_U16(pSrc->Ipv4.sin_port);
     242        pAddr->uAddr.IPv4.u = pSrc->Ipv4.sin_addr.s_addr;
     243    }
     244#ifdef IPRT_WITH_TCPIP_V6
     245    else if (   cbSrc == sizeof(struct sockaddr_in6)
     246             && pSrc->Addr.sa_family == AF_INET6)
     247    {
     248        RT_ZERO(*pAddr);
     249        pAddr->enmType            = RTNETADDRTYPE_IPV6;
     250        pAddr->uPort              = RT_N2H_U16(pSrc->Ipv6.sin6_port);
     251        pAddr->uAddr.IPv6.au32[0] = pSrc->Ipv6.sin6_addr.s6_addr32[0];
     252        pAddr->uAddr.IPv6.au32[1] = pSrc->Ipv6.sin6_addr.s6_addr32[1];
     253        pAddr->uAddr.IPv6.au32[2] = pSrc->Ipv6.sin6_addr.s6_addr32[2];
     254        pAddr->uAddr.IPv6.au32[3] = pSrc->Ipv6.sin6_addr.s6_addr32[3];
     255    }
     256#endif
     257    else
     258        return VERR_NET_ADDRESS_FAMILY_NOT_SUPPORTED;
     259    return VINF_SUCCESS;
     260}
     261
     262
     263/**
     264 * Converts from a generic IPRT network address to a native socket address.
     265 *
     266 * @returns IPRT status code.
     267 * @param   pAddr               Pointer to the generic IPRT network address.
     268 * @param   pDst                The source address.
     269 * @param   cbSrc               The size of the source address.
     270 */
     271static int rtSocketAddrFromNetAddr(PCRTNETADDR pAddr, RTSOCKADDRUNION *pDst, size_t cbDst)
     272{
     273    RT_BZERO(pDst, cbDst);
     274    if (   pAddr->enmType == RTNETADDRTYPE_IPV4
     275        && cbDst >= sizeof(struct sockaddr_in))
     276    {
     277        pDst->Addr.sa_family       = AF_INET;
     278        pDst->Ipv4.sin_port        = RT_H2N_U16(pAddr->uPort);
     279        pDst->Ipv4.sin_addr.s_addr = pAddr->uAddr.IPv4.u;
     280    }
     281#ifdef IPRT_WITH_TCPIP_V6
     282    else if (   pAddr->enmType == RTNETADDRTYPE_IPV6
     283             && cbDst >= sizeof(struct sockaddr_in6))
     284    {
     285        pDst->Addr.sa_family              = AF_INET6;
     286        pDst->Ipv6.sin6_port              = RT_H2N_U16(pAddr->uPort);
     287        pSrc->Ipv6.sin6_addr.s6_addr32[0] = pAddr->uAddr.IPv6.au32[0];
     288        pSrc->Ipv6.sin6_addr.s6_addr32[1] = pAddr->uAddr.IPv6.au32[1];
     289        pSrc->Ipv6.sin6_addr.s6_addr32[2] = pAddr->uAddr.IPv6.au32[2];
     290        pSrc->Ipv6.sin6_addr.s6_addr32[3] = pAddr->uAddr.IPv6.au32[3];
     291    }
     292#endif
     293    else
     294        return VERR_NET_ADDRESS_FAMILY_NOT_SUPPORTED;
     295    return VINF_SUCCESS;
     296}
     297
     298
     299/**
    223300 * Tries to lock the socket for exclusive usage by the calling thread.
    224301 *
     
    502579
    503580    return rc;
     581}
     582
     583
     584RTDECL(int) RTSocketParseInetAddress(const char *pszAddress, unsigned uPort, PRTNETADDR pAddr)
     585{
     586    int rc;
     587
     588    /*
     589     * Validate input.
     590     */
     591    AssertReturn(uPort > 0, VERR_INVALID_PARAMETER);
     592    AssertPtrReturn(pszAddress, VERR_INVALID_POINTER);
     593
     594#ifdef RT_OS_WINDOWS
     595    /*
     596     * Initialize WinSock and check version.
     597     */
     598    WORD    wVersionRequested = MAKEWORD(1, 1);
     599    WSADATA wsaData;
     600    rc = WSAStartup(wVersionRequested, &wsaData);
     601    if (wsaData.wVersion != wVersionRequested)
     602    {
     603        AssertMsgFailed(("Wrong winsock version\n"));
     604        return VERR_NOT_SUPPORTED;
     605    }
     606#endif
     607
     608    /*
     609     * Resolve the address.
     610     */
     611    /** @todo this only supports IPv4, and IPv6 support needs to be added.
     612     * It probably needs to be converted to getnameinfo(). */
     613    struct hostent *pHostEnt = NULL;
     614    pHostEnt = gethostbyname(pszAddress);
     615    if (!pHostEnt)
     616    {
     617        struct in_addr InAddr;
     618        InAddr.s_addr = inet_addr(pszAddress);
     619        pHostEnt = gethostbyaddr((char *)&InAddr, 4, AF_INET);
     620        if (!pHostEnt)
     621        {
     622            rc = rtSocketResolverError();
     623            AssertMsgFailed(("Could not resolve '%s', rc=%Rrc\n", pszAddress, rc));
     624            return rc;
     625        }
     626    }
     627
     628    if (pHostEnt->h_addrtype == AF_INET)
     629    {
     630        RT_ZERO(*pAddr);
     631        pAddr->enmType      = RTNETADDRTYPE_IPV4;
     632        pAddr->uPort        = uPort;
     633        pAddr->uAddr.IPv4.u = ((struct in_addr *)pHostEnt->h_addr)->s_addr;
     634    }
     635    else
     636        return VERR_NET_ADDRESS_FAMILY_NOT_SUPPORTED;
     637
     638    return VINF_SUCCESS;
    504639}
    505640
     
    574709
    575710
     711RTDECL(int) RTSocketReadFrom(RTSOCKET hSocket, void *pvBuffer, size_t cbBuffer, size_t *pcbRead, PRTNETADDR pSrcAddr)
     712{
     713    /*
     714     * Validate input.
     715     */
     716    RTSOCKETINT *pThis = hSocket;
     717    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     718    AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE);
     719    AssertReturn(cbBuffer > 0, VERR_INVALID_PARAMETER);
     720    AssertPtr(pvBuffer);
     721    AssertPtr(pcbRead);
     722    AssertReturn(rtSocketTryLock(pThis), VERR_CONCURRENT_ACCESS);
     723
     724    int rc = rtSocketSwitchBlockingMode(pThis, true /* fBlocking */);
     725    if (RT_FAILURE(rc))
     726        return rc;
     727
     728    /*
     729     * Read data.
     730     */
     731    size_t  cbRead   = 0;
     732    size_t  cbToRead = cbBuffer;
     733    rtSocketErrorReset();
     734    RTSOCKADDRUNION u;
     735#ifdef RT_OS_WINDOWS
     736    int       cbNow  = cbToRead >= INT_MAX/2 ? INT_MAX/2 : (int)cbToRead;
     737    int       cbAddr = sizeof(u);
     738#else
     739    size_t    cbNow  = cbToRead;
     740    socklen_t cbAddr = sizeof(u);
     741#endif
     742    ssize_t cbBytesRead = recvfrom(pThis->hNative, (char *)pvBuffer + cbRead, cbNow, MSG_NOSIGNAL, &u.Addr, &cbAddr);
     743    if (cbBytesRead <= 0)
     744    {
     745        rc = rtSocketError();
     746        Assert(RT_FAILURE_NP(rc) || cbBytesRead == 0);
     747        if (RT_SUCCESS_NP(rc))
     748        {
     749            *pcbRead = 0;
     750            rc = VINF_SUCCESS;
     751        }
     752    }
     753    else
     754    {
     755        if (pSrcAddr)
     756            rc = rtSocketNetAddrFromAddr(&u, cbAddr, pSrcAddr);
     757        *pcbRead = cbBytesRead;
     758    }
     759
     760    rtSocketUnlock(pThis);
     761    return rc;
     762}
     763
     764
    576765RTDECL(int) RTSocketWrite(RTSOCKET hSocket, const void *pvBuffer, size_t cbBuffer)
    577766{
     
    643832
    644833
     834RTDECL(int) RTSocketWriteTo(RTSOCKET hSocket, const void *pvBuffer, size_t cbBuffer, PCRTNETADDR pAddr)
     835{
     836    /*
     837     * Validate input.
     838     */
     839    RTSOCKETINT *pThis = hSocket;
     840    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     841    AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE);
     842
     843    /* no locking since UDP reads may be done concurrently to writes, and
     844     * this is the normal use case of this code. */
     845
     846    int rc = rtSocketSwitchBlockingMode(pThis, true /* fBlocking */);
     847    if (RT_FAILURE(rc))
     848        return rc;
     849
     850    /* Figure out destination address. */
     851    struct sockaddr *pSA = NULL;
     852#ifdef RT_OS_WINDOWS
     853    int cbSA = 0;
     854#else
     855    socklen_t cbSA = 0;
     856#endif
     857    RTSOCKADDRUNION u;
     858    if (pAddr)
     859    {
     860        rc = rtSocketAddrFromNetAddr(pAddr, &u, sizeof(u));
     861        if (RT_FAILURE(rc))
     862            return rc;
     863        pSA = &u.Addr;
     864        cbSA = sizeof(u);
     865    }
     866
     867    /*
     868     * Must write all at once, otherwise it is a failure.
     869     */
     870#ifdef RT_OS_WINDOWS
     871    int     cbNow     = cbBuffer >= INT_MAX / 2 ? INT_MAX / 2 : (int)cbBuffer;
     872#else
     873    size_t  cbNow     = cbBuffer >= SSIZE_MAX   ? SSIZE_MAX   :      cbBuffer;
     874#endif
     875    ssize_t cbWritten = sendto(pThis->hNative, (const char *)pvBuffer, cbNow, MSG_NOSIGNAL, pSA, cbSA);
     876    if (RT_LIKELY((size_t)cbWritten == cbBuffer && cbWritten >= 0))
     877        rc = VINF_SUCCESS;
     878    else if (cbWritten < 0)
     879        rc = rtSocketError();
     880    else
     881        rc = VERR_TOO_MUCH_DATA;
     882
     883    rtSocketUnlock(pThis);
     884    return rc;
     885}
     886
     887
    645888RTDECL(int) RTSocketSgWrite(RTSOCKET hSocket, PCRTSGBUF pSgBuf)
    646889{
     
    10851328
    10861329
    1087 /**
    1088  * Converts from a native socket address to a generic IPRT network address.
    1089  *
    1090  * @returns IPRT status code.
    1091  * @param   pSrc                The source address.
    1092  * @param   cbSrc               The size of the source address.
    1093  * @param   pAddr               Where to return the generic IPRT network
    1094  *                              address.
    1095  */
    1096 static int rtSocketConvertAddress(RTSOCKADDRUNION const *pSrc, size_t cbSrc, PRTNETADDR pAddr)
    1097 {
    1098     /*
    1099      * Convert the address.
    1100      */
    1101     if (   cbSrc == sizeof(struct sockaddr_in)
    1102         && pSrc->Addr.sa_family == AF_INET)
    1103     {
    1104         RT_ZERO(*pAddr);
    1105         pAddr->enmType      = RTNETADDRTYPE_IPV4;
    1106         pAddr->uPort        = RT_N2H_U16(pSrc->Ipv4.sin_port);
    1107         pAddr->uAddr.IPv4.u = pSrc->Ipv4.sin_addr.s_addr;
    1108     }
    1109 #ifdef IPRT_WITH_TCPIP_V6
    1110     else if (   cbSrc == sizeof(struct sockaddr_in6)
    1111              && pSrc->Addr.sa_family == AF_INET6)
    1112     {
    1113         RT_ZERO(*pAddr);
    1114         pAddr->enmType            = RTNETADDRTYPE_IPV6;
    1115         pAddr->uPort              = RT_N2H_U16(pSrc->Ipv6.sin6_port);
    1116         pAddr->uAddr.IPv6.au32[0] = pSrc->Ipv6.sin6_addr.s6_addr32[0];
    1117         pAddr->uAddr.IPv6.au32[1] = pSrc->Ipv6.sin6_addr.s6_addr32[1];
    1118         pAddr->uAddr.IPv6.au32[2] = pSrc->Ipv6.sin6_addr.s6_addr32[2];
    1119         pAddr->uAddr.IPv6.au32[3] = pSrc->Ipv6.sin6_addr.s6_addr32[3];
    1120     }
    1121 #endif
    1122     else
    1123         return VERR_NET_ADDRESS_FAMILY_NOT_SUPPORTED;
    1124     return VINF_SUCCESS;
    1125 }
    1126 
    1127 
    11281330RTDECL(int) RTSocketGetLocalAddress(RTSOCKET hSocket, PRTNETADDR pAddr)
    11291331{
     
    11481350    RT_ZERO(u);
    11491351    if (getsockname(pThis->hNative, &u.Addr, &cbAddr) == 0)
    1150         rc = rtSocketConvertAddress(&u, cbAddr, pAddr);
     1352        rc = rtSocketNetAddrFromAddr(&u, cbAddr, pAddr);
    11511353    else
    11521354        rc = rtSocketError();
     
    11781380    RT_ZERO(u);
    11791381    if (getpeername(pThis->hNative, &u.Addr, &cbAddr) == 0)
    1180         rc = rtSocketConvertAddress(&u, cbAddr, pAddr);
     1382        rc = rtSocketNetAddrFromAddr(&u, cbAddr, pAddr);
    11811383    else
    11821384        rc = rtSocketError();
  • trunk/src/VBox/Runtime/r3/udp.cpp

    r37166 r37196  
    11/* $Id$ */
    22/** @file
    3  * IPRT - TCP/IP.
     3 * IPRT - UDP/IP.
    44 */
    55
    66/*
    7  * Copyright (C) 2006-2010 Oracle Corporation
     7 * Copyright (C) 2006-2011 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3636# include <errno.h>
    3737# include <netinet/in.h>
    38 # include <netinet/tcp.h>
     38# include <netinet/udp.h>
    3939# include <arpa/inet.h>
    4040# include <netdb.h>
    41 # ifdef FIX_FOR_3_2
    42 #  include <fcntl.h>
    43 # endif
    4441#endif
    4542#include <limits.h>
    4643
    4744#include "internal/iprt.h"
    48 #include <iprt/tcp.h>
     45#include <iprt/udp.h>
    4946
    5047#include <iprt/asm.h>
     
    6562*   Defined Constants And Macros                                               *
    6663*******************************************************************************/
    67 /* non-standard linux stuff (it seems). */
    68 #ifndef MSG_NOSIGNAL
    69 # define MSG_NOSIGNAL           0
    70 #endif
    71 #ifndef SHUT_RDWR
    72 # ifdef SD_BOTH
    73 #  define SHUT_RDWR             SD_BOTH
    74 # else
    75 #  define SHUT_RDWR             2
    76 # endif
    77 #endif
    78 #ifndef SHUT_WR
    79 # ifdef SD_SEND
    80 #  define SHUT_WR               SD_SEND
    81 # else
    82 #  define SHUT_WR               1
    83 # endif
    84 #endif
    85 
    8664/* fixup backlevel OSes. */
    8765#if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS)
     
    8967#endif
    9068
    91 /** How many pending connection. */
    92 #define RTTCP_SERVER_BACKLOG    10
    93 
    9469
    9570/*******************************************************************************
     
    9772*******************************************************************************/
    9873/**
    99  * TCP Server state.
    100  */
    101 typedef enum RTTCPSERVERSTATE
     74 * UDP Server state.
     75 */
     76typedef enum RTUDPSERVERSTATE
    10277{
    10378    /** Invalid. */
    104     RTTCPSERVERSTATE_INVALID = 0,
     79    RTUDPSERVERSTATE_INVALID = 0,
    10580    /** Created. */
    106     RTTCPSERVERSTATE_CREATED,
    107     /** Listener thread is starting up. */
    108     RTTCPSERVERSTATE_STARTING,
    109     /** Accepting client connections. */
    110     RTTCPSERVERSTATE_ACCEPTING,
    111     /** Serving a client. */
    112     RTTCPSERVERSTATE_SERVING,
    113     /** Listener terminating. */
    114     RTTCPSERVERSTATE_STOPPING,
    115     /** Listener terminated. */
    116     RTTCPSERVERSTATE_STOPPED,
    117     /** Listener cleans up. */
    118     RTTCPSERVERSTATE_DESTROYING
    119 } RTTCPSERVERSTATE;
     81    RTUDPSERVERSTATE_CREATED,
     82    /** Thread for incoming datagrams is starting up. */
     83    RTUDPSERVERSTATE_STARTING,
     84    /** Waiting for incoming datagrams. */
     85    RTUDPSERVERSTATE_WAITING,
     86    /** Handling an incoming datagram. */
     87    RTUDPSERVERSTATE_RECEIVING,
     88    /** Thread terminating. */
     89    RTUDPSERVERSTATE_STOPPING,
     90    /** Thread terminated. */
     91    RTUDPSERVERSTATE_STOPPED,
     92    /** Final cleanup before being unusable. */
     93    RTUDPSERVERSTATE_DESTROYING
     94} RTUDPSERVERSTATE;
    12095
    12196/*
    122  * Internal representation of the TCP Server handle.
    123  */
    124 typedef struct RTTCPSERVER
    125 {
    126     /** The magic value (RTTCPSERVER_MAGIC). */
     97 * Internal representation of the UDP Server handle.
     98 */
     99typedef struct RTUDPSERVER
     100{
     101    /** The magic value (RTUDPSERVER_MAGIC). */
    127102    uint32_t volatile           u32Magic;
    128103    /** The server state. */
    129     RTTCPSERVERSTATE volatile   enmState;
     104    RTUDPSERVERSTATE volatile   enmState;
    130105    /** The server thread. */
    131106    RTTHREAD                    Thread;
    132107    /** The server socket. */
    133     RTSOCKET volatile           hServerSocket;
    134     /** The socket to the client currently being serviced.
    135      * This is NIL_RTSOCKET when no client is serviced. */
    136     RTSOCKET volatile           hClientSocket;
    137     /** The connection function. */
    138     PFNRTTCPSERVE               pfnServe;
     108    RTSOCKET volatile           hSocket;
     109    /** The datagram receiver function. */
     110    PFNRTUDPSERVE               pfnServe;
    139111    /** Argument to pfnServer. */
    140112    void                       *pvUser;
    141 } RTTCPSERVER;
     113} RTUDPSERVER;
    142114
    143115
     
    145117*   Internal Functions                                                         *
    146118*******************************************************************************/
    147 static DECLCALLBACK(int)  rtTcpServerThread(RTTHREAD ThreadSelf, void *pvServer);
    148 static int  rtTcpServerListen(PRTTCPSERVER pServer);
    149 static int  rtTcpServerListenCleanup(PRTTCPSERVER pServer);
    150 static int  rtTcpServerDestroySocket(RTSOCKET volatile *pSockClient, const char *pszMsg);
    151 static int  rtTcpClose(RTSOCKET Sock, const char *pszMsg, bool fTryGracefulShutdown);
     119static DECLCALLBACK(int)  rtUdpServerThread(RTTHREAD ThreadSelf, void *pvServer);
     120static int  rtUdpServerListen(PRTUDPSERVER pServer);
     121static int  rtUdpServerListenCleanup(PRTUDPSERVER pServer);
     122static int  rtUdpServerDestroySocket(RTSOCKET volatile *pSock, const char *pszMsg);
     123static int  rtUdpClose(RTSOCKET Sock, const char *pszMsg);
    152124
    153125
     
    158130 * @param   hSock           The new socket handle value.
    159131 */
    160 DECLINLINE(RTSOCKET) rtTcpAtomicXchgSock(RTSOCKET volatile *phSock, const RTSOCKET hNew)
     132DECLINLINE(RTSOCKET) rtUdpAtomicXchgSock(RTSOCKET volatile *phSock, const RTSOCKET hNew)
    161133{
    162134    RTSOCKET hRet;
     
    167139
    168140/**
    169  * Tries to change the TCP server state.
    170  */
    171 DECLINLINE(bool) rtTcpServerTrySetState(PRTTCPSERVER pServer, RTTCPSERVERSTATE enmStateNew, RTTCPSERVERSTATE enmStateOld)
     141 * Tries to change the UDP server state.
     142 */
     143DECLINLINE(bool) rtUdpServerTrySetState(PRTUDPSERVER pServer, RTUDPSERVERSTATE enmStateNew, RTUDPSERVERSTATE enmStateOld)
    172144{
    173145    bool fRc;
     
    177149
    178150/**
    179  * Changes the TCP server state.
    180  */
    181 DECLINLINE(void) rtTcpServerSetState(PRTTCPSERVER pServer, RTTCPSERVERSTATE enmStateNew, RTTCPSERVERSTATE enmStateOld)
     151 * Changes the UDP server state.
     152 */
     153DECLINLINE(void) rtUdpServerSetState(PRTUDPSERVER pServer, RTUDPSERVERSTATE enmStateNew, RTUDPSERVERSTATE enmStateOld)
    182154{
    183155    bool fRc;
     
    188160
    189161/**
    190  * Closes the a socket (client or server).
     162 * Closes a socket.
    191163 *
    192164 * @returns IPRT status code.
    193165 */
    194 static int rtTcpServerDestroySocket(RTSOCKET volatile *pSock, const char *pszMsg, bool fTryGracefulShutdown)
    195 {
    196     RTSOCKET hSocket = rtTcpAtomicXchgSock(pSock, NIL_RTSOCKET);
     166static int rtUdpServerDestroySocket(RTSOCKET volatile *pSock, const char *pszMsg)
     167{
     168    RTSOCKET hSocket = rtUdpAtomicXchgSock(pSock, NIL_RTSOCKET);
    197169    if (hSocket != NIL_RTSOCKET)
    198170    {
    199         if (!fTryGracefulShutdown)
    200             RTSocketShutdown(hSocket, true /*fRead*/, true /*fWrite*/);
    201         return rtTcpClose(hSocket, pszMsg, fTryGracefulShutdown);
    202     }
    203     return VINF_TCP_SERVER_NO_CLIENT;
    204 }
    205 
    206 
    207 /**
    208  * Create single connection at a time TCP Server in a separate thread.
    209  *
    210  * The thread will loop accepting connections and call pfnServe for
    211  * each of the incoming connections in turn. The pfnServe function can
    212  * return VERR_TCP_SERVER_STOP too terminate this loop. RTTcpServerDestroy()
     171        return rtUdpClose(hSocket, pszMsg);
     172    }
     173    return VINF_UDP_SERVER_NO_CLIENT;
     174}
     175
     176
     177/**
     178 * Create single datagram at a time UDP Server in a separate thread.
     179 *
     180 * The thread will loop waiting for datagrams and call pfnServe for
     181 * each of the incoming datagrams in turn. The pfnServe function can
     182 * return VERR_UDP_SERVER_STOP too terminate this loop. RTUdpServerDestroy()
    213183 * should be used to terminate the server.
    214184 *
    215185 * @returns iprt status code.
    216  * @param   pszAddress      The address for creating a listening socket.
     186 * @param   pszAddress      The address for creating a datagram socket.
    217187 *                          If NULL or empty string the server is bound to all interfaces.
    218  * @param   uPort           The port for creating a listening socket.
     188 * @param   uPort           The port for creating a datagram socket.
    219189 * @param   enmType         The thread type.
    220190 * @param   pszThrdName     The name of the worker thread.
    221  * @param   pfnServe        The function which will serve a new client connection.
     191 * @param   pfnServe        The function which will handle incoming datagrams.
    222192 * @param   pvUser          User argument passed to pfnServe.
    223193 * @param   ppServer        Where to store the serverhandle.
    224194 */
    225 RTR3DECL(int)  RTTcpServerCreate(const char *pszAddress, unsigned uPort, RTTHREADTYPE enmType, const char *pszThrdName,
    226                                  PFNRTTCPSERVE pfnServe, void *pvUser, PPRTTCPSERVER ppServer)
     195RTR3DECL(int)  RTUdpServerCreate(const char *pszAddress, unsigned uPort, RTTHREADTYPE enmType, const char *pszThrdName,
     196                                 PFNRTUDPSERVE pfnServe, void *pvUser, PPRTUDPSERVER ppServer)
    227197{
    228198    /*
     
    237207     * Create the server.
    238208     */
    239     PRTTCPSERVER pServer;
    240     int rc = RTTcpServerCreateEx(pszAddress, uPort, &pServer);
     209    PRTUDPSERVER pServer;
     210    int rc = RTUdpServerCreateEx(pszAddress, uPort, &pServer);
    241211    if (RT_SUCCESS(rc))
    242212    {
     
    245215         */
    246216        RTMemPoolRetain(pServer);
    247         pServer->enmState   = RTTCPSERVERSTATE_STARTING;
     217        pServer->enmState   = RTUDPSERVERSTATE_STARTING;
    248218        pServer->pvUser     = pvUser;
    249219        pServer->pfnServe   = pfnServe;
    250         rc = RTThreadCreate(&pServer->Thread, rtTcpServerThread, pServer, 0, enmType, /*RTTHREADFLAGS_WAITABLE*/0, pszThrdName);
     220        rc = RTThreadCreate(&pServer->Thread, rtUdpServerThread, pServer, 0, enmType, /*RTTHREADFLAGS_WAITABLE*/0, pszThrdName);
    251221        if (RT_SUCCESS(rc))
    252222        {
     
    263233         * Destroy the server.
    264234         */
    265         rtTcpServerSetState(pServer, RTTCPSERVERSTATE_CREATED, RTTCPSERVERSTATE_STARTING);
    266         RTTcpServerDestroy(pServer);
     235        rtUdpServerSetState(pServer, RTUDPSERVERSTATE_CREATED, RTUDPSERVERSTATE_STARTING);
     236        RTUdpServerDestroy(pServer);
    267237    }
    268238
     
    272242
    273243/**
    274  * Server thread, loops accepting connections until it's terminated.
     244 * Server thread, loops waiting for datagrams until it's terminated.
    275245 *
    276246 * @returns iprt status code. (ignored).
     
    278248 * @param   pvServer        Server handle.
    279249 */
    280 static DECLCALLBACK(int)  rtTcpServerThread(RTTHREAD ThreadSelf, void *pvServer)
    281 {
    282     PRTTCPSERVER    pServer = (PRTTCPSERVER)pvServer;
     250static DECLCALLBACK(int)  rtUdpServerThread(RTTHREAD ThreadSelf, void *pvServer)
     251{
     252    PRTUDPSERVER    pServer = (PRTUDPSERVER)pvServer;
    283253    int             rc;
    284     if (rtTcpServerTrySetState(pServer, RTTCPSERVERSTATE_ACCEPTING, RTTCPSERVERSTATE_STARTING))
    285         rc = rtTcpServerListen(pServer);
     254    if (rtUdpServerTrySetState(pServer, RTUDPSERVERSTATE_WAITING, RTUDPSERVERSTATE_STARTING))
     255        rc = rtUdpServerListen(pServer);
    286256    else
    287         rc = rtTcpServerListenCleanup(pServer);
     257        rc = rtUdpServerListenCleanup(pServer);
    288258    RTMemPoolRelease(RTMEMPOOL_DEFAULT, pServer);
    289259    NOREF(ThreadSelf);
     
    293263
    294264/**
    295  * Create single connection at a time TCP Server.
    296  * The caller must call RTTcpServerListen() to actually start the server.
     265 * Create single datagram at a time UDP Server.
     266 * The caller must call RTUdpServerReceive() to actually start the server.
    297267 *
    298268 * @returns iprt status code.
    299  * @param   pszAddress      The address for creating a listening socket.
     269 * @param   pszAddress      The address for creating a datagram socket.
    300270 *                          If NULL the server is bound to all interfaces.
    301  * @param   uPort           The port for creating a listening socket.
     271 * @param   uPort           The port for creating a datagram socket.
    302272 * @param   ppServer        Where to store the serverhandle.
    303273 */
    304 RTR3DECL(int) RTTcpServerCreateEx(const char *pszAddress, uint32_t uPort, PPRTTCPSERVER ppServer)
     274RTR3DECL(int) RTUdpServerCreateEx(const char *pszAddress, uint32_t uPort, PPRTUDPSERVER ppServer)
    305275{
    306276    int rc;
     
    349319     * Setting up socket.
    350320     */
    351     RTSOCKET WaitSock;
    352     rc = rtSocketCreate(&WaitSock, AF_INET, SOCK_STREAM, IPPROTO_TCP);
     321    RTSOCKET Sock;
     322    rc = rtSocketCreate(&Sock, AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    353323    if (RT_SUCCESS(rc))
    354324    {
    355         RTSocketSetInheritance(WaitSock, false /*fInheritable*/);
     325        RTSocketSetInheritance(Sock, false /*fInheritable*/);
    356326
    357327        /*
     
    359329         */
    360330        int fFlag = 1;
    361         if (!rtSocketSetOpt(WaitSock, SOL_SOCKET, SO_REUSEADDR, &fFlag, sizeof(fFlag)))
     331        if (!rtSocketSetOpt(Sock, SOL_SOCKET, SO_REUSEADDR, &fFlag, sizeof(fFlag)))
    362332        {
    363333            /*
     
    375345
    376346            /*
    377              * Bind a name to a socket and set it listening for connections.
     347             * Bind a name to the socket.
    378348             */
    379             rc = rtSocketBind(WaitSock, (struct sockaddr *)&LocalAddr, sizeof(LocalAddr));
    380             if (RT_SUCCESS(rc))
    381                 rc = rtSocketListen(WaitSock, RTTCP_SERVER_BACKLOG);
     349            rc = rtSocketBind(Sock, (struct sockaddr *)&LocalAddr, sizeof(LocalAddr));
    382350            if (RT_SUCCESS(rc))
    383351            {
     
    385353                 * Create the server handle.
    386354                 */
    387                 PRTTCPSERVER pServer = (PRTTCPSERVER)RTMemPoolAlloc(RTMEMPOOL_DEFAULT, sizeof(*pServer));
     355                PRTUDPSERVER pServer = (PRTUDPSERVER)RTMemPoolAlloc(RTMEMPOOL_DEFAULT, sizeof(*pServer));
    388356                if (pServer)
    389357                {
    390                     pServer->u32Magic       = RTTCPSERVER_MAGIC;
    391                     pServer->enmState       = RTTCPSERVERSTATE_CREATED;
    392                     pServer->Thread         = NIL_RTTHREAD;
    393                     pServer->hServerSocket  = WaitSock;
    394                     pServer->hClientSocket  = NIL_RTSOCKET;
    395                     pServer->pfnServe       = NULL;
    396                     pServer->pvUser         = NULL;
     358                    pServer->u32Magic   = RTUDPSERVER_MAGIC;
     359                    pServer->enmState   = RTUDPSERVERSTATE_CREATED;
     360                    pServer->Thread     = NIL_RTTHREAD;
     361                    pServer->hSocket    = Sock;
     362                    pServer->pfnServe   = NULL;
     363                    pServer->pvUser     = NULL;
    397364                    *ppServer = pServer;
    398365                    return VINF_SUCCESS;
     
    405372        else
    406373            AssertMsgFailed(("rtSocketSetOpt: %Rrc\n", rc));
    407         rtTcpClose(WaitSock, "RTServerCreateEx", false /*fTryGracefulShutdown*/);
     374        rtUdpClose(Sock, "RTServerCreateEx");
    408375    }
    409376
     
    413380
    414381/**
    415  * Listen for incoming connections.
    416  *
    417  * The function will loop accepting connections and call pfnServe for
    418  * each of the incoming connections in turn. The pfnServe function can
    419  * return VERR_TCP_SERVER_STOP too terminate this loop. A stopped server
     382 * Listen for incoming datagrams.
     383 *
     384 * The function will loop waiting for datagrams and call pfnServe for
     385 * each of the incoming datagrams in turn. The pfnServe function can
     386 * return VERR_UDP_SERVER_STOP too terminate this loop. A stopped server
    420387 * can only be destroyed.
    421388 *
    422389 * @returns IPRT status code.
    423  * @retval  VERR_TCP_SERVER_STOP if stopped by pfnServe.
    424  * @retval  VERR_TCP_SERVER_SHUTDOWN if shut down by RTTcpServerShutdown.
    425  *
    426  * @param   pServer         The server handle as returned from RTTcpServerCreateEx().
    427  * @param   pfnServe        The function which will serve a new client connection.
     390 * @retval  VERR_UDP_SERVER_STOP if stopped by pfnServe.
     391 * @retval  VERR_UDP_SERVER_SHUTDOWN if shut down by RTUdpServerShutdown.
     392 *
     393 * @param   pServer         The server handle as returned from RTUdpServerCreateEx().
     394 * @param   pfnServe        The function which will handle incoming datagrams.
    428395 * @param   pvUser          User argument passed to pfnServe.
    429396 */
    430 RTR3DECL(int) RTTcpServerListen(PRTTCPSERVER pServer, PFNRTTCPSERVE pfnServe, void *pvUser)
     397RTR3DECL(int) RTUdpServerListen(PRTUDPSERVER pServer, PFNRTUDPSERVE pfnServe, void *pvUser)
    431398{
    432399    /*
     
    435402    AssertPtrReturn(pfnServe, VERR_INVALID_POINTER);
    436403    AssertPtrReturn(pServer, VERR_INVALID_HANDLE);
    437     AssertReturn(pServer->u32Magic == RTTCPSERVER_MAGIC, VERR_INVALID_HANDLE);
     404    AssertReturn(pServer->u32Magic == RTUDPSERVER_MAGIC, VERR_INVALID_HANDLE);
    438405    AssertReturn(RTMemPoolRetain(pServer) != UINT32_MAX, VERR_INVALID_HANDLE);
    439406
    440407    int rc = VERR_INVALID_STATE;
    441     if (rtTcpServerTrySetState(pServer, RTTCPSERVERSTATE_ACCEPTING, RTTCPSERVERSTATE_CREATED))
     408    if (rtUdpServerTrySetState(pServer, RTUDPSERVERSTATE_WAITING, RTUDPSERVERSTATE_CREATED))
    442409    {
    443410        Assert(!pServer->pfnServe);
    444411        Assert(!pServer->pvUser);
    445412        Assert(pServer->Thread == NIL_RTTHREAD);
    446         Assert(pServer->hClientSocket == NIL_RTSOCKET);
    447413
    448414        pServer->pfnServe = pfnServe;
     
    450416        pServer->Thread   = RTThreadSelf();
    451417        Assert(pServer->Thread != NIL_RTTHREAD);
    452         rc = rtTcpServerListen(pServer);
     418        rc = rtUdpServerListen(pServer);
    453419    }
    454420    else
     
    463429
    464430/**
    465  * Internal worker common for RTTcpServerListen and the thread created by
    466  * RTTcpServerCreate().
     431 * Internal worker common for RTUdpServerListen and the thread created by
     432 * RTUdpServerCreate().
    467433 *
    468434 * The caller makes sure it has its own memory reference and releases it upon
    469435 * return.
    470436 */
    471 static int rtTcpServerListen(PRTTCPSERVER pServer)
    472 {
    473     /*
    474      * Accept connection loop.
     437static int rtUdpServerListen(PRTUDPSERVER pServer)
     438{
     439    /*
     440     * Wait for incoming datagrams loop.
    475441     */
    476442    for (;;)
     
    480446         * allow others to close it while we're stuck in rtSocketAccept.
    481447         */
    482         RTTCPSERVERSTATE    enmState      = pServer->enmState;
    483         RTSOCKET            hServerSocket;
    484         ASMAtomicXchgHandle(&pServer->hServerSocket, NIL_RTSOCKET, &hServerSocket);
    485         if (hServerSocket != NIL_RTSOCKET)
    486         {
    487             RTSocketRetain(hServerSocket);
    488             ASMAtomicWriteHandle(&pServer->hServerSocket, hServerSocket);
    489         }
    490         if (    enmState != RTTCPSERVERSTATE_ACCEPTING
    491             &&  enmState != RTTCPSERVERSTATE_SERVING)
    492         {
    493             RTSocketRelease(hServerSocket);
    494             return rtTcpServerListenCleanup(pServer);
    495         }
    496         if (!rtTcpServerTrySetState(pServer, RTTCPSERVERSTATE_ACCEPTING, enmState))
    497         {
    498             RTSocketRelease(hServerSocket);
     448        RTUDPSERVERSTATE    enmState      = pServer->enmState;
     449        RTSOCKET            hSocket;
     450        ASMAtomicReadHandle(&pServer->hSocket, &hSocket);
     451        if (hSocket != NIL_RTSOCKET)
     452            RTSocketRetain(hSocket);
     453        if (    enmState != RTUDPSERVERSTATE_WAITING
     454            &&  enmState != RTUDPSERVERSTATE_RECEIVING)
     455        {
     456            RTSocketRelease(hSocket);
     457            return rtUdpServerListenCleanup(pServer);
     458        }
     459        if (!rtUdpServerTrySetState(pServer, RTUDPSERVERSTATE_WAITING, enmState))
     460        {
     461            RTSocketRelease(hSocket);
    499462            continue;
    500463        }
    501464
    502465        /*
    503          * Accept connection.
     466         * Wait for incoming datagrams or errors.
    504467         */
    505         struct sockaddr_in  RemoteAddr;
    506         size_t              cbRemoteAddr = sizeof(RemoteAddr);
    507         RTSOCKET            hClientSocket;
    508         RT_ZERO(RemoteAddr);
    509         int rc = rtSocketAccept(hServerSocket, &hClientSocket, (struct sockaddr *)&RemoteAddr, &cbRemoteAddr);
    510         RTSocketRelease(hServerSocket);
     468        uint32_t fEvents;
     469        int rc = RTSocketSelectOneEx(hSocket, RTSOCKET_EVT_READ | RTSOCKET_EVT_ERROR, &fEvents, 1000);
     470        RTSocketRelease(hSocket);
     471        if (rc == VERR_TIMEOUT)
     472            continue;
    511473        if (RT_FAILURE(rc))
    512474        {
     
    515477                || rc == VERR_INVALID_PARAMETER
    516478                || rc == VERR_NET_NOT_SOCKET)
    517                 return rtTcpServerListenCleanup(pServer);
     479                return rtUdpServerListenCleanup(pServer);
    518480            continue;
    519481        }
    520         RTSocketSetInheritance(hClientSocket, false /*fInheritable*/);
     482        if (fEvents & RTSOCKET_EVT_ERROR)
     483            return rtUdpServerListenCleanup(pServer);
    521484
    522485        /*
    523486         * Run a pfnServe callback.
    524487         */
    525         if (!rtTcpServerTrySetState(pServer, RTTCPSERVERSTATE_SERVING, RTTCPSERVERSTATE_ACCEPTING))
    526         {
    527             rtTcpClose(hClientSocket, "rtTcpServerListen", true /*fTryGracefulShutdown*/);
    528             return rtTcpServerListenCleanup(pServer);
    529         }
    530         RTSocketRetain(hClientSocket);
    531         rtTcpAtomicXchgSock(&pServer->hClientSocket, hClientSocket);
    532         rc = pServer->pfnServe(hClientSocket, pServer->pvUser);
    533         rtTcpServerDestroySocket(&pServer->hClientSocket, "Listener: client (secondary)", true /*fTryGracefulShutdown*/);
    534         RTSocketRelease(hClientSocket);
     488        if (!rtUdpServerTrySetState(pServer, RTUDPSERVERSTATE_RECEIVING, RTUDPSERVERSTATE_WAITING))
     489            return rtUdpServerListenCleanup(pServer);
     490        rc = pServer->pfnServe(hSocket, pServer->pvUser);
    535491
    536492        /*
    537493         * Stop the server?
    538494         */
    539         if (rc == VERR_TCP_SERVER_STOP)
    540         {
    541             if (rtTcpServerTrySetState(pServer, RTTCPSERVERSTATE_STOPPING, RTTCPSERVERSTATE_SERVING))
     495        if (rc == VERR_UDP_SERVER_STOP)
     496        {
     497            if (rtUdpServerTrySetState(pServer, RTUDPSERVERSTATE_STOPPING, RTUDPSERVERSTATE_RECEIVING))
    542498            {
    543499                /*
     
    545501                 * we cannot safely access the handle so we'll have to return here.
    546502                 */
    547                 hServerSocket = rtTcpAtomicXchgSock(&pServer->hServerSocket, NIL_RTSOCKET);
    548                 rtTcpServerSetState(pServer, RTTCPSERVERSTATE_STOPPED, RTTCPSERVERSTATE_STOPPING);
    549                 rtTcpClose(hServerSocket, "Listener: server stopped", false /*fTryGracefulShutdown*/);
     503                hSocket = rtUdpAtomicXchgSock(&pServer->hSocket, NIL_RTSOCKET);
     504                rtUdpServerSetState(pServer, RTUDPSERVERSTATE_STOPPED, RTUDPSERVERSTATE_STOPPING);
     505                rtUdpClose(hSocket, "Listener: server stopped");
    550506            }
    551507            else
    552                 rtTcpServerListenCleanup(pServer); /* ignore rc */
     508                rtUdpServerListenCleanup(pServer); /* ignore rc */
    553509            return rc;
    554510        }
     
    560516 * Clean up after listener.
    561517 */
    562 static int rtTcpServerListenCleanup(PRTTCPSERVER pServer)
    563 {
    564     /*
    565      * Close the server socket, the client one shouldn't be set.
    566      */
    567     rtTcpServerDestroySocket(&pServer->hServerSocket, "ListenCleanup", false /*fTryGracefulShutdown*/);
    568     Assert(pServer->hClientSocket == NIL_RTSOCKET);
     518static int rtUdpServerListenCleanup(PRTUDPSERVER pServer)
     519{
     520    /*
     521     * Close the server socket.
     522     */
     523    rtUdpServerDestroySocket(&pServer->hSocket, "ListenCleanup");
    569524
    570525    /*
    571526     * Figure the return code and make sure the state is OK.
    572527     */
    573     RTTCPSERVERSTATE enmState = pServer->enmState;
     528    RTUDPSERVERSTATE enmState = pServer->enmState;
    574529    switch (enmState)
    575530    {
    576         case RTTCPSERVERSTATE_STOPPING:
    577         case RTTCPSERVERSTATE_STOPPED:
    578             return VERR_TCP_SERVER_SHUTDOWN;
    579 
    580         case RTTCPSERVERSTATE_ACCEPTING:
    581             rtTcpServerTrySetState(pServer, RTTCPSERVERSTATE_STOPPED, enmState);
    582             return VERR_TCP_SERVER_DESTROYED;
    583 
    584         case RTTCPSERVERSTATE_DESTROYING:
    585             return VERR_TCP_SERVER_DESTROYED;
    586 
    587         case RTTCPSERVERSTATE_STARTING:
    588         case RTTCPSERVERSTATE_SERVING:
     531        case RTUDPSERVERSTATE_STOPPING:
     532        case RTUDPSERVERSTATE_STOPPED:
     533            return VERR_UDP_SERVER_SHUTDOWN;
     534
     535        case RTUDPSERVERSTATE_WAITING:
     536            rtUdpServerTrySetState(pServer, RTUDPSERVERSTATE_STOPPED, enmState);
     537            return VERR_UDP_SERVER_DESTROYED;
     538
     539        case RTUDPSERVERSTATE_DESTROYING:
     540            return VERR_UDP_SERVER_DESTROYED;
     541
     542        case RTUDPSERVERSTATE_STARTING:
     543        case RTUDPSERVERSTATE_RECEIVING:
    589544        default:
    590545            AssertMsgFailedReturn(("pServer=%p enmState=%d\n", pServer, enmState), VERR_INTERNAL_ERROR_4);
     
    594549
    595550/**
    596  * Listen and accept one incoming connection.
    597  *
    598  * This is an alternative to RTTcpServerListen for the use the callbacks are not
    599  * possible.
    600  *
    601  * @returns IPRT status code.
    602  * @retval  VERR_TCP_SERVER_SHUTDOWN if shut down by RTTcpServerShutdown.
    603  * @retval  VERR_INTERRUPTED if the listening was interrupted.
    604  *
    605  * @param   pServer         The server handle as returned from RTTcpServerCreateEx().
    606  * @param   phClientSocket  Where to return the socket handle to the client
    607  *                          connection (on success only).  This must be closed
    608  *                          by calling RTTcpServerDisconnectClient2().
    609  */
    610 RTR3DECL(int) RTTcpServerListen2(PRTTCPSERVER pServer, PRTSOCKET phClientSocket)
    611 {
    612     /*
    613      * Validate input and retain the instance.
    614      */
    615     AssertPtrReturn(phClientSocket, VERR_INVALID_HANDLE);
    616     *phClientSocket = NIL_RTSOCKET;
    617     AssertReturn(pServer->u32Magic == RTTCPSERVER_MAGIC, VERR_INVALID_HANDLE);
    618     AssertReturn(RTMemPoolRetain(pServer) != UINT32_MAX, VERR_INVALID_HANDLE);
    619 
    620     int rc = VERR_INVALID_STATE;
    621     for (;;)
    622     {
    623         /*
    624          * Change state, getting an extra reference to the socket so we can
    625          * allow others to close it while we're stuck in rtSocketAccept.
    626          */
    627         RTTCPSERVERSTATE    enmState      = pServer->enmState;
    628         RTSOCKET            hServerSocket;
    629         ASMAtomicXchgHandle(&pServer->hServerSocket, NIL_RTSOCKET, &hServerSocket);
    630         if (hServerSocket != NIL_RTSOCKET)
    631         {
    632             RTSocketRetain(hServerSocket);
    633             ASMAtomicWriteHandle(&pServer->hServerSocket, hServerSocket);
    634         }
    635         if (    enmState != RTTCPSERVERSTATE_SERVING
    636             &&  enmState != RTTCPSERVERSTATE_CREATED)
    637         {
    638             RTSocketRelease(hServerSocket);
    639             return rtTcpServerListenCleanup(pServer);
    640         }
    641         if (!rtTcpServerTrySetState(pServer, RTTCPSERVERSTATE_ACCEPTING, enmState))
    642         {
    643             RTSocketRelease(hServerSocket);
    644             continue;
    645         }
    646         Assert(!pServer->pfnServe);
    647         Assert(!pServer->pvUser);
    648         Assert(pServer->Thread == NIL_RTTHREAD);
    649         Assert(pServer->hClientSocket == NIL_RTSOCKET);
    650 
    651         /*
    652          * Accept connection.
    653          */
    654         struct sockaddr_in  RemoteAddr;
    655         size_t              cbRemoteAddr = sizeof(RemoteAddr);
    656         RTSOCKET            hClientSocket;
    657         RT_ZERO(RemoteAddr);
    658         rc = rtSocketAccept(hServerSocket, &hClientSocket, (struct sockaddr *)&RemoteAddr, &cbRemoteAddr);
    659         RTSocketRelease(hServerSocket);
    660         if (RT_FAILURE(rc))
    661         {
    662             if (!rtTcpServerTrySetState(pServer, RTTCPSERVERSTATE_CREATED, RTTCPSERVERSTATE_ACCEPTING))
    663                 rc = rtTcpServerListenCleanup(pServer);
    664             if (RT_FAILURE(rc))
    665                 break;
    666             continue;
    667         }
    668         RTSocketSetInheritance(hClientSocket, false /*fInheritable*/);
    669 
    670         /*
    671          * Chance to the 'serving' state and return the socket.
    672          */
    673         if (rtTcpServerTrySetState(pServer, RTTCPSERVERSTATE_SERVING, RTTCPSERVERSTATE_ACCEPTING))
    674         {
    675             *phClientSocket = hClientSocket;
    676             rc = VINF_SUCCESS;
    677         }
    678         else
    679         {
    680             rtTcpClose(hClientSocket, "RTTcpServerListen2", true /*fTryGracefulShutdown*/);
    681             rc = rtTcpServerListenCleanup(pServer);
    682         }
    683         break;
    684     }
    685 
    686     RTMemPoolRelease(RTMEMPOOL_DEFAULT, pServer);
    687     return rc;
    688 }
    689 
    690 
    691 /**
    692  * Terminate the open connection to the server.
    693  *
    694  * @returns iprt status code.
    695  * @param   pServer         Handle to the server.
    696  */
    697 RTR3DECL(int) RTTcpServerDisconnectClient(PRTTCPSERVER pServer)
    698 {
    699     /*
    700      * Validate input and retain the instance.
    701      */
    702     AssertPtrReturn(pServer, VERR_INVALID_HANDLE);
    703     AssertReturn(pServer->u32Magic == RTTCPSERVER_MAGIC, VERR_INVALID_HANDLE);
    704     AssertReturn(RTMemPoolRetain(pServer) != UINT32_MAX, VERR_INVALID_HANDLE);
    705 
    706     int rc = rtTcpServerDestroySocket(&pServer->hClientSocket, "DisconnectClient: client", true /*fTryGracefulShutdown*/);
    707 
    708     RTMemPoolRelease(RTMEMPOOL_DEFAULT, pServer);
    709     return rc;
    710 }
    711 
    712 
    713 /**
    714  * Terminates an open client connect when using RTTcpListen2
    715  *
    716  * @returns IPRT status code.
    717  * @param   hClientSocket   The client socket handle.  This will be invalid upon
    718  *                          return, whether successful or not.  NIL is quietly
    719  *                          ignored (VINF_SUCCESS).
    720  */
    721 RTR3DECL(int) RTTcpServerDisconnectClient2(RTSOCKET hClientSocket)
    722 {
    723     return rtTcpClose(hClientSocket, "RTTcpServerDisconnectClient2", true /*fTryGracefulShutdown*/);
    724 }
    725 
    726 
    727 /**
    728  * Shuts down the server, leaving client connections open.
     551 * Shuts down the server.
    729552 *
    730553 * @returns IPRT status code.
    731554 * @param   pServer         Handle to the server.
    732555 */
    733 RTR3DECL(int) RTTcpServerShutdown(PRTTCPSERVER pServer)
     556RTR3DECL(int) RTUdpServerShutdown(PRTUDPSERVER pServer)
    734557{
    735558    /*
     
    737560     */
    738561    AssertPtrReturn(pServer, VERR_INVALID_HANDLE);
    739     AssertReturn(pServer->u32Magic == RTTCPSERVER_MAGIC, VERR_INVALID_HANDLE);
     562    AssertReturn(pServer->u32Magic == RTUDPSERVER_MAGIC, VERR_INVALID_HANDLE);
    740563    AssertReturn(RTMemPoolRetain(pServer) != UINT32_MAX, VERR_INVALID_HANDLE);
    741564
     
    745568    for (;;)
    746569    {
    747         RTTCPSERVERSTATE enmState = pServer->enmState;
    748         if (    enmState != RTTCPSERVERSTATE_ACCEPTING
    749             &&  enmState != RTTCPSERVERSTATE_SERVING)
     570        RTUDPSERVERSTATE enmState = pServer->enmState;
     571        if (    enmState != RTUDPSERVERSTATE_WAITING
     572            &&  enmState != RTUDPSERVERSTATE_RECEIVING)
    750573        {
    751574            RTMemPoolRelease(RTMEMPOOL_DEFAULT, pServer);
    752575            switch (enmState)
    753576            {
    754                 case RTTCPSERVERSTATE_CREATED:
    755                 case RTTCPSERVERSTATE_STARTING:
     577                case RTUDPSERVERSTATE_CREATED:
     578                case RTUDPSERVERSTATE_STARTING:
    756579                default:
    757580                    AssertMsgFailed(("%d\n", enmState));
    758581                    return VERR_INVALID_STATE;
    759582
    760                 case RTTCPSERVERSTATE_STOPPING:
    761                 case RTTCPSERVERSTATE_STOPPED:
     583                case RTUDPSERVERSTATE_STOPPING:
     584                case RTUDPSERVERSTATE_STOPPED:
    762585                    return VINF_SUCCESS;
    763586
    764                 case RTTCPSERVERSTATE_DESTROYING:
    765                     return VERR_TCP_SERVER_DESTROYED;
     587                case RTUDPSERVERSTATE_DESTROYING:
     588                    return VERR_UDP_SERVER_DESTROYED;
    766589            }
    767590        }
    768         if (rtTcpServerTrySetState(pServer, RTTCPSERVERSTATE_STOPPING, enmState))
    769         {
    770             rtTcpServerDestroySocket(&pServer->hServerSocket, "RTTcpServerShutdown", false /*fTryGracefulShutdown*/);
    771             rtTcpServerSetState(pServer, RTTCPSERVERSTATE_STOPPED, RTTCPSERVERSTATE_STOPPING);
     591        if (rtUdpServerTrySetState(pServer, RTUDPSERVERSTATE_STOPPING, enmState))
     592        {
     593            rtUdpServerDestroySocket(&pServer->hSocket, "RTUdpServerShutdown");
     594            rtUdpServerSetState(pServer, RTUDPSERVERSTATE_STOPPED, RTUDPSERVERSTATE_STOPPING);
    772595
    773596            RTMemPoolRelease(RTMEMPOOL_DEFAULT, pServer);
     
    779602
    780603/**
    781  * Closes down and frees a TCP Server.
    782  * This will also terminate any open connections to the server.
     604 * Closes down and frees a UDP Server.
    783605 *
    784606 * @returns iprt status code.
    785607 * @param   pServer         Handle to the server.
    786608 */
    787 RTR3DECL(int) RTTcpServerDestroy(PRTTCPSERVER pServer)
     609RTR3DECL(int) RTUdpServerDestroy(PRTUDPSERVER pServer)
    788610{
    789611    /*
     
    791613     */
    792614    AssertPtrReturn(pServer, VERR_INVALID_HANDLE);
    793     AssertReturn(pServer->u32Magic == RTTCPSERVER_MAGIC, VERR_INVALID_HANDLE);
     615    AssertReturn(pServer->u32Magic == RTUDPSERVER_MAGIC, VERR_INVALID_HANDLE);
    794616    AssertReturn(RTMemPoolRetain(pServer) != UINT32_MAX, VERR_INVALID_HANDLE); /* paranoia */
    795617
     
    800622    {
    801623        bool             fDestroyable;
    802         RTTCPSERVERSTATE enmState = pServer->enmState;
     624        RTUDPSERVERSTATE enmState = pServer->enmState;
    803625        switch (enmState)
    804626        {
    805             case RTTCPSERVERSTATE_STARTING:
    806             case RTTCPSERVERSTATE_ACCEPTING:
    807             case RTTCPSERVERSTATE_SERVING:
    808             case RTTCPSERVERSTATE_CREATED:
    809             case RTTCPSERVERSTATE_STOPPED:
    810                 fDestroyable = rtTcpServerTrySetState(pServer, RTTCPSERVERSTATE_DESTROYING, enmState);
     627            case RTUDPSERVERSTATE_STARTING:
     628            case RTUDPSERVERSTATE_WAITING:
     629            case RTUDPSERVERSTATE_RECEIVING:
     630            case RTUDPSERVERSTATE_CREATED:
     631            case RTUDPSERVERSTATE_STOPPED:
     632                fDestroyable = rtUdpServerTrySetState(pServer, RTUDPSERVERSTATE_DESTROYING, enmState);
    811633                break;
    812634
    813635            /* destroyable states */
    814             case RTTCPSERVERSTATE_STOPPING:
     636            case RTUDPSERVERSTATE_STOPPING:
    815637                fDestroyable = true;
    816638                break;
     
    831653     * Destroy it.
    832654     */
    833     ASMAtomicWriteU32(&pServer->u32Magic, ~RTTCPSERVER_MAGIC);
    834     rtTcpServerDestroySocket(&pServer->hServerSocket, "Destroyer: server", false /*fTryGracefulShutdown*/);
    835     rtTcpServerDestroySocket(&pServer->hClientSocket, "Destroyer: client", true  /*fTryGracefulShutdown*/);
     655    ASMAtomicWriteU32(&pServer->u32Magic, ~RTUDPSERVER_MAGIC);
     656    rtUdpServerDestroySocket(&pServer->hSocket, "Destroyer: server");
    836657
    837658    /*
     
    844665
    845666
    846 RTR3DECL(int) RTTcpClientConnect(const char *pszAddress, uint32_t uPort, PRTSOCKET pSock)
    847 {
    848     int rc;
    849 
    850     /*
    851      * Validate input.
    852      */
    853     AssertReturn(uPort > 0, VERR_INVALID_PARAMETER);
    854     AssertPtrReturn(pszAddress, VERR_INVALID_POINTER);
    855 
    856 #ifdef RT_OS_WINDOWS
    857     /*
    858      * Initialize WinSock and check version.
    859      */
    860     WORD    wVersionRequested = MAKEWORD(1, 1);
    861     WSADATA wsaData;
    862     rc = WSAStartup(wVersionRequested, &wsaData);
    863     if (wsaData.wVersion != wVersionRequested)
    864     {
    865         AssertMsgFailed(("Wrong winsock version\n"));
    866         return VERR_NOT_SUPPORTED;
    867     }
    868 #endif
    869 
    870     /*
    871      * Resolve the address.
    872      */
    873     struct hostent *pHostEnt = NULL;
    874     pHostEnt = gethostbyname(pszAddress);
    875     if (!pHostEnt)
    876     {
    877         struct in_addr InAddr;
    878         InAddr.s_addr = inet_addr(pszAddress);
    879         pHostEnt = gethostbyaddr((char *)&InAddr, 4, AF_INET);
    880         if (!pHostEnt)
    881         {
    882             rc = rtSocketResolverError();
    883             AssertMsgFailed(("Could not resolve '%s', rc=%Rrc\n", pszAddress, rc));
    884             return rc;
    885         }
    886     }
    887 
    888     /*
    889      * Create the socket and connect.
    890      */
    891     RTSOCKET Sock;
    892     rc = rtSocketCreate(&Sock, PF_INET, SOCK_STREAM, 0);
    893     if (RT_SUCCESS(rc))
    894     {
    895         RTSocketSetInheritance(Sock, false /*fInheritable*/);
    896 
    897         struct sockaddr_in InAddr;
    898         RT_ZERO(InAddr);
    899         InAddr.sin_family = AF_INET;
    900         InAddr.sin_port = htons(uPort);
    901         InAddr.sin_addr = *((struct in_addr *)pHostEnt->h_addr);
    902         rc = rtSocketConnect(Sock, (struct sockaddr *)&InAddr, sizeof(InAddr));
    903         if (RT_SUCCESS(rc))
    904         {
    905             *pSock = Sock;
    906             return VINF_SUCCESS;
    907         }
    908 
    909         rtTcpClose(Sock, "RTTcpClientConnect", false /*fTryGracefulShutdown*/);
    910     }
    911     return rc;
    912 }
    913 
    914 
    915 RTR3DECL(int) RTTcpClientClose(RTSOCKET Sock)
    916 {
    917     return rtTcpClose(Sock, "RTTcpClientClose", true /*fTryGracefulShutdown*/);
    918 }
    919 
    920 
    921 RTR3DECL(int) RTTcpClientCloseEx(RTSOCKET Sock, bool fGracefulShutdown)
    922 {
    923     return rtTcpClose(Sock, "RTTcpClientCloseEx", fGracefulShutdown);
    924 }
    925 
    926 
    927 #ifdef FIX_FOR_3_2
    928 /**
    929  * Changes the blocking mode of the socket.
    930  *
    931  * @returns 0 on success, -1 on failure.
    932  * @param   hSocket             The socket to work on.
    933  * @param   fBlocking           The desired mode of operation.
    934  */
    935 static int rtTcpSetBlockingMode(RTHCUINTPTR hSocket, bool fBlocking)
    936 {
    937     int     rc        = VINF_SUCCESS;
    938 #ifdef RT_OS_WINDOWS
    939     u_long  uBlocking = fBlocking ? 0 : 1;
    940     if (ioctlsocket(hSocket, FIONBIO, &uBlocking))
    941         return -1;
    942 
    943 #else
    944     int     fFlags    = fcntl(hSocket, F_GETFL, 0);
    945     if (fFlags == -1)
    946         return -1;
    947 
    948     if (fBlocking)
    949         fFlags &= ~O_NONBLOCK;
    950     else
    951         fFlags |= O_NONBLOCK;
    952     if (fcntl(hSocket, F_SETFL, fFlags) == -1)
    953        return -1;
    954 #endif
    955 
    956     return 0;
    957 }
    958 #endif
    959 
    960 
    961667/**
    962668 * Internal close function which does all the proper bitching.
    963669 */
    964 static int rtTcpClose(RTSOCKET Sock, const char *pszMsg, bool fTryGracefulShutdown)
     670static int rtUdpClose(RTSOCKET Sock, const char *pszMsg)
    965671{
    966672    int rc;
     
    971677
    972678    /*
    973      * Try to gracefully shut it down.
    974      */
    975     if (fTryGracefulShutdown)
    976     {
    977         rc = RTSocketShutdown(Sock, false /*fRead*/, true /*fWrite*/);
    978 #ifdef FIX_FOR_3_2
    979         RTHCUINTPTR hNative = RTSocketToNative(Sock);
    980         if (RT_SUCCESS(rc) && rtTcpSetBlockingMode(hNative, false /*fBlocking*/) == 0)
    981 #else
    982         if (RT_SUCCESS(rc))
    983 #endif
    984         {
    985 
    986             size_t      cbReceived = 0;
    987             uint64_t    u64Start   = RTTimeMilliTS();
    988             while (   cbReceived < _1G
    989                    && RTTimeMilliTS() - u64Start < 30000)
    990             {
    991 #ifdef FIX_FOR_3_2
    992                 fd_set FdSetR;
    993                 FD_ZERO(&FdSetR);
    994                 FD_SET(hNative, &FdSetR);
    995 
    996                 fd_set FdSetE;
    997                 FD_ZERO(&FdSetE);
    998                 FD_SET(hNative, &FdSetE);
    999 
    1000                 struct timeval TvTimeout;
    1001                 TvTimeout.tv_sec  = 1;
    1002                 TvTimeout.tv_usec = 0;
    1003                 rc = select(hNative + 1, &FdSetR, NULL, &FdSetE, &TvTimeout);
    1004                 if (rc == 0)
    1005                     continue;
    1006                 if (rc < 0)
    1007                     break;
    1008                 if (FD_ISSET(hNative, &FdSetE))
    1009                     break;
    1010 #else
    1011                 uint32_t fEvents;
    1012                 rc = RTSocketSelectOneEx(Sock, RTSOCKET_EVT_READ | RTSOCKET_EVT_ERROR, &fEvents, 1000);
    1013                 if (rc == VERR_TIMEOUT)
    1014                     continue;
    1015                 if (RT_FAILURE(rc))
    1016                     break;
    1017                 if (fEvents & RTSOCKET_EVT_ERROR)
    1018                     break;
    1019 #endif
    1020 
    1021                 char abBitBucket[16*_1K];
    1022 #ifdef FIX_FOR_3_2
    1023                 ssize_t cbRead = recv(hNative, &abBitBucket[0], sizeof(abBitBucket), MSG_NOSIGNAL);
    1024                 if (cbRead == 0)
    1025                     break; /* orderly shutdown in progress */
    1026                 if (cbRead < 0 && errno != EAGAIN)
    1027                     break; /* some kind of error, never mind which... */
    1028 #else
    1029                 size_t cbRead;
    1030                 rc = RTSocketReadNB(Sock, &abBitBucket[0], sizeof(abBitBucket), &cbRead);
    1031                 if (RT_FAILURE(rc))
    1032                     break; /* some kind of error, never mind which... */
    1033                 if (rc != VINF_TRY_AGAIN && !cbRead)
    1034                     break; /* orderly shutdown in progress */
    1035 #endif
    1036 
    1037                 cbReceived += cbRead;
    1038             }
    1039         }
    1040     }
    1041 
    1042     /*
    1043679     * Close the socket handle (drops our reference to it).
    1044680     */
     
    1047683
    1048684
    1049 RTR3DECL(int) RTTcpRead(RTSOCKET Sock, void *pvBuffer, size_t cbBuffer, size_t *pcbRead)
    1050 {
    1051     return RTSocketRead(Sock, pvBuffer, cbBuffer, pcbRead);
    1052 }
    1053 
    1054 
    1055 RTR3DECL(int)  RTTcpWrite(RTSOCKET Sock, const void *pvBuffer, size_t cbBuffer)
    1056 {
    1057     return RTSocketWrite(Sock, pvBuffer, cbBuffer);
    1058 }
    1059 
    1060 
    1061 RTR3DECL(int)  RTTcpFlush(RTSOCKET Sock)
    1062 {
    1063     int fFlag = 1;
    1064     int rc = rtSocketSetOpt(Sock, IPPROTO_TCP, TCP_NODELAY, &fFlag, sizeof(fFlag));
     685RTR3DECL(int) RTUdpRead(RTSOCKET Sock, void *pvBuffer, size_t cbBuffer, size_t *pcbRead, PRTNETADDR pSrcAddr)
     686{
     687    if (!RT_VALID_PTR(pcbRead))
     688        return VERR_INVALID_POINTER;
     689    return RTSocketReadFrom(Sock, pvBuffer, cbBuffer, pcbRead, pSrcAddr);
     690}
     691
     692
     693RTR3DECL(int)  RTUdpWrite(PRTUDPSERVER pServer, const void *pvBuffer, size_t cbBuffer, PCRTNETADDR pDstAddr)
     694{
     695    /*
     696     * Validate input and retain the instance.
     697     */
     698    AssertPtrReturn(pServer, VERR_INVALID_HANDLE);
     699    AssertReturn(pServer->u32Magic == RTUDPSERVER_MAGIC, VERR_INVALID_HANDLE);
     700    AssertReturn(RTMemPoolRetain(pServer) != UINT32_MAX, VERR_INVALID_HANDLE);
     701
     702    RTSOCKET hSocket;
     703    ASMAtomicReadHandle(&pServer->hSocket, &hSocket);
     704    if (hSocket == NIL_RTSOCKET)
     705    {
     706        RTMemPoolRelease(RTMEMPOOL_DEFAULT, pServer);
     707        return VERR_INVALID_HANDLE;
     708    }
     709    RTSocketRetain(hSocket);
     710
     711    int rc = VINF_SUCCESS;
     712    RTUDPSERVERSTATE enmState = pServer->enmState;
     713    if (    enmState != RTUDPSERVERSTATE_CREATED
     714        &&  enmState != RTUDPSERVERSTATE_STARTING
     715        &&  enmState != RTUDPSERVERSTATE_WAITING
     716        &&  enmState != RTUDPSERVERSTATE_RECEIVING
     717        &&  enmState != RTUDPSERVERSTATE_STOPPING)
     718        rc = VERR_INVALID_STATE;
     719
    1065720    if (RT_SUCCESS(rc))
    1066     {
    1067         fFlag = 0;
    1068         rc = rtSocketSetOpt(Sock, IPPROTO_TCP, TCP_NODELAY, &fFlag, sizeof(fFlag));
    1069     }
     721        rc = RTSocketWriteTo(hSocket, pvBuffer, cbBuffer, pDstAddr);
     722
     723    RTSocketRelease(hSocket);
     724    RTMemPoolRelease(RTMEMPOOL_DEFAULT, pServer);
     725
    1070726    return rc;
    1071727}
    1072728
    1073 
    1074 RTR3DECL(int)  RTTcpSetSendCoalescing(RTSOCKET Sock, bool fEnable)
    1075 {
    1076     int fFlag = fEnable ? 0 : 1;
    1077     return rtSocketSetOpt(Sock, IPPROTO_TCP, TCP_NODELAY, &fFlag, sizeof(fFlag));
    1078 }
    1079 
    1080 
    1081 RTR3DECL(int)  RTTcpSelectOne(RTSOCKET Sock, RTMSINTERVAL cMillies)
    1082 {
    1083     return RTSocketSelectOne(Sock, cMillies);
    1084 }
    1085 
    1086 
    1087 RTR3DECL(int)  RTTcpSelectOneEx(RTSOCKET Sock, uint32_t fEvents, uint32_t *pfEvents,
    1088                                 RTMSINTERVAL cMillies)
    1089 {
    1090     return RTSocketSelectOneEx(Sock, fEvents, pfEvents, cMillies);
    1091 }
    1092 
    1093 
    1094 RTR3DECL(int) RTTcpGetLocalAddress(RTSOCKET Sock, PRTNETADDR pAddr)
    1095 {
    1096     return RTSocketGetLocalAddress(Sock, pAddr);
    1097 }
    1098 
    1099 
    1100 RTR3DECL(int) RTTcpGetPeerAddress(RTSOCKET Sock, PRTNETADDR pAddr)
    1101 {
    1102     return RTSocketGetPeerAddress(Sock, pAddr);
    1103 }
    1104 
    1105 
    1106 RTR3DECL(int)  RTTcpSgWrite(RTSOCKET Sock, PCRTSGBUF pSgBuf)
    1107 {
    1108     return RTSocketSgWrite(Sock, pSgBuf);
    1109 }
    1110 
    1111 
    1112 RTR3DECL(int) RTTcpSgWriteL(RTSOCKET hSocket, size_t cSegs, ...)
    1113 {
    1114     va_list va;
    1115     va_start(va, cSegs);
    1116     int rc = RTSocketSgWriteLV(hSocket, cSegs, va);
    1117     va_end(va);
    1118     return rc;
    1119 }
    1120 
    1121 
    1122 RTR3DECL(int) RTTcpSgWriteLV(RTSOCKET hSocket, size_t cSegs, va_list va)
    1123 {
    1124     return RTSocketSgWriteLV(hSocket, cSegs, va);
    1125 }
    1126 
    1127 
    1128 RTR3DECL(int) RTTcpReadNB(RTSOCKET Sock, void *pvBuffer, size_t cbBuffer, size_t *pcbRead)
    1129 {
    1130     return RTSocketReadNB(Sock, pvBuffer, cbBuffer, pcbRead);
    1131 }
    1132 
    1133 
    1134 RTR3DECL(int) RTTcpWriteNB(RTSOCKET Sock, const void *pvBuffer, size_t cbBuffer, size_t *pcbWritten)
    1135 {
    1136     return RTSocketWriteNB(Sock, pvBuffer, cbBuffer, pcbWritten);
    1137 }
    1138 
    1139 
    1140 RTR3DECL(int)  RTTcpSgWriteNB(RTSOCKET Sock, PCRTSGBUF pSgBuf, size_t *pcbWritten)
    1141 {
    1142     return RTSocketSgWriteNB(Sock, pSgBuf, pcbWritten);
    1143 }
    1144 
    1145 
    1146 RTR3DECL(int) RTTcpSgWriteLNB(RTSOCKET hSocket, size_t cSegs, size_t *pcbWritten, ...)
    1147 {
    1148     va_list va;
    1149     va_start(va, pcbWritten);
    1150     int rc = RTSocketSgWriteLVNB(hSocket, cSegs, pcbWritten, va);
    1151     va_end(va);
    1152     return rc;
    1153 }
    1154 
    1155 
    1156 RTR3DECL(int) RTTcpSgWriteLVNB(RTSOCKET hSocket, size_t cSegs, size_t *pcbWritten, va_list va)
    1157 {
    1158     return RTSocketSgWriteLVNB(hSocket, cSegs, pcbWritten, va);
    1159 }
    1160 
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