Exemple #1
0
        /// <summary>
        /// Executes the command set by the program's command line arguments.
        /// </summary>
        /// <param name="options">The options that dictate the SIP command to execute.</param>
        static async Task RunCommand(Options options)
        {
            try
            {
                logger.LogDebug($"RunCommand {options.Destination}");

                (var dstEp, var dstUri) = ParseDestination(options.Destination);

                logger.LogDebug($"Destination IP end point {dstEp} and SIP URI {dstUri}");

                int  sendCount = 0;
                bool success   = true;

                do
                {
                    IPAddress  localAddress = (dstEp.Address.AddressFamily == AddressFamily.InterNetworkV6) ? IPAddress.IPv6Any : IPAddress.Any;
                    SIPChannel sipChannel   = null;

                    switch (dstEp.Protocol)
                    {
                    case SIPProtocolsEnum.tcp:
                        sipChannel = new SIPTCPChannel(new IPEndPoint(localAddress, DEFAULT_SIP_CLIENT_PORT));
                        (sipChannel as SIPTCPChannel).DisableLocalTCPSocketsCheck = true;     // Allow sends to listeners on this host.
                        break;

                    case SIPProtocolsEnum.tls:
                        var certificate = new X509Certificate2(@"localhost.pfx", "");
                        sipChannel = new SIPTLSChannel(certificate, new IPEndPoint(localAddress, DEFAULT_SIPS_CLIENT_PORT));
                        break;

                    case SIPProtocolsEnum.udp:
                        sipChannel = new SIPUDPChannel(new IPEndPoint(localAddress, DEFAULT_SIP_CLIENT_PORT));
                        break;

                    case SIPProtocolsEnum.ws:
                        sipChannel = new SIPClientWebSocketChannel();
                        break;

                    case SIPProtocolsEnum.wss:
                        sipChannel = new SIPClientWebSocketChannel();
                        break;

                    default:
                        throw new ApplicationException($"Don't know how to create SIP channel for transport {dstEp.Protocol}.");
                    }

                    SIPTransport sipTransport = new SIPTransport();
                    sipTransport.AddSIPChannel(sipChannel);

                    if (sendCount > 0 && options.Period > 0)
                    {
                        await Task.Delay(options.Period * 1000);
                    }

                    sendCount++;

                    DateTime sendTime = DateTime.Now;
                    var      sendTask = SendOptionsTaskAsync(sipTransport, dstUri);
                    var      result   = await Task.WhenAny(sendTask, Task.Delay(options.Timeout * 1000));

                    TimeSpan duration = DateTime.Now.Subtract(sendTime);

                    if (!sendTask.IsCompleted)
                    {
                        logger.LogWarning($"=> Request to {dstEp} did not get a response on send {sendCount} of {options.Count} after {duration.TotalMilliseconds.ToString("0")}ms.");
                        success = false;
                    }
                    else if (!sendTask.Result)
                    {
                        logger.LogWarning($"=> Request to {dstEp} did not get the expected response on request {sendCount} of {options.Count} after {duration.TotalMilliseconds.ToString("0")}ms.");
                        success = false;
                    }
                    else
                    {
                        logger.LogInformation($"=> Got correct response on send {sendCount} of {options.Count} in {duration.TotalMilliseconds.ToString("0")}ms.");
                    }

                    logger.LogDebug("Shutting down the SIP transport...");
                    sipTransport.Shutdown();

                    if (success == false)
                    {
                        break;
                    }
                }while (sendCount < options.Count);

                DNSManager.Stop();

                // Give the transport half a second to shutdown (puts the log messages in a better sequence).
                await Task.Delay(500);

                logger.LogInformation($"=> Command completed {((success) ? "successfully" : "with failure")}.");
            }
            catch (Exception excp)
            {
                logger.LogError($"Exception RunCommand. {excp.Message}");
            }
        }
