diff --git a/server.go b/server.go index 804386a..03329d9 100644 --- a/server.go +++ b/server.go @@ -4,6 +4,8 @@ import ( "bufio" "crypto/tls" "errors" + "io" + "log" "net" "strings" "sync" @@ -83,7 +85,7 @@ func (s *Server) SetDatagramChannelSize(size int) { func defaultTlsPeerName(tlsConn *tls.Conn) (tlsPeer string, ok bool) { state := tlsConn.ConnectionState() if len(state.PeerCertificates) <= 0 { - return "", false + return "", true } cn := state.PeerCertificates[0].Subject.CommonName return cn, true @@ -189,21 +191,25 @@ func (s *Server) goAcceptConnection(listener net.Listener) { } connection, err := listener.Accept() if err != nil { + log.Printf("Failed to accept connection, "+ + "proto=%s, addr=%s, error=%v", + listener.Addr().Network(), listener.Addr(), err, + ) continue } + log.Printf("Accepted connection, proto=%s, remote=%s, local=%s", + listener.Addr().Network(), connection.RemoteAddr(), connection.LocalAddr(), + ) - s.goScanConnection(connection) + s.goReadConnection(connection) } s.wait.Done() }(listener) } -func (s *Server) goScanConnection(connection net.Conn) { - scanner := bufio.NewScanner(connection) - if sf := s.format.GetSplitFunc(); sf != nil { - scanner.Split(sf) - } +func (s *Server) goReadConnection(connection net.Conn) { + reader := bufio.NewReader(connection) remoteAddr := connection.RemoteAddr() var client string @@ -215,27 +221,37 @@ func (s *Server) goScanConnection(connection net.Conn) { if tlsConn, ok := connection.(*tls.Conn); ok { // Handshake now so we get the TLS peer information if err := tlsConn.Handshake(); err != nil { + log.Printf("Failed to complete TLS handshake, closing connection, "+ + "remote=%s, local=%s, error=%v", + tlsConn.RemoteAddr(), tlsConn.LocalAddr(), err, + ) connection.Close() return } + log.Printf("TLS handshake complete, remote=%s, local=%s", + tlsConn.RemoteAddr(), tlsConn.LocalAddr(), + ) if s.tlsPeerNameFunc != nil { var ok bool tlsPeer, ok = s.tlsPeerNameFunc(tlsConn) if !ok { + log.Printf("Failed to get TLS peer name, closing connection, "+ + "remote=%s, local=%s", tlsConn.RemoteAddr(), tlsConn.LocalAddr(), + ) connection.Close() return } } } - var scanCloser *ScanCloser - scanCloser = &ScanCloser{scanner, connection} + readCloser := &ReadCloser{reader, connection} s.wait.Add(1) - go s.scan(scanCloser, client, tlsPeer) + go s.read(readCloser, client, tlsPeer) } -func (s *Server) scan(scanCloser *ScanCloser, client string, tlsPeer string) { +func (s *Server) read(readCloser *ReadCloser, client string, tlsPeer string) { + i := 0 loop: for { select { @@ -244,15 +260,34 @@ loop: default: } if s.readTimeoutMilliseconds > 0 { - scanCloser.closer.SetReadDeadline(time.Now().Add(time.Duration(s.readTimeoutMilliseconds) * time.Millisecond)) + readCloser.closer.SetReadDeadline(time.Now().Add(time.Duration(s.readTimeoutMilliseconds) * time.Millisecond)) } - if scanCloser.Scan() { - s.parser([]byte(scanCloser.Text()), client, tlsPeer) - } else { + // Read up to and including '<' delimiter + token, err := readCloser.ReadString('<') + if token != "" && i > 0 { // Skip traffic that doesnt start with '<' + // Re-add '<' to start; remove from end + token = "<" + token[:len(token)-1] + // Parse as syslog + s.parser([]byte(token), client, tlsPeer) + } + // Break loop on error + if err != nil { + if err == io.EOF { + log.Println("EOF when reading token") + } else { + log.Printf("Error when reading token: %v", err) + } break loop } + i++ + } + // Close connection + if conn, ok := readCloser.closer.(net.Conn); ok { + log.Printf("Closing connection, proto=%s, remote=%s, local=%s", + conn.LocalAddr().Network(), conn.RemoteAddr(), conn.LocalAddr(), + ) } - scanCloser.closer.Close() + readCloser.closer.Close() s.wait.Done() } @@ -318,8 +353,8 @@ type TimeoutCloser interface { SetReadDeadline(t time.Time) error } -type ScanCloser struct { - *bufio.Scanner +type ReadCloser struct { + *bufio.Reader closer TimeoutCloser }