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 ¶
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 FileSystem ¶
FileSystem is the tree the server reads from.
type ImageResolver ¶
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 ¶
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 ¶
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.