Exemple #2
0
        /// <summary>
        /// Runs a single task as part of the overall job.
        /// </summary>
        /// <param name="options">The options that dictate the type of task to run.</param>
        /// <param name="taskNumber">The number assigned to this task.</param>
        /// <returns>A boolean indicating whether this single task succeeded or not.</returns>
        private static async Task <bool> RunTask(Options options, int taskNumber)
        {
            SIPTransport sipTransport = new SIPTransport();

            try
            {
                DateTime startTime = DateTime.Now;

                (var dstEp, var dstUri) = ParseDestination(options.Destination);

                logger.LogDebug($"Destination IP end point {dstEp} and SIP URI {dstUri}");

                IPAddress  localAddress = (dstEp.Address.AddressFamily == AddressFamily.InterNetworkV6) ? IPAddress.IPv6Any : IPAddress.Any;
                SIPChannel sipChannel   = null;

                switch (dstEp.Protocol)
                {
                case SIPProtocolsEnum.tcp:
                    sipChannel = new SIPTCPChannel(new IPEndPoint(localAddress, DEFAULT_SIP_CLIENT_PORT));
                    (sipChannel as SIPTCPChannel).DisableLocalTCPSocketsCheck = true;     // Allow sends to listeners on this host.
                    break;

                case SIPProtocolsEnum.tls:
                    var certificate = new X509Certificate2(@"localhost.pfx", "");
                    sipChannel = new SIPTLSChannel(certificate, new IPEndPoint(localAddress, DEFAULT_SIPS_CLIENT_PORT));
                    break;

                case SIPProtocolsEnum.udp:
                    sipChannel = new SIPUDPChannel(new IPEndPoint(localAddress, DEFAULT_SIP_CLIENT_PORT));
                    break;

                case SIPProtocolsEnum.ws:
                    sipChannel = new SIPClientWebSocketChannel();
                    break;

                case SIPProtocolsEnum.wss:
                    sipChannel = new SIPClientWebSocketChannel();
                    break;

                default:
                    throw new ApplicationException($"Don't know how to create SIP channel for transport {dstEp.Protocol}.");
                }

                sipTransport.AddSIPChannel(sipChannel);

                Task <bool> task = null;

                switch (options.Scenario)
                {
                case Scenarios.uac:
                    task = InitiateCallTaskAsync(sipTransport, dstUri);
                    break;

                case Scenarios.opt:
                default:
                    task = SendOptionsTaskAsync(sipTransport, dstUri);
                    break;
                }

                var result = await Task.WhenAny(task, Task.Delay(options.Timeout * 1000));

                TimeSpan duration = DateTime.Now.Subtract(startTime);
                bool     failed   = false;

                if (!task.IsCompleted)
                {
                    logger.LogWarning($"=> Request to {dstEp} did not get a response on task {taskNumber} after {duration.TotalMilliseconds.ToString("0")}ms.");
                    failed = true;
                }
                else if (!task.Result)
                {
                    logger.LogWarning($"=> Request to {dstEp} did not get the expected response on task {taskNumber} after {duration.TotalMilliseconds.ToString("0")}ms.");
                    failed = true;
                }
                else
                {
                    logger.LogInformation($"=> Got correct response on send {taskNumber} in {duration.TotalMilliseconds.ToString("0")}ms.");
                }

                return(!failed);
            }
            finally
            {
                logger.LogDebug("Shutting down the SIP transport...");
                sipTransport.Shutdown();
            }
        }
Exemple #3
0
        /// <summary>
        /// Initialises a SIP transport to act as the client in a single request/response exchange.
        /// </summary>
        /// <param name="testClientChannel">The client SIP channel to test.</param>
        /// <param name="serverUri">The URI of the server end point to test the client against.</param>
        /// <param name="tcs">The task completion source that this method will set if it receives the expected response.</param>
        /// <param name="cts">Cancellation token in case the server task intialisation fails.</param>
        /// <param name="serverReadyEvent">Event to notify when the server thread is ready for the test to commence.</param>
        private async Task RunClient(
            SIPChannel testClientChannel,
            SIPURI serverUri,
            TaskCompletionSource <bool> tcs,
            CancellationTokenSource cts,
            ManualResetEventSlim serverReadyEvent)
        {
            logger.LogDebug($"RunClient Starting client task for {testClientChannel.ListeningSIPEndPoint}.");

            var clientSIPTransport = new SIPTransport();

            try
            {
                clientSIPTransport.AddSIPChannel(testClientChannel);

                logger.LogDebug($"RunClient test channel created on {testClientChannel.ListeningSIPEndPoint}.");

                clientSIPTransport.SIPTransportResponseReceived += (SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPResponse sipResponse) =>
                {
                    logger.LogDebug($"Expected response received {localSIPEndPoint}<-{remoteEndPoint}: {sipResponse.ShortDescription}");

                    if (sipResponse.Status == SIPResponseStatusCodesEnum.Ok)
                    {
                        // Got the expected response, set the signal.
                        if (!tcs.TrySetResult(true))
                        {
                            logger.LogWarning($"RunClient on test channel {testClientChannel.ListeningSIPEndPoint} FAILED to set result on CompletionSource.");
                        }
                    }

                    return(Task.CompletedTask);
                };

                clientSIPTransport.SIPRequestOutTraceEvent += (SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) =>
                {
                    logger.LogDebug($"CLIENT REQUEST OUT {localSIPEndPoint}->{remoteEndPoint}");
                    logger.LogDebug(sipRequest.ToString());
                };

                clientSIPTransport.SIPResponseInTraceEvent += (SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPResponse sipResponse) =>
                {
                    logger.LogDebug($"CLIENT RESPONSE IN {localSIPEndPoint}<-{remoteEndPoint}");
                    logger.LogDebug(sipResponse.ToString());
                };

                var optionsRequest = SIPRequest.GetRequest(SIPMethodsEnum.OPTIONS, serverUri);

                logger.LogDebug($"RunClient waiting for server to get ready on {serverUri.CanonicalAddress}.");
                serverReadyEvent.Wait(cts.Token);

                await clientSIPTransport.SendRequestAsync(optionsRequest).ConfigureAwait(false);

                await tcs.Task.ConfigureAwait(false);
            }
            catch (Exception excp)
            {
                logger.LogError($"Exception RunClient. {excp.Message}");
            }
            finally
            {
                logger.LogDebug($"Client task completed for {testClientChannel.ListeningSIPEndPoint}.");
                clientSIPTransport.Shutdown();
                logger.LogDebug($"Client task SIP transport shutdown.");
            }
        }