Skip to content

Commit 891d0df

Browse files
authored
Merge branch 'master' into adrien.boitreaud/spark-launcher-metrics
2 parents 4cbda77 + 9b93366 commit 891d0df

108 files changed

Lines changed: 1673 additions & 598 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

communication/src/main/java/datadog/communication/ddagent/DDAgentFeaturesDiscovery.java

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package datadog.communication.ddagent;
22

3-
import static datadog.communication.http.OkHttpUtils.DATADOG_CONTAINER_ID;
43
import static datadog.communication.http.OkHttpUtils.DATADOG_CONTAINER_TAGS_HASH;
4+
import static datadog.communication.http.OkHttpUtils.msgpackRequestBodyOf;
5+
import static datadog.communication.http.OkHttpUtils.prepareRequest;
56
import static datadog.communication.serialization.msgpack.MsgPackWriter.FIXARRAY;
7+
import static java.util.Collections.emptyMap;
68
import static java.util.Collections.emptySet;
79
import static java.util.Collections.singletonList;
810
import static java.util.Collections.unmodifiableSet;
@@ -11,7 +13,6 @@
1113
import com.squareup.moshi.Moshi;
1214
import com.squareup.moshi.Types;
1315
import datadog.common.container.ContainerInfo;
14-
import datadog.communication.http.OkHttpUtils;
1516
import datadog.metrics.api.Monitoring;
1617
import datadog.metrics.api.Recording;
1718
import datadog.metrics.impl.statsd.DDAgentStatsDClientManager;
@@ -151,13 +152,9 @@ private void doDiscovery(State newState) {
151152
// 3. fallback if the endpoint couldn't be found or the response couldn't be parsed
152153
try (Recording recording = discoveryTimer.start()) {
153154
boolean fallback = true;
154-
final Request.Builder requestBuilder =
155-
new Request.Builder().url(agentBaseUrl.resolve("info").url());
156-
final String containerId = ContainerInfo.get().getContainerId();
157-
if (containerId != null) {
158-
requestBuilder.header(DATADOG_CONTAINER_ID, containerId);
159-
}
160-
try (Response response = client.newCall(requestBuilder.build()).execute()) {
155+
final Request request =
156+
prepareRequest(agentBaseUrl.resolve("info"), emptyMap()).get().build();
157+
try (Response response = client.newCall(request).execute()) {
161158
if (response.isSuccessful()) {
162159
processInfoResponseHeaders(response);
163160
fallback = !processInfoResponse(newState, response.body().string());
@@ -202,11 +199,8 @@ private String probeTracesEndpoint(State newState, String[] endpoints) {
202199
try (Response response =
203200
client
204201
.newCall(
205-
new Request.Builder()
206-
.put(
207-
OkHttpUtils.msgpackRequestBodyOf(
208-
singletonList(ByteBuffer.wrap(PROBE_MESSAGE))))
209-
.url(agentBaseUrl.resolve(candidate))
202+
prepareRequest(agentBaseUrl.resolve(candidate), emptyMap())
203+
.put(msgpackRequestBodyOf(singletonList(ByteBuffer.wrap(PROBE_MESSAGE))))
210204
.build())
211205
.execute()) {
212206
if (response.code() != 404) {
Lines changed: 332 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,332 @@
1+
/*
2+
* Copyright (C) 2012 Square, Inc.
3+
* Copyright (C) 2012 The Android Open Source Project
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package okhttp3.internal.platform;
18+
19+
import de.thetaphi.forbiddenapis.SuppressForbidden;
20+
import java.io.IOException;
21+
import java.lang.reflect.Field;
22+
import java.net.InetSocketAddress;
23+
import java.net.Socket;
24+
import java.security.NoSuchAlgorithmException;
25+
import java.util.ArrayList;
26+
import java.util.List;
27+
import java.util.logging.Level;
28+
import java.util.logging.Logger;
29+
import javax.annotation.Nullable;
30+
import javax.net.ssl.SSLContext;
31+
import javax.net.ssl.SSLSocket;
32+
import javax.net.ssl.SSLSocketFactory;
33+
import javax.net.ssl.X509TrustManager;
34+
import okhttp3.OkHttpClient;
35+
import okhttp3.Protocol;
36+
import okhttp3.internal.tls.BasicCertificateChainCleaner;
37+
import okhttp3.internal.tls.BasicTrustRootIndex;
38+
import okhttp3.internal.tls.CertificateChainCleaner;
39+
import okhttp3.internal.tls.TrustRootIndex;
40+
import okio.Buffer;
41+
42+
/**
43+
* Replacement Platform class that avoids eager call to Security.getProviders()
44+
* ----------------------------------------------------------------------------
45+
*
46+
* <p>Access to platform-specific features.
47+
*
48+
* <h3>Server name indication (SNI)</h3>
49+
*
50+
* <p>Supported on Android 2.3+.
51+
*
52+
* <p>Supported on OpenJDK 7+
53+
*
54+
* <h3>Session Tickets</h3>
55+
*
56+
* <p>Supported on Android 2.3+.
57+
*
58+
* <h3>Android Traffic Stats (Socket Tagging)</h3>
59+
*
60+
* <p>Supported on Android 4.0+.
61+
*
62+
* <h3>ALPN (Application Layer Protocol Negotiation)</h3>
63+
*
64+
* <p>Supported on Android 5.0+. The APIs were present in Android 4.4, but that implementation was
65+
* unstable.
66+
*
67+
* <p>Supported on OpenJDK 7 and 8 (via the JettyALPN-boot library).
68+
*
69+
* <p>Supported on OpenJDK 9 via SSLParameters and SSLSocket features.
70+
*
71+
* <h3>Trust Manager Extraction</h3>
72+
*
73+
* <p>Supported on Android 2.3+ and OpenJDK 7+. There are no public APIs to recover the trust
74+
* manager that was used to create an {@link SSLSocketFactory}.
75+
*
76+
* <h3>Android Cleartext Permit Detection</h3>
77+
*
78+
* <p>Supported on Android 6.0+ via {@code NetworkSecurityPolicy}.
79+
*/
80+
public class PatchPlatform {
81+
private static final Platform PLATFORM = findPlatform();
82+
public static final int INFO = 4;
83+
public static final int WARN = 5;
84+
private static final Logger logger = Logger.getLogger(OkHttpClient.class.getName());
85+
86+
public static Platform get() {
87+
return PLATFORM;
88+
}
89+
90+
/** Prefix used on custom headers. */
91+
public String getPrefix() {
92+
return "OkHttp";
93+
}
94+
95+
@SuppressForbidden // allow this use of Class.forName()
96+
protected @Nullable X509TrustManager trustManager(SSLSocketFactory sslSocketFactory) {
97+
// Attempt to get the trust manager from an OpenJDK socket factory. We attempt this on all
98+
// platforms in order to support Robolectric, which mixes classes from both Android and the
99+
// Oracle JDK. Note that we don't support HTTP/2 or other nice features on Robolectric.
100+
try {
101+
Class<?> sslContextClass = Class.forName("sun.security.ssl.SSLContextImpl");
102+
Object context = readFieldOrNull(sslSocketFactory, sslContextClass, "context");
103+
if (context == null) return null;
104+
return readFieldOrNull(context, X509TrustManager.class, "trustManager");
105+
} catch (ClassNotFoundException e) {
106+
return null;
107+
}
108+
}
109+
110+
/**
111+
* Configure TLS extensions on {@code sslSocket} for {@code route}.
112+
*
113+
* @param hostname non-null for client-side handshakes; null for server-side handshakes.
114+
*/
115+
public void configureTlsExtensions(
116+
SSLSocket sslSocket, @Nullable String hostname, List<Protocol> protocols)
117+
throws IOException {}
118+
119+
/**
120+
* Called after the TLS handshake to release resources allocated by {@link
121+
* #configureTlsExtensions}.
122+
*/
123+
public void afterHandshake(SSLSocket sslSocket) {}
124+
125+
/** Returns the negotiated protocol, or null if no protocol was negotiated. */
126+
public @Nullable String getSelectedProtocol(SSLSocket socket) {
127+
return null;
128+
}
129+
130+
public void connectSocket(Socket socket, InetSocketAddress address, int connectTimeout)
131+
throws IOException {
132+
socket.connect(address, connectTimeout);
133+
}
134+
135+
public void log(int level, String message, @Nullable Throwable t) {
136+
Level logLevel = level == WARN ? Level.WARNING : Level.INFO;
137+
logger.log(logLevel, message, t);
138+
}
139+
140+
public boolean isCleartextTrafficPermitted(String hostname) {
141+
return true;
142+
}
143+
144+
/**
145+
* Returns an object that holds a stack trace created at the moment this method is executed. This
146+
* should be used specifically for {@link java.io.Closeable} objects and in conjunction with
147+
* {@link #logCloseableLeak(String, Object)}.
148+
*/
149+
public Object getStackTraceForCloseable(String closer) {
150+
if (logger.isLoggable(Level.FINE)) {
151+
return new Throwable(closer); // These are expensive to allocate.
152+
}
153+
return null;
154+
}
155+
156+
public void logCloseableLeak(String message, Object stackTrace) {
157+
if (stackTrace == null) {
158+
message +=
159+
" To see where this was allocated, set the OkHttpClient logger level to FINE: "
160+
+ "Logger.getLogger(OkHttpClient.class.getName()).setLevel(Level.FINE);";
161+
}
162+
log(WARN, message, (Throwable) stackTrace);
163+
}
164+
165+
public static List<String> alpnProtocolNames(List<Protocol> protocols) {
166+
List<String> names = new ArrayList<>(protocols.size());
167+
for (int i = 0, size = protocols.size(); i < size; i++) {
168+
Protocol protocol = protocols.get(i);
169+
if (protocol == Protocol.HTTP_1_0) continue; // No HTTP/1.0 for ALPN.
170+
names.add(protocol.toString());
171+
}
172+
return names;
173+
}
174+
175+
public CertificateChainCleaner buildCertificateChainCleaner(X509TrustManager trustManager) {
176+
return new BasicCertificateChainCleaner(buildTrustRootIndex(trustManager));
177+
}
178+
179+
public CertificateChainCleaner buildCertificateChainCleaner(SSLSocketFactory sslSocketFactory) {
180+
X509TrustManager trustManager = trustManager(sslSocketFactory);
181+
182+
if (trustManager == null) {
183+
throw new IllegalStateException(
184+
"Unable to extract the trust manager on "
185+
+ Platform.get()
186+
+ ", sslSocketFactory is "
187+
+ sslSocketFactory.getClass());
188+
}
189+
190+
return buildCertificateChainCleaner(trustManager);
191+
}
192+
193+
/* Avoid eager call to Security.getProviders()
194+
----------------------------------------------
195+
| public static boolean isConscryptPreferred() {
196+
| // mainly to allow tests to run cleanly
197+
| if ("conscrypt".equals(System.getProperty("okhttp.platform"))) {
198+
| return true;
199+
| }
200+
|
201+
| // check if Provider manually installed
202+
| String preferredProvider = Security.getProviders()[0].getName();
203+
| return "Conscrypt".equals(preferredProvider);
204+
| }
205+
---------------------------------------------- */
206+
207+
/** Attempt to match the host runtime to a capable Platform implementation. */
208+
private static Platform findPlatform() {
209+
if (isAndroid()) {
210+
return findAndroidPlatform();
211+
} else {
212+
return findJvmPlatform();
213+
}
214+
}
215+
216+
public static boolean isAndroid() {
217+
// This explicit check avoids activating in Android Studio with Android specific classes
218+
// available when running plugins inside the IDE.
219+
return "Dalvik".equals(System.getProperty("java.vm.name"));
220+
}
221+
222+
private static Platform findJvmPlatform() {
223+
/* Avoid eager call to Security.getProviders()
224+
----------------------------------------------
225+
| if (isConscryptPreferred()) {
226+
| Platform conscrypt = ConscryptPlatform.buildIfSupported();
227+
|
228+
| if (conscrypt != null) {
229+
| return conscrypt;
230+
| }
231+
| }
232+
---------------------------------------------- */
233+
234+
Platform jdk9 = Jdk9Platform.buildIfSupported();
235+
236+
if (jdk9 != null) {
237+
return jdk9;
238+
}
239+
240+
Platform jdkWithJettyBoot = JdkWithJettyBootPlatform.buildIfSupported();
241+
242+
if (jdkWithJettyBoot != null) {
243+
return jdkWithJettyBoot;
244+
}
245+
246+
// Probably an Oracle JDK like OpenJDK.
247+
return new Platform();
248+
}
249+
250+
private static Platform findAndroidPlatform() {
251+
Platform android10 = Android10Platform.buildIfSupported();
252+
253+
if (android10 != null) {
254+
return android10;
255+
}
256+
257+
Platform android = AndroidPlatform.buildIfSupported();
258+
259+
if (android == null) {
260+
throw new NullPointerException("No platform found on Android");
261+
}
262+
263+
return android;
264+
}
265+
266+
/**
267+
* Returns the concatenation of 8-bit, length prefixed protocol names.
268+
* http://tools.ietf.org/html/draft-agl-tls-nextprotoneg-04#page-4
269+
*/
270+
static byte[] concatLengthPrefixed(List<Protocol> protocols) {
271+
Buffer result = new Buffer();
272+
for (int i = 0, size = protocols.size(); i < size; i++) {
273+
Protocol protocol = protocols.get(i);
274+
if (protocol == Protocol.HTTP_1_0) continue; // No HTTP/1.0 for ALPN.
275+
result.writeByte(protocol.toString().length());
276+
result.writeUtf8(protocol.toString());
277+
}
278+
return result.readByteArray();
279+
}
280+
281+
static @Nullable <T> T readFieldOrNull(Object instance, Class<T> fieldType, String fieldName) {
282+
for (Class<?> c = instance.getClass(); c != Object.class; c = c.getSuperclass()) {
283+
try {
284+
Field field = c.getDeclaredField(fieldName);
285+
field.setAccessible(true);
286+
Object value = field.get(instance);
287+
if (value == null || !fieldType.isInstance(value)) return null;
288+
return fieldType.cast(value);
289+
} catch (NoSuchFieldException ignored) {
290+
} catch (IllegalAccessException e) {
291+
throw new AssertionError();
292+
}
293+
}
294+
295+
// Didn't find the field we wanted. As a last gasp attempt, try to find the value on a delegate.
296+
if (!fieldName.equals("delegate")) {
297+
Object delegate = readFieldOrNull(instance, Object.class, "delegate");
298+
if (delegate != null) return readFieldOrNull(delegate, fieldType, fieldName);
299+
}
300+
301+
return null;
302+
}
303+
304+
public SSLContext getSSLContext() {
305+
String jvmVersion = System.getProperty("java.specification.version");
306+
if ("1.7".equals(jvmVersion)) {
307+
try {
308+
// JDK 1.7 (public version) only support > TLSv1 with named protocols
309+
return SSLContext.getInstance("TLSv1.2");
310+
} catch (NoSuchAlgorithmException e) {
311+
// fallback to TLS
312+
}
313+
}
314+
315+
try {
316+
return SSLContext.getInstance("TLS");
317+
} catch (NoSuchAlgorithmException e) {
318+
throw new IllegalStateException("No TLS provider", e);
319+
}
320+
}
321+
322+
public TrustRootIndex buildTrustRootIndex(X509TrustManager trustManager) {
323+
return new BasicTrustRootIndex(trustManager.getAcceptedIssuers());
324+
}
325+
326+
public void configureSslSocketFactory(SSLSocketFactory socketFactory) {}
327+
328+
@Override
329+
public String toString() {
330+
return getClass().getSimpleName();
331+
}
332+
}

0 commit comments

Comments
 (0)