1 /* 2 * Copyright 2018 The gRPC Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package io.grpc.alts.internal; 18 19 import com.google.common.annotations.VisibleForTesting; 20 import io.grpc.alts.internal.TransportSecurityCommon.RpcProtocolVersions; 21 import io.grpc.alts.internal.TransportSecurityCommon.RpcProtocolVersions.Version; 22 import javax.annotation.Nullable; 23 24 /** Utility class for Rpc Protocol Versions. */ 25 public final class RpcProtocolVersionsUtil { 26 27 private static final int MAX_RPC_VERSION_MAJOR = 2; 28 private static final int MAX_RPC_VERSION_MINOR = 1; 29 private static final int MIN_RPC_VERSION_MAJOR = 2; 30 private static final int MIN_RPC_VERSION_MINOR = 1; 31 private static final RpcProtocolVersions RPC_PROTOCOL_VERSIONS = 32 RpcProtocolVersions.newBuilder() 33 .setMaxRpcVersion( 34 RpcProtocolVersions.Version.newBuilder() 35 .setMajor(MAX_RPC_VERSION_MAJOR) 36 .setMinor(MAX_RPC_VERSION_MINOR) 37 .build()) 38 .setMinRpcVersion( 39 RpcProtocolVersions.Version.newBuilder() 40 .setMajor(MIN_RPC_VERSION_MAJOR) 41 .setMinor(MIN_RPC_VERSION_MINOR) 42 .build()) 43 .build(); 44 45 /** Returns default Rpc Protocol Versions. */ getRpcProtocolVersions()46 public static RpcProtocolVersions getRpcProtocolVersions() { 47 return RPC_PROTOCOL_VERSIONS; 48 } 49 50 /** 51 * Returns true if first Rpc Protocol Version is greater than or equal to the second one. Returns 52 * false otherwise. 53 */ 54 @VisibleForTesting isGreaterThanOrEqualTo(Version first, Version second)55 static boolean isGreaterThanOrEqualTo(Version first, Version second) { 56 if ((first.getMajor() > second.getMajor()) 57 || (first.getMajor() == second.getMajor() && first.getMinor() >= second.getMinor())) { 58 return true; 59 } 60 return false; 61 } 62 63 /** 64 * Performs check between local and peer Rpc Protocol Versions. This function returns true and the 65 * highest common version if there exists a common Rpc Protocol Version to use, and returns false 66 * and null otherwise. 67 */ checkRpcProtocolVersions( RpcProtocolVersions localVersions, RpcProtocolVersions peerVersions)68 static RpcVersionsCheckResult checkRpcProtocolVersions( 69 RpcProtocolVersions localVersions, RpcProtocolVersions peerVersions) { 70 Version maxCommonVersion; 71 Version minCommonVersion; 72 // maxCommonVersion is MIN(local.max, peer.max) 73 if (isGreaterThanOrEqualTo(localVersions.getMaxRpcVersion(), peerVersions.getMaxRpcVersion())) { 74 maxCommonVersion = peerVersions.getMaxRpcVersion(); 75 } else { 76 maxCommonVersion = localVersions.getMaxRpcVersion(); 77 } 78 // minCommonVersion is MAX(local.min, peer.min) 79 if (isGreaterThanOrEqualTo(localVersions.getMinRpcVersion(), peerVersions.getMinRpcVersion())) { 80 minCommonVersion = localVersions.getMinRpcVersion(); 81 } else { 82 minCommonVersion = peerVersions.getMinRpcVersion(); 83 } 84 if (isGreaterThanOrEqualTo(maxCommonVersion, minCommonVersion)) { 85 return new RpcVersionsCheckResult.Builder() 86 .setResult(true) 87 .setHighestCommonVersion(maxCommonVersion) 88 .build(); 89 } 90 return new RpcVersionsCheckResult.Builder().setResult(false).build(); 91 } 92 93 /** Wrapper class that stores results of Rpc Protocol Versions check. */ 94 static final class RpcVersionsCheckResult { 95 private final boolean result; 96 @Nullable private final Version highestCommonVersion; 97 RpcVersionsCheckResult(Builder builder)98 private RpcVersionsCheckResult(Builder builder) { 99 result = builder.result; 100 highestCommonVersion = builder.highestCommonVersion; 101 } 102 getResult()103 boolean getResult() { 104 return result; 105 } 106 getHighestCommonVersion()107 Version getHighestCommonVersion() { 108 return highestCommonVersion; 109 } 110 111 static final class Builder { 112 private boolean result; 113 @Nullable private Version highestCommonVersion = null; 114 setResult(boolean result)115 public Builder setResult(boolean result) { 116 this.result = result; 117 return this; 118 } 119 setHighestCommonVersion(Version highestCommonVersion)120 public Builder setHighestCommonVersion(Version highestCommonVersion) { 121 this.highestCommonVersion = highestCommonVersion; 122 return this; 123 } 124 build()125 public RpcVersionsCheckResult build() { 126 return new RpcVersionsCheckResult(this); 127 } 128 } 129 } 130 } 131