Esempio n. 1
0
        private async Task <PingReply> SendIcmpEchoRequestOverRawSocketAsync(IPAddress address, byte[] buffer, int timeout, PingOptions?options)
        {
            SocketConfig socketConfig = GetSocketConfig(address, buffer, timeout, options);

            using (Socket socket = GetRawSocket(socketConfig))
            {
                int ipHeaderLength = socketConfig.IsIpv4 ? MinIpHeaderLengthInBytes : 0;
                CancellationTokenSource timeoutTokenSource = new CancellationTokenSource(timeout);

                try
                {
                    await socket.SendToAsync(
                        new ArraySegment <byte>(socketConfig.SendBuffer),
                        SocketFlags.None, socketConfig.EndPoint,
                        timeoutTokenSource.Token)
                    .ConfigureAwait(false);

                    byte[] receiveBuffer = new byte[2 * (MaxIpHeaderLengthInBytes + IcmpHeaderLengthInBytes) + buffer.Length];

                    // Read from the socket in a loop. We may receive messages that are not echo replies, or that are not in response
                    // to the echo request we just sent. We need to filter such messages out, and continue reading until our timeout.
                    // For example, when pinging the local host, we need to filter out our own echo requests that the socket reads.
                    long startingTimestamp = Stopwatch.GetTimestamp();
                    while (!timeoutTokenSource.IsCancellationRequested)
                    {
                        SocketReceiveFromResult receiveResult = await socket.ReceiveFromAsync(
                            new ArraySegment <byte>(receiveBuffer),
                            SocketFlags.None,
                            socketConfig.EndPoint,
                            timeoutTokenSource.Token)
                                                                .ConfigureAwait(false);

                        int bytesReceived = receiveResult.ReceivedBytes;
                        if (bytesReceived - ipHeaderLength < IcmpHeaderLengthInBytes)
                        {
                            continue; // Not enough bytes to reconstruct IP header + ICMP header.
                        }

                        if (TryGetPingReply(socketConfig, receiveBuffer, bytesReceived, startingTimestamp, ref ipHeaderLength, out PingReply? reply))
                        {
                            return(reply);
                        }
                    }
                }
                catch (SocketException ex) when(ex.SocketErrorCode == SocketError.TimedOut)
                {
                }
                catch (SocketException ex) when(ex.SocketErrorCode == SocketError.MessageSize)
                {
                    return(CreatePingReply(IPStatus.PacketTooBig));
                }
                catch (OperationCanceledException)
                {
                }
                finally
                {
                    timeoutTokenSource.Dispose();
                }

                // We have exceeded our timeout duration, and no reply has been received.
                return(CreatePingReply(IPStatus.TimedOut));
            }
        }
