layer4

package
v0.0.0-...-ec8fae2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 4, 2024 License: Apache-2.0 Imports: 21 Imported by: 26

Documentation

Index

Constants

View Source
const MatchingTimeoutDefault = 3 * time.Second
View Source
const MaxMatchingBytes = 8 * 1024

MaxMatchingBytes is the amount of bytes that are at most prefetched during matching. This is probably most relevant for the http matcher since http requests do not have a size limit. 8 KiB should cover most use-cases and is similar to popular webservers.

Variables

View Source
var (
	// VarsCtxKey is the key used to store the variables table
	// in a Connection's context.
	VarsCtxKey caddy.CtxKey = "vars"

	// ReplacerCtxKey is the key used to store the replacer.
	ReplacerCtxKey caddy.CtxKey = "replacer"
)
View Source
var ErrConsumedAllPrefetchedBytes = errors.New("consumed all prefetched bytes")
View Source
var ErrMatchingBufferFull = errors.New("matching buffer is full")
View Source
var ErrMatchingTimeout = errors.New("aborted matching according to timeout")

Functions

func ParseCaddyfileNestedHandlers

func ParseCaddyfileNestedHandlers(d *caddyfile.Dispenser, handlersRaw *[]json.RawMessage) error

ParseCaddyfileNestedHandlers parses the Caddyfile tokens for nested handlers, and composes a list of their raw json configurations.

func ParseCaddyfileNestedMatcherSet

func ParseCaddyfileNestedMatcherSet(d *caddyfile.Dispenser) (caddy.ModuleMap, error)

ParseCaddyfileNestedMatcherSet parses the Caddyfile tokens for a nested matcher set, and returns its raw module map value.

func ParseCaddyfileNestedRoutes

func ParseCaddyfileNestedRoutes(d *caddyfile.Dispenser, routes *RouteList, matchingTimeout *caddy.Duration) error

ParseCaddyfileNestedRoutes parses the Caddyfile tokens for nested named matcher sets, handlers and matching timeout, composes a list of route configurations, and adjusts the matching timeout.

func SetModuleNameInline

func SetModuleNameInline(moduleNameKey, moduleName string, raw json.RawMessage) (json.RawMessage, error)

SetModuleNameInline sets the string value of moduleNameKey to moduleName in raw, where raw must be a JSON encoding of a map, and returns the modified raw. In fact, it is a reverse function for caddy.getModuleNameInline.

Types

type App

type App struct {
	// Servers are the servers to create. The key of each server must be
	// a unique name identifying the server for your own convenience;
	// the order of servers does not matter.
	Servers map[string]*Server `json:"servers,omitempty"`
	// contains filtered or unexported fields
}

App is a Caddy app that operates closest to layer 4 of the OSI model.

func (*App) CaddyModule

func (*App) CaddyModule() caddy.ModuleInfo

CaddyModule returns the Caddy module information.

func (*App) Provision

func (a *App) Provision(ctx caddy.Context) error

Provision sets up the app.

func (*App) Start

func (a *App) Start() error

Start starts the app.

func (*App) Stop

func (a *App) Stop() error

Stop stops the servers and closes all listeners.

type ConnMatcher

type ConnMatcher interface {
	// Match returns true if the given connection matches.
	// It should read from the connection as little as possible:
	// only as much as necessary to determine a match.
	Match(*Connection) (bool, error)
}

ConnMatcher is a type that can match a connection.

type Connection

type Connection struct {
	// The underlying connection.
	net.Conn

	// The context for the connection.
	Context context.Context

	Logger *zap.Logger
	// contains filtered or unexported fields
}

Connection contains information about the connection as it passes through various handlers. It also has the capability of recording and rewinding when necessary.

A Connection can be used as a net.Conn because it embeds a net.Conn; but when wrapping underlying connections, usually you want to be careful to replace the embedded Conn, not this entire Connection value.

Connection structs are NOT safe for concurrent use.

func WrapConnection

func WrapConnection(underlying net.Conn, buf []byte, logger *zap.Logger) *Connection

WrapConnection wraps an underlying connection into a layer4 connection that supports recording and rewinding, as well as adding context with a replacer and variable table. This function is intended for use at the start of a connection handler chain where the underlying connection is not yet a layer4 Connection value.

