• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-2022 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 "net.h"
17 #include <fcntl.h>
18 #include <poll.h>
19 #include <unistd.h>
20 #include <securec.h>
21 #include <sys/socket.h>
22 #include <sys/un.h>
23 #include "common.h"
24 #include "errno.h"
25 #include "log.h"
26 
27 #undef LOG_TAG
28 #define LOG_TAG "WifiRpcNet"
29 
SetNonBlock(int fd,int type)30 int SetNonBlock(int fd, int type)
31 {
32     int flags = fcntl(fd, F_GETFL, 0);
33     if (flags < 0) {
34         LOGE("get socket flags failed!");
35         return -1;
36     }
37     if (type == 1) {
38         flags |= O_NONBLOCK;
39     } else {
40         flags &= ~O_NONBLOCK;
41     }
42     if (fcntl(fd, F_SETFL, flags) < 0) {
43         LOGE("set socket O_NONBLOCK failed!");
44         return -1;
45     }
46     return 0;
47 }
48 
MyRead(int fd,char * buf,int count)49 int MyRead(int fd, char *buf, int count)
50 {
51     int pos = 0;
52     while (count > 0) {
53         int ret = read(fd, buf + pos, count);
54         if (ret == 0) {
55             buf[pos] = 0;
56             return SOCK_CLOSE;
57         } else if (ret < 0) {
58             if (errno == EWOULDBLOCK || errno == EINTR || errno == EAGAIN) {
59                 break;
60             } else {
61                 LOGE("read failed! error is %{public}d", errno);
62                 return SOCK_ERR;
63             }
64         } else {
65             pos += ret;
66             count -= ret;
67         }
68     }
69     buf[pos] = 0;
70 #ifdef DEBUG
71     LOGD("read: %{private}s", buf);
72 #endif
73     return pos;
74 }
75 
MyWrite(int fd,const char * buf,int count)76 int MyWrite(int fd, const char *buf, int count)
77 {
78     int pos = 0;
79     while (count > 0) {
80         int ret = write(fd, buf + pos, count);
81         if (ret == 0) {
82             return SOCK_CLOSE;
83         } else if (ret < 0) {
84             if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) {
85                 break;
86             } else {
87                 LOGE("write failed! error is %{public}d", errno);
88                 return SOCK_ERR;
89             }
90         }
91 #ifdef DEBUG
92         int tmpSize = ret + 1;
93         char *szTmp = (char *)calloc(tmpSize, sizeof(char));
94         if (szTmp != NULL) {
95             if (strncpy_s(szTmp, tmpSize, buf + pos, ret) == EOK) {
96                 LOGD("write: %{private}s", szTmp);
97             }
98             free(szTmp);
99             szTmp = NULL;
100         }
101 #endif
102         pos += ret;
103         count -= ret;
104     }
105     return pos;
106 }
107 
CreateSocket(int domain)108 static int CreateSocket(int domain)
109 {
110     int sock = socket(domain, SOCK_STREAM, 0);
111     if (sock < 0) {
112         LOGE("create socket failed!");
113         return -1;
114     }
115     return sock;
116 }
117 
CreateUnixServer(const char * path,int backlog)118 int CreateUnixServer(const char *path, int backlog)
119 {
120     struct sockaddr_un sockAddr;
121     if (memset_s(&sockAddr, sizeof(sockAddr), 0, sizeof(sockAddr)) != EOK) {
122         return -1;
123     }
124     sockAddr.sun_family = AF_LOCAL;
125     if (strncpy_s(sockAddr.sun_path, sizeof(sockAddr.sun_path), path, strlen(path)) != EOK) {
126         return -1;
127     }
128     int sock = CreateSocket(AF_LOCAL);
129     if (sock < 0) {
130         return -1;
131     }
132     int keepAlive = 1;
133     if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepAlive, sizeof(keepAlive)) < 0) {
134         LOGE("setsockopt failed!");
135         close(sock);
136         return -1;
137     }
138     int reuseaddr = 1;
139     if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&reuseaddr, sizeof(reuseaddr)) < 0) {
140         LOGE("setsockopt failed!");
141         close(sock);
142         return -1;
143     }
144     int ret = bind(sock, (struct sockaddr *)&sockAddr, sizeof(sockAddr));
145     if (ret < 0) {
146         LOGE("bind failed, ret: %{public}d, errno: %{public}d!", ret, errno);
147         close(sock);
148         return -1;
149     }
150     if (SetNonBlock(sock, 1) != 0) {
151         LOGE("set socket non block failed, errno: %{public}d!", errno);
152         close(sock);
153         return -1;
154     }
155     fcntl(sock, F_SETFD, FD_CLOEXEC);
156     if (listen(sock, backlog) < 0) {
157         LOGE("listen failed, errno: %{public}d!", errno);
158         close(sock);
159         return -1;
160     }
161     return sock;
162 }
163 
ConnectUnixServer(const char * path)164 int ConnectUnixServer(const char *path)
165 {
166     struct sockaddr_un sockAddr;
167     if (memset_s(&sockAddr, sizeof(sockAddr), 0, sizeof(sockAddr)) != EOK) {
168         return -1;
169     }
170     sockAddr.sun_family = AF_LOCAL;
171     if (strncpy_s(sockAddr.sun_path, sizeof(sockAddr.sun_path), path, strlen(path)) != EOK) {
172         return -1;
173     }
174     int sock = CreateSocket(AF_LOCAL);
175     if (sock < 0) {
176         return -1;
177     }
178     if (connect(sock, (struct sockaddr *)&sockAddr, sizeof(sockAddr)) < 0) {
179         LOGE("connect failed!");
180         close(sock);
181         return -1;
182     }
183     return sock;
184 }
185 
WaitFdEvent(int fd,unsigned int mask,int milliseconds)186 int WaitFdEvent(int fd, unsigned int mask, int milliseconds)
187 {
188     struct pollfd pFd = {0};
189     pFd.fd = fd;
190     if (mask & READ_EVENT) {
191         pFd.events |= POLLIN;
192     }
193     if (mask & WRIT_EVENT) {
194         pFd.events |= POLLOUT;
195     }
196     int ret = poll(&pFd, 1, milliseconds);
197     if (ret < 0) {
198         LOGE("poll failed! errno=%{public}d", errno);
199         if (errno == EINTR) {
200             return 0;
201         }
202         return -1;
203     } else if (ret == 0) {
204         return 0;
205     } else {
206         return 1;
207     }
208 }
209