예제 #1
0
파일: Program.cs 프로젝트: itfenom/i2p-cs
        static void MyDestination_DataReceived(ClientDestination dest, BufLen data)
        {
            Logging.LogInformation($"Program {UnpublishedDestination}: data received {data:20}");

            var reader = new BufRefLen(data);
            var unzip  = LZUtils.BCGZipDecompressNew((BufLen)reader);
            var packet = new StreamingPacket((BufRefLen)unzip);

            Logging.LogInformation($"Program {UnpublishedDestination}: {packet}");
        }
예제 #2
0
        void UpdateCachedFields(BufRef reader)
        {
            CachedKey        = new I2PIdentHash(reader);
            CachedContent    = reader.Read8() == 0 ? MessageContent.RouterInfo : MessageContent.LeaseSet;
            CachedReplyToken = reader.Read32();
            if (CachedReplyToken != 0)
            {
                CachedReplyTunnelId = reader.Read32();
                CachedReplyGateway  = new I2PIdentHash(reader);
            }

            switch (CachedContent)
            {
            case MessageContent.RouterInfo:
                var length = reader.ReadFlip16();

#if USE_BC_GZIP
                CachedRouterInfo = new I2PRouterInfo(
                    new BufRefLen(LZUtils.BCGZipDecompressNew(new BufLen(reader, 0, length))), true);
#else
                using (var ms = new MemoryStream())
                {
                    ms.Write(reader.BaseArray, reader.BaseArrayOffset, length);
                    ms.Position = 0;

                    using (var gzs = new GZipStream(ms, CompressionMode.Decompress))
                    {
                        var gzdata = StreamUtils.Read(gzs);
                        CachedRouterInfo = new I2PRouterInfo(new BufRefLen(gzdata), true);
                    }
                }
#endif

                reader.Seek(length);
                break;

            case MessageContent.LeaseSet:
                CachedLeaseSet = new I2PLeaseSet(reader);
                break;

            /*
             * case MessageContent.LeaseSet2:
             * break;
             *
             * case MessageContent.EncryptedLeaseSet:
             * break;
             *
             * case MessageContent.MetaLeaseSet:
             * break;
             */
            default:
                throw new InvalidDataException($"DatabaseStoreMessage: {CachedContent} not supported");
            }
        }
예제 #3
0
        public BufLen GenerateData(I2NPMessage msg)
        {
            if (NTCPContext == null)
            {
                throw new Exception("NTCP Session not negotiated!");
            }
            if (NTCPContext.Encryptor == null)
            {
                throw new Exception("NTCP encryptor not available");
            }

            var data = msg != null ? msg.Header16.HeaderAndPayload: null;

            var datalength = msg == null ? 4 : data.Length;
            var buflen     = 2 + datalength + 4;
            var padlength  = BufUtils.Get16BytePadding(buflen);

            buflen += padlength;

            var buf    = new BufLen(new byte[buflen]);
            var writer = new BufRefLen(buf);

            // Length
            if (msg == null)
            {
                // Send timestamp
                writer.Write16(0);
                writer.WriteFlip32((uint)(DateTime.UtcNow - I2PDate.RefDate).TotalSeconds);
            }
            else
            {
                if (data.Length > 16378)
                {
                    throw new ArgumentException("NTCP data can be max 16378 bytes long!");
                }
                writer.WriteFlip16((ushort)data.Length);
                writer.Write(data);
            }

            // Pad
            writer.Write(BufUtils.Random(writer.Length - 4));

            // Checksum
            var checkbuf = new BufLen(buf, 0, writer - buf);
            var checksum = LZUtils.Adler32(1, checkbuf);

            writer.WriteFlip32(checksum);

            // Encrypt
            NTCPContext.Encryptor.ProcessBytes(buf);

            return(buf);
        }
