From bac3da61644515f05663789b122554dc77549286 Mon Sep 17 00:00:00 2001 From: Luca Muscariello Date: Thu, 17 Jan 2019 13:47:57 +0100 Subject: This is the first commit of the hicn project Change-Id: I6f2544ad9b9f8891c88cc4bcce3cf19bd3cc863f Signed-off-by: Luca Muscariello --- libtransport/src/hicn/transport/core/name.cc | 236 +++++++++++++++++++++++++++ 1 file changed, 236 insertions(+) create mode 100755 libtransport/src/hicn/transport/core/name.cc (limited to 'libtransport/src/hicn/transport/core/name.cc') diff --git a/libtransport/src/hicn/transport/core/name.cc b/libtransport/src/hicn/transport/core/name.cc new file mode 100755 index 000000000..10c45eb08 --- /dev/null +++ b/libtransport/src/hicn/transport/core/name.cc @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include + +namespace transport { + +namespace core { + +Name::Name() { name_ = createEmptyName(); } + +Name::Name(int family, const uint8_t *ip_address, std::uint32_t suffix) + : name_(createEmptyName()) { + std::size_t length; + uint8_t *dst = NULL; + + if (family == AF_INET) { + dst = name_->ip4.prefix_as_u8; + length = IPV4_ADDR_LEN; + name_->type = HNT_CONTIGUOUS_V4; + } else if (family == AF_INET6) { + dst = name_->ip6.prefix_as_u8; + length = IPV6_ADDR_LEN; + name_->type = HNT_CONTIGUOUS_V6; + } else { + throw errors::RuntimeException("Specified name family does not exist."); + } + + std::memcpy(dst, ip_address, length); + *reinterpret_cast(dst + length) = suffix; +} + +Name::Name(const char *name, uint32_t segment) { + name_ = createEmptyName(); + + if (hicn_name_create(name, segment, name_.get()) < 0) { + throw errors::InvalidIpAddressException(); + } +} + +Name::Name(const std::string &uri, uint32_t segment) + : Name(uri.c_str(), segment) {} + +Name::Name(const std::string &uri) { + utils::StringTokenizer tokenizer(uri, "|"); + std::string ip_address; + std::string seq_number; + + ip_address = tokenizer.nextToken(); + + try { + seq_number = tokenizer.nextToken(); + } catch (errors::TokenizerException &e) { + seq_number = "0"; + } + + name_ = createEmptyName(); + + if (hicn_name_create(ip_address.c_str(), (uint32_t)atoi(seq_number.c_str()), + name_.get()) < 0) { + throw errors::InvalidIpAddressException(); + } +} + +Name::Name(const Name &name, bool hard_copy) { + name_ = createEmptyName(); + + if (hard_copy) { + if (hicn_name_copy(this->name_.get(), name.name_.get()) < 0) { + throw errors::MalformedNameException(); + } + } else { + *this->name_ = *name.name_; + } +} + +Name::Name(Name &&name) : name_(std::move(name.name_)) {} + +Name &Name::operator=(const Name &name) { + if (hicn_name_copy(this->name_.get(), name.name_.get()) < 0) { + throw errors::MalformedNameException(); + } + + return *this; +} + +bool Name::operator==(const Name &name) const { + return this->equals(name, true); +} + +bool Name::operator!=(const Name &name) const { + return !this->operator==(name); +} + +Name::operator bool() const { + return bool(hicn_name_empty((hicn_name_t *)name_.get())); +} + +bool Name::equals(const Name &name, bool consider_segment) const { + return !hicn_name_compare(name_.get(), name.name_.get(), consider_segment); +} + +std::string Name::toString() const { + char *name = new char[100]; + int ret = hicn_name_ntop(name_.get(), name, standard_name_string_length); + if (ret < 0) { + throw errors::MalformedNameException(); + } + std::string name_string(name); + delete[] name; + + return name_string; +} + +uint32_t Name::getHash32() const { + uint32_t hash; + if (hicn_name_hash((hicn_name_t *)name_.get(), &hash) < 0) { + throw errors::RuntimeException("Error computing the hash of the name!"); + } + return hash; +} + +void Name::clear() { + name_.reset(); + name_ = createEmptyName(); +}; + +Name::Type Name::getType() const { return name_->type; } + +uint32_t Name::getSuffix() const { + uint32_t ret = 0; + if (hicn_name_get_seq_number((hicn_name_t *)name_.get(), &ret) < 0) { + throw errors::RuntimeException( + "Impossible to retrieve the sequence number from the name."); + } + return ret; +} + +Name &Name::setSuffix(uint32_t seq_number) { + if (hicn_name_set_seq_number(name_.get(), seq_number) < 0) { + throw errors::RuntimeException( + "Impossible to set the sequence number to the name."); + } + + return *this; +} + +std::shared_ptr Name::getAddress() const { + Sockaddr *ret = nullptr; + + switch (name_->type) { + case HNT_CONTIGUOUS_V4: + case HNT_IOV_V4: + ret = (Sockaddr *)new Sockaddr4; + break; + case HNT_CONTIGUOUS_V6: + case HNT_IOV_V6: + ret = (Sockaddr *)new Sockaddr6; + break; + default: + throw errors::MalformedNameException(); + } + + if (hicn_name_to_sockaddr_address((hicn_name_t *)name_.get(), ret) < 0) { + throw errors::MalformedNameException(); + } + + return std::shared_ptr(ret); +} + +ip_address_t Name::toIpAddress() const { + ip_address_t ret; + std::memset(&ret, 0, sizeof(ret)); + + if (hicn_name_to_ip_address(name_.get(), &ret) < 0) { + throw errors::InvalidIpAddressException(); + } + + return ret; +} + +int Name::getAddressFamily() const { + int ret = 0; + + if (hicn_name_get_family(name_.get(), &ret) < 0) { + throw errors::InvalidIpAddressException(); + } + + return ret; +} + +void Name::copyToDestination(uint8_t *destination, bool include_suffix) const { + if (hicn_name_copy_to_destination(destination, name_.get(), include_suffix) < + 0) { + throw errors::RuntimeException( + "Impossibe to copy the name into the " + "provided destination"); + } +} + +std::ostream &operator<<(std::ostream &os, const Name &name) { + const std::string &str = name.toString(); + // os << "core:/"; + os << str; + + return os; +} + +} // end namespace core + +} // end namespace transport + +namespace std { +size_t hash::operator()( + const transport::core::Name &name) const { + return name.getHash32(); +} + +} // end namespace std -- cgit 1.2.3-korg