1cc290419Sopenharmony_ci/* 2cc290419Sopenharmony_ci * Copyright (C) 2021 Huawei Device Co., Ltd. 3cc290419Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4cc290419Sopenharmony_ci * you may not use this file except in compliance with the License. 5cc290419Sopenharmony_ci * You may obtain a copy of the License at 6cc290419Sopenharmony_ci * 7cc290419Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8cc290419Sopenharmony_ci * 9cc290419Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10cc290419Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11cc290419Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12cc290419Sopenharmony_ci * See the License for the specific language governing permissions and 13cc290419Sopenharmony_ci * limitations under the License. 14cc290419Sopenharmony_ci */ 15cc290419Sopenharmony_ci#include "daemon_forward.h" 16cc290419Sopenharmony_ci#include <cstdint> 17cc290419Sopenharmony_ci#include "securec.h" 18cc290419Sopenharmony_ci#include "daemon.h" 19cc290419Sopenharmony_ci#include "jdwp.h" 20cc290419Sopenharmony_ci 21cc290419Sopenharmony_cinamespace Hdc { 22cc290419Sopenharmony_ciHdcDaemonForward::HdcDaemonForward(HTaskInfo hTaskInfo) 23cc290419Sopenharmony_ci : HdcForwardBase(hTaskInfo) 24cc290419Sopenharmony_ci{ 25cc290419Sopenharmony_ci} 26cc290419Sopenharmony_ci 27cc290419Sopenharmony_ciHdcDaemonForward::~HdcDaemonForward() 28cc290419Sopenharmony_ci{ 29cc290419Sopenharmony_ci} 30cc290419Sopenharmony_ci 31cc290419Sopenharmony_civoid HdcDaemonForward::SetupJdwpPointCallBack(uv_idle_t *handle) 32cc290419Sopenharmony_ci{ 33cc290419Sopenharmony_ci HCtxForward ctxPoint = (HCtxForward)handle->data; 34cc290419Sopenharmony_ci uint32_t id = ctxPoint->id; 35cc290419Sopenharmony_ci HdcDaemonForward *thisClass = reinterpret_cast<HdcDaemonForward *>(ctxPoint->thisClass); 36cc290419Sopenharmony_ci thisClass->SetupPointContinue(ctxPoint, 1); // It usually works 37cc290419Sopenharmony_ci Base::TryCloseHandle((const uv_handle_t *)handle, Base::CloseIdleCallback); 38cc290419Sopenharmony_ci --thisClass->refCount; 39cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "SetupJdwpPointCallBack finish id:%u", id); 40cc290419Sopenharmony_ci return; 41cc290419Sopenharmony_ci} 42cc290419Sopenharmony_ci 43cc290419Sopenharmony_cibool HdcDaemonForward::SetupJdwpPoint(HCtxForward ctxPoint) 44cc290419Sopenharmony_ci{ 45cc290419Sopenharmony_ci HdcDaemon *daemon = (HdcDaemon *)taskInfo->ownerSessionClass; 46cc290419Sopenharmony_ci HdcJdwp *clsJdwp = (HdcJdwp *)daemon->clsJdwp; 47cc290419Sopenharmony_ci uint32_t pid = std::stol(ctxPoint->localArgs[1]); 48cc290419Sopenharmony_ci if (ctxPoint->checkPoint) { 49cc290419Sopenharmony_ci uint32_t id = ctxPoint->id; 50cc290419Sopenharmony_ci bool ret = clsJdwp->CheckPIDExist(pid); 51cc290419Sopenharmony_ci SetupPointContinue(ctxPoint, (int)ret); 52cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "Jdwp jump checkpoint id:%u", id); 53cc290419Sopenharmony_ci return true; 54cc290419Sopenharmony_ci } 55cc290419Sopenharmony_ci // do slave connect 56cc290419Sopenharmony_ci // fd[0] for forward, fd[1] for jdwp 57cc290419Sopenharmony_ci // forward to close fd[0], fd[1] for jdwp close 58cc290419Sopenharmony_ci int fds[2] = { 0 }; 59cc290419Sopenharmony_ci bool ret = false; 60cc290419Sopenharmony_ci Base::CreateSocketPair(fds); 61cc290419Sopenharmony_ci if (uv_tcp_init(loopTask, &ctxPoint->tcp)) { 62cc290419Sopenharmony_ci return ret; 63cc290419Sopenharmony_ci } 64cc290419Sopenharmony_ci ctxPoint->tcp.data = ctxPoint; 65cc290419Sopenharmony_ci if (uv_tcp_open(&ctxPoint->tcp, fds[0])) { 66cc290419Sopenharmony_ci return ret; 67cc290419Sopenharmony_ci } 68cc290419Sopenharmony_ci constexpr auto len = sizeof(uint32_t); 69cc290419Sopenharmony_ci uint8_t flag[1 + len + len]; 70cc290419Sopenharmony_ci flag[0] = SP_JDWP_NEWFD; 71cc290419Sopenharmony_ci if (memcpy_s(flag + 1, sizeof(flag) - 1, &pid, len) || 72cc290419Sopenharmony_ci memcpy_s(flag + 1 + len, sizeof(flag) - len - 1, &fds[1], len)) { 73cc290419Sopenharmony_ci return ret; 74cc290419Sopenharmony_ci } 75cc290419Sopenharmony_ci if (ThreadCtrlCommunicate(flag, sizeof(flag)) > 0) { 76cc290419Sopenharmony_ci ret = true; 77cc290419Sopenharmony_ci } 78cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "SendJdwpNewFD Finish,ret:%d fd0:%d fd1:%d", ret, fds[0], fds[1]); 79cc290419Sopenharmony_ci if (!ret) { 80cc290419Sopenharmony_ci Base::CloseSocketPair(fds); 81cc290419Sopenharmony_ci return ret; 82cc290419Sopenharmony_ci } 83cc290419Sopenharmony_ci 84cc290419Sopenharmony_ci ++refCount; 85cc290419Sopenharmony_ci Base::IdleUvTask(loopTask, ctxPoint, SetupJdwpPointCallBack); 86cc290419Sopenharmony_ci return ret; 87cc290419Sopenharmony_ci} 88cc290419Sopenharmony_ci 89cc290419Sopenharmony_cibool HdcDaemonForward::SetupArkPoint(HCtxForward ctxPoint) 90cc290419Sopenharmony_ci{ 91cc290419Sopenharmony_ci HdcDaemon *daemon = (HdcDaemon *)taskInfo->ownerSessionClass; 92cc290419Sopenharmony_ci HdcJdwp *clsJdwp = (HdcJdwp *)daemon->clsJdwp; 93cc290419Sopenharmony_ci std::string ark = ctxPoint->localArgs[0]; // ark 94cc290419Sopenharmony_ci std::string svr = ctxPoint->localArgs[1]; // pid@tid@Debugger 95cc290419Sopenharmony_ci std::size_t found = svr.find_first_of("@"); 96cc290419Sopenharmony_ci if (found == std::string::npos) { 97cc290419Sopenharmony_ci SetupPointContinue(ctxPoint, true); 98cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "SetupArkPoint failed id:%s", svr.c_str()); 99cc290419Sopenharmony_ci ctxPoint->lastError = ark + ":" + svr + " parameter invalid"; 100cc290419Sopenharmony_ci return false; 101cc290419Sopenharmony_ci } 102cc290419Sopenharmony_ci std::string pidstr = svr.substr(0, found); 103cc290419Sopenharmony_ci uint32_t pid = static_cast<uint32_t>(std::atoi(pidstr.c_str())); 104cc290419Sopenharmony_ci bool ret = clsJdwp->CheckPIDExist(pid); 105cc290419Sopenharmony_ci if (!ret) { 106cc290419Sopenharmony_ci SetupPointContinue(ctxPoint, (int)ret); 107cc290419Sopenharmony_ci WRITE_LOG(LOG_WARN, "SetupArkPoint failed pid:%u not exist", pid); 108cc290419Sopenharmony_ci ctxPoint->lastError = ark + ":" + svr + " pid invalid"; 109cc290419Sopenharmony_ci return false; 110cc290419Sopenharmony_ci } 111cc290419Sopenharmony_ci // do slave connect 112cc290419Sopenharmony_ci // fd[0] for forward, fd[1] for ark 113cc290419Sopenharmony_ci ret = false; 114cc290419Sopenharmony_ci Base::CreateSocketPair(fds); 115cc290419Sopenharmony_ci std::string str = ark + ":" + svr; 116cc290419Sopenharmony_ci uint32_t size = 1 + sizeof(int32_t) + str.size(); 117cc290419Sopenharmony_ci uint8_t buf[size]; 118cc290419Sopenharmony_ci buf[0] = SP_ARK_NEWFD; 119cc290419Sopenharmony_ci if (memcpy_s(buf + 1, sizeof(int32_t), &fds[1], sizeof(int32_t)) || 120cc290419Sopenharmony_ci memcpy_s(buf + 1 + sizeof(int32_t), str.size(), str.c_str(), str.size())) { 121cc290419Sopenharmony_ci Base::CloseSocketPair(fds); 122cc290419Sopenharmony_ci return ret; 123cc290419Sopenharmony_ci } 124cc290419Sopenharmony_ci // buf: SP_ARK_NEWFD | fd[1] | pid@tid@Debugger 125cc290419Sopenharmony_ci if (ThreadCtrlCommunicate(buf, size) > 0) { 126cc290419Sopenharmony_ci ret = true; 127cc290419Sopenharmony_ci } 128cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "SetupArkPoint Finish,ret:%d fd0:%d fd1:%d", ret, fds[0], fds[1]); 129cc290419Sopenharmony_ci if (!ret) { 130cc290419Sopenharmony_ci Base::CloseSocketPair(fds); 131cc290419Sopenharmony_ci return ret; 132cc290419Sopenharmony_ci } 133cc290419Sopenharmony_ci ++refCount; 134cc290419Sopenharmony_ci Base::IdleUvTask(loopTask, ctxPoint, SetupJdwpPointCallBack); 135cc290419Sopenharmony_ci return ret; 136cc290419Sopenharmony_ci} 137cc290419Sopenharmony_ci} 138