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