private static void _setupNewSocketServer(RelayNode relayNode, string instanceName, int portNumber, bool useAsyncHandler, ConnectionWhitelist connectionWhitelist, bool whitelistOnly) 
		{
			//all public method should lock(_syncRoot) so we should be ok
			SocketServer socketServer = new SocketServer(instanceName, portNumber);

			IMessageHandler messageHandler;
			if (useAsyncHandler)
			{
				messageHandler = new SocketServerAsyncMessageHandler(relayNode, relayNode);
			}
			else
			{
				messageHandler = new SocketServerRelayMessageHandler(relayNode, relayNode);
			}

			socketServer.MessageHandler = messageHandler;
			socketServer.AcceptingConnectionsDelegate = relayNode.AcceptNewConnection;
			socketServer.WhitelistOnly = whitelistOnly;
			socketServer.Start(connectionWhitelist);

			_socketServer = socketServer;
			if (_cachedWhiteListValue != null)
			{
				_socketServer.WhitelistOnly = _cachedWhiteListValue.Value;
				_cachedWhiteListValue = null;
			}
    	}
Ejemplo n.º 2
0
 /// <summary>
 /// Binds the server to a port and starts the server to accept new connections.
 /// </summary>
 /// <param name="instanceName"></param>
 /// <param name="portNumber"></param>
 /// <param name="relayNode">The node to handle new message requests.</param>
 /// <param name="useAsyncHandler">A value indicating if out messages should be asynchronous.</param>
 /// <param name="connectionWhitelist">A delegate that tells if a given
 /// remote endpoint is allowable to connect.</param>
 /// <param name="whitelistOnly">Whether to only allow whitelisted connections.</param>
 public static void Initialize(string instanceName, int portNumber, RelayNode relayNode,
                               bool useAsyncHandler, ConnectionWhitelist connectionWhitelist,
                               bool whitelistOnly)
 {
     lock (_syncRoot)
     {
         _myRelayNode         = relayNode;
         _connectionWhitelist = connectionWhitelist;
         _setupNewSocketServer(relayNode, instanceName, portNumber,
                               useAsyncHandler, _connectionWhitelist, whitelistOnly);
     }
 }
        /// <summary>
        /// Binds the server to a port and starts the server to accept new connections.
        /// </summary>
        /// <param name="instanceName"></param>
        /// <param name="portNumber"></param>
        /// <param name="relayNode">The node to handle new message requests.</param>
		/// <param name="useAsyncHandler">A value indicating if out messages should be asynchronous.</param>
		/// <param name="connectionWhitelist">A delegate that tells if a given
		/// remote endpoint is allowable to connect.</param>
		/// <param name="whitelistOnly">Whether to only allow whitelisted connections.</param>
		public static void Initialize(string instanceName, int portNumber, RelayNode relayNode,
			bool useAsyncHandler, ConnectionWhitelist connectionWhitelist,
			bool whitelistOnly)
        {
			lock (_syncRoot)
			{
        		_myRelayNode = relayNode;
				_connectionWhitelist = connectionWhitelist;
				_setupNewSocketServer(relayNode, instanceName, portNumber,
					useAsyncHandler, _connectionWhitelist, whitelistOnly);
			}
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Closes out any connections that don't satisfy a supplied callback.
        /// </summary>
        /// <param name="connectionWhitelist"><see cref="ConnectionWhitelist"/>
        /// callback that takes the remote <see cref="IPEndPoint"/> and
        /// returns a <see cref="Boolean"/> specifying whether to retain
        /// the connection.</param>
        /// <remarks>If the callback returns <see langword="true"/> then
        /// the connection is retained; otherwise it is closed.</remarks>
        public void PurgeNotWhitelisted(ConnectionWhitelist connectionWhitelist)
        {
            var purgedStates = new List <ConnectionState>();

            connectionsLock.ReadUpgradable(delegate
            {
                var count = connections.Count;
                var keys  = new IPEndPoint[count];
                connections.Keys.CopyTo(keys, 0);
                var values = new ConnectionState[count];
                connections.Values.CopyTo(values, 0);
                for (var idx = count - 1; idx >= 0; --idx)
                {
                    var key = keys[idx];
                    if (!connectionWhitelist(key))
                    {
                        var value = values[idx];
                        connectionsLock.Write(delegate
                        {
                            connections.Remove(key);
                            DecrementCount();
                        });
                        purgedStates.Add(value);
                    }
                }
            });
            foreach (var state in purgedStates)
            {
                try
                {
                    Close(state);
                }
                catch (Exception ex)
                {
                    if (SocketServer.log.IsErrorEnabled)
                    {
                        SocketServer.log.ErrorFormat("Exception doing whitelist check of sockets for closing: {0}", ex.ToString());
                    }
                }
            }
        }
Ejemplo n.º 5
0
        private static void _setupNewSocketServer(RelayNode relayNode, string instanceName, int portNumber, bool useAsyncHandler, ConnectionWhitelist connectionWhitelist, bool whitelistOnly)
        {
            //all public method should lock(_syncRoot) so we should be ok
            SocketServer socketServer = new SocketServer(instanceName, portNumber);

            IMessageHandler messageHandler;

            if (useAsyncHandler)
            {
                messageHandler = new SocketServerAsyncMessageHandler(relayNode, relayNode);
            }
            else
            {
                messageHandler = new SocketServerRelayMessageHandler(relayNode, relayNode);
            }

            socketServer.MessageHandler = messageHandler;
            socketServer.AcceptingConnectionsDelegate = relayNode.AcceptNewRequest;
            socketServer.AcceptingRequestsDelegate    = relayNode.AcceptNewRequest;
            socketServer.WhitelistOnly = whitelistOnly;
            socketServer.Start(connectionWhitelist);

            _socketServer = socketServer;
            if (_cachedWhiteListValue != null)
            {
                _socketServer.WhitelistOnly = _cachedWhiteListValue.Value;
                _cachedWhiteListValue       = null;
            }
        }
Ejemplo n.º 6
0
		/// <summary>
		/// Closes out any connections that don't satisfy a supplied callback.
		/// </summary>
		/// <param name="connectionWhitelist"><see cref="ConnectionWhitelist"/>
		/// callback that takes the remote <see cref="IPEndPoint"/> and
		/// returns a <see cref="Boolean"/> specifying whether to retain
		/// the connection.</param>
		/// <remarks>If the callback returns <see langword="true"/> then
		/// the connection is retained; otherwise it is closed.</remarks>
		public void PurgeNotWhitelisted(ConnectionWhitelist connectionWhitelist)
		{
			var purgedStates = new List<ConnectionState>();
			connectionsLock.ReadUpgradable(delegate
         	{
				var count = connections.Count;
         		var keys = new IPEndPoint[count];
         		connections.Keys.CopyTo(keys, 0);
         		var values = new ConnectionState[count];
         		connections.Values.CopyTo(values, 0);
				for(var idx = count - 1; idx >= 0; --idx)
				{
					var key = keys[idx];
					if (!connectionWhitelist(key))
					{
						var value = values[idx];
						connectionsLock.Write(delegate
                      	{
                      		connections.Remove(key);
                      		DecrementCount();
                      	});
						purgedStates.Add(value);
					}
				}
			});
			foreach(var state in purgedStates)
			{
				try
				{
					Close(state);
				}
				catch (Exception ex)
				{
                    if (SocketServer.log.IsErrorEnabled)
                        SocketServer.log.ErrorFormat("Exception doing whitelist check of sockets for closing: {0}",ex.ToString());
				}				
			}
		}
Ejemplo n.º 7
0
		/// <summary>
		/// Stop listening for connections and dispose of resources
		/// </summary>
		public void Stop()
		{
			if (!isRunning)
			{
				return;
			}

			if (log.IsInfoEnabled)
				log.Info("Socket Server Shutting Down.");
			isRunning = false;

			if (log.IsInfoEnabled)
				log.Info("Socket Server Disconnecting Listener.");

			if (listener.Connected)
			{
				listener.Shutdown(SocketShutdown.Both);
				listener.Disconnect(false);
			}
			listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true);
			listener.Close();


			if (countersInitialized)
			{
				if (requestsQueued.RawValue > 0) //give queued requests a chance to execute
				{
					for (int waits = 0; waits < 5; waits++)
					{
						Thread.Sleep(500);
						if (requestsQueued.RawValue == 0)
							break;
					}
				}
			}

			//try to get rid of all connections

			//kill the connection watcher timer loop
			if (connectionWatcher != null)
			{
				connectionWatcher.Change(Timeout.Infinite, Timeout.Infinite);
				connectionWatcher = null;
			}
			if (log.IsInfoEnabled)
				log.Info("Socket Server Closing Down Sockets.");

			connections.Purge();

			if (log.IsInfoEnabled)
				log.Info("Shutting down dispatchers.");

			OnewayDispatcher.Dispose();
			OnewayDispatcher = null;
			SyncDispatcher.Dispose();
			SyncDispatcher = null;

			if (countersInitialized)
			{
				socketCountCounter.RawValue = 0;
				allocatedBuffers.RawValue = 0;
			}

			connectionWhitelist = null;

			if (log.IsInfoEnabled)
				log.InfoFormat("MySpace SocketTransport Server stopped on port {0}", this.portNumber);

		}
