[srp-client] add "service key record inclusion" mode for testing (#6361)

This commit adds support for "service key record inclusion" mode in
SRP client. When enabled, SRP client will include KEY record in
Service Description Instructions in the SRP update messages that it
sends. KEY record is optional in Service Description Instruction (it
is required and always included in the Host Description Instruction).
The default behavior of SRP client is to not include it. This feature
is intended to override the default behavior for testing only and is
is available under the reference device configuration build (i.e.,
when `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` is enabled).

This commit also add a CLI command for this feature as `srp client
service key [enable/disable]` and updates the `README_SRP_CLIENT.md`.

Finally, this commit adds new spinel property for SRP client "service
key record inclusion" mode along with its get/set handlers in NCP
build.
This commit is contained in:
Abtin Keshavarzian
2021-04-01 21:41:24 -07:00
committed by GitHub
parent ab339041fa
commit a2f63e524d
12 changed files with 212 additions and 5 deletions
+1 -1
View File
@@ -53,7 +53,7 @@ extern "C" {
* @note This number versions both OpenThread platform and user APIs.
*
*/
#define OPENTHREAD_API_VERSION (91)
#define OPENTHREAD_API_VERSION (92)
/**
* @addtogroup api-instance
+30
View File
@@ -561,6 +561,36 @@ otError otSrpClientSetDomainName(otInstance *aInstance, const char *aName);
*/
const char *otSrpClientItemStateToString(otSrpClientItemState aItemState);
/**
* This function enables/disables "service key record inclusion" mode.
*
* When enabled, SRP client will include KEY record in Service Description Instructions in the SRP update messages
* that it sends.
*
* This function is available when `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` configuration is enabled.
*
* @note KEY record is optional in Service Description Instruction (it is required and always included in the Host
* Description Instruction). The default behavior of SRP client is to not include it. This function is intended to
* override the default behavior for testing only.
*
* @param[in] aInstance A pointer to the OpenThread instance.
* @param[in] aEnabled TRUE to enable, FALSE to disable the "service key record inclusion" mode.
*
*/
void otSrpClientSetServiceKeyRecordEnabled(otInstance *aInstance, bool aEnabled);
/**
* This method indicates whether the "service key record inclusion" mode is enabled or disabled.
*
* This function is available when `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` configuration is enabled.
*
* @param[in] aInstance A pointer to the OpenThread instance.
*
* @returns TRUE if "service key record inclusion" mode is enabled, FALSE otherwise.
*
*/
bool otSrpClientIsServiceKeyRecordEnabled(otInstance *aInstance);
/**
* @}
*
+27
View File
@@ -328,6 +328,33 @@ Remove a service with a give instance name and service name.
Done
```
### service key
Usage `srp client service key [enable|disable]`
Enable/Disable "service key record inclusion" mode in SRP client. This command requires `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` feature to be enabled.
KEY record is optional in Service Description Instruction (it is required and always included in the Host Description Instruction). The default behavior of SRP client is to not include it. This command is intended to override the default behavior for testing only (in a `REFERENCE_DEVICE` build).
Get the current "service key record inclusion" mode.
```bash
> srp client service key
Disabled
Done
```
Set the "service key record inclusion" mode.
```bash
> srp client service key enable
Done
> srp client service key
Enabled
Done
```
### start
Usage: `srp client start <serveraddr> <serverport>`
+31
View File
@@ -383,6 +383,37 @@ otError SrpClient::ProcessService(uint8_t aArgsLength, char *aArgs[])
error = otSrpClientRemoveService(mInterpreter.mInstance, const_cast<otSrpClientService *>(service));
}
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
else if (strcmp(aArgs[0], "key") == 0)
{
// `key [enable/disable]`
bool enable;
if (aArgsLength == 1)
{
mInterpreter.OutputEnabledDisabledStatus(otSrpClientIsServiceKeyRecordEnabled(mInterpreter.mInstance));
ExitNow();
}
VerifyOrExit(aArgsLength == 2, error = OT_ERROR_INVALID_ARGS);
if (strcmp(aArgs[1], "enable") == 0)
{
enable = true;
}
else if (strcmp(aArgs[1], "disable") == 0)
{
enable = false;
}
else
{
ExitNow(error = OT_ERROR_INVALID_COMMAND);
}
otSrpClientSetServiceKeyRecordEnabled(mInterpreter.mInstance, enable);
}
#endif // OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
else
{
error = OT_ERROR_INVALID_COMMAND;
+16
View File
@@ -209,4 +209,20 @@ const char *otSrpClientItemStateToString(otSrpClientItemState aItemState)
return Srp::Client::ItemStateToString(static_cast<Srp::Client::ItemState>(aItemState));
}
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
void otSrpClientSetServiceKeyRecordEnabled(otInstance *aInstance, bool aEnabled)
{
Instance &instance = *static_cast<Instance *>(aInstance);
instance.Get<Srp::Client>().SetServiceKeyRecordEnabled(aEnabled);
}
bool otSrpClientIsServiceKeyRecordEnabled(otInstance *aInstance)
{
Instance &instance = *static_cast<Instance *>(aInstance);
return instance.Get<Srp::Client>().IsServiceKeyRecordEnabled();
}
#endif
#endif // OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
+29 -4
View File
@@ -140,6 +140,9 @@ Client::Client(Instance &aInstance)
#if OPENTHREAD_CONFIG_SRP_CLIENT_AUTO_START_API_ENABLE
, mAutoStartModeEnabled(kAutoStartDefaultMode)
, mAutoStartDidSelectServer(false)
#endif
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
, mServiceKeyRecordEnabled(false)
#endif
, mUpdateMessageId(0)
, mRetryWaitInterval(kMinRetryWaitInterval)
@@ -810,16 +813,26 @@ Error Client::AppendServiceInstructions(Service &aService, Message &aMessage, In
UpdateRecordLengthInMessage(rr, offset, aMessage);
aInfo.mRecordCount++;
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
if (mServiceKeyRecordEnabled)
{
// KEY RR is optional in "Service Description Instruction". It
// is added here under `REFERENCE_DEVICE` config and is intended
// for testing only.
SuccessOrExit(error = Dns::Name::AppendPointerLabel(instanceNameOffset, aMessage));
SuccessOrExit(error = AppendKeyRecord(aMessage, aInfo));
}
#endif
exit:
return error;
}
Error Client::AppendHostDescriptionInstruction(Message &aMessage, Info &aInfo) const
{
Error error = kErrorNone;
Dns::ResourceRecord rr;
Dns::KeyRecord key;
Crypto::Ecdsa::P256::PublicKey publicKey;
Error error = kErrorNone;
Dns::ResourceRecord rr;
//----------------------------------
// Host Description Instruction
@@ -847,6 +860,18 @@ Error Client::AppendHostDescriptionInstruction(Message &aMessage, Info &aInfo) c
// KEY RR
SuccessOrExit(error = AppendHostName(aMessage, aInfo));
SuccessOrExit(error = AppendKeyRecord(aMessage, aInfo));
exit:
return error;
}
Error Client::AppendKeyRecord(Message &aMessage, Info &aInfo) const
{
Error error;
Dns::KeyRecord key;
Crypto::Ecdsa::P256::PublicKey publicKey;
key.Init();
key.SetTtl(mLeaseInterval);
key.SetFlags(Dns::KeyRecord::kAuthConfidPermitted, Dns::KeyRecord::kOwnerNonZone,
+29
View File
@@ -572,6 +572,31 @@ public:
*/
static const char *ItemStateToString(ItemState aState);
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
/**
* This method enables/disables "service key record inclusion" mode.
*
* When enabled, SRP client will include KEY record in Service Description Instructions in the SRP update messages
* that it sends.
*
* @note KEY record is optional in Service Description Instruction (it is required and always included in the Host
* Description Instruction). The default behavior of SRP client is to not include it. This method is added under
* `REFERENCE_DEVICE` config and is intended to override the default behavior for testing only.
*
* @param[in] aEnabled TRUE to enable, FALSE to disable the "service key record inclusion" mode.
*
*/
void SetServiceKeyRecordEnabled(bool aEnabled) { mServiceKeyRecordEnabled = aEnabled; }
/**
* This method indicates whether the "service key record inclusion" mode is enabled or disabled.
*
* @returns TRUE if "service key record inclusion" mode is enabled, FALSE otherwise.
*
*/
bool IsServiceKeyRecordEnabled(void) const { return mServiceKeyRecordEnabled; }
#endif // OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
private:
enum : uint8_t
{
@@ -726,6 +751,7 @@ private:
Error ReadOrGenerateKey(Crypto::Ecdsa::P256::KeyPair &aKeyPair);
Error AppendServiceInstructions(Service &aService, Message &aMessage, Info &aInfo);
Error AppendHostDescriptionInstruction(Message &aMessage, Info &aInfo) const;
Error AppendKeyRecord(Message &aMessage, Info &aInfo) const;
Error AppendDeleteAllRrsets(Message &aMessage) const;
Error AppendHostName(Message &aMessage, Info &aInfo, bool aDoNotCompress = false) const;
Error AppendUpdateLeaseOptRecord(Message &aMessage) const;
@@ -767,6 +793,9 @@ private:
bool mAutoStartModeEnabled : 1;
bool mAutoStartDidSelectServer : 1;
#endif
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
bool mServiceKeyRecordEnabled : 1;
#endif
uint16_t mUpdateMessageId;
uint32_t mRetryWaitInterval;
+3
View File
@@ -1412,6 +1412,7 @@ const char *spinel_prop_key_to_cstr(spinel_prop_key_t prop_key)
SPINEL_PROP_CSTR(SRP_CLIENT_HOST_SERVICES_REMOVE),
SPINEL_PROP_CSTR(SRP_CLIENT_HOST_SERVICES_CLEAR),
SPINEL_PROP_CSTR(SRP_CLIENT_EVENT),
SPINEL_PROP_CSTR(SRP_CLIENT_SERVICE_KEY_ENABLED),
SPINEL_PROP_CSTR(SERVER_ALLOW_LOCAL_DATA_CHANGE),
SPINEL_PROP_CSTR(SERVER_SERVICES),
SPINEL_PROP_CSTR(SERVER_LEADER_SERVICES),
@@ -1615,6 +1616,8 @@ const char *spinel_capability_to_cstr(spinel_capability_t capability)
SPINEL_CAP_CSTR(MAC_RETRY_HISTOGRAM),
SPINEL_CAP_CSTR(MULTI_RADIO),
SPINEL_CAP_CSTR(SRP_CLIENT),
SPINEL_CAP_CSTR(DUA),
SPINEL_CAP_CSTR(REFERENCE_DEVICE),
SPINEL_CAP_CSTR(ERROR_RATE_TRACKING),
SPINEL_CAP_CSTR(THREAD_COMMISSIONER),
SPINEL_CAP_CSTR(THREAD_TMF_PROXY),
+17
View File
@@ -1205,6 +1205,7 @@ enum
SPINEL_CAP_MULTI_RADIO = (SPINEL_CAP_OPENTHREAD__BEGIN + 13),
SPINEL_CAP_SRP_CLIENT = (SPINEL_CAP_OPENTHREAD__BEGIN + 14),
SPINEL_CAP_DUA = (SPINEL_CAP_OPENTHREAD__BEGIN + 15),
SPINEL_CAP_REFERENCE_DEVICE = (SPINEL_CAP_OPENTHREAD__BEGIN + 16),
SPINEL_CAP_OPENTHREAD__END = 640,
SPINEL_CAP_THREAD__BEGIN = 1024,
@@ -3979,6 +3980,22 @@ enum
*/
SPINEL_PROP_SRP_CLIENT_EVENT = SPINEL_PROP_OPENTHREAD__BEGIN + 26,
/// SRP Client Service Key Inclusion Enabled
/** Format `b` : Read-Write
* Required capability: `SPINEL_CAP_SRP_CLIENT` & `SPINEL_CAP_REFERENCE_DEVICE`.
*
* This boolean property indicates whether the "service key record inclusion" mode is enabled or not.
*
* When enabled, SRP client will include KEY record in Service Description Instructions in the SRP update messages
* that it sends.
*
* KEY record is optional in Service Description Instruction (it is required and always included in the Host
* Description Instruction). The default behavior of SRP client is to not include it. This function is intended to
* override the default behavior for testing only.
*
*/
SPINEL_PROP_SRP_CLIENT_SERVICE_KEY_ENABLED = SPINEL_PROP_OPENTHREAD__BEGIN + 27,
SPINEL_PROP_OPENTHREAD__END = 0x2000,
SPINEL_PROP_SERVER__BEGIN = 0xA0,
+4
View File
@@ -1930,6 +1930,10 @@ template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CAPS>(void)
SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_CAP_DUA));
#endif
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_CAP_REFERENCE_DEVICE));
#endif
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_CAP_THREAD_BACKBONE_ROUTER));
#endif
+6
View File
@@ -359,6 +359,9 @@ NcpBase::PropertyHandler NcpBase::FindGetPropertyHandler(spinel_prop_key_t aKey)
OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_HOST_NAME),
OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_HOST_ADDRESSES),
OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_SERVICES),
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_SERVICE_KEY_ENABLED),
#endif
#endif
#if OPENTHREAD_CONFIG_LEGACY_ENABLE
@@ -604,6 +607,9 @@ NcpBase::PropertyHandler NcpBase::FindSetPropertyHandler(spinel_prop_key_t aKey)
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_HOST_ADDRESSES),
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_HOST_SERVICES_REMOVE),
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_HOST_SERVICES_CLEAR),
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_SERVICE_KEY_ENABLED),
#endif
#endif
#if OPENTHREAD_CONFIG_LEGACY_ENABLE
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_NEST_LEGACY_ULA_PREFIX),
+19
View File
@@ -3833,6 +3833,25 @@ exit:
}
}
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_SRP_CLIENT_SERVICE_KEY_ENABLED>(void)
{
return mEncoder.WriteBool(otSrpClientIsServiceKeyRecordEnabled(mInstance));
}
template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_SRP_CLIENT_SERVICE_KEY_ENABLED>(void)
{
otError error = OT_ERROR_NONE;
bool enabled;
SuccessOrExit(error = mDecoder.ReadBool(enabled));
otSrpClientSetServiceKeyRecordEnabled(mInstance, enabled);
exit:
return error;
}
#endif
#endif // OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
#if OPENTHREAD_CONFIG_LEGACY_ENABLE