예제 #1
0
파일: Service.cs 프로젝트: vokac/F2B
        private void RegistrationThread()
        {
            Log.Info("RegistrationThread starting");

            int retryInterval = 250;
            LimitedLog ll = new LimitedLog(5, 1000);
            MessageQueue msmq = null;
            string queueName = computerName + "\\private$\\" + registrationQueue;

            while (!shutdown)
            {
                if (msmq == null)
                {
                    msmq = new MessageQueue(queueName);
                    //msmq.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });
                }

                try
                {
                    // NOTE: we process only first F2B record from received message
                    // and ignore the rest (including F2B_EOF)
                    Message msg = msmq.Receive(receiveTimeout);
                    BinaryReader stream = new BinaryReader(msg.BodyStream);

                    byte[] header = stream.ReadBytes(4);
                    if (header[0] != 'F' || header[1] != '2' || header[2] != 'B')
                    {
                        Log.Info("RegistrationThread: Invalid message header");
                        continue;
                    }

                    if (header[3] != (byte) F2B_DATA_TYPE_ENUM.F2B_FWQUEUE_SUBSCRIBE0 && header[3] != (byte)F2B_DATA_TYPE_ENUM.F2B_FWQUEUE_UNSUBSCRIBE0)
                    {
                        Log.Info("RegistrationThread: Invalid message type");
                        continue;
                    }

                    bool reg = header[3] == (byte)F2B_DATA_TYPE_ENUM.F2B_FWQUEUE_SUBSCRIBE0;
                    int size = IPAddress.NetworkToHostOrder(stream.ReadInt32()); // message size
                    BinaryReader data = new BinaryReader(new MemoryStream(stream.ReadBytes(size)));

                    int dnsSize = IPAddress.NetworkToHostOrder(data.ReadInt32());
                    string dns = Encoding.Default.GetString(data.ReadBytes(dnsSize));
                    int uuidSize = IPAddress.NetworkToHostOrder(data.ReadInt32());
                    Guid guid = new Guid(data.ReadBytes(uuidSize));

                    string subscriberQueueName = ".\\Private$\\F2BFW_Subscriber_" + dns + "_" + guid.ToString();

                    Log.Info("RegistrationThread: " + (reg ? "Register" : "Unregister")
                        + " client " + subscriberQueueName + " (" + msg.Label + ")");

                    bool sendAllData = false;
                    MessageQueue subscriber = null;
                    lock (thisSubscribersLock)
                    {
                        // check if we already registered queue with given name
                        foreach (var item in subscribers)
                        {
                            if (item.Key.Path == subscriberQueueName)
                            {
                                subscriber = item.Key;
                                break;
                            }
                        }

                        if (reg) // subscription request / refresh
                        {
                            // create new message queue for subscriber if it doesn't exists
                            if (!MessageQueue.Exists(subscriberQueueName))
                            {
                                MessageQueue newMsMq = MessageQueue.Create(subscriberQueueName);
                                // set the label name and close the message queue
                                newMsMq.Label = msg.Label;
                                //newMsMq.AccessMode = QueueAccessMode.SendAndReceive;
                                //newMsMq.Authenticate = true;
                                //newMsMq.EncryptionRequired = EncryptionRequired.Body;
                                //newMsMq.MaximumJournalSize = 10 * 1024;
                                //newMsMq.MaximumQueueSize = ???;
                                // TODO: privileges
                                newMsMq.Close();
                            }

                            if (subscriber == null)
                            {
                                subscriber = new MessageQueue(subscriberQueueName);
                                subscribers.Add(subscriber, DateTime.UtcNow.Ticks);
                                sendAllData = true;
                            }
                            else
                            {
                                subscribers[subscriber] = DateTime.UtcNow.Ticks;
                            }

                        }
                        else // unsubscribe request
                        {
                            if (subscriber != null)
                            {
                                subscriber.Close();
                                subscribers.Remove(subscriber);
                            }

                            if (MessageQueue.Exists(subscriberQueueName))
                            {
                                MessageQueue.Delete(subscriberQueueName);
                            }
                        }
                    }

                    if (sendAllData)
                    {
                        SendAllData(subscriber);
                    }

                    ll.Reset();
                }
                catch (MessageQueueException ex)
                {
                    // Handle no message arriving in the queue.
                    if (ex.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout)
                    {
                        //ll.Msg("RegistrationThread: No message arrived in queue.");
                    }
                    else if (ex.MessageQueueErrorCode == MessageQueueErrorCode.QueueDeleted)
                    {
                        Log.Info("RegistrationThread: Message queue was deleted ... recreate");
                        msmq.Close();
                        msmq = null;
                    }
                    else if (ex.MessageQueueErrorCode == MessageQueueErrorCode.QueueNotFound)
                    {
                        try
                        {
                            if (!MessageQueue.Exists(queueName))
                            {
                                MessageQueue msmqNew = MessageQueue.Create(queueName);
                                msmqNew.Label = "Fail2ban F2BQueue registration message queue";
                                msmqNew.Close();
                                Log.Info("RegistrationThread: Registration queue " + queueName + " created");
                            }
                            else
                            {
                                ll.Msg("RegistrationThread: Registration queue "
                                            + queueName + " inacceslible: " + ex.Message);
                                // Let's way a bit...
                                ewh.WaitOne(retryInterval * (ll.Last < 10 ? ll.Last : 10));
                                ewh.Reset();
                            }
                        }
                        catch (MessageQueueException ex1)
                        {
                            ll.Msg("RegistrationThread: Unable to create registration queue "
                                        + queueName + ": " + ex1.Message);
                            // Let's way a bit...
                            ewh.WaitOne(retryInterval * (ll.Last < 10 ? ll.Last : 10));
                            ewh.Reset();
                        }
                    }
                    else
                    {
                        ll.Msg("RegistrationThread: Unexpected MSMQ exception (code "
                            + ex.MessageQueueErrorCode + "): " + ex.Message);
                        // Let's way a bit...
                        ewh.WaitOne(retryInterval * (ll.Last < 10 ? ll.Last : 10));
                        ewh.Reset();
                    }
                }
                catch (EndOfStreamException)
                {
                    Log.Info("RegistrationThread: Input data truncated");
                }

                Log.Info("RegistrationThread loop cont(" + !shutdown + ")");
            }

            Log.Info("RegistrationThread finished");
        }
