Example #1
0
        private unsafe IPEndPoint Start(QuicListenerOptions options)
        {
            List <SslApplicationProtocol> applicationProtocols = options.ServerAuthenticationOptions !.ApplicationProtocols !;
            IPEndPoint listenEndPoint = options.ListenEndPoint !;

            SOCKADDR_INET address = MsQuicAddressHelpers.IPEndPointToINet(listenEndPoint);

            uint status;

            Debug.Assert(_stateHandle.IsAllocated);

            MemoryHandle[]? handles = null;
            QuicBuffer[]? buffers   = null;
            try
            {
                MsQuicAlpnHelper.Prepare(applicationProtocols, out handles, out buffers);
                status = MsQuicApi.Api.ListenerStartDelegate(_state.Handle, (QuicBuffer *)Marshal.UnsafeAddrOfPinnedArrayElement(buffers, 0), (uint)applicationProtocols.Count, ref address);
            }
            catch
            {
                _stateHandle.Free();
                throw;
            }
            finally
            {
                MsQuicAlpnHelper.Return(ref handles, ref buffers);
            }

            QuicExceptionHelpers.ThrowIfFailed(status, "ListenerStart failed.");

            SOCKADDR_INET inetAddress = MsQuicParameterHelpers.GetINetParam(MsQuicApi.Api, _state.Handle, QUIC_PARAM_LEVEL.LISTENER, (uint)QUIC_PARAM_LISTENER.LOCAL_ADDRESS);

            return(MsQuicAddressHelpers.INetToIPEndPoint(ref inetAddress));
        }
Example #2
0
        internal override unsafe void Start()
        {
            ThrowIfDisposed();

            SOCKADDR_INET address = MsQuicAddressHelpers.IPEndPointToINet(_listenEndPoint);

            uint status;

            MemoryHandle[]? handles = null;
            QuicBuffer[]? buffers   = null;
            try
            {
                MsQuicAlpnHelper.Prepare(_applicationProtocols, out handles, out buffers);
                status = MsQuicApi.Api.ListenerStartDelegate(_state.Handle, (QuicBuffer *)Marshal.UnsafeAddrOfPinnedArrayElement(buffers, 0), (uint)_applicationProtocols.Count, ref address);
            }
            finally
            {
                MsQuicAlpnHelper.Return(ref handles, ref buffers);
            }

            QuicExceptionHelpers.ThrowIfFailed(status, "ListenerStart failed.");

            SOCKADDR_INET inetAddress = MsQuicParameterHelpers.GetINetParam(MsQuicApi.Api, _state.Handle, QUIC_PARAM_LEVEL.LISTENER, (uint)QUIC_PARAM_LISTENER.LOCAL_ADDRESS);

            _listenEndPoint = MsQuicAddressHelpers.INetToIPEndPoint(ref inetAddress);
        }
Example #3
0
        internal static unsafe SOCKADDR_INET IPEndPointToINet(IPEndPoint endpoint)
        {
            SOCKADDR_INET socketAddress = default;

            if (endpoint.Address != IPAddress.Any && endpoint.Address != IPAddress.IPv6Any)
            {
                switch (endpoint.Address.AddressFamily)
                {
                case AddressFamily.InterNetwork:
                    endpoint.Address.TryWriteBytes(MemoryMarshal.CreateSpan <byte>(ref socketAddress.Ipv4.sin_addr[0], 4), out _);
                    socketAddress.Ipv4.sin_family = (ushort)QUIC_ADDRESS_FAMILY.INET;
                    break;

                case AddressFamily.InterNetworkV6:
                    endpoint.Address.TryWriteBytes(MemoryMarshal.CreateSpan <byte>(ref socketAddress.Ipv6.sin6_addr[0], 16), out _);
                    socketAddress.Ipv6.sin6_family = (ushort)QUIC_ADDRESS_FAMILY.INET6;
                    break;

                default:
                    throw new ArgumentException(SR.net_quic_addressfamily_notsupported);
                }
            }

            SetPort(endpoint.Address.AddressFamily, ref socketAddress, endpoint.Port);
            return(socketAddress);
        }
