public void Start()
        {
            try
            {
                logger.Debug("SIP Proxy daemon starting...");

                // Pre-flight checks.
                if (!File.Exists(m_proxyRuntimeScriptPath))
                {
                    throw new ApplicationException("The proxy cannot start without a runtime script. Path " + m_proxyRuntimeScriptPath + " could not be loaded.");
                }
                else if (m_sipProxySocketsNode == null || m_sipProxySocketsNode.ChildNodes.Count == 0)
                {
                    throw new ApplicationException("The proxy cannot start without at least one socket specified to listen on, please check config file.");
                }

                // Send events from this process to the monitoring socket.
                if (m_monitorPort != 0)
                {
                    // Events will be sent by the monitor channel to the loopback interface and this port.
                    m_monitorEventWriter = new SIPMonitorEventWriter(m_monitorPort);
                    logger.Debug(" SIP Proxy monitor sender initialised for 127.0.0.1:" + m_monitorPort + ".");
                }

                // Configure the SIP transport layer.
                m_sipTransport = new SIPTransport(SIPDNSManager.ResolveSIPService, null, false);
                SIPDNSManager.SIPMonitorLogEvent = FireSIPMonitorEvent;
                m_sipTransport.PerformanceMonitorPrefix = SIPSorceryPerformanceMonitor.PROXY_PREFIX;
                List<SIPChannel> sipChannels = SIPTransportConfig.ParseSIPChannelsNode(m_sipProxySocketsNode);
                m_sipTransport.AddSIPChannel(sipChannels);

                // Create the SIP stateless proxy core.
                m_statelessProxyCore = new SIPProxyCore(FireSIPMonitorEvent, m_sipTransport, m_proxyRuntimeScriptPath, m_appServerEndPointsPath);

                if (!m_publicIPAddressStr.IsNullOrBlank())
                {
                    PublicIPAddress = IPAddress.Parse(m_publicIPAddressStr);
                    m_statelessProxyCore.PublicIPAddress = PublicIPAddress;
                }
                else if (!m_stunServerHostname.IsNullOrBlank())
                {
                    // If a STUN server hostname has been specified start the STUN client thread.
                    ThreadPool.QueueUserWorkItem(delegate { StartSTUNClient(); });
                }

                // Logging.
                m_sipTransport.SIPRequestInTraceEvent += LogSIPRequestIn;
                m_sipTransport.SIPRequestOutTraceEvent += LogSIPRequestOut;
                m_sipTransport.SIPResponseInTraceEvent += LogSIPResponseIn;
                m_sipTransport.SIPResponseOutTraceEvent += LogSIPResponseOut;
                m_sipTransport.SIPBadRequestInTraceEvent += LogSIPBadRequestIn;
                m_sipTransport.SIPBadResponseInTraceEvent += LogSIPBadResponseIn;

                if (m_natKeepAliveSocket != null)
                {
                    m_natKeepAliveRelay = new NATKeepAliveRelay(m_sipTransport, m_natKeepAliveSocket, FireSIPMonitorEvent);
                }

                // Allow silverlight clients to connect to the proxy server's SIP sockets.
                m_silverlightPolicyServer = new SilverlightPolicyServer();

                logger.Debug("SIP Proxy daemon successfully started.");
            }
            catch (Exception excp)
            {
                logger.Error("Exception SIPProxyDaemon Start. " + excp.Message);
            }
        }
 private void StartNATKeepAliveRelay(SIPTransport sipTransport, IPEndPoint natKeepAliveSocket, SIPMonitorLogDelegate logDelegate)
 {
     if (natKeepAliveSocket != null)
     {
         m_natKeepAliveRelay = new NATKeepAliveRelay(sipTransport, natKeepAliveSocket, logDelegate);
         logger.Debug("NAT keep-alive relay created on " + natKeepAliveSocket + ".");
     }
     else
     {
         logger.Warn("The NATKeepAliveRelay cannot be started with an empty socket.");
     }
 }