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; Logging.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); }
private void HandleEndpointTunnelRequest( II2NPHeader msg, TunnelBuildRequestDecrypt decrypt) { var config = new TunnelConfig( TunnelConfig.TunnelDirection.Inbound, TunnelConfig.TunnelPool.External, new TunnelInfo(new List <HopInfo> { new HopInfo( RouterContext.Inst.MyRouterIdentity, new I2PTunnelId()) } )); var tunnel = new EndpointTunnel(this, config, decrypt.Decrypted); tunnel.EstablishedTime.SetNow(); var doaccept = AcceptingTunnels(decrypt.Decrypted); var response = doaccept ? BuildResponseRecord.RequestResponse.Accept : BuildResponseRecord.DefaultErrorReply; Logging.LogDebug($"HandleEndpointTunnelRequest {tunnel.TunnelDebugTrace}: " + $"{tunnel.Destination.Id32Short} Endpoint tunnel request: {response} " + $"for tunnel id {tunnel.ReceiveTunnelId}."); var newrecords = decrypt.CreateTunnelBuildReplyRecords(response); var responsemessage = new VariableTunnelBuildReplyMessage( newrecords.Select(r => new BuildResponseRecord(r)), tunnel.ResponseMessageId); var buildreplymsg = new TunnelGatewayMessage( responsemessage, tunnel.ResponseTunnelId); if (response == BuildResponseRecord.RequestResponse.Accept) { RunningEndpointTunnels[tunnel] = 1; TunnelMgr.AddTunnel(tunnel); AcceptedTunnelBuildRequest(decrypt.Decrypted); } TransportProvider.Send(tunnel.Destination, buildreplymsg); }
private bool HandleReceivedTunnelBuild(VariableTunnelBuildReplyMessage msg) { var cipher = new CbcBlockCipher(new AesEngine()); for (int i = TunnelSetup.Hops.Count - 1; i >= 0; --i) { var proc = TunnelSetup.Hops[i].ReplyProcessing; cipher.Init(false, proc.ReplyKey.Key.ToParametersWithIV(proc.ReplyIV)); for (int j = 0; j <= i; ++j) { cipher.Reset(); var pl = msg.ResponseRecords[TunnelSetup.Hops[j].ReplyProcessing.BuildRequestIndex].Payload; cipher.ProcessBytes(pl); } } bool ok = true; for (int i = 0; i < TunnelSetup.Hops.Count; ++i) { var hop = TunnelSetup.Hops[i]; var ix = hop.ReplyProcessing.BuildRequestIndex; var onerecord = msg.ResponseRecords[ix]; var okhash = onerecord.CheckHash(); if (!okhash) { Logging.LogDebug($"OutboundTunnel {TunnelDebugTrace}: Outbound tunnel build reply, hash check failed from {hop.Peer.IdentHash.Id32Short}"); NetDb.Inst.Statistics.DestinationInformationFaulty(hop.Peer.IdentHash); } var accept = onerecord.Reply == BuildResponseRecord.RequestResponse.Accept; if (accept) { NetDb.Inst.Statistics.SuccessfulTunnelMember(hop.Peer.IdentHash); } else { NetDb.Inst.Statistics.DeclinedTunnelMember(hop.Peer.IdentHash); } ok &= accept && okhash; Logging.LogDebug($"{this}: HandleReceivedTunnelBuild reply[{ix}]: " + $"from {hop.Peer.IdentHash.Id32Short}. {TunnelSetup.Hops.Count} hops, " + $"Tunnel build reply: {onerecord.Reply}"); } if (ok) { TunnelProvider.Inst.OutboundTunnelEstablished(this); foreach (var one in TunnelSetup.Hops) { NetDb.Inst.Statistics.SuccessfulTunnelMember(one.Peer.IdentHash); one.ReplyProcessing = null; // We dont need this anymore } } else { foreach (var one in TunnelSetup.Hops) { NetDb.Inst.Statistics.DeclinedTunnelMember(one.Peer.IdentHash); one.ReplyProcessing = null; // We dont need this anymore } } return(ok); }
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); }