예제 #2
0
파일: Service.cs 프로젝트: vokac/F2B
        private void ProductionThread()
        {
            Log.Info("ProductionThread starting");

            int retryInterval = 250;
            LimitedLog ll = new LimitedLog(5, 1000);
            MessageQueue msmq = null;
            string queueName = computerName + "\\Private$\\" + producerQueue;

            while (!shutdown)
            {
                if (msmq == null)
                {
                    msmq = new MessageQueue(queueName);
                    //msmq.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });
                }

                try
                {
                    Message msg = msmq.Receive(receiveTimeout);
                    BinaryReader istream = new BinaryReader(msg.BodyStream);

                    byte[] header = istream.ReadBytes(4);
                    if (header[0] != 'F' || header[1] != '2' || header[2] != 'B')
                    {
                        Log.Info("ProductionThread: Invalid message header");
                        continue;
                    }

                    int recordSize = IPAddress.NetworkToHostOrder(istream.ReadInt32());

                    if (header[3] == (byte) F2B_DATA_TYPE_ENUM.F2B_FWDATA_TYPE0)
                    {
                        // put message in all subscriber queues
                        byte[] data = istream.ReadBytes(recordSize);
                        long expiration = FwData.Expiration(data);
                        byte[] hash = FwData.GetHash(data);

                        if (expiration < DateTime.UtcNow.Ticks)
                        {
                            Log.Info("ProductionThread: Invalid message expiration (expired)");
                            continue;
                        }

                        lock (thisQDataLock)
                        {
                            // we need unique expiration time to keep all required
                            // data in simple key/value hashmap structure (and we
                            // really don't care about different expiration time in ns)
                            while (qdata.ContainsKey(expiration))
                            {
                                expiration++;
                            }

                            long expirationOld = 0;
                            if (qhash.TryGetValue(hash, out expirationOld))
                            {
                                if (expirationOld > expiration)
                                {
                                    // same data with longer expiration time already exists
                                    continue;
                                }
                            }

                            if (expirationOld != 0 || maxQueueSize == 0 || maxQueueSize > qdata.Count)
                            {
                                qdata[expiration] = new Tuple<byte[], byte[]>(data, hash);
                                qhash[hash] = expiration;

                                if (expirationOld != 0)
                                {
                                    // remove data with older expiration time
                                    qdata.Remove(expirationOld);
                                }
                            }
                            else
                            {
                                Log.Warn("Reached maximum number of F2B filter rules, skiping filter addition");
                            }
                        }

                        Log.Info("ProductionThread: Resubmit received message to " + subscribers.Count + " subscribers (expiration=" + expiration + ")");

                        foreach (MessageQueue subscriber in subscribers.Keys)
                        {
                            // create the message and set the base properties
                            Message msgs = new Message();
                            msgs.Priority = MessagePriority.Normal;
                            msgs.UseJournalQueue = true;
                            msgs.Label = msg.Label;
                            msgs.TimeToBeReceived = timeToBeReceived;

                            BinaryWriter ostream = new BinaryWriter(msgs.BodyStream);
                            ostream.Write(header);
                            ostream.Write(IPAddress.HostToNetworkOrder(data.Length));
                            ostream.Write(data);

                            subscriber.Send(msgs);
                        }
                    }
                    else
                    {
                        Log.Error("ProductionThread: Unknown message type " + header[3]);
                    }

                    ll.Reset();
                }
                catch (MessageQueueException ex)
                {
                    // Handle no message arriving in the queue.
                    if (ex.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout)
                    {
                        //ll.Msg("ProductionThread: No message arrived in queue.");
                    }
                    else if (ex.MessageQueueErrorCode == MessageQueueErrorCode.QueueDeleted)
                    {
                        Log.Info("ProductionThread: Message queue was deleted ... recreate");
                        msmq.Close();
                        msmq = null;
                    }
                    else if (ex.MessageQueueErrorCode == MessageQueueErrorCode.QueueNotFound)
                    {
                        try
                        {
                            if (!MessageQueue.Exists(queueName))
                            {
                                MessageQueue msmqNew = MessageQueue.Create(queueName);
                                msmqNew.Label = "Fail2ban F2BQueue FWDATA production message queue";
                                msmqNew.Close();
                                Log.Info("ProductionThread: Production queue " + queueName + " created");
                            }
                            else
                            {
                                ll.Msg("ProductionThread: Production queue "
                                            + queueName + " inacceslible: " + ex.Message);
                                // Let's way a bit...
                                ewh.WaitOne(retryInterval * (ll.Last < 10 ? ll.Last : 10));
                                ewh.Reset();
                            }
                        }
                        catch (MessageQueueException ex1)
                        {
                            ll.Msg("ProductionThread: Unable to create production queue "
                                        + queueName + ": " + ex1.Message);
                            // Let's way a bit...
                            ewh.WaitOne(retryInterval * (ll.Last < 10 ? ll.Last : 10));
                            ewh.Reset();
                        }
                    }
                    else
                    {
                        ll.Msg("ProductionThread: Unexpected MSMQ exception (code "
                            + ex.MessageQueueErrorCode + "): " + ex.Message);
                        // Let's way a bit...
                        ewh.WaitOne(retryInterval * (ll.Last < 10 ? ll.Last : 10));
                        ewh.Reset();
                    }
                }
                catch (EndOfStreamException)
                {
                    Log.Info("ProductionThread: Input data truncated");
                }

                Log.Info("ProductionThread loop cont(" + !shutdown + ")");
            }

            Log.Info("ProductionThread finished");
        }
