public override SSUState HandleMessage(SSUHeader header, BufRefLen reader) { DataSent(); #if LOG_ALL_TRANSPORT DebugUtils.Log("SSU EstablishedState +" + Session.TransportInstance.ToString() + "+ received: " + header.MessageType.ToString() + ": " + SSUHost.SSUDateTime(header.TimeStamp).ToString()); #endif switch (header.MessageType) { case SSUHeader.MessageTypes.Data: try { var datamsg = new SSUDataMessage(reader, Session.Defragmenter); if (datamsg.ExplicitAcks != null) { Session.Fragmenter.GotAck(datamsg.ExplicitAcks); } if (datamsg.AckBitfields != null) { Session.Fragmenter.GotAck(datamsg.AckBitfields); } if (datamsg.NewMessages != null) { foreach (var msg in datamsg.NewMessages) { var i2npmsg = I2NPMessage.ReadHeader5((BufRefLen)msg.GetPayload()); #if LOG_ALL_TRANSPORT DebugUtils.Log("SSU EstablishedState +" + Session.TransportInstance.ToString() + "+ complete message " + msg.MessageId.ToString() + ": " + i2npmsg.Expiration.ToString()); #endif if (i2npmsg.MessageType == I2PCore.Tunnel.I2NP.Messages.I2NPMessage.MessageTypes.DeliveryStatus) { if (((DeliveryStatusMessage)i2npmsg.Message).IsNetworkId((ulong)I2PConstants.I2P_NETWORK_ID)) { continue; } } Session.MessageReceived(i2npmsg); } } } catch (Exception ex) { DebugUtils.Log("EstablishedState: SSUHost.SSUMessageTypes.Data", ex); } break; case SSUHeader.MessageTypes.SessionDestroyed: DebugUtils.LogDebug(() => string.Format("SSU EstablishedState {0}: SessionDestroyed received.", Session.DebugId)); SendSessionDestroyed(); return(null); case SSUHeader.MessageTypes.PeerTest: HandleIncomingPeerTestPackage(reader); break; case SSUHeader.MessageTypes.RelayResponse: DebugUtils.LogDebug(() => string.Format("SSU EstablishedState {0}: RelayResponse received from {1}.", Session.DebugId, Session.RemoteEP)); var response = new RelayResponse(reader); Session.Host.ReportRelayResponse(header, response, Session.RemoteEP); break; case SSUHeader.MessageTypes.RelayIntro: var intro = new RelayIntro(reader); DebugUtils.LogDebug(() => $"SSU EstablishedState {Session.DebugId}: RelayIntro received from {Session.RemoteEP} for {intro.AliceEndpoint}."); Session.Host.Send(intro.AliceEndpoint, new BufLen(new byte[0])); break; case SSUHeader.MessageTypes.RelayRequest: // if ( !SSUHost.IntroductionSupported ) throw new Exception( "SSU relay introduction not supported" ); DebugUtils.LogDebug(() => string.Format("SSU EstablishedState {0}: Relay introduction not supported.", Session.DebugId)); break; case SSUHeader.MessageTypes.SessionRequest: DebugUtils.LogDebug(() => string.Format("SSU EstablishedState {0}: SessionRequest received. Ending session.", Session.DebugId)); SendSessionDestroyed(); return(null); default: DebugUtils.LogDebug(() => string.Format("SSU EstablishedState {0}: Unexpected message received: {1}.", Session.DebugId, header.MessageType)); break; } return(this); }
public void TestSSUOutOfOrderFragmentation() { var fragmenter = new DataFragmenter(); var smalldata = new BufLen(BufUtils.Random(4 + BufUtils.RandomInt(4))); var smalldatamessage = new I2PCore.Tunnel.I2NP.Messages.DataMessage(smalldata); var smalldata1 = new BufLen(BufUtils.Random(40 + BufUtils.RandomInt(14))); var smalldatamessage1 = new I2PCore.Tunnel.I2NP.Messages.DataMessage(smalldata1); var smalldata2 = new BufLen(BufUtils.Random(130 + BufUtils.RandomInt(39))); var smalldatamessage2 = new I2PCore.Tunnel.I2NP.Messages.DataMessage(smalldata2); var smalldata3 = new BufLen(BufUtils.Random(770 + BufUtils.RandomInt(220))); var smalldatamessage3 = new I2PCore.Tunnel.I2NP.Messages.DataMessage(smalldata3); var data = new BufLen(BufUtils.Random(30000 + BufUtils.RandomInt(30))); var datamessage = new I2PCore.Tunnel.I2NP.Messages.DataMessage(data); var data2 = new BufLen(BufUtils.Random(20000 + BufUtils.RandomInt(1040))); var datamessage2 = new I2PCore.Tunnel.I2NP.Messages.DataMessage(data2); var dest = new byte[MTUConfig.BufferSize]; var start = new BufLen(dest); var writer = new BufRefLen(dest); var tosend = new LinkedList <II2NPHeader5>(); tosend.AddLast(smalldatamessage.Header5); tosend.AddLast(datamessage.Header5); tosend.AddLast(smalldatamessage1.Header5); tosend.AddLast(smalldatamessage2.Header5); tosend.AddLast(smalldatamessage3.Header5); tosend.AddLast(datamessage2.Header5); var tosendshuffle = tosend.Shuffle(); var tosendshuffled = new LinkedList <II2NPHeader5>(tosendshuffle); var sent = new LinkedList <II2NPHeader5>(); foreach (var one in tosend) { sent.AddLast(one); } var sentdata = new LinkedList <BufLen>(); while (true) { var flagbuf = writer.ReadBufLen(1); var fragcountbuf = writer.ReadBufLen(1); var fragments = fragmenter.Send(writer, tosendshuffled); if (fragments == 0) { break; } flagbuf[0] |= (byte)I2PCore.Transport.SSU.SSUDataMessage.DataMessageFlags.WantReply; // no ACKs fragcountbuf[0] = (byte)fragments; sentdata.AddLast(new BufLen(start, 0, writer - start)); dest = new byte[MTUConfig.BufferSize]; start = new BufLen(dest); writer = new BufRefLen(dest); } var shuffled = sentdata.Shuffle(); var receivedmessages = new LinkedList <II2NPHeader5>(); var defragmenter = new DataDefragmenter(); foreach (var frag in shuffled) { var datamsg = new I2PCore.Transport.SSU.SSUDataMessage(new BufRefLen(frag), defragmenter); if (datamsg.NewMessages != null) { foreach (var msg in datamsg.NewMessages) { var i2npmsg = I2NPMessage.ReadHeader5((BufRefLen)msg.GetPayload()); receivedmessages.AddLast(i2npmsg); } } } Assert.IsTrue(receivedmessages.Count == sent.Count); foreach (var sentmsg in sent) { Assert.IsTrue(receivedmessages.SingleOrDefault(m => ((I2PCore.Tunnel.I2NP.Messages.DataMessage)m.Message).Payload == ((I2PCore.Tunnel.I2NP.Messages.DataMessage)sentmsg.Message).Payload) != null); } }