func (*Connection) GetVar

func (cx *Connection) GetVar(key string) interface{}

GetVar gets a value from the context's variable table with the given key. It returns the value if found, and true if it found a value with that key; false otherwise.

func (*Connection) MatchingBytes

func (cx *Connection) MatchingBytes() []byte

MatchingBytes returns all bytes currently available for matching. This is only intended for reading. Do not write into the slice. It's a view of the internal buffer, and you will likely mess up the connection. Use of this for matching purpose should be accompanied by corresponding error value, ErrConsumedAllPrefetchedBytes and ErrMatchingBufferFull, if not matched.

func (*Connection) Read

func (cx *Connection) Read(p []byte) (n int, err error)

Read implements io.Reader in such a way that reads first deplete any associated buffer from the prior recording, and once depleted (or if there isn't one), it continues reading from the underlying connection.

func (*Connection) SetVar

func (cx *Connection) SetVar(key string, value interface{})

SetVar sets a value in the context's variable table with the given key. It overwrites any previous value with the same key.

func (*Connection) Wrap

func (cx *Connection) Wrap(conn net.Conn) *Connection

Wrap wraps conn in a new Connection based on cx (reusing cx's existing buffer and context). This is useful after a connection is wrapped by a package that does not support our Connection type (for example, `tls.Server()`).

func (*Connection) Write

func (cx *Connection) Write(p []byte) (n int, err error)

type Handler

type Handler interface {
	Handle(*Connection) error
}

Handler is a type that can handle connections.

type HandlerFunc

type HandlerFunc func(*Connection) error

HandlerFunc can turn a function into a Handler type.

func (HandlerFunc) Handle

func (h HandlerFunc) Handle(cx *Connection) error

Handle handles a connection; it implements the Handler interface.

type Handlers

type Handlers []NextHandler

Handlers is a list of connection handlers.

func (Handlers) Compile

func (h Handlers) Compile() Handler

Compile assembles the list of handlers into a single handler chain.

type ListenerWrapper

type ListenerWrapper struct {
	// Routes express composable logic for handling byte streams.
	Routes RouteList `json:"routes,omitempty"`

	// Maximum time connections have to complete the matching phase (the first terminal handler is matched). Default: 3s.
	MatchingTimeout caddy.Duration `json:"matching_timeout,omitempty"`
	// contains filtered or unexported fields
}

ListenerWrapper is a Caddy module that wraps App as a listener wrapper, it doesn't support udp.

func (*ListenerWrapper) CaddyModule

func (*ListenerWrapper) CaddyModule() caddy.ModuleInfo

CaddyModule returns the Caddy module information.

func (*ListenerWrapper) Provision

func (lw *ListenerWrapper) Provision(ctx caddy.Context) error

Provision sets up the ListenerWrapper.

func (*ListenerWrapper) UnmarshalCaddyfile

func (lw *ListenerWrapper) UnmarshalCaddyfile(d *caddyfile.Dispenser) error

UnmarshalCaddyfile sets up the ListenerWrapper from Caddyfile tokens. Syntax:

layer4 {
	matching_timeout <duration>
	@a <matcher> [<matcher_args>]
	@b {
		<matcher> [<matcher_args>]
		<matcher> [<matcher_args>]
	}
	route @a @b {
		<handler> [<handler_args>]
	}
	@c <matcher> {
		<matcher_option> [<matcher_option_args>]
	}
	route @c {
		<handler> [<handler_args>]
		<handler> {
			<handler_option> [<handler_option_args>]
		}
	}
}

func (*ListenerWrapper) WrapListener

func (lw *ListenerWrapper) WrapListener(l net.Listener) net.Listener

type MatchLocalIP

type MatchLocalIP struct {
	Ranges []string `json:"ranges,omitempty"`
	// contains filtered or unexported fields
}

MatchLocalIP matches requests by local IP (or CIDR range).

func (*MatchLocalIP) CaddyModule

func (*MatchLocalIP) CaddyModule() caddy.ModuleInfo

CaddyModule returns the Caddy module information.

func (*MatchLocalIP) Match

func (m *MatchLocalIP) Match(cx *Connection) (bool, error)

Match returns true if the connection is from one of the designated IP ranges.

func (*MatchLocalIP) Provision

func (m *MatchLocalIP) Provision(_ caddy.Context) error

Provision parses m's IP ranges, either from IP or CIDR expressions.

func (*MatchLocalIP) UnmarshalCaddyfile

func (m *MatchLocalIP) UnmarshalCaddyfile(d *caddyfile.Dispenser) error

UnmarshalCaddyfile sets up the MatchLocalIP from Caddyfile tokens. Syntax:

local_ip <ranges...>

type MatchNot

type MatchNot struct {
	MatcherSetsRaw []caddy.ModuleMap `json:"-" caddy:"namespace=layer4.matchers"`
	MatcherSets    []MatcherSet      `json:"-"`
}

MatchNot matches requests by negating the results of its matcher sets. A single "not" matcher takes one or more matcher sets. Each matcher set is OR'ed; in other words, if any matcher set returns true, the final result of the "not" matcher is false. Individual matchers within a set work the same (i.e. different matchers in the same set are AND'ed).

NOTE: The generated docs which describe the structure of this module are wrong because of how this type unmarshals JSON in a custom way. The correct structure is:

```json [

{},
{}

] ```

where each of the array elements is a matcher set, i.e. an object keyed by matcher name.

func (*MatchNot) CaddyModule

func (*MatchNot) CaddyModule() caddy.ModuleInfo

CaddyModule implements caddy.Module.

func (*MatchNot) MarshalJSON

func (m *MatchNot) MarshalJSON() ([]byte, error)

MarshalJSON satisfies json.Marshaler by marshaling m's raw matcher sets.

func (*MatchNot) Match

func (m *MatchNot) Match(r *Connection) (bool, error)

Match returns true if r matches m. Since this matcher negates the embedded matchers, false is returned if any of its matcher sets return true.

func (*MatchNot) Provision

func (m *MatchNot) Provision(ctx caddy.Context) error

Provision loads the matcher modules to be negated.

func (*MatchNot) UnmarshalCaddyfile

func (m *MatchNot) UnmarshalCaddyfile(d *caddyfile.Dispenser) error

UnmarshalCaddyfile sets up the MatchNot from Caddyfile tokens. Syntax:

not {
	<matcher> {
		<submatcher> [<args...>]
	}
	<matcher>
}
not <matcher> {
	<submatcher> [<args...>]
}
not <matcher>

Note: all matchers inside a not block are parsed into a single matcher set, i.e. they are ANDed. Multiple matcher sets, that are ORed, aren't supported. Instead, use multiple named matcher sets, each containing a not matcher.

func (*MatchNot) UnmarshalJSON

func (m *MatchNot) UnmarshalJSON(data []byte) error

UnmarshalJSON satisfies json.Unmarshaler. It puts the JSON bytes directly into m's MatcherSetsRaw field.

type MatchRemoteIP

type MatchRemoteIP struct {
	Ranges []string `json:"ranges,omitempty"`
	// contains filtered or unexported fields
}

MatchRemoteIP matches requests by remote IP (or CIDR range).

func (*MatchRemoteIP) CaddyModule

func (*MatchRemoteIP) CaddyModule() caddy.ModuleInfo

CaddyModule returns the Caddy module information.

func (*MatchRemoteIP) Match

func (m *MatchRemoteIP) Match(cx *Connection) (bool, error)

Match returns true if the connection is from one of the designated IP ranges.

func (*MatchRemoteIP) Provision

func (m *MatchRemoteIP) Provision(_ caddy.Context) error

Provision parses m's IP ranges, either from IP or CIDR expressions.

func (*MatchRemoteIP) UnmarshalCaddyfile

func (m *MatchRemoteIP) UnmarshalCaddyfile(d *caddyfile.Dispenser) error

UnmarshalCaddyfile sets up the MatchRemoteIP from Caddyfile tokens. Syntax:

remote_ip <ranges...>

type MatcherSet

type MatcherSet []ConnMatcher

MatcherSet is a set of matchers which must all match in order for the request to be matched successfully.

func (MatcherSet) Match

func (mset MatcherSet) Match(cx *Connection) (matched bool, err error)

Match returns true if the connection matches all matchers in mset or if there are no matchers. Any error terminates matching.

type MatcherSets

type MatcherSets []MatcherSet

MatcherSets is a group of matcher sets capable of checking whether a connection matches any of the sets.

func (*MatcherSets) AnyMatch

func (mss *MatcherSets) AnyMatch(cx *Connection) (matched bool, err error)

AnyMatch returns true if the connection matches any of the matcher sets in mss or if there are no matchers, in which case the request always matches. Any error terminates matching.

func (*MatcherSets) FromInterface

func (mss *MatcherSets) FromInterface(matcherSets interface{}) error

FromInterface fills ms from an interface{} value obtained from LoadModule.

type Middleware

type Middleware func(Handler) Handler

Middleware is a function that wraps a handler.

type NextHandler

type NextHandler interface {
	Handle(*Connection, Handler) error
}

NextHandler is a type that can handle connections as part of a middleware chain.

type NextHandlerFunc

type NextHandlerFunc func(cx *Connection, next Handler) error

NextHandlerFunc can turn a function into a NextHandler type.

func (NextHandlerFunc) Handle

func (h NextHandlerFunc) Handle(cx *Connection, next Handler) error

type RawMatcherSets

type RawMatcherSets []caddy.ModuleMap

RawMatcherSets is a group of matcher sets in their raw JSON form.

type Route

type Route struct {
	// Matchers define the conditions upon which to execute the handlers.
	// All matchers within the same set must match, and at least one set
	// must match; in other words, matchers are AND'ed together within a
	// set, but multiple sets are OR'ed together. No matchers match all.
	MatcherSetsRaw []caddy.ModuleMap `json:"match,omitempty" caddy:"namespace=layer4.matchers"`

	// Handlers define the behavior for handling the stream. They are
	// executed in sequential order if the route's matchers match.
	HandlersRaw []json.RawMessage `json:"handle,omitempty" caddy:"namespace=layer4.handlers inline_key=handler"`
	// contains filtered or unexported fields
}

Route represents a collection of handlers that are gated by matching logic. A route is invoked if its matchers match the byte stream. In an equivalent "if...then" statement, matchers are like the "if" clause and handlers are the "then" clause: if the matchers match, then the handlers will be executed.

func (*Route) Provision

func (r *Route) Provision(ctx caddy.Context) error

Provision sets up a route.

type RouteList

type RouteList []*Route

RouteList is a list of connection routes that can create a middleware chain. Routes are evaluated in sequential order: for the first route, the matchers will be evaluated, and if matched, the handlers invoked; and so on for the second route, etc.

func (RouteList) Compile

func (routes RouteList) Compile(logger *zap.Logger, matchingTimeout time.Duration, next Handler) Handler

Compile prepares a middleware chain from the route list. This should only be done once: after all the routes have been provisioned, and before the server loop begins.

func (RouteList) Provision

func (routes RouteList) Provision(ctx caddy.Context) error

Provision sets up all the routes.

type Server

type Server struct {
	// The network address to bind to. Any Caddy network address
	// is an acceptable value:
	// https://caddyserver.com/docs/conventions#network-addresses
	Listen []string `json:"listen,omitempty"`

	// Routes express composable logic for handling byte streams.
	Routes RouteList `json:"routes,omitempty"`

	// Maximum time connections have to complete the matching phase (the first terminal handler is matched). Default: 3s.
	MatchingTimeout caddy.Duration `json:"matching_timeout,omitempty"`
	// contains filtered or unexported fields
}

Server represents a Caddy layer4 server.

func (*Server) Provision

func (s *Server) Provision(ctx caddy.Context, logger *zap.Logger) error

Provision sets up the server.

func (*Server) UnmarshalCaddyfile

func (s *Server) UnmarshalCaddyfile(d *caddyfile.Dispenser) error

UnmarshalCaddyfile sets up the Server from Caddyfile tokens. Syntax:

<address:port> [<address:port>] {
	matching_timeout <duration>
	@a <matcher> [<matcher_args>]
	@b {
		<matcher> [<matcher_args>]
		<matcher> [<matcher_args>]
	}
	route @a @b {
		<handler> [<handler_args>]
	}
	@c <matcher> {
		<matcher_option> [<matcher_option_args>]
	}
	route @c {
		<handler> [<handler_args>]
		<handler> {
			<handler_option> [<handler_option_args>]
		}
	}
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL