Nathan Harold | 330e108 | 2017-01-12 18:38:57 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2017 The Android Open Source Project |
| 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 | package android.net; |
| 17 | |
| 18 | import android.os.Parcel; |
| 19 | import android.os.Parcelable; |
Nathan Harold | a10003d | 2017-08-23 13:46:33 -0700 | [diff] [blame] | 20 | |
| 21 | import com.android.internal.annotations.VisibleForTesting; |
Nathan Harold | 330e108 | 2017-01-12 18:38:57 -0800 | [diff] [blame] | 22 | |
| 23 | /** @hide */ |
| 24 | public final class IpSecConfig implements Parcelable { |
Nathan Harold | 93962f3 | 2017-03-07 13:23:36 -0800 | [diff] [blame] | 25 | private static final String TAG = "IpSecConfig"; |
Nathan Harold | 330e108 | 2017-01-12 18:38:57 -0800 | [diff] [blame] | 26 | |
Nathan Harold | a10003d | 2017-08-23 13:46:33 -0700 | [diff] [blame] | 27 | // MODE_TRANSPORT or MODE_TUNNEL |
| 28 | private int mMode = IpSecTransform.MODE_TRANSPORT; |
Nathan Harold | 330e108 | 2017-01-12 18:38:57 -0800 | [diff] [blame] | 29 | |
Nathan Harold | a10003d | 2017-08-23 13:46:33 -0700 | [diff] [blame] | 30 | // Needs to be valid only for tunnel mode |
| 31 | // Preventing this from being null simplifies Java->Native binder |
| 32 | private String mLocalAddress = ""; |
Nathan Harold | 330e108 | 2017-01-12 18:38:57 -0800 | [diff] [blame] | 33 | |
Nathan Harold | a10003d | 2017-08-23 13:46:33 -0700 | [diff] [blame] | 34 | // Preventing this from being null simplifies Java->Native binder |
| 35 | private String mRemoteAddress = ""; |
Nathan Harold | 330e108 | 2017-01-12 18:38:57 -0800 | [diff] [blame] | 36 | |
Nathan Harold | d6f50b2 | 2017-10-04 12:58:55 -0700 | [diff] [blame] | 37 | // The underlying Network that represents the "gateway" Network |
Nathan Harold | a10003d | 2017-08-23 13:46:33 -0700 | [diff] [blame] | 38 | // for outbound packets. It may also be used to select packets. |
| 39 | private Network mNetwork; |
Nathan Harold | 330e108 | 2017-01-12 18:38:57 -0800 | [diff] [blame] | 40 | |
| 41 | public static class Flow { |
| 42 | // Minimum requirements for identifying a transform |
| 43 | // SPI identifying the IPsec flow in packet processing |
| 44 | // and a remote IP address |
Nathan Harold | a10003d | 2017-08-23 13:46:33 -0700 | [diff] [blame] | 45 | private int mSpiResourceId = IpSecManager.INVALID_RESOURCE_ID; |
Nathan Harold | 330e108 | 2017-01-12 18:38:57 -0800 | [diff] [blame] | 46 | |
| 47 | // Encryption Algorithm |
Nathan Harold | a10003d | 2017-08-23 13:46:33 -0700 | [diff] [blame] | 48 | private IpSecAlgorithm mEncryption; |
Nathan Harold | 330e108 | 2017-01-12 18:38:57 -0800 | [diff] [blame] | 49 | |
| 50 | // Authentication Algorithm |
Nathan Harold | a10003d | 2017-08-23 13:46:33 -0700 | [diff] [blame] | 51 | private IpSecAlgorithm mAuthentication; |
ludi | b0c95b1 | 2017-05-22 10:52:23 -0700 | [diff] [blame] | 52 | |
Benedict Wong | 0febe5e | 2017-08-22 21:42:33 -0700 | [diff] [blame] | 53 | // Authenticated Encryption Algorithm |
| 54 | private IpSecAlgorithm mAuthenticatedEncryption; |
| 55 | |
ludi | b0c95b1 | 2017-05-22 10:52:23 -0700 | [diff] [blame] | 56 | @Override |
| 57 | public String toString() { |
| 58 | return new StringBuilder() |
Nathan Harold | a10003d | 2017-08-23 13:46:33 -0700 | [diff] [blame] | 59 | .append("{mSpiResourceId=") |
| 60 | .append(mSpiResourceId) |
| 61 | .append(", mEncryption=") |
| 62 | .append(mEncryption) |
| 63 | .append(", mAuthentication=") |
| 64 | .append(mAuthentication) |
Benedict Wong | 0febe5e | 2017-08-22 21:42:33 -0700 | [diff] [blame] | 65 | .append(", mAuthenticatedEncryption=") |
| 66 | .append(mAuthenticatedEncryption) |
ludi | b0c95b1 | 2017-05-22 10:52:23 -0700 | [diff] [blame] | 67 | .append("}") |
| 68 | .toString(); |
| 69 | } |
Nathan Harold | 19ce70b | 2017-09-25 19:33:13 -0700 | [diff] [blame] | 70 | |
| 71 | static boolean equals(IpSecConfig.Flow lhs, IpSecConfig.Flow rhs) { |
| 72 | if (lhs == null || rhs == null) return (lhs == rhs); |
| 73 | return (lhs.mSpiResourceId == rhs.mSpiResourceId |
| 74 | && IpSecAlgorithm.equals(lhs.mEncryption, rhs.mEncryption) |
| 75 | && IpSecAlgorithm.equals(lhs.mAuthentication, rhs.mAuthentication)); |
| 76 | } |
Nathan Harold | 330e108 | 2017-01-12 18:38:57 -0800 | [diff] [blame] | 77 | } |
| 78 | |
Nathan Harold | a10003d | 2017-08-23 13:46:33 -0700 | [diff] [blame] | 79 | private final Flow[] mFlow = new Flow[] {new Flow(), new Flow()}; |
Nathan Harold | 330e108 | 2017-01-12 18:38:57 -0800 | [diff] [blame] | 80 | |
| 81 | // For tunnel mode IPv4 UDP Encapsulation |
| 82 | // IpSecTransform#ENCAP_ESP_*, such as ENCAP_ESP_OVER_UDP_IKE |
Nathan Harold | a10003d | 2017-08-23 13:46:33 -0700 | [diff] [blame] | 83 | private int mEncapType = IpSecTransform.ENCAP_NONE; |
| 84 | private int mEncapSocketResourceId = IpSecManager.INVALID_RESOURCE_ID; |
| 85 | private int mEncapRemotePort; |
Nathan Harold | 330e108 | 2017-01-12 18:38:57 -0800 | [diff] [blame] | 86 | |
Nathan Harold | 330e108 | 2017-01-12 18:38:57 -0800 | [diff] [blame] | 87 | // An interval, in seconds between the NattKeepalive packets |
Nathan Harold | a10003d | 2017-08-23 13:46:33 -0700 | [diff] [blame] | 88 | private int mNattKeepaliveInterval; |
| 89 | |
| 90 | /** Set the mode for this IPsec transform */ |
| 91 | public void setMode(int mode) { |
| 92 | mMode = mode; |
| 93 | } |
| 94 | |
| 95 | /** Set the local IP address for Tunnel mode */ |
| 96 | public void setLocalAddress(String localAddress) { |
| 97 | if (localAddress == null) { |
| 98 | throw new IllegalArgumentException("localAddress may not be null!"); |
| 99 | } |
| 100 | mLocalAddress = localAddress; |
| 101 | } |
| 102 | |
| 103 | /** Set the remote IP address for this IPsec transform */ |
| 104 | public void setRemoteAddress(String remoteAddress) { |
| 105 | if (remoteAddress == null) { |
| 106 | throw new IllegalArgumentException("remoteAddress may not be null!"); |
| 107 | } |
| 108 | mRemoteAddress = remoteAddress; |
| 109 | } |
| 110 | |
| 111 | /** Set the SPI for a given direction by resource ID */ |
| 112 | public void setSpiResourceId(int direction, int resourceId) { |
| 113 | mFlow[direction].mSpiResourceId = resourceId; |
| 114 | } |
| 115 | |
| 116 | /** Set the encryption algorithm for a given direction */ |
| 117 | public void setEncryption(int direction, IpSecAlgorithm encryption) { |
| 118 | mFlow[direction].mEncryption = encryption; |
| 119 | } |
| 120 | |
| 121 | /** Set the authentication algorithm for a given direction */ |
| 122 | public void setAuthentication(int direction, IpSecAlgorithm authentication) { |
| 123 | mFlow[direction].mAuthentication = authentication; |
| 124 | } |
| 125 | |
Benedict Wong | 0febe5e | 2017-08-22 21:42:33 -0700 | [diff] [blame] | 126 | /** Set the authenticated encryption algorithm for a given direction */ |
| 127 | public void setAuthenticatedEncryption(int direction, IpSecAlgorithm authenticatedEncryption) { |
| 128 | mFlow[direction].mAuthenticatedEncryption = authenticatedEncryption; |
| 129 | } |
| 130 | |
Nathan Harold | a10003d | 2017-08-23 13:46:33 -0700 | [diff] [blame] | 131 | public void setNetwork(Network network) { |
| 132 | mNetwork = network; |
| 133 | } |
| 134 | |
| 135 | public void setEncapType(int encapType) { |
| 136 | mEncapType = encapType; |
| 137 | } |
| 138 | |
| 139 | public void setEncapSocketResourceId(int resourceId) { |
| 140 | mEncapSocketResourceId = resourceId; |
| 141 | } |
| 142 | |
| 143 | public void setEncapRemotePort(int port) { |
| 144 | mEncapRemotePort = port; |
| 145 | } |
| 146 | |
| 147 | public void setNattKeepaliveInterval(int interval) { |
| 148 | mNattKeepaliveInterval = interval; |
| 149 | } |
Nathan Harold | 330e108 | 2017-01-12 18:38:57 -0800 | [diff] [blame] | 150 | |
Nathan Harold | 93962f3 | 2017-03-07 13:23:36 -0800 | [diff] [blame] | 151 | // Transport or Tunnel |
| 152 | public int getMode() { |
Nathan Harold | a10003d | 2017-08-23 13:46:33 -0700 | [diff] [blame] | 153 | return mMode; |
Nathan Harold | 93962f3 | 2017-03-07 13:23:36 -0800 | [diff] [blame] | 154 | } |
| 155 | |
Nathan Harold | a10003d | 2017-08-23 13:46:33 -0700 | [diff] [blame] | 156 | public String getLocalAddress() { |
| 157 | return mLocalAddress; |
Nathan Harold | 330e108 | 2017-01-12 18:38:57 -0800 | [diff] [blame] | 158 | } |
| 159 | |
Nathan Harold | 8dc1fd0 | 2017-04-04 19:37:48 -0700 | [diff] [blame] | 160 | public int getSpiResourceId(int direction) { |
Nathan Harold | a10003d | 2017-08-23 13:46:33 -0700 | [diff] [blame] | 161 | return mFlow[direction].mSpiResourceId; |
Nathan Harold | 330e108 | 2017-01-12 18:38:57 -0800 | [diff] [blame] | 162 | } |
| 163 | |
Nathan Harold | a10003d | 2017-08-23 13:46:33 -0700 | [diff] [blame] | 164 | public String getRemoteAddress() { |
| 165 | return mRemoteAddress; |
Nathan Harold | 330e108 | 2017-01-12 18:38:57 -0800 | [diff] [blame] | 166 | } |
| 167 | |
Nathan Harold | 93962f3 | 2017-03-07 13:23:36 -0800 | [diff] [blame] | 168 | public IpSecAlgorithm getEncryption(int direction) { |
Nathan Harold | a10003d | 2017-08-23 13:46:33 -0700 | [diff] [blame] | 169 | return mFlow[direction].mEncryption; |
Nathan Harold | 330e108 | 2017-01-12 18:38:57 -0800 | [diff] [blame] | 170 | } |
| 171 | |
Nathan Harold | 93962f3 | 2017-03-07 13:23:36 -0800 | [diff] [blame] | 172 | public IpSecAlgorithm getAuthentication(int direction) { |
Nathan Harold | a10003d | 2017-08-23 13:46:33 -0700 | [diff] [blame] | 173 | return mFlow[direction].mAuthentication; |
Nathan Harold | 330e108 | 2017-01-12 18:38:57 -0800 | [diff] [blame] | 174 | } |
| 175 | |
Benedict Wong | 0febe5e | 2017-08-22 21:42:33 -0700 | [diff] [blame] | 176 | public IpSecAlgorithm getAuthenticatedEncryption(int direction) { |
| 177 | return mFlow[direction].mAuthenticatedEncryption; |
| 178 | } |
| 179 | |
Nathan Harold | 93962f3 | 2017-03-07 13:23:36 -0800 | [diff] [blame] | 180 | public Network getNetwork() { |
Nathan Harold | a10003d | 2017-08-23 13:46:33 -0700 | [diff] [blame] | 181 | return mNetwork; |
Nathan Harold | 330e108 | 2017-01-12 18:38:57 -0800 | [diff] [blame] | 182 | } |
| 183 | |
| 184 | public int getEncapType() { |
Nathan Harold | a10003d | 2017-08-23 13:46:33 -0700 | [diff] [blame] | 185 | return mEncapType; |
Nathan Harold | 330e108 | 2017-01-12 18:38:57 -0800 | [diff] [blame] | 186 | } |
| 187 | |
Nathan Harold | a10003d | 2017-08-23 13:46:33 -0700 | [diff] [blame] | 188 | public int getEncapSocketResourceId() { |
| 189 | return mEncapSocketResourceId; |
Nathan Harold | 330e108 | 2017-01-12 18:38:57 -0800 | [diff] [blame] | 190 | } |
| 191 | |
| 192 | public int getEncapRemotePort() { |
Nathan Harold | a10003d | 2017-08-23 13:46:33 -0700 | [diff] [blame] | 193 | return mEncapRemotePort; |
Nathan Harold | 330e108 | 2017-01-12 18:38:57 -0800 | [diff] [blame] | 194 | } |
| 195 | |
Nathan Harold | 93962f3 | 2017-03-07 13:23:36 -0800 | [diff] [blame] | 196 | public int getNattKeepaliveInterval() { |
Nathan Harold | a10003d | 2017-08-23 13:46:33 -0700 | [diff] [blame] | 197 | return mNattKeepaliveInterval; |
Nathan Harold | 330e108 | 2017-01-12 18:38:57 -0800 | [diff] [blame] | 198 | } |
| 199 | |
Nathan Harold | 330e108 | 2017-01-12 18:38:57 -0800 | [diff] [blame] | 200 | // Parcelable Methods |
| 201 | |
| 202 | @Override |
| 203 | public int describeContents() { |
| 204 | return 0; |
| 205 | } |
| 206 | |
| 207 | @Override |
| 208 | public void writeToParcel(Parcel out, int flags) { |
Nathan Harold | a10003d | 2017-08-23 13:46:33 -0700 | [diff] [blame] | 209 | out.writeInt(mMode); |
| 210 | out.writeString(mLocalAddress); |
| 211 | out.writeString(mRemoteAddress); |
| 212 | out.writeParcelable(mNetwork, flags); |
| 213 | out.writeInt(mFlow[IpSecTransform.DIRECTION_IN].mSpiResourceId); |
| 214 | out.writeParcelable(mFlow[IpSecTransform.DIRECTION_IN].mEncryption, flags); |
| 215 | out.writeParcelable(mFlow[IpSecTransform.DIRECTION_IN].mAuthentication, flags); |
Benedict Wong | 0febe5e | 2017-08-22 21:42:33 -0700 | [diff] [blame] | 216 | out.writeParcelable(mFlow[IpSecTransform.DIRECTION_IN].mAuthenticatedEncryption, flags); |
Nathan Harold | a10003d | 2017-08-23 13:46:33 -0700 | [diff] [blame] | 217 | out.writeInt(mFlow[IpSecTransform.DIRECTION_OUT].mSpiResourceId); |
| 218 | out.writeParcelable(mFlow[IpSecTransform.DIRECTION_OUT].mEncryption, flags); |
| 219 | out.writeParcelable(mFlow[IpSecTransform.DIRECTION_OUT].mAuthentication, flags); |
Benedict Wong | 0febe5e | 2017-08-22 21:42:33 -0700 | [diff] [blame] | 220 | out.writeParcelable(mFlow[IpSecTransform.DIRECTION_OUT].mAuthenticatedEncryption, flags); |
Nathan Harold | a10003d | 2017-08-23 13:46:33 -0700 | [diff] [blame] | 221 | out.writeInt(mEncapType); |
| 222 | out.writeInt(mEncapSocketResourceId); |
| 223 | out.writeInt(mEncapRemotePort); |
Nathan Harold | 19ce70b | 2017-09-25 19:33:13 -0700 | [diff] [blame] | 224 | out.writeInt(mNattKeepaliveInterval); |
Nathan Harold | 330e108 | 2017-01-12 18:38:57 -0800 | [diff] [blame] | 225 | } |
| 226 | |
Nathan Harold | a10003d | 2017-08-23 13:46:33 -0700 | [diff] [blame] | 227 | @VisibleForTesting |
| 228 | public IpSecConfig() {} |
Nathan Harold | 330e108 | 2017-01-12 18:38:57 -0800 | [diff] [blame] | 229 | |
| 230 | private IpSecConfig(Parcel in) { |
Nathan Harold | a10003d | 2017-08-23 13:46:33 -0700 | [diff] [blame] | 231 | mMode = in.readInt(); |
| 232 | mLocalAddress = in.readString(); |
| 233 | mRemoteAddress = in.readString(); |
| 234 | mNetwork = (Network) in.readParcelable(Network.class.getClassLoader()); |
| 235 | mFlow[IpSecTransform.DIRECTION_IN].mSpiResourceId = in.readInt(); |
| 236 | mFlow[IpSecTransform.DIRECTION_IN].mEncryption = |
Nathan Harold | 330e108 | 2017-01-12 18:38:57 -0800 | [diff] [blame] | 237 | (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader()); |
Nathan Harold | a10003d | 2017-08-23 13:46:33 -0700 | [diff] [blame] | 238 | mFlow[IpSecTransform.DIRECTION_IN].mAuthentication = |
Nathan Harold | 330e108 | 2017-01-12 18:38:57 -0800 | [diff] [blame] | 239 | (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader()); |
Benedict Wong | 0febe5e | 2017-08-22 21:42:33 -0700 | [diff] [blame] | 240 | mFlow[IpSecTransform.DIRECTION_IN].mAuthenticatedEncryption = |
| 241 | (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader()); |
Nathan Harold | a10003d | 2017-08-23 13:46:33 -0700 | [diff] [blame] | 242 | mFlow[IpSecTransform.DIRECTION_OUT].mSpiResourceId = in.readInt(); |
| 243 | mFlow[IpSecTransform.DIRECTION_OUT].mEncryption = |
Nathan Harold | 330e108 | 2017-01-12 18:38:57 -0800 | [diff] [blame] | 244 | (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader()); |
Nathan Harold | a10003d | 2017-08-23 13:46:33 -0700 | [diff] [blame] | 245 | mFlow[IpSecTransform.DIRECTION_OUT].mAuthentication = |
Nathan Harold | 330e108 | 2017-01-12 18:38:57 -0800 | [diff] [blame] | 246 | (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader()); |
Benedict Wong | 0febe5e | 2017-08-22 21:42:33 -0700 | [diff] [blame] | 247 | mFlow[IpSecTransform.DIRECTION_OUT].mAuthenticatedEncryption = |
| 248 | (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader()); |
Nathan Harold | a10003d | 2017-08-23 13:46:33 -0700 | [diff] [blame] | 249 | mEncapType = in.readInt(); |
| 250 | mEncapSocketResourceId = in.readInt(); |
| 251 | mEncapRemotePort = in.readInt(); |
Nathan Harold | 19ce70b | 2017-09-25 19:33:13 -0700 | [diff] [blame] | 252 | mNattKeepaliveInterval = in.readInt(); |
Nathan Harold | 330e108 | 2017-01-12 18:38:57 -0800 | [diff] [blame] | 253 | } |
| 254 | |
ludi | b0c95b1 | 2017-05-22 10:52:23 -0700 | [diff] [blame] | 255 | @Override |
| 256 | public String toString() { |
| 257 | StringBuilder strBuilder = new StringBuilder(); |
| 258 | strBuilder |
Nathan Harold | a10003d | 2017-08-23 13:46:33 -0700 | [diff] [blame] | 259 | .append("{mMode=") |
| 260 | .append(mMode == IpSecTransform.MODE_TUNNEL ? "TUNNEL" : "TRANSPORT") |
| 261 | .append(", mLocalAddress=") |
| 262 | .append(mLocalAddress) |
| 263 | .append(", mRemoteAddress=") |
| 264 | .append(mRemoteAddress) |
| 265 | .append(", mNetwork=") |
| 266 | .append(mNetwork) |
| 267 | .append(", mEncapType=") |
| 268 | .append(mEncapType) |
| 269 | .append(", mEncapSocketResourceId=") |
| 270 | .append(mEncapSocketResourceId) |
| 271 | .append(", mEncapRemotePort=") |
| 272 | .append(mEncapRemotePort) |
| 273 | .append(", mNattKeepaliveInterval=") |
| 274 | .append(mNattKeepaliveInterval) |
| 275 | .append(", mFlow[OUT]=") |
| 276 | .append(mFlow[IpSecTransform.DIRECTION_OUT]) |
| 277 | .append(", mFlow[IN]=") |
| 278 | .append(mFlow[IpSecTransform.DIRECTION_IN]) |
ludi | b0c95b1 | 2017-05-22 10:52:23 -0700 | [diff] [blame] | 279 | .append("}"); |
| 280 | |
| 281 | return strBuilder.toString(); |
| 282 | } |
| 283 | |
Nathan Harold | 330e108 | 2017-01-12 18:38:57 -0800 | [diff] [blame] | 284 | public static final Parcelable.Creator<IpSecConfig> CREATOR = |
| 285 | new Parcelable.Creator<IpSecConfig>() { |
| 286 | public IpSecConfig createFromParcel(Parcel in) { |
| 287 | return new IpSecConfig(in); |
| 288 | } |
| 289 | |
| 290 | public IpSecConfig[] newArray(int size) { |
| 291 | return new IpSecConfig[size]; |
| 292 | } |
| 293 | }; |
Nathan Harold | 19ce70b | 2017-09-25 19:33:13 -0700 | [diff] [blame] | 294 | |
| 295 | @VisibleForTesting |
Nathan Harold | d6f50b2 | 2017-10-04 12:58:55 -0700 | [diff] [blame] | 296 | /** Equals method used for testing */ |
Nathan Harold | 19ce70b | 2017-09-25 19:33:13 -0700 | [diff] [blame] | 297 | public static boolean equals(IpSecConfig lhs, IpSecConfig rhs) { |
| 298 | if (lhs == null || rhs == null) return (lhs == rhs); |
| 299 | return (lhs.mMode == rhs.mMode |
| 300 | && lhs.mLocalAddress.equals(rhs.mLocalAddress) |
| 301 | && lhs.mRemoteAddress.equals(rhs.mRemoteAddress) |
| 302 | && ((lhs.mNetwork != null && lhs.mNetwork.equals(rhs.mNetwork)) |
| 303 | || (lhs.mNetwork == rhs.mNetwork)) |
| 304 | && lhs.mEncapType == rhs.mEncapType |
| 305 | && lhs.mEncapSocketResourceId == rhs.mEncapSocketResourceId |
| 306 | && lhs.mEncapRemotePort == rhs.mEncapRemotePort |
| 307 | && lhs.mNattKeepaliveInterval == rhs.mNattKeepaliveInterval |
| 308 | && IpSecConfig.Flow.equals(lhs.mFlow[IpSecTransform.DIRECTION_OUT], |
| 309 | rhs.mFlow[IpSecTransform.DIRECTION_OUT]) |
| 310 | && IpSecConfig.Flow.equals(lhs.mFlow[IpSecTransform.DIRECTION_IN], |
| 311 | rhs.mFlow[IpSecTransform.DIRECTION_IN])); |
| 312 | } |
Nathan Harold | 330e108 | 2017-01-12 18:38:57 -0800 | [diff] [blame] | 313 | } |