예제 #3
0
파일: Service.cs 프로젝트: phoenixyj/F2B
        private void ConsumptionThread()
        {
            Log.Info("ConsumptionThread starting");

            int          retryInterval = 250;
            LimitedLog   ll            = new LimitedLog(5, 1000);
            MessageQueue msmq          = null;
            string       queueName     = computerName + "\\private$\\" + producerQueue;

            while (!shutdown)
            {
                if (msmq == null)
                {
                    msmq = new MessageQueue(queueName);
                    //msmq.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });
                }

                try
                {
                    Message msg = msmq.Receive(receiveTimeout);

                    processFwStream(msg.BodyStream);

                    ll.Reset();
                }
                catch (MessageQueueException ex)
                {
                    // Handle no message arriving in the queue.
                    if (ex.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout)
                    {
                        ll.Msg("ConsumptionThread: No message arrived in queue.");
                    }
                    else if (ex.MessageQueueErrorCode == MessageQueueErrorCode.QueueDeleted)
                    {
                        Log.Info("ConsumptionThread: Message queue was deleted ... recreate");
                        msmq.Close();
                        msmq = null;
                    }
                    else if (ex.MessageQueueErrorCode == MessageQueueErrorCode.QueueNotFound)
                    {
                        ll.Msg("ConsumptionThread: Producer queue " + queueName + " not found: " + ex.Message);
                        // Let's way a bit...
                        ewh.WaitOne(retryInterval * (ll.Last < 10 ? ll.Last : 10));
                        ewh.Reset();
                    }
                    else
                    {
                        ll.Msg("ConsumptionThread: Unexpected MSMQ exception (code "
                               + ex.MessageQueueErrorCode + "): " + ex.Message);
                        // Let's way a bit...
                        ewh.WaitOne(retryInterval * (ll.Last < 10 ? ll.Last : 10));
                        ewh.Reset();
                    }
                }
                catch (EndOfStreamException)
                {
                    Log.Info("ConsumptionThread: Input data truncated");
                }
                catch (Exception ex)
                {
                    Log.Warn("ConsumptionThread: Unexpected exception: " + ex.Message);
                }

                //Log.Info("ConsumptionThread: loop cont(" + !shutdown + ")");
            }

            Log.Info("ConsumptionThread finished");
        }