Esempio n. 2
0
        private async Task <PingReply> SendIcmpEchoRequestOverRawSocket(IPAddress address, byte[] buffer, int timeout, PingOptions options)
        {
            EndPoint endPoint = new IPEndPoint(address, 0);

            bool         isIpv4       = address.AddressFamily == AddressFamily.InterNetwork;
            ProtocolType protocolType = isIpv4 ? ProtocolType.Icmp : ProtocolType.IcmpV6;
            // Use the current thread's ID as the identifier.
            ushort     identifier = (ushort)Environment.CurrentManagedThreadId;
            IcmpHeader header     = new IcmpHeader()
            {
                Type           = isIpv4 ? (byte)IcmpV4MessageType.EchoRequest : (byte)IcmpV6MessageType.EchoRequest,
                Code           = 0,
                HeaderChecksum = 0,
                Identifier     = identifier,
                SequenceNumber = 0,
            };

            byte[] sendBuffer = CreateSendMessageBuffer(header, buffer);

            using (Socket socket = new Socket(address.AddressFamily, SocketType.Raw, protocolType))
            {
                socket.ReceiveTimeout = timeout;
                socket.SendTimeout    = timeout;
                // Setting Socket.DontFragment and .Ttl is not supported on Unix, so ignore the PingOptions parameter.

                int ipHeaderLength = isIpv4 ? IpHeaderLengthInBytes : 0;
                await socket.SendToAsync(new ArraySegment <byte>(sendBuffer), SocketFlags.None, endPoint).ConfigureAwait(false);

                byte[] receiveBuffer = new byte[ipHeaderLength + IcmpHeaderLengthInBytes + buffer.Length];

                long      elapsed;
                Stopwatch sw = Stopwatch.StartNew();
                // Read from the socket in a loop. We may receive messages that are not echo replies, or that are not in response
                // to the echo request we just sent. We need to filter such messages out, and continue reading until our timeout.
                // For example, when pinging the local host, we need to filter out our own echo requests that the socket reads.
                while ((elapsed = sw.ElapsedMilliseconds) < timeout)
                {
                    Task <SocketReceiveFromResult> receiveTask = socket.ReceiveFromAsync(
                        new ArraySegment <byte>(receiveBuffer),
                        SocketFlags.None,
                        endPoint);
                    var  cts      = new CancellationTokenSource();
                    Task finished = await Task.WhenAny(receiveTask, Task.Delay(timeout - (int)elapsed, cts.Token)).ConfigureAwait(false);

                    cts.Cancel();
                    if (finished != receiveTask)
                    {
                        sw.Stop();
                        return(CreateTimedOutPingReply());
                    }

                    SocketReceiveFromResult receiveResult = receiveTask.GetAwaiter().GetResult();
                    int bytesReceived = receiveResult.ReceivedBytes;
                    if (bytesReceived - ipHeaderLength < IcmpHeaderLengthInBytes)
                    {
                        continue; // Not enough bytes to reconstruct IP header + ICMP header.
                    }

                    byte type, code;
                    unsafe
                    {
                        fixed(byte *bytesPtr = receiveBuffer)
                        {
                            int        icmpHeaderOffset = ipHeaderLength;
                            IcmpHeader receivedHeader   = *((IcmpHeader *)(bytesPtr + icmpHeaderOffset)); // Skip IP header.

                            type = receivedHeader.Type;
                            code = receivedHeader.Code;

                            if (identifier != receivedHeader.Identifier ||
                                type == (byte)IcmpV4MessageType.EchoRequest ||
                                type == (byte)IcmpV6MessageType.EchoRequest)    // Echo Request, ignore
                            {
                                continue;
                            }
                        }
                    }

                    sw.Stop();
                    long roundTripTime = sw.ElapsedMilliseconds;
                    int  dataOffset    = ipHeaderLength + IcmpHeaderLengthInBytes;
                    // We want to return a buffer with the actual data we sent out, not including the header data.
                    byte[] dataBuffer = new byte[bytesReceived - dataOffset];
                    Buffer.BlockCopy(receiveBuffer, dataOffset, dataBuffer, 0, dataBuffer.Length);

                    IPStatus status = isIpv4
                                        ? IcmpV4MessageConstants.MapV4TypeToIPStatus(type, code)
                                        : IcmpV6MessageConstants.MapV6TypeToIPStatus(type, code);

                    return(new PingReply(address, options, status, roundTripTime, dataBuffer));
                }

                // We have exceeded our timeout duration, and no reply has been received.
                sw.Stop();
                return(CreateTimedOutPingReply());
            }
        }
        public static async Task <int> UdpQueryAsync(this Socket socket, ArraySegment <byte> request, ArraySegment <byte> response, IPEndPoint remoteEP, int timeout = 2000, int retries = 1, bool expBackoffTimeout = false, CancellationToken cancellationToken = default)
        {
            Task <SocketReceiveFromResult> recvTask = null;
            EndPoint epAny = GetEndPointAnyFor(remoteEP.AddressFamily);

            int timeoutValue = timeout;
            int retry        = 0;

            while (retry < retries) //retry loop
            {
                if (expBackoffTimeout)
                {
                    timeoutValue = timeout * (2 ^ retry);
                }

                retry++;

                if (cancellationToken.IsCancellationRequested)
                {
                    return(await Task.FromCanceled <int>(cancellationToken)); //task cancelled
                }
                //send request
                await socket.SendToAsync(request, SocketFlags.None, remoteEP);

                while (true)
                {
                    //receive request
                    if (recvTask == null)
                    {
                        recvTask = socket.ReceiveFromAsync(response, SocketFlags.None, epAny);
                    }

                    //receive with timeout
                    using (CancellationTokenSource timeoutCancellationTokenSource = new CancellationTokenSource())
                    {
                        using (CancellationTokenRegistration ctr = cancellationToken.Register(delegate() { timeoutCancellationTokenSource.Cancel(); }))
                        {
                            if (await Task.WhenAny(recvTask, Task.Delay(timeoutValue, timeoutCancellationTokenSource.Token)) != recvTask)
                            {
                                break; //recv timed out
                            }
                        }

                        timeoutCancellationTokenSource.Cancel(); //to stop delay task
                    }

                    SocketReceiveFromResult result = await recvTask;

                    if (remoteEP.Equals(result.RemoteEndPoint))
                    {
                        //got response
                        return(result.ReceivedBytes);
                    }

                    //recv task is complete; set recvTask to null so that another task is used to read next response packet
                    recvTask = null;
                }
            }

            socket.Dispose();
            throw new SocketException((int)SocketError.TimedOut);
        }
