code: private static void exploreClientHello(
              ByteBuffer input,
              List<String> alpnProtocols,
              ByteArrayOutputStream out) throws SSLException {
  
          // client version
          byte helloMajorVersion = input.get();
          byte helloMinorVersion = input.get();
          if(out != null) {
              out.write(helloMajorVersion & 0xFF);
              out.write(helloMinorVersion & 0xFF);
          }
          if(helloMajorVersion != 3 && helloMinorVersion != 3) {
              //we only care about TLS 1.2
              return;
          }
  
  
          // ignore random
          for(int i = 0; i < 32; ++i) {// 32: the length of Random
              byte d = input.get();
              if(out != null) {
                  out.write(d & 0xFF);
              }
          }
  
          // session id
          processByteVector8(input, out);
  
          // cipher_suites
          processByteVector16(input, out);
  
          // compression methods
          processByteVector8(input, out);
          if (input.remaining() > 0) {
              exploreExtensions(input, alpnProtocols, out);
          } else if(out != null) {
              byte[] data = generateAlpnExtension(alpnProtocols);
              writeInt16(out, data.length);
              out.write(data, 0, data.length);
          }
      }
docs: /*
  struct {
  uint32 gmt_unix_time;
  opaque random_bytes[28];
  } Random;
  
  opaque SessionID<0..32>;
  
  uint8 CipherSuite[2];
  
  enum { null(0), (255) } CompressionMethod;
  
  struct {
  ProtocolVersion client_version;
  Random random;
  SessionID session_id;
  CipherSuite cipher_suites<2..2^16-2>;
  CompressionMethod compression_methods<1..2^8-1>;
  select (extensions_present) {
  case false:
  struct {};
  case true:
  Extension extensions<0..2^16-1>;
  };
  } ClientHello;