Exemplo n.º 1
0
        public async Task SendingAndReceiving()
        {
            var transationId    = StunTransactionId.Generate();
            var mappedAddresses = new List <IPEndPoint>();
            var datagramBlock   = new DatagramBlock(new DatagramOptions
            {
                ListeningPoint = new IPEndPoint(IPAddress.Any, 50000)
            });
            var stunMessage = new StunBuilderStep().SetType(StunMessageType.BindingRequest)
                              .SetTransactionId(transationId)
                              .Build();
            var datagram           = new Datagram(stunMessage, new byte[] { 64, 233, 161, 127 }, 19302); //stun1.l.google.com:19302
            var stunMessageHandler = new ActionBlock <StunMessage>(response =>
            {
                if (response.Type != StunMessageType.BindingResponse || response.TransactionId != transationId)
                {
                    return;
                }

                foreach (var attribute in response.Attributes)
                {
                    if (StunMappedAddressAttribute.TryParse(attribute, out var mappedAddressAttribute))
                    {
                        mappedAddresses.Add(new IPEndPoint(new IPAddress(mappedAddressAttribute.EndPoint.Address.ToArray()), mappedAddressAttribute.EndPoint.Port));
                    }
                }
            });
            var stunMessagePipe = new StunPipeBlock();

            datagramBlock.LinkTo(stunMessagePipe, new DataflowLinkOptions {
                PropagateCompletion = true
            });
            stunMessagePipe.LinkTo(stunMessageHandler, new DataflowLinkOptions {
                PropagateCompletion = true
            });
            stunMessagePipe.LinkTo(DataflowBlock.NullTarget <Datagram>());

            using (new Timer(context => datagramBlock.Post(datagram), null, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1)))
            {
                datagramBlock.Start();
                await datagramBlock.Initialization;
                await Task.Delay(4000);

                datagramBlock.Complete();
                await Task.WhenAll(datagramBlock.Completion,
                                   stunMessagePipe.Completion,
                                   stunMessageHandler.Completion);
            }

            mappedAddresses.Should().HaveCountGreaterOrEqualTo(3);
        }
        public static bool TryParse(StunAttribute attribute, out StunMappedAddressAttribute result)
        {
            result = new StunMappedAddressAttribute();

            if (attribute.Type != StunAttributeType.MappedAddress)
            {
                return(false);
            }

            if (!StunIPEndPoint.TryParse(attribute.Content, out var stunEndPoint))
            {
                return(false);
            }

            result = new StunMappedAddressAttribute(stunEndPoint);
            return(true);
        }