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 HdcDaemonForward *thisClass = reinterpret_cast<HdcDaemonForward *>(ctxPoint->thisClass);
35 thisClass->SetupPointContinue(ctxPoint, 1); // It usually works
36 Base::TryCloseHandle((const uv_handle_t *)handle, Base::CloseIdleCallback);
37 WRITE_LOG(LOG_DEBUG, "Setup JdwpPointCallBack finish");
38 --thisClass->refCount;
39 return;
40 }
41
SetupJdwpPoint(HCtxForward ctxPoint)42 bool HdcDaemonForward::SetupJdwpPoint(HCtxForward ctxPoint)
43 {
44 HdcDaemon *daemon = (HdcDaemon *)taskInfo->ownerSessionClass;
45 HdcJdwp *clsJdwp = (HdcJdwp *)daemon->clsJdwp;
46 uint32_t pid = std::stol(ctxPoint->localArgs[1]);
47 if (ctxPoint->checkPoint) { // checke
48 bool ret = clsJdwp->CheckPIDExist(pid);
49 SetupPointContinue(ctxPoint, (int)ret);
50 WRITE_LOG(LOG_DEBUG, "Jdwp jump checkpoint");
51 return true;
52 }
53 // do slave connect
54 // fd[0] for forward, fd[1] for jdwp
55 // forward to close fd[0], fd[1] for jdwp close
56 int fds[2] = { 0 };
57 bool ret = false;
58 Base::CreateSocketPair(fds);
59 if (uv_tcp_init(loopTask, &ctxPoint->tcp)) {
60 return ret;
61 }
62 ctxPoint->tcp.data = ctxPoint;
63 if (uv_tcp_open(&ctxPoint->tcp, fds[0])) {
64 return ret;
65 }
66 constexpr auto len = sizeof(uint32_t);
67 uint8_t flag[1 + len + len];
68 flag[0] = SP_JDWP_NEWFD;
69 if (memcpy_s(flag + 1, sizeof(flag) - 1, &pid, len) ||
70 memcpy_s(flag + 1 + len, sizeof(flag) - len - 1, &fds[1], len)) {
71 return ret;
72 }
73 if (ThreadCtrlCommunicate(flag, sizeof(flag)) > 0) {
74 ret = true;
75 }
76 WRITE_LOG(LOG_DEBUG, "SendJdwpNewFD Finish,ret:%d fd0:%d fd1:%d", ret, fds[0], fds[1]);
77 if (!ret) {
78 Base::CloseSocketPair(fds);
79 return ret;
80 }
81
82 ++refCount;
83 Base::IdleUvTask(loopTask, ctxPoint, SetupJdwpPointCallBack);
84 return ret;
85 }
86 }