Example #4
0
        public void GetBestRoute2Test()
        {
            var addr = new SOCKADDR_INET {
                Ipv4 = new SOCKADDR_IN(new IN_ADDR(192, 168, 0, 202))
            };

            Assert.That(GetBestRoute2(IntPtr.Zero, primaryAdapter.IfIndex, IntPtr.Zero, addr, 0, out var rt, out var src), Is.Zero);
            Assert.That(rt.InterfaceIndex, Is.EqualTo(primaryAdapter.IfIndex));
            Assert.That(src.Ipv4.sin_addr, Is.EqualTo(new IN_ADDR(192, 168, 0, 203)));
        }
Example #5
0
 internal static unsafe IPEndPoint INetToIPEndPoint(SOCKADDR_INET inetAddress)
 {
     if (inetAddress.si_family == IPv4)
     {
         return(new IPEndPoint(new IPAddress(inetAddress.Ipv4.Address), (ushort)IPAddress.NetworkToHostOrder((short)inetAddress.Ipv4.sin_port)));
     }
     else
     {
         return(new IPEndPoint(new IPAddress(inetAddress.Ipv6.Address), (ushort)IPAddress.NetworkToHostOrder((short)inetAddress.Ipv6._port)));
     }
 }
Example #6
0
 internal static unsafe IPEndPoint INetToIPEndPoint(ref SOCKADDR_INET inetAddress)
 {
     if (inetAddress.si_family == (ushort)QUIC_ADDRESS_FAMILY.INET)
     {
         return(new IPEndPoint(new IPAddress(MemoryMarshal.CreateReadOnlySpan <byte>(ref inetAddress.Ipv4.sin_addr[0], 4)), (ushort)IPAddress.NetworkToHostOrder((short)inetAddress.Ipv4.sin_port)));
     }
     else
     {
         return(new IPEndPoint(new IPAddress(MemoryMarshal.CreateReadOnlySpan <byte>(ref inetAddress.Ipv6.sin6_addr[0], 16)), (ushort)IPAddress.NetworkToHostOrder((short)inetAddress.Ipv6.sin6_port)));
     }
 }
Example #7
0
        internal override void Start()
        {
            ThrowIfDisposed();

            SetCallbackHandler();

            SOCKADDR_INET address = MsQuicAddressHelpers.IPEndPointToINet(_listenEndPoint);

            MsQuicStatusException.ThrowIfFailed(MsQuicApi.Api.ListenerStartDelegate(
                                                    _ptr,
                                                    ref address));

            SetListenPort();
        }
Example #8
0
        private uint HandleEventConnected(ConnectionEvent connectionEvent)
        {
            SOCKADDR_INET inetAddress = MsQuicParameterHelpers.GetINetParam(MsQuicApi.Api, _ptr, (uint)QUIC_PARAM_LEVEL.CONNECTION, (uint)QUIC_PARAM_CONN.LOCAL_ADDRESS);

            _localEndPoint = MsQuicAddressHelpers.INetToIPEndPoint(inetAddress);

            _connected = true;
            // I don't believe we need to lock here because
            // handle event connected will not be called at the same time as
            // handle event shutdown initiated by transport
            _connectTcs.Complete(MsQuicStatusCodes.Success);

            return(MsQuicStatusCodes.Success);
        }
Example #9
0
        private static void SetPort(AddressFamily addressFamily, ref SOCKADDR_INET socketAddrInet, int originalPort)
        {
            ushort convertedPort = (ushort)IPAddress.HostToNetworkOrder((short)originalPort);

            switch (addressFamily)
            {
            case AddressFamily.InterNetwork:
                socketAddrInet.Ipv4.sin_port = convertedPort;
                break;

            case AddressFamily.InterNetworkV6:
            default:
                socketAddrInet.Ipv6._port = convertedPort;
                break;
            }
        }