예제 #4
0
        private BufLen ReadBlock()
        {
            var inbufend = 2 + BlockLength + 4;

            inbufend += BufUtils.Get16BytePadding(inbufend);

            while (InBufPos < inbufend)
            {
                if (MySocket.Available > 0)
                {
                    var len = MySocket.Receive(InBuf, InBufPos, inbufend - InBufPos, SocketFlags.None);
                    if (len == 0)
                    {
                        throw new EndOfStreamEncounteredException();
                    }
                    InBufPos += len;
                }
                else
                {
                    Thread.Sleep(400);
                    if (!MySocket.Connected)
                    {
                        throw new EndOfStreamEncounteredException();
                    }
                }
            }

            Cipher.ProcessBytes(new BufLen(InBuf, 16, InBufPos - 16));

            var checksum = LZUtils.Adler32(1, new BufLen(InBuf, 0, InBufPos - 4));
            var blocksum = BufUtils.Flip32(InBuf, InBufPos - 4);

            if (checksum != blocksum)
            {
                throw new ChecksumFailureException("NTCPReader: Received Adler checksum mismatch.");
            }

            var result = new BufLen(InBuf, 2, BlockLength);

            BlockLength = -1;

#if LOG_ALL_TRANSPORT
            Logging.LogTransport(string.Format("NTCPReader +{1}+ block received: {0} bytes [0x{0:X}]", result.Length, Context.TransportInstance));
#endif
            return(result.Clone());
        }
예제 #5
0
파일: Program.cs 프로젝트: itfenom/i2p-cs
        static void MyDestination_DataReceived(ClientDestination dest, BufLen data)
        {
            Logging.LogInformation($"Program {PublishedDestination}: data received {data:15}");

            var reader = new BufRefLen(data);
            var unzip  = LZUtils.BCGZipDecompressNew((BufLen)reader);
            var packet = new StreamingPacket((BufRefLen)unzip);

            Logging.LogInformation($"Program {PublishedDestination}: {packet} {packet.Payload}");

            PublishedDestination.LookupDestination(packet?.From.IdentHash, (hash, ls, tag) =>
            {
                if (ls is null)
                {
                    Logging.LogInformation($"Program {PublishedDestination}: Failed to lookup {hash?.Id32Short}.");
                    return;
                }

                var s  = new BufRefStream();
                var sh = new StreamingPacket(
                    PacketFlags.SYNCHRONIZE
                    | PacketFlags.FROM_INCLUDED
                    | PacketFlags.SIGNATURE_INCLUDED
                    | PacketFlags.MAX_PACKET_SIZE_INCLUDED
                    | PacketFlags.NO_ACK)
                {
                    From            = PublishedDestination.Destination,
                    SigningKey      = MyDestinationInfo.PrivateSigningKey,
                    ReceiveStreamId = packet.ReceiveStreamId,
                    SendStreamId    = SendId,
                    NACKs           = new List <uint>(),
                    Payload         = new BufLen(BufUtils.RandomBytes(30)),
                };

                sh.Write(s);
                var buf    = s.ToByteArray();
                var zipped = LZUtils.BCGZipCompressNew(new BufLen(buf));
                zipped.PokeFlip16(4353, 4);                // source port
                zipped.PokeFlip16(25, 6);                  // dest port
                zipped[9] = (byte)PayloadFormat.Streaming; // streaming

                Logging.LogInformation($"Program {PublishedDestination}: Sending {zipped:20}.");
                PublishedDestination.Send(ls.Destination, zipped);
            });
        }
예제 #6
0
        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);
        }
