xref: /third_party/musl/src/network/socket.c (revision 570af302)
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#ifdef OHOS_FDTRACK_HOOK_ENABLE
9#include "musl_fdtrack_hook.h"
10#endif
11
12#if OHOS_PERMISSION_INTERNET
13typedef uint8_t (*AllowFunc)(void);
14static const char *LIB_NETSYS_CLIENT_NAME = "libnetsys_client.z.so";
15static const char *ALLOW_SOCKET_FUNC_NAME = "IsAllowInternet";
16
17/*
18 * Read a flag from netsys_client, there is only one place to set this flag, is the
19 * founction named DoStartup in startup_appspawn.
20 * */
21uint8_t is_allow_internet(void)
22{
23	static uint8_t first_time = 1;
24	static uint8_t allow = 1;
25
26	if (!first_time) {
27		return allow;
28	}
29
30	void *handler = dlopen(LIB_NETSYS_CLIENT_NAME, RTLD_LAZY);
31	if (handler != NULL) {
32		AllowFunc func = (AllowFunc)dlsym(handler, ALLOW_SOCKET_FUNC_NAME);
33		if (func != NULL && func() == 0) {
34			allow = 0;
35		}
36		dlclose(handler);
37	}
38	first_time = 0;
39	return allow;
40}
41#endif
42
43#ifdef OHOS_SOCKET_HOOK_ENABLE
44int __libc_socket(int domain, int type, int protocol)
45#else
46int socket(int domain, int type, int protocol)
47#endif
48{
49#if OHOS_PERMISSION_INTERNET
50	if ((domain == AF_INET || domain == AF_INET6) && is_allow_internet() == 0) {
51		errno = EPERM;
52		return -1;
53	}
54#endif
55
56	int s = __socketcall(socket, domain, type, protocol, 0, 0, 0);
57	if ((s==-EINVAL || s==-EPROTONOSUPPORT)
58	    && (type&(SOCK_CLOEXEC|SOCK_NONBLOCK))) {
59		s = __socketcall(socket, domain,
60			type & ~(SOCK_CLOEXEC|SOCK_NONBLOCK),
61			protocol, 0, 0, 0);
62		if (s < 0) return __syscall_ret(s);
63		if (type & SOCK_CLOEXEC)
64			__syscall(SYS_fcntl, s, F_SETFD, FD_CLOEXEC);
65		if (type & SOCK_NONBLOCK)
66			__syscall(SYS_fcntl, s, F_SETFL, O_NONBLOCK);
67	}
68#ifdef OHOS_FDTRACK_HOOK_ENABLE
69	return FDTRACK_START_HOOK(__syscall_ret(s));
70#endif
71	return __syscall_ret(s);
72}
73