Esempio n. 4
0
        public async Task SendToRecvFrom_Datagram_UDP(IPAddress loopbackAddress)
        {
            IPAddress leftAddress = loopbackAddress, rightAddress = loopbackAddress;

            // TODO #5185: Harden against packet loss
            const int DatagramSize    = 256;
            const int DatagramsToSend = 256;
            const int AckTimeout      = 1000;
            const int TestTimeout     = 30000;

            var left = new Socket(leftAddress.AddressFamily, SocketType.Dgram, ProtocolType.Udp);

            left.BindToAnonymousPort(leftAddress);

            var right = new Socket(rightAddress.AddressFamily, SocketType.Dgram, ProtocolType.Udp);

            right.BindToAnonymousPort(rightAddress);

            var leftEndpoint  = (IPEndPoint)left.LocalEndPoint;
            var rightEndpoint = (IPEndPoint)right.LocalEndPoint;

            var receiverAck = new SemaphoreSlim(0);
            var senderAck   = new SemaphoreSlim(0);

            var  receivedChecksums = new uint?[DatagramsToSend];
            Task leftThread        = Task.Run(async() =>
            {
                using (left)
                {
                    EndPoint remote = leftEndpoint.Create(leftEndpoint.Serialize());
                    var recvBuffer  = new byte[DatagramSize];
                    for (int i = 0; i < DatagramsToSend; i++)
                    {
                        SocketReceiveFromResult result = await ReceiveFromAsync(
                            left, new ArraySegment <byte>(recvBuffer), remote);
                        Assert.Equal(DatagramSize, result.ReceivedBytes);
                        Assert.Equal(rightEndpoint, result.RemoteEndPoint);

                        int datagramId = recvBuffer[0];
                        Assert.Null(receivedChecksums[datagramId]);
                        receivedChecksums[datagramId] = Fletcher32.Checksum(recvBuffer, 0, result.ReceivedBytes);

                        receiverAck.Release();
                        Assert.True(await senderAck.WaitAsync(TestTimeout));
                    }
                }
            });

            var sentChecksums = new uint[DatagramsToSend];

            using (right)
            {
                var random     = new Random();
                var sendBuffer = new byte[DatagramSize];
                for (int i = 0; i < DatagramsToSend; i++)
                {
                    random.NextBytes(sendBuffer);
                    sendBuffer[0] = (byte)i;

                    int sent = await SendToAsync(right, new ArraySegment <byte>(sendBuffer), leftEndpoint);

                    Assert.True(await receiverAck.WaitAsync(AckTimeout));
                    senderAck.Release();

                    Assert.Equal(DatagramSize, sent);
                    sentChecksums[i] = Fletcher32.Checksum(sendBuffer, 0, sent);
                }
            }

            await leftThread;

            for (int i = 0; i < DatagramsToSend; i++)
            {
                Assert.NotNull(receivedChecksums[i]);
                Assert.Equal(sentChecksums[i], (uint)receivedChecksums[i]);
            }
        }
