diff --git a/.gitmodules b/.gitmodules index 83544d54d..65d5ef54e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -950,6 +950,9 @@ [submodule "vendor/grammars/ocaml.tmbundle"] path = vendor/grammars/ocaml.tmbundle url = https://github.com/textmate/ocaml.tmbundle +[submodule "vendor/grammars/omnetpp-textmate-msg"] + path = vendor/grammars/omnetpp-textmate-msg + url = https://github.com/omnetpp/omnetpp-textmate-msg.git [submodule "vendor/grammars/omnetpp-textmate-ned"] path = vendor/grammars/omnetpp-textmate-ned url = https://github.com/omnetpp/omnetpp-textmate-ned.git diff --git a/grammars.yml b/grammars.yml index b711da658..0c8d52b1b 100644 --- a/grammars.yml +++ b/grammars.yml @@ -890,6 +890,8 @@ vendor/grammars/ocaml.tmbundle: - source.ocaml - source.ocamllex - source.ocamlyacc +vendor/grammars/omnetpp-textmate-msg: +- source.msg vendor/grammars/omnetpp-textmate-ned: - source.ned vendor/grammars/ooc.tmbundle: diff --git a/lib/linguist/generic.yml b/lib/linguist/generic.yml index 9c911f495..68386f2c9 100644 --- a/lib/linguist/generic.yml +++ b/lib/linguist/generic.yml @@ -16,6 +16,7 @@ extensions: - ".9" - ".app" - ".cmp" +- ".msg" - ".resource" - ".sol" - ".stl" diff --git a/lib/linguist/heuristics.yml b/lib/linguist/heuristics.yml index e89672763..923303e6d 100644 --- a/lib/linguist/heuristics.yml +++ b/lib/linguist/heuristics.yml @@ -504,6 +504,10 @@ disambiguations: - negative_pattern: '/\*' - pattern: '^\s*\.(?:include\s|globa?l\s|[A-Za-z][_A-Za-z0-9]*:)' - language: MAXScript +- extensions: ['.msg'] + rules: + - language: omnetpp-msg + pattern: '^cplusplus \{\{|^namespace[\s]*([^.\s]*\.)*[^.\s]*;|^struct \{|^message [\S]* (extends)? [\S]*[\s]*\{|^packet \{|^class (extends) [\S]*[\s]*\{|^enum \{|^import ([^.\s]*\.)*[^.\s]*;' - extensions: ['.n'] rules: - language: Roff diff --git a/lib/linguist/languages.yml b/lib/linguist/languages.yml index 802f2fe89..b5eebfe28 100644 --- a/lib/linguist/languages.yml +++ b/lib/linguist/languages.yml @@ -8606,6 +8606,14 @@ nesC: ace_mode: text tm_scope: source.nesc language_id: 417 +omnetpp-msg: + type: programming + extensions: + - ".msg" + color: "#a0e0a0" + tm_scope: source.msg + ace_mode: text + language_id: 664100008 omnetpp-ned: type: programming extensions: diff --git a/samples/omnetpp-msg/GptpPacket.msg b/samples/omnetpp-msg/GptpPacket.msg new file mode 100644 index 000000000..735cc46db --- /dev/null +++ b/samples/omnetpp-msg/GptpPacket.msg @@ -0,0 +1,250 @@ +// +// Copyright (C) 2020 OpenSim Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later +// + +// +// @authors: Enkhtuvshin Janchivnyambuu +// Henning Puttnies +// Peter Danielis +// University of Rostock, Germany +// + +import inet.clock.common.ClockEvent; +import inet.clock.contract.ClockTime; +import inet.common.TagBase; +import inet.common.packet.chunk.Chunk; +import inet.common.packet.Packet; + +cplusplus {{ +#include "inet/common/Units.h" +#include "inet/clock/common/ClockEvent.h" + +namespace inet { + +using namespace inet::units::values; +const B GPTP_HEADER_SIZE = B(34); +const B GPTP_TLV_SIZE = B(4); +const B GPTP_FOLLOW_UP_INFORMATION_TLV_BODYSIZE = B(28); +const B GPTP_SYNC_1STEP_PACKET_SIZE = GPTP_HEADER_SIZE + B(10) + GPTP_TLV_SIZE + GPTP_FOLLOW_UP_INFORMATION_TLV_BODYSIZE; +const B GPTP_SYNC_2STEP_PACKET_SIZE = GPTP_HEADER_SIZE + B(10); +const B GPTP_FOLLOW_UP_PACKET_SIZE = GPTP_HEADER_SIZE + B(10) + GPTP_TLV_SIZE + GPTP_FOLLOW_UP_INFORMATION_TLV_BODYSIZE; +const B GPTP_PDELAY_REQ_PACKET_SIZE = GPTP_HEADER_SIZE + B(20); +const B GPTP_PDELAY_RESP_PACKET_SIZE = GPTP_HEADER_SIZE + B(20); +const B GPTP_PDELAY_RESP_FOLLOW_UP_PACKET_SIZE = GPTP_HEADER_SIZE + B(20); +} + +}} + +namespace inet; + +@property[bit](type=int; usage=field; desc="define stored size in bits"); + +enum GptpNodeType +{ + MASTER_NODE = 11; + BRIDGE_NODE = 12; + SLAVE_NODE = 13; +} + +enum GptpPortType +{ + MASTER_PORT = 2; + SLAVE_PORT = 1; + PASSIVE_PORT = 0; +} + +enum GptpMessageType +{ + GPTPTYPE_SYNC = 0x0; + GPTPTYPE_FOLLOW_UP = 0x8; + GPTPTYPE_PDELAY_REQ = 0x2; + GPTPTYPE_PDELAY_RESP = 0x3; + GPTPTYPE_PDELAY_RESP_FOLLOW_UP = 0xA; +} + +enum GptpSelfMsgKind { + GPTP_SELF_REQ_ANSWER_KIND = 101; + GPTP_SELF_MSG_SYNC = 103; + GPTP_REQUEST_TO_SEND_SYNC = 104; + GPTP_SELF_MSG_PDELAY_REQ = 105; +} + +// ieee802.1AS-2020 10.6.2.2.8: flags (Octet2) +// Table 10-9—Values of flag bits +enum GptpFlags { + alternateMasterFlag = 1; // Not used in this standard; transmitted as FALSE and ignored on reception + twoStepFlag = 2; // For Sync messages: + // a) For a one-step transmitting PTP Port (see 11.1.3 and 11.2.13.9), the value is FALSE. + // b) For a two-step transmitting PTP Port, the value is TRUE. + // For Pdelay_Resp messages: The value is transmitted as TRUE and ignored on reception + + // TODO add more flags +} + +enum GptpTlvType { + GPTP_FOLLOW_UP_INFORMATION_TLV = 0x03; +} + +//struct Timestamp +//{ +// UInteger48 seconds; +// UInteger32 nanoseconds; +//}; + +//struct ExtendedTimestamp +//{ +// UInteger48 seconds; +// UInteger48 fractionalNanoseconds; +//}; + +//typedef Octet8 ClockIdentity; + +struct PortIdentity +{ + @packetData; + uint64_t clockIdentity; + uint16_t portNumber; +}; + +//struct ClockQuality +//{ +// UInteger8 clockClass; +// Enumeration8 clockAccuracy; +// UInteger16 offsetScaledLogVariance; +//}; + +message GptpReqAnswerEvent extends ClockEvent +{ + int portId; + clocktime_t ingressTimestamp; + PortIdentity sourcePortIdentity; + uint16_t sequenceId; +} + +// ieee802.1AS-2020 10.6.2.1, 11.4.2 +class GptpBase extends FieldsChunk +{ + uint8_t majorSdoId @bit(4); // The value is specified in 8.1 for all transmitted PTP messages of a gPTP domain. The value is specified in + // 11.2.17 for all transmitted PTP messages of the Common Mean Link Delay Service. Any PTP message + // received for which the value is not one of the values specified in those subclauses shall be ignored. + GptpMessageType messageType @bit(4); + uint8_t minorVersionPTP @bit(4) = 1; // For transmitted messages, the value shall be 1 (see 7.5.4 and 13.3.2.5 of IEEE Std 1588-2019). + // For received messages, the value is ignored. + uint8_t versionPTP @bit(4) = 2; // For transmitted messages, the value shall be 2 (see 7.5.4 and 13.3.2.4 of IEEE Std 1588-2019). For received + // messages, if the value is not 2, the entire message shall be ignored. + uint16_t messageLengthField @bit(16); // The value is the total number of octets that form the PTP message. + uint8_t domainNumber @bit(8); // The domainNumber for Pdelay_Req, Pdelay_Resp, and Pdelay_Resp_Follow_Up messages shall be 0. + // The domainNumber for all other PTP messages is as specified in 10.6.2.2.6. + uint8_t minorSdoId @bit(8); // The value is specified in 8.1 for all transmitted PTP messages of a gPTP domain. The value is specified in + // 11.2.17 for all transmitted PTP messages of the Common Mean Link Delay Service. Any PTP message + // received for which the value is not one of the values specified in those subclauses shall be ignored. + // Currently unused in INET + uint16_t flags @bit(16); // 10.6.2.2.8 flags (Octet2) + // The value of the bits of the array are defined in Table 10-9. For message types where the bit is not defined in + // Table 10-9, the value of the bit is set to FALSE. + // Use ~GptpFlags enums. + clocktime_t correctionField @bit(64) = 0; // The correctionField is the value of the correction as specified in Table 11-6, measured in nanoseconds and + // multiplied by 2^16. For example, 2.5 ns is represented as 0x0000000000028000. + uint32_t messageTypeSpecific @bit(32); // The value of the messageTypeSpecific field varies, based on the value of the messageType field, as described in Table 10-10. + PortIdentity sourcePortIdentity @bit(80); // The value is the PTP Port identity attribute (see 8.5.2) of the PTP Port that transmits the PTP message. + uint16_t sequenceId @bit(16); // The sequenceId field is assigned as specified in 10.5.7. + uint8_t controlField @bit(8) = 0; // The value is 0. + uint8_t logMessageInterval @bit(8); // For Sync and Follow_Up messages, the value is the value of currentLogSyncInterval (see 10.2.5.4 and + // 10.7.2.3). For Pdelay_Req messages, the value is the value of currentLogPdelayReqInterval. For + // Pdelay_Resp and Pdelay_Resp_Follow_Up messages, the value is transmitted as 0x7F and ignored on + // reception. +} + +class GptpTlv extends cObject { + @packetData; + GptpTlvType tlvType @bit(16); + uint16_t lengthField @bit(16); +} + +// The fields of the Follow_Up information TLV shall be as specified in Table 11-11 and in 11.4.4.3.2 through +// 11.4.4.3.9. This TLV is a standard organization extension TLV for the Follow_Up message, as specified in +// 14.3 of IEEE Std 1588-2019. +// NOTE—The Follow_Up information TLV is different from the CUMULATIVE_RATE_RATIO TLV of IEEE Std 1588- +// 2019 (see 16.10 and Table 52 of IEEE Std 1588-2019). While both TLVs carry cumulative rate offset information, the +// Follow_Up information TLV also carries information on the Grandmaster Clock time base, most recent phase change, +// and most recent frequency change. The CUMULATIVE_RATE_RATIO TLV is not used by gPTP. +class GptpFollowUpInformationTlv extends GptpTlv +{ + tlvType = GPTP_FOLLOW_UP_INFORMATION_TLV; + lengthField @bit(16) = B(GPTP_FOLLOW_UP_INFORMATION_TLV_BODYSIZE).get(); + uint32_t organizationId @bit(24) = 0x0080C2; + uint32_t organizationSubType @bit(24) = 1; + double rateRatio @bit(32); // 11.4.4.3.6 The value of cumulativeScaledRateOffset is equal to (rateRatio – 1.0) / (2^41), truncated to the next smaller + // signed integer, where rateRatio is the ratio of the frequency of the Grandmaster Clock to the frequency of the + // LocalClock entity in the PTP Instance that sends the message. + uint16_t gmTimeBaseIndicator @bit(16); // The value of gmTimeBaseIndicator is the timeBaseIndicator of the ClockSource entity for the current + // Grandmaster PTP Instance (see 9.2.2.3). + clocktime_t lastGmPhaseChange @bit(96); // The value of lastGmPhaseChange is the time of the current Grandmaster Clock minus the time of the + // previous Grandmaster Clock, at the time that the current Grandmaster PTP Instance became the + // Grandmaster PTP Instance. The value is copied from the lastGmPhaseChange member of the MDSyncSend + // structure whose receipt causes the MD entity to send the Follow_Up message (see 11.2.11). + int32_t scaledLastGmFreqChange @bit(32); // The value of scaledLastGmFreqChange is the fractional frequency offset of the current Grandmaster Clock + // relative to the previous Grandmaster Clock, at the time that the current Grandmaster PTP Instance became + // the Grandmaster PTP Instance, or relative to itself prior to the last change in gmTimeBaseIndicator, + // multiplied by 241 and truncated to the next smaller signed integer. The value is obtained by multiplying the + // lastGmFreqChange member of MDSyncSend whose receipt causes the MD entity to send the Follow_Up + // message (see 11.2.11) by 241, and truncating to the next smaller signed integer. +} + +cplusplus(GptpFollowUpInformationTlv) {{ + void setCumulativeScaledRateOffset(int32_t x) { setRateRatio(1.0 + (double)(x) / (double)((uint64_t)1<<41)); } + int32_t getCumulativeScaledRateOffset() const { return (int32_t)ceil((getRateRatio() - 1.0) * (double)((uint64_t)1<<41)); } +}} + +class GptpSync extends GptpBase +{ + messageType = GPTPTYPE_SYNC; + flags = twoStepFlag; + chunkLength = GPTP_SYNC_2STEP_PACKET_SIZE; + messageLengthField = B(GPTP_SYNC_2STEP_PACKET_SIZE).get(); + // clocktime_t originTimestamp; // filled when twoStep flag is FALSE + // followUpInformationTLV; // filled when twoStep flag is FALSE +} + +class GptpFollowUp extends GptpBase +{ + messageType = GPTPTYPE_FOLLOW_UP; + chunkLength = GPTP_FOLLOW_UP_PACKET_SIZE; + messageLengthField = B(GPTP_FOLLOW_UP_PACKET_SIZE).get(); + clocktime_t preciseOriginTimestamp; // 11.4.4.2.1 + GptpFollowUpInformationTlv followUpInformationTLV; +} + +class GptpPdelayReq extends GptpBase +{ + messageType = GPTPTYPE_PDELAY_REQ; + chunkLength = GPTP_PDELAY_REQ_PACKET_SIZE; + messageLengthField = B(GPTP_PDELAY_REQ_PACKET_SIZE).get(); + clocktime_t reserved1; + clocktime_t reserved2; +} + +class GptpPdelayResp extends GptpBase +{ + messageType = GPTPTYPE_PDELAY_RESP; + chunkLength = GPTP_PDELAY_RESP_PACKET_SIZE; + messageLengthField = B(GPTP_PDELAY_RESP_PACKET_SIZE).get(); + clocktime_t requestReceiptTimestamp; + PortIdentity requestingPortIdentity; +} + +class GptpPdelayRespFollowUp extends GptpBase +{ + messageType = GPTPTYPE_PDELAY_RESP_FOLLOW_UP; + chunkLength = GPTP_PDELAY_RESP_FOLLOW_UP_PACKET_SIZE; + messageLengthField = B(GPTP_PDELAY_RESP_FOLLOW_UP_PACKET_SIZE).get(); + clocktime_t responseOriginTimestamp; + PortIdentity requestingPortIdentity; +} + +class GptpIngressTimeInd extends TagBase +{ + clocktime_t arrivalClockTime; +} diff --git a/samples/omnetpp-msg/TcpConnection.msg b/samples/omnetpp-msg/TcpConnection.msg new file mode 100644 index 000000000..8dee3fe0a --- /dev/null +++ b/samples/omnetpp-msg/TcpConnection.msg @@ -0,0 +1,66 @@ +// +// Copyright (C) 2016 OpenSim Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later +// + +import inet.common.INETDefs; +import inet.common.packet.ChunkBuffer; +import inet.common.packet.ChunkQueue; +import inet.common.packet.Packet; +import inet.networklayer.common.L3Address; +import inet.transportlayer.tcp.TcpConnectionState; + +cplusplus {{ +#include "inet/transportlayer/tcp/Tcp.h" +#include "inet/transportlayer/tcp/TcpAlgorithm.h" +#include "inet/transportlayer/tcp/TcpConnection.h" +#include "inet/transportlayer/tcp/TcpReceiveQueue.h" +#include "inet/transportlayer/tcp/TcpSackRexmitQueue.h" +#include "inet/transportlayer/tcp/TcpSendQueue.h" +#include "inet/transportlayer/tcp_common/TcpHeader.h" +}} + +namespace inet::tcp; + +class TcpSackRexmitQueue { @existingClass; } +class TcpAlgorithm extends cObject { @existingClass; } + +class TcpSendQueue extends cObject +{ + @existingClass; + @descriptor(readonly); + ChunkQueue dataBuffer; +} + +class TcpReceiveQueue extends cObject +{ + @existingClass; + @descriptor(readonly); + ReorderBuffer reorderBuffer; +} + +class TcpConnection extends cObject +{ + @existingClass; + @descriptor(readonly); + + int socketId; // identifies connection within the app + int listeningSocketId; // identifies listening connection within the app + + // socket pair + L3Address localAddr @getter(getLocalAddress); + L3Address remoteAddr @getter(getRemoteAddress); + int localPort; + int remotePort; + + TcpStateVariables *state; + + // TCP queues + TcpSendQueue *sendQueue; + TcpReceiveQueue *receiveQueue; + TcpSackRexmitQueue *rexmitQueue; + + TcpAlgorithm *tcpAlgorithm; + int fsmState; +}; diff --git a/samples/omnetpp-msg/TcpConnectionState.msg b/samples/omnetpp-msg/TcpConnectionState.msg new file mode 100644 index 000000000..3ec8881e3 --- /dev/null +++ b/samples/omnetpp-msg/TcpConnectionState.msg @@ -0,0 +1,242 @@ +// +// Copyright (C) 2022 OpenSim Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later +// + +import inet.common.INETDefs; +import inet.transportlayer.tcp_common.TcpHeader; + +namespace inet::tcp; + +cplusplus {{ +typedef std::list SackList; +}} + +class SackList { @existingClass; } + +// +// TCP FSM states +// +// Brief descriptions (cf RFC 793, page 20): +// +// LISTEN - waiting for a connection request +// SYN-SENT - part of 3-way handshake (waiting for peer's SYN+ACK or SYN) +// SYN-RECEIVED - part of 3-way handshake (we sent SYN too, waiting for it to be acked) +// ESTABLISHED - normal data transfer +// FIN-WAIT-1 - FIN sent, waiting for its ACK (or peer's FIN) +// FIN-WAIT-2 - our side of the connection closed (our FIN acked), waiting for peer's FIN +// CLOSE-WAIT - FIN received and acked, waiting for local user to close +// LAST-ACK - remote side closed, FIN sent, waiting for its ACK +// CLOSING - simultaneous close: sent FIN, then got peer's FIN +// TIME-WAIT - both FIN's acked, waiting for some time to be sure remote TCP received our ACK +// CLOSED - represents no connection state at all. +// +// Note: FIN-WAIT-1, FIN-WAIT-2, CLOSING, TIME-WAIT represents active close (that is, +// local user closes first), and CLOSE-WAIT and LAST-ACK represents passive close. +// +enum TcpState { + TCP_S_INIT = 0; + TCP_S_CLOSED = 1; + TCP_S_LISTEN = 2; + TCP_S_SYN_SENT = 3; + TCP_S_SYN_RCVD = 4; + TCP_S_ESTABLISHED = 5; + TCP_S_CLOSE_WAIT = 6; + TCP_S_LAST_ACK = 7; + TCP_S_FIN_WAIT_1 = 8; + TCP_S_FIN_WAIT_2 = 9; + TCP_S_CLOSING = 10; + TCP_S_TIME_WAIT = 11; +}; + +// +// Event, strictly for the FSM state transition purposes. +// DO NOT USE outside performStateTransition()! +// +enum TcpEventCode { + TCP_E_IGNORE = 0; + + // app commands + // (Note: no RECEIVE command, data are automatically passed up) + TCP_E_OPEN_ACTIVE = 1; + TCP_E_OPEN_PASSIVE = 2; + TCP_E_ACCEPT = 3; + TCP_E_SEND = 4; + TCP_E_CLOSE = 5; + TCP_E_ABORT = 6; + TCP_E_DESTROY = 7; + TCP_E_STATUS = 8; + TCP_E_QUEUE_BYTES_LIMIT = 9; + TCP_E_READ = 10; + TCP_E_SETOPTION = 11; + + // TPDU types + TCP_E_RCV_DATA = 12; + TCP_E_RCV_ACK = 13; + TCP_E_RCV_SYN = 14; + TCP_E_RCV_SYN_ACK = 15; + TCP_E_RCV_FIN = 16; + TCP_E_RCV_FIN_ACK = 17; + TCP_E_RCV_RST = 18; // covers RST+ACK too + + TCP_E_RCV_UNEXP_SYN = 19; // unexpected SYN + + // timers + TCP_E_TIMEOUT_2MSL = 20; // RFC 793, a.k.a. TIME-WAIT timer + TCP_E_TIMEOUT_CONN_ESTAB = 21; + TCP_E_TIMEOUT_FIN_WAIT_2 = 22; + + // All other timers (REXMT, PERSIST, DELAYED-ACK, KEEP-ALIVE, etc.), + // are handled in TcpAlgorithm. +}; + +// +// Contains state variables ("TCB") for TCP. +// +// TcpStateVariables is effectively a "struct" -- it only contains +// public data members. (Only declared as a class so that we can use +// cObject as base class and make it possible to inspect +// it in Tkenv.) +// +// TcpStateVariables only contains variables needed to implement +// the "base" (RFC 793) TCP. More advanced TCP variants are encapsulated +// into TcpAlgorithm subclasses which can have their own state blocks, +// subclassed from TcpStateVariables. See TcpAlgorithm::createStateVariables(). +// +struct TcpStateVariables +{ + @implements(cObject); + @descriptor(readonly); + + bool active = false; // set if the connection was initiated by an active open + bool fork = false; // if passive and in LISTEN: whether to fork on an incoming connection + + uint32_t snd_mss = 0; // sender maximum segment size (without headers, i.e. only segment text); see RFC 2581, page 1. + // This will be set to the minimum of the local smss parameter and the value specified in the + // MSS option received during connection setup. + + // send sequence number variables (see RFC 793, "3.2. Terminology") + uint32_t snd_una = 0; // send unacknowledged + uint32_t snd_nxt = 0; // send next (drops back on retransmission) + uint32_t snd_max = 0; // max seq number sent (needed because snd_nxt is re-set on retransmission) + uint32_t snd_wnd = 0; // send window + uint32_t snd_up = 0; // send urgent pointer + uint32_t snd_wl1 = 0; // segment sequence number used for last window update + uint32_t snd_wl2 = 0; // segment ack. number used for last window update + uint32_t iss = 0; // initial sequence number (ISS) + + // receive sequence number variables + uint32_t rcv_nxt = 0; // receive next + uint32_t rcv_wnd = 0; // receive window + uint32_t rcv_up = 0; // receive urgent pointer; + uint32_t irs = 0; // initial receive sequence number + uint32_t rcv_adv = 0; // advertised window + + // SYN, SYN+ACK retransmission variables (handled separately + // because normal rexmit belongs to TcpAlgorithm) + int syn_rexmit_count = 0; // number of SYN/SYN+ACK retransmissions (=1 after first rexmit) + simtime_t syn_rexmit_timeout; // current SYN/SYN+ACK retransmission timeout + + // whether ACK of our FIN has been received. Needed in FIN bit processing + // to decide between transition to TIME-WAIT and CLOSING (set event code + // TCP_E_RCV_FIN or TCP_E_RCV_FIN_ACK). + bool fin_ack_rcvd = false; + + bool send_fin = false; // true if a user CLOSE command has been "queued" + uint32_t snd_fin_seq = 0; // if send_fin == true: FIN should be sent just before this sequence number + + bool fin_rcvd = false; // whether FIN received or not + uint32_t rcv_fin_seq = 0; // if fin_rcvd: sequence number of received FIN + + bool nagle_enabled = false; // set if Nagle's algorithm (RFC 896) is enabled + bool delayed_acks_enabled = false; // set if delayed ACK algorithm (RFC 1122) is enabled + bool limited_transmit_enabled = false; // set if Limited Transmit algorithm (RFC 3042) is enabled + bool increased_IW_enabled = false; // set if Increased Initial Window (RFC 3390) is enabled + + uint32_t full_sized_segment_counter = 0; // this counter is needed for delayed ACK + bool ack_now = false; // send ACK immediately, needed if delayed_acks_enabled is set + // Based on [Stevens, W.R.: TCP/IP Illustrated, Volume 2, page 861]. + // ack_now should be set when: + // - delayed ACK timer expires + // - an out-of-order segment is received + // - SYN is received during the three-way handshake + // - a persist probe is received + // - FIN is received + + bool afterRto = false; // set at RTO, reset when snd_nxt == snd_max or snd_una == snd_max + + // WINDOW_SCALE related variables + bool ws_support = false; // set if the host supports Window Scale (header option) (RFC 1323) + bool ws_enabled = false; // set if the connection uses Window Scale (header option) + int ws_manual_scale = -1; // the value of scale parameter if it was set manually (-1 otherwise) + bool snd_ws = false; // set if initial WINDOW_SCALE has been sent + bool rcv_ws = false; // set if initial WINDOW_SCALE has been received + unsigned int rcv_wnd_scale = 0; // RFC 1323, page 31: "Receive window scale power" + unsigned int snd_wnd_scale = 0; // RFC 1323, page 31: "Send window scale power" + + // TIMESTAMP related variables + bool ts_support = false; // set if the host supports Timestamps (header option) (RFC 1322) + bool ts_enabled = false; // set if the connection uses Window Scale (header option) + bool snd_initial_ts = false; // set if initial TIMESTAMP has been sent + bool rcv_initial_ts = false; // set if initial TIMESTAMP has been received + uint32_t ts_recent = 0; // RFC 1323, page 31: "Latest received Timestamp" + uint32_t last_ack_sent = 0; // RFC 1323, page 31: "Last ACK field sent" + simtime_t time_last_data_sent; // time at which the last data segment was sent (needed to compute the IDLE time for PAWS) + + // SACK related variables + bool sack_support = false; // set if the host supports selective acknowledgment (header option) (RFC 2018, 2883, 3517) + bool sack_enabled = false; // set if the connection uses selective acknowledgment (header option) + bool snd_sack_perm = false; // set if SACK_PERMITTED has been sent + bool rcv_sack_perm = false; // set if SACK_PERMITTED has been received + uint32_t start_seqno = 0; // start sequence number of last received out-of-order segment + uint32_t end_seqno = 0; // end sequence number of last received out-of-order segment + bool snd_sack = false; // set if received vaild out-of-order segment or rcv_nxt changed, but receivedQueue is not empty + bool snd_dsack = false; // set if received duplicated segment (sequenceNo+PLength < rcv_nxt) or (segment is not acceptable) + SackList sacks_array; // MAX_SACK_BLOCKS is set to 60 + uint32_t highRxt = 0; // RFC 3517, page 3: ""HighRxt" is the highest sequence number which has been retransmitted during the current loss recovery phase." + uint32_t pipe = 0; // RFC 3517, page 3: ""Pipe" is a sender's estimate of the number of bytes outstanding in the network." + uint32_t recoveryPoint = 0; // RFC 3517 + uint32_t sackedBytes = 0; // number of sackedBytes + uint32_t sackedBytes_old = 0; // old number of sackedBytes - needed for RFC 3042 to check if last dupAck contained new sack information + bool lossRecovery = false; // indicates if algorithm is in loss recovery phase + + // queue management + uint32_t sendQueueLimit = 0; + bool queueUpdate = true; + + // those counters would logically belong to TcpAlgorithm, but it's a lot easier to manage them here + uint32_t dupacks = 0; // current number of received consecutive duplicate ACKs + uint32_t snd_sacks = 0; // number of sent sacks + uint32_t rcv_sacks = 0; // number of received sacks + uint32_t rcv_oooseg = 0; // number of received out-of-order segments + uint32_t rcv_naseg = 0; // number of received not acceptable segments + + // receiver buffer / receiver queue related variables + uint32_t maxRcvBuffer = 0; // maximal amount of bytes in tcp receive queue + uint32_t usedRcvBuffer = 0; // current amount of used bytes in tcp receive queue + uint32_t freeRcvBuffer = 0; // current amount of free bytes in tcp receive queue + uint32_t tcpRcvQueueDrops = 0; // number of drops in tcp receive queue + + // ECN + bool ecnEchoState = false; // indicates if connection is in echo mode (got CE indication from IP and didn't get CWR from sender yet) + bool sndCwr = false; // set if ECE was handled + bool gotEce = false; // set if packet with ECE arrived + bool gotCeIndication = false; // set if CE was set in controlInfo from IP + bool ect = false; // set if this connection is ECN Capable (ECT stands for ECN-Capable transport - rfc-3168) + bool endPointIsWillingECN = false; // set if the other end-point is willing to use ECN + bool ecnSynSent = false; // set if ECN-setup SYN packet was sent + bool ecnWillingness = false; // set if current host is willing to use ECN + bool sndAck = false; // set if sending Ack packet, used to set relevant info in controlInfo. + bool rexmit = false; // set if retransmitting data, used to send not-ECT codepoint (rfc3168, p. 20) + simtime_t eceReactionTime; // records the time of the last ECE reaction + + uint32_t dupthresh = 0; // used for TcpTahoe, TcpReno and SACK (RFC 3517) +}; + +cplusplus(TcpStateVariables) {{ + public: + virtual ~TcpStateVariables(); + virtual std::string str() const override; + virtual std::string detailedInfo() const; +}} diff --git a/test/test_heuristics.rb b/test/test_heuristics.rb index a81d81b3e..ed2800210 100755 --- a/test/test_heuristics.rb +++ b/test/test_heuristics.rb @@ -723,6 +723,12 @@ def test_ms_by_heuristics }) end + def test_msg_by_heuristics + assert_heuristics({ + "omnetpp-msg" => all_fixtures("omnetpp-msg", "*.msg"), + }) + end + def test_n_by_heuristics assert_heuristics({ "Roff" => all_fixtures("Roff", "*.n"), diff --git a/vendor/README.md b/vendor/README.md index cf3204e36..f2b1a53f6 100644 --- a/vendor/README.md +++ b/vendor/README.md @@ -680,6 +680,7 @@ This is a list of grammars that Linguist selects to provide syntax highlighting - **mupad:** [ccreutzig/sublime-MuPAD](https://github.com/ccreutzig/sublime-MuPAD) - **nanorc:** [Alhadis/language-etc](https://github.com/Alhadis/language-etc) - **nesC:** [cdwilson/nesC.tmbundle](https://github.com/cdwilson/nesC.tmbundle) +- **omnetpp-msg:** [omnetpp/omnetpp-textmate-msg](https://github.com/omnetpp/omnetpp-textmate-msg) - **omnetpp-ned:** [omnetpp/omnetpp-textmate-ned](https://github.com/omnetpp/omnetpp-textmate-ned) - **ooc:** [nilium/ooc.tmbundle](https://github.com/nilium/ooc.tmbundle) - **q:** [komsit37/sublime-q](https://github.com/komsit37/sublime-q) diff --git a/vendor/grammars/omnetpp-textmate-msg b/vendor/grammars/omnetpp-textmate-msg new file mode 160000 index 000000000..e14a5524b --- /dev/null +++ b/vendor/grammars/omnetpp-textmate-msg @@ -0,0 +1 @@ +Subproject commit e14a5524b6bb4420ee578331698735c1e0bd0a7e diff --git a/vendor/licenses/git_submodule/omnetpp-textmate-msg.dep.yml b/vendor/licenses/git_submodule/omnetpp-textmate-msg.dep.yml new file mode 100644 index 000000000..04bb6fbf9 --- /dev/null +++ b/vendor/licenses/git_submodule/omnetpp-textmate-msg.dep.yml @@ -0,0 +1,31 @@ +--- +name: omnetpp-textmate-msg +version: e14a5524b6bb4420ee578331698735c1e0bd0a7e +type: git_submodule +homepage: https://github.com/omnetpp/omnetpp-textmate-msg.git +license: mit +licenses: +- sources: LICENSE + text: | + MIT License + + Copyright (c) 2024 OpenSim Ltd. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +notices: []