public void MakeAndReadFragment() { var arec = new DatabaseLookupMessage( new I2PIdentHash(true), new I2PIdentHash(true), DatabaseLookupMessage.LookupTypes.Normal); var msg = new TunnelMessageRouter( arec, new I2PIdentHash(true)); var refmsgdata = msg.Message.CreateHeader16.HeaderAndPayload; var fragments = TunnelDataMessage.MakeFragments( new TunnelMessage[] { msg }, BufUtils.RandomUint()); var mkmsg = new TunnelDataFragmentReassembly(); var recvtmsgs = mkmsg.Process(fragments.Shuffle().ToArray(), out var _); foreach (var rmsg in recvtmsgs) { var rmsgdata = rmsg.Message.CreateHeader16.HeaderAndPayload; Assert.IsTrue(msg.Delivery == rmsg.Delivery); Assert.IsTrue(refmsgdata == rmsgdata); } }
/* * Exploration * * Exploration is a special form of netdb lookup, where a router attempts to learn about new routers. * It does this by sending a floodfill router a I2NP DatabaseLookupMessage, looking for a random key. * As this lookup will fail, the floodfill would normally respond with a I2NP DatabaseSearchReplyMessage * containing hashes of floodfill routers close to the key. This would not be helpful, as the requesting * router probably already knows those floodfills, and it would be impractical to add ALL floodfill * routers to the "don't include" field of the lookup. For an exploration query, the requesting router * adds a router hash of all zeros to the "don't include" field of the DatabaseLookupMessage. * * The floodfill will then respond only with non-floodfill routers close to the requested key. * * https://geti2p.net/en/docs/how/network-database * * 11 => exploration lookup, return DatabaseSearchReplyMessage * containing non-floodfill routers only (replaces an * excludedPeer of all zeroes) * https://geti2p.net/spec/i2np#databaselookup */ void ExplorationRouterLookup() { I2PIdentHash ident = new I2PIdentHash(true); var ff = NetDb.Inst.GetClosestFloodfill(ident, 10, null, false) .Shuffle() .Take(DatabaseLookupSelectFloodfillCount) .ToArray(); foreach (var oneff in ff) { var msg = new DatabaseLookupMessage( ident, RouterContext.Inst.MyRouterIdentity.IdentHash, DatabaseLookupMessage.LookupTypes.Exploration, new I2PIdentHash[] { new I2PIdentHash(false) }); #if LOG_ALL_IDENT_LOOKUPS Logging.Log("IdentResolver: Random router lookup " + ident.Id32Short + " sent to " + oneff.Id32Short); #endif try { TransportProvider.Send(oneff, msg); } catch (Exception ex) { Logging.Log(ex); } } }
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 void MakeAndReadFragments() { 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.Random(2048 + BufUtils.RandomInt(1024)))); origmsgs.Add(new TunnelMessageTunnel( adatarec.Header16, new I2PIdentHash(true), BufUtils.RandomUint())); break; case 1: var arec = new DatabaseLookupMessage( new I2PIdentHash(true), new I2PIdentHash(true), DatabaseLookupMessage.LookupTypes.Normal); origmsgs.Add(new TunnelMessageRouter(arec.Header16, new I2PIdentHash(true))); break; case 2: var adatarec2 = new DataMessage(new BufLen(BufUtils.Random(2048 + BufUtils.RandomInt(1024)))); origmsgs.Add(new TunnelMessageLocal(adatarec2.Header16)); break; } } var msgs = TunnelDataMessage.MakeFragments(origmsgs, BufUtils.RandomUint()); var mkmsg = new TunnelDataFragmentReassembly(); var recvtmsgs = mkmsg.Process(msgs); foreach (var rmsg in recvtmsgs) { Assert.IsTrue(origmsgs.SingleOrDefault(m => m.Delivery == rmsg.Delivery && m.Header.HeaderAndPayload == rmsg.Header.HeaderAndPayload ) != null); } }
private void SendRIDatabaseLookup(I2PIdentHash ident, IdentUpdateRequestInfo info) { var ff = NetDb.Inst.GetClosestFloodfill( ident, 10 + 3 * info.Retries, info.AlreadyQueried, false); if (!ff.Any()) { Logging.Log($"IdentResolver: failed to find a floodfill router to lookup ({ident}): "); return; } ff.Shuffle(); ff = ff.Take(DatabaseLookupSelectFloodfillCount).ToArray(); foreach (var oneff in ff) { try { var msg = new DatabaseLookupMessage( ident, RouterContext.Inst.MyRouterIdentity.IdentHash, DatabaseLookupMessage.LookupTypes.RouterInfo); TransportProvider.Send(oneff, msg); #if LOG_ALL_IDENT_LOOKUPS Logging.Log($"IdentResolver: RouterInfo query {msg.Key.Id32Short} sent to {oneff.Id32Short}"); #endif } catch (Exception ex) { Logging.Log("SendRIDatabaseLookup", ex); } } foreach (var f in ff) { info.AlreadyQueried.Add(f); } }
private void SendRIDatabaseLookup(I2PIdentHash ident, IdentUpdateRequestInfo info) { var ff = NetDb.Inst.GetClosestFloodfill(ident, 10, info.AlreadyQueried, false).ToArray(); if (ff == null || ff.Length == 0) { DebugUtils.Log("IdentResolver: failed to find a floodfill router to lookup (" + ident.ToString() + "): "); return; } ff.Shuffle(); ff = ff.Take(DatabaseLookupSelectFloodfillCount).ToArray(); foreach (var oneff in ff) { try { var msg = new DatabaseLookupMessage( ident, RouterContext.Inst.MyRouterIdentity.IdentHash, DatabaseLookupMessage.LookupTypes.RouterInfo); TransportProvider.Send(oneff, msg); #if LOG_ALL_IDENT_LOOKUPS DebugUtils.Log("IdentResolver: RouterInfo query " + msg.Key.Id32Short + " sent to " + oneff.Id32Short); #endif } catch (Exception ex) { DebugUtils.Log("SendRIDatabaseLookup", ex); } } lock (info.AlreadyQueried) { info.AlreadyQueried.AddRange(ff); } }
public void MakeAndReadFragments100() { var origmsgs = new List <TunnelMessage>(); for (int i = 0; i < 100; ++i) { switch (BufUtils.RandomInt(3)) { case 0: var adatarec = new DataMessage(new BufLen(BufUtils.RandomBytes(2048))); origmsgs.Add(new TunnelMessageTunnel( adatarec, new I2PIdentHash(true), BufUtils.RandomUint())); break; case 1: var arec = new DatabaseLookupMessage( new I2PIdentHash(true), new I2PIdentHash(true), DatabaseLookupMessage.LookupTypes.Normal); 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 TunnelMessageLocal(adatarec2)); break; } } var msgs = TunnelDataMessage.MakeFragments(origmsgs, BufUtils.RandomUint()); var mkmsg = new TunnelDataFragmentReassembly(); var chunks = msgs .Shuffle() .ToArray() .Chunk(a => 1 + BufUtils.RandomInt(10)) .Shuffle(); var recvtmsgs = chunks.SelectMany(c => mkmsg.Process(c, out var _)).ToArray(); Assert.IsTrue(origmsgs.All(o => recvtmsgs.Any(m => m.Delivery == o.Delivery && m.Message.CreateHeader16.HeaderAndPayload == o.Message.CreateHeader16.HeaderAndPayload ))); var mkmsg2 = new TunnelDataFragmentReassembly(); var chunks2 = msgs .Shuffle() .ToArray() .Skip(1) .Chunk(a => 1 + BufUtils.RandomInt(10)) .Shuffle(); var recvtmsgs2 = chunks2.SelectMany(c => mkmsg2.Process(c, out var _)).ToArray(); Assert.IsFalse(origmsgs.All(o => recvtmsgs2.Any(m => m.Delivery == o.Delivery && m.Message.CreateHeader16.HeaderAndPayload == o.Message.CreateHeader16.HeaderAndPayload ))); }
private void SendLSDatabaseLookup(I2PIdentHash ident, IdentUpdateRequestInfo info) { var outtunnel = TunnelProvider.Inst.GetEstablishedOutboundTunnel(true); var replytunnel = TunnelProvider.Inst.GetInboundTunnel(true); if (outtunnel is null || replytunnel is null) { Logging.LogDebug($"SendLSDatabaseLookup: " + $"outtunnel: {outtunnel}, replytunnel: {replytunnel}"); return; } var getnext = DateTime.UtcNow.Hour >= 23; var ff = NetDb.Inst.GetClosestFloodfill( ident, DatabaseLookupSelectFloodfillCount + 2 * info.Retries, info.AlreadyQueried, getnext) .Select(r => new { Id = r, NetDb.Inst.Statistics[r].Score }); #if LOG_ALL_IDENT_LOOKUPS StringBuilder foundrouters = new StringBuilder(); StringBuilder foundrouterskeys = new StringBuilder(); foreach (var router in ff) { foundrouters.AppendFormat("{0}{1}{2}", (foundrouters.Length != 0 ? ", " : ""), router.Id32Short, FreenetBase64.Encode(router.Hash)); foundrouterskeys.AppendFormat("{0}{1}{2}", (foundrouterskeys.Length != 0 ? ", " : ""), router.Id32Short, FreenetBase64.Encode(router.RoutingKey.Hash)); } var st = foundrouters.ToString(); var st2 = foundrouterskeys.ToString(); #endif if (!ff.Any()) { Logging.Log($"IdentResolver failed to find a floodfill router to lookup ({ident}): "); return; } var minscore = ff.Min(r => r.Score); for (int i = 0; i < DatabaseLookupSelectFloodfillCount; ++i) { var oneff = ff .RandomWeighted(r => r.Score - minscore + 0.1) .Id; try { var msg = new DatabaseLookupMessage( ident, replytunnel.Destination, replytunnel.GatewayTunnelId, DatabaseLookupMessage.LookupTypes.LeaseSet, null); outtunnel.Send(new TunnelMessageRouter(msg, oneff)); info.AlreadyQueried.Add(oneff); #if !LOG_ALL_IDENT_LOOKUPS Logging.Log($"IdentResolver: LeaseSet query {msg.Key.Id32Short} " + $"sent to {oneff.Id32Short}. Dist: {oneff ^ msg.Key.RoutingKey}"); #endif } catch (Exception ex) { Logging.Log("SendLSDatabaseLookup", ex); } } }
private void SendLSDatabaseLookup(I2PIdentHash ident, IdentUpdateRequestInfo info) { /* * var replytunnel = TunnelProvider.Inst.GetInboundTunnel(); * if ( replytunnel == null ) return; */ var ff = NetDb.Inst.GetClosestFloodfill(ident, DatabaseLookupSelectFloodfillCount * 2, info.AlreadyQueried, false).ToArray(); #if LOG_ALL_IDENT_LOOKUPS StringBuilder foundrouters = new StringBuilder(); StringBuilder foundrouterskeys = new StringBuilder(); foreach (var router in ff) { foundrouters.AppendFormat("{0}{1}{2}", (foundrouters.Length != 0 ? ", " : ""), router.Id32Short, FreenetBase64.Encode(router.Hash)); foundrouterskeys.AppendFormat("{0}{1}{2}", (foundrouterskeys.Length != 0 ? ", " : ""), router.Id32Short, FreenetBase64.Encode(router.RoutingKey.Hash)); } var st = foundrouters.ToString(); var st2 = foundrouterskeys.ToString(); #endif if (ff == null || ff.Length == 0) { DebugUtils.Log("IdentResolver failed to find a floodfill router to lookup (" + ident.ToString() + "): "); return; } ff.Shuffle(); ff = ff.Take(DatabaseLookupSelectFloodfillCount).ToArray(); foreach (var oneff in ff) { try { var msg = new DatabaseLookupMessage( ident, RouterContext.Inst.MyRouterIdentity.IdentHash, DatabaseLookupMessage.LookupTypes.LeaseSet); /* * var msg = new DatabaseLookupMessage( * ident, * replytunnel.Destination, replytunnel.GatewayTunnelId, * DatabaseLookupMessage.LookupTypes.LeaseSet, null ); */ //TunnelProvider.Inst.SendEncrypted( oneff.Identity, false, msg ); TransportProvider.Send(oneff, msg); #if LOG_ALL_IDENT_LOOKUPS DebugUtils.Log(string.Format("IdentResolver: LeaseSet query {0} sent to {1}. Dist: {2}", msg.Key.Id32Short, oneff.Id32Short, oneff ^ msg.Key.RoutingKey)); #endif } catch (Exception ex) { DebugUtils.Log("SendLSDatabaseLookup", ex); } } lock (info.AlreadyQueried) { info.AlreadyQueried.AddRange(ff); } }
public static I2NPMessage GetMessage( I2NPMessage.MessageTypes messagetype, BufRef reader, uint?msgid = null) { I2NPMessage result = null; try { switch (messagetype) { case I2NPMessage.MessageTypes.Garlic: result = new GarlicMessage(reader); break; case I2NPMessage.MessageTypes.Data: result = new DataMessage(reader); break; case I2NPMessage.MessageTypes.DatabaseSearchReply: result = new DatabaseSearchReplyMessage(reader); break; case I2NPMessage.MessageTypes.DatabaseStore: result = new DatabaseStoreMessage(reader); break; case I2NPMessage.MessageTypes.DeliveryStatus: result = new DeliveryStatusMessage(reader); break; case I2NPMessage.MessageTypes.TunnelData: result = new TunnelDataMessage(reader); break; case I2NPMessage.MessageTypes.TunnelGateway: result = new TunnelGatewayMessage(reader); break; case I2NPMessage.MessageTypes.DatabaseLookup: result = new DatabaseLookupMessage(reader); break; case I2NPMessage.MessageTypes.VariableTunnelBuild: result = new VariableTunnelBuildMessage(reader); break; case I2NPMessage.MessageTypes.TunnelBuild: result = new TunnelBuildMessage(reader); break; case I2NPMessage.MessageTypes.TunnelBuildReply: result = new TunnelBuildReplyMessage(reader); break; case I2NPMessage.MessageTypes.VariableTunnelBuildReply: result = new VariableTunnelBuildReplyMessage(reader); break; default: Logging.LogDebug($"GetMessage: '{messagetype}' is not a known message type!"); throw new NotImplementedException(); } } catch (Exception ex) { Logging.Log("GetMessage", ex); throw; } if (result != null && msgid.HasValue) { result.MessageId = msgid.Value; } return(result); }