예제 #7
0
        public void TestGZip()
        {
            var smalldata = BufUtils.RandomBytes(200);
            var bigdata   = BufUtils.RandomBytes(2 * 1024 * 1024);

            var smalldata_zero = new byte[200];
            var bigdata_zero   = new byte[2 * 1024 * 1024];

            var b1 = LZUtils.BCGZipCompressNew(new BufLen(smalldata));
            var b2 = LZUtils.BCGZipDecompressNew(b1);

            Assert.IsTrue(b2 == new BufLen(smalldata));

            b1 = LZUtils.BCGZipCompressNew(new BufLen(bigdata));
            b2 = LZUtils.BCGZipDecompressNew(b1);
            Assert.IsTrue(b2 == new BufLen(bigdata));

            b1 = LZUtils.BCGZipCompressNew(new BufLen(smalldata_zero));
            b2 = LZUtils.BCGZipDecompressNew(b1);
            Assert.IsTrue(b2 == new BufLen(smalldata_zero));

            b1 = LZUtils.BCGZipCompressNew(new BufLen(bigdata_zero));
            b2 = LZUtils.BCGZipDecompressNew(b1);
            Assert.IsTrue(b2 == new BufLen(bigdata_zero));

            var ba1 = LZUtils.BCGZipCompress(bigdata);

            b2 = LZUtils.BCGZipDecompressNew(new BufLen(ba1));
            Assert.IsTrue(b2 == new BufLen(bigdata));

            b1 = LZUtils.BCGZipCompressNew(new BufLen(bigdata_zero));
            var ba2 = LZUtils.BCGZipDecompress(b1);

            Assert.IsTrue(new BufLen(ba2) == new BufLen(bigdata_zero));

            for (int i = bigdata.Length / 10; i < bigdata.Length - bigdata.Length / 10; ++i)
            {
                bigdata[i] = 42;
            }
            b1 = LZUtils.BCGZipCompressNew(new BufLen(bigdata));
            b2 = LZUtils.BCGZipDecompressNew(b1);
            Assert.IsTrue(b2 == new BufLen(bigdata));
        }
예제 #8
0
        void UpdateCachedFields(BufRef reader)
        {
            CachedKey        = new I2PIdentHash(reader);
            CachedContent    = reader.Read8() == 0 ? MessageContent.RouterInfo : MessageContent.LeaseSet;
            CachedReplyToken = reader.Read32();
            if (CachedReplyToken != 0)
            {
                CachedReplyTunnelId = reader.Read32();
                CachedReplyGateway  = new I2PIdentHash(reader);
            }

            if (CachedContent == MessageContent.RouterInfo)
            {
                var length = reader.ReadFlip16();

#if USE_BC_GZIP
                CachedRouterInfo = new I2PRouterInfo(
                    new BufRefLen(LZUtils.BCGZipDecompressNew(new BufLen(reader, 0, length))), true);
#else
                using (var ms = new MemoryStream())
                {
                    ms.Write(reader.BaseArray, reader.BaseArrayOffset, length);
                    ms.Position = 0;

                    using (var gzs = new GZipStream(ms, CompressionMode.Decompress))
                    {
                        var gzdata = StreamUtils.Read(gzs);
                        CachedRouterInfo = new I2PRouterInfo(new BufRefLen(gzdata), true);
                    }
                }
#endif

                reader.Seek(length);
            }
            else
            {
                CachedLeaseSet = new I2PLeaseSet(reader);
            }
        }
