• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "stream_server.h"
17 
18 #include <cinttypes>
19 
20 #include <sys/socket.h>
21 
22 #include "sensor_errors.h"
23 
24 #undef LOG_TAG
25 #define LOG_TAG "StreamServer"
26 
27 namespace OHOS {
28 namespace Sensors {
29 namespace {
30 constexpr int32_t INVALID_PID = -1;
31 constexpr int32_t INVALID_FD = -1;
32 } // namespace
33 
~StreamServer()34 StreamServer::~StreamServer()
35 {
36     CALL_LOG_ENTER;
37     std::lock_guard<std::mutex> sessionLock(sessionMutex_);
38     idxPidMap_.clear();
39     for (const auto &item : sessionsMap_) {
40         if (item.second == nullptr) {
41             SEN_HILOGE("SessionPtr is null");
42             continue;
43         }
44         item.second->Close();
45     }
46     sessionsMap_.clear();
47 }
48 
GetClientFd(int32_t pid)49 int32_t StreamServer::GetClientFd(int32_t pid)
50 {
51     std::lock_guard<std::mutex> sessionLock(sessionMutex_);
52     auto it = idxPidMap_.find(pid);
53     return it == idxPidMap_.end() ? INVALID_FD : it->second;
54 }
55 
GetClientPid(int32_t fd)56 int32_t StreamServer::GetClientPid(int32_t fd)
57 {
58     std::lock_guard<std::mutex> sessionLock(sessionMutex_);
59     auto it = sessionsMap_.find(fd);
60     return it == sessionsMap_.end() ? INVALID_PID : it->second->GetPid();
61 }
62 
GetSession(int32_t fd)63 SessionPtr StreamServer::GetSession(int32_t fd)
64 {
65     std::lock_guard<std::mutex> sessionLock(sessionMutex_);
66     auto it = sessionsMap_.find(fd);
67     if (it == sessionsMap_.end()) {
68         SEN_HILOGE("Session not found");
69         return nullptr;
70     }
71     CHKPP(it->second);
72     return it->second->GetSharedPtr();
73 }
74 
GetSessionByPid(int32_t pid)75 SessionPtr StreamServer::GetSessionByPid(int32_t pid)
76 {
77     int32_t fd = GetClientFd(pid);
78     if (fd <= 0) {
79         SEN_HILOGE("Session not found");
80         return nullptr;
81     }
82     return GetSession(fd);
83 }
84 
AddSocketPairInfo(int32_t uid,int32_t pid,int32_t tokenType,int32_t & serverFd,int32_t & clientFd)85 int32_t StreamServer::AddSocketPairInfo(int32_t uid, int32_t pid, int32_t tokenType,
86     int32_t &serverFd, int32_t &clientFd)
87 {
88     CALL_LOG_ENTER;
89     int32_t sockFds[2] = { -1 };
90     if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockFds) != 0) {
91         SEN_HILOGE("Socketpair failed, errno:%{public}d", errno);
92         return ERROR;
93     }
94     fdsan_exchange_owner_tag(sockFds[0], 0, TAG);
95     fdsan_exchange_owner_tag(sockFds[1], 0, TAG);
96     serverFd = sockFds[0];
97     clientFd = sockFds[1];
98     if (serverFd < 0 || clientFd < 0) {
99         SEN_HILOGE("ServerFd or clientFd is invalid");
100         return ERROR;
101     }
102     static constexpr size_t bufferSize = 32 * 1024;
103     SessionPtr sess = nullptr;
104     if (setsockopt(serverFd, SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize)) != 0) {
105         SEN_HILOGE("Setsockopt serverFd send buffer size failed, errno:%{public}d", errno);
106         goto CLOSE_SOCK;
107     }
108     if (setsockopt(serverFd, SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize)) != 0) {
109         SEN_HILOGE("Setsockopt serverFd recv buffer size failed, errno:%{public}d", errno);
110         goto CLOSE_SOCK;
111     }
112     if (setsockopt(clientFd, SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize)) != 0) {
113         SEN_HILOGE("Setsockopt clientFd send buffer size failed, errno:%{public}d", errno);
114         goto CLOSE_SOCK;
115     }
116     if (setsockopt(clientFd, SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize)) != 0) {
117         SEN_HILOGE("Setsockopt clientFd recv buffer size failed, errno:%{public}d", errno);
118         goto CLOSE_SOCK;
119     }
120     sess = std::make_shared<StreamSession>("", serverFd, uid, pid);
121     sess->SetTokenType(tokenType);
122     if (!AddSession(sess)) {
123         SEN_HILOGE("AddSession fail");
124         goto CLOSE_SOCK;
125     }
126     return ERR_OK;
127 
128 CLOSE_SOCK:
129     fdsan_close_with_tag(sockFds[0], TAG);
130     fdsan_close_with_tag(sockFds[1], TAG);
131     serverFd = -1;
132     clientFd = -1;
133     return ERROR;
134 }
135 
AddSession(SessionPtr sess)136 bool StreamServer::AddSession(SessionPtr sess)
137 {
138     CALL_LOG_ENTER;
139     CHKPF(sess);
140     auto fd = sess->GetFd();
141     if (fd < 0) {
142         SEN_HILOGE("Fd is Invalid");
143         return false;
144     }
145     auto pid = sess->GetPid();
146     if (pid <= 0) {
147         SEN_HILOGE("Pid is invalid");
148         return false;
149     }
150     std::lock_guard<std::mutex> sessionLock(sessionMutex_);
151     if (sessionsMap_.size() > MAX_SESSON_ALARM) {
152         SEN_HILOGE("Too many clients, size:%{public}zu", sessionsMap_.size());
153         return false;
154     }
155     idxPidMap_[pid] = fd;
156     sessionsMap_[fd] = sess;
157     return true;
158 }
159 
DelSession(int32_t pid)160 void StreamServer::DelSession(int32_t pid)
161 {
162     CALL_LOG_ENTER;
163     std::lock_guard<std::mutex> sessionLock(sessionMutex_);
164     auto pidIt = idxPidMap_.find(pid);
165     if (pidIt == idxPidMap_.end()) {
166         SEN_HILOGW("Pid session not exist");
167         return;
168     }
169     int32_t fd = pidIt->second;
170     idxPidMap_.erase(pidIt);
171     auto fdIt = sessionsMap_.find(fd);
172     if (fdIt != sessionsMap_.end()) {
173         sessionsMap_.erase(fdIt);
174     }
175     if (fd >= 0) {
176         int32_t ret = fdsan_close_with_tag(fd, TAG);
177         if (ret != 0) {
178             SEN_HILOGE("Socket fd close failed, ret:%{public}d, errno:%{public}d", ret, errno);
179         }
180     }
181 }
182 } // namespace Sensors
183 } // namespace OHOS