Beispiel #1
0
        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();
        }
Beispiel #2
0
 internal void DistributeIncomingMessage(ITransport instance, II2NPHeader msg)
 {
     if (IncomingMessage != null)
     {
         lock (IncomingMessage) IncomingMessage(instance, msg);
     }
 }
Beispiel #3
0
        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);
        }
        internal void HandleTunnelBuildRecords(
            II2NPHeader msg,
            TunnelBuildRequestDecrypt decrypt)
        {
            if (decrypt.Decrypted.ToAnyone)
            {
                // Im outbound endpoint
                Logging.LogDebug($"HandleTunnelBuildRecords: Outbound endpoint request {decrypt}");
                HandleEndpointTunnelRequest(msg, decrypt);
                return;
            }

            if (decrypt.Decrypted.FromAnyone)
            {
                // Im inbound gateway
                Logging.LogDebug($"HandleTunnelBuildRecords: Inbound gateway request {decrypt}");
                HandleGatewayTunnelRequest(msg, decrypt);
                return;
            }

            if (decrypt.Decrypted.NextIdent != RouterContext.Inst.MyRouterIdentity.IdentHash)
            {
                // Im transit tunnel
                Logging.LogDebug($"HandleTunnelBuildRecords: Transit tunnel request {decrypt}");
                HandleTransitTunnelRequest(msg, decrypt);
                return;
            }

            throw new NotSupportedException();
        }
        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);
        }
Beispiel #6
0
 void host_DataBlockReceived(ITransport arg1, II2NPHeader arg2)
 {
     lock ( DataReceived )
     {
         DataReceived.Add(arg2);
     }
 }
Beispiel #7
0
        internal void MessageReceived( II2NPHeader newmessage )
        {
#if DEBUG
            if ( DataBlockReceived == null ) Logging.LogWarning( "SSUSession: " + DebugId + " No observers for DataBlockReceived!" );
#endif
            if ( DataBlockReceived != null ) DataBlockReceived( this, newmessage );
        }
Beispiel #8
0
        public virtual void MessageReceived(II2NPHeader msg)
        {
            Bandwidth.DataReceived(msg.HeaderAndPayload.Length);

            lock ( ReceiveQueue )
            {
                ReceiveQueue.AddFirst(msg);
            }
        }
Beispiel #9
0
 void Transport_DataBlockReceived(ITransport instance, II2NPHeader msg)
 {
     try
     {
         DistributeIncomingMessage(instance, msg);
     }
     catch (Exception ex)
     {
         Logging.Log(ex);
     }
 }
Beispiel #10
0
        private static I2NPMessage CreateReplyMessage(
            II2NPHeader msg,
            TunnelBuildRequestDecrypt decrypt,
            BuildResponseRecord.RequestResponse response)
        {
            var newrecords = decrypt.CreateTunnelBuildReplyRecords(response);

            if (msg.MessageType == I2NPMessage.MessageTypes.VariableTunnelBuild)
            {
                return(new VariableTunnelBuildMessage(newrecords));
            }
            else
            {
                return(new TunnelBuildMessage(newrecords));
            }
        }
Beispiel #11
0
        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);
        }
Beispiel #12
0
        static void TunnelProvider_I2NPMessageReceived(II2NPHeader msg)
        {
            switch (msg.MessageType)
            {
            case I2NPMessage.MessageTypes.DatabaseStore:
                var ds = (DatabaseStoreMessage)msg.Message;
#if LOG_ALL_TUNNEL_TRANSFER
                Logging.Log($"Router: DatabaseStore : {ds.Key.Id32Short}");
#endif
                HandleDatabaseStore(ds);
                break;

            case I2NPMessage.MessageTypes.DatabaseSearchReply:
                var dsr = (DatabaseSearchReplyMessage)msg.Message;
#if LOG_ALL_TUNNEL_TRANSFER
                Logging.Log($"Router: DatabaseSearchReply: {dsr}");
#endif
                NetDb.Inst.AddDatabaseSearchReply(dsr);
                break;

            case I2NPMessage.MessageTypes.DeliveryStatus:
#if LOG_ALL_TUNNEL_TRANSFER || LOG_ALL_LEASE_MGMT
                Logging.LogDebug($"Router: DeliveryStatus: {msg.Message}");
#endif

                var dsmsg = (DeliveryStatusMessage)msg.Message;
                DeliveryStatusReceived?.Invoke(dsmsg);
                break;

            case I2NPMessage.MessageTypes.Garlic:
#if LOG_ALL_TUNNEL_TRANSFER
                Logging.LogDebug($"Router: Garlic: {msg.Message}");
#endif
                HandleGarlic((GarlicMessage)msg.Message);
                break;

            default:
                Logging.LogDebug($"TunnelProvider_I2NPMessageReceived: Unhandled message ({msg.Message})");
                break;
            }
        }
