• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 "fault_logger_server.h"
17 
18 #include <sys/socket.h>
19 #include <sys/un.h>
20 #include <unistd.h>
21 
22 #include "dfx_define.h"
23 #include "dfx_log.h"
24 #include "faultloggerd_socket.h"
25 #include "fault_coredump_service.h"
26 
27 namespace OHOS {
28 namespace HiviewDFX {
29 
30 namespace {
31 constexpr const char* const FAULTLOGGERD_SERVER_TAG = "FAULT_LOGGER_SERVER";
32 }
33 
SocketServer(EpollManager & epollManager)34 SocketServer::SocketServer(EpollManager& epollManager) : epollManager_(epollManager) {}
35 
Init()36 bool SocketServer::Init()
37 {
38     std::unique_ptr<IFaultLoggerService> logFileDesService(new (std::nothrow) FileDesService());
39     AddService(LOG_FILE_DES_CLIENT, std::move(logFileDesService));
40 #ifndef HISYSEVENT_DISABLE
41     std::unique_ptr<IFaultLoggerService> reportExceptionService(new (std::nothrow) ExceptionReportService());
42     AddService(REPORT_EXCEPTION_CLIENT, std::move(reportExceptionService));
43     std::unique_ptr<IFaultLoggerService> statsClientService(new (std::nothrow) StatsService());
44     AddService(DUMP_STATS_CLIENT, std::move(statsClientService));
45 #endif
46     if (!AddServerListener(SERVER_SOCKET_NAME) || !AddServerListener(SERVER_CRASH_SOCKET_NAME)) {
47         return false;
48     }
49 #ifndef is_ohos_lite
50     AddService(COREDUMP_CLIENT, std::make_unique<CoredumpService>());
51     AddService(COREDUMP_PROCESS_DUMP_CLIENT, std::make_unique<CoredumpStatusService>());
52 
53     AddService(PIPE_FD_CLIENT, std::make_unique<PipeService>());
54     AddService(SDK_DUMP_CLIENT, std::make_unique<SdkDumpService>());
55     AddService(PIPE_FD_LITEPERF_CLIENT, std::make_unique<LitePerfPipeService>());
56     if (!AddServerListener(SERVER_SDKDUMP_SOCKET_NAME)) {
57         return false;
58     }
59 #endif
60     return true;
61 }
62 
AddService(int32_t clientType,std::unique_ptr<IFaultLoggerService> service)63 void SocketServer::AddService(int32_t clientType, std::unique_ptr<IFaultLoggerService> service)
64 {
65     if (service) {
66         faultLoggerServices_.emplace_back(clientType, std::move(service));
67     }
68 }
69 
AddServerListener(const char * socketName)70 bool SocketServer::AddServerListener(const char* socketName)
71 {
72     constexpr int32_t maxConnection = 30;
73     SmartFd fd = StartListen(socketName, maxConnection);
74     if (!fd) {
75         return false;
76     }
77     std::unique_ptr<EpollListener> serverListener(new SocketServerListener(*this, std::move(fd), socketName));
78     return epollManager_.AddListener(std::move(serverListener));
79 }
80 
SocketServerListener(SocketServer & socketServer,SmartFd fd,std::string socketName)81 SocketServer::SocketServerListener::SocketServerListener(SocketServer& socketServer, SmartFd fd, std::string socketName)
82     : EpollListener(std::move(fd), true), socketServer_(socketServer), socketName_(std::move(socketName)) {}
83 
ClientRequestListener(SocketServerListener & socketServerListener,SmartFd fd,uid_t clientUid)84 SocketServer::ClientRequestListener::ClientRequestListener(
85     SocketServerListener& socketServerListener, SmartFd fd, uid_t clientUid)
86     : EpollListener(std::move(fd)), socketServerListener_(socketServerListener), clientUid_(clientUid) {}
87 
~ClientRequestListener()88 SocketServer::ClientRequestListener::~ClientRequestListener()
89 {
90     uint32_t& connectionNum = socketServerListener_.socketServer_.connectionNums_[clientUid_];
91     if (--connectionNum == 0) {
92         socketServerListener_.socketServer_.connectionNums_.erase(clientUid_);
93     }
94 }
95 
GetTargetService(int32_t faultLoggerClientType) const96 IFaultLoggerService* SocketServer::ClientRequestListener::GetTargetService(int32_t faultLoggerClientType) const
97 {
98     for (const auto& faultLoggerServicePair : socketServerListener_.socketServer_.faultLoggerServices_) {
99         if (faultLoggerServicePair.first == faultLoggerClientType) {
100             return faultLoggerServicePair.second.get();
101         }
102     }
103     return nullptr;
104 }
105 
OnEventPoll()106 void SocketServer::ClientRequestListener::OnEventPoll()
107 {
108     constexpr int32_t maxBuffSize = 2048;
109     std::vector<uint8_t> buf(maxBuffSize, 0);
110     ssize_t nread = OHOS_TEMP_FAILURE_RETRY(read(GetFd(), buf.data(), maxBuffSize));
111     if (nread >= static_cast<ssize_t>(sizeof(RequestDataHead))) {
112         auto dataHead = reinterpret_cast<RequestDataHead*>(buf.data());
113         DFXLOGI("%{public}s :: %{public}s receive request from pid: %{public}d, clientType: %{public}d",
114                 FAULTLOGGERD_SERVER_TAG, socketServerListener_.socketName_.c_str(),
115                 dataHead->clientPid, dataHead->clientType);
116         IFaultLoggerService* service = GetTargetService(dataHead->clientType);
117         int32_t retCode = service ? service->OnReceiveMsg(socketServerListener_.socketName_, GetFd(), nread, buf)
118             : ResponseCode::UNKNOWN_CLIENT_TYPE;
119         if (retCode != ResponseCode::REQUEST_SUCCESS) {
120             SendMsgToSocket(GetFd(), &retCode, sizeof(retCode));
121         }
122         DFXLOGI("%{public}s :: %{public}s has processed request for pid: %{public}d, clientType: %{public}d, "
123             "and retCode %{public}d", FAULTLOGGERD_SERVER_TAG, socketServerListener_.socketName_.c_str(),
124             dataHead->clientPid, dataHead->clientType, retCode);
125     }
126 }
127 
OnEventPoll()128 void SocketServer::SocketServerListener::OnEventPoll()
129 {
130     struct sockaddr_un clientAddr{};
131     auto clientAddrSize = static_cast<socklen_t>(sizeof(clientAddr));
132     SmartFd connectionFd{static_cast<int>(OHOS_TEMP_FAILURE_RETRY(accept(GetFd(),
133         reinterpret_cast<struct sockaddr*>(&clientAddr), &clientAddrSize)))};
134     if (!connectionFd) {
135         DFXLOGW("%{public}s :: Failed to accept connection from %{public}s",
136             FAULTLOGGERD_SERVER_TAG, socketName_.c_str());
137         return;
138     }
139     struct ucred credentials{};
140     socklen_t len = sizeof(credentials);
141     if (getsockopt(connectionFd.GetFd(), SOL_SOCKET, SO_PEERCRED, &credentials, &len) == -1) {
142         DFXLOGE("%{public}s :: Failed to GetCredential, errno: %{public}d", FAULTLOGGERD_SERVER_TAG, errno);
143         return;
144     }
145     auto& connectionNum = socketServer_.connectionNums_[credentials.uid];
146 #ifdef FAULTLOGGERD_TEST
147     constexpr auto connectionLimit = 1;
148 #else
149     constexpr auto connectionLimit = 5;
150 #endif
151     if (connectionNum >= connectionLimit) {
152         DFXLOGE("%{public}s :: reject new connection for uid %{public}d.", FAULTLOGGERD_SERVER_TAG, credentials.uid);
153         return;
154     }
155     connectionNum++;
156     std::unique_ptr<EpollListener> clientRequestListener(
157         new (std::nothrow) ClientRequestListener(*this, std::move(connectionFd), credentials.uid));
158     socketServer_.epollManager_.AddListener(std::move(clientRequestListener));
159 }
160 }
161 }