DBGCTcp.cpp revision 489ff469f658c1a9e95ec8c62fec535c9ca6c6a7
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * DBGC - Debugger Console, TCP backend.
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * available from http://www.virtualbox.org. This file is free software;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * you can redistribute it and/or modify it under the terms of the GNU
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * General Public License (GPL) as published by the Free Software
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * additional information or have any questions.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*******************************************************************************
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync* Header Files *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync*******************************************************************************/
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync/*******************************************************************************
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync* Structures and Typedefs *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync*******************************************************************************/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Debug console TCP backend instance data.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsynctypedef struct DBGCTCP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** The I/O backend for the console. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** The socket of the connection. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** Connection status. */
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync/** Pointer to the instance data of the console TCP backend. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** Converts a pointer to DBGCTCP::Back to a pointer to DBGCTCP. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#define DBGCTCP_BACK2DBGCTCP(pBack) ( (PDBGCTCP)((char *)pBack - RT_OFFSETOF(DBGCTCP, Back)) )
afed5ab737f4aacfae3fe73776f40e989190a7cavboxsync/*******************************************************************************
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync* Internal Functions *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync*******************************************************************************/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int dbgcTcpConnection(RTSOCKET Sock, void *pvUser);
0174432b2b1a760b89840ba696f7ba51def65dddvboxsync * Checks if there is input.
0174432b2b1a760b89840ba696f7ba51def65dddvboxsync * @returns true if there is input ready.
7666082b743c5e146a8cee6cc794ff4bc3fd0ffdvboxsync * @returns false if there not input ready.
7666082b743c5e146a8cee6cc794ff4bc3fd0ffdvboxsync * @param pBack Pointer to the backend structure supplied by
7666082b743c5e146a8cee6cc794ff4bc3fd0ffdvboxsync * the backend. The backend can use this to find
7666082b743c5e146a8cee6cc794ff4bc3fd0ffdvboxsync * it's instance data.
7666082b743c5e146a8cee6cc794ff4bc3fd0ffdvboxsync * @param cMillies Number of milliseconds to wait on input data.
7666082b743c5e146a8cee6cc794ff4bc3fd0ffdvboxsyncstatic DECLCALLBACK(bool) dbgcTcpBackInput(PDBGCBACK pBack, uint32_t cMillies)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return false;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Read input.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @returns VBox status code.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pBack Pointer to the backend structure supplied by
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * the backend. The backend can use this to find
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * it's instance data.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pvBuf Where to put the bytes we read.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param cbBuf Maximum nymber of bytes to read.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pcbRead Where to store the number of bytes actually read.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * If NULL the entire buffer must be filled for a
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * successful return.
22e281e75ed636601178296c6daebda8f1d17c59vboxsyncstatic DECLCALLBACK(int) dbgcTcpBackRead(PDBGCBACK pBack, void *pvBuf, size_t cbBuf, size_t *pcbRead)
22e281e75ed636601178296c6daebda8f1d17c59vboxsync int rc = RTTcpRead(pDbgcTcp->Sock, pvBuf, cbBuf, pcbRead);
22e281e75ed636601178296c6daebda8f1d17c59vboxsync * Write (output).
22e281e75ed636601178296c6daebda8f1d17c59vboxsync * @returns VBox status code.
22e281e75ed636601178296c6daebda8f1d17c59vboxsync * @param pBack Pointer to the backend structure supplied by
22e281e75ed636601178296c6daebda8f1d17c59vboxsync * the backend. The backend can use this to find
22e281e75ed636601178296c6daebda8f1d17c59vboxsync * it's instance data.
22e281e75ed636601178296c6daebda8f1d17c59vboxsync * @param pvBuf What to write.
22e281e75ed636601178296c6daebda8f1d17c59vboxsync * @param cbBuf Number of bytes to write.
22e281e75ed636601178296c6daebda8f1d17c59vboxsync * @param pcbWritten Where to store the number of bytes actually written.
22e281e75ed636601178296c6daebda8f1d17c59vboxsync * If NULL the entire buffer must be successfully written.
22e281e75ed636601178296c6daebda8f1d17c59vboxsyncstatic DECLCALLBACK(int) dbgcTcpBackWrite(PDBGCBACK pBack, const void *pvBuf, size_t cbBuf, size_t *pcbWritten)
22e281e75ed636601178296c6daebda8f1d17c59vboxsync * convert '\n' to '\r\n' while writing.
22e281e75ed636601178296c6daebda8f1d17c59vboxsync /* write newlines */
c17f5c90f2cb60b38ecabebce128724c6ff2d036vboxsync /* write till next newline */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const char *pszNL = (const char *)memchr(pvBuf, '\n', cbLeft);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* advance */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Set returned value and return.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Serve a TCP Server connection.
a11c569636fa6838bd423f4631a9660a5a84204bvboxsync * @returns VBox status.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @returns VERR_TCP_SERVER_STOP to terminate the server loop forcing
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * the RTTcpCreateServer() call to return.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param Sock The socket which the client is connected to.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * The call will close this socket.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pvUser The VM handle.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int dbgcTcpConnection(RTSOCKET Sock, void *pvUser)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow(("dbgcTcpConnection: connection! Sock=%d pvUser=%p\n", Sock, pvUser));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Start the console.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc = DBGCCreate((PVM)pvUser, &DbgcTcp.Back, 0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow(("dbgcTcpConnection: disconnect rc=%Vrc\n", rc));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Spawns a new thread with a TCP based debugging console service.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @returns VBox status.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pVM VM handle.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param ppvData Where to store a pointer to the instance data.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Check what the configuration says.
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync PCFGMNODE pKey = CFGMR3GetChild(CFGMR3GetRoot(pVM), "DBGC");
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync int rc = CFGMR3QueryBool(pKey, "Enabled", &fEnabled);
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync if (rc == VERR_CFGM_VALUE_NOT_FOUND || rc == VERR_CFGM_NO_PARENT)
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync#if defined(VBOX_WITH_DEBUGGER) && !defined(__L4ENV__) && !defined(DEBUG_dmik)
576d4214137bce409cdcf01e8df4a0bca5e0b2d1vboxsync AssertMsgFailed(("Configuration error: Querying \"Enabled\" -> %Vrc\n", rc));
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync LogFlow(("DBGCTcpCreate: returns VINF_SUCCESS (Disabled)\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Get the port configuration.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (rc == VERR_CFGM_VALUE_NOT_FOUND || rc == VERR_CFGM_NO_PARENT)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertMsgFailed(("Configuration error: Querying \"Port\" -> %Vrc\n", rc));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Get the address configuration.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = CFGMR3QueryString(pKey, "Address", szAddress, sizeof(szAddress));
e08de24d4792d31b7f2aac29db5cb8840d940009vboxsync if (rc == VERR_CFGM_VALUE_NOT_FOUND || rc == VERR_CFGM_NO_PARENT)
e50404712a2b5234c42bdf9740bddab5729ba188vboxsync AssertMsgFailed(("Configuration error: Querying \"Address\" -> %Vrc\n", rc));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Create the server (separate thread).
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = RTTcpServerCreate(szAddress, u32Port, RTTHREADTYPE_DEBUGGER, "DBGC", dbgcTcpConnection, pVM, &pServer);
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync LogFlow(("DBGCTcpCreate: Created server on port %d %s\n", u32Port, szAddress));
247b55faa8d054157f2481e68caca36f4dc9542cvboxsync * Terminates any running TCP base debugger consolse service.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @returns VBox status.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pVM VM handle.
57399ab65e2825c324fb9dcb4642d4ae2c232509vboxsyncDBGDECL(int) DBGCTcpTerminate(PVM pVM, void *pvData)
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync * Destroy the server instance if any.