예제 #1
0
ndn_Error
ndn_TlvDecoder_skipRemainingNestedTlvs
  (struct ndn_TlvDecoder *self, size_t endOffset, int skipCritical)
{
  while(self->offset < endOffset) {
    ndn_Error error;
    uint64_t type;
    int critical;
    uint64_t lengthVarNumber;

    if ((error = ndn_TlvDecoder_readVarNumber(self, &type)))
      return error;

    if ((error = ndn_TlvDecoder_readVarNumber(self, &lengthVarNumber)))
      return error;
    critical = (type <= 31 || (type & 1) == 1);
    if (critical && !skipCritical)
      return NDN_ERROR_Unrecognized_critical_TLV_type_code;

    // Silently ignore if the length is larger than size_t.
    self->offset += (size_t)lengthVarNumber;
    if (self->offset > self->inputLength)
      return NDN_ERROR_TLV_length_exceeds_buffer_length;
  }

  if (self->offset != endOffset)
    return NDN_ERROR_TLV_length_does_not_equal_total_length_of_nested_TLVs;

  return NDN_ERROR_success;
}
예제 #2
0
ndn_Error
ndn_decodeTlvNameComponent
  (struct ndn_NameComponent *component, struct ndn_TlvDecoder *decoder)
{
  ndn_Error error;
  uint64_t type;
  size_t saveOffset;

  saveOffset = decoder->offset;
  if ((error = ndn_TlvDecoder_readVarNumber(decoder, &type)))
    return error;
  // Restore the position.
  ndn_TlvDecoder_seek(decoder, saveOffset);

  if ((error = ndn_TlvDecoder_readBlobTlv(decoder, type, &component->value)))
    return error;
  if (type == ndn_Tlv_ImplicitSha256DigestComponent)
    component->type = ndn_NameComponentType_IMPLICIT_SHA256_DIGEST;
  else if (type == ndn_Tlv_ParametersSha256DigestComponent)
    component->type = ndn_NameComponentType_PARAMETERS_SHA256_DIGEST;
  else if (type == ndn_Tlv_NameComponent)
    component->type = ndn_NameComponentType_GENERIC;
  else {
    // Unrecognized type code.
    component->type = ndn_NameComponentType_OTHER_CODE;
    component->otherTypeCode = (int)type;
  }

  return NDN_ERROR_success;
}
예제 #3
0
ndn_Error
ndn_decodeTlvNameComponent
  (struct ndn_NameComponent *component, struct ndn_TlvDecoder *decoder)
{
  ndn_Error error;
  uint64_t type;
  size_t saveOffset;

  saveOffset = decoder->offset;
  if ((error = ndn_TlvDecoder_readVarNumber(decoder, &type)))
    return error;
  // Restore the position.
  ndn_TlvDecoder_seek(decoder, saveOffset);

  if ((error = ndn_TlvDecoder_readBlobTlv(decoder, type, &component->value)))
    return error;
  if (type == ndn_Tlv_ImplicitSha256DigestComponent)
    component->type = ndn_NameComponentType_IMPLICIT_SHA256_DIGEST;
  else
    component->type = ndn_NameComponentType_GENERIC;

  return NDN_ERROR_success;
}
예제 #4
0
ndn_Error
ndn_decodeTlvLpPacket
  (struct ndn_LpPacket *lpPacket, struct ndn_TlvDecoder *decoder)
{
  ndn_Error error;
  size_t endOffset;

  ndn_LpPacket_clear(lpPacket);

  if ((error = ndn_TlvDecoder_readNestedTlvsStart
       (decoder, ndn_Tlv_LpPacket_LpPacket, &endOffset)))
    return error;

  while (decoder->offset < endOffset) {
    // Imitate ndn_TlvDecoder_readTypeAndLength.
    uint64_t fieldTypeVarNumber;
    int fieldType;
    uint64_t fieldLength;
    size_t fieldEndOffset;

    if ((error = ndn_TlvDecoder_readVarNumber(decoder, &fieldTypeVarNumber)))
      return error;
    fieldType = (int)fieldTypeVarNumber;
    if ((error = ndn_TlvDecoder_readVarNumber(decoder, &fieldLength)))
      return error;
    fieldEndOffset = decoder->offset + (size_t)fieldLength;
    if (fieldEndOffset > decoder->inputLength)
      return NDN_ERROR_TLV_length_exceeds_buffer_length;

    if (fieldType == ndn_Tlv_LpPacket_Fragment) {
      // Set the fragment to the bytes of the TLV value.
      if ((error = ndn_TlvDecoder_getSlice
           (decoder, decoder->offset, fieldEndOffset,
            &lpPacket->fragmentWireEncoding)))
        return error;
      ndn_TlvDecoder_seek(decoder, fieldEndOffset);

      // The fragment is supposed to be the last field.
      break;
    }
    else if (fieldType == ndn_Tlv_LpPacket_Nack) {
      struct ndn_NetworkNack *networkNack;
      int code;

      if ((error = ndn_NetworkNack_add(lpPacket, &networkNack)))
        return error;
      if ((error = ndn_TlvDecoder_readOptionalNonNegativeIntegerTlv
           (decoder, ndn_Tlv_LpPacket_NackReason, fieldEndOffset, &code)))
        return error;
      // The enum numeric values are the same as this wire format, so use as is.
      if (code < 0 || code == ndn_NetworkNackReason_NONE)
        // This includes an omitted NackReason.
        networkNack->reason = ndn_NetworkNackReason_NONE;
      else if (code == ndn_NetworkNackReason_CONGESTION ||
               code == ndn_NetworkNackReason_DUPLICATE ||
               code == ndn_NetworkNackReason_NO_ROUTE)
        networkNack->reason = code;
      else {
        // Unrecognized reason.
        networkNack->reason = ndn_NetworkNackReason_OTHER_CODE;
        networkNack->otherReasonCode = code;
      }
    }
    else if (fieldType == ndn_Tlv_LpPacket_IncomingFaceId) {
      struct ndn_IncomingFaceId *incomingFaceId;

      if ((error = ndn_IncomingFaceId_add(lpPacket, &incomingFaceId)))
        return error;
      if ((error = ndn_TlvDecoder_readNonNegativeInteger
           (decoder, fieldLength, &incomingFaceId->faceId)))
        return error;
    }
    else {
      // Unrecognized field type. The conditions for ignoring are here:
      // http://redmine.named-data.net/projects/nfd/wiki/NDNLPv2
      int canIgnore =
        (fieldType >= ndn_Tlv_LpPacket_IGNORE_MIN &&
         fieldType <= ndn_Tlv_LpPacket_IGNORE_MAX &&
         (fieldType & 0x01) == 1);
      if (!canIgnore)
        return NDN_ERROR_did_not_get_the_expected_TLV_type;

      // Ignore.
      ndn_TlvDecoder_seek(decoder, fieldEndOffset);
    }

    if ((error = ndn_TlvDecoder_finishNestedTlvs(decoder, fieldEndOffset)))
      return error;
  }

  if ((error = ndn_TlvDecoder_finishNestedTlvs(decoder, endOffset)))
    return error;

  return NDN_ERROR_success;
}