예제 #9
0
파일: Program.cs 프로젝트: itfenom/i2p-cs
        static void Main(string[] args)
        {
            Logging.ReadAppConfig();
            Logging.LogToDebug   = false;
            Logging.LogToConsole = true;

            RouterContext.RouterSettingsFile = "EchoClientRouter.bin";
            RouterContext.Inst = new RouterContext(
                new I2PCertificate(
                    I2PSigningKey.SigningKeyTypes.DSA_SHA1));

            for (int i = 0; i < args.Length; ++i)
            {
                switch (args[i])
                {
                case "--addr":
                case "--address":
                    if (args.Length > i + 1)
                    {
                        RouterContext.Inst.DefaultExtAddress = IPAddress.Parse(args[++i]);
                        Console.WriteLine($"addr {RouterContext.Inst.DefaultExtAddress}");
                    }
                    else
                    {
                        Console.WriteLine("--addr require ip number");
                        return;
                    }
                    break;

                case "--port":
                    if (args.Length > i + 1)
                    {
                        var port = int.Parse(args[++i]);
                        RouterContext.Inst.DefaultTCPPort = port;
                        RouterContext.Inst.DefaultUDPPort = port;
                        Console.WriteLine($"port {port}");
                    }
                    else
                    {
                        Console.WriteLine("--port require port number");
                        return;
                    }
                    break;

                case "--nofw":
                    RouterContext.Inst.IsFirewalled = false;
                    Console.WriteLine($"Firewalled {RouterContext.Inst.IsFirewalled}");
                    break;

                default:
                    Console.WriteLine(args[i]);
                    Console.WriteLine("Usage: I2P.exe --addr 12.34.56.78 --port 8081 --nofw");
                    break;
                }
            }

            RouterContext.Inst.ApplyNewSettings();
            Router.Start();

            var destb32    = AppSettings["RemoteDestination"];
            var remotedest = new I2PIdentHash(destb32);

            MyDestinationInfo      = new I2PDestinationInfo(I2PSigningKey.SigningKeyTypes.EdDSA_SHA512_Ed25519);
            UnpublishedDestination = Router.CreateDestination(MyDestinationInfo, false, out _);
            UnpublishedDestination.DataReceived += MyDestination_DataReceived;
            UnpublishedDestination.Name          = "UnpublishedDestination";

            Logging.LogInformation($"MyDestination: {UnpublishedDestination.Destination.IdentHash} {MyDestinationInfo.Destination.Certificate}");

            var interval = new PeriodicAction(TickSpan.Seconds(40));

            while (true)
            {
                try
                {
                    Connected = true;

                    while (Connected)
                    {
                        Thread.Sleep(2000);

                        uint recvid = BufUtils.RandomUintNZ();

                        interval.Do(() =>
                        {
                            Logging.LogInformation($"Program {UnpublishedDestination}: Looking for {remotedest}.");
                            UnpublishedDestination.LookupDestination(remotedest, (hash, ls, tag) =>
                            {
                                if (ls is null)
                                {
                                    Logging.LogInformation($"Program {UnpublishedDestination}: Failed to lookup {hash.Id32Short}.");
                                    return;
                                }

                                var test = new I2PIdentHash(ls.Destination);
                                Logging.LogInformation($"Program {UnpublishedDestination}: Found {remotedest}, test: {test.Id32Short}.");

                                var s  = new BufRefStream();
                                var sh = new StreamingPacket(
                                    PacketFlags.SYNCHRONIZE
                                    | PacketFlags.FROM_INCLUDED
                                    | PacketFlags.SIGNATURE_INCLUDED
                                    | PacketFlags.MAX_PACKET_SIZE_INCLUDED
                                    | PacketFlags.NO_ACK)
                                {
                                    From            = UnpublishedDestination.Destination,
                                    SigningKey      = MyDestinationInfo.PrivateSigningKey,
                                    ReceiveStreamId = recvid,
                                    NACKs           = new List <uint>(),
                                    Payload         = new BufLen(new byte[0]),
                                };

                                sh.Write(s);
                                var buf    = s.ToByteArray();
                                var zipped = LZUtils.BCGZipCompressNew(new BufLen(buf));
                                zipped.PokeFlip16(4353, 4);                // source port
                                zipped.PokeFlip16(25, 6);                  // dest port
                                zipped[9] = (byte)PayloadFormat.Streaming; // streaming

                                Logging.LogInformation($"Program {UnpublishedDestination}: Sending {zipped:20}.");

                                UnpublishedDestination.Send(ls.Destination, zipped);
                            });
                        });
                    }
                }
                catch (SocketException ex)
                {
                    Logging.Log(ex);
                }
                catch (IOException ex)
                {
                    Logging.Log(ex);
                }
                catch (Exception ex)
                {
                    Logging.Log(ex);
                }
            }
        }