Example #10
0
        private static uint HandleEventConnected(State state, ref ConnectionEvent connectionEvent)
        {
            if (state.Connected)
            {
                return(MsQuicStatusCodes.Success);
            }

            if (state.IsServer)
            {
                state.Connected = true;
                MsQuicListener.State?listenerState = state.ListenerState;
                state.ListenerState = null;

                if (listenerState != null)
                {
                    if (listenerState.PendingConnections.TryRemove(state.Handle.DangerousGetHandle(), out MsQuicConnection? connection))
                    {
                        // Move connection from pending to Accept queue and hand it out.
                        if (listenerState.AcceptConnectionQueue.Writer.TryWrite(connection))
                        {
                            return(MsQuicStatusCodes.Success);
                        }
                        // Listener is closed
                        connection.Dispose();
                    }
                }

                return(MsQuicStatusCodes.UserCanceled);
            }
            else
            {
                // Connected will already be true for connections accepted from a listener.
                Debug.Assert(!Monitor.IsEntered(state));
                SOCKADDR_INET inetAddress = MsQuicParameterHelpers.GetINetParam(MsQuicApi.Api, state.Handle, QUIC_PARAM_LEVEL.CONNECTION, (uint)QUIC_PARAM_CONN.LOCAL_ADDRESS);

                Debug.Assert(state.Connection != null);
                state.Connection._localEndPoint = MsQuicAddressHelpers.INetToIPEndPoint(ref inetAddress);
                state.Connection.SetNegotiatedAlpn(connectionEvent.Data.Connected.NegotiatedAlpn, connectionEvent.Data.Connected.NegotiatedAlpnLength);
                state.Connection = null;

                state.Connected = true;
                state.ConnectTcs !.SetResult(MsQuicStatusCodes.Success);
                state.ConnectTcs = null;
            }

            return(MsQuicStatusCodes.Success);
        }
Example #11
0
        private uint HandleEventConnected(ref ConnectionEvent connectionEvent)
        {
            if (!_connected)
            {
                // _connected will already be true for connections accepted from a listener.

                SOCKADDR_INET inetAddress = MsQuicParameterHelpers.GetINetParam(MsQuicApi.Api, _ptr, (uint)QUIC_PARAM_LEVEL.CONNECTION, (uint)QUIC_PARAM_CONN.LOCAL_ADDRESS);
                _localEndPoint = MsQuicAddressHelpers.INetToIPEndPoint(ref inetAddress);

                SetNegotiatedAlpn(connectionEvent.Data.Connected.NegotiatedAlpn, connectionEvent.Data.Connected.NegotiatedAlpnLength);

                _connected = true;
                _connectTcs.SetResult(MsQuicStatusCodes.Success);
            }

            return(MsQuicStatusCodes.Success);
        }
Example #12
0
        internal static SOCKADDR_INET IPEndPointToINet(IPEndPoint endpoint)
        {
            SOCKADDR_INET socketAddress = default;

            byte[] buffer = endpoint.Address.GetAddressBytes();
            if (endpoint.Address != IPAddress.Any && endpoint.Address != IPAddress.IPv6Any)
            {
                switch (endpoint.Address.AddressFamily)
                {
                case AddressFamily.InterNetwork:
                    socketAddress.Ipv4.sin_addr0  = buffer[0];
                    socketAddress.Ipv4.sin_addr1  = buffer[1];
                    socketAddress.Ipv4.sin_addr2  = buffer[2];
                    socketAddress.Ipv4.sin_addr3  = buffer[3];
                    socketAddress.Ipv4.sin_family = IPv4;
                    break;

                case AddressFamily.InterNetworkV6:
                    socketAddress.Ipv6._addr0  = buffer[0];
                    socketAddress.Ipv6._addr1  = buffer[1];
                    socketAddress.Ipv6._addr2  = buffer[2];
                    socketAddress.Ipv6._addr3  = buffer[3];
                    socketAddress.Ipv6._addr4  = buffer[4];
                    socketAddress.Ipv6._addr5  = buffer[5];
                    socketAddress.Ipv6._addr6  = buffer[6];
                    socketAddress.Ipv6._addr7  = buffer[7];
                    socketAddress.Ipv6._addr8  = buffer[8];
                    socketAddress.Ipv6._addr9  = buffer[9];
                    socketAddress.Ipv6._addr10 = buffer[10];
                    socketAddress.Ipv6._addr11 = buffer[11];
                    socketAddress.Ipv6._addr12 = buffer[12];
                    socketAddress.Ipv6._addr13 = buffer[13];
                    socketAddress.Ipv6._addr14 = buffer[14];
                    socketAddress.Ipv6._addr15 = buffer[15];
                    socketAddress.Ipv6._family = IPv6;
                    break;

                default:
                    throw new ArgumentException("Only IPv4 or IPv6 are supported");
                }
            }

            SetPort(endpoint.Address.AddressFamily, ref socketAddress, endpoint.Port);
            return(socketAddress);
        }
        public static SOCKADDR_INET Convert(IPEndPoint endpoint)
        {
            var socketAddress = new SOCKADDR_INET();
            var buffer        = endpoint.Address.GetAddressBytes();

            switch (endpoint.Address.AddressFamily)
            {
            case AddressFamily.InterNetwork:
                socketAddress.Ipv4.sin_addr0  = buffer[0];
                socketAddress.Ipv4.sin_addr1  = buffer[1];
                socketAddress.Ipv4.sin_addr2  = buffer[2];
                socketAddress.Ipv4.sin_addr3  = buffer[3];
                socketAddress.Ipv4.sin_family = IPv4;
                break;

            case AddressFamily.InterNetworkV6:
                socketAddress.Ipv6.sin6_addr0  = buffer[0];
                socketAddress.Ipv6.sin6_addr1  = buffer[1];
                socketAddress.Ipv6.sin6_addr2  = buffer[2];
                socketAddress.Ipv6.sin6_addr3  = buffer[3];
                socketAddress.Ipv6.sin6_addr4  = buffer[4];
                socketAddress.Ipv6.sin6_addr5  = buffer[5];
                socketAddress.Ipv6.sin6_addr6  = buffer[6];
                socketAddress.Ipv6.sin6_addr7  = buffer[7];
                socketAddress.Ipv6.sin6_addr8  = buffer[8];
                socketAddress.Ipv6.sin6_addr9  = buffer[9];
                socketAddress.Ipv6.sin6_addr10 = buffer[10];
                socketAddress.Ipv6.sin6_addr11 = buffer[11];
                socketAddress.Ipv6.sin6_addr12 = buffer[12];
                socketAddress.Ipv6.sin6_addr13 = buffer[13];
                socketAddress.Ipv6.sin6_addr14 = buffer[14];
                socketAddress.Ipv6.sin6_addr15 = buffer[15];
                socketAddress.Ipv6.sin6_family = IPv6;
                break;

            default:
                throw new ArgumentException("Only IPv4 or IPv6 are supported");
            }

            SetPort(endpoint.Address.AddressFamily, ref socketAddress, endpoint.Port);
            return(socketAddress);
        }
