public async Task <List <NATEndpoint> > LookupEndpoints(TempSessionWithSecrets userSession, string targetSession)
        {
            var natPunchthroughApi = new NATPunchthroughApi();

            natPunchthroughApi.Configuration.ApiKey["api_key"] = userSession.ApiKey;
            return(await natPunchthroughApi.EndpointsGetAsync(targetSession));
        }
        private async Task<UdpClient> PerformNATPunchthroughInternal(TempSessionWithSecrets userSession, UdpClient specificUdpClient, int timeout)
        {
            var natPunchthroughApi = new NATPunchthroughApi();
            natPunchthroughApi.Configuration.ApiKey["api_key"] = userSession.ApiKey;

            var start = DateTime.UtcNow;

            var udpClient = specificUdpClient ?? new UdpClient();

            while (true)
            {
                NATNegotation negotation;
                try
                {
                    negotation = await natPunchthroughApi.PunchthroughPutAsync(userSession.Id);
                }
                catch (HiveMP.NATPunchthrough.Client.ApiException ex)
                {
                    // There are no NAT punchthrough servers for us to use, send a UDP packet to 
                    // localhost so we get an outbound address and port.
                    var b = new byte[] { (byte)'a' };
                    await udpClient.SendAsync(
                        b,
                        1,
                        "localhost",
                        4242);
                    await Task.Delay(100);

                    return udpClient;
                }

                if (negotation.Port == null)
                {
                    throw new InvalidOperationException();
                }

                await udpClient.SendAsync(
                    negotation.Message,
                    negotation.Message.Length,
                    negotation.Host,
                    negotation.Port.Value);

                await Task.Delay(100);

                if (await natPunchthroughApi.PunchthroughGetAsync(userSession.Id) == true)
                {
                    // NAT punchthrough completed successfully.
                    return udpClient;
                }

                if (timeout > 0 && (DateTime.UtcNow - start).TotalMilliseconds > timeout)
                {
                    throw new TimeoutException("Unable to perform NAT punchthrough before the timeout occurred.");
                }

                await Task.Delay(100);
            }
        }
        private void ContinuousNATPunchthrough(BackgroundNATPunchthrough punchthrough)
        {
            var natPunchthroughApi = new NATPunchthroughApi();

            natPunchthroughApi.Configuration.ApiKey["api_key"] = punchthrough.UserSession.ApiKey;

            while (!punchthrough.ShouldStop)
            {
                var udpClient = punchthrough.UdpClient;

                while (true)
                {
                    NATNegotation negotation;
                    try
                    {
                        negotation = natPunchthroughApi.PunchthroughPut(punchthrough.UserSession.Id);
                    }
                    catch
                    {
                        continue;
                    }

                    if (negotation.Port == null)
                    {
                        throw new InvalidOperationException();
                    }

                    udpClient.Send(
                        negotation.Message,
                        negotation.Message.Length,
                        negotation.Host,
                        negotation.Port.Value);

                    Thread.Sleep(1000);

                    try
                    {
                        if (natPunchthroughApi.PunchthroughGet(punchthrough.UserSession.Id) == true)
                        {
                            // NAT punchthrough completed successfully.
                            continue;
                        }
                    }
                    catch
                    {
                        continue;
                    }

                    Thread.Sleep(1000);
                }
            }
        }
        private void ContinuousNATPunchthrough(BackgroundNATPunchthrough punchthrough)
        {
            var natPunchthroughApi = new NATPunchthroughApi();
            natPunchthroughApi.Configuration.ApiKey["api_key"] = punchthrough.UserSession.ApiKey;

            while (!punchthrough.ShouldStop)
            {
                var udpClient = punchthrough.UdpClient;

                while (true)
                {
                    NATNegotation negotation;
                    try
                    {
                        negotation = natPunchthroughApi.PunchthroughPut(punchthrough.UserSession.Id);
                    }
                    catch
                    {
                        continue;
                    }

                    if (negotation.Port == null)
                    {
                        throw new InvalidOperationException();
                    }

                    udpClient.Send(
                        negotation.Message,
                        negotation.Message.Length,
                        negotation.Host,
                        negotation.Port.Value);

                    Thread.Sleep(1000);

                    try
                    {
                        if (natPunchthroughApi.PunchthroughGet(punchthrough.UserSession.Id) == true)
                        {
                            // NAT punchthrough completed successfully.
                            continue;
                        }
                    }
                    catch
                    {
                        continue;
                    }

                    Thread.Sleep(1000);
                }
            }
        }
        private async Task <UdpClient> PerformNATPunchthroughInternal(TempSessionWithSecrets userSession, UdpClient specificUdpClient, int timeout)
        {
            var natPunchthroughApi = new NATPunchthroughApi();

            natPunchthroughApi.Configuration.ApiKey["api_key"] = userSession.ApiKey;

            var start = DateTime.UtcNow;

            var udpClient = specificUdpClient ?? new UdpClient();

            while (true)
            {
                var negotation = await natPunchthroughApi.PunchthroughPutAsync(userSession.Id);

                if (negotation.Port == null)
                {
                    throw new InvalidOperationException();
                }

                await udpClient.SendAsync(
                    negotation.Message,
                    negotation.Message.Length,
                    negotation.Host,
                    negotation.Port.Value);

                await Task.Delay(100);

                if (await natPunchthroughApi.PunchthroughGetAsync(userSession.Id) == true)
                {
                    // NAT punchthrough completed successfully.
                    return(udpClient);
                }

                if (timeout > 0 && (DateTime.UtcNow - start).TotalMilliseconds > timeout)
                {
                    throw new TimeoutException("Unable to perform NAT punchthrough before the timeout occurred.");
                }

                await Task.Delay(100);
            }
        }
 public async Task<List<NATEndpoint>> LookupEndpoints(TempSessionWithSecrets userSession, string targetSession)
 {
     var natPunchthroughApi = new NATPunchthroughApi();
     natPunchthroughApi.Configuration.ApiKey["api_key"] = userSession.ApiKey;
     return await natPunchthroughApi.EndpointsGetAsync(targetSession);
 }
        private async Task<UdpClient> PerformNATPunchthroughInternal(TempSessionWithSecrets userSession, UdpClient specificUdpClient, int timeout)
        {
            var natPunchthroughApi = new NATPunchthroughApi();
            natPunchthroughApi.Configuration.ApiKey["api_key"] = userSession.ApiKey;

            var start = DateTime.UtcNow;

            var udpClient = specificUdpClient ?? new UdpClient();

            while (true)
            {
                var negotation = await natPunchthroughApi.PunchthroughPutAsync(userSession.Id);
                if (negotation.Port == null)
                {
                    throw new InvalidOperationException();
                }

                await udpClient.SendAsync(
                    negotation.Message,
                    negotation.Message.Length,
                    negotation.Host,
                    negotation.Port.Value);

                await Task.Delay(100);

                if (await natPunchthroughApi.PunchthroughGetAsync(userSession.Id) == true)
                {
                    // NAT punchthrough completed successfully.
                    return udpClient;
                }

                if (timeout > 0 && (DateTime.UtcNow - start).TotalMilliseconds > timeout)
                {
                    throw new TimeoutException("Unable to perform NAT punchthrough before the timeout occurred.");
                }

                await Task.Delay(100);
            }
        }