DBGCTcp.cpp revision ad27e1d5e48ca41245120c331cc88b50464813ce
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * DBGC - Debugger Console, TCP backend.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Copyright (C) 2006-2010 Oracle Corporation
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * available from http://www.virtualbox.org. This file is free software;
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * you can redistribute it and/or modify it under the terms of the GNU
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * General Public License (GPL) as published by the Free Software
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/*******************************************************************************
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync* Header Files *
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync*******************************************************************************/
b1cc3e87518139898395f96974ecff9e6bf228fbvboxsync/*******************************************************************************
b1cc3e87518139898395f96974ecff9e6bf228fbvboxsync* Structures and Typedefs *
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync*******************************************************************************/
388b6b190a5407548753b7fde12fa58134ec3563vboxsync * Debug console TCP backend instance data.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsynctypedef struct DBGCTCP
f9ce005e61f0fbb51a2cabc53d58c3485151faa9vboxsync /** The I/O backend for the console. */
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync /** The socket of the connection. */
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync /** Connection status. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** Pointer to the instance data of the console TCP backend. */
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync/** Converts a pointer to DBGCTCP::Back to a pointer to DBGCTCP. */
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync#define DBGCTCP_BACK2DBGCTCP(pBack) ( (PDBGCTCP)((char *)pBack - RT_OFFSETOF(DBGCTCP, Back)) )
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync/*******************************************************************************
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync* Internal Functions *
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync*******************************************************************************/
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsyncstatic int dbgcTcpConnection(RTSOCKET Sock, void *pvUser);
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync * Checks if there is input.
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync * @returns true if there is input ready.
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync * @returns false if there not input ready.
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync * @param pBack Pointer to the backend structure supplied by
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync * the backend. The backend can use this to find
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync * it's instance data.
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync * @param cMillies Number of milliseconds to wait on input data.
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsyncstatic DECLCALLBACK(bool) dbgcTcpBackInput(PDBGCBACK pBack, uint32_t cMillies)
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync return false;
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * Read input.
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * @returns VBox status code.
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * @param pBack Pointer to the backend structure supplied by
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * the backend. The backend can use this to find
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * it's instance data.
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * @param pvBuf Where to put the bytes we read.
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * @param cbBuf Maximum nymber of bytes to read.
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * @param pcbRead Where to store the number of bytes actually read.
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * If NULL the entire buffer must be filled for a
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * successful return.
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsyncstatic DECLCALLBACK(int) dbgcTcpBackRead(PDBGCBACK pBack, void *pvBuf, size_t cbBuf, size_t *pcbRead)
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync int rc = RTTcpRead(pDbgcTcp->Sock, pvBuf, cbBuf, pcbRead);
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * Write (output).
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * @returns VBox status code.
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * @param pBack Pointer to the backend structure supplied by
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * the backend. The backend can use this to find
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * it's instance data.
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * @param pvBuf What to write.
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * @param cbBuf Number of bytes to write.
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * @param pcbWritten Where to store the number of bytes actually written.
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * If NULL the entire buffer must be successfully written.
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsyncstatic DECLCALLBACK(int) dbgcTcpBackWrite(PDBGCBACK pBack, const void *pvBuf, size_t cbBuf, size_t *pcbWritten)
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * convert '\n' to '\r\n' while writing.
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync /* write newlines */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /* write till next newline */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync const char *pszNL = (const char *)memchr(pvBuf, '\n', cbLeft);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /* advance */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Set returned value and return.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync/** @copydoc FNDBGCBACKSETREADY */
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsyncstatic DECLCALLBACK(void) dbgcTcpBackSetReady(PDBGCBACK pBack, bool fBusy)
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Serve a TCP Server connection.
fb41ad77bcfbdb3aaa1fc9503a37ee6a70dc6461vboxsync * @returns VBox status.
fb41ad77bcfbdb3aaa1fc9503a37ee6a70dc6461vboxsync * @returns VERR_TCP_SERVER_STOP to terminate the server loop forcing
fb41ad77bcfbdb3aaa1fc9503a37ee6a70dc6461vboxsync * the RTTcpCreateServer() call to return.
fb41ad77bcfbdb3aaa1fc9503a37ee6a70dc6461vboxsync * @param Sock The socket which the client is connected to.
fb41ad77bcfbdb3aaa1fc9503a37ee6a70dc6461vboxsync * The call will close this socket.
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync * @param pvUser The VM handle.
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsyncstatic int dbgcTcpConnection(RTSOCKET Sock, void *pvUser)
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync LogFlow(("dbgcTcpConnection: connection! Sock=%d pvUser=%p\n", Sock, pvUser));
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync * Start the console.
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync int rc = DBGCCreate((PVM)pvUser, &DbgcTcp.Back, 0);
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync LogFlow(("dbgcTcpConnection: disconnect rc=%Rrc\n", rc));
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync * Spawns a new thread with a TCP based debugging console service.
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync * @returns VBox status.
cd5df721f068659172f3bf95de8fedeb465f057dvboxsync * @param pVM VM handle.
cd5df721f068659172f3bf95de8fedeb465f057dvboxsync * @param ppvData Where to store a pointer to the instance data.
cd5df721f068659172f3bf95de8fedeb465f057dvboxsync * Check what the configuration says.
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync PCFGMNODE pKey = CFGMR3GetChild(CFGMR3GetRoot(pVM), "DBGC");
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync int rc = CFGMR3QueryBoolDef(pKey, "Enabled", &fEnabled,
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync#if defined(VBOX_WITH_DEBUGGER) && defined(VBOX_WITH_DEBUGGER_TCP_BY_DEFAULT) && !defined(__L4ENV__) && !defined(DEBUG_dmik)
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync return VM_SET_ERROR(pVM, rc, "Configuration error: Failed querying \"DBGC/Enabled\"");
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync LogFlow(("DBGCTcpCreate: returns VINF_SUCCESS (Disabled)\n"));
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * Get the port configuration.
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync rc = CFGMR3QueryU32Def(pKey, "Port", &u32Port, 5000);
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync return VM_SET_ERROR(pVM, rc, "Configuration error: Failed querying \"DBGC/Port\"");
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * Get the address configuration.
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync rc = CFGMR3QueryStringDef(pKey, "Address", szAddress, sizeof(szAddress), "");
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync return VM_SET_ERROR(pVM, rc, "Configuration error: Failed querying \"DBGC/Address\"");
ecf100db90e8e3af96312908282d3c20e754fbe8vboxsync * Create the server (separate thread).
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync rc = RTTcpServerCreate(szAddress, u32Port, RTTHREADTYPE_DEBUGGER, "DBGC", dbgcTcpConnection, pVM, &pServer);
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync LogFlow(("DBGCTcpCreate: Created server on port %d %s\n", u32Port, szAddress));
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync return VM_SET_ERROR(pVM, rc, "Cannot start TCP-based debugging console service");
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Terminates any running TCP base debugger console service.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @returns VBox status.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param pVM VM handle.
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsyncDBGDECL(int) DBGCTcpTerminate(PVM pVM, void *pvData)
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Destroy the server instance if any.