Example #14
0
        private static uint HandleEventConnected(State state, ref ConnectionEvent connectionEvent)
        {
            if (!state.Connected)
            {
                // Connected will already be true for connections accepted from a listener.
                Debug.Assert(!Monitor.IsEntered(state));
                SOCKADDR_INET inetAddress = MsQuicParameterHelpers.GetINetParam(MsQuicApi.Api, state.Handle, QUIC_PARAM_LEVEL.CONNECTION, (uint)QUIC_PARAM_CONN.LOCAL_ADDRESS);

                Debug.Assert(state.Connection != null);
                state.Connection._localEndPoint = MsQuicAddressHelpers.INetToIPEndPoint(ref inetAddress);
                state.Connection.SetNegotiatedAlpn(connectionEvent.Data.Connected.NegotiatedAlpn, connectionEvent.Data.Connected.NegotiatedAlpnLength);
                state.Connection = null;

                state.Connected = true;
                state.ConnectTcs !.SetResult(MsQuicStatusCodes.Success);
                state.ConnectTcs = null;
            }

            return(MsQuicStatusCodes.Success);
        }
Example #15
0
        /// <summary>
        /// Tries to resolve the hardware address for the <paramref name="remoteAddress"/>.
        /// </summary>
        /// <param name="localAddress">The address of the local endpoint to use to send the resolution request.</param>
        /// <param name="remoteAddress">The romote IP address to resolve.</param>
        /// <param name="entry">If successful, an <see cref="MIB_IPNET_ROW2"/> for the <paramref name="remoteAddress"/>.</param>
        /// <returns></returns>
        static bool TryResolveIPNetEntry(IPAddress localAddress, IPAddress remoteAddress, out MIB_IPNET_ROW2 entry)
        {
            //Set up target address
            entry = new MIB_IPNET_ROW2();
            entry.PhysicalAddress = new byte[32];
            entry.State           = NL_NEIGHBOR_STATE.NlnsReachable;

            //Either InterfaceLuid or InterfaceIndex must be filled
            entry.InterfaceIndex = (uint)GetAdapterIndex(localAddress);

            //Populate the IP address depending on whether the address is IPv4 or IPv6
            if (remoteAddress.AddressFamily == AddressFamily.InterNetwork)
            {
                entry.Address.Ipv4.sin_family = AF_INET;
                entry.Address.Ipv4.Address    = remoteAddress.GetAddressBytes();
            }
            else
            {
                entry.Address.Ipv6.sin6_family = AF_INET6;
                entry.Address.Ipv6.Address     = remoteAddress.GetAddressBytes();
            }

            //Set up the local address to use to resolve the remote address
            byte[]        localAddressBytes = localAddress.GetAddressBytes();
            SOCKADDR_INET sourceAddress     = new SOCKADDR_INET();

            if (localAddress.AddressFamily == AddressFamily.InterNetworkV6)
            {
                sourceAddress.Ipv6.Address = localAddressBytes;
            }
            else
            {
                sourceAddress.Ipv4.Address = localAddressBytes;
            }

            //Try and resolve the address
            int hr = NativeMethods.ResolveIpNetEntry2(ref entry, ref sourceAddress);

            Marshal.ThrowExceptionForHR(hr);
            return(hr == 0 && HasPhysicalAddress(entry));
        }
