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 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()); }
private ITransport CreateTransport(I2PRouterInfo ri) { ITransport transport = null; try { var pproviders = TransportProtocols .Select(tp => new { Provider = tp, Capability = tp.ContactCapability(ri) }) .Where(tp => tp.Capability != ProtocolCapabilities.None) .GroupBy(tp => tp.Capability) .OrderByDescending(cc => (int)cc.Key); var pprovider = pproviders.FirstOrDefault()?.Random(); if (pprovider == null) { Logging.LogTransport( $"TransportProvider: CreateTransport: No usable address found for {ri.Identity.IdentHash.Id32Short}!"); return(null); } transport = pprovider.Provider.AddSession(ri); Logging.LogTransport($"TransportProvider: Creating new {transport} to {ri.Identity.IdentHash.Id32Short}"); AddTransport(transport); transport.Connect(); var dstore = new DatabaseStoreMessage(RouterContext.Inst.MyRouterInfo); transport.Send(dstore); } catch (Exception ex) { #if LOG_MUCH_TRANSPORT Logging.LogTransport(ex); Logging.LogTransport("TransportProvider: CreateTransport stack trace: " + System.Environment.StackTrace); #else Logging.LogTransport($"TransportProvider: Exception [{ex.GetType()}] " + $"'{ex.Message}' to {ri.Identity.IdentHash.Id32Short}."); #endif if (transport != null) { Remove(transport); } throw; } return(transport); }
private void SendUpdate(I2PIdentHash ff, uint token) { // If greater than zero, a DeliveryStatusMessage // is requested with the Message ID set to the value of the Reply Token. // A floodfill router is also expected to flood the data to the closest floodfill peers // if the token is greater than zero. // https://geti2p.net/spec/i2np#databasestore var ds = new DatabaseStoreMessage( RouterContext.Inst.MyRouterInfo, token, RouterContext.Inst.MyRouterInfo.Identity.IdentHash, 0); TransportProvider.Send(ff, ds); }
internal void LocalLeaseSetUpdated(I2PLeaseSet leaseset) { LatestLocalLeaseSet = leaseset; var dbsmessage = new DatabaseStoreMessage(leaseset); var info = Send(true, new GarlicCloveDeliveryDestination(dbsmessage, Destination.IdentHash)); #if LOG_ALL_TUNNEL_TRANSFER if (info != null) { Logging.LogDebug(() => string.Format( "DestinationSession: LeaseSet update bundled in Destination trafic. ({0}) TrackingId: {1}, Ack MessageId: {2}.", info.KeyType, info.TrackingId, info.AckMessageId)); } #endif LatestLeaseSetSendTime.SetNow(); }
DatabaseStoreMessage CreateDatabaseStoreMessage() { 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); return(dbsm); }
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)); }
private void SendLeaseSetUpdateGarlic( I2PIdentHash ffdest, I2PPublicKey pubkey, I2PLeaseSet ls, uint token) { // If greater than zero, a DeliveryStatusMessage // is requested with the Message ID set to the value of the Reply Token. // A floodfill router is also expected to flood the data to the closest floodfill peers // if the token is greater than zero. // https://geti2p.net/spec/i2np#databasestore var outtunnel = TunnelProvider.Inst.GetEstablishedOutboundTunnel(false); var replytunnel = ls.Leases.Random(); if (outtunnel is null || replytunnel is null) { Logging.LogDebug($"SendLeaseSetUpdateGarlic: " + $"outtunnel: {outtunnel}, replytunnel: {replytunnel?.TunnelGw?.Id32Short}"); return; } var ds = new DatabaseStoreMessage(ls); var delivstatus = new DeliveryStatusMessage(token); // As explained on the network database page, local LeaseSets are sent to floodfill // routers in a Database Store Message wrapped in a Garlic Message so it is not // visible to the tunnel's outbound gateway. var garlic = new Garlic( new GarlicClove( new GarlicCloveDeliveryLocal(ds)), new GarlicClove( new GarlicCloveDeliveryTunnel(delivstatus, replytunnel.TunnelGw, replytunnel.TunnelId)) ); var egmsg = Garlic.EGEncryptGarlic(garlic, pubkey, new I2PSessionKey(), null); outtunnel.Send( new TunnelMessageRouter( egmsg, ffdest)); }
internal static void HandleDatabaseStore(DatabaseStoreMessage ds) { if (ds.RouterInfo == null && ds.LeaseSet == null) { throw new ArgumentException("DatabaseStore without Router or Lease info!"); } if (ds.RouterInfo != null) { #if LOG_ALL_TUNNEL_TRANSFER //Logging.Log( "HandleDatabaseStore: DatabaseStore RouterInfo" + ds.ToString() ); #endif NetDb.Inst.AddRouterInfo(ds.RouterInfo); } else { #if LOG_ALL_TUNNEL_TRANSFER //Logging.Log( "HandleDatabaseStore: DatabaseStore LeaseSet" + ds.ToString() ); #endif NetDb.Inst.AddLeaseSet(ds.LeaseSet); } if (ds.ReplyToken != 0) { if (ds.ReplyTunnelId != 0) { var outtunnel = TunnelProvider.Inst.GetEstablishedOutboundTunnel(true); if (outtunnel != null) { outtunnel.Send(new TunnelMessageRouter( (new TunnelGatewayMessage( new DeliveryStatusMessage(ds.ReplyToken), ds.ReplyTunnelId)), ds.ReplyGateway)); } } else { TransportProvider.Send(ds.ReplyGateway, new DeliveryStatusMessage(ds.ReplyToken)); } } }
private void SendUpdateTunnelReply(I2PIdentHash ff, uint token) { // If greater than zero, a DeliveryStatusMessage // is requested with the Message ID set to the value of the Reply Token. // A floodfill router is also expected to flood the data to the closest floodfill peers // if the token is greater than zero. // https://geti2p.net/spec/i2np#databasestore var replytunnel = TunnelProvider.Inst.GetInboundTunnel(true); var ds = new DatabaseStoreMessage(RouterContext.Inst.MyRouterInfo, token, replytunnel.Destination, replytunnel.ReceiveTunnelId); lock ( OutstandingRequests ) { OutstandingRequests[token] = new FFUpdateRequestInfo(ff); } TransportProvider.Send(ff, ds); }
private ITransport CreateTransport(I2PRouterInfo ri) { ITransport transport = null; try { var ntcpaddr = ri.Adresses.Where(a => (a.TransportStyle == "NTCP") && a.HaveHostAndPort && (RouterContext.Inst.UseIpV6 || a.Options.ValueContains("host", "."))); var ssuaddr = ri.Adresses.Where(a => (a.TransportStyle == "SSU") && a.Options.Contains("key") && (RouterContext.Inst.UseIpV6 || a.Options.ValueContains("host", ".") || a.Options.ValueContains("ihost0", "."))); I2PRouterAddress ra = ssuaddr .Where(a => a.Options.Contains("host")) .Random() ?? ntcpaddr.Random() ?? ssuaddr.Random(); if (ra == null) { Logging.LogTransport( $"TransportProvider: CreateTransport: No usable address found for {ri.Identity.IdentHash.Id32Short}!"); return(null); } switch (ra.TransportStyle.ToString()) { case "SSU": transport = SsuHost.AddSession(ra, ri.Identity); break; case "NTCP": transport = new NTCPClientOutgoing(ra, ri.Identity); break; default: throw new NotImplementedException(); } Logging.LogTransport( string.Format("TransportProvider: Creating new {0} transport {2} to {1}", ra.TransportStyle, ri.Identity.IdentHash.Id32Short, transport.DebugId)); AddTransport(transport); transport.Connect(); var dstore = new DatabaseStoreMessage(RouterContext.Inst.MyRouterInfo); transport.Send(dstore); } catch (Exception ex) { #if LOG_MUCH_TRANSPORT Logging.LogTransport(ex); Logging.LogTransport("TransportProvider: CreateTransport stack trace: " + System.Environment.StackTrace); #else Logging.LogTransport($"TransportProvider: Exception [{ex.GetType()}] " + $"'{ex.Message}' to {ri.Identity.IdentHash.Id32Short}."); #endif if (transport != null) { Remove(transport); } throw; } return(transport); }
private ITransport CreateTransport(I2PRouterInfo ri) { ITransport transport = null; try { I2PRouterAddress ra_ntcp = null; var ntcpaddr = ri.Adresses.Where(a => (a.TransportStyle == "NTCP") && a.Options.Contains("host") && a.Options.Contains("port") && (RouterContext.Inst.UseIpV6 || a.Options["host"].Contains('.'))); var a1 = ntcpaddr.Where(a => GetAddressFamiliy(a, "host") == System.Net.Sockets.AddressFamily.InterNetwork); if (a1.Any()) { ra_ntcp = a1.Random(); } else { a1 = ntcpaddr.Where(a => Dns.GetHostEntry(a.Options["host"]).AddressList. Any(aa => aa.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)); if (a1.Any()) { ra_ntcp = a1.Random(); } } I2PRouterAddress ra_ssu = null; var ssuaddr = ri.Adresses.Where(a => (a.TransportStyle == "SSU") && a.Options.Contains("key")); a1 = ssuaddr.Where(a => GetAddressFamiliy(a, "host") == System.Net.Sockets.AddressFamily.InterNetwork || GetAddressFamiliy(a, "ihost0") == System.Net.Sockets.AddressFamily.InterNetwork); if (a1.Any()) { ra_ssu = a1.Random(); } else { a1 = ntcpaddr.Where(a => Dns.GetHostEntry(a.Options["host"]).AddressList. Any(aa => aa.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)); if (a1.Any()) { ra_ssu = a1.Random(); } else { a1 = ntcpaddr.Where(a => Dns.GetHostEntry(a.Options["ihost0"]).AddressList. Any(aa => aa.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)); if (a1.Any()) { ra_ssu = a1.Random(); } } } I2PRouterAddress ra; //if ( ra_ntcp != null ) ra = ra_ntcp; else ra = ra_ssu; if (ra_ssu != null) { ra = ra_ssu; } else { ra = ra_ntcp; } if (ra == null) { Logging.LogTransport( string.Format("TransportProvider: CreateTransport: No usable address found for {0}!", ri.Identity.IdentHash.Id32Short)); return(null); } switch (ra.TransportStyle.ToString()) { case "SSU": transport = SsuHost.AddSession(ra, ri.Identity); break; case "NTCP": transport = new NTCPClientOutgoing(ra, ri.Identity); break; default: throw new NotImplementedException(); } Logging.LogTransport( string.Format("TransportProvider: Creating new {0} transport {2} to {1}", ra.TransportStyle, ri.Identity.IdentHash.Id32Short, transport.DebugId)); AddTransport(transport, ri.Identity.IdentHash); transport.Connect(); var dstore = new DatabaseStoreMessage(RouterContext.Inst.MyRouterInfo); transport.Send(dstore); } catch (Exception ex) { #if LOG_ALL_TRANSPORT Logging.LogTransport(ex); Logging.LogTransport("TransportProvider: CreateTransport stack trace: " + System.Environment.StackTrace); #else Logging.LogTransport("TransportProvider: Exception [" + ex.GetType().ToString() + "] '" + ex.Message + "' to " + ri.Identity.IdentHash.Id32Short + "."); #endif if (transport != null) { Remove(transport); } throw; } return(transport); }
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); }