/* $Id$ */
/** @file
* TCP socket driver implementing the IStream interface.
*/
/*
* Copyright (C) 2006-2015 Oracle Corporation.
*
* This file was contributed by Alexey Eromenko (derived from DrvNamedPipe)
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
#include <iprt/semaphore.h>
#include <stdlib.h>
#include "VBoxDD.h"
#ifdef RT_OS_WINDOWS
# include <ws2tcpip.h>
#else /* !RT_OS_WINDOWS */
# include <errno.h>
# include <unistd.h>
# include <netdb.h>
# ifndef SHUT_RDWR /* OS/2 */
# endif
#endif /* !RT_OS_WINDOWS */
#ifndef SHUT_RDWR
# ifdef SD_BOTH
# else
# endif
#endif
/*******************************************************************************
* Defined Constants And Macros *
*******************************************************************************/
/** Converts a pointer to DRVTCP::IMedia to a PDRVTCP. */
#define PDMISTREAM_2_DRVTCP(pInterface) ( (PDRVTCP)((uintptr_t)pInterface - RT_OFFSETOF(DRVTCP, IStream)) )
/*******************************************************************************
* Structures and Typedefs *
*******************************************************************************/
/**
* TCP driver instance data.
*
* @implements PDMISTREAM
*/
typedef struct DRVTCP
{
/** The stream interface. */
/** Pointer to the driver instance. */
/** Pointer to the TCP server address:port or port only. (Freed by MM) */
char *pszLocation;
/** Flag whether VirtualBox represents the server or client side. */
bool fIsServer;
/** Socket handle of the TCP socket for server. */
int TCPServer;
/** Socket handle of the TCP socket connection. */
int TCPConnection;
/** Thread for listening for new connections. */
/** Flag to signal listening thread to shut down. */
bool volatile fShutdown;
/*******************************************************************************
* Internal Functions *
*******************************************************************************/
/** @copydoc PDMISTREAM::pfnRead */
{
{
if (cbReallyRead == 0)
{
#ifdef RT_OS_WINDOWS
#else
#endif
}
else if (cbReallyRead == -1)
{
cbReallyRead = 0;
}
*pcbRead = cbReallyRead;
}
else
{
RTThreadSleep(100);
*pcbRead = 0;
}
return rc;
}
/** @copydoc PDMISTREAM::pfnWrite */
{
{
if (cbWritten == 0)
{
#ifdef RT_OS_WINDOWS
#else
#endif
}
else if (cbWritten == -1)
{
cbWritten = 0;
}
}
return rc;
}
/**
* @interface_method_impl{PDMIBASE,pfnQueryInterface}
*/
{
return NULL;
}
/* -=-=-=-=- listen thread -=-=-=-=- */
/**
* Receive thread loop.
*
* @returns 0 on success.
* @param ThreadSelf Thread handle to this thread.
* @param pvUser User argument.
*/
{
{
{
break;
}
if (s == -1)
{
break;
}
{
#ifdef RT_OS_WINDOWS
closesocket(s);
#else
close(s);
#endif
}
else
pThis->TCPConnection = s;
}
return VINF_SUCCESS;
}
/* -=-=-=-=- PDMDRVREG -=-=-=-=- */
/**
* Common worker for drvTCPPowerOff and drvTCPDestructor.
*
* @param pThis The instance data.
*/
{
/*
* Signal shutdown of the listener thread.
*/
{
#ifdef RT_OS_WINDOWS
#else
#endif
}
}
/**
* Power off a TCP socket stream driver instance.
*
* This does most of the destruction work, to avoid ordering dependencies.
*
* @param pDrvIns The driver instance data.
*/
{
}
/**
* Destruct a TCP socket stream driver instance.
*
* Most VM resources are freed by the VM. This callback is provided so that
* any non-VM resources can be freed correctly.
*
* @param pDrvIns The driver instance data.
*/
{
/*
* While the thread exits, clean up as much as we can.
*/
{
#ifdef RT_OS_WINDOWS
#else
#endif
}
&& pThis->pszLocation)
/*
* Wait for the thread.
*/
{
if (RT_SUCCESS(rc))
else
}
}
/**
* Construct a TCP socket stream driver instance.
*
* @copydoc FNPDMDRVCONSTRUCT
*/
{
/*
* Init the static parts.
*/
/* IBase */
/* IStream */
/*
* Validate and read the configuration.
*/
if (RT_FAILURE(rc))
if (RT_FAILURE(rc))
/*
*/
if (s == -1)
{
/* Bind address to the telnet socket. */
N_("DrvTCP#%d failed to bind to socket %s"),
if (RT_FAILURE(rc))
}
else
{
char *token;
if(token) {
}
if(token) {
}
/* Connect to the telnet socket. */
pThis->TCPConnection = s;
N_("DrvTCP#%d failed to connect to socket %s"),
}
return VINF_SUCCESS;
}
/**
* TCP stream driver registration record.
*/
{
/* u32Version */
/* szName */
"TCP",
/* szRCMod */
"",
/* szR0Mod */
"",
/* pszDescription */
"TCP serial stream driver.",
/* fFlags */
/* fClass. */
/* cMaxInstances */
~0U,
/* cbInstance */
sizeof(DRVTCP),
/* pfnConstruct */
/* pfnDestruct */
/* pfnRelocate */
NULL,
/* pfnIOCtl */
NULL,
/* pfnPowerOn */
NULL,
/* pfnReset */
NULL,
/* pfnSuspend */
NULL,
/* pfnResume */
NULL,
/* pfnAttach */
NULL,
/* pfnDetach */
NULL,
/* pfnPowerOff */
/* pfnSoftReset */
NULL,
/* u32EndVersion */
};