proxyproto

package module
v1.0.2 Latest Latest
Warning

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

Go to latest
Published: Sep 1, 2023 License: MIT Imports: 16 Imported by: 2

README

proxyproto

Go language to imeplementation of PROXY Protocol.

Supports version 1 & 2, TLV and CRC-32c (PP2_TYPE_CRC32C).

The official documentation: https://github.com/haproxy/haproxy/blob/master/doc/proxy-protocol.txt

Usage

Server Side
package main

import (
	"log"
	"net"

	"github.com/fango6/proxyproto"
)

func main() {
	ln, err := net.Listen("tcp", "127.0.0.1:9090")
	if err != nil {
		log.Fatal(err)
	}

	proxyListener := proxyproto.NewListener(ln)
	for {
		conn, err := proxyListener.Accept()
		if err != nil {
			log.Println(err)
			continue
		}

		go server(conn)
	}
}

func server(conn net.Conn) {
	// do something
}

Client Side
package main

import (
	"log"
	"net"
	"time"

	"github.com/fango6/proxyproto"
)

func main() {
	h := &proxyproto.Header{
		Version:           proxyproto.Version2,
		Command:           proxyproto.CMD_PROXY,
		AddressFamily:     proxyproto.AF_INET,
		TransportProtocol: proxyproto.SOCK_STREAM,

		SrcAddr: &net.TCPAddr{
			IP:   net.IPv4(127, 0, 0, 1),
			Port: 12345,
		},
		DstAddr: &net.TCPAddr{
			IP:   net.IPv4(127, 0, 0, 1),
			Port: 56789,
		},
	}

	raw, err := h.Format()
	if err != nil {
		log.Println("err:", err)
		return
	}

	conn, err := net.DialTimeout("tcp", "127.0.0.1:9090", time.Second*5)
	if err != nil {
		log.Println("err:", err)
		return
	}
	n, err := h.WriteTo(conn)
	if err != nil || n != len(raw) {
		log.Println("write PROXY header to connection fail:", err)
	}
}

More usages in the example folder, please move to there.

Documentation

Index

Constants

View Source
const (
	Version1 Version = 0x1 // Version 1
	Version2 Version = 0x2 // Version 2

	CMD_LOCAL Command = 0x0 // Local
	CMD_PROXY Command = 0x1 // Proxy

	AF_UNSPEC AddressFamily = 0x0 // Unspec
	AF_INET   AddressFamily = 0x1 // IPv4
	AF_INET6  AddressFamily = 0x2 // IPv6
	AF_UNIX   AddressFamily = 0x3 // Unix

	SOCK_UNSPEC TransportProtocol = 0x0 // Unspec
	SOCK_STREAM TransportProtocol = 0x1 // TCP
	SOCK_DGRAM  TransportProtocol = 0x2 // UDP

	Unknown string = "Unknown" // Unknown value
)

Variables

View Source
var (
	ErrUnknownVersion      = errors.New("formater unknown version")
	ErrUnknownAddrFamily   = errors.New("formater unknown address family")
	ErrUnknownTranProtocol = errors.New("formater unknown transport protocol")
	ErrInvalidAddress      = errors.New("formater invalid source or destination address")
	ErrExceedPayloadLength = errors.New("payload's length exceeds uint16 (65535) when TLV will be wrote")
)
View Source
var (
	ErrTlvLenTooShort = errors.New("TLV's length is too short")
	ErrTlvValTooShort = errors.New("TLV's values are too short")
)
View Source
var (
	ErrMustEndWithCRLF = errors.New("pp1 header must end with '\\r\\n'")
	ErrHeaderTooLong   = errors.New("pp1 header too long")

	ErrNotFoundAddressFamily = errors.New("pp1 header not found address family")
	ErrInvalidAddressFamily  = errors.New("pp1 invalid address family")
	ErrNotFoundAddressOrPort = errors.New("pp1 header not found address or port")
)
View Source
var (
	ErrUnknownVersionAndCommand         = errors.New("pp2 unknown version and command")
	ErrUnknownAddrFamilyAndTranProtocol = errors.New("pp2 unknown address family and transport protocol")
	ErrPayloadLengthTooShort            = errors.New("pp2 payload length is too short")
	ErrPayloadBytesTooShort             = errors.New("pp2 payload of bytes are too short")
)
View Source
var (
	ErrNoProxyProtocol = errors.New("proxy protocol prefix not present")
)
View Source
var ErrValidateCRC32cChecksum = errors.New("pp2 failed to validate CRC-32c checksum")

