1 #include <sys/socket.h>
2 #include <fcntl.h>
3 #include <errno.h>
4 #include <dlfcn.h>
5 #include <stdint.h>
6 #include <stddef.h>
7 #include "syscall.h"
8
9 #if OHOS_PERMISSION_INTERNET
10 typedef uint8_t (*AllowFunc)(void);
11 static const char *LIB_NETSYS_CLIENT_NAME = "libnetsys_client.z.so";
12 static const char *ALLOW_SOCKET_FUNC_NAME = "IsAllowInternet";
13
14 /*
15 * Read a flag from netsys_client, there is only one place to set this flag, is the
16 * founction named DoStartup in startup_appspawn.
17 * */
is_allow_internet(void)18 uint8_t is_allow_internet(void)
19 {
20 static uint8_t first_time = 1;
21 static uint8_t allow = 1;
22
23 if (!first_time) {
24 return allow;
25 }
26
27 void *handler = dlopen(LIB_NETSYS_CLIENT_NAME, RTLD_LAZY);
28 if (handler != NULL) {
29 AllowFunc func = (AllowFunc)dlsym(handler, ALLOW_SOCKET_FUNC_NAME);
30 if (func != NULL && func() == 0) {
31 allow = 0;
32 }
33 dlclose(handler);
34 }
35 first_time = 0;
36 return allow;
37 }
38 #endif
39
socket(int domain,int type,int protocol)40 int socket(int domain, int type, int protocol)
41 {
42 #if OHOS_PERMISSION_INTERNET
43 if ((domain == AF_INET || domain == AF_INET6) && is_allow_internet() == 0) {
44 errno = EPERM;
45 return -1;
46 }
47 #endif
48
49 int s = socketcall(socket, domain, type, protocol, 0, 0, 0);
50 if (s<0 && (errno==EINVAL || errno==EPROTONOSUPPORT)
51 && (type&(SOCK_CLOEXEC|SOCK_NONBLOCK))) {
52 s = socketcall(socket, domain,
53 type & ~(SOCK_CLOEXEC|SOCK_NONBLOCK),
54 protocol, 0, 0, 0);
55 if (s < 0) return s;
56 if (type & SOCK_CLOEXEC)
57 __syscall(SYS_fcntl, s, F_SETFD, FD_CLOEXEC);
58 if (type & SOCK_NONBLOCK)
59 __syscall(SYS_fcntl, s, F_SETFL, O_NONBLOCK);
60 }
61 return s;
62 }
63