void ConnectionStateHandler(NWConnectionState state, NWError error)
        {
            switch (state)
            {
            case NWConnectionState.Ready:
                connectedEvent.Set();
                break;

            case NWConnectionState.Cancelled:
                connection?.Dispose();
                connection = null;
                stack?.Dispose();
                stack = null;
                foreach (var o in options)
                {
                    o.Dispose();
                }
                break;

            case NWConnectionState.Invalid:
            case NWConnectionState.Failed:
                Assert.Inconclusive("Network connection could not be performed.");
                break;
            }
        }
Exemple #2
0
        public void Init()
        {
            TestRuntime.AssertXcodeVersion(10, 0);
            // we want to use a single connection, since it is expensive
            connectedEvent = new AutoResetEvent(false);
            host           = "www.google.com";
            using (var parameters = NWParameters.CreateTcp())
                using (var endpoint = NWEndpoint.Create(host, "80")) {
                    connection = new NWConnection(endpoint, parameters);
                    connection.SetQueue(DispatchQueue.DefaultGlobalQueue);              // important, else we will get blocked
                    connection.SetStateChangeHandler(ConnectionStateHandler);
                    connection.Start();
                    Assert.True(connectedEvent.WaitOne(20000), "Connection timed out.");
                    stack = parameters.ProtocolStack;
                    using (var ipOptions = stack.InternetProtocol) {
                        if (ipOptions != null)
                        {
#if NET
                            ipOptions.SetVersion(NWIPVersion.Version4);
#else
                            ipOptions.IPSetVersion(NWIPVersion.Version4);
#endif
                            stack.PrependApplicationProtocol(ipOptions);
                        }
                    }
                }
        }
    static NWConnection CreateOutboundConnection(string name, string port)
    {
        NWEndpoint endpoint;

        if (bonjour)
        {
            endpoint = NWEndpoint.CreateBonjourService(name, GetServiceType(), "local");
        }
        else
        {
            endpoint = NWEndpoint.Create(name, port);
        }

        Action <NWProtocolOptions> configureTls = SetupTls();
        NWParameters parameters;

        if (useUdp)
        {
            if (useTls)
            {
                parameters = NWParameters.CreateSecureUdp(configureTls: configureTls, configureUdp: null);
            }
            else
            {
                parameters = NWParameters.CreateUdp(configureUdp: null);
            }
        }
        else
        {
            if (useTls)
            {
                parameters = NWParameters.CreateSecureTcp(configureTls: configureTls, configureTcp: null);
            }
            else
            {
                parameters = NWParameters.CreateTcp(configureTcp: null);
            }
        }

        using (NWProtocolStack protocolStack = parameters.ProtocolStack){
            if (ipv4 || ipv6)
            {
                NWProtocolOptions ipOptions = protocolStack.InternetProtocol;
                ipOptions.IPSetVersion(ipv4 ? NWIPVersion.Version4 : NWIPVersion.Version6);
            }
        }

        if (localAddr != null || localPort != null)
        {
            using (NWEndpoint localEndpoint = NWEndpoint.Create(localAddr != null ? localAddr : "::", port == null ? "0" : port))
                parameters.LocalEndpoint = localEndpoint;
        }

        var connection = new NWConnection(endpoint, parameters);

        endpoint.Dispose();
        parameters.Dispose();
        return(connection);
    }
    static NWListener CreateAndStartListener(string host, string port)
    {
        Action <NWProtocolOptions> configureTls = SetupTls();
        NWParameters parameters;

        // Create the parameters, either TLS or no TLS, and with UDP or no UDP
        if (useUdp)
        {
            if (useTls)
            {
                parameters = NWParameters.CreateSecureUdp(configureTls: configureTls, configureUdp: null);
            }
            else
            {
                parameters = NWParameters.CreateUdp(configureUdp: null);
            }
        }
        else
        {
            if (useTls)
            {
                parameters = NWParameters.CreateSecureTcp(configureTls: configureTls, configureTcp: null);
            }
            else
            {
                parameters = NWParameters.CreateTcp(configureTcp: null);
            }
        }

        // If specified, set the IP version
        using (NWProtocolStack protocolStack = parameters.ProtocolStack){
            if (ipv4 || ipv6)
            {
                NWProtocolOptions ipOptions = protocolStack.InternetProtocol;
                ipOptions.IPSetVersion(ipv4 ? NWIPVersion.Version4 : NWIPVersion.Version6);
            }
        }

        // Bind to local address and port
        string address = bonjour ? null : host;

        if (address != null || port != null)
        {
            NWEndpoint localEndpoint = NWEndpoint.Create(address != null ? address : "::", port != null ? port : "0");
            Console.WriteLine("Getting {0} and {1}", address != null ? address : "::", port != null ? port : "0");
            parameters.LocalEndpoint = localEndpoint;
            Console.WriteLine("With port: " + localEndpoint.Port);
        }

        var listener = NWListener.Create(parameters);

        if (bonjour && host != null)
        {
            listener.SetAdvertiseDescriptor(NWAdvertiseDescriptor.CreateBonjourService(host, GetServiceType(), "local"));
            listener.SetAdvertisedEndpointChangedHandler((NWEndpoint advertisedEndpoint, bool added) => {
                if (verbose)
                {
                    var astr = added ? "added" : "removed";
                    warn($"Listener {astr} on {advertisedEndpoint.BonjourServiceName} on ({advertisedEndpoint.BonjourServiceName}.{GetServiceType()}.local");
                }
            });
        }

        listener.SetQueue(DispatchQueue.MainQueue);
        listener.SetStateChangedHandler((listenerState, error) => {
            var errno = (SslStatus)(error == null ? 0 : error.ErrorCode);
            switch (listenerState)
            {
            case NWListenerState.Waiting:
                if (verbose)
                {
                    warn($"Listener on port {listener.Port} udp={useUdp} waiting");
                }
                break;

            case NWListenerState.Failed:
                warn($"Listener on port {listener.Port} udp={useUdp} failed");
                break;

            case NWListenerState.Ready:
                if (verbose)
                {
                    warn($"Listener on port {listener.Port} udp={useUdp} ready");
                }
                break;

            case NWListenerState.Cancelled:
                listener = null;
                break;
            }
        });

        listener.SetNewConnectionHandler((connection) => {
            if (inboundConnection != null)
            {
                // We only support one connection at a time, so if we already
                // have one, reject the incoming connection.
                connection.Cancel();
            }
            else
            {
                if (verbose)
                {
                    warn($"New Connection on {connection.Handle} with {connection.Endpoint}");
                }
                // Accept the incoming connection and start sending  and receiving on it
                inboundConnection = connection;
                StartConnection(inboundConnection);
                StartSendReceiveLoop(inboundConnection);
            }
        });
        listener.Start();

        return(listener);
    }