Message

dsns.message.hashable(cls)

Decorator for Message dataclasses that makes them hashable. This uses the source, data, and time fields for hashing. The type is also used to distinguish between different message types. It also implements __eq__ for comparison.

dsns.message.broadcast(cls)

Decorator for BroadcastMessage dataclasses that makes them hashable, and adds the necessary dataclass decorator.

dsns.message.lcg_id_generator(seed=0) Iterator[int]

a: LCG Multiplier c: LCG Increment m: Modulo, currently 2^32 but TODO consider increasing to 2^64 if you see repetitions in UIDs!

class dsns.message.BaseMessage(*, source: int, data: object = None, time: float = 0.0, hops: int = 0, dropped: float = False, size: int = 0)

Base class for messages. This class should not be used directly.

source: int
data: object = None
time: float = 0.0
hops: int = 0
dropped: float = False
size: int = 0

I run into edge case where two different messages have same UID. These can be two checkpoints which give race conditions in my LTP transmission functionality. A fix could be to store reported checkpoints and other fields as LinkMessageIDs. However, if the same message has the same UID on the same link we get to same race. So fix is to cycle periodically through UID. Fix: Use LCG Psuedorandom generator

uid: int
copy(keep_uid: bool = True)

Copy the message.

Returns:

Copy of the message.

__init__(*, source: int, data: object = None, time: float = 0.0, hops: int = 0, dropped: float = False, size: int = 0) None
class dsns.message.DirectMessage(*, source: int, data: object = None, time: float = 0.0, hops: int = 0, dropped: float = False, size: int = 0, destination: int)

Message to be sent between nodes.

destination: int
__init__(*, source: int, data: object = None, time: float = 0.0, hops: int = 0, dropped: float = False, size: int = 0, destination: int) None
class dsns.message.BroadcastMessage(*, source: int, data: object = None, time: float = 0.0, hops: int = 0, dropped: float = False, size: int = 0)

Message to be broadcast between nodes.

__init__(*, source: int, data: object = None, time: float = 0.0, hops: int = 0, dropped: float = False, size: int = 0) None
class dsns.message.LinkLossProbability(source: int, destination: int, reset_loss_probability: bool = False, loss_probability: float = 0.0)
source: int
destination: int
reset_loss_probability: bool = False
loss_probability: float = 0.0
__init__(source: int, destination: int, reset_loss_probability: bool = False, loss_probability: float = 0.0) None
class dsns.message.LinkLossProbabilityUpdateEvent(time: float, updates: list[LinkLossProbability])

Event to update the probability of message loss on given links

