internal void HandleTunnelBuildRecords( II2NPHeader msg, IEnumerable <AesEGBuildRequestRecord> records, EGBuildRequestRecord myrec, BuildRequestRecord drec) { if (drec.ToAnyone) { // Im outbound endpoint Logging.LogDebug("HandleTunnelBuildRecords: Outbound endpoint request " + drec.ToString()); HandleEndpointTunnelRequest(msg, records, myrec, drec); return; } if (drec.FromAnyone) { // Im inbound gateway Logging.LogDebug("HandleTunnelBuildRecords: Inbound gateway request " + drec.ToString()); HandleGatewayTunnelRequest(msg, records, myrec, drec); return; } if (drec.NextIdent != RouterContext.Inst.MyRouterIdentity.IdentHash) { // Im passthrough tunnel Logging.LogDebug("HandleTunnelBuildRecords: Passthrough tunnel request " + drec.ToString()); HandlePassthroughTunnelRequest(msg, records, myrec, drec); return; } throw new NotSupportedException(); }
private void HandleGatewayTunnelRequest( II2NPHeader msg, IEnumerable <AesEGBuildRequestRecord> records, EGBuildRequestRecord myrec, BuildRequestRecord drec) { var tunnel = new GatewayTunnel(drec); var replykey = drec.ReplyKey.Key.Clone(); var replyiv = drec.ReplyIV.Clone(); tunnel.EstablishedTime.SetNow(); var doaccept = AcceptingTunnels(drec); var response = doaccept ? BuildResponseRecord.RequestResponse.Accept : BuildResponseRecord.DefaultErrorReply; Logging.LogDebug(() => string.Format("HandleGatewayTunnelRequest {3}: {0} Gateway tunnel request: {1} for tunnel id {2}.", tunnel.Destination.Id32Short, response, tunnel.ReceiveTunnelId, tunnel.TunnelDebugTrace)); TunnelProvider.UpdateTunnelBuildReply(records, myrec, replykey, replyiv, response); if (response == BuildResponseRecord.RequestResponse.Accept) { AddTunnel(tunnel); TunnelMgr.AddExternalTunnel(tunnel); AcceptedTunnelBuildRequest(drec); } TransportProvider.Send(tunnel.Destination, msg.Message); }
private void HandleEndpointTunnelRequest( II2NPHeader msg, IEnumerable <AesEGBuildRequestRecord> records, EGBuildRequestRecord myrec, BuildRequestRecord drec) { var tunnel = new EndpointTunnel(drec); var replykey = drec.ReplyKey.Key.Clone(); var replyiv = drec.ReplyIV.Clone(); tunnel.EstablishedTime.SetNow(); var doaccept = AcceptingTunnels(drec); var response = doaccept ? BuildResponseRecord.RequestResponse.Accept : BuildResponseRecord.DefaultErrorReply; DebugUtils.LogDebug(() => string.Format("HandleEndpointTunnelRequest {3}: {0} Endpoint tunnel request: {1} for tunnel id {2}.", tunnel.Destination.Id32Short, response, tunnel.ReceiveTunnelId, tunnel.TunnelDebugTrace)); TunnelProvider.UpdateTunnelBuildReply(records, myrec, replykey, replyiv, response); var responsemessage = new VariableTunnelBuildReplyMessage(records.Select(r => new BuildResponseRecord(r))); var buildreplymsg = new TunnelGatewayMessage(responsemessage.GetHeader16(tunnel.ResponseMessageId), tunnel.ResponseTunnelId); if (response == BuildResponseRecord.RequestResponse.Accept) { AddTunnel(tunnel); TunnelMgr.AddExternalTunnel(tunnel); AcceptedTunnelBuildRequest(drec); } TransportProvider.Send(tunnel.Destination, buildreplymsg); }
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 TunnelBuildRequestDecrypt( IEnumerable <AesEGBuildRequestRecord> records, I2PIdentHash me, I2PPrivateKey key) { RecordsField = records; Me = me; Key = key; ToMeField = RecordsField.FirstOrDefault(rec => Me.Hash16 == rec.ToPeer16); if (ToMeField != null) { MyRecord = new EGBuildRequestRecord(ToMeField); DecryptedRecord = MyRecord.Decrypt(key); } }
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(); }
private bool AcceptingTunnels(BuildRequestRecord drec) { // TODO: Implement /* * if ( !NextHopFilter.Update( drec.NextIdent ) ) * { * Logging.LogDebug( () => string.Format( "TransitProvider AcceptingTunnels: Reject due same next destination. " + * "Running tunnels: {0}. Accept: {1}.", * RunningTunnels.Count, false ) ); * } */ var currenttunnelcount = RunningGatewayTunnels.Count + RunningEndpointTunnels.Count + RunningTransitTunnels.Count; bool recent = HaveSeenTunnelBuildRequest(drec); if (recent) { Logging.LogDebug($"TransitProvider AcceptingTunnels: Reject due to similarity to recent tunnel. " + $"Running tunnels: {currenttunnelcount}. Accept: false."); return(false); } var result = currenttunnelcount < MaxRunningTransitTunnels; result &= TunnelMgr.AcceptTransitTunnels; if (result) { AcceptedTunnelBuildRequest(drec); } Logging.LogDebug($"TransitProvider AcceptingTunnels: Running tunnels: {currenttunnelcount}. Accept: {result}."); return(result); }
private bool AcceptingTunnels(BuildRequestRecord drec) { // TODO: Implement /* * if ( !NextHopFilter.Update( drec.NextIdent ) ) * { * Logging.LogDebug( () => string.Format( "PassthroughProvider AcceptingTunnels: Reject due same next destination. " + * "Running tunnels: {0}. Accept: {1}.", * RunningTunnels.Count, false ) ); * } */ bool recent = HaveSeenTunnelBuildRequest(drec); if (recent) { Logging.LogDebug(() => string.Format("PassthroughProvider AcceptingTunnels: Reject due to similarity to recent tunnel. " + "Running tunnels: {0}. Accept: {1}.", RunningTunnels.Count, false)); return(false); } var result = RunningTunnels.Count < MaxRunningPassthroughTunnels; result &= TunnelMgr.ClientsMgr.ClientTunnelsStatusOk; if (result) { AcceptedTunnelBuildRequest(drec); } Logging.LogDebug(() => string.Format("PassthroughProvider AcceptingTunnels: Running tunnels: {0}. Accept: {1}.", RunningTunnels.Count, result)); return(result); //if ( result ) result = NetDb.Inst.GetConnectionRank( id ) }
bool HaveSeenTunnelBuildRequest(BuildRequestRecord drec) { return(!AcceptedTunnelHashes.Update(drec.GetReducedHash())); }
void AcceptedTunnelBuildRequest(BuildRequestRecord drec) { }
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 static VariableTunnelBuildMessage BuildInboundTunnel( TunnelInfo setup) { byte usehops = (byte)(setup.Hops.Count > 5 ? 8 : 5); var result = new VariableTunnelBuildMessage(usehops); // Hop sort order var requests = new List <BuildRequestRecord>(); for (int i = 0; i < setup.Hops.Count; ++i) { // Hop order: GW -> us 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 { // Used to identify the record as the last in an inbound tunnel to us rec.NextIdent = hop.Peer.IdentHash; rec.NextTunnel = hop.TunnelId; } rec.RequestTime = DateTime.UtcNow; rec.FromAnyone = gateway; 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 BufferedBlockCipher(new CbcBlockCipher(new AesEngine())); // Dont Aes the first block for (int i = setup.Hops.Count - 2; i >= 0; --i) { var prevhop = requests[i]; cipher.Init(false, new ParametersWithIV(new KeyParameter(prevhop.ReplyKey.ToByteArray()), prevhop.ReplyIV.ToByteArray())); for (int j = i + 1; j < setup.Hops.Count; ++j) { cipher.Reset(); order[j].Process(cipher); } } 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); }