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 "forward.h" 16cc290419Sopenharmony_ci#include "base.h" 17cc290419Sopenharmony_ci 18cc290419Sopenharmony_cinamespace Hdc { 19cc290419Sopenharmony_ciHdcForwardBase::HdcForwardBase(HTaskInfo hTaskInfo) 20cc290419Sopenharmony_ci : HdcTaskBase(hTaskInfo) 21cc290419Sopenharmony_ci{ 22cc290419Sopenharmony_ci fds[0] = -1; 23cc290419Sopenharmony_ci fds[1] = -1; 24cc290419Sopenharmony_ci} 25cc290419Sopenharmony_ci 26cc290419Sopenharmony_ciHdcForwardBase::~HdcForwardBase() 27cc290419Sopenharmony_ci{ 28cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "~HdcForwardBase channelId:%u", taskInfo->channelId); 29cc290419Sopenharmony_ci}; 30cc290419Sopenharmony_ci 31cc290419Sopenharmony_cibool HdcForwardBase::ReadyForRelease() 32cc290419Sopenharmony_ci{ 33cc290419Sopenharmony_ci if (!HdcTaskBase::ReadyForRelease()) { 34cc290419Sopenharmony_ci WRITE_LOG(LOG_WARN, "not ready for release channelId:%u", taskInfo->channelId); 35cc290419Sopenharmony_ci return false; 36cc290419Sopenharmony_ci } 37cc290419Sopenharmony_ci return true; 38cc290419Sopenharmony_ci} 39cc290419Sopenharmony_ci 40cc290419Sopenharmony_civoid HdcForwardBase::StopTask() 41cc290419Sopenharmony_ci{ 42cc290419Sopenharmony_ci ctxPointMutex.lock(); 43cc290419Sopenharmony_ci vector<HCtxForward> ctxs; 44cc290419Sopenharmony_ci map<uint32_t, HCtxForward>::iterator iter; 45cc290419Sopenharmony_ci for (iter = mapCtxPoint.begin(); iter != mapCtxPoint.end(); ++iter) { 46cc290419Sopenharmony_ci HCtxForward ctx = iter->second; 47cc290419Sopenharmony_ci ctxs.push_back(ctx); 48cc290419Sopenharmony_ci } 49cc290419Sopenharmony_ci // FREECONTEXT in the STOP is triggered by the other party sector, no longer notifying each other. 50cc290419Sopenharmony_ci mapCtxPoint.clear(); 51cc290419Sopenharmony_ci ctxPointMutex.unlock(); 52cc290419Sopenharmony_ci for (auto ctx: ctxs) { 53cc290419Sopenharmony_ci FreeContext(ctx, 0, false); 54cc290419Sopenharmony_ci } 55cc290419Sopenharmony_ci} 56cc290419Sopenharmony_ci 57cc290419Sopenharmony_civoid HdcForwardBase::OnAccept(uv_stream_t *server, HCtxForward ctxClient, uv_stream_t *client) 58cc290419Sopenharmony_ci{ 59cc290419Sopenharmony_ci HCtxForward ctxListen = (HCtxForward)server->data; 60cc290419Sopenharmony_ci char buf[BUF_SIZE_DEFAULT] = { 0 }; 61cc290419Sopenharmony_ci bool ret = false; 62cc290419Sopenharmony_ci while (true) { 63cc290419Sopenharmony_ci if (uv_accept(server, client)) { 64cc290419Sopenharmony_ci WRITE_LOG(LOG_FATAL, "uv_accept id:%u type:%d remoteParamenters:%s", 65cc290419Sopenharmony_ci ctxListen->id, ctxListen->type, ctxListen->remoteParamenters.c_str()); 66cc290419Sopenharmony_ci break; 67cc290419Sopenharmony_ci } 68cc290419Sopenharmony_ci ctxClient->type = ctxListen->type; 69cc290419Sopenharmony_ci ctxClient->remoteParamenters = ctxListen->remoteParamenters; 70cc290419Sopenharmony_ci int maxSize = sizeof(buf) - forwardParameterBufSize; 71cc290419Sopenharmony_ci // clang-format off 72cc290419Sopenharmony_ci if (snprintf_s(buf + forwardParameterBufSize, maxSize, maxSize - 1, "%s", 73cc290419Sopenharmony_ci ctxClient->remoteParamenters.c_str()) < 0) { 74cc290419Sopenharmony_ci break; 75cc290419Sopenharmony_ci } 76cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "OnAccept id:%u type:%d remoteParamenters:%s", 77cc290419Sopenharmony_ci ctxClient->id, ctxClient->type, ctxClient->remoteParamenters.c_str()); 78cc290419Sopenharmony_ci SendToTask(ctxClient->id, CMD_FORWARD_ACTIVE_SLAVE, reinterpret_cast<uint8_t *>(buf), 79cc290419Sopenharmony_ci strlen(buf + forwardParameterBufSize) + 9); // 9: pre 8bytes preserve for param bits 80cc290419Sopenharmony_ci ret = true; 81cc290419Sopenharmony_ci break; 82cc290419Sopenharmony_ci } 83cc290419Sopenharmony_ci if (!ret) { 84cc290419Sopenharmony_ci FreeContext(ctxClient, 0, false); 85cc290419Sopenharmony_ci } 86cc290419Sopenharmony_ci} 87cc290419Sopenharmony_ci 88cc290419Sopenharmony_civoid HdcForwardBase::ListenCallback(uv_stream_t *server, const int status) 89cc290419Sopenharmony_ci{ 90cc290419Sopenharmony_ci HCtxForward ctxListen = (HCtxForward)server->data; 91cc290419Sopenharmony_ci HdcForwardBase *thisClass = ctxListen->thisClass; 92cc290419Sopenharmony_ci uv_stream_t *client = nullptr; 93cc290419Sopenharmony_ci 94cc290419Sopenharmony_ci if (status == -1 || !ctxListen->ready) { 95cc290419Sopenharmony_ci WRITE_LOG(LOG_FATAL, "ListenCallback status:%d id:%u ready:%d", 96cc290419Sopenharmony_ci status, ctxListen->id, ctxListen->ready); 97cc290419Sopenharmony_ci thisClass->FreeContext(ctxListen, 0, false); 98cc290419Sopenharmony_ci thisClass->TaskFinish(); 99cc290419Sopenharmony_ci return; 100cc290419Sopenharmony_ci } 101cc290419Sopenharmony_ci HCtxForward ctxClient = (HCtxForward)thisClass->MallocContext(true); 102cc290419Sopenharmony_ci if (!ctxClient) { 103cc290419Sopenharmony_ci return; 104cc290419Sopenharmony_ci } 105cc290419Sopenharmony_ci if (ctxListen->type == FORWARD_TCP) { 106cc290419Sopenharmony_ci uv_tcp_init(ctxClient->thisClass->loopTask, &ctxClient->tcp); 107cc290419Sopenharmony_ci client = (uv_stream_t *)&ctxClient->tcp; 108cc290419Sopenharmony_ci } else { 109cc290419Sopenharmony_ci // FORWARD_ABSTRACT, FORWARD_RESERVED, FORWARD_FILESYSTEM, 110cc290419Sopenharmony_ci uv_pipe_init(ctxClient->thisClass->loopTask, &ctxClient->pipe, 0); 111cc290419Sopenharmony_ci client = (uv_stream_t *)&ctxClient->pipe; 112cc290419Sopenharmony_ci } 113cc290419Sopenharmony_ci thisClass->OnAccept(server, ctxClient, client); 114cc290419Sopenharmony_ci} 115cc290419Sopenharmony_ci 116cc290419Sopenharmony_civoid *HdcForwardBase::MallocContext(bool masterSlave) 117cc290419Sopenharmony_ci{ 118cc290419Sopenharmony_ci HCtxForward ctx = nullptr; 119cc290419Sopenharmony_ci if ((ctx = new ContextForward()) == nullptr) { 120cc290419Sopenharmony_ci return nullptr; 121cc290419Sopenharmony_ci } 122cc290419Sopenharmony_ci ctx->id = Base::GetRandomU32(); 123cc290419Sopenharmony_ci ctx->masterSlave = masterSlave; 124cc290419Sopenharmony_ci ctx->thisClass = this; 125cc290419Sopenharmony_ci ctx->fdClass = nullptr; 126cc290419Sopenharmony_ci ctx->tcp.data = ctx; 127cc290419Sopenharmony_ci ctx->pipe.data = ctx; 128cc290419Sopenharmony_ci AdminContext(OP_ADD, ctx->id, ctx); 129cc290419Sopenharmony_ci refCount++; 130cc290419Sopenharmony_ci return ctx; 131cc290419Sopenharmony_ci} 132cc290419Sopenharmony_ci 133cc290419Sopenharmony_civoid HdcForwardBase::FreeContextCallBack(HCtxForward ctx) 134cc290419Sopenharmony_ci{ 135cc290419Sopenharmony_ci Base::DoNextLoop(loopTask, ctx, [this](const uint8_t flag, string &msg, const void *data) { 136cc290419Sopenharmony_ci HCtxForward ctx = (HCtxForward)data; 137cc290419Sopenharmony_ci AdminContext(OP_REMOVE, ctx->id, nullptr); 138cc290419Sopenharmony_ci if (ctx != nullptr) { 139cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "Finally to delete id:%u", ctx->id); 140cc290419Sopenharmony_ci delete ctx; 141cc290419Sopenharmony_ci ctx = nullptr; 142cc290419Sopenharmony_ci } 143cc290419Sopenharmony_ci if (refCount > 0) { 144cc290419Sopenharmony_ci --refCount; 145cc290419Sopenharmony_ci } 146cc290419Sopenharmony_ci }); 147cc290419Sopenharmony_ci} 148cc290419Sopenharmony_ci 149cc290419Sopenharmony_civoid HdcForwardBase::FreeJDWP(HCtxForward ctx) 150cc290419Sopenharmony_ci{ 151cc290419Sopenharmony_ci Base::CloseFd(ctx->fd); 152cc290419Sopenharmony_ci if (ctx->fdClass) { 153cc290419Sopenharmony_ci ctx->fdClass->StopWorkOnThread(false, nullptr); 154cc290419Sopenharmony_ci 155cc290419Sopenharmony_ci auto funcReqClose = [](uv_idle_t *handle) -> void { 156cc290419Sopenharmony_ci uv_close_cb funcIdleHandleClose = [](uv_handle_t *handle) -> void { 157cc290419Sopenharmony_ci HCtxForward ctx = (HCtxForward)handle->data; 158cc290419Sopenharmony_ci ctx->thisClass->FreeContextCallBack(ctx); 159cc290419Sopenharmony_ci delete (uv_idle_t *)handle; 160cc290419Sopenharmony_ci }; 161cc290419Sopenharmony_ci HCtxForward context = (HCtxForward)handle->data; 162cc290419Sopenharmony_ci if (context->fdClass->ReadyForRelease()) { 163cc290419Sopenharmony_ci delete context->fdClass; 164cc290419Sopenharmony_ci context->fdClass = nullptr; 165cc290419Sopenharmony_ci Base::TryCloseHandle((uv_handle_t *)handle, funcIdleHandleClose); 166cc290419Sopenharmony_ci } 167cc290419Sopenharmony_ci }; 168cc290419Sopenharmony_ci Base::IdleUvTask(loopTask, ctx, funcReqClose); 169cc290419Sopenharmony_ci } 170cc290419Sopenharmony_ci} 171cc290419Sopenharmony_ci 172cc290419Sopenharmony_civoid HdcForwardBase::FreeContext(HCtxForward ctxIn, const uint32_t id, bool bNotifyRemote) 173cc290419Sopenharmony_ci{ 174cc290419Sopenharmony_ci std::lock_guard<std::mutex> lock(ctxFreeMutex); 175cc290419Sopenharmony_ci HCtxForward ctx = nullptr; 176cc290419Sopenharmony_ci if (!ctxIn) { 177cc290419Sopenharmony_ci if (!(ctx = (HCtxForward)AdminContext(OP_QUERY, id, nullptr))) { 178cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "Query id:%u failed", id); 179cc290419Sopenharmony_ci return; 180cc290419Sopenharmony_ci } 181cc290419Sopenharmony_ci } else { 182cc290419Sopenharmony_ci ctx = ctxIn; 183cc290419Sopenharmony_ci } 184cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "FreeContext id:%u, bNotifyRemote:%d, finish:%d", 185cc290419Sopenharmony_ci ctx->id, bNotifyRemote, ctx->finish); 186cc290419Sopenharmony_ci if (ctx->finish) { 187cc290419Sopenharmony_ci return; 188cc290419Sopenharmony_ci } 189cc290419Sopenharmony_ci if (bNotifyRemote) { 190cc290419Sopenharmony_ci SendToTask(ctx->id, CMD_FORWARD_FREE_CONTEXT, nullptr, 0); 191cc290419Sopenharmony_ci } 192cc290419Sopenharmony_ci uv_close_cb funcHandleClose = [](uv_handle_t *handle) -> void { 193cc290419Sopenharmony_ci HCtxForward ctx = (HCtxForward)handle->data; 194cc290419Sopenharmony_ci ctx->thisClass->FreeContextCallBack(ctx); 195cc290419Sopenharmony_ci }; 196cc290419Sopenharmony_ci switch (ctx->type) { 197cc290419Sopenharmony_ci case FORWARD_TCP: 198cc290419Sopenharmony_ci case FORWARD_JDWP: 199cc290419Sopenharmony_ci case FORWARD_ARK: 200cc290419Sopenharmony_ci Base::TryCloseHandle((uv_handle_t *)&ctx->tcp, true, funcHandleClose); 201cc290419Sopenharmony_ci break; 202cc290419Sopenharmony_ci case FORWARD_ABSTRACT: 203cc290419Sopenharmony_ci case FORWARD_RESERVED: 204cc290419Sopenharmony_ci case FORWARD_FILESYSTEM: 205cc290419Sopenharmony_ci Base::TryCloseHandle((uv_handle_t *)&ctx->pipe, true, funcHandleClose); 206cc290419Sopenharmony_ci break; 207cc290419Sopenharmony_ci case FORWARD_DEVICE: { 208cc290419Sopenharmony_ci FreeJDWP(ctx); 209cc290419Sopenharmony_ci break; 210cc290419Sopenharmony_ci } 211cc290419Sopenharmony_ci default: 212cc290419Sopenharmony_ci break; 213cc290419Sopenharmony_ci } 214cc290419Sopenharmony_ci ctx->finish = true; 215cc290419Sopenharmony_ci} 216cc290419Sopenharmony_ci 217cc290419Sopenharmony_cibool HdcForwardBase::SendToTask(const uint32_t cid, const uint16_t command, uint8_t *bufPtr, const int bufSize) 218cc290419Sopenharmony_ci{ 219cc290419Sopenharmony_ci StartTraceScope("HdcForwardBase::SendToTask"); 220cc290419Sopenharmony_ci bool ret = false; 221cc290419Sopenharmony_ci // usually MAX_SIZE_IOBUF*2 from HdcFileDescriptor maxIO 222cc290419Sopenharmony_ci if (bufSize > Base::GetMaxBufSizeStable() * BUF_MULTIPLE) { 223cc290419Sopenharmony_ci WRITE_LOG(LOG_FATAL, "SendToTask bufSize:%d", bufSize); 224cc290419Sopenharmony_ci return false; 225cc290419Sopenharmony_ci } 226cc290419Sopenharmony_ci auto newBuf = new uint8_t[bufSize + BUF_EXTEND_SIZE]; 227cc290419Sopenharmony_ci if (!newBuf) { 228cc290419Sopenharmony_ci return false; 229cc290419Sopenharmony_ci } 230cc290419Sopenharmony_ci *reinterpret_cast<uint32_t *>(newBuf) = htonl(cid); 231cc290419Sopenharmony_ci if (bufSize > 0 && bufPtr != nullptr && memcpy_s(newBuf + BUF_EXTEND_SIZE, bufSize, bufPtr, bufSize) != EOK) { 232cc290419Sopenharmony_ci delete[] newBuf; 233cc290419Sopenharmony_ci return false; 234cc290419Sopenharmony_ci } 235cc290419Sopenharmony_ci ret = SendToAnother(command, newBuf, bufSize + BUF_EXTEND_SIZE); 236cc290419Sopenharmony_ci delete[] newBuf; 237cc290419Sopenharmony_ci return ret; 238cc290419Sopenharmony_ci} 239cc290419Sopenharmony_ci 240cc290419Sopenharmony_ci// Forward flow is small and frequency is fast 241cc290419Sopenharmony_civoid HdcForwardBase::AllocForwardBuf(uv_handle_t *handle, size_t sizeSuggested, uv_buf_t *buf) 242cc290419Sopenharmony_ci{ 243cc290419Sopenharmony_ci size_t size = sizeSuggested; 244cc290419Sopenharmony_ci if (size > MAX_USBFFS_BULK) { 245cc290419Sopenharmony_ci size = MAX_USBFFS_BULK; 246cc290419Sopenharmony_ci } 247cc290419Sopenharmony_ci buf->base = (char *)new char[size]; 248cc290419Sopenharmony_ci if (buf->base) { 249cc290419Sopenharmony_ci buf->len = (size > 0) ? (size - 1) : 0; 250cc290419Sopenharmony_ci } else { 251cc290419Sopenharmony_ci WRITE_LOG(LOG_WARN, "AllocForwardBuf == null"); 252cc290419Sopenharmony_ci } 253cc290419Sopenharmony_ci} 254cc290419Sopenharmony_ci 255cc290419Sopenharmony_civoid HdcForwardBase::ReadForwardBuf(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) 256cc290419Sopenharmony_ci{ 257cc290419Sopenharmony_ci HCtxForward ctx = (HCtxForward)stream->data; 258cc290419Sopenharmony_ci if (nread < 0) { 259cc290419Sopenharmony_ci WRITE_LOG(LOG_INFO, "ReadForwardBuf nread:%zd id:%u", nread, ctx->id); 260cc290419Sopenharmony_ci ctx->thisClass->FreeContext(ctx, 0, true); 261cc290419Sopenharmony_ci delete[] buf->base; 262cc290419Sopenharmony_ci return; 263cc290419Sopenharmony_ci } 264cc290419Sopenharmony_ci if (nread == 0) { 265cc290419Sopenharmony_ci WRITE_LOG(LOG_INFO, "ReadForwardBuf nread:0 id:%u", ctx->id); 266cc290419Sopenharmony_ci delete[] buf->base; 267cc290419Sopenharmony_ci return; 268cc290419Sopenharmony_ci } 269cc290419Sopenharmony_ci ctx->thisClass->SendToTask(ctx->id, CMD_FORWARD_DATA, (uint8_t *)buf->base, nread); 270cc290419Sopenharmony_ci // clear 271cc290419Sopenharmony_ci delete[] buf->base; 272cc290419Sopenharmony_ci} 273cc290419Sopenharmony_ci 274cc290419Sopenharmony_civoid HdcForwardBase::ConnectTarget(uv_connect_t *connection, int status) 275cc290419Sopenharmony_ci{ 276cc290419Sopenharmony_ci HCtxForward ctx = (HCtxForward)connection->data; 277cc290419Sopenharmony_ci HdcForwardBase *thisClass = ctx->thisClass; 278cc290419Sopenharmony_ci delete connection; 279cc290419Sopenharmony_ci if (status < 0) { 280cc290419Sopenharmony_ci constexpr int bufSize = 1024; 281cc290419Sopenharmony_ci char buf[bufSize] = { 0 }; 282cc290419Sopenharmony_ci uv_err_name_r(status, buf, bufSize); 283cc290419Sopenharmony_ci WRITE_LOG(LOG_WARN, "Forward connect result:%d error:%s", status, buf); 284cc290419Sopenharmony_ci } 285cc290419Sopenharmony_ci thisClass->SetupPointContinue(ctx, status); 286cc290419Sopenharmony_ci} 287cc290419Sopenharmony_ci 288cc290419Sopenharmony_cibool HdcForwardBase::CheckNodeInfo(const char *nodeInfo, string as[2]) 289cc290419Sopenharmony_ci{ 290cc290419Sopenharmony_ci string str = nodeInfo; 291cc290419Sopenharmony_ci size_t strLen = str.size(); 292cc290419Sopenharmony_ci if (strLen < 1) { 293cc290419Sopenharmony_ci return false; 294cc290419Sopenharmony_ci } 295cc290419Sopenharmony_ci size_t pos = str.find(':'); 296cc290419Sopenharmony_ci if (pos != string::npos) { 297cc290419Sopenharmony_ci if (pos == 0 || pos == strLen - 1) { 298cc290419Sopenharmony_ci return false; 299cc290419Sopenharmony_ci } 300cc290419Sopenharmony_ci as[0] = str.substr(0, pos); 301cc290419Sopenharmony_ci as[1] = str.substr(pos + 1); 302cc290419Sopenharmony_ci } else { 303cc290419Sopenharmony_ci return false; 304cc290419Sopenharmony_ci } 305cc290419Sopenharmony_ci if (as[0] == "tcp") { 306cc290419Sopenharmony_ci if (as[1].size() > std::to_string(MAX_IP_PORT).size()) { 307cc290419Sopenharmony_ci return false; 308cc290419Sopenharmony_ci } 309cc290419Sopenharmony_ci int port = atoi(as[1].c_str()); 310cc290419Sopenharmony_ci if (port <= 0 || port > MAX_IP_PORT) { 311cc290419Sopenharmony_ci return false; 312cc290419Sopenharmony_ci } 313cc290419Sopenharmony_ci } 314cc290419Sopenharmony_ci return true; 315cc290419Sopenharmony_ci} 316cc290419Sopenharmony_ci 317cc290419Sopenharmony_cibool HdcForwardBase::SetupPointContinue(HCtxForward ctx, int status) 318cc290419Sopenharmony_ci{ 319cc290419Sopenharmony_ci if (ctx->checkPoint) { 320cc290419Sopenharmony_ci // send to active 321cc290419Sopenharmony_ci uint8_t flag = status > 0; 322cc290419Sopenharmony_ci SendToTask(ctx->id, CMD_FORWARD_CHECK_RESULT, &flag, 1); 323cc290419Sopenharmony_ci FreeContext(ctx, 0, false); 324cc290419Sopenharmony_ci return true; 325cc290419Sopenharmony_ci } 326cc290419Sopenharmony_ci if (status < 0) { 327cc290419Sopenharmony_ci FreeContext(ctx, 0, true); 328cc290419Sopenharmony_ci return false; 329cc290419Sopenharmony_ci } 330cc290419Sopenharmony_ci // send to active 331cc290419Sopenharmony_ci if (!SendToTask(ctx->id, CMD_FORWARD_ACTIVE_MASTER, nullptr, 0)) { 332cc290419Sopenharmony_ci WRITE_LOG(LOG_FATAL, "SetupPointContinue SendToTask failed id:%u", ctx->id); 333cc290419Sopenharmony_ci FreeContext(ctx, 0, true); 334cc290419Sopenharmony_ci return false; 335cc290419Sopenharmony_ci } 336cc290419Sopenharmony_ci return DoForwardBegin(ctx); 337cc290419Sopenharmony_ci} 338cc290419Sopenharmony_ci 339cc290419Sopenharmony_cibool HdcForwardBase::DetechForwardType(HCtxForward ctxPoint) 340cc290419Sopenharmony_ci{ 341cc290419Sopenharmony_ci string &sFType = ctxPoint->localArgs[0]; 342cc290419Sopenharmony_ci string &sNodeCfg = ctxPoint->localArgs[1]; 343cc290419Sopenharmony_ci // string to enum 344cc290419Sopenharmony_ci if (sFType == "tcp") { 345cc290419Sopenharmony_ci ctxPoint->type = FORWARD_TCP; 346cc290419Sopenharmony_ci } else if (sFType == "dev") { 347cc290419Sopenharmony_ci ctxPoint->type = FORWARD_DEVICE; 348cc290419Sopenharmony_ci } else if (sFType == "localabstract") { 349cc290419Sopenharmony_ci // daemon shell: /system/bin/socat abstract-listen:linux-abstract - 350cc290419Sopenharmony_ci // daemon shell: /system/bin/socat - abstract-connect:linux-abstract 351cc290419Sopenharmony_ci // host: hdc fport tcp:8080 localabstract:linux-abstract 352cc290419Sopenharmony_ci ctxPoint->type = FORWARD_ABSTRACT; 353cc290419Sopenharmony_ci } else if (sFType == "localreserved") { 354cc290419Sopenharmony_ci sNodeCfg = harmonyReservedSocketPrefix + sNodeCfg; 355cc290419Sopenharmony_ci ctxPoint->type = FORWARD_RESERVED; 356cc290419Sopenharmony_ci } else if (sFType == "localfilesystem") { 357cc290419Sopenharmony_ci sNodeCfg = filesystemSocketPrefix + sNodeCfg; 358cc290419Sopenharmony_ci ctxPoint->type = FORWARD_FILESYSTEM; 359cc290419Sopenharmony_ci } else if (sFType == "jdwp") { 360cc290419Sopenharmony_ci ctxPoint->type = FORWARD_JDWP; 361cc290419Sopenharmony_ci } else if (sFType == "ark") { 362cc290419Sopenharmony_ci ctxPoint->type = FORWARD_ARK; 363cc290419Sopenharmony_ci } else { 364cc290419Sopenharmony_ci return false; 365cc290419Sopenharmony_ci } 366cc290419Sopenharmony_ci return true; 367cc290419Sopenharmony_ci} 368cc290419Sopenharmony_ci 369cc290419Sopenharmony_cibool HdcForwardBase::SetupTCPPoint(HCtxForward ctxPoint) 370cc290419Sopenharmony_ci{ 371cc290419Sopenharmony_ci string &sNodeCfg = ctxPoint->localArgs[1]; 372cc290419Sopenharmony_ci int port = atoi(sNodeCfg.c_str()); 373cc290419Sopenharmony_ci ctxPoint->tcp.data = ctxPoint; 374cc290419Sopenharmony_ci uv_tcp_init(loopTask, &ctxPoint->tcp); 375cc290419Sopenharmony_ci struct sockaddr_in addr; 376cc290419Sopenharmony_ci if (ctxPoint->masterSlave) { 377cc290419Sopenharmony_ci uv_ip4_addr("127.0.0.1", port, &addr); // loop interface 378cc290419Sopenharmony_ci uv_tcp_bind(&ctxPoint->tcp, (const struct sockaddr *)&addr, 0); 379cc290419Sopenharmony_ci if (uv_listen((uv_stream_t *)&ctxPoint->tcp, UV_LISTEN_LBACKOG, ListenCallback)) { 380cc290419Sopenharmony_ci ctxPoint->lastError = "TCP Port listen failed at " + sNodeCfg; 381cc290419Sopenharmony_ci return false; 382cc290419Sopenharmony_ci } 383cc290419Sopenharmony_ci } else { 384cc290419Sopenharmony_ci uv_ip4_addr("127.0.0.1", port, &addr); // loop interface 385cc290419Sopenharmony_ci uv_connect_t *conn = new(std::nothrow) uv_connect_t(); 386cc290419Sopenharmony_ci if (conn == nullptr) { 387cc290419Sopenharmony_ci WRITE_LOG(LOG_FATAL, "SetupTCPPoint new conn failed"); 388cc290419Sopenharmony_ci return false; 389cc290419Sopenharmony_ci } 390cc290419Sopenharmony_ci conn->data = ctxPoint; 391cc290419Sopenharmony_ci uv_tcp_connect(conn, (uv_tcp_t *)&ctxPoint->tcp, (const struct sockaddr *)&addr, ConnectTarget); 392cc290419Sopenharmony_ci } 393cc290419Sopenharmony_ci return true; 394cc290419Sopenharmony_ci} 395cc290419Sopenharmony_ci 396cc290419Sopenharmony_cibool HdcForwardBase::SetupDevicePoint(HCtxForward ctxPoint) 397cc290419Sopenharmony_ci{ 398cc290419Sopenharmony_ci uint8_t flag = 1; 399cc290419Sopenharmony_ci string &sNodeCfg = ctxPoint->localArgs[1]; 400cc290419Sopenharmony_ci string resolvedPath = Base::CanonicalizeSpecPath(sNodeCfg); 401cc290419Sopenharmony_ci if ((ctxPoint->fd = open(resolvedPath.c_str(), O_RDWR)) < 0) { 402cc290419Sopenharmony_ci ctxPoint->lastError = "Open unix-dev failed"; 403cc290419Sopenharmony_ci flag = -1; 404cc290419Sopenharmony_ci } 405cc290419Sopenharmony_ci auto funcRead = [&](const void *a, uint8_t *b, const int c) -> bool { 406cc290419Sopenharmony_ci HCtxForward ctx = (HCtxForward)a; 407cc290419Sopenharmony_ci return SendToTask(ctx->id, CMD_FORWARD_DATA, b, c); 408cc290419Sopenharmony_ci }; 409cc290419Sopenharmony_ci auto funcFinish = [&](const void *a, const bool b, const string c) -> bool { 410cc290419Sopenharmony_ci HCtxForward ctx = (HCtxForward)a; 411cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "funcFinish id:%u ret:%d reason:%s", ctx->id, b, c.c_str()); 412cc290419Sopenharmony_ci FreeContext(ctx, 0, true); 413cc290419Sopenharmony_ci return false; 414cc290419Sopenharmony_ci }; 415cc290419Sopenharmony_ci ctxPoint->fdClass = new(std::nothrow) HdcFileDescriptor(loopTask, ctxPoint->fd, ctxPoint, funcRead, 416cc290419Sopenharmony_ci funcFinish, true); 417cc290419Sopenharmony_ci if (ctxPoint->fdClass == nullptr) { 418cc290419Sopenharmony_ci WRITE_LOG(LOG_FATAL, "SetupDevicePoint new ctxPoint->fdClass failed"); 419cc290419Sopenharmony_ci return false; 420cc290419Sopenharmony_ci } 421cc290419Sopenharmony_ci SetupPointContinue(ctxPoint, flag); 422cc290419Sopenharmony_ci return true; 423cc290419Sopenharmony_ci} 424cc290419Sopenharmony_ci 425cc290419Sopenharmony_cibool HdcForwardBase::LocalAbstractConnect(uv_pipe_t *pipe, string &sNodeCfg) 426cc290419Sopenharmony_ci{ 427cc290419Sopenharmony_ci bool abstractRet = false; 428cc290419Sopenharmony_ci#ifndef _WIN32 429cc290419Sopenharmony_ci int s = 0; 430cc290419Sopenharmony_ci do { 431cc290419Sopenharmony_ci if ((s = socket(AF_LOCAL, SOCK_STREAM, 0)) < 0) { 432cc290419Sopenharmony_ci break; 433cc290419Sopenharmony_ci } 434cc290419Sopenharmony_ci fcntl(s, F_SETFD, FD_CLOEXEC); 435cc290419Sopenharmony_ci struct sockaddr_un addr; 436cc290419Sopenharmony_ci Base::ZeroStruct(addr); 437cc290419Sopenharmony_ci int addrLen = sNodeCfg.size() + offsetof(struct sockaddr_un, sun_path) + 1; 438cc290419Sopenharmony_ci addr.sun_family = AF_LOCAL; 439cc290419Sopenharmony_ci addr.sun_path[0] = 0; 440cc290419Sopenharmony_ci 441cc290419Sopenharmony_ci if (memcpy_s(addr.sun_path + 1, sizeof(addr.sun_path) - 1, sNodeCfg.c_str(), sNodeCfg.size()) != EOK) { 442cc290419Sopenharmony_ci break; 443cc290419Sopenharmony_ci }; 444cc290419Sopenharmony_ci struct timeval timeout = { 3, 0 }; 445cc290419Sopenharmony_ci setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)); 446cc290419Sopenharmony_ci if (connect(s, reinterpret_cast<struct sockaddr *>(&addr), addrLen) < 0) { 447cc290419Sopenharmony_ci WRITE_LOG(LOG_FATAL, "LocalAbstractConnect failed errno:%d", errno); 448cc290419Sopenharmony_ci break; 449cc290419Sopenharmony_ci } 450cc290419Sopenharmony_ci if (uv_pipe_open(pipe, s)) { 451cc290419Sopenharmony_ci break; 452cc290419Sopenharmony_ci } 453cc290419Sopenharmony_ci abstractRet = true; 454cc290419Sopenharmony_ci } while (false); 455cc290419Sopenharmony_ci if (!abstractRet) { 456cc290419Sopenharmony_ci Base::CloseFd(s); 457cc290419Sopenharmony_ci } 458cc290419Sopenharmony_ci#endif 459cc290419Sopenharmony_ci return abstractRet; 460cc290419Sopenharmony_ci} 461cc290419Sopenharmony_ci 462cc290419Sopenharmony_cibool HdcForwardBase::SetupFilePoint(HCtxForward ctxPoint) 463cc290419Sopenharmony_ci{ 464cc290419Sopenharmony_ci string &sNodeCfg = ctxPoint->localArgs[1]; 465cc290419Sopenharmony_ci ctxPoint->pipe.data = ctxPoint; 466cc290419Sopenharmony_ci uv_pipe_init(loopTask, &ctxPoint->pipe, 0); 467cc290419Sopenharmony_ci if (ctxPoint->masterSlave) { 468cc290419Sopenharmony_ci if (ctxPoint->type == FORWARD_RESERVED || ctxPoint->type == FORWARD_FILESYSTEM) { 469cc290419Sopenharmony_ci unlink(sNodeCfg.c_str()); 470cc290419Sopenharmony_ci } 471cc290419Sopenharmony_ci if (uv_pipe_bind(&ctxPoint->pipe, sNodeCfg.c_str())) { 472cc290419Sopenharmony_ci ctxPoint->lastError = "Unix pipe bind failed"; 473cc290419Sopenharmony_ci return false; 474cc290419Sopenharmony_ci } 475cc290419Sopenharmony_ci if (uv_listen((uv_stream_t *)&ctxPoint->pipe, UV_LISTEN_LBACKOG, ListenCallback)) { 476cc290419Sopenharmony_ci ctxPoint->lastError = "Unix pipe listen failed"; 477cc290419Sopenharmony_ci return false; 478cc290419Sopenharmony_ci } 479cc290419Sopenharmony_ci } else { 480cc290419Sopenharmony_ci if (ctxPoint->type == FORWARD_ABSTRACT) { 481cc290419Sopenharmony_ci bool abstractRet = LocalAbstractConnect(&ctxPoint->pipe, sNodeCfg); 482cc290419Sopenharmony_ci SetupPointContinue(ctxPoint, abstractRet ? 0 : -1); 483cc290419Sopenharmony_ci if (!abstractRet) { 484cc290419Sopenharmony_ci ctxPoint->lastError = "LocalAbstractConnect failed"; 485cc290419Sopenharmony_ci return false; 486cc290419Sopenharmony_ci } 487cc290419Sopenharmony_ci } else { 488cc290419Sopenharmony_ci uv_connect_t *connect = new(std::nothrow) uv_connect_t(); 489cc290419Sopenharmony_ci if (connect == nullptr) { 490cc290419Sopenharmony_ci WRITE_LOG(LOG_FATAL, "SetupFilePoint new connect failed"); 491cc290419Sopenharmony_ci return false; 492cc290419Sopenharmony_ci } 493cc290419Sopenharmony_ci connect->data = ctxPoint; 494cc290419Sopenharmony_ci uv_pipe_connect(connect, &ctxPoint->pipe, sNodeCfg.c_str(), ConnectTarget); 495cc290419Sopenharmony_ci } 496cc290419Sopenharmony_ci } 497cc290419Sopenharmony_ci return true; 498cc290419Sopenharmony_ci} 499cc290419Sopenharmony_ci 500cc290419Sopenharmony_cibool HdcForwardBase::SetupPoint(HCtxForward ctxPoint) 501cc290419Sopenharmony_ci{ 502cc290419Sopenharmony_ci bool ret = true; 503cc290419Sopenharmony_ci if (!DetechForwardType(ctxPoint)) { 504cc290419Sopenharmony_ci return false; 505cc290419Sopenharmony_ci } 506cc290419Sopenharmony_ci switch (ctxPoint->type) { 507cc290419Sopenharmony_ci case FORWARD_TCP: 508cc290419Sopenharmony_ci if (!SetupTCPPoint(ctxPoint)) { 509cc290419Sopenharmony_ci ret = false; 510cc290419Sopenharmony_ci }; 511cc290419Sopenharmony_ci break; 512cc290419Sopenharmony_ci#ifndef _WIN32 513cc290419Sopenharmony_ci case FORWARD_DEVICE: 514cc290419Sopenharmony_ci if (!SetupDevicePoint(ctxPoint)) { 515cc290419Sopenharmony_ci ret = false; 516cc290419Sopenharmony_ci }; 517cc290419Sopenharmony_ci break; 518cc290419Sopenharmony_ci case FORWARD_JDWP: 519cc290419Sopenharmony_ci if (!SetupJdwpPoint(ctxPoint)) { 520cc290419Sopenharmony_ci ret = false; 521cc290419Sopenharmony_ci }; 522cc290419Sopenharmony_ci break; 523cc290419Sopenharmony_ci case FORWARD_ABSTRACT: 524cc290419Sopenharmony_ci case FORWARD_RESERVED: 525cc290419Sopenharmony_ci case FORWARD_FILESYSTEM: 526cc290419Sopenharmony_ci if (!SetupFilePoint(ctxPoint)) { 527cc290419Sopenharmony_ci ret = false; 528cc290419Sopenharmony_ci }; 529cc290419Sopenharmony_ci break; 530cc290419Sopenharmony_ci#else 531cc290419Sopenharmony_ci case FORWARD_DEVICE: 532cc290419Sopenharmony_ci case FORWARD_JDWP: 533cc290419Sopenharmony_ci case FORWARD_ABSTRACT: 534cc290419Sopenharmony_ci case FORWARD_RESERVED: 535cc290419Sopenharmony_ci case FORWARD_FILESYSTEM: 536cc290419Sopenharmony_ci ctxPoint->lastError = "Not supoort forward-type"; 537cc290419Sopenharmony_ci ret = false; 538cc290419Sopenharmony_ci break; 539cc290419Sopenharmony_ci#endif 540cc290419Sopenharmony_ci default: 541cc290419Sopenharmony_ci ctxPoint->lastError = "Not supoort forward-type"; 542cc290419Sopenharmony_ci ret = false; 543cc290419Sopenharmony_ci break; 544cc290419Sopenharmony_ci } 545cc290419Sopenharmony_ci return ret; 546cc290419Sopenharmony_ci} 547cc290419Sopenharmony_ci 548cc290419Sopenharmony_cibool HdcForwardBase::BeginForward(const string &command, string &sError) 549cc290419Sopenharmony_ci{ 550cc290419Sopenharmony_ci bool ret = false; 551cc290419Sopenharmony_ci int argc = 0; 552cc290419Sopenharmony_ci char bufString[BUF_SIZE_SMALL] = ""; 553cc290419Sopenharmony_ci HCtxForward ctxPoint = (HCtxForward)MallocContext(true); 554cc290419Sopenharmony_ci if (!ctxPoint) { 555cc290419Sopenharmony_ci WRITE_LOG(LOG_FATAL, "MallocContext failed"); 556cc290419Sopenharmony_ci return false; 557cc290419Sopenharmony_ci } 558cc290419Sopenharmony_ci char **argv = Base::SplitCommandToArgs(command.c_str(), &argc); 559cc290419Sopenharmony_ci if (argv == nullptr) { 560cc290419Sopenharmony_ci WRITE_LOG(LOG_FATAL, "SplitCommandToArgs failed"); 561cc290419Sopenharmony_ci return false; 562cc290419Sopenharmony_ci } 563cc290419Sopenharmony_ci while (true) { 564cc290419Sopenharmony_ci if (argc < CMD_ARG1_COUNT) { 565cc290419Sopenharmony_ci break; 566cc290419Sopenharmony_ci } 567cc290419Sopenharmony_ci if (strlen(argv[0]) > BUF_SIZE_SMALL || strlen(argv[1]) > BUF_SIZE_SMALL) { 568cc290419Sopenharmony_ci break; 569cc290419Sopenharmony_ci } 570cc290419Sopenharmony_ci if (!CheckNodeInfo(argv[0], ctxPoint->localArgs)) { 571cc290419Sopenharmony_ci break; 572cc290419Sopenharmony_ci } 573cc290419Sopenharmony_ci if (!CheckNodeInfo(argv[1], ctxPoint->remoteArgs)) { 574cc290419Sopenharmony_ci break; 575cc290419Sopenharmony_ci } 576cc290419Sopenharmony_ci ctxPoint->remoteParamenters = argv[1]; 577cc290419Sopenharmony_ci if (!SetupPoint(ctxPoint)) { 578cc290419Sopenharmony_ci break; 579cc290419Sopenharmony_ci } 580cc290419Sopenharmony_ci 581cc290419Sopenharmony_ci ret = true; 582cc290419Sopenharmony_ci break; 583cc290419Sopenharmony_ci } 584cc290419Sopenharmony_ci sError = ctxPoint->lastError; 585cc290419Sopenharmony_ci if (ret) { 586cc290419Sopenharmony_ci // First 8-byte parameter bit 587cc290419Sopenharmony_ci int maxBufSize = sizeof(bufString) - forwardParameterBufSize; 588cc290419Sopenharmony_ci if (snprintf_s(bufString + forwardParameterBufSize, maxBufSize, maxBufSize - 1, "%s", argv[1]) > 0) { 589cc290419Sopenharmony_ci SendToTask(ctxPoint->id, CMD_FORWARD_CHECK, reinterpret_cast<uint8_t *>(bufString), 590cc290419Sopenharmony_ci forwardParameterBufSize + strlen(bufString + forwardParameterBufSize) + 1); 591cc290419Sopenharmony_ci taskCommand = command; 592cc290419Sopenharmony_ci } 593cc290419Sopenharmony_ci } 594cc290419Sopenharmony_ci delete[](reinterpret_cast<char *>(argv)); 595cc290419Sopenharmony_ci return ret; 596cc290419Sopenharmony_ci} 597cc290419Sopenharmony_ci 598cc290419Sopenharmony_ciinline bool HdcForwardBase::FilterCommand(uint8_t *bufCmdIn, uint32_t *idOut, uint8_t **pContentBuf) 599cc290419Sopenharmony_ci{ 600cc290419Sopenharmony_ci *pContentBuf = bufCmdIn + DWORD_SERIALIZE_SIZE; 601cc290419Sopenharmony_ci *idOut = ntohl(*reinterpret_cast<uint32_t *>(bufCmdIn)); 602cc290419Sopenharmony_ci return true; 603cc290419Sopenharmony_ci} 604cc290419Sopenharmony_ci 605cc290419Sopenharmony_cibool HdcForwardBase::SlaveConnect(uint8_t *bufCmd, const int bufSize, bool bCheckPoint, string &sError) 606cc290419Sopenharmony_ci{ 607cc290419Sopenharmony_ci if (bufSize <= DWORD_SERIALIZE_SIZE + forwardParameterBufSize) { 608cc290419Sopenharmony_ci WRITE_LOG(LOG_FATAL, "Illegal payloadSize, shorter than forward header"); 609cc290419Sopenharmony_ci return false; 610cc290419Sopenharmony_ci } 611cc290419Sopenharmony_ci bool ret = false; 612cc290419Sopenharmony_ci char *content = nullptr; 613cc290419Sopenharmony_ci uint32_t idSlaveOld = 0; 614cc290419Sopenharmony_ci HCtxForward ctxPoint = (HCtxForward)MallocContext(false); 615cc290419Sopenharmony_ci if (!ctxPoint) { 616cc290419Sopenharmony_ci WRITE_LOG(LOG_FATAL, "MallocContext failed"); 617cc290419Sopenharmony_ci return false; 618cc290419Sopenharmony_ci } 619cc290419Sopenharmony_ci idSlaveOld = ctxPoint->id; 620cc290419Sopenharmony_ci ctxPoint->checkPoint = bCheckPoint; 621cc290419Sopenharmony_ci // refresh another id,8byte param 622cc290419Sopenharmony_ci FilterCommand(bufCmd, &ctxPoint->id, reinterpret_cast<uint8_t **>(&content)); 623cc290419Sopenharmony_ci AdminContext(OP_UPDATE, idSlaveOld, ctxPoint); 624cc290419Sopenharmony_ci content += forwardParameterBufSize; 625cc290419Sopenharmony_ci if (!CheckNodeInfo(content, ctxPoint->localArgs)) { 626cc290419Sopenharmony_ci WRITE_LOG(LOG_FATAL, "SlaveConnect CheckNodeInfo failed content:%s", content); 627cc290419Sopenharmony_ci goto Finish; 628cc290419Sopenharmony_ci } 629cc290419Sopenharmony_ci if (!DetechForwardType(ctxPoint)) { 630cc290419Sopenharmony_ci WRITE_LOG(LOG_FATAL, "SlaveConnect DetechForwardType failed content:%s", content); 631cc290419Sopenharmony_ci goto Finish; 632cc290419Sopenharmony_ci } 633cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "id:%u type:%d", ctxPoint->id, ctxPoint->type); 634cc290419Sopenharmony_ci if (ctxPoint->type == FORWARD_ARK) { 635cc290419Sopenharmony_ci if (ctxPoint->checkPoint) { 636cc290419Sopenharmony_ci if (!SetupArkPoint(ctxPoint)) { 637cc290419Sopenharmony_ci sError = ctxPoint->lastError; 638cc290419Sopenharmony_ci WRITE_LOG(LOG_FATAL, "SlaveConnect SetupArkPoint failed content:%s", content); 639cc290419Sopenharmony_ci goto Finish; 640cc290419Sopenharmony_ci } 641cc290419Sopenharmony_ci } else { 642cc290419Sopenharmony_ci SetupPointContinue(ctxPoint, 0); 643cc290419Sopenharmony_ci } 644cc290419Sopenharmony_ci ret = true; 645cc290419Sopenharmony_ci } else { 646cc290419Sopenharmony_ci if (!ctxPoint->checkPoint) { 647cc290419Sopenharmony_ci if (!SetupPoint(ctxPoint)) { 648cc290419Sopenharmony_ci sError = ctxPoint->lastError; 649cc290419Sopenharmony_ci WRITE_LOG(LOG_FATAL, "SlaveConnect SetupPoint failed content:%s", content); 650cc290419Sopenharmony_ci goto Finish; 651cc290419Sopenharmony_ci } 652cc290419Sopenharmony_ci } else { 653cc290419Sopenharmony_ci SetupPointContinue(ctxPoint, 0); 654cc290419Sopenharmony_ci } 655cc290419Sopenharmony_ci ret = true; 656cc290419Sopenharmony_ci } 657cc290419Sopenharmony_ciFinish: 658cc290419Sopenharmony_ci if (!ret) { 659cc290419Sopenharmony_ci FreeContext(ctxPoint, 0, true); 660cc290419Sopenharmony_ci } 661cc290419Sopenharmony_ci return ret; 662cc290419Sopenharmony_ci} 663cc290419Sopenharmony_ci 664cc290419Sopenharmony_cibool HdcForwardBase::DoForwardBegin(HCtxForward ctx) 665cc290419Sopenharmony_ci{ 666cc290419Sopenharmony_ci switch (ctx->type) { 667cc290419Sopenharmony_ci case FORWARD_TCP: 668cc290419Sopenharmony_ci case FORWARD_JDWP: // jdwp use tcp ->socketpair->jvm 669cc290419Sopenharmony_ci uv_tcp_nodelay((uv_tcp_t *)&ctx->tcp, 1); 670cc290419Sopenharmony_ci uv_read_start((uv_stream_t *)&ctx->tcp, AllocForwardBuf, ReadForwardBuf); 671cc290419Sopenharmony_ci break; 672cc290419Sopenharmony_ci case FORWARD_ARK: 673cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "DoForwardBegin ark socketpair id:%u fds[0]:%d", ctx->id, fds[0]); 674cc290419Sopenharmony_ci uv_tcp_init(loopTask, &ctx->tcp); 675cc290419Sopenharmony_ci uv_tcp_open(&ctx->tcp, fds[0]); 676cc290419Sopenharmony_ci uv_tcp_nodelay((uv_tcp_t *)&ctx->tcp, 1); 677cc290419Sopenharmony_ci uv_read_start((uv_stream_t *)&ctx->tcp, AllocForwardBuf, ReadForwardBuf); 678cc290419Sopenharmony_ci break; 679cc290419Sopenharmony_ci case FORWARD_ABSTRACT: 680cc290419Sopenharmony_ci case FORWARD_RESERVED: 681cc290419Sopenharmony_ci case FORWARD_FILESYSTEM: 682cc290419Sopenharmony_ci uv_read_start((uv_stream_t *)&ctx->pipe, AllocForwardBuf, ReadForwardBuf); 683cc290419Sopenharmony_ci break; 684cc290419Sopenharmony_ci case FORWARD_DEVICE: { 685cc290419Sopenharmony_ci ctx->fdClass->StartWorkOnThread(); 686cc290419Sopenharmony_ci break; 687cc290419Sopenharmony_ci } 688cc290419Sopenharmony_ci default: 689cc290419Sopenharmony_ci break; 690cc290419Sopenharmony_ci } 691cc290419Sopenharmony_ci ctx->ready = true; 692cc290419Sopenharmony_ci return true; 693cc290419Sopenharmony_ci} 694cc290419Sopenharmony_ci 695cc290419Sopenharmony_civoid *HdcForwardBase::AdminContext(const uint8_t op, const uint32_t id, HCtxForward hInput) 696cc290419Sopenharmony_ci{ 697cc290419Sopenharmony_ci ctxPointMutex.lock(); 698cc290419Sopenharmony_ci void *hRet = nullptr; 699cc290419Sopenharmony_ci map<uint32_t, HCtxForward> &mapCtx = mapCtxPoint; 700cc290419Sopenharmony_ci switch (op) { 701cc290419Sopenharmony_ci case OP_ADD: 702cc290419Sopenharmony_ci mapCtx[id] = hInput; 703cc290419Sopenharmony_ci break; 704cc290419Sopenharmony_ci case OP_REMOVE: 705cc290419Sopenharmony_ci mapCtx.erase(id); 706cc290419Sopenharmony_ci break; 707cc290419Sopenharmony_ci case OP_QUERY: 708cc290419Sopenharmony_ci if (mapCtx.count(id)) { 709cc290419Sopenharmony_ci hRet = mapCtx[id]; 710cc290419Sopenharmony_ci } 711cc290419Sopenharmony_ci break; 712cc290419Sopenharmony_ci case OP_UPDATE: 713cc290419Sopenharmony_ci mapCtx.erase(id); 714cc290419Sopenharmony_ci mapCtx[hInput->id] = hInput; 715cc290419Sopenharmony_ci break; 716cc290419Sopenharmony_ci default: 717cc290419Sopenharmony_ci break; 718cc290419Sopenharmony_ci } 719cc290419Sopenharmony_ci ctxPointMutex.unlock(); 720cc290419Sopenharmony_ci return hRet; 721cc290419Sopenharmony_ci} 722cc290419Sopenharmony_ci 723cc290419Sopenharmony_civoid HdcForwardBase::SendCallbackForwardBuf(uv_write_t *req, int status) 724cc290419Sopenharmony_ci{ 725cc290419Sopenharmony_ci ContextForwardIO *ctxIO = (ContextForwardIO *)req->data; 726cc290419Sopenharmony_ci HCtxForward ctx = reinterpret_cast<HCtxForward>(ctxIO->ctxForward); 727cc290419Sopenharmony_ci if (status < 0 && !ctx->finish) { 728cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "SendCallbackForwardBuf ctx->type:%d, status:%d finish", ctx->type, status); 729cc290419Sopenharmony_ci ctx->thisClass->FreeContext(ctx, 0, true); 730cc290419Sopenharmony_ci } 731cc290419Sopenharmony_ci delete[] ctxIO->bufIO; 732cc290419Sopenharmony_ci delete ctxIO; 733cc290419Sopenharmony_ci delete req; 734cc290419Sopenharmony_ci} 735cc290419Sopenharmony_ci 736cc290419Sopenharmony_ciint HdcForwardBase::SendForwardBuf(HCtxForward ctx, uint8_t *bufPtr, const int size) 737cc290419Sopenharmony_ci{ 738cc290419Sopenharmony_ci int nRet = 0; 739cc290419Sopenharmony_ci if (size > static_cast<int>(HDC_BUF_MAX_BYTES - 1)) { 740cc290419Sopenharmony_ci WRITE_LOG(LOG_WARN, "SendForwardBuf size:%d > HDC_BUF_MAX_BYTES, ctxId:%u", size, ctx->id); 741cc290419Sopenharmony_ci return -1; 742cc290419Sopenharmony_ci } 743cc290419Sopenharmony_ci if (size <= 0) { 744cc290419Sopenharmony_ci WRITE_LOG(LOG_WARN, "SendForwardBuf failed size:%d, ctxId:%u", size, ctx->id); 745cc290419Sopenharmony_ci return -1; 746cc290419Sopenharmony_ci } 747cc290419Sopenharmony_ci auto pDynBuf = new(std::nothrow) uint8_t[size]; 748cc290419Sopenharmony_ci if (!pDynBuf) { 749cc290419Sopenharmony_ci WRITE_LOG(LOG_WARN, "SendForwardBuf new DynBuf failed size:%d, ctxId:%u", size, ctx->id); 750cc290419Sopenharmony_ci return -1; 751cc290419Sopenharmony_ci } 752cc290419Sopenharmony_ci (void)memcpy_s(pDynBuf, size, bufPtr, size); 753cc290419Sopenharmony_ci if (ctx->type == FORWARD_DEVICE) { 754cc290419Sopenharmony_ci nRet = ctx->fdClass->WriteWithMem(pDynBuf, size); 755cc290419Sopenharmony_ci } else { 756cc290419Sopenharmony_ci auto ctxIO = new ContextForwardIO(); 757cc290419Sopenharmony_ci if (!ctxIO) { 758cc290419Sopenharmony_ci WRITE_LOG(LOG_WARN, "SendForwardBuf new ContextForwardIO failed, ctxId:%u", ctx->id); 759cc290419Sopenharmony_ci delete[] pDynBuf; 760cc290419Sopenharmony_ci return -1; 761cc290419Sopenharmony_ci } 762cc290419Sopenharmony_ci ctxIO->ctxForward = ctx; 763cc290419Sopenharmony_ci ctxIO->bufIO = pDynBuf; 764cc290419Sopenharmony_ci if (ctx->type == FORWARD_TCP || ctx->type == FORWARD_JDWP || ctx->type == FORWARD_ARK) { 765cc290419Sopenharmony_ci nRet = Base::SendToStreamEx((uv_stream_t *)&ctx->tcp, pDynBuf, size, nullptr, 766cc290419Sopenharmony_ci (void *)SendCallbackForwardBuf, (void *)ctxIO); 767cc290419Sopenharmony_ci } else { 768cc290419Sopenharmony_ci // FORWARD_ABSTRACT, FORWARD_RESERVED, FORWARD_FILESYSTEM, 769cc290419Sopenharmony_ci nRet = Base::SendToStreamEx((uv_stream_t *)&ctx->pipe, pDynBuf, size, nullptr, 770cc290419Sopenharmony_ci (void *)SendCallbackForwardBuf, (void *)ctxIO); 771cc290419Sopenharmony_ci } 772cc290419Sopenharmony_ci if (nRet < 0) { 773cc290419Sopenharmony_ci WRITE_LOG(LOG_WARN, "SendForwardBuf SendToStreamEx ret:%d, size:%d ctxId:%u type:%d", 774cc290419Sopenharmony_ci nRet, size, ctx->id, ctx->type); 775cc290419Sopenharmony_ci } 776cc290419Sopenharmony_ci } 777cc290419Sopenharmony_ci return nRet; 778cc290419Sopenharmony_ci} 779cc290419Sopenharmony_ci 780cc290419Sopenharmony_cibool HdcForwardBase::CommandForwardCheckResult(HCtxForward ctx, uint8_t *payload) 781cc290419Sopenharmony_ci{ 782cc290419Sopenharmony_ci bool ret = true; 783cc290419Sopenharmony_ci bool bCheck = static_cast<bool>(payload); 784cc290419Sopenharmony_ci LogMsg(bCheck ? MSG_OK : MSG_FAIL, "Forwardport result:%s", bCheck ? "OK" : "Failed"); 785cc290419Sopenharmony_ci if (bCheck) { 786cc290419Sopenharmony_ci string mapInfo = taskInfo->serverOrDaemon ? "1|" : "0|"; 787cc290419Sopenharmony_ci mapInfo += taskCommand; 788cc290419Sopenharmony_ci ctx->ready = true; 789cc290419Sopenharmony_ci ServerCommand(CMD_FORWARD_SUCCESS, reinterpret_cast<uint8_t *>(const_cast<char *>(mapInfo.c_str())), 790cc290419Sopenharmony_ci mapInfo.size() + 1); 791cc290419Sopenharmony_ci } else { 792cc290419Sopenharmony_ci ret = false; 793cc290419Sopenharmony_ci FreeContext(ctx, 0, false); 794cc290419Sopenharmony_ci } 795cc290419Sopenharmony_ci return ret; 796cc290419Sopenharmony_ci} 797cc290419Sopenharmony_ci 798cc290419Sopenharmony_cibool HdcForwardBase::ForwardCommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize) 799cc290419Sopenharmony_ci{ 800cc290419Sopenharmony_ci if (payloadSize <= DWORD_SERIALIZE_SIZE && command != CMD_FORWARD_FREE_CONTEXT 801cc290419Sopenharmony_ci && command != CMD_FORWARD_ACTIVE_MASTER) { 802cc290419Sopenharmony_ci WRITE_LOG(LOG_FATAL, "Illegal payloadSize, shorter than forward command header"); 803cc290419Sopenharmony_ci return false; 804cc290419Sopenharmony_ci } 805cc290419Sopenharmony_ci bool ret = true; 806cc290419Sopenharmony_ci uint8_t *pContent = nullptr; 807cc290419Sopenharmony_ci int sizeContent = 0; 808cc290419Sopenharmony_ci uint32_t id = 0; 809cc290419Sopenharmony_ci HCtxForward ctx = nullptr; 810cc290419Sopenharmony_ci FilterCommand(payload, &id, &pContent); 811cc290419Sopenharmony_ci sizeContent = payloadSize - DWORD_SERIALIZE_SIZE; 812cc290419Sopenharmony_ci if (!(ctx = (HCtxForward)AdminContext(OP_QUERY, id, nullptr))) { 813cc290419Sopenharmony_ci WRITE_LOG(LOG_WARN, "Query id:%u failed", id); 814cc290419Sopenharmony_ci return true; 815cc290419Sopenharmony_ci } 816cc290419Sopenharmony_ci switch (command) { 817cc290419Sopenharmony_ci case CMD_FORWARD_CHECK_RESULT: { 818cc290419Sopenharmony_ci ret = CommandForwardCheckResult(ctx, pContent); 819cc290419Sopenharmony_ci break; 820cc290419Sopenharmony_ci } 821cc290419Sopenharmony_ci case CMD_FORWARD_ACTIVE_MASTER: { 822cc290419Sopenharmony_ci ret = DoForwardBegin(ctx); 823cc290419Sopenharmony_ci break; 824cc290419Sopenharmony_ci } 825cc290419Sopenharmony_ci case CMD_FORWARD_DATA: { 826cc290419Sopenharmony_ci if (ctx->finish) { 827cc290419Sopenharmony_ci break; 828cc290419Sopenharmony_ci } 829cc290419Sopenharmony_ci if (SendForwardBuf(ctx, pContent, sizeContent) < 0) { 830cc290419Sopenharmony_ci WRITE_LOG(LOG_WARN, "ForwardCommandDispatch SendForwardBuf rc < 0, ctxid:%u", ctx->id); 831cc290419Sopenharmony_ci FreeContext(ctx, 0, true); 832cc290419Sopenharmony_ci } 833cc290419Sopenharmony_ci break; 834cc290419Sopenharmony_ci } 835cc290419Sopenharmony_ci case CMD_FORWARD_FREE_CONTEXT: { 836cc290419Sopenharmony_ci FreeContext(ctx, 0, false); 837cc290419Sopenharmony_ci break; 838cc290419Sopenharmony_ci } 839cc290419Sopenharmony_ci default: 840cc290419Sopenharmony_ci ret = false; 841cc290419Sopenharmony_ci break; 842cc290419Sopenharmony_ci } 843cc290419Sopenharmony_ci if (!ret) { 844cc290419Sopenharmony_ci if (ctx) { 845cc290419Sopenharmony_ci FreeContext(ctx, 0, true); 846cc290419Sopenharmony_ci } else { 847cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "ctx==nullptr raw free"); 848cc290419Sopenharmony_ci TaskFinish(); 849cc290419Sopenharmony_ci } 850cc290419Sopenharmony_ci } 851cc290419Sopenharmony_ci return ret; 852cc290419Sopenharmony_ci} 853cc290419Sopenharmony_ci 854cc290419Sopenharmony_cibool HdcForwardBase::CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize) 855cc290419Sopenharmony_ci{ 856cc290419Sopenharmony_ci if (command != CMD_FORWARD_DATA) { 857cc290419Sopenharmony_ci WRITE_LOG(LOG_WARN, "CommandDispatch command:%d payloadSize:%d", command, payloadSize); 858cc290419Sopenharmony_ci } 859cc290419Sopenharmony_ci bool ret = true; 860cc290419Sopenharmony_ci string sError; 861cc290419Sopenharmony_ci // prepare 862cc290419Sopenharmony_ci if (command == CMD_FORWARD_INIT) { 863cc290419Sopenharmony_ci string strCommand(reinterpret_cast<char *>(payload), payloadSize); 864cc290419Sopenharmony_ci if (!BeginForward(strCommand, sError)) { 865cc290419Sopenharmony_ci ret = false; 866cc290419Sopenharmony_ci goto Finish; 867cc290419Sopenharmony_ci } 868cc290419Sopenharmony_ci return true; 869cc290419Sopenharmony_ci } else if (command == CMD_FORWARD_CHECK) { 870cc290419Sopenharmony_ci // Detect remote if it's reachable 871cc290419Sopenharmony_ci if (!SlaveConnect(payload, payloadSize, true, sError)) { 872cc290419Sopenharmony_ci ret = false; 873cc290419Sopenharmony_ci goto Finish; 874cc290419Sopenharmony_ci } 875cc290419Sopenharmony_ci return true; 876cc290419Sopenharmony_ci } else if (command == CMD_FORWARD_ACTIVE_SLAVE) { 877cc290419Sopenharmony_ci // slave connect target port when activating 878cc290419Sopenharmony_ci if (!SlaveConnect(payload, payloadSize, false, sError)) { 879cc290419Sopenharmony_ci ret = false; 880cc290419Sopenharmony_ci goto Finish; 881cc290419Sopenharmony_ci } 882cc290419Sopenharmony_ci return true; 883cc290419Sopenharmony_ci } 884cc290419Sopenharmony_ci if (!ForwardCommandDispatch(command, payload, payloadSize)) { 885cc290419Sopenharmony_ci ret = false; 886cc290419Sopenharmony_ci goto Finish; 887cc290419Sopenharmony_ci } 888cc290419Sopenharmony_ciFinish: 889cc290419Sopenharmony_ci if (!ret) { 890cc290419Sopenharmony_ci if (!sError.size()) { 891cc290419Sopenharmony_ci LogMsg(MSG_FAIL, "Forward parament failed"); 892cc290419Sopenharmony_ci } else { 893cc290419Sopenharmony_ci LogMsg(MSG_FAIL, const_cast<char *>(sError.c_str())); 894cc290419Sopenharmony_ci WRITE_LOG(LOG_WARN, const_cast<char *>(sError.c_str())); 895cc290419Sopenharmony_ci } 896cc290419Sopenharmony_ci } 897cc290419Sopenharmony_ci return ret; 898cc290419Sopenharmony_ci} 899cc290419Sopenharmony_ci} // namespace Hdc 900