• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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