tftp

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 23, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package tftp is a read-only RFC 1350 TFTP server shaped for SGI PROMs: 512-byte blocks by default (RFC 2347/2348/2349 options when a client negotiates them), transfer sockets bound inside a configurable low port range (PROMs ignore transfers from high source ports), block counter rollover for files past 32MB, and tolerance for paths with or without a leading slash.

Index

Constants

This section is empty.

Variables

View Source
var ErrNotFound = errors.New("file not found")

ErrNotFound is returned by a FileSystem when the path does not exist.

Functions

This section is empty.

Types

type File

type File interface {
	io.ReaderAt
	Size() int64
}

File is an open, random-access file.

type FileSystem

type FileSystem interface {
	Open(path string) (File, error)
}

FileSystem is the tree the server reads from.

type ImageResolver

type ImageResolver interface {
	ResolveImage(path string) (Resolved, error)
}

ImageResolver is optionally implemented by a FileSystem that can say which image file and in-image path a served path came from, so a recorded transfer names the backing image. A FileSystem that doesn't back onto named media need not implement it.

type Resolved

type Resolved struct {
	Image string
	Path  string
}

Resolved is what ImageResolver reports: the backing image's filename and the location within that image's own filesystem.

type Server

type Server struct {
	FS FileSystem

	// AllowIP filters clients; nil allows everyone.
	AllowIP func(netip.Addr) bool

	// PortMin and PortMax bound the transfer sockets' local ports.
	// Zero means ephemeral.
	PortMin, PortMax int

	// RetryInterval is the DATA retransmit interval (default 1s).
	RetryInterval time.Duration

	// Retries is how many times a DATA block is resent before the
	// transfer is abandoned (default 5).
	Retries int

	// FinalRetries and FinalTimeout govern only the last DATA block of a
	// transfer (default 1 retry, 300ms). SGI PROMs reopen a file to seek
	// within it and routinely stop listening once they have what they
	// need, without ACKing the last block sent; the ordinary mid-transfer
	// retry budget (Retries x RetryInterval) exists for real packet loss,
	// not for that expected silence, so the last block gets a cheaper
	// policy to avoid paying it on every reopen.
	FinalRetries int
	FinalTimeout time.Duration

	// Logger, when set, receives leveled log output: DEBUG for every
	// datagram and per-block DATA/ACK detail, INFO for each transfer
	// started or finished, WARN for a request refused or a transfer a
	// client stopped acking, ERROR for this side failing to read or
	// send. A nil Logger is silent.
	Logger *logging.Logger

	// Recorder, when set, receives a tftp_transfer_end record for each
	// completed or abandoned transfer. A nil Recorder is a no-op.
	Recorder *capture.Recorder

	// ClientName, when set, maps a client IP to its configured alias for
	// the recorded transfer. Nil, or a miss, records the IP.
	ClientName func(netip.Addr) string
	// contains filtered or unexported fields
}

Server serves read requests. The zero value is not usable without FS.

func (*Server) Serve

func (s *Server) Serve(pc net.PacketConn) error

Serve answers requests arriving on pc (conventionally bound to :69) until pc is closed.

func (*Server) Shutdown

func (s *Server) Shutdown(timeout time.Duration) bool

Shutdown stops accepting new transfers, closes every in-flight transfer socket so a transfer stuck in its retry budget fails its next send or read and aborts at once, and waits up to timeout for the handlers to finish recording. A bare Wait would not cancel a transfer, whose default retries can outlast the drain window. Returns false if the timeout still elapsed with transfers running.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL