private async Task UdpReceiveMessagesAsync(Socket socket, CancellationToken cancellationToken, Func <SyslogMessage, CancellationToken, Task> callback) { byte[] buffer = new byte[1024]; int readSize = 0; try { EndPoint sender = new IPEndPoint(IPAddress.Loopback, 0); while ((readSize = await UdpReceiveBufferAsync(socket, buffer, 0, 1024, sender, SocketFlags.None)) > 0) { if (cancellationToken.IsCancellationRequested) { return; } if (readSize > MaxMessageSize) { Trace.WriteLine("Maximum message size exceeded. Closing socket."); return; } SyslogMessage sm = null; if (SyslogMessage.TryParse(((IPEndPoint)sender).Address, Encoding.ASCII.GetString(buffer, 0, readSize), out sm)) { await callback(sm, cancellationToken); } } } finally { try { if (socket.Connected) { socket.Close(); } } catch (SocketException ex) { Trace.WriteLine($"{ex.Message} ({ex.GetType()})"); } } }
static public bool TryParse(IPAddress sender, string message, out SyslogMessage logmsg) { logmsg = new SyslogMessage(sender); Match msgMatch; if (sender == null || string.IsNullOrEmpty(message)) { return(false); } if (!(msgMatch = _reRFC5234.Match(message)).Success) { Trace.WriteLine($"Could not understand received message '{message}'."); return(false); } string strValue; int intValue; DateTime dtValue; if (msgMatch.Groups["PRI"].Success && !string.IsNullOrWhiteSpace((strValue = msgMatch.Groups["PRI"].Value)) && Int32.TryParse(strValue.Substring(1, strValue.Length - 2), out intValue)) { logmsg.Facility = (SyslogFacility)Math.Floor((double)intValue / 8); logmsg.Severity = (SyslogSeverity)(intValue % 8); } if (msgMatch.Groups["VER"].Success && !string.IsNullOrWhiteSpace((strValue = msgMatch.Groups["VER"].Value)) && Int32.TryParse(strValue, out intValue)) { logmsg.Version = intValue; } if (msgMatch.Groups["TS"].Success && !string.IsNullOrWhiteSpace((strValue = msgMatch.Groups["TS"].Value)) && DateTime.TryParse(strValue, null, System.Globalization.DateTimeStyles.RoundtripKind, out dtValue)) { logmsg.Timestamp = dtValue; } if (msgMatch.Groups["HOST"].Success && !string.IsNullOrWhiteSpace((strValue = msgMatch.Groups["HOST"].Value))) { logmsg.Hostname = strValue; } if (msgMatch.Groups["APP"].Success && !string.IsNullOrWhiteSpace((strValue = msgMatch.Groups["APP"].Value))) { logmsg.AppName = strValue; } if (msgMatch.Groups["PID"].Success && !string.IsNullOrWhiteSpace((strValue = msgMatch.Groups["PID"].Value))) { logmsg.ProcId = strValue; } if (msgMatch.Groups["MSGID"].Success && !string.IsNullOrWhiteSpace((strValue = msgMatch.Groups["MSGID"].Value))) { logmsg.MsgId = strValue; } if (msgMatch.Groups["SD"].Success && !string.IsNullOrWhiteSpace((strValue = msgMatch.Groups["SD"].Value))) { var sdMatch = _reSD.Match(msgMatch.Groups["SD"].Value.Trim('[', ']', ' ')); foreach (Capture kvTerm in sdMatch.Groups["term"].Captures) { Capture sdKey = null; foreach (Capture keyMatch in sdMatch.Groups["prefix"].Captures) { if (keyMatch.Index >= kvTerm.Index && keyMatch.Index <= kvTerm.Index + kvTerm.Length) { sdKey = keyMatch; break; } } if (sdKey == null) { if (!logmsg.Data.ContainsKey(kvTerm.Value)) { logmsg.Data.Add(kvTerm.Value, null); } continue; } Capture sdValue = null; foreach (Capture termStringMatch in sdMatch.Groups["termString"].Captures) { if (termStringMatch.Index >= kvTerm.Index && termStringMatch.Index <= kvTerm.Index + kvTerm.Length) { sdValue = termStringMatch; break; } } if (!logmsg.Data.ContainsKey(sdKey.Value)) { logmsg.Data.Add(sdKey.Value, sdValue?.Value.Trim(' ', '"')); } } } if (msgMatch.Groups["MSG"].Success) { logmsg.Content = msgMatch.Groups["MSG"].Value; } return(true); }
static public bool TryParse(IPAddress sender, byte[] message, out SyslogMessage logmsg) { return(TryParse(sender, Encoding.ASCII.GetString(message), out logmsg)); }
private async Task TcpReceiveMessageAsync(Socket socket, CancellationToken cancellationToken, Func <SyslogMessage, CancellationToken, Task> callback) { byte[] buffer = new byte[1024]; int readSize = 0; StringBuilder txt = new StringBuilder(); try { while (socket.Connected && (readSize = await TcpReceiveBufferAsync(socket, buffer, 0, buffer.Length, SocketFlags.None)) > 0) { if (cancellationToken.IsCancellationRequested) { return; } if (txt.Length + readSize > MaxMessageSize) { Trace.WriteLine("Maximum message size exceeded. Closing socket."); return; } var s = Encoding.ASCII.GetString(buffer, 0, readSize); int idx = 0; if ((idx = s.IndexOf("\n")) > -1) { txt.Append(s.Substring(0, idx)); SyslogMessage sm = null; if (SyslogMessage.TryParse(((IPEndPoint)socket.RemoteEndPoint).Address, txt.ToString(), out sm)) { await callback(sm, cancellationToken); } txt = new StringBuilder(s.Substring(idx + 1)); continue; } else { txt.Append(s); } } if (txt.Length == 0) { return; // Timeout or socket error } SyslogMessage msg; if (SyslogMessage.TryParse(((IPEndPoint)socket.RemoteEndPoint).Address, txt.ToString(), out msg)) { await callback(msg, cancellationToken); } } finally { try { if (socket.Connected) { socket.Close(); } } catch (SocketException) { } } }