__init__(time: float, updates: list[LinkLossProbability])
updates: list[LinkLossProbability] = []
class dsns.message.HybridDirectMessage(*, source: int, data: object = None, time: float = 0.0, hops: int = 0, dropped: float = False, size: int = 0, destination: int, reliable_data_size: int, unreliable_data_size: int)
reliable_data_size: int
unreliable_data_size: int
__init__(*, source: int, data: object = None, time: float = 0.0, hops: int = 0, dropped: float = False, size: int = 0, destination: int, reliable_data_size: int, unreliable_data_size: int) None
class dsns.message.LTPSegment(*, source: int, data: object = None, time: float = 0.0, hops: int = 0, dropped: float = False, size: int = 0, destination: int, underlying_message: dsns.message.HybridDirectMessage, session: int)
underlying_message: HybridDirectMessage
session: int
__init__(*, source: int, data: object = None, time: float = 0.0, hops: int = 0, dropped: float = False, size: int = 0, destination: int, underlying_message: HybridDirectMessage, session: int) None
class dsns.message.LTPDataType(*values)
RED = 'RED'
GREEN = 'GREEN'
class dsns.message.LTPCheckpointData(*, expected_uids: list[int])
expected_uids: list[int]
__init__(*, expected_uids: list[int]) None
class dsns.message.LTPDataSegment(*, source: int, data: object = None, time: float = 0.0, hops: int = 0, dropped: float = False, size: int = 0, destination: int, underlying_message: dsns.message.HybridDirectMessage, session: int, data_type: dsns.message.LTPDataType, is_checkpoint: bool = False, checkpoint_data: dsns.message.LTPCheckpointData = None, is_end_of_green_only_block: bool = False)
data_type: LTPDataType
is_checkpoint: bool = False
checkpoint_data: LTPCheckpointData = None
is_end_of_green_only_block: bool = False
__init__(*, source: int, data: object = None, time: float = 0.0, hops: int = 0, dropped: float = False, size: int = 0, destination: int, underlying_message: HybridDirectMessage, session: int, data_type: LTPDataType, is_checkpoint: bool = False, checkpoint_data: LTPCheckpointData = None, is_end_of_green_only_block: bool = False) None
class dsns.message.LTPReportSegment(*, source: int, data: object = None, time: float = 0.0, hops: int = 0, dropped: float = False, size: int = 0, destination: int, underlying_message: dsns.message.HybridDirectMessage, session: int, report_checkpoint_uid: int, received_segment_uids: list[int])
report_checkpoint_uid: int
received_segment_uids: list[int]
__init__(*, source: int, data: object = None, time: float = 0.0, hops: int = 0, dropped: float = False, size: int = 0, destination: int, underlying_message: HybridDirectMessage, session: int, report_checkpoint_uid: int, received_segment_uids: list[int]) None
class dsns.message.LTPReportAcknowledgementSegment(*, source: int, data: object = None, time: float = 0.0, hops: int = 0, dropped: float = False, size: int = 0, destination: int, underlying_message: dsns.message.HybridDirectMessage, session: int, acked_report_message_uid: int)
acked_report_message_uid: int
__init__(*, source: int, data: object = None, time: float = 0.0, hops: int = 0, dropped: float = False, size: int = 0, destination: int, underlying_message: HybridDirectMessage, session: int, acked_report_message_uid: int) None
class dsns.message.LinkMessageID(source: int, destination: int, uid: int)
source: int
destination: int
uid: int
__init__(source: int, destination: int, uid: int) None
source: int
destination: int
__init__(source: int, destination: int) None
class dsns.message.MessageLostEvent(time: float, source: int, destination: int, message: BaseMessage)
__init__(time: float, source: int, destination: int, message: BaseMessage)
source: int
destination: int
message: LTPSegment
class dsns.message.LTPSegmentReceivedEvent(time: float, source: int, destination: int, message: LTPSegment)

Event for when LTP segments are received. Source and destination refer to the satellites that sent and received the message, respectively. Once all LTP messages are received and processed, a MessageReceivedEvent is issued for underlying message

__init__(time: float, source: int, destination: int, message: LTPSegment)
message: LTPSegment
class dsns.message.LossConfig(seed: float = 0, default_loss_probability: float = 0)
__init__(seed: float = 0, default_loss_probability: float = 0)
is_message_lost(source: int, destination: int, size: int) bool
class dsns.message.MessageRerouteEvent(time: float, source: int, previous_destination: int, message: BaseMessage)

Event for when a message has been queued on the link, but the link went down so now we want to reroute it by passing it up from link level to network level

__init__(time: float, source: int, previous_destination: int, message: BaseMessage)
previous_destination: int
message: BaseMessage
class dsns.message.MessageQueuedEvent(time: float, source: int, destination: int, message: BaseMessage)

Event for when a message has been queued on the link, waiting to be transmitted with respect to bandwidth capacity

__init__(time: float, source: int, destination: int, message: BaseMessage)
message: BaseMessage
class dsns.message.MessageSentEvent(time: float, source: int, destination: int, message: BaseMessage)

Event for when a message is sent. Source and destination refer to the satellites that sent and received the message, respectively.

__init__(time: float, source: int, destination: int, message: BaseMessage)
message: BaseMessage
class dsns.message.MessageReceivedEvent(time: float, source: int, destination: int, message: BaseMessage)

Event for when a message is received. Source and destination refer to the satellites that sent and received the message, respectively.

__init__(time: float, source: int, destination: int, message: BaseMessage)
message: BaseMessage
class dsns.message.MessageDeliveredEvent(time: float, destination: int, message: BaseMessage)

Event for when a message is delivered.

__init__(time: float, destination: int, message: BaseMessage)
destination: int
message: BaseMessage
class dsns.message.MessageBroadcastDeliveredEvent(time: float, message: BroadcastMessage)

Event for when a message broadcast has been delivered to all nodes in the network.

