• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
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 "network_profiler_socker_client.h"
17 
18 #include "network_profiler_common.h"
19 #include "network_profiler.h"
20 
21 namespace {
22 std::atomic<bool> g_disableHook = false;
23 
24 } // namespace
25 
26 namespace OHOS::Developtools::Profiler {
NetworkProfilerSocketClient(int pid,NetworkProfiler * profiler,void (* disableHookCallback)())27 NetworkProfilerSocketClient::NetworkProfilerSocketClient(int pid, NetworkProfiler* profiler,
28     void (*disableHookCallback)()) : pid_(pid), disableHookCallback_(disableHookCallback), profiler_(profiler)
29 {
30     smbFd_ = 0;
31     eventFd_ = 0;
32     unixSocketClient_ = nullptr;
33     serviceName_ = "NetworkProfilerService";
34     Connect(NETWORK_PROFILER_UNIX_SOCKET_FULL_PATH, disableHookCallback_);
35 }
36 
~NetworkProfilerSocketClient()37 NetworkProfilerSocketClient::~NetworkProfilerSocketClient()
38 {
39     if (writer_) {
40         writer_->Flush();
41     }
42     unixSocketClient_ = nullptr;
43     writer_ = nullptr;
44 }
45 
Connect(const std::string addrname,void (* disableHookCallback)())46 bool NetworkProfilerSocketClient::Connect(const std::string addrname, void (*disableHookCallback)())
47 {
48     if (unixSocketClient_ != nullptr) {
49         return false;
50     }
51     unixSocketClient_ = std::make_shared<UnixSocketClient>();
52     if (!unixSocketClient_->Connect(addrname, *this, disableHookCallback)) {
53         unixSocketClient_ = nullptr;
54         return false;
55     }
56 
57     unixSocketClient_->SendHookConfig(reinterpret_cast<uint8_t *>(&pid_), sizeof(pid_));
58     return true;
59 }
60 
ProtocolProc(SocketContext & context,uint32_t pnum,const int8_t * buf,const uint32_t size)61 bool NetworkProfilerSocketClient::ProtocolProc(SocketContext &context, uint32_t pnum, const int8_t *buf,
62                                                const uint32_t size)
63 {
64     CHECK_TRUE(size == sizeof(NetworkConfig), true, "NetworkProfilerSocketClient config size not match = %u\n", size);
65     NetworkConfig* config = reinterpret_cast<NetworkConfig *>(const_cast<int8_t*>(buf));
66     smbFd_ = context.ReceiveFileDiscriptor();
67     eventFd_ = context.ReceiveFileDiscriptor();
68     PROFILER_LOG_INFO(LOG_CORE, "network profiler client: ProtocolProc: smbFd: %d, eventFd: %d, shmSize: %d",
69         smbFd_, eventFd_, config->shmSize);
70     flushInterval_ = config->flushCount;
71     std::string smbName = "networkProfilerSmb_" + std::to_string(pid_);
72     profiler_->SetClockId(config->clock);
73     writer_ = std::make_shared<NetworkProfilerWriter>(smbName, config->shmSize, smbFd_, eventFd_, config->block);
74     profiler_->SetEnableFlag(true);
75     profiler_->SetWaitingFlag(false);
76     profiler_->SendCachedData();
77     return true;
78 }
79 
SendNetworkProfilerData(const void * data,size_t size,const void * payload,size_t payloadSize)80 bool NetworkProfilerSocketClient::SendNetworkProfilerData(const void* data, size_t size,
81                                                           const void* payload, size_t payloadSize)
82 {
83     if (writer_ == nullptr || unixSocketClient_ == nullptr || g_disableHook) {
84         return false;
85     } else if (unixSocketClient_->GetClientState() == CLIENT_STAT_THREAD_EXITED) {
86         DisableHook();
87         return false;
88     }
89 
90     bool ret = writer_->WriteWithPayloadTimeout(
91         data,
92         size,
93         payload,
94         payloadSize,
95         std::bind(&NetworkProfilerSocketClient::PeerIsConnected, this));
96     if (!ret) {
97         DisableHook();
98         return false;
99     }
100     writer_->Flush();
101     return true;
102 }
103 
Flush()104 void NetworkProfilerSocketClient::Flush()
105 {
106     if (writer_ == nullptr || unixSocketClient_ == nullptr) {
107         return;
108     }
109     writer_->Flush();
110 }
111 
DisableHook()112 void NetworkProfilerSocketClient::DisableHook()
113 {
114     bool expected = false;
115     if (g_disableHook.compare_exchange_strong(expected, true, std::memory_order_release, std::memory_order_relaxed)) {
116         HILOG_INFO(LOG_CORE, "%s %p", __func__, disableHookCallback_);
117         if (disableHookCallback_ != nullptr) {
118             disableHookCallback_();
119         }
120     }
121 }
122 
PeerIsConnected()123 bool NetworkProfilerSocketClient::PeerIsConnected()
124 {
125     if (unixSocketClient_ == nullptr) {
126         return false;
127     }
128     return !unixSocketClient_->IsConnected();
129 }
130 }