mirror of
				https://github.com/tailscale/tailscale.git
				synced 2025-10-31 08:11:32 +01:00 
			
		
		
		
	The first packet fragment guard had an additional guard clause that was incorrectly comparing a length in bytes to a length in octets, and was also comparing what should have been an entire IPv4 through transport header length to a subprotocol payload length. The subprotocol header size guards were otherwise protecting against short transport headers, as is the conservative non-first fragment minimum offset size. Add an explicit disallowing of fragmentation for TSMP for the avoidance of doubt. Updates #cleanup Updates #5727 Signed-off-by: James Tucker <james@tailscale.com>
		
			
				
	
	
		
			68 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			68 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright (c) Tailscale Inc & AUTHORS
 | |
| // SPDX-License-Identifier: BSD-3-Clause
 | |
| 
 | |
| package packet
 | |
| 
 | |
| import (
 | |
| 	"errors"
 | |
| 	"math"
 | |
| )
 | |
| 
 | |
| const igmpHeaderLength = 8
 | |
| const tcpHeaderLength = 20
 | |
| const sctpHeaderLength = 12
 | |
| 
 | |
| // maxPacketLength is the largest length that all headers support.
 | |
| // IPv4 headers using uint16 for this forces an upper bound of 64KB.
 | |
| const maxPacketLength = math.MaxUint16
 | |
| 
 | |
| var (
 | |
| 	// errSmallBuffer is returned when Marshal receives a buffer
 | |
| 	// too small to contain the header to marshal.
 | |
| 	errSmallBuffer = errors.New("buffer too small")
 | |
| 	// errLargePacket is returned when Marshal receives a payload
 | |
| 	// larger than the maximum representable size in header
 | |
| 	// fields.
 | |
| 	errLargePacket = errors.New("packet too large")
 | |
| )
 | |
| 
 | |
| // Header is a packet header capable of marshaling itself into a byte
 | |
| // buffer.
 | |
| type Header interface {
 | |
| 	// Len returns the length of the marshaled packet.
 | |
| 	Len() int
 | |
| 	// Marshal serializes the header into buf, which must be at
 | |
| 	// least Len() bytes long. Implementations of Marshal assume
 | |
| 	// that bytes after the first Len() are payload bytes for the
 | |
| 	// purpose of computing length and checksum fields. Marshal
 | |
| 	// implementations must not allocate memory.
 | |
| 	Marshal(buf []byte) error
 | |
| }
 | |
| 
 | |
| // HeaderChecksummer is implemented by Header implementations that
 | |
| // need to do a checksum over their payloads.
 | |
| type HeaderChecksummer interface {
 | |
| 	Header
 | |
| 
 | |
| 	// WriteCheck writes the correct checksum into buf, which should
 | |
| 	// be be the already-marshalled header and payload.
 | |
| 	WriteChecksum(buf []byte)
 | |
| }
 | |
| 
 | |
| // Generate generates a new packet with the given Header and
 | |
| // payload. This function allocates memory, see Header.Marshal for an
 | |
| // allocation-free option.
 | |
| func Generate(h Header, payload []byte) []byte {
 | |
| 	hlen := h.Len()
 | |
| 	buf := make([]byte, hlen+len(payload))
 | |
| 
 | |
| 	copy(buf[hlen:], payload)
 | |
| 	h.Marshal(buf)
 | |
| 
 | |
| 	if hc, ok := h.(HeaderChecksummer); ok {
 | |
| 		hc.WriteChecksum(buf)
 | |
| 	}
 | |
| 
 | |
| 	return buf
 | |
| }
 |