예제 #4
0
파일: Service.cs 프로젝트: vokac/F2B
        private void ConsumptionThread()
        {
            Log.Info("ConsumptionThread starting");

            int retryInterval = 250;
            LimitedLog ll = new LimitedLog(5, 1000);
            MessageQueue msmq = null;
            string queueName = computerName + "\\private$\\" + producerQueue;

            while (!shutdown)
            {
                if (msmq == null)
                {
                    msmq = new MessageQueue(queueName);
                    //msmq.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });
                }

                try
                {
                    Message msg = msmq.Receive(receiveTimeout);

                    processFwStream(msg.BodyStream);

                    ll.Reset();
                }
                catch (MessageQueueException ex)
                {
                    // Handle no message arriving in the queue.
                    if (ex.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout)
                    {
                        ll.Msg("ConsumptionThread: No message arrived in queue.");
                    }
                    else if (ex.MessageQueueErrorCode == MessageQueueErrorCode.QueueDeleted)
                    {
                        Log.Info("ConsumptionThread: Message queue was deleted ... recreate");
                        msmq.Close();
                        msmq = null;
                    }
                    else if (ex.MessageQueueErrorCode == MessageQueueErrorCode.QueueNotFound)
                    {
                        ll.Msg("ConsumptionThread: Producer queue " + queueName + " not found: " + ex.Message);
                        // Let's way a bit...
                        ewh.WaitOne(retryInterval * (ll.Last < 10 ? ll.Last : 10));
                        ewh.Reset();
                    }
                    else
                    {
                        ll.Msg("ConsumptionThread: Unexpected MSMQ exception (code "
                            + ex.MessageQueueErrorCode + "): " + ex.Message);
                        // Let's way a bit...
                        ewh.WaitOne(retryInterval * (ll.Last < 10 ? ll.Last : 10));
                        ewh.Reset();
                    }
                }
                catch (EndOfStreamException)
                {
                    Log.Info("ConsumptionThread: Input data truncated");
                }
                catch (Exception ex)
                {
                    Log.Warn("ConsumptionThread: Unexpected exception: " + ex.Message);
                }

                //Log.Info("ConsumptionThread: loop cont(" + !shutdown + ")");
            }

            Log.Info("ConsumptionThread finished");
        }
