1 /* 2 * Copyright (c) 2021-2023 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 16 #include "hook_socket_client.h" 17 18 #include "common.h" 19 #include "hook_common.h" 20 #include "unix_socket_client.h" 21 #include "logging.h" 22 23 namespace { 24 const int MOVE_BIT_8 = 8; 25 const int MOVE_BIT_32 = 32; 26 const int MOVE_BIT_48 = 48; 27 const int MOVE_BIT_56 = 56; 28 constexpr int FLUSH_FLAG = 20; 29 std::atomic<uint64_t> g_flushCount = 0; 30 } // namespace 31 HookSocketClient(int pid,ClientConfig * config)32 HookSocketClient::HookSocketClient(int pid, ClientConfig *config) : pid_(pid), config_(config) 33 { 34 smbFd_ = 0; 35 eventFd_ = 0; 36 unixSocketClient_ = nullptr; 37 serviceName_ = "HookService"; 38 Connect(DEFAULT_UNIX_SOCKET_HOOK_FULL_PATH); 39 } 40 ~HookSocketClient()41 HookSocketClient::~HookSocketClient() 42 { 43 if (stackWriter_) { 44 stackWriter_->Flush(); 45 HILOG_INFO(LOG_CORE, "~HookSocketClient Flush()"); 46 } 47 unixSocketClient_ = nullptr; 48 stackWriter_ = nullptr; 49 } 50 Connect(const std::string addrname)51 bool HookSocketClient::Connect(const std::string addrname) 52 { 53 if (unixSocketClient_ != nullptr) { 54 return false; 55 } 56 unixSocketClient_ = std::make_shared<UnixSocketClient>(); 57 if (!unixSocketClient_->Connect(addrname, *this)) { 58 unixSocketClient_ = nullptr; 59 return false; 60 } 61 62 unixSocketClient_->SendHookConfig(reinterpret_cast<uint8_t *>(&pid_), sizeof(pid_)); 63 return true; 64 } 65 ProtocolProc(SocketContext & context,uint32_t pnum,const int8_t * buf,const uint32_t size)66 bool HookSocketClient::ProtocolProc(SocketContext &context, uint32_t pnum, const int8_t *buf, const uint32_t size) 67 { 68 CHECK_TRUE(size == sizeof(ClientConfig), true, "HookSocketClient::config config size not match = %u\n", size); 69 *config_ = *reinterpret_cast<ClientConfig *>(const_cast<int8_t*>(buf)); 70 config_->maxStackDepth = config_->maxStackDepth > MAX_UNWIND_DEPTH ? MAX_UNWIND_DEPTH : config_->maxStackDepth; 71 std::string configStr = config_->ToString(); 72 HILOG_INFO(LOG_CORE, "recv hook client config:%s\n", configStr.c_str()); 73 74 smbFd_ = context.ReceiveFileDiscriptor(); 75 eventFd_ = context.ReceiveFileDiscriptor(); 76 stackWriter_ = std::make_shared<StackWriter>("hooknativesmb", config_->shareMemroySize, 77 smbFd_, eventFd_, config_->isBlocked); 78 79 COMMON::PrintMallinfoLog("stackWriter init(byte) => "); 80 return true; 81 } 82 SendStack(const void * data,size_t size)83 bool HookSocketClient::SendStack(const void* data, size_t size) 84 { 85 if (stackWriter_ == nullptr || unixSocketClient_ == nullptr) { 86 return false; 87 } 88 89 if (!unixSocketClient_->SendHeartBeat()) { 90 return false; 91 } 92 93 stackWriter_->WriteTimeout(data, size); 94 stackWriter_->Flush(); 95 96 return true; 97 } 98 SendStackWithPayload(const void * data,size_t size,const void * payload,size_t payloadSize)99 bool HookSocketClient::SendStackWithPayload(const void* data, size_t size, const void* payload, 100 size_t payloadSize) 101 { 102 if (stackWriter_ == nullptr || unixSocketClient_ == nullptr) { 103 return false; 104 } 105 106 stackWriter_->WriteWithPayloadTimeout(data, size, payload, payloadSize); 107 g_flushCount++; 108 if (g_flushCount % FLUSH_FLAG == 0) { 109 stackWriter_->Flush(); 110 } 111 return true; 112 } 113 Flush()114 void HookSocketClient::Flush() 115 { 116 if (stackWriter_ == nullptr || unixSocketClient_ == nullptr) { 117 return; 118 } 119 stackWriter_->Flush(); 120 } 121