Documentation
¶
Overview ¶
Package bp implements the Bundle Protocol version 6 per RFC 5050, profiled for space missions by CCSDS 734.2-B-1.
Bundle Protocol is the network layer of Delay-Tolerant Networking. It moves application data units (bundles) hop by hop across links that are never all up at once, storing them at intermediate nodes rather than holding an end-to-end session open.
Version 6, not version 7 ¶
CCSDS 734.2-B-1 profiles RFC 5050, which is Bundle Protocol version 6. It is NOT BPv7 (RFC 9171): BPv7 encodes bundles in CBOR and is wire-incompatible. This package implements what CCSDS specifies. BPv7 would be a separate package.
The CCSDS profile adds two things on top of RFC 5050: the IPN naming scheme with Compressed Bundle Header Encoding (RFC 6260), and a mandatory Extended Class of Service block (annex C).
A bundle is a primary block followed by one or more canonical blocks, the last of which is normally the payload:
[ primary block │ extension blocks... │ payload block ]
Nearly every field is a Self-Delimiting Numeric Value, so this package builds on pkg/sdnv.
Index ¶
- Constants
- Variables
- type AdminRecord
- type BlockFlags
- type BlockType
- type Bundle
- func DecodeBundle(data []byte) (*Bundle, error)
- func DecodeBundleN(data []byte, opts DecodeOptions) (*Bundle, int, error)
- func DecodeBundleWithOptions(data []byte, opts DecodeOptions) (*Bundle, error)
- func NewBundle(primary *PrimaryBlock, payload []byte, options ...BundleOption) (*Bundle, error)
- func Reassemble(fragments []*Bundle) (*Bundle, error)
- func (b *Bundle) AdminRecord() (*AdminRecord, error)
- func (b *Bundle) ECOS() (*ECOS, bool)
- func (b *Bundle) Encode() ([]byte, error)
- func (b *Bundle) Fragment(maxPayload int) ([]*Bundle, error)
- func (b *Bundle) Humanize() string
- func (b *Bundle) Payload() ([]byte, error)
- func (b *Bundle) PayloadBlock() (*CanonicalBlock, error)
- func (b *Bundle) String() string
- func (b *Bundle) Validate() error
- type BundleFlags
- type BundleOption
- type CanonicalBlock
- type CreationTimestamp
- type CustodySignal
- type DTNTime
- type DecodeOptions
- type ECOS
- type ECOSFlags
- type EIDReference
- type EndpointID
- type PrimaryBlock
- type Priority
- type ReasonCode
- type RecordType
- type StatusFlags
- type StatusReport
Constants ¶
const DTNScheme = "dtn"
DTNScheme is the scheme of the null endpoint "dtn:none".
const DefaultMaxBlockLength = 16 << 20
DefaultMaxBlockLength bounds a decoded block body when DecodeOptions leaves MaxBlockLength at zero: 16 MiB.
RFC 5050 sets no ceiling and a block length is an SDNV reaching 2^64, so without a cap one corrupt bundle would size an allocation from a bogus length.
const DefaultMaxBlocks = 64
DefaultMaxBlocks bounds the block count when DecodeOptions leaves MaxBlocks at zero.
const ECOSCustodySignalOrdinal uint8 = 255
ECOSCustodySignalOrdinal is the ordinal value annex C reserves for custody signals (C3.1.4).
const IPNScheme = "ipn"
IPNScheme is the naming scheme CCSDS 734.2-B-1 clause 3.2.1 requires, defined by RFC 6260 clause 2.1.
const RecordFlagFragment uint8 = 0x01
RecordFlagFragment is the administrative record flag saying the record concerns a fragment, so the fragment offset and length fields are present (clause 6.1, figure 9).
const Version = 6
Version is the bundle protocol version this package implements, per RFC 5050 clause 4.5.1.
Variables ¶
var ( // ErrDataTooShort indicates the input ended before a field it must contain. ErrDataTooShort = errors.New("data too short for the bundle field being read") // ErrInvalidVersion indicates a bundle version other than 6. BPv7 uses a // CBOR encoding that is wire-incompatible and is not implemented here. ErrInvalidVersion = errors.New("invalid bundle version: this package speaks version 6") // ErrDictionaryOffset indicates a scheme or scheme-specific-part offset // pointing outside the dictionary. ErrDictionaryOffset = errors.New("endpoint offset points outside the dictionary") // ErrInvalidEndpointID indicates an endpoint ID that cannot be parsed. ErrInvalidEndpointID = errors.New("invalid endpoint ID") // ErrMissingPayload indicates a bundle with no payload block, which // RFC 5050 clause 4.5.2 requires. ErrMissingPayload = errors.New("bundle has no payload block") // ErrMultiplePayloads indicates more than one payload block. ErrMultiplePayloads = errors.New("bundle has more than one payload block") // ErrNoLastBlock indicates a bundle whose final block does not carry the // last-block flag. ErrNoLastBlock = errors.New("the final block does not have the last-block flag set") // ErrFragmentFlags indicates fragment fields present without the fragment // flag, or the reverse. ErrFragmentFlags = errors.New("fragment fields do not match the fragment flag") // ErrNotFragment indicates a reassembly operation on a bundle that is not // a fragment. ErrNotFragment = errors.New("bundle is not a fragment") // ErrIncompleteFragments indicates a reassembly attempt with gaps still // unfilled. ErrIncompleteFragments = errors.New("fragments do not cover the whole application data unit") // ErrMismatchedFragments indicates fragments from different bundles. ErrMismatchedFragments = errors.New("fragments do not belong to the same bundle") // ErrCannotFragment indicates a bundle whose "must not be fragmented" // flag forbids the operation. ErrCannotFragment = errors.New("bundle must not be fragmented") // ErrAdminRecordFlags indicates an administrative record requesting // custody transfer or status reports, which clause 4.2 forbids. ErrAdminRecordFlags = errors.New("an administrative record must not request custody transfer or status reports") // ErrInvalidPriority indicates a class of service of 3, which RFC 5050 // Clause 4.2 reserves. ErrInvalidPriority = errors.New("class of service 3 is reserved") // ErrAnonymousSource indicates a bundle with source dtn:none that // requests custody transfer or omits the "must not be fragmented" flag. // Clause 4.2: an anonymous bundle is not uniquely identifiable, so it can // neither take custody nor be fragmented. ErrAnonymousSource = errors.New("an anonymous bundle must not request custody and must set the no-fragment flag") // ErrTrailingBytes indicates data left over after a complete bundle. // DecodeBundle refuses it rather than silently dropping octets; use // DecodeBundleN when bundles arrive back to back in one buffer. ErrTrailingBytes = errors.New("data continues past the end of the bundle") // ErrNotAdminRecord indicates an administrative-record operation on a // bundle that is not one. ErrNotAdminRecord = errors.New("bundle payload is not an administrative record") // ErrInvalidRecordType indicates an unknown administrative record type. ErrInvalidRecordType = errors.New("invalid administrative record type") // ErrBlockTooLarge indicates a block length beyond the configured // maximum. A block length is an SDNV reaching 2^64, so a cap is what // stops one corrupt bundle exhausting memory. ErrBlockTooLarge = errors.New("block length exceeds the maximum this decoder accepts") // ErrInvalidECOS indicates an Extended Class of Service block that // contradicts CCSDS 734.2-B-1 annex C. ErrInvalidECOS = errors.New("invalid Extended Class of Service block") )
Sentinel errors returned by the Bundle Protocol codecs.
var NullEndpoint = EndpointID{Scheme: DTNScheme, SSP: "none"}
NullEndpoint is "dtn:none", the endpoint that names nobody. RFC 5050 clause 4.4 uses it for a bundle with no identifiable source.
Functions ¶
This section is empty.
Types ¶
type AdminRecord ¶
type AdminRecord struct {
Type RecordType
Flags uint8
StatusReport *StatusReport
CustodySignal *CustodySignal
}
AdminRecord is the payload of a bundle whose administrative-record flag is set, per clause 6.1: a four-bit type code, four bits of flags, then type-specific content.
Exactly one of StatusReport and CustodySignal is set.
func DecodeAdminRecord ¶
func DecodeAdminRecord(data []byte) (*AdminRecord, error)
DecodeAdminRecord parses an administrative record from a bundle payload.
func NewCustodySignalRecord ¶
func NewCustodySignalRecord(c *CustodySignal) *AdminRecord
NewCustodySignalRecord wraps a custody signal as an administrative record.
func NewStatusReportRecord ¶
func NewStatusReportRecord(s *StatusReport) *AdminRecord
NewStatusReportRecord wraps a status report as an administrative record.
func (*AdminRecord) Encode ¶
func (a *AdminRecord) Encode() ([]byte, error)
Encode serializes the administrative record.
func (*AdminRecord) Humanize ¶
func (a *AdminRecord) Humanize() string
Humanize returns a human-readable summary.
type BlockFlags ¶
type BlockFlags uint64
BlockFlags are the block processing control flags of RFC 5050 clause 4.5.2.
const ( // BlockReplicate asks that this block be copied into every fragment (bit 0). BlockReplicate BlockFlags = 1 << 0 // BlockReportIfUnprocessed asks for a status report when the block cannot // be processed (bit 1). BlockReportIfUnprocessed BlockFlags = 1 << 1 // BlockDeleteIfUnprocessed deletes the bundle when the block cannot be // processed (bit 2). BlockDeleteIfUnprocessed BlockFlags = 1 << 2 // BlockLast marks the final block of the bundle (bit 3). BlockLast BlockFlags = 1 << 3 // BlockDiscardIfUnprocessed drops the block when it cannot be processed // (bit 4). BlockDiscardIfUnprocessed BlockFlags = 1 << 4 // BlockForwarded records that the block passed through a node that could // not process it (bit 5). BlockForwarded BlockFlags = 1 << 5 // BlockHasEIDRefs marks a block carrying EID references (bit 6). BlockHasEIDRefs BlockFlags = 1 << 6 )
func (BlockFlags) Has ¶
func (f BlockFlags) Has(want BlockFlags) bool
Has reports whether every flag in want is set.
type BlockType ¶
type BlockType uint8
BlockType is the 8-bit type code of a canonical block, per RFC 5050 clause 4.5.2.
const ( // BlockTypePayload is the bundle payload block. It is the only type // RFC 5050 assigns. BlockTypePayload BlockType = 1 // BlockTypeECOS is the Extended Class of Service block that // CCSDS 734.2-B-1 clause 3.3 requires. The code is IANA-assigned; 19 is the // value in the IANA Bundle Block Types registry. BlockTypeECOS BlockType = 19 )
type Bundle ¶
type Bundle struct {
Primary *PrimaryBlock
Blocks []*CanonicalBlock
}
Bundle is a complete Bundle Protocol data unit: a primary block followed by one or more canonical blocks, per RFC 5050 clause 4.1.
The last block must carry the last-block flag, and exactly one block must be the payload.
func DecodeBundle ¶
DecodeBundle parses a complete bundle. Data continuing past the last block is an error: a codec that silently drops octets hides corruption. Use DecodeBundleN when bundles arrive back to back in one buffer.
func DecodeBundleN ¶
func DecodeBundleN(data []byte, opts DecodeOptions) (*Bundle, int, error)
DecodeBundleN parses one bundle from the front of data, returning the bundle and the octets consumed. Trailing data is left for the caller, which is what a stream of concatenated bundles needs.
func DecodeBundleWithOptions ¶
func DecodeBundleWithOptions(data []byte, opts DecodeOptions) (*Bundle, error)
DecodeBundleWithOptions parses a complete bundle under explicit limits, rejecting trailing data like DecodeBundle.
func NewBundle ¶
func NewBundle(primary *PrimaryBlock, payload []byte, options ...BundleOption) (*Bundle, error)
NewBundle builds a bundle carrying one payload.
func Reassemble ¶
Reassemble rebuilds the original bundle from a set of fragments, per clause 5.9.
The fragments may arrive in any order and may overlap; what matters is that together they cover the whole application data unit.
func (*Bundle) AdminRecord ¶
func (b *Bundle) AdminRecord() (*AdminRecord, error)
AdminRecord parses the bundle's payload as an administrative record. It fails when the bundle's administrative-record flag is not set.
func (*Bundle) Fragment ¶
Fragment splits a bundle into pieces whose payloads are at most maxPayload octets each, per RFC 5050 clause 5.8.
Every fragment carries the same primary block with the fragment flag set, its own offset into the original application data unit, and the total ADU length so a receiver knows when it has everything.
Blocks flagged "replicate in every fragment" are copied into each piece. Of the rest, clause 5.8 sends blocks that precede the payload with the first fragment and blocks that follow the payload with the last.
func (*Bundle) PayloadBlock ¶
func (b *Bundle) PayloadBlock() (*CanonicalBlock, error)
PayloadBlock returns the payload block.
type BundleFlags ¶
type BundleFlags uint64
BundleFlags are the bundle processing control flags of RFC 5050 clause 4.2.
The field is an SDNV, so it has no fixed width. Bits 0 to 6 are handling requests, 7 to 13 carry the class of service, and 14 to 20 request status reports.
const ( // FlagFragment marks a bundle that is a fragment (bit 0). FlagFragment BundleFlags = 1 << 0 // FlagAdminRecord marks an administrative record payload (bit 1). FlagAdminRecord BundleFlags = 1 << 1 // FlagNoFragment forbids fragmenting this bundle (bit 2). FlagNoFragment BundleFlags = 1 << 2 // FlagCustodyRequested asks the next node to take custody (bit 3). FlagCustodyRequested BundleFlags = 1 << 3 // FlagSingleton marks a destination that is a singleton endpoint (bit 4). FlagSingleton BundleFlags = 1 << 4 // FlagAppAck asks for application-level acknowledgement (bit 5). FlagAppAck BundleFlags = 1 << 5 // FlagReportReception asks for a bundle-reception status report (bit 14). FlagReportReception BundleFlags = 1 << 14 // FlagReportCustody asks for a custody-acceptance report (bit 15). FlagReportCustody BundleFlags = 1 << 15 // FlagReportForwarding asks for a forwarding report (bit 16). FlagReportForwarding BundleFlags = 1 << 16 // FlagReportDelivery asks for a delivery report (bit 17). FlagReportDelivery BundleFlags = 1 << 17 // FlagReportDeletion asks for a deletion report (bit 18). FlagReportDeletion BundleFlags = 1 << 18 )
func (BundleFlags) Has ¶
func (f BundleFlags) Has(want BundleFlags) bool
Has reports whether every flag in want is set.
func (BundleFlags) Priority ¶
func (f BundleFlags) Priority() Priority
Priority extracts the class of service from the flags.
func (BundleFlags) WithPriority ¶
func (f BundleFlags) WithPriority(p Priority) BundleFlags
WithPriority returns the flags with the class of service replaced.
type BundleOption ¶
BundleOption configures a bundle at construction.
func WithBlock ¶
func WithBlock(block *CanonicalBlock) BundleOption
WithBlock attaches an extension block ahead of the payload.
func WithECOS ¶
func WithECOS(e ECOS) BundleOption
WithECOS attaches an Extended Class of Service block.
CCSDS 734.2-B-1 annex C, C3.1.1 requires the ECOS block to precede the payload, and C3.1.2 allows at most one per bundle.
type CanonicalBlock ¶
type CanonicalBlock struct {
Type BlockType
Flags BlockFlags
// EIDReferences are present only when BlockHasEIDRefs is set. They point
// into the primary block's dictionary.
EIDReferences []EIDReference
// Data is the block-type-specific body.
Data []byte
}
CanonicalBlock is any block other than the primary one, per clause 4.5.2.
func DecodeCanonicalBlock ¶
func DecodeCanonicalBlock(data []byte, maxBlockLength uint64) (*CanonicalBlock, int, error)
DecodeCanonicalBlock parses a canonical block from the front of data, returning the block and the octets consumed.
maxBlockLength caps the body; pass zero for DefaultMaxBlockLength.
func (*CanonicalBlock) Encode ¶
func (b *CanonicalBlock) Encode() ([]byte, error)
Encode serializes the canonical block.
func (*CanonicalBlock) Humanize ¶
func (b *CanonicalBlock) Humanize() string
Humanize returns a human-readable summary.
func (*CanonicalBlock) IsLast ¶
func (b *CanonicalBlock) IsLast() bool
IsLast reports whether this block carries the last-block flag.
func (*CanonicalBlock) Validate ¶
func (b *CanonicalBlock) Validate() error
Validate checks the block against clause 4.5.2.
type CreationTimestamp ¶
CreationTimestamp identifies a bundle together with its source endpoint, per clause 4.5.1. The time is seconds since the year 2000, and the sequence number distinguishes bundles created within the same second.
type CustodySignal ¶
type CustodySignal struct {
// Succeeded is the high bit of the status byte: custody was accepted.
Succeeded bool
// Reason occupies the low seven bits of the status byte.
Reason ReasonCode
IsFragment bool
FragmentOffset uint64
FragmentLength uint64
// SignalTime is when the signal was generated. Unlike a status report,
// this time is always present.
SignalTime DTNTime
CreationTimestamp CreationTimestamp
SourceEndpoint EndpointID
}
CustodySignal is a custody signal, per clause 6.1.2, figure 13. It tells the current custodian whether the reporting node took custody.
func (*CustodySignal) Encode ¶
func (c *CustodySignal) Encode() ([]byte, error)
Encode serializes the custody signal as administrative record content.
func (*CustodySignal) Humanize ¶
func (c *CustodySignal) Humanize() string
Humanize returns a human-readable summary.
type DTNTime ¶
DTNTime is a time in the representation clause 6.1 defines for administrative records: seconds since the start of the year 2000, and nanoseconds within that second.
CCSDS 734.2-B-1 clause 3.4 relaxes the precision requirement: where a spacecraft clock cannot produce meaningful nanoseconds, the onboard precision is used instead, and this does not drive a requirement on the clock.
type DecodeOptions ¶
type DecodeOptions struct {
// MaxBlockLength caps a single block's body. Zero selects
// DefaultMaxBlockLength.
MaxBlockLength uint64
// MaxBlocks caps how many blocks one bundle may carry. Zero selects
// DefaultMaxBlocks.
MaxBlocks int
}
DecodeOptions tunes bundle decoding.
type ECOS ¶
type ECOS struct {
Flags ECOSFlags
// Ordinal ranks this bundle among other expedited ones: 100 is more
// urgent than 99. It has no significance unless the bundle's class of
// service is expedited. Value 255 is reserved for custody signals.
Ordinal uint8
// FlowLabel is an opaque value for the convergence layer, present only
// when ECOSFlowLabelPresent is set.
FlowLabel uint64
}
ECOS is the Extended Class of Service block CCSDS 734.2-B-1 clause 3.3 requires conformant implementations to support.
RFC 5050 gives a bundle three priority levels. Space operations need more: a finer ordinal ranking within the expedited class, a way to mark emergency traffic that should go by every route at once, and a way to ask for or refuse convergence-layer retransmission.
func (*ECOS) Block ¶
func (e *ECOS) Block() (*CanonicalBlock, error)
Block wraps the ECOS data in a canonical block.
Annex C requires bit 0 of the block processing flags (replicate in every fragment) and forbids EID references (C2 b and c).
type ECOSFlags ¶
type ECOSFlags uint8
ECOSFlags are the flags byte of an Extended Class of Service block, per annex C, item C2 f).
const ( // ECOSCritical asks that one copy go along every path that might reach // the destination (0x01). ECOSCritical ECOSFlags = 0x01 // ECOSStreaming asks for best-efforts forwarding, without retransmission // (0x02). ECOSStreaming ECOSFlags = 0x02 // ECOSFlowLabelPresent says a flow label SDNV follows the ordinal byte // (0x04). ECOSFlowLabelPresent ECOSFlags = 0x04 // ECOSReliable asks for a convergence layer that retransmits on loss // (0x08). ECOSReliable ECOSFlags = 0x08 )
type EIDReference ¶
EIDReference is a pair of dictionary offsets naming an endpoint from within a canonical block, per clause 4.5.2.
type EndpointID ¶
EndpointID names a bundle endpoint: a scheme and a scheme-specific part.
On the wire an endpoint is a pair of offsets into the primary block's dictionary, which is how the same scheme string is shared between the destination, source, report-to and custodian without repeating it.
func IPNEndpoint ¶
func IPNEndpoint(node, service uint64) EndpointID
IPNEndpoint builds an endpoint in the IPN scheme that CCSDS mandates.
The scheme-specific part is a node number and a service number separated by a period, per CCSDS 734.2-B-1 clause 3.2.1. Node numbers run 1 to 2^64-1 and are assigned by SANA; service numbers run 0 to 2^64-1.
func ParseEndpointID ¶
func ParseEndpointID(uri string) (EndpointID, error)
ParseEndpointID parses a URI of the form "scheme:ssp".
func (EndpointID) Humanize ¶
func (e EndpointID) Humanize() string
Humanize returns a human-readable description of the endpoint.
func (EndpointID) IPNParts ¶
func (e EndpointID) IPNParts() (node, service uint64, err error)
IPNParts splits an IPN endpoint into its node and service numbers.
func (EndpointID) IsNull ¶
func (e EndpointID) IsNull() bool
IsNull reports whether this is the null endpoint.
func (EndpointID) String ¶
func (e EndpointID) String() string
String renders the endpoint as a URI.
type PrimaryBlock ¶
type PrimaryBlock struct {
Flags BundleFlags
Destination EndpointID
Source EndpointID
ReportTo EndpointID
Custodian EndpointID
CreationTimestamp CreationTimestamp
// Lifetime is how long the bundle stays useful, in seconds from its
// creation timestamp.
Lifetime uint64
// FragmentOffset and TotalADULength are present only when FlagFragment
// is set (clause 4.5.1).
FragmentOffset uint64
TotalADULength uint64
}
PrimaryBlock is the primary bundle block of RFC 5050 clause 4.5.1.
The four endpoints travel as offsets into a shared dictionary rather than as strings, so a bundle whose source and report-to are the same endpoint pays for that string once.
func DecodePrimaryBlock ¶
func DecodePrimaryBlock(data []byte) (*PrimaryBlock, int, error)
DecodePrimaryBlock parses a primary block from the front of data, returning the block and the octets consumed.
func (*PrimaryBlock) Encode ¶
func (p *PrimaryBlock) Encode() ([]byte, error)
Encode serializes the primary block.
func (*PrimaryBlock) Humanize ¶
func (p *PrimaryBlock) Humanize() string
Humanize returns a human-readable summary.
func (*PrimaryBlock) IsAdminRecord ¶
func (p *PrimaryBlock) IsAdminRecord() bool
IsAdminRecord reports whether the payload is an administrative record.
func (*PrimaryBlock) IsFragment ¶
func (p *PrimaryBlock) IsFragment() bool
IsFragment reports whether this block describes a fragment.
func (*PrimaryBlock) Validate ¶
func (p *PrimaryBlock) Validate() error
Validate checks the block against clause 4.2 and clause 4.5.1.
type ReasonCode ¶
type ReasonCode uint8
ReasonCode explains a status report or custody signal, per clause 6.1.1.
The list is neither exhaustive nor exclusive: other DTN specifications may define more.
const ( // ReasonNoInformation means no additional information. ReasonNoInformation ReasonCode = 0x00 // ReasonLifetimeExpired means the bundle outlived its lifetime. ReasonLifetimeExpired ReasonCode = 0x01 // ReasonForwardedUnidirectional means it was forwarded over a // unidirectional link. ReasonForwardedUnidirectional ReasonCode = 0x02 // ReasonTransmissionCancelled means transmission was cancelled. ReasonTransmissionCancelled ReasonCode = 0x03 // ReasonDepletedStorage means the node ran out of storage. ReasonDepletedStorage ReasonCode = 0x04 // ReasonEndpointIDUnintelligible means the destination could not be parsed. ReasonEndpointIDUnintelligible ReasonCode = 0x05 // ReasonNoRoute means no route to the destination. ReasonNoRoute ReasonCode = 0x06 // ReasonNoContact means no timely contact with the next node. ReasonNoContact ReasonCode = 0x07 // ReasonBlockUnintelligible means a block could not be processed. ReasonBlockUnintelligible ReasonCode = 0x08 )
type RecordType ¶
type RecordType uint8
RecordType is the 4-bit administrative record type code of RFC 5050 clause 6.1.
const ( // RecordStatusReport reports how a bundle progressed through the network. RecordStatusReport RecordType = 1 // RecordCustodySignal accepts or refuses custody of a bundle. RecordCustodySignal RecordType = 2 )
type StatusFlags ¶
type StatusFlags uint8
StatusFlags are the status report flags of clause 6.1.1, figure 11. Each bit says what the reporting node did with the bundle.
const ( // StatusReceived means the reporting node received the bundle. StatusReceived StatusFlags = 0x01 // StatusCustodyAccepted means it accepted custody. StatusCustodyAccepted StatusFlags = 0x02 // StatusForwarded means it forwarded the bundle. StatusForwarded StatusFlags = 0x04 // StatusDelivered means it delivered the bundle. StatusDelivered StatusFlags = 0x08 // StatusDeleted means it deleted the bundle. StatusDeleted StatusFlags = 0x10 )
func (StatusFlags) Has ¶
func (f StatusFlags) Has(want StatusFlags) bool
Has reports whether every flag in want is set.
type StatusReport ¶
type StatusReport struct {
Flags StatusFlags
Reason ReasonCode
// IsFragment says the record concerns a fragment, so the offset and
// length fields are present.
IsFragment bool
FragmentOffset uint64
FragmentLength uint64
// Each time is present only when the matching flag in Flags is set.
ReceiptTime DTNTime
CustodyTime DTNTime
ForwardTime DTNTime
DeliveryTime DTNTime
DeletionTime DTNTime
// The bundle being reported on is identified by its creation timestamp
// and source endpoint.
CreationTimestamp CreationTimestamp
SourceEndpoint EndpointID
}
StatusReport is a bundle status report, per clause 6.1.1, figure 10.
A time field is present only when its matching status flag is set, which is what makes the record variable-length.
func (*StatusReport) Encode ¶
func (s *StatusReport) Encode() ([]byte, error)
Encode serializes the status report as administrative record content.
func (*StatusReport) Humanize ¶
func (s *StatusReport) Humanize() string
Humanize returns a human-readable summary.