/// <summary> /// Analyse the frame header, calculate RTO. /// </summary> /// <param name="fh_message">The fh_message.</param> /// <param name="reload_connection">The reload_connection.</param> /// <returns></returns> private byte[] analyseFrameHeader(SimpleOverlayConnectionTableElement connectionTableEntry, byte[] fh_message) { if (ReloadGlobals.Framing) { /* Handle FrameHeader */ FramedMessageType type = (FramedMessageType)fh_message[0]; if (type == FramedMessageType.ack) { FramedMessageAck fh_ack = FMA_FromBytes(fh_message); m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_FH, String.Format("Rx FH ACK {0}, 0x{1:x}", fh_ack.ack_sequence, fh_ack.received)); /* Calculate RTO */ DateTime sent; if (connectionTableEntry.fh_sent.TryGetValue(fh_ack.ack_sequence, out sent)) { long rtt = DateTime.Now.Ticks - sent.Ticks; if (connectionTableEntry.srtt == 0.0) { connectionTableEntry.srtt = rtt; connectionTableEntry.rttvar = 0.5 * rtt; connectionTableEntry.rto = new TimeSpan(Convert.ToInt64(rtt + 4 * connectionTableEntry.rttvar)); } else { double alpha = 0.125; double beta = 0.25; connectionTableEntry.srtt = (1.0 - alpha) * connectionTableEntry.srtt + alpha * rtt; connectionTableEntry.rttvar = (1.0 - beta) * connectionTableEntry.rttvar + beta * System.Math.Abs(connectionTableEntry.srtt - rtt); connectionTableEntry.rto = new TimeSpan(Convert.ToInt64(connectionTableEntry.srtt + 4 * connectionTableEntry.rttvar)); } connectionTableEntry.fh_sent.Remove(fh_ack.ack_sequence); m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_FH, String.Format("RTT {0}, SRTT {1}, RTTVAR {2}, RTO {3}", rtt, connectionTableEntry.srtt, connectionTableEntry.rttvar, connectionTableEntry.rto)); } } else { if (type == FramedMessageType.data) { FramedMessageData fh_data = FMD_FromBytes(fh_message); byte[] fh_stripped_data = new byte[fh_message.Length - 8]; Array.Copy(fh_message, 8, fh_stripped_data, 0, fh_message.Length - 8); UInt32 received = 0; UInt32 n = fh_data.sequence; /* Calculate FH received mask */ foreach (UInt32 m in connectionTableEntry.fh_received) { if (m < n || m >= (n - 32)) { UInt32 bit = n - m - 1; if (bit < 32) received |= ((UInt32)1 << (int)bit); } } while (connectionTableEntry.fh_received.Count >= 32) connectionTableEntry.fh_received.Dequeue(); connectionTableEntry.fh_received.Enqueue(fh_data.sequence); /* Acknowledge it */ FramedMessageAck fh_ack = new FramedMessageAck(); fh_ack.type = FramedMessageType.ack; fh_ack.ack_sequence = fh_data.sequence; fh_ack.received = received; m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_FH, String.Format("Tx FH ACK {0}, 0x{1:x}", fh_ack.ack_sequence, fh_ack.received)); //in - offset out - bytesprocessed Send(new Node(connectionTableEntry.NodeID, null), ToBytes(fh_ack)); return fh_stripped_data; } } return null; } else return fh_message; }
public byte[] ToBytes(FramedMessageAck fmack) { MemoryStream ms = new MemoryStream(); using (BinaryWriter writer = new BinaryWriter(ms)) { writer.Write((Byte)fmack.type); writer.Write(System.Net.IPAddress.HostToNetworkOrder((int)fmack.ack_sequence)); writer.Write(System.Net.IPAddress.HostToNetworkOrder((int)fmack.received)); } return ms.ToArray(); }