Example #16
0
        internal override void Start()
        {
            ThrowIfDisposed();

            // protect against double starts.
            if (_started)
            {
                throw new QuicException("Cannot start Listener multiple times");
            }

            _started = true;
            SetCallbackHandler();

            SOCKADDR_INET address = MsQuicAddressHelpers.IPEndPointToINet(_listenEndPoint);

            QuicExceptionHelpers.ThrowIfFailed(MsQuicApi.Api.ListenerStartDelegate(
                                                   _ptr,
                                                   ref address),
                                               "Failed to start listener.");

            SetListenPort();
        }
Example #17
0
        internal override ValueTask ConnectAsync(CancellationToken cancellationToken = default)
        {
            ThrowIfDisposed();

            if (_configuration is null)
            {
                throw new InvalidOperationException($"{nameof(ConnectAsync)} must not be called on a connection obtained from a listener.");
            }

            QUIC_ADDRESS_FAMILY af = _remoteEndPoint.AddressFamily switch
            {
                AddressFamily.Unspecified => QUIC_ADDRESS_FAMILY.UNSPEC,
                AddressFamily.InterNetwork => QUIC_ADDRESS_FAMILY.INET,
                AddressFamily.InterNetworkV6 => QUIC_ADDRESS_FAMILY.INET6,
                _ => throw new ArgumentException(SR.Format(SR.net_quic_unsupported_address_family, _remoteEndPoint.AddressFamily))
            };

            Debug.Assert(_state.StateGCHandle.IsAllocated);

            _state.Connection = this;
            uint   status;
            string targetHost;
            int    port;

            if (_remoteEndPoint is IPEndPoint)
            {
                SOCKADDR_INET address = MsQuicAddressHelpers.IPEndPointToINet((IPEndPoint)_remoteEndPoint);
                unsafe
                {
                    Debug.Assert(!Monitor.IsEntered(_state));
                    status = MsQuicApi.Api.SetParamDelegate(_state.Handle, QUIC_PARAM_LEVEL.CONNECTION, (uint)QUIC_PARAM_CONN.REMOTE_ADDRESS, (uint)sizeof(SOCKADDR_INET), (byte *)&address);
                    QuicExceptionHelpers.ThrowIfFailed(status, "Failed to connect to peer.");
                }

                targetHost = _state.TargetHost ?? ((IPEndPoint)_remoteEndPoint).Address.ToString();
                port       = ((IPEndPoint)_remoteEndPoint).Port;
            }
            else if (_remoteEndPoint is DnsEndPoint)
            {
                port = ((DnsEndPoint)_remoteEndPoint).Port;
                string dnsHost = ((DnsEndPoint)_remoteEndPoint).Host !;

                // We don't have way how to set separate SNI and name for connection at this moment.
                // If the name is actually IP address we can use it to make at least some cases work for people
                // who want to bypass DNS but connect to specific virtual host.
                if (!string.IsNullOrEmpty(_state.TargetHost) && !dnsHost.Equals(_state.TargetHost, StringComparison.InvariantCultureIgnoreCase) && IPAddress.TryParse(dnsHost, out IPAddress? address))
                {
                    // This is form of IPAddress and _state.TargetHost is set to different string
                    SOCKADDR_INET quicAddress = MsQuicAddressHelpers.IPEndPointToINet(new IPEndPoint(address, port));
                    unsafe
                    {
                        Debug.Assert(!Monitor.IsEntered(_state));
                        status = MsQuicApi.Api.SetParamDelegate(_state.Handle, QUIC_PARAM_LEVEL.CONNECTION, (uint)QUIC_PARAM_CONN.REMOTE_ADDRESS, (uint)sizeof(SOCKADDR_INET), (byte *)&quicAddress);
                        QuicExceptionHelpers.ThrowIfFailed(status, "Failed to connect to peer.");
                    }
                    targetHost = _state.TargetHost !;
                }
                else
                {
                    targetHost = dnsHost;
                }
            }
            else
            {
                throw new ArgumentException($"Unsupported remote endpoint type '{_remoteEndPoint.GetType()}'.");
            }

            // We store TCS to local variable to avoid NRE if callbacks finish fast and set _state.ConnectTcs to null.
            var tcs = _state.ConnectTcs = new TaskCompletionSource <uint>(TaskCreationOptions.RunContinuationsAsynchronously);

            try
            {
                Debug.Assert(!Monitor.IsEntered(_state));
                status = MsQuicApi.Api.ConnectionStartDelegate(
                    _state.Handle,
                    _configuration,
                    af,
                    targetHost,
                    (ushort)port);

                QuicExceptionHelpers.ThrowIfFailed(status, "Failed to connect to peer.");

                // this handle is ref counted by MsQuic, so safe to dispose here.
                _configuration.Dispose();
                _configuration = null;
            }
            catch
            {
                _state.StateGCHandle.Free();
                _state.Connection = null;
                throw;
            }

            return(new ValueTask(tcs.Task));
        }