Functions

func CalcCRC32cChecksum added in v1.0.1

func CalcCRC32cChecksum(raw []byte) []byte

CalcCRC32cChecksum calculate a CRC32c checksum value of the whole PROXY header.

func ChecksumCRC32c

func ChecksumCRC32c(h *Header) bool

ChecksumCRC32c CRC-32c checksum with header. just do it when the header is valid and contains a CRC-32c checksum.

Types

type AddressFamily

type AddressFamily byte // IPv4, IPv6 or Unix

func (AddressFamily) String

func (af AddressFamily) String() string

type Command

type Command byte // Local or Proxy

func (Command) String

func (c Command) String() string

type Conn

type Conn struct {
	net.Conn

	Header *Header
	// contains filtered or unexported fields
}

Conn wrap net.Conn, want to read and parse Proxy Protocol header, and so on.

func NewConn

func NewConn(conn net.Conn, opts ...Option) *Conn

func (*Conn) Err

func (c *Conn) Err() error

Err read header error

func (*Conn) GetVpceID added in v1.0.2

func (c *Conn) GetVpceID() string

GetVpceID find VPC endpoint ID in the PROXY header's TLVs. an unregistered PP2Type will be choosen, and the first byte discarded.

func (*Conn) GetVpceIDWithType added in v1.0.2

func (c *Conn) GetVpceIDWithType(typ PP2Type, subType PP2Type) string

GetVpceIDWithType gets VPC endpoint ID with PP2Type from PROXY header. the subtype of 0 returns all values, otherwise the first byte is discarded.

func (*Conn) LocalAddr

func (c *Conn) LocalAddr() net.Addr

LocalAddr implement net.Conn, in order to read Proxy Protocol header

func (*Conn) LogrusFields

func (c *Conn) LogrusFields() logrus.Fields

LogrusFields header fields for logrus

func (*Conn) RawHeader

func (c *Conn) RawHeader() []byte

RawHeader get raw header

func (*Conn) Read

func (c *Conn) Read(b []byte) (int, error)

Read implement net.Conn, in order to read Proxy Protocol header

func (*Conn) RemoteAddr

func (c *Conn) RemoteAddr() net.Addr

RemoteAddr implement net.Conn, in order to read Proxy Protocol header

func (*Conn) SetDeadline

func (c *Conn) SetDeadline(t time.Time) error

SetDeadline implement net.Conn, in order to catch deadline

func (*Conn) SetReadDeadline

func (c *Conn) SetReadDeadline(t time.Time) error

SetReadDeadline implement net.Conn, in order to catch deadline

func (*Conn) TLVs

func (c *Conn) TLVs() TLVs

TLVs get TLVs of pp2

func (*Conn) ZapFields

func (c *Conn) ZapFields() []zap.Field

ZapFields header fields for zap

type Header struct {
	Version           Version
	Command           Command
	AddressFamily     AddressFamily
	TransportProtocol TransportProtocol

	SrcAddr net.Addr // source address
	DstAddr net.Addr // destination address

	Raw  []byte // raw proxy protocol header
	TLVs TLVs   // all of TLV groups
}

func ReadHeader

func ReadHeader(reader *bufio.Reader) (*Header, error)

func (*Header) Format added in v1.0.1

func (h *Header) Format() ([]byte, error)

