1 /* 2 * Copyright (C) 2021 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 com.android.server.connectivity.mdns; 17 18 import android.annotation.NonNull; 19 import android.annotation.Nullable; 20 21 /** 22 * The class that contains mDNS feature flags; 23 */ 24 public class MdnsFeatureFlags { 25 /** 26 * A feature flag to control whether the mDNS offload is enabled or not. 27 */ 28 public static final String NSD_FORCE_DISABLE_MDNS_OFFLOAD = "nsd_force_disable_mdns_offload"; 29 30 /** 31 * A feature flag to control whether the probing question should include 32 * InetAddressRecords or not. 33 */ 34 public static final String INCLUDE_INET_ADDRESS_RECORDS_IN_PROBING = 35 "include_inet_address_records_in_probing"; 36 /** 37 * A feature flag to control whether expired services removal should be enabled. 38 */ 39 public static final String NSD_EXPIRED_SERVICES_REMOVAL = 40 "nsd_expired_services_removal"; 41 42 /** 43 * A feature flag to control whether the label count limit should be enabled. 44 */ 45 public static final String NSD_LIMIT_LABEL_COUNT = "nsd_limit_label_count"; 46 47 /** 48 * A feature flag to control whether the known-answer suppression should be enabled. 49 */ 50 public static final String NSD_KNOWN_ANSWER_SUPPRESSION = "nsd_known_answer_suppression"; 51 52 /** 53 * A feature flag to control whether unicast replies should be enabled. 54 * 55 * <p>Enabling this feature causes replies to queries with the Query Unicast (QU) flag set to be 56 * sent unicast instead of multicast, as per RFC6762 5.4. 57 */ 58 public static final String NSD_UNICAST_REPLY_ENABLED = "nsd_unicast_reply_enabled"; 59 60 /** 61 * A feature flag to control whether the aggressive query mode should be enabled. 62 */ 63 public static final String NSD_AGGRESSIVE_QUERY_MODE = "nsd_aggressive_query_mode"; 64 65 /** 66 * A feature flag to control whether the query with known-answer should be enabled. 67 */ 68 public static final String NSD_QUERY_WITH_KNOWN_ANSWER = "nsd_query_with_known_answer"; 69 70 // Flag for offload feature 71 public final boolean mIsMdnsOffloadFeatureEnabled; 72 73 // Flag for including InetAddressRecords in probing questions. 74 public final boolean mIncludeInetAddressRecordsInProbing; 75 76 // Flag for expired services removal 77 public final boolean mIsExpiredServicesRemovalEnabled; 78 79 // Flag for label count limit 80 public final boolean mIsLabelCountLimitEnabled; 81 82 // Flag for known-answer suppression 83 public final boolean mIsKnownAnswerSuppressionEnabled; 84 85 // Flag to enable replying unicast to queries requesting unicast replies 86 public final boolean mIsUnicastReplyEnabled; 87 88 // Flag for aggressive query mode 89 public final boolean mIsAggressiveQueryModeEnabled; 90 91 // Flag for query with known-answer 92 public final boolean mIsQueryWithKnownAnswerEnabled; 93 94 @Nullable 95 private final FlagOverrideProvider mOverrideProvider; 96 97 /** 98 * A provider that can indicate whether a flag should be force-enabled for testing purposes. 99 */ 100 public interface FlagOverrideProvider { 101 /** 102 * Indicates whether the flag should be force-enabled for testing purposes. 103 */ isForceEnabledForTest(@onNull String flag)104 boolean isForceEnabledForTest(@NonNull String flag); 105 } 106 107 /** 108 * Indicates whether the flag should be force-enabled for testing purposes. 109 */ isForceEnabledForTest(@onNull String flag)110 private boolean isForceEnabledForTest(@NonNull String flag) { 111 return mOverrideProvider != null && mOverrideProvider.isForceEnabledForTest(flag); 112 } 113 114 /** 115 * Indicates whether {@link #NSD_UNICAST_REPLY_ENABLED} is enabled, including for testing. 116 */ isUnicastReplyEnabled()117 public boolean isUnicastReplyEnabled() { 118 return mIsUnicastReplyEnabled || isForceEnabledForTest(NSD_UNICAST_REPLY_ENABLED); 119 } 120 121 /** 122 * Indicates whether {@link #NSD_AGGRESSIVE_QUERY_MODE} is enabled, including for testing. 123 */ isAggressiveQueryModeEnabled()124 public boolean isAggressiveQueryModeEnabled() { 125 return mIsAggressiveQueryModeEnabled || isForceEnabledForTest(NSD_AGGRESSIVE_QUERY_MODE); 126 } 127 128 /** 129 * Indicates whether {@link #NSD_KNOWN_ANSWER_SUPPRESSION} is enabled, including for testing. 130 */ isKnownAnswerSuppressionEnabled()131 public boolean isKnownAnswerSuppressionEnabled() { 132 return mIsKnownAnswerSuppressionEnabled 133 || isForceEnabledForTest(NSD_KNOWN_ANSWER_SUPPRESSION); 134 } 135 136 /** 137 * Indicates whether {@link #NSD_QUERY_WITH_KNOWN_ANSWER} is enabled, including for testing. 138 */ isQueryWithKnownAnswerEnabled()139 public boolean isQueryWithKnownAnswerEnabled() { 140 return mIsQueryWithKnownAnswerEnabled 141 || isForceEnabledForTest(NSD_QUERY_WITH_KNOWN_ANSWER); 142 } 143 144 /** 145 * The constructor for {@link MdnsFeatureFlags}. 146 */ MdnsFeatureFlags(boolean isOffloadFeatureEnabled, boolean includeInetAddressRecordsInProbing, boolean isExpiredServicesRemovalEnabled, boolean isLabelCountLimitEnabled, boolean isKnownAnswerSuppressionEnabled, boolean isUnicastReplyEnabled, boolean isAggressiveQueryModeEnabled, boolean isQueryWithKnownAnswerEnabled, @Nullable FlagOverrideProvider overrideProvider)147 public MdnsFeatureFlags(boolean isOffloadFeatureEnabled, 148 boolean includeInetAddressRecordsInProbing, 149 boolean isExpiredServicesRemovalEnabled, 150 boolean isLabelCountLimitEnabled, 151 boolean isKnownAnswerSuppressionEnabled, 152 boolean isUnicastReplyEnabled, 153 boolean isAggressiveQueryModeEnabled, 154 boolean isQueryWithKnownAnswerEnabled, 155 @Nullable FlagOverrideProvider overrideProvider) { 156 mIsMdnsOffloadFeatureEnabled = isOffloadFeatureEnabled; 157 mIncludeInetAddressRecordsInProbing = includeInetAddressRecordsInProbing; 158 mIsExpiredServicesRemovalEnabled = isExpiredServicesRemovalEnabled; 159 mIsLabelCountLimitEnabled = isLabelCountLimitEnabled; 160 mIsKnownAnswerSuppressionEnabled = isKnownAnswerSuppressionEnabled; 161 mIsUnicastReplyEnabled = isUnicastReplyEnabled; 162 mIsAggressiveQueryModeEnabled = isAggressiveQueryModeEnabled; 163 mIsQueryWithKnownAnswerEnabled = isQueryWithKnownAnswerEnabled; 164 mOverrideProvider = overrideProvider; 165 } 166 167 168 /** Returns a {@link Builder} for {@link MdnsFeatureFlags}. */ newBuilder()169 public static Builder newBuilder() { 170 return new Builder(); 171 } 172 173 /** A builder to create {@link MdnsFeatureFlags}. */ 174 public static final class Builder { 175 176 private boolean mIsMdnsOffloadFeatureEnabled; 177 private boolean mIncludeInetAddressRecordsInProbing; 178 private boolean mIsExpiredServicesRemovalEnabled; 179 private boolean mIsLabelCountLimitEnabled; 180 private boolean mIsKnownAnswerSuppressionEnabled; 181 private boolean mIsUnicastReplyEnabled; 182 private boolean mIsAggressiveQueryModeEnabled; 183 private boolean mIsQueryWithKnownAnswerEnabled; 184 private FlagOverrideProvider mOverrideProvider; 185 186 /** 187 * The constructor for {@link Builder}. 188 */ Builder()189 public Builder() { 190 mIsMdnsOffloadFeatureEnabled = false; 191 mIncludeInetAddressRecordsInProbing = false; 192 mIsExpiredServicesRemovalEnabled = true; // Default enabled. 193 mIsLabelCountLimitEnabled = true; // Default enabled. 194 mIsKnownAnswerSuppressionEnabled = true; // Default enabled. 195 mIsUnicastReplyEnabled = true; // Default enabled. 196 mIsAggressiveQueryModeEnabled = false; 197 mIsQueryWithKnownAnswerEnabled = false; 198 mOverrideProvider = null; 199 } 200 201 /** 202 * Set whether the mDNS offload feature is enabled. 203 * 204 * @see #NSD_FORCE_DISABLE_MDNS_OFFLOAD 205 */ setIsMdnsOffloadFeatureEnabled(boolean isMdnsOffloadFeatureEnabled)206 public Builder setIsMdnsOffloadFeatureEnabled(boolean isMdnsOffloadFeatureEnabled) { 207 mIsMdnsOffloadFeatureEnabled = isMdnsOffloadFeatureEnabled; 208 return this; 209 } 210 211 /** 212 * Set whether the probing question should include InetAddressRecords. 213 * 214 * @see #INCLUDE_INET_ADDRESS_RECORDS_IN_PROBING 215 */ setIncludeInetAddressRecordsInProbing( boolean includeInetAddressRecordsInProbing)216 public Builder setIncludeInetAddressRecordsInProbing( 217 boolean includeInetAddressRecordsInProbing) { 218 mIncludeInetAddressRecordsInProbing = includeInetAddressRecordsInProbing; 219 return this; 220 } 221 222 /** 223 * Set whether the expired services removal is enabled. 224 * 225 * @see #NSD_EXPIRED_SERVICES_REMOVAL 226 */ setIsExpiredServicesRemovalEnabled(boolean isExpiredServicesRemovalEnabled)227 public Builder setIsExpiredServicesRemovalEnabled(boolean isExpiredServicesRemovalEnabled) { 228 mIsExpiredServicesRemovalEnabled = isExpiredServicesRemovalEnabled; 229 return this; 230 } 231 232 /** 233 * Set whether the label count limit is enabled. 234 * 235 * @see #NSD_LIMIT_LABEL_COUNT 236 */ setIsLabelCountLimitEnabled(boolean isLabelCountLimitEnabled)237 public Builder setIsLabelCountLimitEnabled(boolean isLabelCountLimitEnabled) { 238 mIsLabelCountLimitEnabled = isLabelCountLimitEnabled; 239 return this; 240 } 241 242 /** 243 * Set whether the known-answer suppression is enabled. 244 * 245 * @see #NSD_KNOWN_ANSWER_SUPPRESSION 246 */ setIsKnownAnswerSuppressionEnabled(boolean isKnownAnswerSuppressionEnabled)247 public Builder setIsKnownAnswerSuppressionEnabled(boolean isKnownAnswerSuppressionEnabled) { 248 mIsKnownAnswerSuppressionEnabled = isKnownAnswerSuppressionEnabled; 249 return this; 250 } 251 252 /** 253 * Set whether the unicast reply feature is enabled. 254 * 255 * @see #NSD_UNICAST_REPLY_ENABLED 256 */ setIsUnicastReplyEnabled(boolean isUnicastReplyEnabled)257 public Builder setIsUnicastReplyEnabled(boolean isUnicastReplyEnabled) { 258 mIsUnicastReplyEnabled = isUnicastReplyEnabled; 259 return this; 260 } 261 262 /** 263 * Set a {@link FlagOverrideProvider} to be used by {@link #isForceEnabledForTest(String)}. 264 * 265 * If non-null, features that use {@link #isForceEnabledForTest(String)} will use that 266 * provider to query whether the flag should be force-enabled. 267 */ setOverrideProvider(@ullable FlagOverrideProvider overrideProvider)268 public Builder setOverrideProvider(@Nullable FlagOverrideProvider overrideProvider) { 269 mOverrideProvider = overrideProvider; 270 return this; 271 } 272 273 /** 274 * Set whether the aggressive query mode is enabled. 275 * 276 * @see #NSD_AGGRESSIVE_QUERY_MODE 277 */ setIsAggressiveQueryModeEnabled(boolean isAggressiveQueryModeEnabled)278 public Builder setIsAggressiveQueryModeEnabled(boolean isAggressiveQueryModeEnabled) { 279 mIsAggressiveQueryModeEnabled = isAggressiveQueryModeEnabled; 280 return this; 281 } 282 283 /** 284 * Set whether the query with known-answer is enabled. 285 * 286 * @see #NSD_QUERY_WITH_KNOWN_ANSWER 287 */ setIsQueryWithKnownAnswerEnabled(boolean isQueryWithKnownAnswerEnabled)288 public Builder setIsQueryWithKnownAnswerEnabled(boolean isQueryWithKnownAnswerEnabled) { 289 mIsQueryWithKnownAnswerEnabled = isQueryWithKnownAnswerEnabled; 290 return this; 291 } 292 293 /** 294 * Builds a {@link MdnsFeatureFlags} with the arguments supplied to this builder. 295 */ build()296 public MdnsFeatureFlags build() { 297 return new MdnsFeatureFlags(mIsMdnsOffloadFeatureEnabled, 298 mIncludeInetAddressRecordsInProbing, 299 mIsExpiredServicesRemovalEnabled, 300 mIsLabelCountLimitEnabled, 301 mIsKnownAnswerSuppressionEnabled, 302 mIsUnicastReplyEnabled, 303 mIsAggressiveQueryModeEnabled, 304 mIsQueryWithKnownAnswerEnabled, 305 mOverrideProvider); 306 } 307 } 308 } 309