cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * TestExecServ - Basic Remote Execution Service, TCP/IP Transport Layer.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * Copyright (C) 2010-2014 Oracle Corporation
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * available from http://www.virtualbox.org. This file is free software;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * you can redistribute it and/or modify it under the terms of the GNU
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * General Public License (GPL) as published by the Free Software
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * The contents of this file may alternatively be used under the terms
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * of the Common Development and Distribution License Version 1.0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * VirtualBox OSE distribution, in which case the provisions of the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * CDDL are applicable instead of those of the GPL.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * You may elect to license modified versions of this file under the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * terms and conditions of either the GPL or the CDDL or both.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync/*******************************************************************************
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync* Header Files *
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync*******************************************************************************/
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync/*******************************************************************************
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync* Defined Constants And Macros *
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync*******************************************************************************/
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync/** The default server port. */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync/** The default client port. */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync/** The default server bind address. */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync/** The default client connect address (i.e. of the host server). */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync/*******************************************************************************
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync* Global Variables *
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync*******************************************************************************/
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync/** @name TCP Parameters
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncstatic enum { TXSTCPMODE_BOTH, TXSTCPMODE_CLIENT, TXSTCPMODE_SERVER }
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync/** The addresses to bind to. Empty string means any. */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncstatic char g_szTcpBindAddr[256] = TXS_TCP_DEF_BIND_ADDRESS;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync/** The TCP port to listen to. */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncstatic uint32_t g_uTcpBindPort = TXS_TCP_DEF_BIND_PORT;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync/** The addresses to connect to if fRevesedSetupMode is @c true. */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncstatic char g_szTcpConnectAddr[256] = TXS_TCP_DEF_CONNECT_ADDRESS;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync/** The TCP port to listen to. */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncstatic uint32_t g_uTcpConnectPort = TXS_TCP_DEF_CONNECT_PORT;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync/** Critical section for serializing access to the next few variables. */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync/** Pointer to the TCP server instance. */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync/** Thread calling RTTcpServerListen2. */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync/** Thread calling RTTcpClientConnect. */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync/** The main thread handle (for signalling). */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync/** Stop connecting attempts when set. */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync/** Connect cancel cookie. */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncstatic PRTTCPCLIENTCONNECTCANCEL volatile g_pTcpConnectCancelCookie = NULL;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync/** Socket of the current client. */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync/** Indicates whether g_hTcpClient comes from the server or from a client
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * connect (relevant when closing it). */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync/** The size of the stashed data. */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync/** The size of the stashed data allocation. */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync/** The stashed data. */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * Disconnects the current client.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * Sets the current client socket in a safe manner.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * @returns NIL_RTSOCKET if consumed, other wise hTcpClient.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * @param hTcpClient The client socket.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * @param fFromServer Set if server type connection.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncstatic RTSOCKET txsTcpSetClient(RTSOCKET hTcpClient, bool fFromServer)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync int rc = RTThreadUserSignal(g_hThreadMain); AssertRC(rc);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * Server mode connection thread.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * @returns iprt status code.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * @param hSelf Thread handle. Ignored.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * @param pvUser Ignored.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncstatic DECLCALLBACK(int) txsTcpServerConnectThread(RTTHREAD hSelf, void *pvUser)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync int rc = RTTcpServerListen2(g_pTcpServer, &hTcpClient);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Log(("txsTcpConnectServerThread: RTTcpServerListen2 -> %Rrc\n", rc));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync hTcpClient = txsTcpSetClient(hTcpClient, true /*fFromServer*/);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * Checks if it's a fatal RTTcpClientConnect return code.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * @returns true / false.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * @param rc The iprt status.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncstatic bool txsTcpIsFatalClientConnectStatus(int rc)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * Client mode connection thread.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * @returns iprt status code.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * @param hSelf Thread handle. Use to sleep on. The main thread will
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * signal it to speed up thread shutdown.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * @param pvUser Ignored.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncstatic DECLCALLBACK(int) txsTcpClientConnectThread(RTTHREAD hSelf, void *pvUser)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync /* Stop? */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Log2(("Calling RTTcpClientConnect(%s, %u,)...\n", g_szTcpConnectAddr, g_uTcpConnectPort));
ca7ea74e4145b138179345f2c83316a97452467cvboxsync int rc = RTTcpClientConnectEx(g_szTcpConnectAddr, g_uTcpConnectPort, &hTcpClient,
ca7ea74e4145b138179345f2c83316a97452467cvboxsync RT_SOCKETCONNECT_DEFAULT_WAIT, &g_pTcpConnectCancelCookie);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Log(("txsTcpRecvPkt: RTTcpClientConnect -> %Rrc\n", rc));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync hTcpClient = txsTcpSetClient(hTcpClient, true /*fFromServer*/);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync RTTcpClientCloseEx(hTcpClient, true /* fGracefulShutdown*/);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync /* Delay a wee bit before retrying. */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * Wait on the threads to complete.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * @returns Thread status (if collected), otherwise VINF_SUCCESS.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * @param cMillies The period to wait on each thread.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncstatic int txsTcpConnectWaitOnThreads(RTMSINTERVAL cMillies)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync int rc2 = RTThreadWait(g_hThreadTcpConnect, cMillies, &rcThread);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync int rc2 = RTThreadWait(g_hThreadTcpServer, cMillies, &rcThread);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * Connects to the peer.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * @returns VBox status code. Updates g_hTcpClient and g_fTcpClientFromServer on
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync rc = RTTcpServerListen2(g_pTcpServer, &g_hTcpClient);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Log(("txsTcpRecvPkt: RTTcpServerListen2 -> %Rrc\n", rc));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Log2(("Calling RTTcpClientConnect(%s, %u,)...\n", g_szTcpConnectAddr, g_uTcpConnectPort));
ca7ea74e4145b138179345f2c83316a97452467cvboxsync rc = RTTcpClientConnect(g_szTcpConnectAddr, g_uTcpConnectPort, &g_hTcpClient);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Log(("txsTcpRecvPkt: RTTcpClientConnect -> %Rrc\n", rc));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if (RT_SUCCESS(rc) || txsTcpIsFatalClientConnectStatus(rc))
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync /* Delay a wee bit before retrying. */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * Create client threads.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync rc = RTThreadCreate(&g_hThreadTcpConnect, txsTcpClientConnectThread, NULL, 0, RTTHREADTYPE_DEFAULT,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if (g_hThreadTcpServer == NIL_RTTHREAD && RT_SUCCESS(rc))
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync rc = RTThreadCreate(&g_hThreadTcpServer, txsTcpServerConnectThread, NULL, 0, RTTHREADTYPE_DEFAULT,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * Wait for connection to be established.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * Cancel the threads.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync RTTcpClientCancelConnect(&g_pTcpConnectCancelCookie);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync AssertMsg(RT_SUCCESS(rc) ? g_hTcpClient != NIL_RTSOCKET : g_hTcpClient == NIL_RTSOCKET, ("%Rrc %p\n", rc, g_hTcpClient));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * @interface_method_impl{TXSTRANSPORT,txsTcpNotifyReboot}
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Log(("txsTcpNotifyReboot: RTTcpServerDestroy(%p)\n", g_pTcpServer));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync RTMsgInfo("RTTcpServerDestroy failed in txsTcpNotifyReboot: %Rrc", rc);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * @interface_method_impl{TXSTRANSPORT,pfnNotifyBye}
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Log(("txsTcpNotifyBye: txsTcpDisconnectClient %RTsock\n", g_hTcpClient));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * @interface_method_impl{TXSTRANSPORT,pfnNotifyHowdy}
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync /* nothing to do here */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * @interface_method_impl{TXSTRANSPORT,pfnBabble}
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncstatic DECLCALLBACK(void) txsTcpBabble(PCTXSPKTHDR pPktHdr, RTMSINTERVAL cMsSendTimeout)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * Quietly ignore already disconnected client.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * Try send the babble reply.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync NOREF(cMsSendTimeout); /** @todo implement the timeout here; non-blocking write + select-on-write. */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync size_t cbToSend = RT_ALIGN_Z(pPktHdr->cb, TXSPKT_ALIGNMENT);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * Disconnect the client.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Log(("txsTcpBabble: txsTcpDisconnectClient(%RTsock) (RTTcpWrite rc=%Rrc)\n", g_hTcpClient, rc));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * @interface_method_impl{TXSTRANSPORT,pfnSendPkt}
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncstatic DECLCALLBACK(int) txsTcpSendPkt(PCTXSPKTHDR pPktHdr)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * Fail if no client connection.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * Write it.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync size_t cbToSend = RT_ALIGN_Z(pPktHdr->cb, TXSPKT_ALIGNMENT);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync int rc = RTTcpWrite(hTcpClient, pPktHdr, cbToSend);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync /* assume fatal connection error. */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Log(("RTTcpWrite -> %Rrc -> txsTcpDisconnectClient(%RTsock)\n", rc, g_hTcpClient));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * @interface_method_impl{TXSTRANSPORT,pfnRecvPkt}
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncstatic DECLCALLBACK(int) txsTcpRecvPkt(PPTXSPKTHDR ppPktHdr)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * Do we have to wait for a client to connect?
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync hTcpClient = g_hTcpClient; Assert(hTcpClient != NIL_RTSOCKET);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * Read state.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * Any stashed data?
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * Read and valid the length.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync rc = RTTcpRead(hTcpClient, pbData + offData, sizeof(uint32_t) - offData, &cbRead);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Log(("txsTcpRecvPkt: RTTcpRead -> %Rrc / cbRead=0 -> VERR_NET_NOT_CONNECTED (#1)\n", rc));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if (cbData >= sizeof(TXSPKTHDR) && cbData <= TXSPKT_MAX_SIZE)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * Align the length and reallocate the return packet it necessary.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * Read the remainder of the data.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync rc = RTTcpRead(hTcpClient, pbData + offData, cbData - offData, &cbRead);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Log(("txsTcpRecvPkt: RTTcpRead -> %Rrc / cbRead=0 -> VERR_NET_NOT_CONNECTED (#2)\n", rc));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * Deal with errors.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync /* stash it away for the next call. */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync /* assume fatal connection error. */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Log(("txsTcpRecvPkt: RTTcpRead -> %Rrc -> txsTcpDisconnectClient(%RTsock)\n", rc, g_hTcpClient));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * @interface_method_impl{TXSTRANSPORT,pfnPollSetAdd}
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncstatic DECLCALLBACK(int) txsTcpPollSetAdd(RTPOLLSET hPollSet, uint32_t idStart)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return RTPollSetAddSocket(hPollSet, g_hTcpClient, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR, idStart);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * @interface_method_impl{TXSTRANSPORT,pfnPollIn}
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return false;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync int rc = RTTcpSelectOne(hTcpClient, 0/*cMillies*/);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * @interface_method_impl{TXSTRANSPORT,pfnTerm}
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync /* Signal thread */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync RTTcpClientCancelConnect(&g_pTcpConnectCancelCookie);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync /* Shut down the server (will wake up thread). */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync RTMsgInfo("RTTcpServerDestroy failed in txsTcpTerm: %Rrc", rc);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync /* Shut down client */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync int rc = RTTcpServerDisconnectClient2(g_hTcpClient);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync RTMsgInfo("RTTcpServerDisconnectClient2(%RTsock) failed in txsTcpTerm: %Rrc", g_hTcpClient, rc);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync RTMsgInfo("RTTcpClientClose(%RTsock) failed in txsTcpTerm: %Rrc", g_hTcpClient, rc);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync /* Clean up stashing. */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync /* Wait for the thread (they should've had some time to quit by now). */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync /* Finally, clean up the critical section. */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * @interface_method_impl{TXSTRANSPORT,pfnInit}
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if (RT_SUCCESS(rc) && g_enmTcpMode != TXSTCPMODE_CLIENT)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync rc = RTTcpServerCreateEx(g_szTcpBindAddr[0] ? g_szTcpBindAddr : NULL, g_uTcpBindPort, &g_pTcpServer);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync RTMsgInfo("RTTcpServerCreateEx(%s, %u,) failed: %Rrc, retrying for 20 seconds...\n",
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_szTcpBindAddr[0] ? g_szTcpBindAddr : NULL, g_uTcpBindPort, rc);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync rc = RTTcpServerCreateEx(g_szTcpBindAddr[0] ? g_szTcpBindAddr : NULL, g_uTcpBindPort, &g_pTcpServer);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync RTMsgError("RTTcpServerCreateEx(%s, %u,) failed: %Rrc\n",
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_szTcpBindAddr[0] ? g_szTcpBindAddr : NULL, g_uTcpBindPort, rc);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync/** Options */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync /* legacy: */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * @interface_method_impl{TXSTRANSPORT,pfnOption}
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncstatic DECLCALLBACK(int) txsTcpOption(int ch, PCRTGETOPTUNION pVal)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return RTMsgErrorRc(VERR_INVALID_PARAMETER, "Invalid TCP mode: '%s'\n", pVal->psz);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync rc = RTStrCopy(g_szTcpBindAddr, sizeof(g_szTcpBindAddr), pVal->psz);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return RTMsgErrorRc(VERR_INVALID_PARAMETER, "TCP bind address is too long (%Rrc)", rc);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_uTcpBindPort = pVal->u16 == 0 ? TXS_TCP_DEF_BIND_PORT : pVal->u16;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync /* fall thru */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync rc = RTStrCopy(g_szTcpConnectAddr, sizeof(g_szTcpConnectAddr), pVal->psz);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return RTMsgErrorRc(VERR_INVALID_PARAMETER, "TCP connect address is too long (%Rrc)", rc);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync strcpy(g_szTcpConnectAddr, TXS_TCP_DEF_CONNECT_ADDRESS);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_uTcpConnectPort = pVal->u16 == 0 ? TXS_TCP_DEF_CONNECT_PORT : pVal->u16;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * @interface_method_impl{TXSTRANSPORT,pfnUsage}
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync " --tcp-mode <both|client|server>\n"
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync " Selects the mode of operation.\n"
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync " Default: both\n"
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync " --tcp-bind-address <address>\n"
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync " The address(es) to listen to TCP connection on. Empty string\n"
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync " means any address, this is the default.\n"
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync " --tcp-bind-port <port>\n"
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync " The port to listen to TCP connections on.\n"
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync " Default: %u\n"
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync " --tcp-connect-address <address>\n"
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync " The address of the server to try connect to in client mode.\n"
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync " --tcp-connect-port <port>\n"
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync " The port on the server to connect to in client mode.\n"
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync " Default: %u\n"
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , TXS_TCP_DEF_BIND_PORT, TXS_TCP_DEF_CONNECT_PORT);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync/** Command line options for the TCP/IP transport layer. */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync { "--tcp-mode", TXSTCPOPT_MODE, RTGETOPT_REQ_STRING },
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync { "--tcp-bind-address", TXSTCPOPT_BIND_ADDRESS, RTGETOPT_REQ_STRING },
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync { "--tcp-bind-port", TXSTCPOPT_BIND_PORT, RTGETOPT_REQ_UINT16 },
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync { "--tcp-connect-address", TXSTCPOPT_CONNECT_ADDRESS, RTGETOPT_REQ_STRING },
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync { "--tcp-connect-port", TXSTCPOPT_CONNECT_PORT, RTGETOPT_REQ_UINT16 },
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync /* legacy */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync { "--tcp-port", TXSTCPOPT_LEGACY_PORT, RTGETOPT_REQ_UINT16 },
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync { "--tcp-connect", TXSTCPOPT_LEGACY_CONNECT, RTGETOPT_REQ_STRING },
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync/** TCP/IP transport layer. */