//-------------------------------------------------------------------------- static void handle_single_session(rpc_server_t *server) { lprintf("=========================================================\n" "Accepting incoming connection...\n"); qstring open = prepare_rpc_packet(RPC_OPEN); append_long(open, IDD_INTERFACE_VERSION); append_long(open, DEBUGGER_ID); append_long(open, sizeof(ea_t)); rpc_packet_t *rp = server->process_request(open, PRF_LOGIN|PRF_DONT_POLL); if ( rp == NULL ) { lprintf("Could not establish the connection\n"); delete server; return; } // Answer is beyond the rpc_packet_t buffer const uchar *answer = (uchar *)(rp+1); const uchar *end = answer + rp->length; bool send_response = true; bool ok = extract_long(&answer, end); if ( !ok ) { lprintf("Incompatible IDA Pro version\n"); send_response = false; } else if ( server_password != NULL ) { char *pass = extract_str(&answer, end); if ( strcmp(pass, server_password) != '\0' ) { lprintf("Bad password\n"); ok = false; } } qfree(rp); if ( send_response ) { server->poll_debug_events = false; server->has_pending_event = false; open = prepare_rpc_packet(RPC_OK); append_long(open, ok); server->send_request(open); if ( ok ) { qstring cmd; rpc_packet_t *packet = server->process_request(cmd, PRF_POLL); if ( packet != NULL ) qfree(packet); } } server->network_error_code = 0; lprintf("Closing incoming connection...\n"); server->term_irs(); #ifndef __SINGLE_THREADED_SERVER__ // Remove the session from the list qmutex_lock(g_lock); for (rpc_server_list_t::iterator it = clients_list.begin(); it != clients_list.end();++it) { if ( it->first != server ) continue; // free the thread resources qthread_free(it->second); // remove client from the list clients_list.erase(it); break; } qmutex_unlock(g_lock); #endif // Free the debug session delete server; }
//-------------------------------------------------------------------------- static void handle_single_session(rpc_server_t *server) { static int s_sess_id = 1; int sid = s_sess_id++; char peername[MAXSTR]; if ( !irs_peername(server->irs, peername, sizeof(peername), false) ) qstrncpy(peername, "(unknown)", sizeof(peername)); lprintf("=========================================================\n" "[%d] Accepting connection from %s...\n", sid, peername); bytevec_t req = prepare_rpc_packet(RPC_OPEN); append_dd(req, IDD_INTERFACE_VERSION); append_dd(req, DEBUGGER_ID); append_dd(req, sizeof(ea_t)); rpc_packet_t *rp = server->process_request(req, true); bool handle_request = true; bool send_response = true; bool ok; if ( rp == NULL ) { lprintf("[%d] Could not establish the connection\n", sid); handle_request = false; send_response = false; } if ( handle_request ) { // Answer is beyond the rpc_packet_t buffer const uchar *answer = (uchar *)(rp+1); const uchar *end = answer + rp->length; ok = extract_long(&answer, end) != 0; if ( !ok ) { lprintf("[%d] Incompatible IDA version\n", sid); send_response = false; } else if ( server_password != NULL ) { char *pass = extract_str(&answer, end); if ( strcmp(pass, server_password) != '\0' ) { lprintf("[%d] Bad password\n", sid); ok = false; } } qfree(rp); } if ( send_response ) { req = prepare_rpc_packet(RPC_OK); append_dd(req, ok); server->send_request(req); if ( ok ) { // the main loop: handle client requests until it drops the connection // or sends us RPC_OK (see rpc_debmod_t::close_remote) bytevec_t empty; rpc_packet_t *packet = server->process_request(empty); if ( packet != NULL ) qfree(packet); } } server->network_error_code = 0; lprintf("[%d] Closing connection from %s...\n", sid, peername); bool preserve_server = keep_broken_connections && server->get_broken_connection(); if ( !preserve_server ) { // Terminate dedicated debugger instance. server->get_debugger_instance()->dbg_term(); server->term_irs(); } else { server->term_irs(); lprintf("[%d] Debugged session entered into sleeping mode\n", sid); server->prepare_broken_connection(); } if ( !preserve_server ) { // Remove the session from the list srv_lock_begin(); for (rpc_server_list_t::iterator it = clients_list.begin(); it != clients_list.end();++it) { if ( it->first != server ) continue; #ifndef __SINGLE_THREADED_SERVER__ // free the thread resources qthread_free(it->second); #endif // remove client from the list clients_list.erase(it); break; } srv_lock_end(); // Free the debug session delete server; } }