Transmission
- class dsns.transmission.MessageLocationTracker
- __init__()
- remove_message_from_location(message: DirectMessage, link: Link)
- add_message_to_location(message: DirectMessage, link: Link)
- is_message_at_location(message: DirectMessage, link: Link)
- class dsns.transmission.MessageScheduledSendCompletedEvent(time: float, send_start_time: float, source: int, destination: int, message: BaseMessage)
Event for when a message was scheduled to have been fully transmitted onto the link.
- __init__(time: float, send_start_time: float, source: int, destination: int, message: BaseMessage)
- message: BaseMessage
- class dsns.transmission.BandwidthUpdateEvent(time: float, source: int, destination: int, bandwidth: float)
Event to update the bandwidth of a link.
- __init__(time: float, source: int, destination: int, bandwidth: float)
- class dsns.transmission.TransmissionInterval(start_time: float, end_time: float)
- start_time: float
- end_time: float
- __init__(start_time: float, end_time: float) None
- class dsns.transmission.LinkTransmissionActor(default_bandwidth: float, per_link_bandwidth: dict | None = None, buffer_if_link_busy: bool = False, reroute_on_link_down: bool = True, message_location_tracker: ~dsns.transmission.MessageLocationTracker = <dsns.transmission.MessageLocationTracker object>)
Models bandwidth to schedule when messages are sent This actor schedules one message at a time
- __init__(default_bandwidth: float, per_link_bandwidth: dict | None = None, buffer_if_link_busy: bool = False, reroute_on_link_down: bool = True, message_location_tracker: ~dsns.transmission.MessageLocationTracker = <dsns.transmission.MessageLocationTracker object>)
- handle_message_queued_event(mobility: MultiConstellation, event: MessageQueuedEvent, message: BaseMessage) list[Event]
- handle_message_scheduled_send_completed_event(mobility: MultiConstellation, event: MessageScheduledSendCompletedEvent, message: BaseMessage) list[Event]
Check if this scheduled send completion is stale. If not raise the corresponding MessageSentEvent to signal that the entire message was successfully transmitted onto the link.
- handle_link_down_event(mobility: MultiConstellation, event: LinkDownEvent) list[Event]
Assume for now that if buffering is enabled a message is buffered (not sent) until it can and is successfully sent TODO: expand this later for specific behavior depending on what goes down
- handle_message_sent_event(mobility: MultiConstellation, event: MessageSentEvent, message: BaseMessage) list[Event]
MessageSentEvent signifies the entire message was transmitted onto the link successfully. If there is a next message waiting to be sent on that link, schedule it.
- handle_link_up_event(mobility: MultiConstellation, event: LinkUpEvent) list[Event]
Recomputes scheduled send completion events for buffered messages Note these must be scheduled before any new store and forward messages are queued and scheduled for
- handle_bandwidth_update_event(mobility: MultiConstellation, event: BandwidthUpdateEvent)
- handle_event(mobility: MultiConstellation, event) list[Event]
Handle an event.
- Parameters:
mobility – The mobility model to handle the event with.
event – The event to handle.
- Returns:
List of events to add to the event queue.
- class dsns.transmission.MessageTransmissionTimeoutEvent(time: float, message: BaseMessage, source: int, destination: int)
- __init__(time: float, message: BaseMessage, source: int, destination: int)
- message: int
- source: int
- destination: int
- class dsns.transmission.LTPSegmentDroppedEvent(time: float, source: int, message: LTPSegment, reason: DropReason = DropReason.UNKNOWN)
Event for when an LTP Segment is dropped. Source refers to the satellite that dropped the message.
- __init__(time: float, source: int, message: LTPSegment, reason: DropReason = DropReason.UNKNOWN)
- message: LTPSegment
- class dsns.transmission.AbortReason(*values)
- LTP_SESSION_CANCELATION = 'LTP_SESSION_CANCELATION'
- UNKNOWN = 'UNKNWON'
- class dsns.transmission.MessageReceptionCanceledEvent(time: float, source: int, message: BaseMessage, destination: int, reason: AbortReason = AbortReason.UNKNOWN)
Event for when a receiver aborts receiving a message from a sender. Note sender can drop the message, but receiver cannot drop something they don’t have yet. They can only abort its reception.
- __init__(time: float, source: int, message: BaseMessage, destination: int, reason: AbortReason = AbortReason.UNKNOWN)
- message: BaseMessage
- class dsns.transmission.RetransmissionConfig(timeout: ~typing.Callable[[float], float] = <function RetransmissionConfig.<lambda>>, max_retries: int = 10)
Configuration for retransmission timeouts.
- “Then, to account for the additional delay imposed by interrupted
connectivity, we dynamically suspend timers during periods when the relevant remote LTP engines are known to be unable to transmit responses.” - Not a concern as we start timers when message fully transmitted.
LTP RFC 5325 - Read Section ‘3.1.3. Timers’ for Justification “So the initial expected arrival time for each acknowledging segment is typically computed as simply the current time at the moment that radiation of the original segment begins, plus twice the one-way light time, plus 2*N seconds of margin to account for processing and queuing delays and for radiation time at both ends. N is a parameter set by network management for which 2 seconds seem to be a reasonable default value.”
We simplify this by starting timers when the message is fully transmitted into the link (but since message size <<< bandwidth this is negligible).
Then compute timeout by default as recommende in the RFC as RTT + 2*N, where N=2 as recommended
- timeout()
No real optimal value. Based on RFC this is a limit dependent on the network config. Given the loose retransmission timeout (extra 4 seconds on RTT), 10 retries should be sufficient.
https://support.microsoft.com/en-gb/topic/how-to-modify-the-tcp-ip-maximum-retransmission-time-out-7ae0982a-4963-fa7e-ee79-ff6d0da73db8 TCP default value for TcpMaxDataRetransmissions is 5. Standard value I would argue. So this is more than enough.
- max_retries: int = 10
- __init__(timeout: ~typing.Callable[[float], float] = <function RetransmissionConfig.<lambda>>, max_retries: int = 10) None
- class dsns.transmission.LTPSessionID(source: int, destination: int, underlying_message_uid: int, session: int)
- source: int
- destination: int
- underlying_message_uid: int
- session: int
- __init__(source: int, destination: int, underlying_message_uid: int, session: int) None
- class dsns.transmission.LTPMessageRetransmissionActor(config: ~dsns.transmission.RetransmissionConfig, report_segment_base_size: int = 9, report_ack_size: int = 5, model_bandwidth=False, message_location_tracker: ~dsns.transmission.MessageLocationTracker = <dsns.transmission.MessageLocationTracker object>)
https://www.rfc-editor.org/rfc/pdfrfc/rfc5326.txt.pdf RFC 5326 Implements LTP based retransmission for satelite communication. Each original direct message is now encapsulated as a series of LTP segments in an LTPBlock. The remaining LTPMessage’s are control messages for sending a checkpoint, report segment and report ack.
Each LTPBlock has a red part for reliable transfer and green part for unreliable transfer. Each LTPBlock must be followed by a checkpoint segment at the end. Checkpoints require sender to reply with a report segment of missing data When a sender gets a report segment they acknowledge it and retransmit missing data.
Checkpoints and report segments have timeouts.
Retransmission timers for timeouts are started when the message is sent and not when it’s queued. This is so that we don’t retransmit messages that are waiting for transmission because of bandwidth availability.
- __init__(config: ~dsns.transmission.RetransmissionConfig, report_segment_base_size: int = 9, report_ack_size: int = 5, model_bandwidth=False, message_location_tracker: ~dsns.transmission.MessageLocationTracker = <dsns.transmission.MessageLocationTracker object>)
- handle_message_sent_event(mobility: MultiConstellation, event: MessageSentEvent, message: LTPSegment) list[Event]
- handle_data_segment_received_event(mobility: MultiConstellation, event: LTPSegmentReceivedEvent, message: LTPDataSegment) list[Event]
- handle_report_segment_received_event(mobility: MultiConstellation, event: LTPSegmentReceivedEvent, message: LTPReportSegment) list[Event]
If its a duplicate report segment We only ack it but don’t retransmit missing data again As per 6.13 in https://www.rfc-editor.org/rfc/pdfrfc/rfc5326.txt.pdf
As per 6.13 if the session is canceled (underlying message or corresponding checkpoint is dropped) we only ack.
- handle_report_ack_received_event(mobility: MultiConstellation, event: LTPSegmentReceivedEvent, message: LTPReportAcknowledgementSegment) list[Event]
- handle_message_dropped_event(mobility: MultiConstellation, event: LTPSegmentDroppedEvent, message: LTPSegment) list[Event]
- handle_message_transmission_timeout_event(mobility: MultiConstellation, event: MessageTransmissionTimeoutEvent, message: LTPSegment) list[Event]
- handle_ltp_segment_created_event(mobility: MultiConstellation, event: LTPSegmentCreatedEvent, message: LTPSegment)
- handle_message_reroute_event(mobility: MultiConstellation, event: MessageRerouteEvent)
- handle_event(mobility: MultiConstellation, event: Event) list[Event]
Handle an event.
- Parameters:
mobility – The mobility model to handle the event with.
event – The event to handle.
- Returns:
List of events to add to the event queue.