Ejemplo n.º 8
0
		/// <summary>
		/// Start listening for connections.
		/// </summary>
		/// <param name="connectionWhiteList">An optional <see cref="ConnectionWhitelist"/>
		/// used to evaluate whether incoming and existing connections are
		/// whitelisted.</param>
		public void Start(ConnectionWhitelist connectionWhiteList)
		{
			if (isRunning)
			{
				if (log.IsWarnEnabled)
					log.Warn("Attempt to start already running socket server on port " + this.portNumber);
				return;
			}

			this.connectionWhitelist = connectionWhiteList;

			InitializeCounters();

			GetConfig();

			if (log.IsInfoEnabled)
				log.InfoFormat("Using a memory stream pool with an initial size of {0} bytes, reusing buffers {1} times. Reusing connectionstates {2} times. Using {3} sync threads and {4} one way threads",
				config.InitialMessageSize, config.BufferPoolReuses, config.ConnectionStateReuses, SyncThreads, OnewayThreads);

			bufferPool = new MemoryStreamPool(config.InitialMessageSize, config.BufferPoolReuses);

			if (countersInitialized)
			{
				bufferPool.AllocatedItemsCounter = this.allocatedBuffers;
			}

			buildConnectionStateDelegate = new ResourcePool<ConnectionState>.BuildItemDelegate(BuildConnectionState);
			resetConnectionStateDelegate = new ResourcePool<ConnectionState>.ResetItemDelegate(ResetConnectionState);

			connectionStatePool = new ResourcePool<ConnectionState>(buildConnectionStateDelegate, resetConnectionStateDelegate);
			connectionStatePool.MaxItemReuses = config.ConnectionStateReuses;

			listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

			connections = new ConnectionList(socketCountCounter);
			connectionCheckInterval = config.ConnectionCheckIntervalSeconds * 1000;
			connectionWatcher = new Timer(new TimerCallback(CheckConnections), null, connectionCheckInterval, connectionCheckInterval);

			int currentWorker, currentCompletion, oldWorker, oldCompletion;
			ThreadPool.GetAvailableThreads(out currentWorker, out currentCompletion);
			oldWorker = currentWorker;
			oldCompletion= currentCompletion;
			if (config.MaximumWorkerThreads > 0) currentWorker = config.MaximumWorkerThreads;
			if (config.MaximumCompletionPortThreads > 0) currentCompletion = config.MaximumCompletionPortThreads;
			bool maxSet = ThreadPool.SetMaxThreads(currentWorker, currentCompletion);

			if (config.MaximumWorkerThreads > 0 || config.MaximumCompletionPortThreads > 0)
			{
				if (maxSet == false)
				{
					if (log.IsWarnEnabled)
					{
						log.WarnFormat("FAILED to change max ThreadPool threads from ({0}worker/{1}completion) to ({2}worker/{3}completion)", oldWorker, oldCompletion, currentWorker, currentCompletion);
					}
				}
				else
				{
					if (log.IsInfoEnabled) log.InfoFormat("Successfully changed max ThreadPool threads from ({0}worker/{1}completion) to ({2}worker/{3}completion)", oldWorker, oldCompletion, currentWorker, currentCompletion);
				}
			}

			//kick off CCR
			OnewayDispatcher = new Dispatcher(OnewayThreads, ThreadPriority.Normal, true, "Socket Server OneWay:" + portNumber.ToString());
			SyncDispatcher = new Dispatcher(SyncThreads, ThreadPriority.AboveNormal, true, "Socket Server Sync:" + portNumber.ToString());
			OnewayMessageQueue = new DispatcherQueue("Socket Server " + portNumber.ToString() + " one way", OnewayDispatcher, TaskExecutionPolicy.ConstrainQueueDepthThrottleExecution, config.OnewayQueueDepth);
			SyncMessageQueue = new DispatcherQueue("Socket Server " + portNumber.ToString() + " sync", SyncDispatcher, TaskExecutionPolicy.ConstrainQueueDepthThrottleExecution, config.SyncQueueDepth);

			Arbiter.Activate(OnewayMessageQueue,
				Arbiter.Receive<ProcessState>(true, OnewayMessagePort, delegate(ProcessState state) { ProcessCall(state); }));

			Arbiter.Activate(SyncMessageQueue,
				Arbiter.Receive<ProcessState>(true, SyncMessagePort, delegate(ProcessState state) { ProcessCall(state); }));

			listener.Bind(new IPEndPoint(IPAddress.Any, this.portNumber));

			listener.Listen(500);

			isRunning = true;

			listener.BeginAccept(acceptCallBack, listener);

			timerThread = new Thread(TimerStart);
			timerThread.IsBackground = true;
			timerThread.Start();

			if (log.IsInfoEnabled)
				log.Info("MySpace SocketTransport Server started on port " + this.portNumber);
		}