TH_HDL client_handler(void* client) { client_t* cli = (client_t*)client; char buff[BUFF_SIZE]; cli->running = true; if(cli->server->auth && !client_authenticate(cli)) cli->running = false; while(cli->running && cli->server->running) { //readline int r = read_line(cli->sock, buff, BUFF_SIZE, true); if(r <= 0) break; request_t req; _log(LVL_TRACE, "Request received : %s\n", buff); if(decode_request(cli, &req, buff, r) < 0) continue; // Process request process_request(&req); //Send response encode_reply(&req, buff, BUFF_SIZE); _log(LVL_TRACE, "Reply sent : %s\n", buff); send(cli->sock, buff, strlen(buff), 0); } _log(LVL_TRACE, "Exiting client thread\n", buff); cli->running = false; shutdown(cli->sock, SHUT_WR); close(cli->sock); server_unregister_client(cli->server, cli); free(client); _log(LVL_TRACE, "Client thread exited\n", buff); TH_RETURN; }
static bool decode_exception_message (RDebug *dbg, exc_msg *msg) { kern_return_t kret; int ret; /* check if the message is for us */ if (msg->hdr.msgh_local_port != ex.exception_port) return false; //XXX gdb from apple check this dunno why /* check message header. */ if (!(msg->hdr.msgh_bits & MACH_MSGH_BITS_COMPLEX)) return false; /* check descriptors. */ if (msg->hdr.msgh_size < sizeof (mach_msg_header_t) + sizeof (mach_msg_body_t) + 2 * sizeof (mach_msg_port_descriptor_t) + sizeof (NDR_record_t) + sizeof (exception_type_t) + sizeof (mach_msg_type_number_t) + sizeof (mach_exception_data_t)) return false; /* check data representation. */ if (msg->NDR.mig_vers != NDR_PROTOCOL_2_0 || msg->NDR.if_vers != NDR_PROTOCOL_2_0 || msg->NDR.mig_encoding != NDR_record.mig_encoding || msg->NDR.int_rep != NDR_record.int_rep || msg->NDR.char_rep != NDR_record.char_rep || msg->NDR.float_rep != NDR_record.float_rep) return -1; /* We got new rights to the task, get rid of it.*/ kret = mach_port_deallocate (mach_task_self (), msg->task.name); if (kret != KERN_SUCCESS) { eprintf ("faild to deallocate task port " "decode_exception_message\n"); } if (pid_to_task (dbg->pid) != msg->task.name) { //we receive a exception from an unkown process this could //happen if the child fork, as the created process will inherit //its exception port //XXX should we manage this in somehow? mig_reply_error_t reply; kret = mach_port_deallocate (mach_task_self (), msg->thread.name); if (kret != KERN_SUCCESS) { eprintf ("failed to deallocate thread port " "decode_exception_message\n"); return false; } encode_reply (&reply, &msg->hdr, KERN_SUCCESS); kret = mach_msg (&reply.Head, MACH_SEND_MSG | MACH_SEND_INTERRUPT, reply.Head.msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); if (kret != KERN_SUCCESS) { eprintf ("failed to reply decode_exception_message\n"); return false; } } kret = mach_port_deallocate (mach_task_self (), msg->thread.name); if (kret != KERN_SUCCESS) { eprintf ("failed to deallocate thread port " "decode_exception_message two\n"); return false; } decode_exception_type (msg->exception); ret = write (exc_pipe[1], &msg->exception, sizeof(int)); if (ret == -1) eprintf ("failed to write exception into the pipe\n"); return true; }
//TODO improve this code static int __xnu_wait (RDebug *dbg, int pid) { // here comes the important thing kern_return_t kr; int ret_code, reason = R_DEBUG_REASON_UNKNOWN; mig_reply_error_t reply; bool ret; exc_msg msg; if (!dbg) { return reason; } msg.hdr.msgh_local_port = ex.exception_port; msg.hdr.msgh_size = sizeof (exc_msg); for (;;) { kr = mach_msg ( &msg.hdr, MACH_RCV_MSG | MACH_RCV_INTERRUPT, 0, sizeof (exc_msg), ex.exception_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); if (kr == MACH_RCV_INTERRUPTED) { reason = R_DEBUG_REASON_MACH_RCV_INTERRUPTED; break; } else if (kr != MACH_MSG_SUCCESS) { eprintf ("message didn't succeded\n"); break; } ret = validate_mach_message (dbg, &msg); if (!ret) { ret = handle_dead_notify (dbg, &msg); if (ret) { reason = R_DEBUG_REASON_DEAD; break; } } if (!ret) { encode_reply (&reply, &msg.hdr, KERN_FAILURE); kr = mach_msg (&reply.Head, MACH_SEND_MSG | MACH_SEND_INTERRUPT, reply.Head.msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); if (reply.Head.msgh_remote_port != 0 && kr != MACH_MSG_SUCCESS) { kr = mach_port_deallocate(mach_task_self (), reply.Head.msgh_remote_port); if (kr != KERN_SUCCESS) { eprintf ("failed to deallocate reply port\n"); } } continue; } reason = handle_exception_message (dbg, &msg, &ret_code); encode_reply (&reply, &msg.hdr, ret_code); kr = mach_msg (&reply.Head, MACH_SEND_MSG | MACH_SEND_INTERRUPT, reply.Head.msgh_size, 0, MACH_PORT_NULL, 0, MACH_PORT_NULL); if (reply.Head.msgh_remote_port != 0 && kr != MACH_MSG_SUCCESS) { kr = mach_port_deallocate(mach_task_self (), reply.Head.msgh_remote_port); if (kr != KERN_SUCCESS) eprintf ("failed to deallocate reply port\n"); } break; // to avoid infinite loops } dbg->stopaddr = r_debug_reg_get (dbg, "PC"); return reason; }