Exemple #1
0
 public static void Subscribe(this DataLinkCollection dlc, string channel, Action <DataLink, string, Memory <byte> > action) =>
 dlc.Subscribe(
     channel,
     (d, s, m) =>
 {
     action(d, s, m);
     return(new ValueTask <bool>(true));
 });
Exemple #2
0
 public static void Subscribe(this DataLinkCollection dlc, string channel, Func <DataLink, string, Memory <byte>, ValueTask> action) =>
 dlc.Subscribe(
     channel,
     async(d, s, m) =>
 {
     await action(d, s, m);
     return(true);
 });
Exemple #3
0
        public override async void OnHealthyChanged(DataLinkCollection sender, DataLink dataLink)
        {
            if (!dataLink.IsHealthy)
            {
                await dataLink.Disconnect();

                _ = _dlf.ConnectAsync(dataLink.RemoteName, dataLink.RemoteListenPort, sender);
            }
        }
Exemple #4
0
        public static async Task <bool> BroadcastWithAckWithTrackAsync(this DataLinkCollection dlc, string group, string content)
        {
            var length = Encoding.UTF8.GetByteCount(content);

            using (var owner = ExactSizeMemoryPool.Shared.Rent(length))
            {
                Encoding.UTF8.GetBytes(content, owner.Memory.Span);
                return(await dlc.BroadcastWithAckWithTrackAsync(group, owner.Memory));
            }
        }
Exemple #5
0
        public static async ValueTask SendTo(this DataLinkCollection dlc, string peer, string group, string content)
        {
            var length = Encoding.UTF8.GetByteCount(content);

            using (var owner = ExactSizeMemoryPool.Shared.Rent(length))
            {
                Encoding.UTF8.GetBytes(content, owner.Memory.Span);
                await dlc.SendTo(peer, group, owner.Memory);
            }
        }
Exemple #6
0
 public Program(string name, ushort port, X509Certificate2 certificate)
 {
     _dlcs = new DataLinkCollectionStore(port);
     _dlf  = new DataLinkFactory(_dlcs, this, port, certificate);
     _dlcs.Add(nameof(Program), this, name);
     _dlc = _dlcs.Get(nameof(Program));
     _dlc.Subscribe(BroadcastChannel, OnBroadcast);
     _dlc.Subscribe(P2PChannel, OnP2P);
     _dlc.Subscribe(PerfChannel, OnPerf);
     _ = StartAutoSync();
 }
Exemple #7
0
 internal DataLink(DataLinkCollection dlc, IPEndPoint remote, Stream stream, IDataLinkHandler handler, DataLinkDecoder decoder, DCConnectMessage connectMessage, ReadOnlyMemory <byte> memory)
 {
     _dlc             = dlc;
     _stream          = stream;
     _handler         = handler;
     _decoder         = decoder;
     Remote           = remote;
     RemoteName       = connectMessage.InstanceName;
     RemoteListenPort = connectMessage.Port;
     _inPipe.Writer.WriteAsync(memory);
     _inPipe.Writer.FlushAsync();
 }
Exemple #8
0
        public async Task ConnectAsync(string hostname, int port, DataLinkCollection dlc, ReadOnlyMemory <byte> args = default)
        {
            Socket socket  = null;
            bool   success = false;

            try
            {
                socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
                await socket.ConnectAsync(hostname, port);

                var stream = new SslStream(new NetworkStream(socket, true));
                await stream.AuthenticateAsClientAsync(
                    new SslClientAuthenticationOptions
                {
                    AllowRenegotiation             = true,
                    CertificateRevocationCheckMode = X509RevocationMode.NoCheck,
                    ClientCertificates             = new X509CertificateCollection {
                        _certificate
                    },
                    EnabledSslProtocols = SslProtocols.Tls12,
                    EncryptionPolicy    = EncryptionPolicy.RequireEncryption,
                    RemoteCertificateValidationCallback = (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) => certificate.Equals(_certificate),
                    TargetHost = nameof(DataLink),
                });

                if (await CreateDataLinkAsClientAsync(socket.RemoteEndPoint as IPEndPoint, stream, dlc, args) != null)
                {
                    success = true;
                }
            }
            finally
            {
                if (!success)
                {
                    socket?.Close();
                }
            }
        }
Exemple #9
0
 public override void OnReplySyncNode(DataLinkCollection sender, string host, ushort port, string name)
 {
     _ = _dlf.ConnectAsync(host, port, sender);
 }
Exemple #10
0
 public virtual void OnHealthyChanged(DataLinkCollection sender, DataLink dataLink)
 {
 }
Exemple #11
0
 public virtual void OnReplySyncNode(DataLinkCollection sender, string host, ushort port, string name)
 {
 }
Exemple #12
0
 public static void Subscribe(this DataLinkCollection dlc, string channel, Func <DataLink, string, Memory <byte>, bool> action) =>
 dlc.Subscribe(
     channel,
     (d, s, m) => new ValueTask <bool>(action(d, s, m)));
Exemple #13
0
        private async Task <DataLink> CreateDataLinkAsClientAsync(IPEndPoint remote, Stream stream, DataLinkCollection dlc, ReadOnlyMemory <byte> args)
        {
            using (var cm = DataLinkEncoder.Encode(new DCConnectMessage(dlc.ServiceName, dlc.Name, LocalPort, args)))
            {
                await stream.WriteAsync(cm.Memory);

                await stream.FlushAsync();
            }
            var decoder = new DataLinkDecoder();

            // 1024 is enough for current connect message.
            using (var owner = MemoryPool <byte> .Shared.Rent(1024))
            {
                int count = 0;
                while (true)
                {
                    count += await stream.ReadAsync(owner.Memory.Slice(count));

                    if (decoder.TryParseTransportMessage(new ReadOnlySequence <byte>(owner.Memory.Slice(0, count)), out var tm))
                    {
                        if (tm.Type != DataLinkMessageType.Connect)
                        {
                            stream.Close();
                            return(null);
                        }
                        var connect = decoder.ParseConnect(tm.Content);
                        if (connect.ServiceName != dlc.ServiceName)
                        {
                            stream.Close();
                            return(null);
                        }
                        if (connect.InstanceName == dlc.Name)
                        {
                            stream.Close();
                            return(null);
                        }
                        var moreData = owner.Memory.Slice(tm.Length, count - tm.Length);
                        return(dlc.CreateInternal(remote, stream, decoder, connect, moreData));
                    }
                }
            }
        }