Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/sun/net/ext/ExtendedSocketOptions.java
41159 views
1
/*
2
* Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package sun.net.ext;
27
28
import java.io.FileDescriptor;
29
import java.net.SocketException;
30
import java.net.SocketOption;
31
import java.util.Collections;
32
import java.util.HashSet;
33
import java.util.Set;
34
35
/**
36
* Defines the infrastructure to support extended socket options, beyond those
37
* defined in {@link java.net.StandardSocketOptions}.
38
*
39
* Extended socket options are accessed through the jdk.net API, which is in
40
* the jdk.net module.
41
*/
42
public abstract class ExtendedSocketOptions {
43
44
public static final short SOCK_STREAM = 1;
45
public static final short SOCK_DGRAM = 2;
46
47
private final Set<SocketOption<?>> options;
48
private final Set<SocketOption<?>> datagramOptions;
49
private final Set<SocketOption<?>> clientStreamOptions;
50
private final Set<SocketOption<?>> serverStreamOptions;
51
private final Set<SocketOption<?>> unixDomainClientOptions;
52
53
/** Tells whether or not the option is supported. */
54
public final boolean isOptionSupported(SocketOption<?> option) {
55
return options().contains(option);
56
}
57
58
/** Return the, possibly empty, set of extended socket options available. */
59
public final Set<SocketOption<?>> options() { return options; }
60
61
/**
62
* Returns the (possibly empty) set of extended socket options for
63
* stream-oriented listening sockets.
64
*/
65
public static Set<SocketOption<?>> serverSocketOptions() {
66
return getInstance().options0(SOCK_STREAM, true);
67
}
68
69
/**
70
* Returns the (possibly empty) set of extended socket options for
71
* stream-oriented connecting sockets.
72
*/
73
public static Set<SocketOption<?>> clientSocketOptions() {
74
return getInstance().options0(SOCK_STREAM, false);
75
}
76
77
/**
78
* Return the, possibly empty, set of extended socket options available for
79
* Unix domain client sockets. Note, there are no extended
80
* Unix domain server options.
81
*/
82
private final Set<SocketOption<?>> unixDomainClientOptions() {
83
return unixDomainClientOptions;
84
}
85
86
public static Set<SocketOption<?>> unixDomainSocketOptions() {
87
return getInstance().unixDomainClientOptions();
88
}
89
90
/**
91
* Returns the (possibly empty) set of extended socket options for
92
* datagram-oriented sockets.
93
*/
94
public static Set<SocketOption<?>> datagramSocketOptions() {
95
return getInstance().options0(SOCK_DGRAM, false);
96
}
97
98
private static boolean isDatagramOption(SocketOption<?> option) {
99
if (option.name().startsWith("TCP_") || isUnixDomainOption(option)) {
100
return false;
101
} else {
102
return true;
103
}
104
}
105
106
private static boolean isUnixDomainOption(SocketOption<?> option) {
107
return option.name().equals("SO_PEERCRED");
108
}
109
110
private static boolean isStreamOption(SocketOption<?> option, boolean server) {
111
if (option.name().startsWith("UDP_") || isUnixDomainOption(option)) {
112
return false;
113
} else {
114
return true;
115
}
116
}
117
118
private Set<SocketOption<?>> options0(short type, boolean server) {
119
switch (type) {
120
case SOCK_DGRAM:
121
return datagramOptions;
122
case SOCK_STREAM:
123
if (server) {
124
return serverStreamOptions;
125
} else {
126
return clientStreamOptions;
127
}
128
default:
129
//this will never happen
130
throw new IllegalArgumentException("Invalid socket option type");
131
}
132
}
133
134
/** Sets the value of a socket option, for the given socket. */
135
public abstract void setOption(FileDescriptor fd, SocketOption<?> option, Object value)
136
throws SocketException;
137
138
/** Returns the value of a socket option, for the given socket. */
139
public abstract Object getOption(FileDescriptor fd, SocketOption<?> option)
140
throws SocketException;
141
142
protected ExtendedSocketOptions(Set<SocketOption<?>> options) {
143
this.options = options;
144
var datagramOptions = new HashSet<SocketOption<?>>();
145
var serverStreamOptions = new HashSet<SocketOption<?>>();
146
var clientStreamOptions = new HashSet<SocketOption<?>>();
147
var unixDomainClientOptions = new HashSet<SocketOption<?>>();
148
for (var option : options) {
149
if (isDatagramOption(option)) {
150
datagramOptions.add(option);
151
}
152
if (isStreamOption(option, true)) {
153
serverStreamOptions.add(option);
154
}
155
if (isStreamOption(option, false)) {
156
clientStreamOptions.add(option);
157
}
158
if (isUnixDomainOption(option)) {
159
unixDomainClientOptions.add(option);
160
}
161
}
162
this.datagramOptions = Set.copyOf(datagramOptions);
163
this.serverStreamOptions = Set.copyOf(serverStreamOptions);
164
this.clientStreamOptions = Set.copyOf(clientStreamOptions);
165
this.unixDomainClientOptions = Set.copyOf(unixDomainClientOptions);
166
}
167
168
private static volatile ExtendedSocketOptions instance;
169
170
public static ExtendedSocketOptions getInstance() {
171
ExtendedSocketOptions ext = instance;
172
if (ext != null) {
173
return ext;
174
}
175
try {
176
// If the class is present, it will be initialized which
177
// triggers registration of the extended socket options.
178
Class<?> c = Class.forName("jdk.net.ExtendedSocketOptions");
179
ext = instance;
180
} catch (ClassNotFoundException e) {
181
synchronized (ExtendedSocketOptions.class) {
182
ext = instance;
183
if (ext != null) {
184
return ext;
185
}
186
// the jdk.net module is not present => no extended socket options
187
ext = instance = new NoExtendedSocketOptions();
188
}
189
}
190
return ext;
191
}
192
193
/** Registers support for extended socket options. Invoked by the jdk.net module. */
194
public static synchronized void register(ExtendedSocketOptions extOptions) {
195
if (instance != null)
196
throw new InternalError("Attempting to reregister extended options");
197
198
instance = extOptions;
199
}
200
201
static final class NoExtendedSocketOptions extends ExtendedSocketOptions {
202
203
NoExtendedSocketOptions() {
204
super(Collections.<SocketOption<?>>emptySet());
205
}
206
207
@Override
208
public void setOption(FileDescriptor fd, SocketOption<?> option, Object value)
209
throws SocketException
210
{
211
throw new UnsupportedOperationException(
212
"no extended options: " + option.name());
213
}
214
215
@Override
216
public Object getOption(FileDescriptor fd, SocketOption<?> option)
217
throws SocketException
218
{
219
throw new UnsupportedOperationException(
220
"no extended options: " + option.name());
221
}
222
}
223
}
224
225