/// <summary> /// Creates a callback for the socket receive event /// </summary> /// <returns>Returns bool if the callback is setup successfully.</returns> public bool RegisterReceiveOperation() { // Ensure that the listener socket is still alive if (_socket == null) { return(false); } try { // receive from anybody _remoteEndpoint = new IPEndPoint(IPAddress.Any, 0); var ep = _remoteEndpoint; // Setup the receive buffer to be used when a message is received _receiveBuffer = new byte[ReceiveBufferSize]; // nice and big receive buffer // Setup the receive callback _socket.BeginReceiveFrom(_receiveBuffer, 0, ReceiveBufferSize, SocketFlags.None, ref ep, ReceiveCallback, _socket); } catch (Exception ex) { _socket.Close(); _socket = null; EventLogger.LogEvent("Could not add callback method to the socket because: " + ex.Message, System.Diagnostics.EventLogEntryType.Warning); } return(true); }
/// <summary> /// Creates a callback for the socket receive event /// </summary> /// <returns>Returns bool if the callback is setup successfully.</returns> public bool RegisterReceiveOperation() { // Ensure that the listener socket is still alive if (this.socket == null) { return(false); } try { // receive from anybody this.remoteEndpoint = new IPEndPoint(IPAddress.Any, 0); EndPoint ep = (EndPoint)this.remoteEndpoint; // Setup the receive buffer to be used when a message is received this.receiveBuffer = new byte[RECEIVE_BUFFER_SIZE]; // nice and big receive buffer // Setup the receive callback this.socket.BeginReceiveFrom(receiveBuffer, 0, RECEIVE_BUFFER_SIZE, SocketFlags.None, ref this.remoteEndpoint, new AsyncCallback(ReceiveCallback), this.socket); } catch (Exception ex) { this.socket.Close(); this.socket = null; EventLogger.LogEvent("Could not add callback method to the socket because: " + ex.Message, System.Diagnostics.EventLogEntryType.Warning); } return(true); }
/// <summary> /// Adds parsed message to the specified hanlder buffer. /// </summary> /// <param name="bufferName">The name of the buffer for the handler.</param> /// <param name="entry">The parsed message.</param> public void AddEntry(string bufferName, string[] entry) { try { // Lock the buffer while adding data so that other threads do not try to write to the buffer lock (_buffers[bufferName]) { if (_buffers.ContainsKey(bufferName)) { _buffers[bufferName].Add(entry); } // Notify waiting threads that this object is available Monitor.Pulse(_buffers[bufferName]); } } catch (Exception ex) { EventLogger.LogEvent("Could not add entry to the buffer because: " + ex.Message, System.Diagnostics.EventLogEntryType.Warning); } }
/// <summary> /// Flushes all buffers that contain data by calling each buffer handler's StoreMessages method. /// </summary> public void Flush() { Trace.WriteLine("Flushing"); // Get a fast, one-way, read-only enumer of the buffers' keys var enumer = _buffers.Keys.GetEnumerator(); List <string[]> copiedList = null; // Ensure that a buffer is defined if (enumer.Current == null) { enumer.MoveNext(); } while (enumer.Current != null) { var currentVal = _buffers[enumer.Current]; // Lock the buffer while a copy is made so that new entries being added do not block or fail the copy. lock (currentVal) { try { if (currentVal.Count > 0) { copiedList = DeepCopy(currentVal); // Ensure that the copied object contains the same number of messages. if (copiedList.Count != currentVal.Count) { EventLogger.LogEvent("An error occured while storing messages for " + enumer.Current, System.Diagnostics.EventLogEntryType.Error); } // Clear the buffer. currentVal.Clear(); } } catch (Exception ex) { EventLogger.LogEvent("Could not store messages from " + enumer.Current + " because: " + ex.Message, System.Diagnostics.EventLogEntryType.Error); } finally { Monitor.Pulse(currentVal); } } if (copiedList != null && copiedList.Count > 0) { try { // Get a refence to the storer interface of the handler var storer = _handlers[enumer.Current].GetStorer(); if (storer != null) { //Process the list of messages if (!storer.StoreMessages(copiedList)) { EventLogger.LogEvent("An error occured while storing messages for " + enumer.Current, System.Diagnostics.EventLogEntryType.Warning); } else { copiedList.Clear(); } } } catch (Exception ex) { EventLogger.LogEvent("Could not store message from " + enumer.Current + " because: " + ex.Message, System.Diagnostics.EventLogEntryType.Warning); } } enumer.MoveNext(); } }
/// <summary> /// Processes a message received event. /// </summary> /// <param name="result">The result of a receive event.</param> private void ReceiveCallback(IAsyncResult result) { Trace.WriteLine("Receive callback"); // get a reference to the socket on which the message was received Socket sock = (Socket)result.AsyncState; EndPoint ep = null; IPEndPoint remoteEp = null; // variable to store received data length int inlen; _remoteEndpoint = new IPEndPoint(IPAddress.Any, 0); // Gather information about the message and the sender try { ep = _remoteEndpoint; inlen = sock.EndReceiveFrom(result, ref ep); remoteEp = (IPEndPoint)ep; } catch (Exception ex) { // only post messages if class socket reference is not null // in all other cases, the socket has been terminated if (_socket != null) { EventLogger.LogEvent("Receive operation failed with message: " + ex.Message, System.Diagnostics.EventLogEntryType.Warning); } inlen = -1; } // if socket has been closed, ignore received data and return if (_socket == null) { return; } // check that received data is long enough if (inlen <= 0) { // request next packet RegisterReceiveOperation(); return; } // If an IP forward is defined for the source of this message, forward the message to the specified IP's if (_ipForwards.ContainsKey(remoteEp.Address.ToString())) { if (_socket != null) { foreach (string ipAddress in _ipForwards[remoteEp.Address.ToString()]) { var sendBuffer = new byte[_receiveBuffer.Length]; _receiveBuffer.CopyTo(sendBuffer, 0); _sendSocket.BeginSendTo(sendBuffer, 0, inlen, SocketFlags.None, new IPEndPoint(IPAddress.Parse(ipAddress), 514), new AsyncCallback(SendCallback), _sendSocket); } } } string packet = null; // Get the human readable text of the message to process try { packet = System.Text.Encoding.ASCII.GetString(_receiveBuffer, 0, inlen); } catch (Exception ex) { EventLogger.LogEvent("Could not parse packet to string because: " + ex.Message, System.Diagnostics.EventLogEntryType.Warning); } // Run the regular expression against the message text to extract the groups var m = _msgRegex.Match(packet); //If a match is not found the message is not valid if (m != null && !string.IsNullOrEmpty(packet)) { //parse PRI section into a priority value int pri; var priority = int.TryParse(m.Groups["PRI"].Value, out pri) ? pri : 0; //parse the HEADER section - contains TIMESTAMP and HOSTNAME string hostname = null; DateTime?timestamp = null; // Get the timestamp and hostname from the header of the message if (!string.IsNullOrEmpty(m.Groups["HDR"].Value)) { if (!string.IsNullOrEmpty(m.Groups["TIMESTAMP"].Value)) { try { timestamp = new DateTime( DateTime.Now.Year, MonthNumber(m.Groups["MMM"].Value), int.Parse(m.Groups["DD"].Value), int.Parse(m.Groups["HH"].Value), int.Parse(m.Groups["MM"].Value), int.Parse(m.Groups["SS"].Value) ); } catch (ArgumentException) { //Ignore bad timestamp args. } } if (!string.IsNullOrEmpty(m.Groups["HOSTNAME"].Value)) { hostname = m.Groups["HOSTNAME"].Value; } } if (!timestamp.HasValue) { //add timestamp as per RFC3164 timestamp = DateTime.Now; } if (string.IsNullOrEmpty(hostname)) { hostname = ep.ToString(); } // Get the message text part of the message if it was found if ((m.Groups["MSG"].Value) != null) { var message = m.Groups["MSG"].Value; try { var sm = new SyslogMessage(priority, timestamp.Value, hostname, message); // Ensure that a handler is defined for the MessageReceived event if (MessageReceived != null) { Trace.WriteLine("Calling MessageReceived event"); MessageReceived(new MessageReceivedEventArgs(sm)); } //If the message is from an IP not listed in any filter do not process it if (!_ipFilters.ContainsKey(remoteEp.Address.ToString())) { Trace.WriteLine("Remote IP not listed in filter"); RegisterReceiveOperation(); return; } string[] parsedMsg = null; if (_ipFilters[remoteEp.Address.ToString()].ParserClassName != null) { try { // Parse the message using the parser defined for IP from where the message came parsedMsg = _ipFilters[remoteEp.Address.ToString()].GetParser().Parse(sm); } catch (Exception ex) { EventLogger.LogEvent("Could not get parser or parse message for ip " + remoteEp.Address.ToString() + " because: " + ex.Message, System.Diagnostics.EventLogEntryType.Warning); } } // Add the message to the LogBuffer if a storage Class is defined and message was parsed successfully. if (parsedMsg != null && _buffer != null && _ipFilters[remoteEp.Address.ToString()].StorerClassName != null) { Trace.WriteLine("Adding message to buffer"); _buffer.AddEntry(_ipFilters[remoteEp.Address.ToString()].AssemblyName, parsedMsg); } } catch (Exception ex) { EventLogger.LogEvent("Could not create new SyslogMessage because: " + ex.Message, System.Diagnostics.EventLogEntryType.Warning); } } } // Return the socket to the listen state RegisterReceiveOperation(); }
/// <summary> /// Creates a socket that waits for traffic and sets up the handler modules /// </summary> /// <returns>Returns true if the listener starts successfully. Otherwise, false.</returns> public bool Start() { HandlerSection handlers; // Get the handlers collection Trace.WriteLine("Loading handlers"); try { handlers = (HandlerSection)System.Configuration.ConfigurationManager.GetSection("handlerSection"); } catch (Exception ex) { EventLogger.LogEvent("Could not load configuration because: " + ex.Message, System.Diagnostics.EventLogEntryType.Error); return(false); } // Ensure that a socket needs to be initialized. if (_socket != null) { return(true); } // Ensure that a socket needs to be initialized and bound. if (_socket != null && _socket.IsBound) { return(true); } try { _socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); } catch (Exception ex) { EventLogger.LogEvent("Could not create socket because: " + ex.Message, System.Diagnostics.EventLogEntryType.Error); return(false); } Trace.WriteLine("Binding socket"); // Bind the socket to the specificed IP and port try { _socket.Bind(new IPEndPoint(_listenAddress, _listenPort)); } catch (Exception ex) { _socket.Close(); _socket = null; EventLogger.LogEvent("Could not bind socket because: " + ex.Message, System.Diagnostics.EventLogEntryType.Error); return(false); } if (_socket == null) { return(false); } // Create a new LogBuffer that will be used to store messages until they are discarded or flushed to a persistent store. _buffer = new LogBuffer(_logBufferFlushFrequency); if (handlers != null) { Trace.WriteLine("Initialising handlers"); // Load each module (handler) from the configuration file foreach (HandlerConfiguration handler in handlers.Handlers) { IDictionary <string, string> properties = new Dictionary <string, string>(); handler.HandlerProperties.AllKeys.All(key => { properties[key] = handler.HandlerProperties[key].Value; return(true); }); var msgHandler = new MessageHandler(handler.AssemblyName, handler.ParserClassName, handler.StorageClassName, handler.ConnectionString, properties); // If the handler has a storage class then setup the buffer to temporarily store the messages if (handler.StorageClassName != null) { Trace.WriteLine("Intialising buffer"); _buffer.InitHandler(msgHandler); } // If the handler is configured for specific IP addresses, setup the IP handler lookup list if (!string.IsNullOrEmpty(handler.FilterIPAddresses)) { var filters = handler.FilterIPAddresses.Split(',', ';'); foreach (var filter in filters) { _ipFilters.Add(filter, msgHandler); // If the handler also has IP forwards set, add them to the IP Forwards lookup list if (!string.IsNullOrEmpty(handler.IPForwards)) { _ipForwards.Add(filter, handler.IPForwards.Split(',', ';')); } } } } } // If any handler has an IP forward setup, create a send socket that will be used forward messages if (_ipForwards.Count > 0) { try { _sendSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); _sendSocket.Bind(new IPEndPoint(IPAddress.Any, 0)); } catch (Exception ex) { } } Trace.WriteLine("Registering receive event"); try { // Start the listen operation on the socket RegisterReceiveOperation(); } catch (Exception ex) { EventLogger.LogEvent("Could not register socket on data received event because: " + ex.Message, System.Diagnostics.EventLogEntryType.Error); return(false); } return(true); }
/// <summary> /// Creates a socket that waits for traffic and sets up the handler modules /// </summary> /// <returns>Returns true if the listener starts successfully. Otherwise, false.</returns> public bool Start() { HandlerSection handlers; // Get the handlers collection try { handlers = (HandlerSection)System.Configuration.ConfigurationManager.GetSection("handlerSection"); } catch (Exception ex) { EventLogger.LogEvent("Could not load configuration because: " + ex.Message, System.Diagnostics.EventLogEntryType.Error); return(false); } // Ensure that a socket needs to be initialized. if (this.socket != null) { return(true); } // Ensure that a socket needs to be initialized and bound. if (this.socket != null && this.socket.IsBound) { return(true); } try { this.socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); } catch (Exception ex) { EventLogger.LogEvent("Could not create socket because: " + ex.Message, System.Diagnostics.EventLogEntryType.Error); return(false); } // Bind the socket to the specificed IP and port try { this.socket.Bind(new IPEndPoint(this.listenAddress, SYSLOG_PORT)); } catch (Exception ex) { this.socket.Close(); this.socket = null; EventLogger.LogEvent("Could not bind socket because: " + ex.Message, System.Diagnostics.EventLogEntryType.Error); return(false); } if (this.socket == null) { return(false); } // Create a new LogBuffer that will be used to store messages until they are discarded or flushed to a persistent store. buffer = new LogBuffer(this.logBufferFlushFrequency); if (handlers != null) { // Load each module (handler) from the configuration file foreach (HandlerConfiguration handler in handlers.Handlers) { MessageHandler msgHandler = new MessageHandler(handler.AssemblyName, handler.ParserClassName, handler.StorageClassName, handler.ConnectionString); // If the handler has a storage class then setup the buffer to temporarily store the messages if (handler.StorageClassName != null) { buffer.InitializeBuffer(msgHandler); } // If the handler is configured for specific IP addresses, setup the IP handler lookup list if (handler.FilterIPAddresses != null) { string[] filters = handler.FilterIPAddresses.Split(',', ';'); for (int i = 0; i < filters.Length; i++) { ipFilters.Add(filters[i], msgHandler); // If the handler also has IP forwards set, add them to the IP Forwards lookup list if (handler.IPForwards != null && handler.IPForwards.Length > 0) { ipForwards.Add(filters[i], handler.IPForwards.Split(',', ';')); } } } } } // If any handler has an IP forward setup, create a send socket that will be used forward messages if (ipForwards.Count > 0) { try { sendSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); sendSocket.Bind(new IPEndPoint(IPAddress.Any, 0)); } catch (Exception ex) { } } try { // Start the listen operation on the socket RegisterReceiveOperation(); } catch (Exception ex) { EventLogger.LogEvent("Could not register socket on data received event because: " + ex.Message, System.Diagnostics.EventLogEntryType.Error); return(false); } return(true); }