Beispiel #13
0
        private bool HandleReceiveQueue()
        {
            II2NPHeader msg = null;
            List <TunnelDataMessage> tdmsgs = null;

            lock ( ReceiveQueue )
            {
                if (ReceiveQueue.Count == 0)
                {
                    return(true);
                }

                if (ReceiveQueue.Any(mq => mq.MessageType == I2NPMessage.MessageTypes.TunnelData))
                {
                    var removelist = ReceiveQueue.Where(mq => mq.MessageType == I2NPMessage.MessageTypes.TunnelData);
                    tdmsgs = removelist.Select(mq => (TunnelDataMessage)mq.Message).ToList();
                    foreach (var one in removelist.ToArray())
                    {
                        ReceiveQueue.Remove(one);
                    }
                }
                else
                {
                    msg = ReceiveQueue.Last.Value;
                    ReceiveQueue.RemoveLast();
                }
            }

            if (tdmsgs != null)
            {
                HandleTunnelData(tdmsgs);
                return(true);
            }

            DebugUtils.LogDebug("InboundTunnel " + TunnelDebugTrace + " HandleReceiveQueue: " + msg.MessageType.ToString());

            switch (msg.MessageType)
            {
            case I2NPMessage.MessageTypes.TunnelData:
                throw new NotImplementedException("Should not happen " + TunnelDebugTrace);

            case I2NPMessage.MessageTypes.TunnelBuildReply:
                ThreadPool.QueueUserWorkItem(cb =>
                {
                    TunnelProvider.Inst.HandleTunnelBuildReply((II2NPHeader16)msg, (TunnelBuildReplyMessage)msg.Message);
                });
                return(true);

            case I2NPMessage.MessageTypes.VariableTunnelBuildReply:
                ThreadPool.QueueUserWorkItem(cb =>
                {
                    TunnelProvider.Inst.HandleVariableTunnelBuildReply((II2NPHeader16)msg, (VariableTunnelBuildReplyMessage)msg.Message);
                });
                return(true);

            case I2NPMessage.MessageTypes.DeliveryStatus:
#if LOG_ALL_TUNNEL_TRANSFER
                DebugUtils.LogDebug("InboundTunnel " + TunnelDebugTrace + ": DeliveryStatus: " + msg.Message.ToString());
#endif

                ThreadPool.QueueUserWorkItem(cb => {
                    lock (DeliveryStatusReceivedLock) if (DeliveryStatusReceived != null)
                        {
                            DeliveryStatusReceived((DeliveryStatusMessage)msg.Message);
                        }
                });
                break;

            case I2NPMessage.MessageTypes.DatabaseStore:
                var ds = (DatabaseStoreMessage)msg.Message;
                ThreadPool.QueueUserWorkItem(cb =>
                {
                    TunnelProvider.HandleDatabaseStore(ds);
                });
                break;

            case I2NPMessage.MessageTypes.Garlic:
#if LOG_ALL_TUNNEL_TRANSFER
                DebugUtils.Log("InboundTunnel " + TunnelDebugTrace + ": Garlic: " + msg.Message.ToString());
#endif

                ThreadPool.QueueUserWorkItem(cb =>
                {
                    lock (GarlicMessageReceivedLock) if (GarlicMessageReceived != null)
                        {
                            GarlicMessageReceived((GarlicMessage)msg.Message);
                        }
                });
                break;

            default:
                DebugUtils.LogWarning("InboundTunnel " + TunnelDebugTrace + " HandleReceiveQueue: Dropped " + msg.ToString());
                break;
            }

            return(true);
        }