Source:
public void run() { if (mMeasurement.finishTime > 0) { mCountDownLatch.countDown(); return; } try { setupSSLSocket(); mMeasurement.startTime = now(); connectAndHandshake(); } catch (NoSuchAlgorithmException | IOException | KeyManagementException | KeyStoreException e) { mMeasurement.recordFailure(e.toString()); return; } if (!TextUtils.isEmpty(mHostname)) { if (!verifyHostname(mHostname)) { mMeasurement.recordFailure("Hostname verification failed"); return; } } mMeasurement.description += " src{" + getLocalAddressString(mSslSocket) + "}"; final String sixRandomDigits = String.valueOf(mRandom.nextInt(900000) + 100000); mMeasurement.description += " qtype{" + mQueryType + "}" + " qname{" + sixRandomDigits + "-android-ds.metric.gstatic.com}"; final byte[] dnsPacket = getDnsQueryPacket(sixRandomDigits); try { OutputStream output = mSslSocket.getOutputStream(); ByteBuffer querySize = ByteBuffer.allocate(2); querySize.putShort((short) dnsPacket.length); output.write(querySize.array()); output.write(dnsPacket); InputStream input = mSslSocket.getInputStream(); byte[] buf = new byte[2]; input.read(buf, 0, 2); final short expectReplyLen = ByteBuffer.wrap(buf).getShort(); byte[] reply = new byte[expectReplyLen]; int read = 0; while (read < expectReplyLen) { int n = input.read(reply, read, expectReplyLen - read); if (n < 0) break; read += n; } if (read == expectReplyLen && read > DNS_HEADER_SIZE) { mMeasurement.recordSuccess("1/1 " + responseCodeStr((int) (reply[3]) & 0x0f)); } else { mMeasurement.recordFailure("Unexpected answer length " + read); } } catch (IOException e) { mMeasurement.recordFailure(e.toString()); } try { mSslSocket.close(); } catch (IOException ignored) { } }

Target:
public void run() { if (!ensureMeasurementNecessary()) return; final String sixRandomDigits = String.valueOf(mRandom.nextInt(900000) + 100000); final byte[] dnsPacket = getDnsQueryPacket(sixRandomDigits); try (SSLSocket sslSocket = setupSSLSocket()) { mMeasurement.startTime = now(); sslSocket.connect( new InetSocketAddress(mTarget, DNS_TLS_PORT), TCP_CONNECT_TIMEOUT); sslSocket.startHandshake(); maybeDoHostnameVerification(sslSocket); mMeasurement.description += " src{" + getLocalAddressString(sslSocket) + "}" + " qtype{" + mQueryType + "}" + " qname{" + sixRandomDigits + "-android-ds.metric.gstatic.com}"; final OutputStream output = sslSocket.getOutputStream(); final ByteBuffer querySize = ByteBuffer.allocate(2); querySize.putShort((short) dnsPacket.length); output.write(querySize.array()); output.write(dnsPacket); final InputStream input = sslSocket.getInputStream(); final byte[] buf = new byte[2]; input.read(buf, 0, 2); final short expectReplyLen = ByteBuffer.wrap(buf).getShort(); final byte[] reply = new byte[expectReplyLen]; int read = 0; while (read < expectReplyLen) { int n = input.read(reply, read, expectReplyLen - read); if (n < 0) break; read += n; } if (read == expectReplyLen && read > DNS_HEADER_SIZE) { mMeasurement.recordSuccess("1/1 " + responseCodeStr((int) (reply[3]) & 0x0f)); } else { mMeasurement.recordFailure("Unexpected answer length " + read); } } catch (IOException | NoSuchAlgorithmException | KeyManagementException | KeyStoreException e) { mMeasurement.recordFailure(e.toString()); } }