youtubebeat/vendor/github.com/elastic/beats/packetbeat/protos/applayer/applayer.go

243 lines
6.6 KiB
Go

// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. licenses this file to you under
// the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
// Package applayer provides common definitions with common fields
// for use with application layer protocols among beats.
package applayer
import (
"errors"
"time"
"github.com/elastic/beats/libbeat/beat"
"github.com/elastic/beats/libbeat/common"
"github.com/elastic/beats/libbeat/common/streambuf"
)
// A Message its direction indicator
type NetDirection uint8
const (
// Message due to a response by server
NetReverseDirection NetDirection = 0
// Message was send by client
NetOriginalDirection NetDirection = 1
)
// Transport type indicator. One of TransportUdp or TransportTcp
type Transport uint8
const (
TransportUDP Transport = iota
TransportTCP
)
// String returns the transport type its textual representation.
func (t Transport) String() string {
switch t {
case TransportUDP:
return "udp"
case TransportTCP:
return "tcp"
default:
return "invalid"
}
}
// A Stream provides buffering data if stream based protocol is used.
// Use Init to initialize a stream with en empty buffer and buffering limit.
// A Stream its zero value is a valid unlimited stream buffer.
type Stream struct {
// Buf provides the buffering with parsing support
Buf streambuf.Buffer
// MaxDataInStream sets the maximum number of bytes held in buffer.
// If limit is reached append function will return an error.
MaxDataInStream int
}
// A Transaction defines common fields for all application layer protocols.
type Transaction struct {
// Type is the name of the application layer protocol transaction be represented.
Type string
// Transaction source and destination IPs and Ports.
Tuple common.IPPortTuple
// Transport layer type
Transport Transport
// Src describes the transaction source/initiator endpoint
Src common.Endpoint
// Dst describes the transaction destination endpoint
Dst common.Endpoint
// Ts sets the transaction its initial timestamp
Ts TransactionTimestamp
// ResponseTime is the transaction duration in milliseconds. Should be set
// to -1 if duration is unknown
ResponseTime int32
// Status of final transaction
Status string // see libbeat/common/statuses.go
// Notes holds a list of interesting events and errors encountered when
// processing the transaction
Notes []string
// BytesIn is the number of bytes returned by destination endpoint
BytesIn uint64
// BytesOut is the number of bytes send by source endpoint to destination endpoint
BytesOut uint64
}
// TransactionTimestamp defines a transaction its initial timestamps as unix
// timestamp in milliseconds and time.Time struct.
type TransactionTimestamp struct {
Millis int64
Ts time.Time
}
// Message defines common application layer message fields. Some of these fields
// are required to initialize a Transaction (see (*Transaction).InitWithMsg).
type Message struct {
Ts time.Time
Tuple common.IPPortTuple
Transport Transport
CmdlineTuple *common.CmdlineTuple
Direction NetDirection
IsRequest bool
Size uint64
Notes []string
}
// Error code if stream exceeds max allowed size on Append.
var ErrStreamTooLarge = errors.New("Stream data too large")
// Init initializes a stream with an empty buffer and max size. Calling Init
// twice will fully re-initialize the buffer, such that calling Init before putting
// the stream in some object pool, no memory will be leaked.
func (stream *Stream) Init(maxDataInStream int) {
stream.MaxDataInStream = maxDataInStream
stream.Buf = streambuf.Buffer{}
}
// Reset will remove all bytes already read from the buffer.
func (stream *Stream) Reset() {
stream.Buf.Reset()
}
// Append adds data to the Stream its buffer. If internal buffer is nil, data
// will be retained as is. Use Write if you don't intend to retain the buffer in
// the stream.
func (stream *Stream) Append(data []byte) error {
err := stream.Buf.Append(data)
if err != nil {
return err
}
if stream.MaxDataInStream > 0 && stream.Buf.Total() > stream.MaxDataInStream {
return ErrStreamTooLarge
}
return nil
}
// Write copies data to the Stream its buffer. The data slice will not be
// retained by the buffer.
func (stream *Stream) Write(data []byte) (int, error) {
n, err := stream.Buf.Write(data)
if err != nil {
return n, err
}
if stream.MaxDataInStream > 0 && stream.Buf.Total() > stream.MaxDataInStream {
return n, ErrStreamTooLarge
}
return n, nil
}
// Init initializes some common fields. ResponseTime, Status, BytesIn and
// BytesOut are initialized to zero and must be filled by application code.
func (t *Transaction) Init(
typ string,
tuple common.IPPortTuple,
transport Transport,
direction NetDirection,
time time.Time,
cmdline *common.CmdlineTuple,
notes []string,
) {
t.Type = typ
t.Transport = transport
t.Tuple = tuple
// transactions have microseconds resolution
t.Ts.Ts = time
t.Ts.Millis = int64(time.UnixNano() / 1000)
t.Src, t.Dst = common.MakeEndpointPair(tuple.BaseTuple, cmdline)
t.Notes = notes
if direction == NetReverseDirection {
t.Src, t.Dst = t.Dst, t.Src
}
}
// InitWithMsg initializes some common fields from a Message. ResponseTime,
// Status, BytesIn and BytesOut are initialized to zero and must be filled by
// application code.
func (t *Transaction) InitWithMsg(
typ string,
msg *Message,
) {
t.Init(
typ,
msg.Tuple,
msg.Transport,
msg.Direction,
msg.Ts,
msg.CmdlineTuple,
nil,
)
}
// Event fills common event fields.
func (t *Transaction) Event(event *beat.Event) error {
event.Timestamp = t.Ts.Ts
fields := event.Fields
fields["type"] = t.Type
fields["responsetime"] = t.ResponseTime
fields["src"] = &t.Src
fields["dst"] = &t.Dst
fields["transport"] = t.Transport.String()
fields["bytes_out"] = t.BytesOut
fields["bytes_in"] = t.BytesIn
fields["status"] = t.Status
if len(t.Notes) > 0 {
fields["notes"] = t.Notes
}
return nil
}
// AddNotes appends some notes to a message.
func (m *Message) AddNotes(n ...string) {
m.Notes = append(m.Notes, n...)
}