public void TestSimpleDatabaseStoreLeaseSetEd25519Creation() { var linfo = new I2PLeaseInfo(Public, PublicSigningEd25519, Private, PrivateSigningEd25519); var leases = new List <I2PLease>(); for (int i = 0; i < 5; ++i) { leases.Add(new I2PLease(new I2PIdentHash(true), (uint)((i * 72 + 6) * i * 1314 + 5) % 40000, I2PDate.Now)); } var ls = new I2PLeaseSet(new I2PDestination(Public, PublicSigningEd25519), leases, linfo); var dbsm = new DatabaseStoreMessage(ls); var data = dbsm.Header16.HeaderAndPayload; var recreated = I2NPMessage.ReadHeader16(new BufRefLen(data)); Assert.IsTrue(recreated.MessageType == I2NPMessage.MessageTypes.DatabaseStore); var rdsm = (DatabaseStoreMessage)recreated.Message; Assert.IsTrue(rdsm.LeaseSet.Leases.Count == 5); Assert.IsTrue(BufUtils.Equal(ls.Destination.ToByteArray(), rdsm.LeaseSet.Destination.ToByteArray())); Assert.IsTrue(BufUtils.Equal(ls.PublicKey.ToByteArray(), rdsm.LeaseSet.PublicKey.ToByteArray())); Assert.IsTrue(BufUtils.Equal(ls.PublicSigningKey.ToByteArray(), rdsm.LeaseSet.PublicSigningKey.ToByteArray())); for (int i = 0; i < 5; ++i) { Assert.IsTrue(BufUtils.Equal(ls.Leases[i].ToByteArray(), rdsm.LeaseSet.Leases[i].ToByteArray())); } Assert.IsTrue(rdsm.LeaseSet.VerifySignature()); }
public void Add(I2NPMessage msg) { lock ( Messages ) { Messages.Add(msg); } }
public virtual void SendRaw(I2NPMessage msg) { lock ( SendQueue ) { SendRawQueue.AddFirst(msg); } }
public void TestSimpleTunnelDataCreation() { var smalldata = BufUtils.RandomBytes(38); var srcmsgs = new List <TunnelMessage>(); srcmsgs.Add(new TunnelMessageLocal(new DeliveryStatusMessage(1234))); var msgfrags = TunnelDataMessage.MakeFragments(srcmsgs, 0x3e5c); Assert.IsTrue(msgfrags.Count() == 1); var firstmsg = msgfrags.First(); var serialized = firstmsg.CreateHeader16.HeaderAndPayload; var recovered = I2NPMessage.ReadHeader16(new BufRefLen(serialized)); var reassembler = new TunnelDataFragmentReassembly(); var reassembledmsgs = reassembler.Process( new TunnelDataMessage[] { (TunnelDataMessage)recovered.Message }, out var _); Assert.IsTrue(reassembledmsgs.Count() == 1); var firstrecinstr = reassembledmsgs.First(); Assert.IsTrue(firstrecinstr.Delivery == TunnelMessage.DeliveryTypes.Local); Assert.IsTrue(firstrecinstr.Message.MessageType == I2NPMessage.MessageTypes.DeliveryStatus); Assert.IsTrue(((DeliveryStatusMessage)firstrecinstr.Message).StatusMessageId == 1234); }
public void TestSimpleDatabaseHeader5StoreCreation() { var mapping = new I2PMapping(); mapping["One"] = "1"; mapping["2"] = "Two"; var ri = new I2PRouterInfo( new I2PRouterIdentity(Public, PublicSigning), I2PDate.Now, new I2PRouterAddress[] { new I2PRouterAddress(new IPAddress(424242L), 773, 42, "SSU") }, mapping, PrivateSigning); var dbsm = new DatabaseStoreMessage(ri); var data = dbsm.CreateHeader16.HeaderAndPayload; var recreated = I2NPMessage.ReadHeader16(new BufRefLen(data)); Assert.IsTrue(recreated.MessageType == I2NPMessage.MessageTypes.DatabaseStore); var rdsm = (DatabaseStoreMessage)recreated.Message; Assert.IsTrue(rdsm.RouterInfo.Options["One"] == "1"); Assert.IsTrue(rdsm.RouterInfo.Options["2"] == "Two"); Assert.IsTrue(rdsm.RouterInfo.VerifySignature()); }
public void Send(I2NPMessage msg) { if (Terminated) { throw new EndOfStreamEncounteredException(); } lock ( SendQueue ) { var len = SendQueue.Count; if (len < SendQueueLengthUpperLimit) { SendQueue.AddLast(msg.Header5); } #if DEBUG else { DebugUtils.LogWarning( string.Format("SSUSession {0}: SendQueue is {1} messages long! Dropping new message. Max queue: {2} ({3:###0}s)", DebugId, len, SessionMaxSendQueueLength, MinTimeBetweenSendQueueLogs.DeltaToNow.ToSeconds)); } SessionMaxSendQueueLength = Math.Max(SessionMaxSendQueueLength, len); if ((len > SendQueueLengthWarningLimit) && (MinTimeBetweenSendQueueLogs.DeltaToNowMilliseconds > 4000)) { DebugUtils.LogWarning( string.Format("SSUSession {0}: SendQueue is {1} messages long! Max queue: {2} ({3:###0}s)", DebugId, len, SessionMaxSendQueueLength, MinTimeBetweenSendQueueLogs.DeltaToNow.ToSeconds)); MinTimeBetweenSendQueueLogs.SetNow(); } #endif } }
public GarlicClove(GarlicCloveDelivery delivery) { Delivery = delivery; Message = delivery.Message; CloveId = BufUtils.RandomUint(); Expiration = new I2PDate(DateTime.UtcNow + TimeSpan.FromSeconds(8)); }
public GarlicClove(GarlicCloveDelivery delivery, I2PDate exp) { Delivery = delivery; Message = delivery.Message; CloveId = BufUtils.RandomUint(); Expiration = exp; }
public void MakeAndReadFragmentsWithSerialize() { var origmsgs = new List <TunnelMessage>(); for (int i = 0; i < 200; ++i) { switch (BufUtils.RandomInt(3)) { case 0: var adatarec = new DataMessage( new BufLen( BufUtils.RandomBytes(2048 + BufUtils.RandomInt(1024)))); origmsgs.Add(new TunnelMessageLocal(adatarec)); break; case 1: var arec = new DatabaseLookupMessage( new I2PIdentHash(true), new I2PIdentHash(true), DatabaseLookupMessage.LookupTypes.RouterInfo); origmsgs.Add(new TunnelMessageRouter( arec, new I2PIdentHash(true))); break; case 2: var adatarec2 = new DataMessage( new BufLen( BufUtils.RandomBytes(2048 + BufUtils.RandomInt(1024)))); origmsgs.Add(new TunnelMessageTunnel(adatarec2, new I2PIdentHash(true), BufUtils.RandomUint())); break; } } var msgs = TunnelDataMessage.MakeFragments(origmsgs, BufUtils.RandomUint()); var recvlist = new List <TunnelDataMessage>(); foreach (var msg in msgs) { recvlist.Add((TunnelDataMessage)I2NPMessage.ReadHeader16( new BufRefLen(msg.CreateHeader16.HeaderAndPayload)).Message); } var mkmsg = new TunnelDataFragmentReassembly(); var recvtmsgs = mkmsg.Process(recvlist, out var _); foreach (var rmsg in recvtmsgs) { Assert.IsTrue(origmsgs.SingleOrDefault(m => m.Delivery == rmsg.Delivery && m.Message.CreateHeader16.HeaderAndPayload == rmsg.Message.CreateHeader16.HeaderAndPayload ) != null); } }
public GarlicClove(BufRef reader) { Delivery = GarlicCloveDelivery.CreateGarlicCloveDelivery(reader); Message = I2NPMessage.ReadHeader16(reader).Message; CloveId = reader.Read32(); Expiration = new I2PDate(reader); reader.Seek(3); // Cert }
public DeliveryStatusMessage() { AllocateBuffer(12); var writer = new BufRefLen(Payload); Timestamp = new I2PDate(DateTime.UtcNow); StatusMessageId = I2NPMessage.GenerateMessageId(); }
public virtual void MessageReceived(I2NPMessage msg, int recvdatasize) { #if LOG_ALL_TUNNEL_TRANSFER Logging.LogDebug($"{this}: MessageReceived {msg.Message}"); #endif Bandwidth.DataReceived(recvdatasize); //Logging.LogDebug( $"{this}: MessageReceived {msg.MessageType} TDM len {recvsize}" ); ReceiveQueue.Enqueue(msg); }
public BufLen GenerateData(I2NPMessage msg) { if (NTCPContext == null) { throw new Exception("NTCP Session not negotiated!"); } if (NTCPContext.Encryptor == null) { throw new Exception("NTCP encryptor not available"); } var data = msg != null ? msg.Header16.HeaderAndPayload: null; var datalength = msg == null ? 4 : data.Length; var buflen = 2 + datalength + 4; var padlength = BufUtils.Get16BytePadding(buflen); buflen += padlength; var buf = new BufLen(new byte[buflen]); var writer = new BufRefLen(buf); // Length if (msg == null) { // Send timestamp writer.Write16(0); writer.WriteFlip32((uint)(DateTime.UtcNow - I2PDate.RefDate).TotalSeconds); } else { if (data.Length > 16378) { throw new ArgumentException("NTCP data can be max 16378 bytes long!"); } writer.WriteFlip16((ushort)data.Length); writer.Write(data); } // Pad writer.Write(BufUtils.Random(writer.Length - 4)); // Checksum var checkbuf = new BufLen(buf, 0, writer - buf); var checksum = LZUtils.Adler32(1, checkbuf); writer.WriteFlip32(checksum); // Encrypt NTCPContext.Encryptor.ProcessBytes(buf); return(buf); }
public void Send(I2NPMessage msg) { if (Terminated) { throw new EndOfStreamEncounteredException(); } var sendqlen = SendQueue.Count; #if DEBUG SessionMaxSendQueueLength = Math.Max(SessionMaxSendQueueLength, sendqlen); if ((SendQueue.Count > SendQueueLengthWarningLimit) && (MinTimeBetweenSendQueueLogs.DeltaToNowMilliseconds > 4000)) { DebugUtils.LogWarning( string.Format("NTCPClient {0}: SendQueue is {1} messages long! Max queue: {2} ({3:###0}s)", DebugId, sendqlen, SessionMaxSendQueueLength, MinTimeBetweenSendQueueLogs.DeltaToNow.ToSeconds)); MinTimeBetweenSendQueueLogs.SetNow(); } #endif lock ( SendQueue ) { if (sendqlen < SendQueueLengthUpperLimit) { SendQueue.AddLast(msg); } #if DEBUG else { DebugUtils.LogWarning( string.Format("NTCPClient {0}: SendQueue is {1} messages long! Dropping new message. Max queue: {2} ({3:###0}s)", DebugId, sendqlen, SessionMaxSendQueueLength, MinTimeBetweenSendQueueLogs.DeltaToNow.ToSeconds)); } #endif } try { TryInitiateSend(); } catch (SocketException ex) { if (NTCPContext.RemoteRouterIdentity != null) { NetDb.Inst.Statistics.FailedToConnect(NTCPContext.RemoteRouterIdentity.IdentHash); } throw new EndOfStreamEncounteredException(ex.ToString()); } }
public void TestGarlicCreate() { var ls = new I2PDate(DateTime.Now + TimeSpan.FromMinutes(5)); var origmessage = new DeliveryStatusMessage(I2NPMessage.GenerateMessageId()); var bigmessage = new DataMessage(new BufLen(BufUtils.RandomBytes(14 * 1024))); var garlic = new Garlic( new GarlicClove( new GarlicCloveDeliveryLocal(origmessage), ls), new GarlicClove( new GarlicCloveDeliveryLocal(bigmessage), ls) ); var egmsg = Garlic.EGEncryptGarlic( garlic, Public, new I2PSessionKey(), null); var origegdata = I2NPMessage.Clone(egmsg); var origegdata2 = I2NPMessage.Clone(egmsg); // Decrypt var(aesblock, sessionkey1) = Garlic.EGDecryptGarlic(origegdata, Private); var newgarlic = new Garlic((BufRefLen)aesblock.Payload); var g1 = new BufLen(garlic.ToByteArray()); var g2 = new BufLen(newgarlic.ToByteArray()); Assert.IsTrue(g1 == g2); // Retrieve var(aesblock2, sessionkey2) = Garlic.RetrieveAESBlock(origegdata2, Private, null); newgarlic = new Garlic((BufRefLen)aesblock2.Payload); g1 = new BufLen(garlic.ToByteArray()); g2 = new BufLen(newgarlic.ToByteArray()); Assert.IsTrue(g1 == g2); Assert.IsTrue(sessionkey1 == sessionkey2); }
public void TestEncodeDecodeAES() { var m1 = new DeliveryStatusMessage(0x4321); var m2 = new DeliveryStatusMessage(0xa3c2); var garlic = new Garlic( new GarlicClove( new GarlicCloveDeliveryDestination( m1, Destination.IdentHash)), new GarlicClove( new GarlicCloveDeliveryDestination( m2, Destination.IdentHash)) ); // No tags var sessionkey = new I2PSessionKey(); var sessiontag = new I2PSessionTag(); var cg = Garlic.AESEncryptGarlic(garlic, sessionkey, sessiontag, null); var egdata = I2NPMessage.Clone(cg); var(aesblock, sk) = Garlic.RetrieveAESBlock(egdata, Private, (t) => sessionkey); var g2 = new Garlic((BufRefLen)aesblock.Payload); Assert.IsTrue(BufUtils.Equal(garlic.ToByteArray(), g2.ToByteArray())); // With tags var tags = new List <I2PSessionTag>(); for (int i = 0; i < 30; ++i) { tags.Add(new I2PSessionTag()); } cg = Garlic.AESEncryptGarlic(garlic, sessionkey, sessiontag, null); egdata = I2NPMessage.Clone(cg); (aesblock, sk) = Garlic.RetrieveAESBlock(egdata, Private, (t) => sessionkey); g2 = new Garlic((BufRefLen)aesblock.Payload); Assert.IsTrue(BufUtils.Equal(garlic.ToByteArray(), g2.ToByteArray())); }
public void TestSimpleDatabaseStoreLeaseSetCreation() { var linfo = new I2PLeaseInfo(Public, PublicSigning, Private, PrivateSigning); var leases = new List <I2PLease>(); for (int i = 0; i < 5; ++i) { leases.Add(new I2PLease( new I2PIdentHash(true), new I2PTunnelId())); } var ls = new I2PLeaseSet(new I2PDestination(Public, PublicSigning), leases, linfo); var dbsm = new DatabaseStoreMessage(ls); var data = dbsm.CreateHeader16.HeaderAndPayload.Clone(); var recreated = I2NPMessage.ReadHeader16(new BufRefLen(data)); Assert.IsTrue(recreated.MessageType == I2NPMessage.MessageTypes.DatabaseStore); var rdsm = (DatabaseStoreMessage)recreated.Message; Assert.IsTrue(rdsm.LeaseSet.Leases.Count() == 5); Assert.IsTrue(BufUtils.Equal(ls.Destination.ToByteArray(), rdsm.LeaseSet.Destination.ToByteArray())); Assert.IsTrue(BufUtils.Equal(ls.PublicKey.ToByteArray(), rdsm.LeaseSet.PublicKey.ToByteArray())); Assert.IsTrue(BufUtils.Equal(ls.PublicSigningKey.ToByteArray(), rdsm.LeaseSet.PublicSigningKey.ToByteArray())); var rdsmlsar = rdsm.LeaseSet.Leases.ToArray(); var lsar = ls.Leases.ToArray(); // Order should be maintained for (int i = 0; i < 5; ++i) { Assert.IsTrue( BufUtils.Equal( lsar[i].ToByteArray(), rdsmlsar[i].ToByteArray())); } Assert.IsTrue(rdsm.LeaseSet.VerifySignature(PublicSigning)); }
public void TestSingleLargeTunnelDataCreation() { var sourcedata = new BufLen(BufUtils.RandomBytes(9000)); var srcmsgs = new List <TunnelMessage>(); srcmsgs.Add(new TunnelMessageTunnel(new DataMessage(sourcedata), new I2PIdentHash(true), 4242)); var msgfrags = TunnelDataMessage.MakeFragments(srcmsgs, 0x3e5c); Assert.IsTrue(msgfrags.Count() == 10); var serbuf = new List <byte>(); foreach (var frag in msgfrags) { serbuf.AddRange(frag.CreateHeader16.HeaderAndPayload); } var serbufarray = serbuf.ToArray(); var reassembler = new TunnelDataFragmentReassembly(); var reader = new BufRefLen(serbufarray); var readmsgs = new List <TunnelDataMessage>(); while (reader.Length > 0) { readmsgs.Add((TunnelDataMessage)(I2NPMessage.ReadHeader16(reader)).Message); } var reassembledmsgs = reassembler.Process(readmsgs, out var _); Assert.IsTrue(reassembledmsgs.Count() == 1); Assert.IsTrue(reassembler.BufferedFragmentCount == 0); var firstrecinstr = reassembledmsgs.First(); Assert.IsTrue(firstrecinstr.Delivery == TunnelMessage.DeliveryTypes.Tunnel); Assert.IsTrue(((TunnelMessageTunnel)firstrecinstr).Tunnel == 4242); Assert.IsTrue(firstrecinstr.Message.MessageType == I2NPMessage.MessageTypes.Data); var datamsg = (DataMessage)firstrecinstr.Message; Assert.IsTrue(datamsg.DataMessagePayloadLength == sourcedata.Length); Assert.IsTrue(datamsg.DataMessagePayload == sourcedata); }
private static void AddTunnelMessage(List <TunnelMessage> result, TunnelDataFragment initialfragment, byte[] buf) { switch (initialfragment.Delivery) { case TunnelMessage.DeliveryTypes.Local: result.Add(new TunnelMessageLocal(I2NPMessage.ReadHeader16(new BufRef(buf)))); break; case TunnelMessage.DeliveryTypes.Router: result.Add(new TunnelMessageRouter(I2NPMessage.ReadHeader16(new BufRef(buf)), new I2PIdentHash((BufRefLen)initialfragment.ToHash))); break; case TunnelMessage.DeliveryTypes.Tunnel: result.Add(new TunnelMessageTunnel(I2NPMessage.ReadHeader16(new BufRef(buf)), new I2PIdentHash((BufRefLen)initialfragment.ToHash), initialfragment.Tunnel)); break; } }
void DestinationMessageReceived(I2NPMessage msg) { #if LOG_ALL_TUNNEL_TRANSFER DebugUtils.LogDebug("ClientDestination: DestinationMessageReceived: " + msg.ToString()); #endif if (msg.MessageType == I2NPMessage.MessageTypes.Data && DataReceived != null) { var dmsg = (DataMessage)msg.Header16.Message; DataReceived(dmsg.Payload); } if (msg.MessageType == I2NPMessage.MessageTypes.DatabaseStore) { var dbsmsg = (DatabaseStoreMessage)msg.Header16.Message; if (dbsmsg.LeaseSet != null) { Destinations.RemoteLeaseSetUpdated(dbsmsg.LeaseSet); } } }
internal void Add(I2PIdentHash dest, I2NPMessage msg) { if (CurrentlyUnresolvableRouters.Contains(dest)) { throw new RouterUnresolvableException($"Destination is tagged as unresolvable {dest}"); } var sendlookup = false; lock ( QueuedMessages ) { if (!QueuedMessages.ContainsKey(dest)) { var newld = new LookupDestination(dest); newld.Add(msg); QueuedMessages[dest] = newld; sendlookup = true; } else { var queue = QueuedMessages[dest]; if (queue.Messages.Count < MaxMessagesInQueue) { queue.Add(msg); } #if DEBUG else { Logging.LogWarning("UnknownRouterQueue: Add: Too many messages in queue. Dropping new message."); } #endif } } if (sendlookup) { NetDb.Inst.IdentHashLookup.LookupRouterInfo(dest); } }
protected GarlicCloveDelivery(I2NPMessage msg, DeliveryMethod mtd) { Message = msg; Flag = (byte)mtd; }
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); }
private static bool Send(I2PIdentHash dest, I2NPMessage data, int reclvl) { ITransport transp = null; try { if (dest == RouterContext.Inst.MyRouterIdentity.IdentHash) { Logging.LogTransport($"TransportProvider: Loopback {data}"); TransportProvider.Inst.DistributeIncomingMessage(null, data.CreateHeader16); return(true); } lock ( TransportSelectionLock ) { if (TransportProvider.Inst.CurrentlyUnknownRouters.Contains(dest)) { TransportProvider.Inst.CurrentlyUnknownRouters.Add(dest, data); return(true); } transp = TransportProvider.Inst.GetEstablishedTransport(dest, false); if (transp != null) { transp.Send(data); return(true); } if (NetDb.Inst.Contains(dest)) { transp = TransportProvider.Inst.GetTransport(dest); if (transp == null) { throw new FailedToConnectException($"Unable to contact {dest}"); } transp.Send(data); } else { if (TransportProvider.Inst.CurrentlyUnresolvableRouters.Contains(dest)) { throw new ArgumentException($"Unable to resolve {dest}"); } TransportProvider.Inst.CurrentlyUnknownRouters.Add(dest, data); } } } catch (FailedToConnectException ex) { if (transp != null) { TransportProvider.Inst.Remove(transp); } if (dest != null && NetDb.Inst != null) { NetDb.Inst.Statistics.FailedToConnect(dest); } Logging.LogTransport($"TransportProvider.Send: {( transp == null ? "<>" : transp.DebugId )}" + $" Exception {ex.GetType()}"); return(false); } catch (EndOfStreamEncounteredException ex) { TransportProvider.Inst.Remove(transp); Logging.LogTransport($"TransportProvider.Send: Connection {( transp == null ? "<>" : transp.DebugId )}" + $" closed exception: {ex.GetType()}"); if (reclvl > 1 || !Send(dest, data, reclvl + 1)) { Logging.LogTransport($"TransportProvider.Send: Recconnection failed to {dest.Id32Short}, reclvl: {reclvl}."); throw; } } catch (RouterUnresolvableException ex) { if (dest != null) { NetDb.Inst.Statistics.DestinationInformationFaulty(dest); } Logging.LogTransport($"TransportProvider.Send: Unresolvable router: {ex.Message}"); return(false); } catch (Exception ex) { if (transp != null) { TransportProvider.Inst.Remove(transp); } if (dest != null) { NetDb.Inst.Statistics.DestinationInformationFaulty(dest); } Logging.LogTransport($"TransportProvider.Send: Exception {ex.GetType()}, {ex.Message}"); throw; } return(true); }
public static bool Send(I2PIdentHash dest, I2NPMessage data) { return(Send(dest, data, 0)); }
private bool HandleTunnelMessage(I2NPMessage msg) { #if LOG_ALL_TUNNEL_TRANSFER Logging.LogDebug($"{this} HandleReceiveQueue: {msg.MessageType}"); #endif switch (msg.MessageType) { case I2NPMessage.MessageTypes.TunnelBuildReply: case I2NPMessage.MessageTypes.TunnelData: throw new NotImplementedException($"Should not happen {TunnelDebugTrace}"); case I2NPMessage.MessageTypes.VariableTunnelBuildReply: ThreadPool.QueueUserWorkItem(cb => { TunnelProvider.Inst.HandleTunnelBuildReply((VariableTunnelBuildReplyMessage)msg); }); return(true); case I2NPMessage.MessageTypes.DeliveryStatus: #if LOG_ALL_TUNNEL_TRANSFER Logging.LogDebug($"{this}: DeliveryStatus: {msg.Message}"); #endif ThreadPool.QueueUserWorkItem(cb => { lock ( DeliveryStatusReceivedLock ) { DeliveryStatusReceived?.Invoke((DeliveryStatusMessage)msg); } }); break; case I2NPMessage.MessageTypes.DatabaseStore: var ds = (DatabaseStoreMessage)msg; ThreadPool.QueueUserWorkItem(cb => { Router.HandleDatabaseStore(ds); }); break; case I2NPMessage.MessageTypes.DatabaseSearchReply: var dsr = (DatabaseSearchReplyMessage)msg; ThreadPool.QueueUserWorkItem(cb => { NetDb.Inst.AddDatabaseSearchReply(dsr); }); break; case I2NPMessage.MessageTypes.Garlic: var garlic = (GarlicMessage)msg; #if LOG_ALL_TUNNEL_TRANSFER || LOG_ALL_LEASE_MGMT Logging.Log($"{this}: Garlic received"); #endif ThreadPool.QueueUserWorkItem(cb => { lock ( GarlicMessageReceivedLock ) { GarlicMessageReceived?.Invoke(garlic); } }); break; default: Logging.LogWarning($"{this}: HandleReceiveQueue: Dropped {msg}"); break; } return(true); }
void TestOneOutboundTunnel() { if (OutboundTunnels.IsEmpty) { return; } if (!OutboundTunnels.TryDequeue(out var outtunnel)) { return; } if (!outtunnel.Active || outtunnel.Metrics.PassedTunnelTest) { return; } OutboundTunnels.Enqueue(outtunnel); var run = OutstandingTests.Get(outtunnel); if (run != null) { // Run has finished? if (run.TestedPartners.Count >= RunsPerTest) { if (run.LastRun.DeltaToNow < TimeBetweenTests) { return; } run.OutstandingProbes.Clear(); run.SuccessPartners.Clear(); run.TestedPartners.Clear(); } } else { run = new TestRun2(outtunnel); OutstandingTests[outtunnel] = run; } var test = TestResults.Get(outtunnel, () => new TunnelTestResult(outtunnel)); var intunnels = TunnelProvider.Inst.GetInboundTunnels() .Where(t => t.Active) .Shuffle() .Take(RunsPerTest * 2) .ToArray(); if (!intunnels.Any()) { //Logging.LogDebug( "TunnelTester: Failed to get a established inbound tunnel." ); return; } run.LastRun.SetNow(); string tunneldbginfo = ""; foreach (var intunnel in intunnels) { if (run.FailurePartners.Contains(intunnel) || run.SuccessPartners.Contains(intunnel) || run.TestedPartners.Contains(intunnel)) { continue; } run.TestedPartners.Add(intunnel); var probe = new ProbesSent() { Tunnel = outtunnel, Partner = intunnel, MessageId = I2NPMessage.GenerateMessageId(), TotalHops = outtunnel.Config.Info.Hops.Count + intunnel.Config.Info.Hops.Count }; tunneldbginfo += $"({intunnel.TunnelDebugTrace}:{probe.MessageId})"; run.OutstandingProbes.Add(probe); OutstandingProbeIds[probe.MessageId] = probe; outtunnel.Send(new TunnelMessageTunnel(new DeliveryStatusMessage(probe.MessageId), intunnel)); } if (tunneldbginfo.Length > 0) { Logging.LogDebug( $"TunnelTester: Starting outbound tunnel {outtunnel.TunnelDebugTrace} test with tunnels: {tunneldbginfo}"); } }
public override void SendRaw(I2NPMessage msg) { throw new NotImplementedException(); }
void Run() { try { try { NTCPContext.TransportInstance = TransportInstance; Watchdog.Inst.StartMonitor(Thread.CurrentThread, 20000); try { MySocket = CreateSocket(); RemoteDescription = MySocket.RemoteEndPoint.ToString(); #if LOG_ALL_TRANSPORT DebugUtils.LogDebug("My local endpoint IP# : " + ((IPEndPoint)MySocket.LocalEndPoint).Address.ToString()); DebugUtils.LogDebug("My local endpoint Port : " + ((IPEndPoint)MySocket.LocalEndPoint).Port.ToString()); #endif DHNegotiate(); } catch (SocketException ex) { if (NTCPContext.RemoteRouterIdentity != null) { NetDb.Inst.Statistics.FailedToConnect(NTCPContext.RemoteRouterIdentity.IdentHash); } throw new FailedToConnectException(ex.ToString()); } catch (FormatException) { if (NTCPContext.RemoteRouterIdentity != null) { NetDb.Inst.Statistics.DestinationInformationFaulty(NTCPContext.RemoteRouterIdentity.IdentHash); } throw; } catch (NotSupportedException) { if (NTCPContext.RemoteRouterIdentity != null) { NetDb.Inst.Statistics.DestinationInformationFaulty(NTCPContext.RemoteRouterIdentity.IdentHash); } throw; } catch (ThreadInterruptedException) { if (NTCPContext.RemoteRouterIdentity != null) { NetDb.Inst.Statistics.SlowHandshakeConnect(NTCPContext.RemoteRouterIdentity.IdentHash); } throw; } catch (ThreadAbortException) { if (NTCPContext.RemoteRouterIdentity != null) { NetDb.Inst.Statistics.SlowHandshakeConnect(NTCPContext.RemoteRouterIdentity.IdentHash); } throw; } DHSucceeded = true; Watchdog.Inst.UpdateTimeout(Thread.CurrentThread, InactivityTimeoutSeconds * 1000); TryInitiateSend(); #if DEBUG if (ConnectionEstablished == null) { DebugUtils.LogWarning("NTCPClient: No observers for ConnectionEstablished!"); } #endif if (ConnectionEstablished != null) { ConnectionEstablished(this); } NetDb.Inst.Statistics.SuccessfulConnect(NTCPContext.RemoteRouterIdentity.IdentHash); var reader = new NTCPReader(MySocket, NTCPContext); while (!Terminated) { var data = reader.Read(); //DebugUtils.LogDebug( "Read: " + data.Length ); Watchdog.Inst.Ping(Thread.CurrentThread); if (reader.NTCPDataSize == 0) { //if ( TimeSyncReceived != null ) TimeSyncReceived( this, data ); } else { #if DEBUG if (DataBlockReceived == null) { DebugUtils.LogWarning("NTCPClient: No observers for DataBlockReceived !"); } #endif if (DataBlockReceived != null) { DataBlockReceived(this, I2NPMessage.ReadHeader16(new BufRefLen(data))); } } } } catch (ThreadAbortException) { DebugUtils.LogDebug(string.Format("NTCP {0} Aborted", DebugId)); } catch (ThreadInterruptedException) { DebugUtils.LogDebug(string.Format("NTCP {0} Interrupted", DebugId)); } catch (FailedToConnectException) { DebugUtils.LogDebug(string.Format("NTCP {0} Failed to connect", DebugId)); } catch (EndOfStreamEncounteredException) { DebugUtils.LogDebug(string.Format("NTCP {0} Disconnected", DebugId)); } catch (IOException ex) { DebugUtils.LogDebug(string.Format("NTCP {1} Exception: {0}", ex, DebugId)); } catch (SocketException ex) { DebugUtils.LogDebug(string.Format("NTCP {1} Exception: {0}", ex, DebugId)); } catch (Exception ex) { #if DEBUG if (ConnectionException == null) { DebugUtils.LogWarning("NTCPClient: No observers for ConnectionException!"); } #endif if (ConnectionException != null) { ConnectionException(this, ex); } DebugUtils.LogDebug(string.Format("NTCP {1} Exception: {0}", ex, DebugId)); } } finally { Terminated = true; Watchdog.Inst.StopMonitor(Thread.CurrentThread); try { if (!DHSucceeded && NTCPContext.RemoteRouterIdentity != null) { NetDb.Inst.Statistics.FailedToConnect(NTCPContext.RemoteRouterIdentity.IdentHash); } } catch (Exception ex) { DebugUtils.Log(DebugId, ex); } DebugUtils.LogDebug(string.Format("NTCP {0} Shut down. {1}", DebugId, RemoteDescription)); try { #if DEBUG if (ConnectionShutDown == null) { DebugUtils.LogWarning("NTCPClient: No observers for ConnectionShutDown!"); } #endif if (ConnectionShutDown != null) { ConnectionShutDown(this); } } catch (Exception ex) { DebugUtils.Log(DebugId, ex); } if (MySocket != null) { try { MySocket.Shutdown(SocketShutdown.Both); MySocket.Close(); } catch (Exception ex) { DebugUtils.Log(DebugId, ex); } finally { MySocket = null; } } } }
public override SSUState HandleMessage(SSUHeader header, BufRefLen reader) { 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.ReadHeader16((BufRefLen)msg.GetPayload()); #if LOG_MUCH_TRANSPORT Logging.LogDebugData($"SSU {this} complete message " + $"{msg.MessageId}: {i2npmsg.Expiration}"); #endif if (i2npmsg.MessageType == I2NPMessage.MessageTypes.DeliveryStatus) { if (((DeliveryStatusMessage)i2npmsg.Message).IsNetworkId((ulong)I2PConstants.I2P_NETWORK_ID)) { continue; } } Session.MessageReceived(i2npmsg); } } } catch (Exception ex) { Logging.Log("EstablishedState: SSUHost.SSUMessageTypes.Data", ex); } break; case SSUHeader.MessageTypes.PeerTest: HandleIncomingPeerTestPackage(reader); break; case SSUHeader.MessageTypes.RelayResponse: Logging.LogTransport($"SSU EstablishedState {Session.DebugId}: RelayResponse received from {Session.RemoteEP}."); var response = new RelayResponse(reader); Session.Host.ReportRelayResponse(header, response, Session.RemoteEP); break; case SSUHeader.MessageTypes.RelayIntro: var intro = new RelayIntro(reader); Logging.LogTransport($"SSU EstablishedState {Session.DebugId}: RelayIntro received from {Session.RemoteEP} for {intro.AliceEndpoint}."); var data = new BufLen(new byte[12]); data.Randomize(); Send(intro.AliceEndpoint, data); ++Session.Host.EPStatisitcs[Session.RemoteEP].RelayIntrosReceived; ++Session.RelayIntroductionsReceived; break; case SSUHeader.MessageTypes.RelayRequest: // TODO: Implement // if ( !SSUHost.IntroductionSupported ) throw new Exception( "SSU relay introduction not supported" ); Logging.LogTransport(string.Format("SSU EstablishedState {0}: Relay introduction not supported.", Session.DebugId)); break; case SSUHeader.MessageTypes.SessionRequest: Logging.LogTransport(string.Format("SSU EstablishedState {0}: SessionRequest received. Ending session.", Session.DebugId)); SendSessionDestroyed(); return(null); default: Logging.LogTransport(string.Format("SSU EstablishedState {0}: Unexpected message received: {1}.", Session.DebugId, header.MessageType)); break; } return(this); }