Format format header to bytes.

func (*Header) FormatWithChecksum added in v1.0.1

func (h *Header) FormatWithChecksum() ([]byte, error)

FormatWithChecksum formater header to bytes, and append checksum with CRC-32c.

func (*Header) LogrusFields

func (h *Header) LogrusFields() logrus.Fields

func (*Header) WriteTo added in v1.0.1

func (h *Header) WriteTo(w io.Writer) (int, error)

WriteTo implements io.WriteTo

func (*Header) ZapFields

func (h *Header) ZapFields() []zap.Field

type Listener

type Listener struct {
	net.Listener
	// contains filtered or unexported fields
}

func NewListener

func NewListener(listener net.Listener, opts ...Option) *Listener

func (*Listener) Accept

func (ln *Listener) Accept() (net.Conn, error)

func (*Listener) Addr

func (ln *Listener) Addr() net.Addr

func (*Listener) Close

func (ln *Listener) Close() error

type Option

type Option func(*Conn)

func WithCRC32cChecksum

func WithCRC32cChecksum(want bool) Option

WithCRC32cChecksum validate CRC-32c checksum. pp2 (proxy protocol version 2) will validate it.

func WithDisableProxyProto

func WithDisableProxyProto(disable bool) Option

WithDisableProxyProto header is not read

func WithPostReadHeader

func WithPostReadHeader(fn PostReadHeader) Option

WithPostReadHeader want to do after reading header, such as logging

func WithReadHeaderTimeout

func WithReadHeaderTimeout(duration time.Duration) Option

WithReadHeaderTimeout read header with timeout

type PP2Type

type PP2Type byte

PP2Type type of proxy protocol version 2

const (
	PP2_TYPE_ALPN           PP2Type = 0x01
	PP2_TYPE_AUTHORITY      PP2Type = 0x02
	PP2_TYPE_CRC32C         PP2Type = 0x03
	PP2_TYPE_NOOP           PP2Type = 0x04
	PP2_TYPE_UNIQUE_ID      PP2Type = 0x05
	PP2_TYPE_SSL            PP2Type = 0x20
	PP2_SUBTYPE_SSL_VERSION PP2Type = 0x21
	PP2_SUBTYPE_SSL_CN      PP2Type = 0x22
	PP2_SUBTYPE_SSL_CIPHER  PP2Type = 0x23
	PP2_SUBTYPE_SSL_SIG_ALG PP2Type = 0x24
	PP2_SUBTYPE_SSL_KEY_ALG PP2Type = 0x25
	PP2_TYPE_NETNS          PP2Type = 0x30
)

The following types have already been registered for the <type> field:

type PostReadHeader

type PostReadHeader func(h *Header, err error)

PostReadHeader will be called after reading Proxy Protocol header.

type TLV

type TLV struct {
	Type   PP2Type
	Length uint16
	Value  []byte
}

TLV a Type-Length-Value group

func NewNoOpTLV added in v1.0.1

func NewNoOpTLV(length uint16) TLV

NewNoOpTLV create a PP2_TYPE_NOOP TLV group.

func NewTLV added in v1.0.1

func NewTLV(t PP2Type, val []byte) TLV

func (TLV) Format added in v1.0.1

func (tlv TLV) Format() []byte

Format format to raw bytes for PROXY sender.

func (TLV) IsRegistered

func (tlv TLV) IsRegistered() bool

IsRegistered true if type have already been registered

func (TLV) String

func (tlv TLV) String() string

type TLVs

type TLVs []TLV

TLVs TLV groups

func (TLVs) String

func (s TLVs) String() string

type TransportProtocol

type TransportProtocol byte // TCP or UDP

func (TransportProtocol) String

func (tp TransportProtocol) String() string

type Version

type Version byte // Version 1 or 2

func (Version) String

func (v Version) String() string

Directories

Path Synopsis
example

Jump to

Keyboard shortcuts

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