public DatabaseLookupMessage( I2PIdentHash key, I2PIdentHash tunnelgw, I2PTunnelId tunnelid, LookupTypes flags, IEnumerable <I2PIdentHash> excludelist) { var excludecount = excludelist == null ? 0 : excludelist.Count(); AllocateBuffer(2 * 32 + 1 + 4 + 2 + 32 * excludecount); var writer = new BufRefLen(Payload); writer.Write(key.Hash); writer.Write(tunnelgw.Hash); writer.Write8((byte)((byte)flags | (byte)LookupTypes.Tunnel)); writer.Write32(tunnelid); if (excludecount > 0) { writer.WriteFlip16((ushort)excludecount); foreach (var addr in excludelist) { writer.Write(addr.Hash); } } else { writer.Write16(0); } //dest.Add( 0 ); // Tags }
public DatabaseStoreMessage( I2PLeaseSet leaseset, uint replytoken, I2PIdentHash replygw, I2PTunnelId replytunnelid) { var ls = leaseset.ToByteArray(); AllocateBuffer(32 + 5 + (replytoken != 0 ? 4 + 32: 0) + ls.Length); var writer = new BufRefLen(Payload); writer.Write(leaseset.Destination.IdentHash.Hash); writer.Write8((byte)MessageContent.LeaseSet); writer.Write32(replytoken); if (replytoken != 0) { writer.Write32(replytunnelid); if (replygw == null || replygw.Hash.Length != 32) { throw new FormatException("ReplyGateway has to be 32 bytes long!"); } writer.Write(replygw.Hash); } writer.Write(ls); UpdateCachedFields((BufRefLen)Payload); }
void UpdateCachedFields(BufRef reader) { CachedKey = new I2PIdentHash(reader); CachedFrom = new I2PIdentHash(reader); CachedLookupType = (LookupTypes)reader.Read8(); if (((byte)CachedLookupType & 0x01) != 0) { CachedTunnelId = new I2PTunnelId(reader); } var excludecount = reader.ReadFlip16(); for (int i = 0; i < excludecount; ++i) { CachedExcludeList.Add(new DatabaseSearchReplyMessage(reader)); } if (((byte)CachedLookupType & 0x02) != 0) { CachedReplyKey = new I2PSessionKey(reader); var tagcount = reader.Read8(); CachedTags.Add(new I2PSessionTag(reader)); } }
public TunnelDataMessage(I2PTunnelId desttunnel) { AllocateBuffer(DataLength + 4); TunnelId = desttunnel; IV.Randomize(); }
public I2NPHeader16(BufRef reader, I2PTunnelId fromtunnel) : base(reader, fromtunnel) { MessageRef = I2NPUtil.GetMessage(this, reader); #if DEBUG DebugCheckMessageCreation(MessageRef); #endif }
public OutboundTunnel(ITunnelOwner owner, TunnelConfig config, int replytunnelhops) : base(owner, config) { var outtunnel = config.Info.Hops[0]; NextHop = outtunnel.Peer.IdentHash; SendTunnelId = outtunnel.TunnelId; ReplyTunnelHops = replytunnelhops; }
public OutboundTunnel(TunnelConfig config, int replytunnelhops) : base(config) { TunnelSetup = config.Info; var outtunnel = TunnelSetup.Hops[0]; NextHop = outtunnel.Peer.IdentHash; SendTunnelId = outtunnel.TunnelId; ReplyTunnelHops = replytunnelhops; }
public TunnelDataMessage(byte[] data, I2PTunnelId tunnel) { var start = new BufRef(data); var reader = new BufRefLen(data); reader.Seek(4 + DataLength); SetBuffer(start, reader); TunnelId = tunnel; UpdateFirstDeliveryInstructionPosition(); }
public TunnelGatewayMessage(I2NPMessage message, I2PTunnelId outtunnel) { var msg = message.CreateHeader16.HeaderAndPayload; AllocateBuffer(6 + msg.Length); TunnelId = outtunnel; GatewayMessageLength = (ushort)msg.Length; // TODO: Remove mem copy Payload.Poke(msg, 6); }
// Fake 0-hop protected InboundTunnel(ITunnelOwner owner, TunnelConfig config) : base(owner, config) { Established = true; ReceiveTunnelId = config.Info.Hops.Last().TunnelId; RemoteGateway = RouterContext.Inst.MyRouterIdentity.IdentHash; GatewayTunnelId = ReceiveTunnelId; Logging.LogDebug($"{this}: 0-hop tunnel {Destination?.Id32Short} created."); }
public GarlicCloveDeliveryTunnel(BufRef reader, byte flag) : base(DeliveryMethod.Tunnel) { Flag = flag; if ((Flag & (byte)DeliveryFlags.Encrypted) != 0) { SessionKey = new I2PSessionKey(reader); } Destination = new I2PIdentHash(reader); Tunnel = new I2PTunnelId(reader); if ((Flag & (byte)DeliveryFlags.Delay) != 0) { Delay = reader.ReadFlip32(); } }
public InboundTunnel(ITunnelOwner owner, TunnelConfig config, int outtunnelhops) : base(owner, config) { OutTunnelHops = outtunnelhops; var gw = config.Info.Hops[0]; RemoteGateway = gw.Peer.IdentHash; GatewayTunnelId = gw.TunnelId; ReceiveTunnelId = config.Info.Hops.Last().TunnelId; #if LOG_ALL_TUNNEL_TRANSFER Logging.LogDebug($"InboundTunnel: Tunnel {Destination?.Id32Short} created."); #endif }
public GatewayTunnel(BuildRequestRecord brrec) : base(null) { Config = new TunnelConfig( TunnelConfig.TunnelDirection.Outbound, TunnelConfig.TunnelPool.External, null); Limiter = new BandwidthLimiter(Bandwidth.SendBandwidth, TunnelSettings.GatewayTunnelBitrateLimit); ReceiveTunnelId = new I2PTunnelId(brrec.ReceiveTunnel); SendTunnelId = new I2PTunnelId(brrec.NextTunnel); NextHop = new I2PIdentHash(new BufRefLen(brrec.NextIdent.Hash.Clone())); IVKey = brrec.IVKey.Clone(); LayerKey = brrec.LayerKey.Clone(); }
public DatabaseStoreMessage( I2PRouterInfo info, uint replytoken, I2PIdentHash replygw, I2PTunnelId replytunnelid) { BufLen msb; #if USE_BC_GZIP msb = LZUtils.BCGZipCompressNew(new BufLen(info.ToByteArray())); #else using (var ms = new MemoryStream()) { var buf = info.ToByteArray(); using (var gzs = new GZipStream(ms, CompressionMode.Compress)) { gzs.Write(buf, 0, buf.Length); gzs.Flush(); } msb = new BufLen(ms.ToArray()); } #endif var len = 32 + 1 + 4 + 2 + msb.Length + (replytoken != 0 ? 4 + 32 : 0); AllocateBuffer(len); var writer = new BufRefLen(Payload); writer.Write(info.Identity.IdentHash.Hash); writer.Write8((byte)MessageContent.RouterInfo); writer.Write(BitConverter.GetBytes(replytoken)); if (replytoken != 0) { writer.Write(BitConverter.GetBytes(replytunnelid)); if (replygw == null || replygw.Hash.Length != 32) { throw new FormatException("ReplyGateway has to be 32 bytes long!"); } writer.Write(replygw.Hash); } writer.WriteFlip16((ushort)msb.Length); writer.Write(msb); }
public EndpointTunnel(BuildRequestRecord brrec) : base(null) { Config = new TunnelConfig( TunnelConfig.TunnelDirection.Inbound, TunnelConfig.TunnelRole.Endpoint, TunnelConfig.TunnelPool.External, null); Limiter = new BandwidthLimiter(Bandwidth.SendBandwidth, TunnelSettings.EndpointTunnelBitrateLimit); ReceiveTunnelId = new I2PTunnelId(brrec.ReceiveTunnel); ResponseTunnelId = new I2PTunnelId(brrec.NextTunnel); ResponseMessageId = brrec.SendMessageId; NextHop = new I2PIdentHash(new BufRefLen(brrec.NextIdent.Hash.Clone())); IVKey = brrec.IVKey.Clone(); LayerKey = brrec.LayerKey.Clone(); }
public InboundTunnel(TunnelConfig config, int outtunnelhops) : base(config) { if (config != null) { Fake0HopTunnel = false; TunnelSetup = config.Info; OutTunnelHops = outtunnelhops; var gw = TunnelSetup.Hops[0]; RemoteGateway = gw.Peer.IdentHash; GatewayTunnelId = gw.TunnelId; ReceiveTunnelId = TunnelSetup.Hops.Last().TunnelId; #if LOG_ALL_TUNNEL_TRANSFER Logging.LogDebug($"InboundTunnel: Tunnel {Destination.Id32Short} created."); #endif } else { Fake0HopTunnel = true; var hops = new List <HopInfo> { new HopInfo(RouterContext.Inst.MyRouterIdentity, new I2PTunnelId()) }; TunnelSetup = new TunnelInfo(hops); Config = new TunnelConfig( TunnelConfig.TunnelDirection.Inbound, TunnelConfig.TunnelPool.Exploratory, TunnelSetup); ReceiveTunnelId = TunnelSetup.Hops.Last().TunnelId; RemoteGateway = RouterContext.Inst.MyRouterIdentity.IdentHash; GatewayTunnelId = ReceiveTunnelId; #if LOG_ALL_TUNNEL_TRANSFER Logging.LogDebug($"InboundTunnel {TunnelDebugTrace}: 0-hop tunnel {Destination.Id32Short} created."); #endif } }
public InboundTunnel(TunnelConfig config, int outtunnelhops) : base(config) { if (config != null) { Fake0HopTunnel = false; TunnelSetup = config.Info; OutTunnelHops = outtunnelhops; var gw = TunnelSetup.Hops[0]; RemoteGateway = gw.Peer.IdentHash; GatewayTunnelId = gw.TunnelId; ReceiveTunnelId = TunnelSetup.Hops.Last().TunnelId; DebugUtils.LogDebug("InboundTunnel: Tunnel " + Destination.Id32Short + " created."); } else { Fake0HopTunnel = true; var hops = new List <HopInfo>(); hops.Add(new HopInfo(RouterContext.Inst.MyRouterIdentity, new I2PTunnelId())); TunnelSetup = new TunnelInfo(hops); Config = new TunnelConfig( TunnelConfig.TunnelDirection.Inbound, TunnelConfig.TunnelRole.Endpoint, TunnelConfig.TunnelPool.Exploratory, TunnelSetup); ReceiveTunnelId = TunnelSetup.Hops.Last().TunnelId; RemoteGateway = RouterContext.Inst.MyRouterIdentity.IdentHash; GatewayTunnelId = ReceiveTunnelId; DebugUtils.LogDebug("InboundTunnel " + TunnelDebugTrace + ": 0-hop tunnel " + Destination.Id32Short + " created."); } }
protected I2NPHeader(BufRef reader, I2PTunnelId tunnel) { Buf = reader.ReadBufLen(Length); FromTunnel = tunnel; }
public TunnelMessageTunnel(II2NPHeader16 header, InboundTunnel tunnel) : base(header, tunnel.Destination, DeliveryTypes.Tunnel) { Tunnel = tunnel.GatewayTunnelId; }
public HopInfo(I2PKeysAndCert dest, I2PTunnelId id) { Peer = dest; TunnelId = id; }
public GarlicCloveDeliveryTunnel(I2NPMessage msg, I2PIdentHash dest, I2PTunnelId tunnel) : base(msg, DeliveryMethod.Tunnel) { Destination = dest; Tunnel = tunnel; }
public GarlicCloveDeliveryTunnel(I2NPMessage msg, InboundTunnel tunnel) : base(msg, DeliveryMethod.Tunnel) { Destination = tunnel.Destination; Tunnel = tunnel.GatewayTunnelId; }
private static PaddingInfo CalculatePadding(IEnumerable <TunnelMessage> messages, I2PTunnelId desttunnel) { var result = new PaddingInfo(); int tunneldatabufferavailable = FREE_SPACE_IN_DATA_MESSAGE_BODY; var currenttdrecord = new TunnelDataConstructionInfo(desttunnel); result.TDMessages.Add(currenttdrecord); var lastix = messages.Count() - 1; var ix = 0; foreach (var one in messages) { var lastmessage = ix++ == lastix; var data = one.Message.CreateHeader16.HeaderAndPayload; var datareader = new BufRefLen(data); nexttunneldatablock: int firstfragmentheadersize; bool fragmented = false; switch (one.Delivery) { case TunnelMessage.DeliveryTypes.Local: firstfragmentheadersize = 3; if (data.Length + firstfragmentheadersize > tunneldatabufferavailable) { firstfragmentheadersize += 4; // Need message id fragmented = true; } break; case TunnelMessage.DeliveryTypes.Router: firstfragmentheadersize = 35; if (data.Length + firstfragmentheadersize > tunneldatabufferavailable) { firstfragmentheadersize += 4; // Need message id fragmented = true; } break; case TunnelMessage.DeliveryTypes.Tunnel: firstfragmentheadersize = 39; if (data.Length + firstfragmentheadersize > tunneldatabufferavailable) { firstfragmentheadersize += 4; // Need message id fragmented = true; } break; default: throw new NotImplementedException(); } var freespace = tunneldatabufferavailable - firstfragmentheadersize; if (freespace < TUNNEL_DATA_MESSAGE_FREE_SPACE_LOW_WATERMARK) { currenttdrecord.PaddingNeeded = tunneldatabufferavailable; currenttdrecord = new TunnelDataConstructionInfo(desttunnel); result.TDMessages.Add(currenttdrecord); tunneldatabufferavailable = FREE_SPACE_IN_DATA_MESSAGE_BODY; goto nexttunneldatablock; } // Might fit, and have at least TUNNEL_DATA_MESSAGE_FREE_SPACE_LOW_WATERMARK bytes for payload. var useddata = fragmented ? freespace : datareader.Length; var usedspace = firstfragmentheadersize + useddata; currenttdrecord.Fragments.Add( new TunnelDataFragmentCreation( currenttdrecord.TunnelDataInstance, one, new BufLen(datareader, 0, useddata), fragmented)); datareader.Seek(useddata); tunneldatabufferavailable -= usedspace; int fragnr = 1; while (datareader.Length > 0) { if (tunneldatabufferavailable < TUNNEL_DATA_MESSAGE_FREE_SPACE_LOW_WATERMARK + FOLLOW_ON_FRAGMENT_HEADER_SIZE) { currenttdrecord.PaddingNeeded = tunneldatabufferavailable; currenttdrecord = new TunnelDataConstructionInfo(desttunnel); result.TDMessages.Add(currenttdrecord); tunneldatabufferavailable = FREE_SPACE_IN_DATA_MESSAGE_BODY; } freespace = tunneldatabufferavailable - FOLLOW_ON_FRAGMENT_HEADER_SIZE; if (datareader.Length <= freespace) { currenttdrecord.Fragments.Add( new TunnelDataFragmentFollowOn( currenttdrecord.TunnelDataInstance, one, new BufLen(datareader), fragnr++, true )); tunneldatabufferavailable -= FOLLOW_ON_FRAGMENT_HEADER_SIZE + datareader.Length; datareader.Seek(datareader.Length); if (lastmessage) { currenttdrecord.PaddingNeeded = tunneldatabufferavailable; return(result); } } else { useddata = freespace; currenttdrecord.Fragments.Add( new TunnelDataFragmentFollowOn( currenttdrecord.TunnelDataInstance, one, new BufLen(datareader, 0, useddata), fragnr++, false )); datareader.Seek(useddata); tunneldatabufferavailable = 0; } } } currenttdrecord.PaddingNeeded = tunneldatabufferavailable; return(result); }
internal TunnelDataConstructionInfo(I2PTunnelId desttunnel) { TunnelDataInstance = new TunnelDataMessage(desttunnel); }
public static IEnumerable <TunnelDataMessage> MakeFragments(IEnumerable <TunnelMessage> messages, I2PTunnelId desttunnel) { var padcalc = CalculatePadding(messages, desttunnel); foreach (var one in padcalc.TDMessages) { //Logging.Log( "New message" ); var writer = new BufRefLen(one.TunnelDataInstance.Payload); writer.Seek(24); // TunnelID, IV, Checksum of "Tunnel Message (Decrypted)" if (one.PaddingNeeded > 0) { //Logging.Log( "Padding " + one.PaddingNeeded.ToString() + " bytes" ); writer.Write(new BufRefLen(BufUtils.RandomNZ(one.PaddingNeeded))); } writer.Write8(0); // The Zero one.TunnelDataInstance.SetFirstDeliveryInstructionPoint(writer.View); foreach (var frag in one.Fragments) { var fragstart = new BufRefLen(writer); frag.Append(writer); //Logging.Log( "Fragment " + ( one.TunnelDataInstance.Writer - fragstart ).ToString() + " bytes" ); } one.TunnelDataInstance.Checksum.Poke(I2PHashSHA256.GetHash( one.TunnelDataInstance.FirstDeliveryInstruction, one.TunnelDataInstance.IV), 0, 4); if (writer.Length != 0) { Logging.LogCritical("TunnelData: MakeFragments. Tunnel block is not filled!"); throw new Exception("TunnelData message not filled. Something is wrong."); } } return(padcalc.TDMessages.Select(msg => msg.TunnelDataInstance)); }
public static VariableTunnelBuildMessage BuildOutboundTunnel( TunnelInfo setup, I2PIdentHash replyaddr, I2PTunnelId replytunnel, uint replymessageid) { byte usehops = (byte)(setup.Hops.Count > 5 ? 8 : 5); //byte usehops = 7; // 8 makes the response "TunnelBuildReply" var result = new VariableTunnelBuildMessage(usehops); // Hop sort order var requests = new List <BuildRequestRecord>(); for (int i = 0; i < setup.Hops.Count; ++i) { // Hop order: Our out dest -> Endpoint var endpoint = i == setup.Hops.Count - 1; var gateway = i == 0; var rec = new BuildRequestRecord(); rec.Data.Randomize(); rec.Flag = 0; var hop = setup.Hops[i]; rec.OurIdent = hop.Peer.IdentHash; rec.ReceiveTunnel = hop.TunnelId; if (!endpoint) { var nexthop = setup.Hops[i + 1]; rec.NextIdent = nexthop.Peer.IdentHash; rec.NextTunnel = nexthop.TunnelId; } else { rec.SendMessageId = replymessageid; rec.NextIdent = replyaddr; rec.NextTunnel = replytunnel; } rec.RequestTime = DateTime.UtcNow; rec.ToAnyone = endpoint; hop.LayerKey = new I2PSessionKey(rec.LayerKey.Clone()); hop.IVKey = new I2PSessionKey(rec.IVKey.Clone()); requests.Add(rec); #if LOG_ALL_TUNNEL_TRANSFER Logging.Log(rec.ToString()); #endif } // Physical record sort order var order = new List <AesEGBuildRequestRecord>(result.Records); order.Shuffle(); // Scramble the rest for (int i = setup.Hops.Count; i < usehops; ++i) { order[i].Data.Randomize(); } // ElGamal encrypt all of the non random records // and place them in shuffled order. for (int i = 0; i < setup.Hops.Count; ++i) { var hop = setup.Hops[i]; var egrec = new EGBuildRequestRecord(order[i].Data, requests[i], hop.Peer.IdentHash, hop.Peer.PublicKey); } var cipher = new CbcBlockCipher(new AesEngine()); // Dont Aes the first destination for (int i = setup.Hops.Count - 2; i >= 0; --i) { var prevhop = requests[i]; cipher.Init(false, prevhop.ReplyKeyBuf.ToParametersWithIV(prevhop.ReplyIV)); for (int j = i + 1; j < setup.Hops.Count; ++j) { cipher.Reset(); cipher.ProcessBytes(order[j].Data); } } for (int i = 0; i < setup.Hops.Count; ++i) { setup.Hops[i].ReplyProcessing = new ReplyProcessingInfo() { BuildRequestIndex = result.Records.IndexOf(order[i]), ReplyIV = requests[i].ReplyIV.Clone(), ReplyKey = new I2PSessionKey(requests[i].ReplyKeyBuf.Clone()) }; } return(result); }
public TunnelMessageTunnel(I2NPMessage message, I2PIdentHash destination, I2PTunnelId tunnel) : base(message, destination, DeliveryTypes.Tunnel) { Tunnel = tunnel; }
public TunnelMessageTunnel(II2NPHeader16 header, I2PIdentHash destination, I2PTunnelId tunnel) : base(header, destination, DeliveryTypes.Tunnel) { Tunnel = tunnel; }
public TunnelMessageTunnel(I2NPMessage message, InboundTunnel tunnel) : base(message, tunnel.Destination, DeliveryTypes.Tunnel) { Tunnel = tunnel.GatewayTunnelId; }