Drop dot at the end of service type

The service type that found from NsdManager#discoverServices()
with old backend(mDnsResponder) has an extra dot at the end. And
the previous API accepted both formats, so we need to keep
backwards compatibility with both formats. Thus, drop that extra
dot when constructing the service type for the new backend.

Bug: 266030646
Test: atest FrameoworksNetTests
Change-Id: I987ab866f6a3a7cff654f96978057fdd93b859d6
This commit is contained in:
Paul Hu
2023-03-03 15:14:00 +08:00
parent e4f5f258d6
commit 7445e3dc78
2 changed files with 42 additions and 25 deletions

View File

@@ -496,31 +496,6 @@ public class NsdService extends INsdManager.Stub {
clientInfo.mClientIdForServiceUpdates = 0; clientInfo.mClientIdForServiceUpdates = 0;
} }
/**
* Check the given service type is valid and construct it to a service type
* which can use for discovery / resolution service.
*
* <p> The valid service type should be 2 labels, or 3 labels if the query is for a
* subtype (see RFC6763 7.1). Each label is up to 63 characters and must start with an
* underscore; they are alphanumerical characters or dashes or underscore, except the
* last one that is just alphanumerical. The last label must be _tcp or _udp.
*
* @param serviceType the request service type for discovery / resolution service
* @return constructed service type or null if the given service type is invalid.
*/
@Nullable
private String constructServiceType(String serviceType) {
if (TextUtils.isEmpty(serviceType)) return null;
final Pattern serviceTypePattern = Pattern.compile(
"^(_[a-zA-Z0-9-_]{1,61}[a-zA-Z0-9]\\.)?"
+ "(_[a-zA-Z0-9-_]{1,61}[a-zA-Z0-9]\\._(?:tcp|udp))$");
final Matcher matcher = serviceTypePattern.matcher(serviceType);
if (!matcher.matches()) return null;
return matcher.group(1) == null
? serviceType
: matcher.group(1) + "_sub." + matcher.group(2);
}
/** /**
* Truncate a service name to up to 63 UTF-8 bytes. * Truncate a service name to up to 63 UTF-8 bytes.
@@ -1233,6 +1208,34 @@ public class NsdService extends INsdManager.Stub {
return sb.toString(); return sb.toString();
} }
/**
* Check the given service type is valid and construct it to a service type
* which can use for discovery / resolution service.
*
* <p> The valid service type should be 2 labels, or 3 labels if the query is for a
* subtype (see RFC6763 7.1). Each label is up to 63 characters and must start with an
* underscore; they are alphanumerical characters or dashes or underscore, except the
* last one that is just alphanumerical. The last label must be _tcp or _udp.
*
* @param serviceType the request service type for discovery / resolution service
* @return constructed service type or null if the given service type is invalid.
*/
@Nullable
public static String constructServiceType(String serviceType) {
if (TextUtils.isEmpty(serviceType)) return null;
final Pattern serviceTypePattern = Pattern.compile(
"^(_[a-zA-Z0-9-_]{1,61}[a-zA-Z0-9]\\.)?"
+ "(_[a-zA-Z0-9-_]{1,61}[a-zA-Z0-9]\\._(?:tcp|udp))"
// Drop '.' at the end of service type that is compatible with old backend.
+ "\\.?$");
final Matcher matcher = serviceTypePattern.matcher(serviceType);
if (!matcher.matches()) return null;
return matcher.group(1) == null
? matcher.group(2)
: matcher.group(1) + "_sub." + matcher.group(2);
}
@VisibleForTesting @VisibleForTesting
NsdService(Context ctx, Handler handler, long cleanupDelayMs) { NsdService(Context ctx, Handler handler, long cleanupDelayMs) {
this(ctx, handler, cleanupDelayMs, new Dependencies()); this(ctx, handler, cleanupDelayMs, new Dependencies());

View File

@@ -21,6 +21,7 @@ import static android.net.nsd.NsdManager.FAILURE_BAD_PARAMETERS;
import static android.net.nsd.NsdManager.FAILURE_INTERNAL_ERROR; import static android.net.nsd.NsdManager.FAILURE_INTERNAL_ERROR;
import static android.net.nsd.NsdManager.FAILURE_OPERATION_NOT_RUNNING; import static android.net.nsd.NsdManager.FAILURE_OPERATION_NOT_RUNNING;
import static com.android.server.NsdService.constructServiceType;
import static com.android.testutils.ContextUtils.mockService; import static com.android.testutils.ContextUtils.mockService;
import static libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges; import static libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
@@ -1181,6 +1182,19 @@ public class NsdServiceTest {
verify(mSocketProvider, timeout(CLEANUP_DELAY_MS + TIMEOUT_MS)).requestStopWhenInactive(); verify(mSocketProvider, timeout(CLEANUP_DELAY_MS + TIMEOUT_MS)).requestStopWhenInactive();
} }
@Test
public void testConstructServiceType() {
final String serviceType1 = "test._tcp";
final String serviceType2 = "_test._quic";
final String serviceType3 = "_123._udp.";
final String serviceType4 = "_TEST._999._tcp.";
assertEquals(null, constructServiceType(serviceType1));
assertEquals(null, constructServiceType(serviceType2));
assertEquals("_123._udp", constructServiceType(serviceType3));
assertEquals("_TEST._sub._999._tcp", constructServiceType(serviceType4));
}
private void waitForIdle() { private void waitForIdle() {
HandlerUtils.waitForIdle(mHandler, TIMEOUT_MS); HandlerUtils.waitForIdle(mHandler, TIMEOUT_MS);
} }