• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     /**
71      * A feature flag to avoid advertising empty TXT records, as per RFC 6763 6.1.
72      */
73     public static final String NSD_AVOID_ADVERTISING_EMPTY_TXT_RECORDS =
74             "nsd_avoid_advertising_empty_txt_records";
75 
76     /**
77      * A feature flag to control whether the cached services removal should be enabled.
78      * The removal will be triggered if the retention time has elapsed after all listeners have been
79      * unregistered from the service type client or the interface has been destroyed.
80      */
81     public static final String NSD_CACHED_SERVICES_REMOVAL = "nsd_cached_services_removal";
82 
83     /**
84      * A feature flag to control whether to use shorter (16 characters + .local) hostnames, instead
85      * of Android_[32 characters] hostnames.
86      */
87     public static final String NSD_USE_SHORT_HOSTNAMES = "nsd_use_short_hostnames";
88 
89     /**
90      * A feature flag to control the retention time for cached services.
91      *
92      * <p> Making the retention time configurable allows for testing and future adjustments.
93      */
94     public static final String NSD_CACHED_SERVICES_RETENTION_TIME =
95             "nsd_cached_services_retention_time";
96     public static final int DEFAULT_CACHED_SERVICES_RETENTION_TIME_MILLISECONDS = 10000;
97 
98     /**
99      * A feature flag to control whether the accurate delay callback should be enabled.
100      */
101     public static final String NSD_ACCURATE_DELAY_CALLBACK = "nsd_accurate_delay_callback";
102 
103     // Flag for offload feature
104     public final boolean mIsMdnsOffloadFeatureEnabled;
105 
106     // Flag for including InetAddressRecords in probing questions.
107     public final boolean mIncludeInetAddressRecordsInProbing;
108 
109     // Flag for expired services removal
110     public final boolean mIsExpiredServicesRemovalEnabled;
111 
112     // Flag for label count limit
113     public final boolean mIsLabelCountLimitEnabled;
114 
115     // Flag for known-answer suppression
116     public final boolean mIsKnownAnswerSuppressionEnabled;
117 
118     // Flag to enable replying unicast to queries requesting unicast replies
119     public final boolean mIsUnicastReplyEnabled;
120 
121     // Flag for aggressive query mode
122     public final boolean mIsAggressiveQueryModeEnabled;
123 
124     // Flag for query with known-answer
125     public final boolean mIsQueryWithKnownAnswerEnabled;
126 
127     // Flag for avoiding advertising empty TXT records
128     public final boolean mAvoidAdvertisingEmptyTxtRecords;
129 
130     // Flag for cached services removal
131     public final boolean mIsCachedServicesRemovalEnabled;
132 
133     // Retention Time for cached services
134     public final long mCachedServicesRetentionTime;
135 
136     // Flag for accurate delay callback
137     public final boolean mIsAccurateDelayCallbackEnabled;
138 
139     // Flag to use shorter (16 characters + .local) hostnames
140     public final boolean mIsShortHostnamesEnabled;
141 
142     @Nullable
143     private final FlagOverrideProvider mOverrideProvider;
144 
145     /**
146      * A provider that can indicate whether a flag should be force-enabled for testing purposes.
147      */
148     public interface FlagOverrideProvider {
149         /**
150          * Indicates whether the flag should be force-enabled for testing purposes.
151          */
isForceEnabledForTest(@onNull String flag)152         boolean isForceEnabledForTest(@NonNull String flag);
153 
154 
155         /**
156          * Get the int value of the flag for testing purposes.
157          */
getIntValueForTest(@onNull String flag, int defaultValue)158         int getIntValueForTest(@NonNull String flag, int defaultValue);
159     }
160 
161     /**
162      * Indicates whether the flag should be force-enabled for testing purposes.
163      */
isForceEnabledForTest(@onNull String flag)164     private boolean isForceEnabledForTest(@NonNull String flag) {
165         return mOverrideProvider != null && mOverrideProvider.isForceEnabledForTest(flag);
166     }
167 
168     /**
169      * Get the int value of the flag for testing purposes.
170      *
171      * @return the test int value, or given default value if it is unset or the OverrideProvider
172      * doesn't exist.
173      */
getIntValueForTest(@onNull String flag, int defaultValue)174     private int getIntValueForTest(@NonNull String flag, int defaultValue) {
175         if (mOverrideProvider == null) {
176             return defaultValue;
177         }
178         return mOverrideProvider.getIntValueForTest(flag, defaultValue);
179     }
180 
181     /**
182      * Indicates whether {@link #NSD_UNICAST_REPLY_ENABLED} is enabled, including for testing.
183      */
isUnicastReplyEnabled()184     public boolean isUnicastReplyEnabled() {
185         return mIsUnicastReplyEnabled || isForceEnabledForTest(NSD_UNICAST_REPLY_ENABLED);
186     }
187 
188     /**
189      * Indicates whether {@link #NSD_AGGRESSIVE_QUERY_MODE} is enabled, including for testing.
190      */
isAggressiveQueryModeEnabled()191     public boolean isAggressiveQueryModeEnabled() {
192         return mIsAggressiveQueryModeEnabled || isForceEnabledForTest(NSD_AGGRESSIVE_QUERY_MODE);
193     }
194 
195     /**
196      * Indicates whether {@link #NSD_KNOWN_ANSWER_SUPPRESSION} is enabled, including for testing.
197      */
isKnownAnswerSuppressionEnabled()198     public boolean isKnownAnswerSuppressionEnabled() {
199         return mIsKnownAnswerSuppressionEnabled
200                 || isForceEnabledForTest(NSD_KNOWN_ANSWER_SUPPRESSION);
201     }
202 
203     /**
204      * Indicates whether {@link #NSD_QUERY_WITH_KNOWN_ANSWER} is enabled, including for testing.
205      */
isQueryWithKnownAnswerEnabled()206     public boolean isQueryWithKnownAnswerEnabled() {
207         return mIsQueryWithKnownAnswerEnabled
208                 || isForceEnabledForTest(NSD_QUERY_WITH_KNOWN_ANSWER);
209     }
210 
211     /**
212      * Indicates whether {@link #NSD_AVOID_ADVERTISING_EMPTY_TXT_RECORDS} is enabled, including for
213      * testing.
214      */
avoidAdvertisingEmptyTxtRecords()215     public boolean avoidAdvertisingEmptyTxtRecords() {
216         return mAvoidAdvertisingEmptyTxtRecords
217                 || isForceEnabledForTest(NSD_AVOID_ADVERTISING_EMPTY_TXT_RECORDS);
218     }
219 
220     /**
221      * Indicates whether {@link #NSD_CACHED_SERVICES_REMOVAL} is enabled, including for testing.
222      */
isCachedServicesRemovalEnabled()223     public boolean isCachedServicesRemovalEnabled() {
224         return mIsCachedServicesRemovalEnabled
225                 || isForceEnabledForTest(NSD_CACHED_SERVICES_REMOVAL);
226     }
227 
228     /**
229      * Get the value which is set to {@link #NSD_CACHED_SERVICES_RETENTION_TIME}, including for
230      * testing.
231      */
getCachedServicesRetentionTime()232     public long getCachedServicesRetentionTime() {
233         return getIntValueForTest(
234                 NSD_CACHED_SERVICES_RETENTION_TIME, (int) mCachedServicesRetentionTime);
235     }
236 
isShortHostnamesEnabled()237     public boolean isShortHostnamesEnabled() {
238         return mIsShortHostnamesEnabled || isForceEnabledForTest(NSD_USE_SHORT_HOSTNAMES);
239     }
240 
241     /**
242      * Indicates whether {@link #NSD_ACCURATE_DELAY_CALLBACK} is enabled, including for testing.
243      */
isAccurateDelayCallbackEnabled()244     public boolean isAccurateDelayCallbackEnabled() {
245         return mIsAccurateDelayCallbackEnabled
246                 || isForceEnabledForTest(NSD_ACCURATE_DELAY_CALLBACK);
247     }
248 
249     /**
250      * The constructor for {@link MdnsFeatureFlags}.
251      */
MdnsFeatureFlags(boolean isOffloadFeatureEnabled, boolean includeInetAddressRecordsInProbing, boolean isExpiredServicesRemovalEnabled, boolean isLabelCountLimitEnabled, boolean isKnownAnswerSuppressionEnabled, boolean isUnicastReplyEnabled, boolean isAggressiveQueryModeEnabled, boolean isQueryWithKnownAnswerEnabled, boolean avoidAdvertisingEmptyTxtRecords, boolean isCachedServicesRemovalEnabled, long cachedServicesRetentionTime, boolean isAccurateDelayCallbackEnabled, boolean isShortHostnamesEnabled, @Nullable FlagOverrideProvider overrideProvider)252     public MdnsFeatureFlags(boolean isOffloadFeatureEnabled,
253             boolean includeInetAddressRecordsInProbing,
254             boolean isExpiredServicesRemovalEnabled,
255             boolean isLabelCountLimitEnabled,
256             boolean isKnownAnswerSuppressionEnabled,
257             boolean isUnicastReplyEnabled,
258             boolean isAggressiveQueryModeEnabled,
259             boolean isQueryWithKnownAnswerEnabled,
260             boolean avoidAdvertisingEmptyTxtRecords,
261             boolean isCachedServicesRemovalEnabled,
262             long cachedServicesRetentionTime,
263             boolean isAccurateDelayCallbackEnabled,
264             boolean isShortHostnamesEnabled,
265             @Nullable FlagOverrideProvider overrideProvider) {
266         mIsMdnsOffloadFeatureEnabled = isOffloadFeatureEnabled;
267         mIncludeInetAddressRecordsInProbing = includeInetAddressRecordsInProbing;
268         mIsExpiredServicesRemovalEnabled = isExpiredServicesRemovalEnabled;
269         mIsLabelCountLimitEnabled = isLabelCountLimitEnabled;
270         mIsKnownAnswerSuppressionEnabled = isKnownAnswerSuppressionEnabled;
271         mIsUnicastReplyEnabled = isUnicastReplyEnabled;
272         mIsAggressiveQueryModeEnabled = isAggressiveQueryModeEnabled;
273         mIsQueryWithKnownAnswerEnabled = isQueryWithKnownAnswerEnabled;
274         mAvoidAdvertisingEmptyTxtRecords = avoidAdvertisingEmptyTxtRecords;
275         mIsCachedServicesRemovalEnabled = isCachedServicesRemovalEnabled;
276         mCachedServicesRetentionTime = cachedServicesRetentionTime;
277         mIsAccurateDelayCallbackEnabled = isAccurateDelayCallbackEnabled;
278         mIsShortHostnamesEnabled = isShortHostnamesEnabled;
279         mOverrideProvider = overrideProvider;
280     }
281 
282 
283     /** Returns a {@link Builder} for {@link MdnsFeatureFlags}. */
newBuilder()284     public static Builder newBuilder() {
285         return new Builder();
286     }
287 
288     /** A builder to create {@link MdnsFeatureFlags}. */
289     public static final class Builder {
290 
291         private boolean mIsMdnsOffloadFeatureEnabled;
292         private boolean mIncludeInetAddressRecordsInProbing;
293         private boolean mIsExpiredServicesRemovalEnabled;
294         private boolean mIsLabelCountLimitEnabled;
295         private boolean mIsKnownAnswerSuppressionEnabled;
296         private boolean mIsUnicastReplyEnabled;
297         private boolean mIsAggressiveQueryModeEnabled;
298         private boolean mIsQueryWithKnownAnswerEnabled;
299         private boolean mAvoidAdvertisingEmptyTxtRecords;
300         private boolean mIsCachedServicesRemovalEnabled;
301         private long mCachedServicesRetentionTime;
302         private boolean mIsAccurateDelayCallbackEnabled;
303         private boolean mIsShortHostnamesEnabled;
304         private FlagOverrideProvider mOverrideProvider;
305 
306         /**
307          * The constructor for {@link Builder}.
308          */
Builder()309         public Builder() {
310             mIsMdnsOffloadFeatureEnabled = false;
311             mIncludeInetAddressRecordsInProbing = false;
312             mIsExpiredServicesRemovalEnabled = true; // Default enabled.
313             mIsLabelCountLimitEnabled = true; // Default enabled.
314             mIsKnownAnswerSuppressionEnabled = true; // Default enabled.
315             mIsUnicastReplyEnabled = true; // Default enabled.
316             mIsAggressiveQueryModeEnabled = false;
317             mIsQueryWithKnownAnswerEnabled = false;
318             mAvoidAdvertisingEmptyTxtRecords = true; // Default enabled.
319             mIsCachedServicesRemovalEnabled = true; // Default enabled.
320             mCachedServicesRetentionTime = DEFAULT_CACHED_SERVICES_RETENTION_TIME_MILLISECONDS;
321             mIsAccurateDelayCallbackEnabled = false;
322             mIsShortHostnamesEnabled = true; // Default enabled.
323             mOverrideProvider = null;
324         }
325 
326         /**
327          * Set whether the mDNS offload feature is enabled.
328          *
329          * @see #NSD_FORCE_DISABLE_MDNS_OFFLOAD
330          */
setIsMdnsOffloadFeatureEnabled(boolean isMdnsOffloadFeatureEnabled)331         public Builder setIsMdnsOffloadFeatureEnabled(boolean isMdnsOffloadFeatureEnabled) {
332             mIsMdnsOffloadFeatureEnabled = isMdnsOffloadFeatureEnabled;
333             return this;
334         }
335 
336         /**
337          * Set whether the probing question should include InetAddressRecords.
338          *
339          * @see #INCLUDE_INET_ADDRESS_RECORDS_IN_PROBING
340          */
setIncludeInetAddressRecordsInProbing( boolean includeInetAddressRecordsInProbing)341         public Builder setIncludeInetAddressRecordsInProbing(
342                 boolean includeInetAddressRecordsInProbing) {
343             mIncludeInetAddressRecordsInProbing = includeInetAddressRecordsInProbing;
344             return this;
345         }
346 
347         /**
348          * Set whether the expired services removal is enabled.
349          *
350          * @see #NSD_EXPIRED_SERVICES_REMOVAL
351          */
setIsExpiredServicesRemovalEnabled(boolean isExpiredServicesRemovalEnabled)352         public Builder setIsExpiredServicesRemovalEnabled(boolean isExpiredServicesRemovalEnabled) {
353             mIsExpiredServicesRemovalEnabled = isExpiredServicesRemovalEnabled;
354             return this;
355         }
356 
357         /**
358          * Set whether the label count limit is enabled.
359          *
360          * @see #NSD_LIMIT_LABEL_COUNT
361          */
setIsLabelCountLimitEnabled(boolean isLabelCountLimitEnabled)362         public Builder setIsLabelCountLimitEnabled(boolean isLabelCountLimitEnabled) {
363             mIsLabelCountLimitEnabled = isLabelCountLimitEnabled;
364             return this;
365         }
366 
367         /**
368          * Set whether the known-answer suppression is enabled.
369          *
370          * @see #NSD_KNOWN_ANSWER_SUPPRESSION
371          */
setIsKnownAnswerSuppressionEnabled(boolean isKnownAnswerSuppressionEnabled)372         public Builder setIsKnownAnswerSuppressionEnabled(boolean isKnownAnswerSuppressionEnabled) {
373             mIsKnownAnswerSuppressionEnabled = isKnownAnswerSuppressionEnabled;
374             return this;
375         }
376 
377         /**
378          * Set whether the unicast reply feature is enabled.
379          *
380          * @see #NSD_UNICAST_REPLY_ENABLED
381          */
setIsUnicastReplyEnabled(boolean isUnicastReplyEnabled)382         public Builder setIsUnicastReplyEnabled(boolean isUnicastReplyEnabled) {
383             mIsUnicastReplyEnabled = isUnicastReplyEnabled;
384             return this;
385         }
386 
387         /**
388          * Set a {@link FlagOverrideProvider} to be used by {@link #isForceEnabledForTest(String)}.
389          *
390          * If non-null, features that use {@link #isForceEnabledForTest(String)} will use that
391          * provider to query whether the flag should be force-enabled.
392          */
setOverrideProvider(@ullable FlagOverrideProvider overrideProvider)393         public Builder setOverrideProvider(@Nullable FlagOverrideProvider overrideProvider) {
394             mOverrideProvider = overrideProvider;
395             return this;
396         }
397 
398         /**
399          * Set whether the aggressive query mode is enabled.
400          *
401          * @see #NSD_AGGRESSIVE_QUERY_MODE
402          */
setIsAggressiveQueryModeEnabled(boolean isAggressiveQueryModeEnabled)403         public Builder setIsAggressiveQueryModeEnabled(boolean isAggressiveQueryModeEnabled) {
404             mIsAggressiveQueryModeEnabled = isAggressiveQueryModeEnabled;
405             return this;
406         }
407 
408         /**
409          * Set whether the query with known-answer is enabled.
410          *
411          * @see #NSD_QUERY_WITH_KNOWN_ANSWER
412          */
setIsQueryWithKnownAnswerEnabled(boolean isQueryWithKnownAnswerEnabled)413         public Builder setIsQueryWithKnownAnswerEnabled(boolean isQueryWithKnownAnswerEnabled) {
414             mIsQueryWithKnownAnswerEnabled = isQueryWithKnownAnswerEnabled;
415             return this;
416         }
417 
418         /**
419          * Set whether to avoid advertising empty TXT records.
420          *
421          * @see #NSD_AVOID_ADVERTISING_EMPTY_TXT_RECORDS
422          */
setAvoidAdvertisingEmptyTxtRecords(boolean avoidAdvertisingEmptyTxtRecords)423         public Builder setAvoidAdvertisingEmptyTxtRecords(boolean avoidAdvertisingEmptyTxtRecords) {
424             mAvoidAdvertisingEmptyTxtRecords = avoidAdvertisingEmptyTxtRecords;
425             return this;
426         }
427 
428         /**
429          * Set whether the cached services removal is enabled.
430          *
431          * @see #NSD_CACHED_SERVICES_REMOVAL
432          */
setIsCachedServicesRemovalEnabled(boolean isCachedServicesRemovalEnabled)433         public Builder setIsCachedServicesRemovalEnabled(boolean isCachedServicesRemovalEnabled) {
434             mIsCachedServicesRemovalEnabled = isCachedServicesRemovalEnabled;
435             return this;
436         }
437 
438         /**
439          * Set cached services retention time.
440          *
441          * @see #NSD_CACHED_SERVICES_RETENTION_TIME
442          */
setCachedServicesRetentionTime(long cachedServicesRetentionTime)443         public Builder setCachedServicesRetentionTime(long cachedServicesRetentionTime) {
444             mCachedServicesRetentionTime = cachedServicesRetentionTime;
445             return this;
446         }
447 
448         /**
449          * Set whether the accurate delay callback is enabled.
450          *
451          * @see #NSD_ACCURATE_DELAY_CALLBACK
452          */
setIsAccurateDelayCallbackEnabled(boolean isAccurateDelayCallbackEnabled)453         public Builder setIsAccurateDelayCallbackEnabled(boolean isAccurateDelayCallbackEnabled) {
454             mIsAccurateDelayCallbackEnabled = isAccurateDelayCallbackEnabled;
455             return this;
456         }
457 
458         /**
459          * Set whether the short hostnames feature is enabled.
460          *
461          * @see #NSD_USE_SHORT_HOSTNAMES
462          */
setIsShortHostnamesEnabled(boolean isShortHostnamesEnabled)463         public Builder setIsShortHostnamesEnabled(boolean isShortHostnamesEnabled) {
464             mIsShortHostnamesEnabled = isShortHostnamesEnabled;
465             return this;
466         }
467 
468         /**
469          * Builds a {@link MdnsFeatureFlags} with the arguments supplied to this builder.
470          */
build()471         public MdnsFeatureFlags build() {
472             return new MdnsFeatureFlags(mIsMdnsOffloadFeatureEnabled,
473                     mIncludeInetAddressRecordsInProbing,
474                     mIsExpiredServicesRemovalEnabled,
475                     mIsLabelCountLimitEnabled,
476                     mIsKnownAnswerSuppressionEnabled,
477                     mIsUnicastReplyEnabled,
478                     mIsAggressiveQueryModeEnabled,
479                     mIsQueryWithKnownAnswerEnabled,
480                     mAvoidAdvertisingEmptyTxtRecords,
481                     mIsCachedServicesRemovalEnabled,
482                     mCachedServicesRetentionTime,
483                     mIsAccurateDelayCallbackEnabled,
484                     mIsShortHostnamesEnabled,
485                     mOverrideProvider);
486         }
487     }
488 }
489