blob: 64bf1c775fea634ade26e6bcae42af1d3ff717d8 [file] [log] [blame]
Bence Békybac04052022-04-07 15:44:29 -04001// Copyright (c) 2019 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
ericorth920d43f2023-12-11 12:43:42 -08005#include "quiche/quic/core/internet_checksum.h"
Bence Békybac04052022-04-07 15:44:29 -04006
Benjamin Barenblat66cfacd2022-05-27 13:37:07 -07007#include <stdint.h>
8#include <string.h>
9
ericorth055049e2023-12-13 10:06:39 -080010#include "absl/strings/string_view.h"
11#include "absl/types/span.h"
12
Bence Békybac04052022-04-07 15:44:29 -040013namespace quic {
14
15void InternetChecksum::Update(const char* data, size_t size) {
16 const char* current;
17 for (current = data; current + 1 < data + size; current += 2) {
Benjamin Barenblat66cfacd2022-05-27 13:37:07 -070018 uint16_t v;
19 memcpy(&v, current, sizeof(v));
20 accumulator_ += v;
Bence Békybac04052022-04-07 15:44:29 -040021 }
22 if (current < data + size) {
Benjamin Barenblat66cfacd2022-05-27 13:37:07 -070023 accumulator_ += *reinterpret_cast<const unsigned char*>(current);
Bence Békybac04052022-04-07 15:44:29 -040024 }
25}
26
27void InternetChecksum::Update(const uint8_t* data, size_t size) {
28 Update(reinterpret_cast<const char*>(data), size);
29}
30
ericorth055049e2023-12-13 10:06:39 -080031void InternetChecksum::Update(absl::string_view data) {
32 Update(data.data(), data.size());
33}
34
35void InternetChecksum::Update(absl::Span<const uint8_t> data) {
36 Update(reinterpret_cast<const char*>(data.data()), data.size());
37}
38
Bence Békybac04052022-04-07 15:44:29 -040039uint16_t InternetChecksum::Value() const {
40 uint32_t total = accumulator_;
41 while (total & 0xffff0000u) {
42 total = (total >> 16u) + (total & 0xffffu);
43 }
44 return ~static_cast<uint16_t>(total);
45}
46
47} // namespace quic