summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip/header/checksum.go
diff options
context:
space:
mode:
authorIan Gudger <igudger@google.com>2018-11-05 15:38:32 -0800
committerShentubot <shentubot@google.com>2018-11-05 15:39:30 -0800
commit37cbce1f9156109a58ae3d350f8e0e9d027b3785 (patch)
treea76b631fd031c1f348562cc9b3a2275b43fb1556 /pkg/tcpip/header/checksum.go
parent704b56a40d0a041a4e6f814c3dbb1f9ec15f9002 (diff)
Merge segments in sender's writeList
PiperOrigin-RevId: 220185891 Change-Id: Iaea73fd7b2fa8c399b989cdcaabf4885f370df4b
Diffstat (limited to 'pkg/tcpip/header/checksum.go')
-rw-r--r--pkg/tcpip/header/checksum.go39
1 files changed, 35 insertions, 4 deletions
diff --git a/pkg/tcpip/header/checksum.go b/pkg/tcpip/header/checksum.go
index 12f208fde..2c2fcbd9b 100644
--- a/pkg/tcpip/header/checksum.go
+++ b/pkg/tcpip/header/checksum.go
@@ -18,12 +18,11 @@ package header
import (
"gvisor.googlesource.com/gvisor/pkg/tcpip"
+ "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer"
)
-// Checksum calculates the checksum (as defined in RFC 1071) of the bytes in the
-// given byte array.
-func Checksum(buf []byte, initial uint16) uint16 {
- v := uint32(initial)
+func calculateChecksum(buf []byte, initial uint32) uint16 {
+ v := initial
l := len(buf)
if l&1 != 0 {
@@ -38,8 +37,40 @@ func Checksum(buf []byte, initial uint16) uint16 {
return ChecksumCombine(uint16(v), uint16(v>>16))
}
+// Checksum calculates the checksum (as defined in RFC 1071) of the bytes in the
+// given byte array.
+//
+// The initial checksum must have been computed on an even number of bytes.
+func Checksum(buf []byte, initial uint16) uint16 {
+ return calculateChecksum(buf, uint32(initial))
+}
+
+// ChecksumVV calculates the checksum (as defined in RFC 1071) of the bytes in
+// the given VectorizedView.
+//
+// The initial checksum must have been computed on an even number of bytes.
+func ChecksumVV(vv buffer.VectorisedView, initial uint16) uint16 {
+ var odd bool
+ sum := initial
+ for _, v := range vv.Views() {
+ if len(v) == 0 {
+ continue
+ }
+ s := uint32(sum)
+ if odd {
+ s += uint32(v[0])
+ v = v[1:]
+ }
+ odd = len(v)&1 != 0
+ sum = calculateChecksum(v, s)
+ }
+ return sum
+}
+
// ChecksumCombine combines the two uint16 to form their checksum. This is done
// by adding them and the carry.
+//
+// Note that checksum a must have been computed on an even number of bytes.
func ChecksumCombine(a, b uint16) uint16 {
v := uint32(a) + uint32(b)
return uint16(v + v>>16)