• 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         return -1;
136     }
137     int reuseaddr = 1;
138     if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&reuseaddr, sizeof(reuseaddr)) < 0) {
139         LOGE("setsockopt failed!");
140         return -1;
141     }
142     int ret = bind(sock, (struct sockaddr *)&sockAddr, sizeof(sockAddr));
143     if (ret < 0) {
144         LOGE("bind failed, ret: %{public}d, errno: %{public}d!", ret, errno);
145         close(sock);
146         return -1;
147     }
148     if (SetNonBlock(sock, 1) != 0) {
149         LOGE("set socket non block failed, errno: %{public}d!", errno);
150         close(sock);
151         return -1;
152     }
153     fcntl(sock, F_SETFD, FD_CLOEXEC);
154     if (listen(sock, backlog) < 0) {
155         LOGE("listen failed, errno: %{public}d!", errno);
156         close(sock);
157         return -1;
158     }
159     return sock;
160 }
161 
ConnectUnixServer(const char * path)162 int ConnectUnixServer(const char *path)
163 {
164     struct sockaddr_un sockAddr;
165     if (memset_s(&sockAddr, sizeof(sockAddr), 0, sizeof(sockAddr)) != EOK) {
166         return -1;
167     }
168     sockAddr.sun_family = AF_LOCAL;
169     if (strncpy_s(sockAddr.sun_path, sizeof(sockAddr.sun_path), path, strlen(path)) != EOK) {
170         return -1;
171     }
172     int sock = CreateSocket(AF_LOCAL);
173     if (sock < 0) {
174         return -1;
175     }
176     if (connect(sock, (struct sockaddr *)&sockAddr, sizeof(sockAddr)) < 0) {
177         LOGE("connect failed!");
178         close(sock);
179         return -1;
180     }
181     return sock;
182 }
183 
WaitFdEvent(int fd,unsigned int mask,int milliseconds)184 int WaitFdEvent(int fd, unsigned int mask, int milliseconds)
185 {
186     struct pollfd pFd = {0};
187     pFd.fd = fd;
188     if (mask & READ_EVENT) {
189         pFd.events |= POLLIN;
190     }
191     if (mask & WRIT_EVENT) {
192         pFd.events |= POLLOUT;
193     }
194     int ret = poll(&pFd, 1, milliseconds);
195     if (ret < 0) {
196         LOGE("poll failed! errno=%{public}d", errno);
197         if (errno == EINTR) {
198             return 0;
199         }
200         return -1;
201     } else if (ret == 0) {
202         return 0;
203     } else {
204         return 1;
205     }
206 }
207