Example #18
0
    public static byte[] GetMacFromIPv6Address(IPAddress ipv6Address)
    {
        if (ipv6Address.AddressFamily !=
            System.Net.Sockets.AddressFamily.InterNetworkV6)
        {
            throw new ArgumentException(
                      "The IPAddress provided was not an IPv6 address.");
        }

        //set up target address
        MIB_IPNET_ROW2 row2 = new MIB_IPNET_ROW2();

        row2.PhysicalAddress             = new byte[32];
        row2.State                       = NL_NEIGHBOR_STATE.NlnsReachable;
        row2.Address.Ipv6.sin6_addr.Byte = new byte[16];
        row2.Address.Ipv6.sin6_family    = AF_INET6;
        row2.Address.Ipv6.sin6_flowinfo  = 0;
        row2.Address.Ipv6.sin6_port      = 0;
        row2.Address.Ipv6.sin6_scope_id  = Convert.ToUInt32(ipv6Address.ScopeId);

        byte[] ipv6AddressBytes = ipv6Address.GetAddressBytes();
        System.Buffer.BlockCopy(ipv6AddressBytes, 0,
                                row2.Address.Ipv6.sin6_addr.Byte, 0, ipv6AddressBytes.Length);
        //get this machine's local IPv6 address
        SOCKADDR_INET sock = new SOCKADDR_INET();

        sock.Ipv6.sin6_family    = AF_INET6;
        sock.Ipv6.sin6_flowinfo  = 0;
        sock.Ipv6.sin6_port      = 0;
        sock.Ipv6.sin6_addr.Byte = new byte[16];
        IPAddress[] addresses = Dns.GetHostAddresses(Dns.GetHostName());
        foreach (IPAddress address in addresses)
        {
            if (address.AddressFamily ==
                System.Net.Sockets.AddressFamily.InterNetworkV6)
            {
                sock.Ipv6.sin6_addr.Byte = address.GetAddressBytes();
                break;
            }
        }
        foreach (NetworkInterface netInterface in
                 NetworkInterface.GetAllNetworkInterfaces())
        {
            if (netInterface.OperationalStatus == OperationalStatus.Up)
            {
                row2.InterfaceIndex = (uint)clsNetworkStats.GetInterfaceIndex(
                    netInterface.Description);
                break;
            }
        }
        int result = ResolveIpNetEntry2(ref row2, ref sock);

        if (result != 0)
        {
            throw new ApplicationException(
                      "The call to ResolveIpNetEntry2 failed; error number: " +
                      result.ToString());
        }
        byte[] macAddress = new byte[6];
        System.Buffer.BlockCopy(row2.PhysicalAddress, 0, macAddress, 0, 6);
        return(macAddress);
    }