Esempio n. 5
0
        public async Task SendToRecvFrom_Datagram_UDP(IPAddress loopbackAddress, bool useClone)
        {
            IPAddress leftAddress = loopbackAddress, rightAddress = loopbackAddress;

            const int DatagramSize       = 256;
            const int DatagramsToSend    = 256;
            const int ReceiverAckTimeout = 5000;
            const int SenderAckTimeout   = 10000;

            using var origLeft  = new Socket(leftAddress.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
            using var origRight = new Socket(rightAddress.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
            origLeft.BindToAnonymousPort(leftAddress);
            origRight.BindToAnonymousPort(rightAddress);

            using var left  = useClone ? new Socket(origLeft.SafeHandle) : origLeft;
            using var right = useClone ? new Socket(origRight.SafeHandle) : origRight;

            // Force non-blocking mode in ...SyncForceNonBlocking variants of the test:
            ConfigureNonBlocking(left);
            ConfigureNonBlocking(right);

            var leftEndpoint  = (IPEndPoint)left.LocalEndPoint;
            var rightEndpoint = (IPEndPoint)right.LocalEndPoint;

            var receiverAck = new SemaphoreSlim(0);
            var senderAck   = new SemaphoreSlim(0);

            _output.WriteLine($"{DateTime.Now}: Sending data from {rightEndpoint} to {leftEndpoint}");

            var  receivedChecksums = new uint?[DatagramsToSend];
            Task leftThread        = Task.Run(async() =>
            {
                EndPoint remote = leftEndpoint.Create(leftEndpoint.Serialize());
                var recvBuffer  = new byte[DatagramSize];
                for (int i = 0; i < DatagramsToSend; i++)
                {
                    SocketReceiveFromResult result = await ReceiveFromAsync(
                        left, new ArraySegment <byte>(recvBuffer), remote);
                    Assert.Equal(DatagramSize, result.ReceivedBytes);
                    Assert.Equal(rightEndpoint, result.RemoteEndPoint);

                    int datagramId = recvBuffer[0];
                    Assert.Null(receivedChecksums[datagramId]);
                    receivedChecksums[datagramId] = Fletcher32.Checksum(recvBuffer, 0, result.ReceivedBytes);

                    receiverAck.Release();
                    bool gotAck = await senderAck.WaitAsync(SenderAckTimeout);
                    Assert.True(gotAck, $"{DateTime.Now}: Timeout waiting {SenderAckTimeout} for senderAck in iteration {i}");
                }
            });

            var sentChecksums = new uint[DatagramsToSend];

            using (right)
            {
                var random     = new Random();
                var sendBuffer = new byte[DatagramSize];
                for (int i = 0; i < DatagramsToSend; i++)
                {
                    random.NextBytes(sendBuffer);
                    sendBuffer[0] = (byte)i;

                    int sent = await SendToAsync(right, new ArraySegment <byte>(sendBuffer), leftEndpoint);

                    bool gotAck = await receiverAck.WaitAsync(ReceiverAckTimeout);

                    Assert.True(gotAck, $"{DateTime.Now}: Timeout waiting {ReceiverAckTimeout} for receiverAck in iteration {i} after sending {sent}. Receiver is in {leftThread.Status}");
                    senderAck.Release();

                    Assert.Equal(DatagramSize, sent);
                    sentChecksums[i] = Fletcher32.Checksum(sendBuffer, 0, sent);
                }
            }

            await leftThread;

            for (int i = 0; i < DatagramsToSend; i++)
            {
                Assert.NotNull(receivedChecksums[i]);
                Assert.Equal(sentChecksums[i], (uint)receivedChecksums[i]);
            }
        }
        public async Task <int> UdpQueryAsync(ArraySegment <byte> request, ArraySegment <byte> response, EndPoint remoteEP, int timeout = 10000, int retries = 1, bool expBackoffTimeout = false, CancellationToken cancellationToken = default)
        {
            Task <SocketReceiveFromResult> recvTask = null;

            int timeoutValue = timeout;
            int retry        = 0;

            while (retry < retries) //retry loop
            {
                if (expBackoffTimeout)
                {
                    timeoutValue = timeout * (2 ^ retry);
                }

                retry++;

                if (cancellationToken.IsCancellationRequested)
                {
                    return(await Task.FromCanceled <int>(cancellationToken)); //task cancelled
                }
                //send request
                await SendToAsync(request, remoteEP);

                while (true)
                {
                    //receive request
                    if (recvTask == null)
                    {
                        recvTask = ReceiveFromAsync(response);
                    }

                    //receive with timeout
                    using (CancellationTokenSource timeoutCancellationTokenSource = new CancellationTokenSource())
                    {
                        using (CancellationTokenRegistration ctr = cancellationToken.Register(delegate() { timeoutCancellationTokenSource.Cancel(); }))
                        {
                            if (await Task.WhenAny(recvTask, Task.Delay(timeoutValue, timeoutCancellationTokenSource.Token)) != recvTask)
                            {
                                break; //recv timed out
                            }
                        }

                        timeoutCancellationTokenSource.Cancel(); //to stop delay task
                    }

                    SocketReceiveFromResult result = await recvTask;

                    if ((remoteEP is DomainEndPoint) || remoteEP.Equals(result.RemoteEndPoint)) //in case remoteEP is domain end point then returned response will contain the resolved IP address so cant compare it together
                    {
                        //got response
                        return(result.ReceivedBytes);
                    }

                    //recv task is complete; set recvTask to null so that another task is used to read next response packet
                    recvTask = null;
                }
            }

            _udpSocket.Dispose();
            throw new SocketException((int)SocketError.TimedOut);
        }
        public async Task <SocketReceiveFromResult> ReceiveFromAsync(ArraySegment <byte> buffer)
        {
            byte[] datagram = new byte[262 + buffer.Count];

            SocketReceiveFromResult result = await _udpSocket.ReceiveFromAsync(datagram, SocketFlags.None, SocketExtension.GetEndPointAnyFor(_udpSocket.AddressFamily));

            if (result.ReceivedBytes < 10)
            {
                throw new SocksProxyException("Incomplete SOCKS5 datagram was received.");
            }

            EndPoint remoteEP;

            switch ((SocksAddressType)datagram[3])
            {
            case SocksAddressType.IPv4Address:
            {
                byte[] address = new byte[4];
                Buffer.BlockCopy(datagram, 3 + 1, address, 0, 4);

                byte[] port = new byte[2];
                Buffer.BlockCopy(datagram, 3 + 1 + 4, port, 0, 2);
                Array.Reverse(port);

                remoteEP = new IPEndPoint(new IPAddress(address), BitConverter.ToUInt16(port, 0));
            }
            break;

            case SocksAddressType.IPv6Address:
            {
                byte[] address = new byte[16];
                Buffer.BlockCopy(datagram, 3 + 1, address, 0, 16);

                byte[] port = new byte[2];
                Buffer.BlockCopy(datagram, 3 + 1 + 16, port, 0, 2);
                Array.Reverse(port);

                remoteEP = new IPEndPoint(new IPAddress(address), BitConverter.ToUInt16(port, 0));
            }
            break;

            case SocksAddressType.DomainName:
            {
                int length = datagram[3 + 1];

                byte[] address = new byte[length];
                Buffer.BlockCopy(datagram, 3 + 1 + 1, address, 0, length);

                byte[] port = new byte[2];
                Buffer.BlockCopy(datagram, 3 + 1 + 1 + length, port, 0, 2);
                Array.Reverse(port);

                remoteEP = new DomainEndPoint(Encoding.ASCII.GetString(address), BitConverter.ToUInt16(port, 0));
            }
            break;

            default:
                throw new NotSupportedException("SocksAddressType not supported.");
            }

            int addressSize;

            switch (remoteEP.AddressFamily)
            {
            case AddressFamily.InterNetwork:
                addressSize = 4;
                break;

            case AddressFamily.InterNetworkV6:
                addressSize = 16;
                break;

            case AddressFamily.Unspecified:
                addressSize = 1 + (remoteEP as DomainEndPoint).Address.Length;
                break;

            default:
                throw new NotSupportedException("AddressFamily not supported.");
            }

            int dataOffset = 6 + addressSize;
            int dataSize   = result.ReceivedBytes - dataOffset;

            if (dataSize > buffer.Count)
            {
                dataSize = buffer.Count;
            }

            ArraySegment <byte> recvData = new ArraySegment <byte>(datagram, dataOffset, dataSize);

            recvData.CopyTo(buffer);

            if (_relayEP == null)
            {
                _relayEP = result.RemoteEndPoint; //set new relay ep
            }
            return(new SocketReceiveFromResult()
            {
                ReceivedBytes = dataSize, RemoteEndPoint = remoteEP
            });
        }
Esempio n. 8
0
        private async Task RunAcceptLoopAsync()
        {
            try
            {
                while (true)
                {
                    for (var schedulerIndex = 0; schedulerIndex < _numSchedulers; schedulerIndex++)
                    {
                        try
                        {
                            ArraySegment <byte>     buffer        = new ArraySegment <byte>(new byte[4096]);
                            IPEndPoint              sender        = new IPEndPoint(_listenSocket.AddressFamily == AddressFamily.InterNetworkV6 ? IPAddress.IPv6Any : IPAddress.Any, 0);
                            SocketReceiveFromResult receiveResult = await _listenSocket.ReceiveFromAsync(buffer, SocketFlags.None, sender);

                            if (receiveResult.ReceivedBytes > 0)
                            {
                                AbstractPacketBase packet = AbstractPacketBase.Parse(buffer.AsSpan());
                                System.Console.WriteLine($"rcv {receiveResult.RemoteEndPoint} " + packet.ToString());

                                //var response = new RegularPacket(connectionID, 2, null);
                                //await _listenSocket.SendToAsync(new ArraySegment<byte>(response.PadAndNullEncrypt()), SocketFlags.None, receiveResult.RemoteEndPoint);

                                /*
                                 * if (_connections.TryGetValue(connectionID, out QuicConnection connection))
                                 * {
                                 *  await connection.Input.WriteAsync(buffer);
                                 * }
                                 * else
                                 * {
                                 *  connection = new QuicConnection(connectionID.ToString(), _listenSocket, _memoryPool, _schedulers[schedulerIndex], _logger);
                                 *  _connections.Add(connectionID, connection);
                                 *  await connection.StartAsync(_dispatcher);
                                 * }
                                 */
                            }
                        }
                        catch (SocketException ex) when(ex.SocketErrorCode == SocketError.ConnectionReset)
                        {
                            // REVIEW: Should there be a separate log message for a connection reset this early?
                            _logger.LogDebug($"Connection Reset: connectionId: ({null})");
                        }
                        catch (SocketException ex) when(!_unbinding)
                        {
                            _logger.LogError(ex, $"Connection Error: connectionId: ({null})");
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                if (_unbinding)
                {
                    // Means we must be unbinding. Eat the exception.
                }
                else
                {
                    _logger.LogCritical(ex, $"Unexpected exeption in {nameof(QuicTransport)}.{nameof(RunAcceptLoopAsync)}.");
                    _listenException = ex;

                    // Request shutdown so we can rethrow this exception
                    // in Stop which should be observable.
                    _applicationLifetime.StopApplication();
                }
            }
        }
Esempio n. 9
0
        public void StartReceive()
        {
            _socket = CreateSocket();

            var thread = new Thread(async() =>
            {
                while (true)
                {
                    try
                    {
                        //Start receiving data
                        ArraySegment <byte> buff = new ArraySegment <byte>(new byte[2500]);
                        var end = new IPEndPoint(IPAddress.Any, 0);
                        SocketReceiveFromResult v = await _socket.ReceiveFromAsync(buff, SocketFlags.None, end);

                        // Check if we can accept it
                        if (!_accept)
                        {
                            continue;
                        }

                        AtemServerConnection conn = Connections.FindOrCreateConnection(v.RemoteEndPoint, out _);
                        if (conn == null)
                        {
                            continue;
                        }

                        byte[] buffer = buff.Array;
                        var packet    = new ReceivedPacket(buffer);

                        if (packet.CommandCode.HasFlag(ReceivedPacket.CommandCodeFlags.Handshake))
                        {
                            conn.ResetConnStatsInfo();
                            // send handshake back
                            byte[] test =
                            {
                                buffer[0], buffer[1], // flags + length
                                buffer[2], buffer[3], // session id
                                0x00, 0x00,           // acked pkt id
                                0x00, 0x00,           // retransmit request
                                buffer[8], buffer[9], // unknown2
                                0x00, 0x00,           // server pkt id
                                0x02, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00
                            };

                            var sendThread = new Thread(o =>
                            {
                                while (!conn.HasTimedOut)
                                {
                                    conn.TrySendQueued(_socket);
                                    Task.Delay(1).Wait();
                                }
                                Console.WriteLine("send finished");
                            });
                            sendThread.Name = $"To {conn.Endpoint}";
                            sendThread.Start();

                            await _socket.SendToAsync(new ArraySegment <byte>(test, 0, 20), SocketFlags.None, v.RemoteEndPoint);

                            continue;
                        }

                        if (!conn.IsOpened)
                        {
                            var recvThread = new Thread(o =>
                            {
                                while (!conn.HasTimedOut || conn.HasCommandsToProcess)
                                {
                                    List <ICommand> cmds = conn.GetNextCommands();

                                    Log.DebugFormat("Recieved {0} commands", cmds.Count);
                                    //conn.HandleInner(_state, connection, cmds);
                                }
                            });
                            recvThread.Name = $"Receive {conn.Endpoint}";
                            recvThread.Start();
                        }
                        conn.Receive(_socket, packet);

                        if (conn.ReadyForData)
                        {
                            QueueDataDumps(conn);
                        }
                    }
                    catch (SocketException)
                    {
                        // Reinit the socket as it is now unavailable
                        //_socket = CreateSocket();
                    }
                }
            });

            thread.Name = "AtemServer";
            thread.Start();
        }