/** * This private function is called by ndn_TlvEncoder_writeNestedTlv to write the TLVs in the body of the Selectors value. * @param context This is the ndn_Interest struct pointer which was passed to writeTlv. * @param encoder the ndn_TlvEncoder which is calling this. * @return 0 for success, else an error code. */ static ndn_Error encodeSelectorsValue(const void *context, struct ndn_TlvEncoder *encoder) { struct ndn_Interest *interest = (struct ndn_Interest *)context; ndn_Error error; if ((error = ndn_TlvEncoder_writeOptionalNonNegativeIntegerTlv (encoder, ndn_Tlv_MinSuffixComponents, interest->minSuffixComponents))) return error; if ((error = ndn_TlvEncoder_writeOptionalNonNegativeIntegerTlv (encoder, ndn_Tlv_MaxSuffixComponents, interest->maxSuffixComponents))) return error; if ((error = ndn_TlvEncoder_writeNestedTlv (encoder, ndn_Tlv_PublisherPublicKeyLocator, ndn_encodeTlvKeyLocatorValue, &interest->keyLocator, 1))) return error; if (interest->exclude.nEntries > 0) { if ((error = ndn_TlvEncoder_writeNestedTlv(encoder, ndn_Tlv_Exclude, encodeExcludeValue, &interest->exclude, 0))) return error; } if ((error = ndn_TlvEncoder_writeOptionalNonNegativeIntegerTlv (encoder, ndn_Tlv_ChildSelector, interest->childSelector))) return error; if (interest->mustBeFresh) { if ((error = ndn_TlvEncoder_writeTypeAndLength(encoder, ndn_Tlv_MustBeFresh, 0))) return error; } // else MustBeFresh == false, so nothing to encode. return NDN_ERROR_success; }
/** * This private function is called by ndn_TlvEncoder_writeNestedTlv to write the TLVs in the body of the Data value. * @param context This is the DataValueContext struct pointer which was passed to writeTlv. * @param encoder the ndn_TlvEncoder which is calling this. * @return 0 for success, else an error code. */ static ndn_Error encodeDataValue(const void *context, struct ndn_TlvEncoder *encoder) { const struct DataValueContext *dataValueContext = (const struct DataValueContext *)context; const struct ndn_Data *data = dataValueContext->data; ndn_Error error; size_t dummyBeginOffset, dummyEndOffset; *dataValueContext->signedPortionBeginOffset = encoder->offset; if ((error = ndn_encodeTlvName (&data->name, &dummyBeginOffset, &dummyEndOffset, encoder))) return error; if ((error = ndn_TlvEncoder_writeNestedTlv(encoder, ndn_Tlv_MetaInfo, encodeMetaInfoValue, &data->metaInfo, 0))) return error; if ((error = ndn_TlvEncoder_writeBlobTlv(encoder, ndn_Tlv_Content, &data->content))) return error; if ((error = ndn_encodeTlvSignatureInfo(&data->signature, encoder))) return error; *dataValueContext->signedPortionEndOffset = encoder->offset; if ((error = ndn_TlvEncoder_writeBlobTlv(encoder, ndn_Tlv_SignatureValue, &data->signature.signature))) return error; return NDN_ERROR_success; }
ndn_Error ndn_encodeTlvDelegationSet_Delegation (const struct ndn_DelegationSet_Delegation *delegation, struct ndn_TlvEncoder *encoder) { return ndn_TlvEncoder_writeNestedTlv (encoder, ndn_Tlv_Link_Delegation, encodeDelegationValue, delegation, 0); }
ndn_Error ndn_encodeTlvControlResponse (const struct ndn_ControlResponse *controlResponse, struct ndn_TlvEncoder *encoder) { return ndn_TlvEncoder_writeNestedTlv (encoder, ndn_Tlv_NfdCommand_ControlResponse, encodeControlResponseValue, controlResponse, 0); }
void writeNestedTlv (unsigned int type, ndn_Error (*writeValue)(void *context, struct ndn_TlvEncoder* encoder), void *context, bool omitZeroLength = false) { ndn_Error error; if ((error = ndn_TlvEncoder_writeNestedTlv (this, type, writeValue, context, omitZeroLength ? 1 : 0))) throw std::runtime_error(ndn_getErrorString(error)); }
ndn_Error ndn_encodeTlvSignatureInfo (const struct ndn_Signature *signatureInfo, struct ndn_TlvEncoder *encoder) { if (signatureInfo->type == ndn_SignatureType_Generic) { // Handle a Generic signature separately since it has the entire encoding. const struct ndn_Blob *encoding = &signatureInfo->signatureInfoEncoding; ndn_Error error; size_t endOffset; uint64_t signatureType; // Do a test decoding to sanity check that it is valid TLV. struct ndn_TlvDecoder decoder; ndn_TlvDecoder_initialize(&decoder, encoding->value, encoding->length); error = ndn_TlvDecoder_readNestedTlvsStart (&decoder, ndn_Tlv_SignatureInfo, &endOffset); if (!error) error = ndn_TlvDecoder_readNonNegativeIntegerTlv (&decoder, ndn_Tlv_SignatureType, &signatureType); if (!error) error = ndn_TlvDecoder_finishNestedTlvs(&decoder, endOffset); if (error) return NDN_ERROR_The_Generic_signature_encoding_is_not_a_valid_NDN_TLV_SignatureInfo; return ndn_TlvEncoder_writeArray(encoder, encoding->value, encoding->length); } if (signatureInfo->type == ndn_SignatureType_Sha256WithRsaSignature || signatureInfo->type == ndn_SignatureType_Sha256WithEcdsaSignature || signatureInfo->type == ndn_SignatureType_HmacWithSha256Signature) return ndn_TlvEncoder_writeNestedTlv (encoder, ndn_Tlv_SignatureInfo, encodeSignatureWithKeyLocatorAndValidityPeriodValue, signatureInfo, 0); else if (signatureInfo->type == ndn_SignatureType_DigestSha256Signature) return ndn_TlvEncoder_writeNestedTlv (encoder, ndn_Tlv_SignatureInfo, encodeDigestSha256Value, signatureInfo, 0); else return NDN_ERROR_encodeSignatureInfo_unrecognized_SignatureType; }
ndn_Error ndn_encodeTlvData (const struct ndn_Data *data, size_t *signedPortionBeginOffset, size_t *signedPortionEndOffset, struct ndn_TlvEncoder *encoder) { // Create the context to pass to encodeDataValue. struct DataValueContext dataValueContext; dataValueContext.data = data; dataValueContext.signedPortionBeginOffset = signedPortionBeginOffset; dataValueContext.signedPortionEndOffset = signedPortionEndOffset; return ndn_TlvEncoder_writeNestedTlv(encoder, ndn_Tlv_Data, encodeDataValue, &dataValueContext, 0); }
ndn_Error ndn_encodeTlvInterest (const struct ndn_Interest *interest, size_t *signedPortionBeginOffset, size_t *signedPortionEndOffset, struct ndn_TlvEncoder *encoder) { // Create the context to pass to encodeInterestValue. struct InterestValueContext interestValueContext; interestValueContext.interest = interest; interestValueContext.signedPortionBeginOffset = signedPortionBeginOffset; interestValueContext.signedPortionEndOffset = signedPortionEndOffset; return ndn_TlvEncoder_writeNestedTlv (encoder, ndn_Tlv_Interest, encodeInterestValue, &interestValueContext, 0); }
/** * This private function is called by ndn_TlvEncoder_writeNestedTlv to write the * TLVs in the body of a signature value which has a KeyLocator and * ValidityPeriod, e.g. SignatureSha256WithRsa. * @param context This is the ndn_Signature struct pointer which was passed to * writeTlv. Use signature->type as the TLV type, assuming that the * ndn_SignatureType enum has the same values as the TLV signature types. * @param encoder the ndn_TlvEncoder which is calling this. * @return 0 for success, else an error code. */ static ndn_Error encodeSignatureWithKeyLocatorAndValidityPeriodValue (const void *context, struct ndn_TlvEncoder *encoder) { struct ndn_Signature *signature = (struct ndn_Signature *)context; ndn_Error error; if ((error = ndn_TlvEncoder_writeNonNegativeIntegerTlv (encoder, ndn_Tlv_SignatureType, signature->type))) return error; if ((error = ndn_TlvEncoder_writeNestedTlv (encoder, ndn_Tlv_KeyLocator, ndn_encodeTlvKeyLocatorValue, &signature->keyLocator, 0))) return error; if (ndn_ValidityPeriod_hasPeriod(&signature->validityPeriod)) { if ((error = ndn_TlvEncoder_writeNestedTlv (encoder, ndn_Tlv_ValidityPeriod_ValidityPeriod, encodeValidityPeriodValue, &signature->validityPeriod, 0))) return error; } return NDN_ERROR_success; }
/** * This private function is called by ndn_TlvEncoder_writeNestedTlv to write the TLVs in the body of the Interest value. * @param context This is the InterestValueContext struct pointer which was passed to writeTlv. * @param encoder the ndn_TlvEncoder which is calling this. * @return 0 for success, else an error code. */ static ndn_Error encodeInterestValue(const void *context, struct ndn_TlvEncoder *encoder) { const struct InterestValueContext *interestValueContext = (const struct InterestValueContext *)context; const struct ndn_Interest *interest = interestValueContext->interest; ndn_Error error; uint8_t nonceBuffer[4]; struct ndn_Blob nonceBlob; if ((error = ndn_encodeTlvName (&interest->name, interestValueContext->signedPortionBeginOffset, interestValueContext->signedPortionEndOffset, encoder))) return error; // For Selectors, set omitZeroLength true. if ((error = ndn_TlvEncoder_writeNestedTlv(encoder, ndn_Tlv_Selectors, encodeSelectorsValue, interest, 1))) return error; // Encode the Nonce as 4 bytes. nonceBlob.length = sizeof(nonceBuffer); if (interest->nonce.length == 0) { // Generate a random nonce. if ((error = ndn_generateRandomBytes(nonceBuffer, sizeof(nonceBuffer)))) return error; nonceBlob.value = nonceBuffer; } else if (interest->nonce.length < 4) { // TLV encoding requires 4 bytes, so pad out to 4 using random bytes. ndn_memcpy(nonceBuffer, interest->nonce.value, interest->nonce.length); if ((error = ndn_generateRandomBytes (nonceBuffer + interest->nonce.length, sizeof(nonceBuffer) - interest->nonce.length))) return error; nonceBlob.value = nonceBuffer; } else // TLV encoding requires 4 bytes, so truncate to 4. nonceBlob.value = interest->nonce.value; if ((error = ndn_TlvEncoder_writeBlobTlv(encoder, ndn_Tlv_Nonce, &nonceBlob))) return error; if ((error = ndn_TlvEncoder_writeOptionalNonNegativeIntegerTlvFromDouble (encoder, ndn_Tlv_InterestLifetime, interest->interestLifetimeMilliseconds))) return error; if (interest->forwardingHintWireEncoding.value && interest->forwardingHintWireEncoding.length > 0) { if (interest->selectedDelegationIndex >= 0) return NDN_ERROR_An_Interest_may_not_have_a_selected_delegation_when_encoding_a_forwarding_hint; if (interest->linkWireEncoding.value) return NDN_ERROR_An_Interest_may_not_have_a_link_object_when_encoding_a_forwarding_hint; // Add the encoded sequence of delegations as is. if ((error = ndn_TlvEncoder_writeBlobTlv (encoder, ndn_Tlv_ForwardingHint, &interest->forwardingHintWireEncoding))) return error; } if (interest->linkWireEncoding.value) { // Encode the entire link as is. if ((error = ndn_TlvEncoder_writeArray (encoder, interest->linkWireEncoding.value, interest->linkWireEncoding.length))) return error; } if ((error = ndn_TlvEncoder_writeOptionalNonNegativeIntegerTlv (encoder, ndn_Tlv_SelectedDelegation, interest->selectedDelegationIndex))) return error; return NDN_ERROR_success; }