Example #19
0
        private static void SetPort(AddressFamily addressFamily, ref SOCKADDR_INET socketAddrInet, int originalPort)
        {
            ushort convertedPort = (ushort)IPAddress.HostToNetworkOrder((short)originalPort);

            socketAddrInet.Ipv4.sin_port = convertedPort;
        }
Example #20
0
        internal override ValueTask ConnectAsync(CancellationToken cancellationToken = default)
        {
            ThrowIfDisposed();

            if (_configuration is null)
            {
                throw new Exception($"{nameof(ConnectAsync)} must not be called on a connection obtained from a listener.");
            }

            QUIC_ADDRESS_FAMILY af = _remoteEndPoint.AddressFamily switch
            {
                AddressFamily.Unspecified => QUIC_ADDRESS_FAMILY.UNSPEC,
                AddressFamily.InterNetwork => QUIC_ADDRESS_FAMILY.INET,
                AddressFamily.InterNetworkV6 => QUIC_ADDRESS_FAMILY.INET6,
                _ => throw new Exception(SR.Format(SR.net_quic_unsupported_address_family, _remoteEndPoint.AddressFamily))
            };

            Debug.Assert(_state.StateGCHandle.IsAllocated);

            _state.Connection = this;
            uint   status;
            string targetHost;
            int    port;

            if (_remoteEndPoint is IPEndPoint)
            {
                SOCKADDR_INET address = MsQuicAddressHelpers.IPEndPointToINet((IPEndPoint)_remoteEndPoint);
                unsafe
                {
                    Debug.Assert(!Monitor.IsEntered(_state));
                    status = MsQuicApi.Api.SetParamDelegate(_state.Handle, QUIC_PARAM_LEVEL.CONNECTION, (uint)QUIC_PARAM_CONN.REMOTE_ADDRESS, (uint)sizeof(SOCKADDR_INET), (byte *)&address);
                    QuicExceptionHelpers.ThrowIfFailed(status, "Failed to connect to peer.");
                }

                targetHost = _state.TargetHost ?? ((IPEndPoint)_remoteEndPoint).Address.ToString();
                port       = ((IPEndPoint)_remoteEndPoint).Port;
            }
            else if (_remoteEndPoint is DnsEndPoint)
            {
                // We don't have way how to set separate SNI and name for connection at this moment.
                targetHost = ((DnsEndPoint)_remoteEndPoint).Host;
                port       = ((DnsEndPoint)_remoteEndPoint).Port;
            }
            else
            {
                throw new Exception($"Unsupported remote endpoint type '{_remoteEndPoint.GetType()}'.");
            }

            // We store TCS to local variable to avoid NRE if callbacks finish fast and set _state.ConnectTcs to null.
            var tcs = _state.ConnectTcs = new TaskCompletionSource <uint>(TaskCreationOptions.RunContinuationsAsynchronously);

            try
            {
                Debug.Assert(!Monitor.IsEntered(_state));
                status = MsQuicApi.Api.ConnectionStartDelegate(
                    _state.Handle,
                    _configuration,
                    af,
                    targetHost,
                    (ushort)port);

                QuicExceptionHelpers.ThrowIfFailed(status, "Failed to connect to peer.");

                // this handle is ref counted by MsQuic, so safe to dispose here.
                _configuration.Dispose();
                _configuration = null;
            }
            catch
            {
                _state.StateGCHandle.Free();
                _state.Connection = null;
                throw;
            }

            return(new ValueTask(tcs.Task));
        }
Example #21
0
        private void SetListenPort()
        {
            SOCKADDR_INET inetAddress = MsQuicParameterHelpers.GetINetParam(MsQuicApi.Api, _ptr, (uint)QUIC_PARAM_LEVEL.LISTENER, (uint)QUIC_PARAM_LISTENER.LOCAL_ADDRESS);

            _listenEndPoint = MsQuicAddressHelpers.INetToIPEndPoint(ref inetAddress);
        }
Example #22
0
 private static extern int ResolveIpNetEntry2(ref MIB_IPNET_ROW2 Row,
                                              ref SOCKADDR_INET SourceAddress);