예제 #5
0
파일: Service.cs 프로젝트: phoenixyj/F2B
        private void ProductionThread()
        {
            Log.Info("ProductionThread starting");

            int          retryInterval = 250;
            LimitedLog   ll            = new LimitedLog(5, 1000);
            MessageQueue msmq          = null;
            string       queueName     = computerName + "\\Private$\\" + producerQueue;

            while (!shutdown)
            {
                if (msmq == null)
                {
                    msmq = new MessageQueue(queueName);
                    //msmq.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });
                }

                try
                {
                    Message      msg     = msmq.Receive(receiveTimeout);
                    BinaryReader istream = new BinaryReader(msg.BodyStream);

                    byte[] header = istream.ReadBytes(4);
                    if (header[0] != 'F' || header[1] != '2' || header[2] != 'B')
                    {
                        Log.Info("ProductionThread: Invalid message header");
                        continue;
                    }

                    int recordSize = IPAddress.NetworkToHostOrder(istream.ReadInt32());

                    if (header[3] == (byte)F2B_DATA_TYPE_ENUM.F2B_FWDATA_TYPE0)
                    {
                        // put message in all subscriber queues
                        byte[] data       = istream.ReadBytes(recordSize);
                        long   expiration = FwData.Expiration(data);
                        byte[] hash       = FwData.GetHash(data);

                        if (expiration < DateTime.UtcNow.Ticks)
                        {
                            Log.Info("ProductionThread: Invalid message expiration (expired)");
                            continue;
                        }

                        lock (thisQDataLock)
                        {
                            // we need unique expiration time to keep all required
                            // data in simple key/value hashmap structure (and we
                            // really don't care about different expiration time in ns)
                            while (qdata.ContainsKey(expiration))
                            {
                                expiration++;
                            }

                            long expirationOld = 0;
                            if (qhash.TryGetValue(hash, out expirationOld))
                            {
                                if (expirationOld > expiration)
                                {
                                    // same data with longer expiration time already exists
                                    continue;
                                }
                            }

                            if (expirationOld != 0 || maxQueueSize == 0 || maxQueueSize > qdata.Count)
                            {
                                qdata[expiration] = new Tuple <byte[], byte[]>(data, hash);
                                qhash[hash]       = expiration;

                                if (expirationOld != 0)
                                {
                                    // remove data with older expiration time
                                    qdata.Remove(expirationOld);
                                }
                            }
                            else
                            {
                                Log.Warn("Reached maximum number of F2B filter rules, skiping filter addition");
                            }
                        }

                        Log.Info("ProductionThread: Resubmit received message to " + subscribers.Count + " subscribers (expiration=" + expiration + ")");

                        foreach (MessageQueue subscriber in subscribers.Keys)
                        {
                            // create the message and set the base properties
                            Message msgs = new Message();
                            msgs.Priority         = MessagePriority.Normal;
                            msgs.UseJournalQueue  = true;
                            msgs.Label            = msg.Label;
                            msgs.TimeToBeReceived = timeToBeReceived;

                            BinaryWriter ostream = new BinaryWriter(msgs.BodyStream);
                            ostream.Write(header);
                            ostream.Write(IPAddress.HostToNetworkOrder(data.Length));
                            ostream.Write(data);

                            subscriber.Send(msgs);
                        }
                    }
                    else
                    {
                        Log.Error("ProductionThread: Unknown message type " + header[3]);
                    }

                    ll.Reset();
                }
                catch (MessageQueueException ex)
                {
                    // Handle no message arriving in the queue.
                    if (ex.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout)
                    {
                        //ll.Msg("ProductionThread: No message arrived in queue.");
                    }
                    else if (ex.MessageQueueErrorCode == MessageQueueErrorCode.QueueDeleted)
                    {
                        Log.Info("ProductionThread: Message queue was deleted ... recreate");
                        msmq.Close();
                        msmq = null;
                    }
                    else if (ex.MessageQueueErrorCode == MessageQueueErrorCode.QueueNotFound)
                    {
                        try
                        {
                            if (!MessageQueue.Exists(queueName))
                            {
                                MessageQueue msmqNew = MessageQueue.Create(queueName);
                                msmqNew.Label = "Fail2ban F2BQueue FWDATA production message queue";
                                msmqNew.Close();
                                Log.Info("ProductionThread: Production queue " + queueName + " created");
                            }
                            else
                            {
                                ll.Msg("ProductionThread: Production queue "
                                       + queueName + " inacceslible: " + ex.Message);
                                // Let's way a bit...
                                ewh.WaitOne(retryInterval * (ll.Last < 10 ? ll.Last : 10));
                                ewh.Reset();
                            }
                        }
                        catch (MessageQueueException ex1)
                        {
                            ll.Msg("ProductionThread: Unable to create production queue "
                                   + queueName + ": " + ex1.Message);
                            // Let's way a bit...
                            ewh.WaitOne(retryInterval * (ll.Last < 10 ? ll.Last : 10));
                            ewh.Reset();
                        }
                    }
                    else
                    {
                        ll.Msg("ProductionThread: Unexpected MSMQ exception (code "
                               + ex.MessageQueueErrorCode + "): " + ex.Message);
                        // Let's way a bit...
                        ewh.WaitOne(retryInterval * (ll.Last < 10 ? ll.Last : 10));
                        ewh.Reset();
                    }
                }
                catch (EndOfStreamException)
                {
                    Log.Info("ProductionThread: Input data truncated");
                }

                Log.Info("ProductionThread loop cont(" + !shutdown + ")");
            }

            Log.Info("ProductionThread finished");
        }
