Hybrid ICN (hICN) plugin  v21.06-rc0-4-g18fa668
packet.h
1 /*
2  * Copyright (c) 2017-2019 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #pragma once
17 
18 #include <hicn/transport/auth/crypto_hash.h>
19 #include <hicn/transport/auth/crypto_suite.h>
20 #include <hicn/transport/auth/key_id.h>
21 #include <hicn/transport/core/name.h>
22 #include <hicn/transport/core/payload_type.h>
23 #include <hicn/transport/errors/malformed_packet_exception.h>
24 #include <hicn/transport/portability/portability.h>
25 #include <hicn/transport/utils/branch_prediction.h>
26 #include <hicn/transport/utils/membuf.h>
27 #include <hicn/transport/utils/object_pool.h>
28 
29 namespace transport {
30 
31 namespace auth {
32 class Signer;
33 class AsymmetricSigner;
34 class SymmetricSigner;
35 class Verifier;
36 class AsymmetricVerifier;
37 class SymmetricVerifier;
38 } // namespace auth
39 
40 namespace core {
41 
42 /*
43  * Basic IP packet, modelled as circular chain of buffers:
44  * Header = H
45  * Payload = P
46  *
47  * H_0 --> H_1 --> H_2 --> P_0 --> P_1 --> P_2
48  * \_______________________________________|
49  */
50 
51 class Packet : public utils::MemBuf,
52  public std::enable_shared_from_this<Packet> {
53  friend class auth::Signer;
54  friend class auth::SymmetricSigner;
55  friend class auth::AsymmetricSigner;
56  friend class auth::Verifier;
57  friend class auth::AsymmetricVerifier;
58  friend class auth::SymmetricVerifier;
59 
60  public:
61  using Ptr = std::shared_ptr<Packet>;
62  using MemBufPtr = std::shared_ptr<utils::MemBuf>;
63  using Format = hicn_format_t;
64  static constexpr size_t default_mtu = 1500;
65 
71  Packet(Format format = HF_INET6_TCP, std::size_t additional_header_size = 0);
72 
77  /* Copy buffer */
78  Packet(CopyBufferOp, const uint8_t *buffer, std::size_t size);
79  /* Wrap buffer */
80  Packet(WrapBufferOp, uint8_t *buffer, std::size_t length, std::size_t size);
81  /* Create new using pre-allocated buffer */
82  Packet(CreateOp, uint8_t *buffer, std::size_t length, std::size_t size,
83  Format format = HF_INET6_TCP, std::size_t additional_header_size = 0);
84  /* Move MemBuf */
85  Packet(MemBuf &&buffer);
86 
87  Packet(Packet &&other);
88 
89  /*
90  * Copy constructor and assignemnt operators.
91  */
92  Packet(const Packet &other);
93  Packet &operator=(const Packet &other);
94 
95  friend bool operator==(const Packet &l_packet, const Packet &r_packet);
96 
97  virtual ~Packet();
98 
99  static std::size_t getHeaderSizeFromFormat(Format format,
100  std::size_t signature_size = 0) {
101  std::size_t header_length;
102  hicn_packet_get_header_length_from_format(format, &header_length);
103  int is_ah = _is_ah(format);
104  return is_ah * (header_length + signature_size) + (!is_ah) * header_length;
105  }
106 
107  static std::size_t getHeaderSizeFromBuffer(Format format,
108  const uint8_t *buffer);
109 
110  static std::size_t getPayloadSizeFromBuffer(Format format,
111  const uint8_t *buffer);
112 
113  static bool isInterest(const uint8_t *buffer);
114 
115  bool isInterest();
116 
117  static Format getFormatFromBuffer(const uint8_t *buffer, std::size_t length) {
118  Format format = HF_UNSPEC;
119  hicn_packet_get_format((const hicn_header_t *)buffer, &format);
120  return format;
121  }
122 
123  void reset() {
124  clear();
125  packet_start_ = reinterpret_cast<hicn_header_t *>(writableData());
126  header_offset_ = 0;
127  format_ = HF_UNSPEC;
128  payload_type_ = PayloadType::UNSPECIFIED;
129  name_.clear();
130 
131  if (isChained()) {
132  separateChain(next(), prev());
133  }
134  }
135 
136  void setFormat(Packet::Format format = HF_INET6_TCP,
137  std::size_t additional_header_size = 0);
138 
139  std::size_t payloadSize() const;
140 
141  std::size_t headerSize() const;
142 
143  std::shared_ptr<utils::MemBuf> acquireMemBufReference();
144 
145  virtual const Name &getName() const = 0;
146 
147  virtual Name &getWritableName() = 0;
148 
149  virtual void setName(const Name &name) = 0;
150 
151  virtual void setLifetime(uint32_t lifetime) = 0;
152 
153  virtual uint32_t getLifetime() const = 0;
154 
155  Packet &appendPayload(const uint8_t *buffer, std::size_t length);
156 
157  Packet &appendPayload(std::unique_ptr<utils::MemBuf> &&payload);
158 
159  std::unique_ptr<utils::MemBuf> getPayload() const;
160 
161  Packet &updateLength(std::size_t length = 0);
162 
163  PayloadType getPayloadType() const;
164 
165  Packet &setPayloadType(PayloadType payload_type);
166 
167  Format getFormat() const;
168 
169  void dump() const;
170 
171  static void dump(uint8_t *buffer, std::size_t length);
172 
173  virtual void setLocator(const ip_address_t &locator) = 0;
174 
175  virtual ip_address_t getLocator() const = 0;
176 
180  void setSignatureTimestamp(const uint64_t &timestamp_milliseconds);
181 
182  uint64_t getSignatureTimestamp() const;
183 
184  void setValidationAlgorithm(const auth::CryptoSuite &validation_algorithm);
185 
186  auth::CryptoSuite getValidationAlgorithm() const;
187 
188  void setKeyId(const auth::KeyId &key_id);
189 
190  auth::KeyId getKeyId() const;
191 
192  virtual auth::CryptoHash computeDigest(auth::CryptoHashType algorithm) const;
193 
194  void setChecksum() {
195  uint16_t partial_csum =
196  csum(data() + HICN_V6_TCP_HDRLEN, length() - HICN_V6_TCP_HDRLEN, 0);
197 
198  for (utils::MemBuf *current = next(); current != this;
199  current = current->next()) {
200  partial_csum = csum(current->data(), current->length(), ~partial_csum);
201  }
202 
203  if (hicn_packet_compute_header_checksum(format_, packet_start_,
204  partial_csum) < 0) {
206  }
207  }
208 
209  bool checkIntegrity() const;
210 
211  Packet &setSyn();
212  Packet &resetSyn();
213  bool testSyn() const;
214  Packet &setAck();
215  Packet &resetAck();
216  bool testAck() const;
217  Packet &setRst();
218  Packet &resetRst();
219  bool testRst() const;
220  Packet &setFin();
221  Packet &resetFin();
222  bool testFin() const;
223  Packet &resetFlags();
224  std::string printFlags() const;
225 
226  Packet &setSrcPort(uint16_t srcPort);
227  Packet &setDstPort(uint16_t dstPort);
228  uint16_t getSrcPort() const;
229  uint16_t getDstPort() const;
230 
231  Packet &setTTL(uint8_t hops);
232  uint8_t getTTL() const;
233 
234  private:
235  virtual void resetForHash() = 0;
236  void setSignatureSize(std::size_t size_bytes);
237  void setSignatureSizeGap(std::size_t size_bytes);
238  void prependPayload(const uint8_t **buffer, std::size_t *size);
239 
240  bool authenticationHeader() const { return _is_ah(format_); }
241 
242  std::size_t getSignatureSize() const {
243  size_t size_bytes;
244  int ret =
245  hicn_packet_get_signature_size(format_, packet_start_, &size_bytes);
246 
247  if (ret < 0) {
248  throw errors::RuntimeException("Packet without Authentication Header.");
249  }
250 
251  return size_bytes;
252  }
253 
254  std::size_t getSignatureSizeGap() const {
255  uint8_t size_bytes;
256  int ret =
257  hicn_packet_get_signature_gap(format_, packet_start_, &size_bytes);
258 
259  if (ret < 0) {
260  throw errors::RuntimeException("Packet without Authentication Header.");
261  }
262 
263  return (size_t)size_bytes;
264  }
265 
266  std::size_t getSignatureSizeReal() const {
267  return getSignatureSize() - getSignatureSizeGap();
268  }
269 
270  uint8_t *getSignature() const;
271 
272  protected:
273  hicn_header_t *packet_start_;
274  std::size_t header_offset_;
275  mutable Format format_;
276  Name name_;
277  mutable PayloadType payload_type_;
278  static const core::Name base_name;
279 };
280 
281 } // end namespace core
282 
283 } // end namespace transport
transport::core::Packet
Definition: packet.h:51
hicn_header_t
Definition: header.h:91
transport::core::Name
Definition: name.h:45
hicn_packet_compute_header_checksum
int hicn_packet_compute_header_checksum(hicn_format_t format, hicn_header_t *packet, u16 init_sum)
compute the checksum of the packet header, adding init_sum to the final value
hicn_packet_get_signature_size
int hicn_packet_get_signature_size(hicn_format_t format, const hicn_header_t *packet, size_t *bytes)
Retrieves the signature size.
ip_address_t
Definition: ip_address.h:68
transport::auth::Signer
Definition: signer.h:33
transport::auth::CryptoHash
Definition: crypto_hash.h:40
errors::MalformedPacketException
Definition: malformed_packet_exception.h:22
hicn_packet_get_format
int hicn_packet_get_format(const hicn_header_t *packet, hicn_format_t *format)
Parse packet headers and return hICN format.
transport::auth::AsymmetricSigner
Definition: signer.h:82
transport::core::Packet::Packet
Packet(Format format=HF_INET6_TCP, std::size_t additional_header_size=0)
transport::core::Packet::setSignatureTimestamp
void setSignatureTimestamp(const uint64_t &timestamp_milliseconds)
Set signature timestamp, in milliseconds.
transport
Definition: forwarder_config.h:32
transport::auth::SymmetricVerifier
Definition: verifier.h:157
transport::auth::AsymmetricVerifier
Definition: verifier.h:126
utils::MemBuf::separateChain
std::unique_ptr< MemBuf > separateChain(MemBuf *head, MemBuf *tail)
Definition: membuf.h:309
transport::auth::SymmetricSigner
Definition: signer.h:94
transport::auth::Verifier
Definition: verifier.h:34
hicn_packet_get_header_length_from_format
int hicn_packet_get_header_length_from_format(hicn_format_t format, size_t *header_length)
Return total length of hicn headers (but signature payload)
errors::RuntimeException
Definition: runtime_exception.h:25
utils::MemBuf
Definition: membuf.h:45
utils::MemBuf::MemBuf
MemBuf() noexcept