00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00027 #include "inspectorj/agent/agentserver.h"
00028
00029 using inspectorj::agent::AgentServer;
00030 using namespace inspectorj::jdwp;
00031
00032 namespace inspectorj {
00033 namespace agent {
00034
00040 AgentServer::AgentServer(int portNum, AgentPacketHandler *handler)
00041 : portNum(portNum),
00042 pktHandler(handler),
00043 quit(false),
00044 started(false),
00045 error(0),
00046 socket(0),
00047 acceptor(0),
00048 agentSocket(0)
00049 {
00050
00051 }
00052
00056 AgentServer::~AgentServer()
00057 {
00058 if (socket) {
00059 delete socket;
00060 socket = 0;
00061 }
00062 if (agentSocket) {
00063 delete agentSocket;
00064 agentSocket = 0;
00065 }
00066 if (error) {
00067 delete error;
00068 error = 0;
00069 }
00070 }
00071
00075 void AgentServer::stop()
00076 {
00077 this->quit = true;
00078 if (socket && socket->is_open()) {
00079 socket->close();
00080 }
00081
00082
00083
00084
00085 if (acceptor) {
00086 acceptor->close();
00087 }
00088 }
00089
00090 void AgentServer::shutDown()
00091 {
00092 if (socket) {
00093 if ( socket->is_open() && !quit) {
00094 socket->close();
00095 }
00096 socket->io_service().stop();
00097 }
00098 this->started = false;
00099 this->quit = false;
00100 }
00101
00105 bool AgentServer::isStarted()
00106 {
00107 return this->started;
00108 }
00109
00114 void AgentServer::start()
00115 {
00116 this->quit = false;
00117 boost::asio::io_service io_service;
00118
00119 try
00120 {
00121 char handshake[JDWP_HANDSHAKE_LENGTH + 1];
00122 while (!quit) {
00123 this->started = false;
00124 error = new boost::system::error_code();
00125 size_t bytesRead = 0;
00126
00127 if (socket) {
00128 delete socket;
00129 socket = 0;
00130 }
00131 socket = new tcp::socket(io_service);
00132
00133 if (agentSocket) {
00134 delete agentSocket;
00135 agentSocket = 0;
00136 }
00137 agentSocket = new AgentSocket(socket, error);
00138 pktHandler->setAgentSocket(agentSocket);
00139 pktHandler->attachCurrentThreadToVM();
00140
00141 if (acceptor) {
00142 delete acceptor;
00143 acceptor = 0;
00144 }
00145 acceptor = new tcp::acceptor(io_service, tcp::endpoint(tcp::v4(), portNum));
00146 acceptor->accept(*socket, *error);
00147 delete acceptor;
00148 acceptor = 0;
00149
00150
00151
00152
00153
00154
00155
00156
00157 if (quit) {
00158 shutDown();
00159 return;
00160 }
00161
00162 this->started = true;
00163
00164 AgentLogger::info("Accepted client connection");
00165
00166
00167 if (socket->available() < JDWP_HANDSHAKE_LENGTH ) {
00168
00169 boost::asio::io_service timer_io_service;
00170 boost::asio::deadline_timer t(timer_io_service, boost::posix_time::seconds(1));
00171 t.wait();
00172
00173 if (socket->available() < JDWP_HANDSHAKE_LENGTH) {
00174
00175 AgentLogger::warn("No handshake received from client... disconnecting");
00176 continue;
00177 }
00178 }
00179
00180
00181 if (! agentSocket->read(handshake, JDWP_HANDSHAKE_LENGTH)) continue;
00182 handshake[JDWP_HANDSHAKE_LENGTH] = '\0';
00183
00184
00185 if (strcmp(handshake, JDWP_HANDSHAKE) != 0) {
00186
00187 AgentLogger::warn("Incorrect handshake received from client: [%s]... disconnecting",handshake);
00188 continue;
00189 }
00190
00191 boost::asio::write(*socket, boost::asio::buffer(JDWP_HANDSHAKE),
00192 boost::asio::transfer_all(), *error);
00193
00194
00195 while (!checkError(*error) && !quit)
00196 {
00197
00198 jdwpCmdPacket cmdPacket;
00199
00200 if (! agentSocket->read(cmdPacket.len)) continue;
00201 if (! agentSocket->read(cmdPacket.id)) continue;
00202 if (! agentSocket->read(cmdPacket.flags)) continue;
00203 if (! agentSocket->read(cmdPacket.cmdSet)) continue;
00204 if (! agentSocket->read(cmdPacket.cmd)) continue;
00205
00206 if (cmdPacket.cmdSet == INSPECTORJ_COMMAND_SET)
00207 {
00208 if (cmdPacket.cmd == IJ_DISCONNECT)
00209 {
00210 break;
00211 }
00212 else if (cmdPacket.cmd == IJ_EXIT)
00213 {
00214 quit = true;
00215 break;
00216 }
00217 }
00218
00219 int dataSize = cmdPacket.len - JDWP_HEADER_LENGTH;
00220
00221
00222 if ( dataSize > 0 ) {
00223 cmdPacket.data = new jbyte[dataSize];
00224 if (! agentSocket->read((char *)cmdPacket.data, dataSize)) continue;
00225 } else {
00226 cmdPacket.data = NULL;
00227 }
00228
00229
00230
00231
00232
00233
00234 pktHandler->processCommand(new JDWPCommand(cmdPacket));
00235 }
00236 }
00237 }
00238 catch (std::exception& e)
00239 {
00240
00241
00242
00243 if (! this->quit ) {
00244 AgentLogger::error("inspectorj server stopping becasue of exception:");
00245 AgentLogger::error(e.what());
00246 }
00247 }
00248
00249 this->shutDown();
00250 }
00251
00256 bool AgentServer::checkError(boost::system::error_code& error)
00257 {
00258 if (error) {
00259 if (error != boost::asio::error::eof)
00260 throw boost::system::system_error(error);
00261 }
00262 return error;
00263 }
00264
00265 }
00266 }