예제 #6
0
파일: Service.cs 프로젝트: phoenixyj/F2B
        private void RegistrationThread()
        {
            Log.Info("RegistrationThread starting");

            int          retryInterval = 250;
            LimitedLog   ll            = new LimitedLog(5, 1000);
            MessageQueue msmq          = null;
            string       queueName     = computerName + "\\private$\\" + registrationQueue;

            while (!shutdown)
            {
                if (msmq == null)
                {
                    msmq = new MessageQueue(queueName);
                    //msmq.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });
                }

                try
                {
                    // NOTE: we process only first F2B record from received message
                    // and ignore the rest (including F2B_EOF)
                    Message      msg    = msmq.Receive(receiveTimeout);
                    BinaryReader stream = new BinaryReader(msg.BodyStream);

                    byte[] header = stream.ReadBytes(4);
                    if (header[0] != 'F' || header[1] != '2' || header[2] != 'B')
                    {
                        Log.Info("RegistrationThread: Invalid message header");
                        continue;
                    }

                    if (header[3] != (byte)F2B_DATA_TYPE_ENUM.F2B_FWQUEUE_SUBSCRIBE0 && header[3] != (byte)F2B_DATA_TYPE_ENUM.F2B_FWQUEUE_UNSUBSCRIBE0)
                    {
                        Log.Info("RegistrationThread: Invalid message type");
                        continue;
                    }

                    bool         reg  = header[3] == (byte)F2B_DATA_TYPE_ENUM.F2B_FWQUEUE_SUBSCRIBE0;
                    int          size = IPAddress.NetworkToHostOrder(stream.ReadInt32()); // message size
                    BinaryReader data = new BinaryReader(new MemoryStream(stream.ReadBytes(size)));

                    int    dnsSize  = IPAddress.NetworkToHostOrder(data.ReadInt32());
                    string dns      = Encoding.Default.GetString(data.ReadBytes(dnsSize));
                    int    uuidSize = IPAddress.NetworkToHostOrder(data.ReadInt32());
                    Guid   guid     = new Guid(data.ReadBytes(uuidSize));

                    string subscriberQueueName = ".\\Private$\\F2BFW_Subscriber_" + dns + "_" + guid.ToString();

                    Log.Info("RegistrationThread: " + (reg ? "Register" : "Unregister")
                             + " client " + subscriberQueueName + " (" + msg.Label + ")");

                    bool         sendAllData = false;
                    MessageQueue subscriber  = null;
                    lock (thisSubscribersLock)
                    {
                        // check if we already registered queue with given name
                        foreach (var item in subscribers)
                        {
                            if (item.Key.Path == subscriberQueueName)
                            {
                                subscriber = item.Key;
                                break;
                            }
                        }

                        if (reg) // subscription request / refresh
                        {
                            // create new message queue for subscriber if it doesn't exists
                            if (!MessageQueue.Exists(subscriberQueueName))
                            {
                                MessageQueue newMsMq = MessageQueue.Create(subscriberQueueName);
                                // set the label name and close the message queue
                                newMsMq.Label = msg.Label;
                                //newMsMq.AccessMode = QueueAccessMode.SendAndReceive;
                                //newMsMq.Authenticate = true;
                                //newMsMq.EncryptionRequired = EncryptionRequired.Body;
                                //newMsMq.MaximumJournalSize = 10 * 1024;
                                //newMsMq.MaximumQueueSize = ???;
                                // TODO: privileges
                                newMsMq.Close();
                            }

                            if (subscriber == null)
                            {
                                subscriber = new MessageQueue(subscriberQueueName);
                                subscribers.Add(subscriber, DateTime.UtcNow.Ticks);
                                sendAllData = true;
                            }
                            else
                            {
                                subscribers[subscriber] = DateTime.UtcNow.Ticks;
                            }
                        }
                        else // unsubscribe request
                        {
                            if (subscriber != null)
                            {
                                subscriber.Close();
                                subscribers.Remove(subscriber);
                            }

                            if (MessageQueue.Exists(subscriberQueueName))
                            {
                                MessageQueue.Delete(subscriberQueueName);
                            }
                        }
                    }

                    if (sendAllData)
                    {
                        SendAllData(subscriber);
                    }

                    ll.Reset();
                }
                catch (MessageQueueException ex)
                {
                    // Handle no message arriving in the queue.
                    if (ex.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout)
                    {
                        //ll.Msg("RegistrationThread: No message arrived in queue.");
                    }
                    else if (ex.MessageQueueErrorCode == MessageQueueErrorCode.QueueDeleted)
                    {
                        Log.Info("RegistrationThread: Message queue was deleted ... recreate");
                        msmq.Close();
                        msmq = null;
                    }
                    else if (ex.MessageQueueErrorCode == MessageQueueErrorCode.QueueNotFound)
                    {
                        try
                        {
                            if (!MessageQueue.Exists(queueName))
                            {
                                MessageQueue msmqNew = MessageQueue.Create(queueName);
                                msmqNew.Label = "Fail2ban F2BQueue registration message queue";
                                msmqNew.Close();
                                Log.Info("RegistrationThread: Registration queue " + queueName + " created");
                            }
                            else
                            {
                                ll.Msg("RegistrationThread: Registration queue "
                                       + queueName + " inacceslible: " + ex.Message);
                                // Let's way a bit...
                                ewh.WaitOne(retryInterval * (ll.Last < 10 ? ll.Last : 10));
                                ewh.Reset();
                            }
                        }
                        catch (MessageQueueException ex1)
                        {
                            ll.Msg("RegistrationThread: Unable to create registration queue "
                                   + queueName + ": " + ex1.Message);
                            // Let's way a bit...
                            ewh.WaitOne(retryInterval * (ll.Last < 10 ? ll.Last : 10));
                            ewh.Reset();
                        }
                    }
                    else
                    {
                        ll.Msg("RegistrationThread: Unexpected MSMQ exception (code "
                               + ex.MessageQueueErrorCode + "): " + ex.Message);
                        // Let's way a bit...
                        ewh.WaitOne(retryInterval * (ll.Last < 10 ? ll.Last : 10));
                        ewh.Reset();
                    }
                }
                catch (EndOfStreamException)
                {
                    Log.Info("RegistrationThread: Input data truncated");
                }

                Log.Info("RegistrationThread loop cont(" + !shutdown + ")");
            }

            Log.Info("RegistrationThread finished");
        }