__init__(time: float, message: BroadcastMessage)
message: BroadcastMessage
class dsns.message.DropReason(*values)
DUPLICATE = 'DUPLICATE'
INSUFFICIENT_BUFFER = 'INSUFFICIENT_BUFFER'
MISCONFIGURED = 'MISCONFIGURED'
INDICATED = 'INDICATED'
NO_NEXT_HOP = 'NO_NEXT_HOP'
RETRANSMISSION_RETRIES_EXHAUSTED = 'RETRANSMISSION_RETRIES_EXHAUSTED'
UNKNOWN = 'UNKNOWN'
class dsns.message.MessageDroppedEvent(time: float, source: int, message: BaseMessage, reason: DropReason = DropReason.UNKNOWN)

Event for when a message is dropped. Source refers to the satellite that dropped the message.

__init__(time: float, source: int, message: BaseMessage, reason: DropReason = DropReason.UNKNOWN)
message: BaseMessage
class dsns.message.MessageCreatedEvent(time: float, message: BaseMessage)

Event for when a message is created.

__init__(time: float, message: BaseMessage)
message: BaseMessage
class dsns.message.LTPSegmentCreatedEvent(time: float, message: LTPSegment)

Event for when a LTP Segment is created.

__init__(time: float, message: LTPSegment)
message: LTPSegment
class dsns.message.AttackMessageDroppedEvent(time: float, source: int, message: BaseMessage, reason: DropReason = DropReason.UNKNOWN)

Event for when a message is dropped because of an attack.

dsns.message.LinkDownAttackStrategy(links: set[tuple[int, int]], start_time: float = 0.0, probability: float = 1.0, seed: int | None = None, message_filter: Callable[[BaseMessage], bool] | None = None) Callable[[MessageSentEvent], bool]

Create an attack strategy that takes down links after a given time.

Parameters:
  • links – Set of links to drop messages for.

  • start_time – Time to start dropping messages from.

  • probability – Probability of dropping a message.

  • seed – Seed to use for the random number generator.

  • message_filter – Optional filter function. If provided, only messages that pass the filter will be dropped.

Returns:

Attack strategy.

dsns.message.NodeDownAttackStrategy(nodes: set[int], start_time: float = 0.0, probability: float = 1.0, seed: int | None = None, message_filter: Callable[[BaseMessage], bool] | None = None) Callable[[MessageSentEvent], bool]

Create an attack strategy that takes down nodes after a given time.

Parameters:
  • nodes – Set of nodes to drop messages for.

  • start_time – Time to start dropping messages from.

  • probability – Probability of dropping a message.

  • seed – Seed to use for the random number generator.

  • message_filter – Optional filter function. If provided, only messages that pass the filter will be dropped.

Returns:

Attack strategy.

dsns.message.MultipleAttackStrategy(strategies: list[Callable[[MessageSentEvent], bool]]) Callable[[MessageSentEvent], bool]

Create an attack strategy that combines multiple attack strategies.

Parameters:

strategies – List of attack strategies to combine.

Returns:

Combined attack strategy.

class dsns.message.RELIABLE_TRANSFER_TYPE(*values)
NONE = 'NONE'
LTP = 'LTP'
class dsns.message.ReliableTransferConfig

Abstract base class for configurations on how routing actor should send messages Either break them down into LTP segments or send the entire message unreliably

abstractmethod get_messages(time: int, source: int, destination: int, message: HybridDirectMessage) list[DirectMessage]
class dsns.message.UnreliableConfig

Specific transfer config for unreliable transfer

get_messages(time: int, source: int, destination: int, message: HybridDirectMessage) list[DirectMessage]
class dsns.message.LTPConfig(max_segment_size: int = 8192)

https://ntrs.nasa.gov/api/citations/20240015952/downloads/IEEE_Aeroconf_2025%20final.pdf Says performance increases sharply until 8KB Segment Size and then marginally until 64KB. But 64KB is more on the unrealistic side (IP fragmentation and otherwise that we don’t have). Whereas 9KB Jumbo Frames are possible. So we will stick to performance maximising Segment Size for regular DTNs at 8KB. Suggests 8KB-64KB Segment Size (especially on HDTNs like relay links). - Uses high bandwidth link with different MTU (we don’t model MTU here) - Uses unrealistically high bandwidth though (not the goal of that paper) so need to find other more realistic source for this

__init__(max_segment_size: int = 8192)
get_messages(time: int, source: int, destination: int, message: HybridDirectMessage) list[DirectMessage]