Repository: pires/go-proxyproto (go)

Issue:
An example for a Dialer and Listener is required.
This is a really good library but it's missing examples for a Dialer and a Listener.
IE client and a server service.
I might write one and I was thinking about a simple "echo" client and server.

The server would accept a PROXY TCP protocol connection and will echo back(and log to stdout) if possible the request protocol(TCP4\TCP6 only), src and destination IP:PORT.

The client would open a connection to a PROXY enabled server(Listener) with a specific src and destination IP:PORT (TCP4\TCP6) and will receive the into the socket\connection a line of readable text containing the received IP:PORT.

I have seen an implementation of this but I forgot to save the links so I cannot copy and paste it and I will need to use some CPU to write it.
Any recommendations on where to start?

I have seen this implementation but it's still not sitting well for me
- https://github.com/Freeaqingme/go-proxyproto/blob/master/protocol.go

Other examples:
- https://github.com/armon/go-proxyproto
- https://github.com/kennylevinsen/serve2d
- https://github.com/nabeken/mikoi/blob/master/mikoi.go
- https://github.com/ninchat/go-proxyprotocol
- https://github.com/inkel/viaproxy/blob/master/conn.go
- https://github.com/djmaze/proxy-responder/blob/master/main.go

I wrote a TPROXY Server and Library in golang at:
- https://github.com/elico/go-linux-tproxy

Which has a basic TCP proxy server function that can eventually utilize the PROXY protocol in couple environments.

Pull request:
Added example for Client to readme, fixes #3

Patch:
diff --git a/README.md b/README.md
index 0957e66..5661fde 100644
--- a/README.md
+++ b/README.md
@@ -25,7 +25,54 @@ $ go get -u github.com/pires/go-proxyproto
 
 ## Usage
 
-### Client (TODO)
+### Client
+
+```go
+package main
+
+import (
+	"io"
+	"log"
+	"net"
+
+	proxyproto "github.com/pires/go-proxyproto"
+)
+
+func chkErr(err error) {
+	if err != nil {
+		log.Fatalf("Error: %s", err.Error())
+	}
+}
+
+func main() {
+	// Dial some proxy listener e.g. https://github.com/mailgun/proxyproto
+	target, err := net.ResolveTCPAddr("tcp", "127.0.0.1:2319")
+	chkErr(err)
+
+	conn, err := net.DialTCP("tcp", nil, target)
+	chkErr(err)
+
+	defer conn.Close()
+
+	// Create a proxyprotocol header or use HeaderProxyFromAddrs() if you
+	// have two conn's
+	header := &proxyproto.Header{
+		Version:            1,
+		Command:            proxyproto.PROXY,
+		TransportProtocol:  proxyproto.TCPv4,
+		SourceAddress:      net.ParseIP("10.1.1.1"),
+		SourcePort:         1000,
+		DestinationAddress: net.ParseIP("20.2.2.2"),
+		DestinationPort:    2000,
+	}
+	// After the connection was created write the proxy headers first
+	_, err = header.WriteTo(conn)
+	chkErr(err)
+	// Then your data... e.g.:
+	_, err = io.WriteString(conn, "HELO")
+	chkErr(err)
+}
+```
 
 ### Server
 
diff --git a/addr_proto.go b/addr_proto.go
index 0d0bc70..56b9155 100644
--- a/addr_proto.go
+++ b/addr_proto.go
@@ -4,13 +4,13 @@ package proxyproto
 type AddressFamilyAndProtocol byte
 
 const (
-	UNSPEC       AddressFamilyAndProtocol = '\x00'
-	TCPv4        AddressFamilyAndProtocol = '\x11'
-	UDPv4        AddressFamilyAndProtocol = '\x12'
-	TCPv6        AddressFamilyAndProtocol = '\x21'
-	UDPv6        AddressFamilyAndProtocol = '\x22'
-	UnixStream   AddressFamilyAndProtocol = '\x31'
-	UnixDatagram AddressFamilyAndProtocol = '\x32'
+	UNSPEC       = '\x00'
+	TCPv4        = '\x11'
+	UDPv4        = '\x12'
+	TCPv6        = '\x21'
+	UDPv6        = '\x22'
+	UnixStream   = '\x31'
+	UnixDatagram = '\x32'
 )
 
 var supportedTransportProtocol = map[AddressFamilyAndProtocol]bool{
@@ -54,18 +54,18 @@ func (ap AddressFamilyAndProtocol) IsUnspec() bool {
 
 func (ap AddressFamilyAndProtocol) toByte() byte {
 	if ap.IsIPv4() && ap.IsStream() {
-		return byte(TCPv4)
+		return TCPv4
 	} else if ap.IsIPv4() && ap.IsDatagram() {
-		return byte(UDPv4)
+		return UDPv4
 	} else if ap.IsIPv6() && ap.IsStream() {
-		return byte(TCPv6)
+		return TCPv6
 	} else if ap.IsIPv6() && ap.IsDatagram() {
-		return byte(UDPv6)
+		return UDPv6
 	} else if ap.IsUnix() && ap.IsStream() {
-		return byte(UnixStream)
+		return UnixStream
 	} else if ap.IsUnix() && ap.IsDatagram() {
-		return byte(UnixDatagram)
+		return UnixDatagram
 	}
 
-	return byte(UNSPEC)
+	return UNSPEC
 }
diff --git a/header.go b/header.go
index 5c5f869..b6babb2 100644
--- a/header.go
+++ b/header.go
@@ -16,19 +16,19 @@ var (
 	SIGV1 = []byte{'\x50', '\x52', '\x4F', '\x58', '\x59'}
 	SIGV2 = []byte{'\x0D', '\x0A', '\x0D', '\x0A', '\x00', '\x0D', '\x0A', '\x51', '\x55', '\x49', '\x54', '\x0A'}
 
-	ErrCantReadProtocolVersionAndCommand    = errors.New("proxyproto: can't read proxy protocol version and command")
-	ErrCantReadAddressFamilyAndProtocol     = errors.New("proxyproto: can't read address family or protocol")
-	ErrCantReadLength                       = errors.New("proxyproto: can't read length")
-	ErrCantResolveSourceUnixAddress         = errors.New("proxyproto: can't resolve source Unix address")
-	ErrCantResolveDestinationUnixAddress    = errors.New("proxyproto: can't resolve destination Unix address")
-	ErrNoProxyProtocol                      = errors.New("proxyproto: proxy protocol signature not present")
-	ErrUnknownProxyProtocolVersion          = errors.New("proxyproto: unknown proxy protocol version")
-	ErrUnsupportedProtocolVersionAndCommand = errors.New("proxyproto: unsupported proxy protocol version and command")
-	ErrUnsupportedAddressFamilyAndProtocol  = errors.New("proxyproto: unsupported address family and protocol")
-	ErrInvalidLength                        = errors.New("proxyproto: invalid length")
-	ErrInvalidAddress                       = errors.New("proxyproto: invalid address")
-	ErrInvalidPortNumber                    = errors.New("proxyproto: invalid port number")
-	ErrSuperfluousProxyHeader               = errors.New("proxyproto: upstream connection sent PROXY header but isn't allowed to send one")
+	ErrCantReadProtocolVersionAndCommand    = errors.New("Can't read proxy protocol version and command")
+	ErrCantReadAddressFamilyAndProtocol     = errors.New("Can't read address family or protocol")
+	ErrCantReadLength                       = errors.New("Can't read length")
+	ErrCantResolveSourceUnixAddress         = errors.New("Can't resolve source Unix address")
+	ErrCantResolveDestinationUnixAddress    = errors.New("Can't resolve destination Unix address")
+	ErrNoProxyProtocol                      = errors.New("Proxy protocol signature not present")
+	ErrUnknownProxyProtocolVersion          = errors.New("Unknown proxy protocol version")
+	ErrUnsupportedProtocolVersionAndCommand = errors.New("Unsupported proxy protocol version and command")
+	ErrUnsupportedAddressFamilyAndProtocol  = errors.New("Unsupported address family and protocol")
+	ErrInvalidLength                        = errors.New("Invalid length")
+	ErrInvalidAddress                       = errors.New("Invalid address")
+	ErrInvalidPortNumber                    = errors.New("Invalid port number")
+	ErrSuperfluousProxyHeader               = errors.New("Upstream connection sent PROXY header but isn't allowed to send one")
 )
 
 // Header is the placeholder for proxy protocol header.
@@ -43,69 +43,6 @@ type Header struct {
 	rawTLVs            []byte
 }
 
-// HeaderProxyFromAddrs creates a new PROXY header from a source and a
-// destination address. If version is zero, the latest protocol version is
-// used.
-//
-// The header is filled on a best-effort basis: if hints cannot be inferred
-// from the provided addresses, the header will be left unspecified.
-func HeaderProxyFromAddrs(version byte, sourceAddr, destAddr net.Addr) *Header {
-	if version < 1 || version > 2 {
-		version = 2
-	}
-	h := &Header{
-		Version:           version,
-		Command:           PROXY,
-		TransportProtocol: UNSPEC,
-	}
-	switch sourceAddr := sourceAddr.(type) {
-	case *net.TCPAddr:
-		destAddr, ok := destAddr.(*net.TCPAddr)
-		if !ok {
-			break
-		}
-		if len(sourceAddr.IP.To4()) == net.IPv4len {
-			h.TransportProtocol = TCPv4
-		} else if len(sourceAddr.IP) == net.IPv6len {
-			h.TransportProtocol = TCPv6
-		} else {
-			break
-		}
-		h.SourceAddress = sourceAddr.IP
-		h.DestinationAddress = destAddr.IP
-		h.SourcePort = uint16(sourceAddr.Port)
-		h.DestinationPort = uint16(destAddr.Port)
-	case *net.UDPAddr:
-		destAddr, ok := destAddr.(*net.UDPAddr)
-		if !ok {
-			break
-		}
-		if len(sourceAddr.IP.To4()) == net.IPv4len {
-			h.TransportProtocol = UDPv4
-		} else if len(sourceAddr.IP) == net.IPv6len {
-			h.TransportProtocol = UDPv6
-		} else {
-			break
-		}
-		h.SourceAddress = sourceAddr.IP
-		h.DestinationAddress = destAddr.IP
-		h.SourcePort = uint16(sourceAddr.Port)
-		h.DestinationPort = uint16(destAddr.Port)
-	case *net.UnixAddr:
-		_, ok := destAddr.(*net.UnixAddr)
-		if !ok {
-			break
-		}
-		switch sourceAddr.Net {
-		case "unix":
-			h.TransportProtocol = UnixStream
-		case "unixgram":
-			h.TransportProtocol = UnixDatagram
-		}
-	}
-	return h
-}
-
 // RemoteAddr returns the address of the remote endpoint of the connection.
 func (header *Header) RemoteAddr() net.Addr {
 	return &net.TCPAddr{
diff --git a/policy.go b/policy.go
index 71ad62b..c76ec67 100644
--- a/policy.go
+++ b/policy.go
@@ -117,14 +117,14 @@ func parse(allowed []string) ([]func(net.IP) bool, error) {
 		if strings.LastIndex(allowFrom, "/") > 0 {
 			_, ipRange, err := net.ParseCIDR(allowFrom)
 			if err != nil {
-				return nil, fmt.Errorf("proxyproto: given string %q is not a valid IP range: %v", allowFrom, err)
+				return nil, fmt.Errorf("Given string %q is not a valid IP range: %v", allowFrom, err)
 			}
 
 			a[i] = ipRange.Contains
 		} else {
 			allowed := net.ParseIP(allowFrom)
 			if allowed == nil {
-				return nil, fmt.Errorf("proxyproto: given string %q is not a valid IP address", allowFrom)
+				return nil, fmt.Errorf("Given string %q is not a valid IP address", allowFrom)
 			}
 
 			a[i] = allowed.Equal
@@ -142,7 +142,7 @@ func ipFromAddr(upstream net.Addr) (net.IP, error) {
 
 	upstreamIP := net.ParseIP(upstreamString)
 	if nil == upstreamIP {
-		return nil, fmt.Errorf("proxyproto: invalid IP address")
+		return nil, fmt.Errorf("invalid IP address")
 	}
 
 	return upstreamIP, nil
diff --git a/tlv.go b/tlv.go
index e6a2149..bbc86b5 100644
--- a/tlv.go
+++ b/tlv.go
@@ -11,30 +11,30 @@ import (
 const (
 	// Section 2.2
 	PP2_TYPE_ALPN           PP2Type = 0x01
-	PP2_TYPE_AUTHORITY      PP2Type = 0x02
-	PP2_TYPE_CRC32C         PP2Type = 0x03
-	PP2_TYPE_NOOP           PP2Type = 0x04
-	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
+	PP2_TYPE_AUTHORITY              = 0x02
+	PP2_TYPE_CRC32C                 = 0x03
+	PP2_TYPE_NOOP                   = 0x04
+	PP2_TYPE_SSL                    = 0x20
+	PP2_SUBTYPE_SSL_VERSION         = 0x21
+	PP2_SUBTYPE_SSL_CN              = 0x22
+	PP2_SUBTYPE_SSL_CIPHER          = 0x23
+	PP2_SUBTYPE_SSL_SIG_ALG         = 0x24
+	PP2_SUBTYPE_SSL_KEY_ALG         = 0x25
+	PP2_TYPE_NETNS                  = 0x30
 
 	// Section 2.2.7, reserved types
-	PP2_TYPE_MIN_CUSTOM     PP2Type = 0xE0
-	PP2_TYPE_MAX_CUSTOM     PP2Type = 0xEF
-	PP2_TYPE_MIN_EXPERIMENT PP2Type = 0xF0
-	PP2_TYPE_MAX_EXPERIMENT PP2Type = 0xF7
-	PP2_TYPE_MIN_FUTURE     PP2Type = 0xF8
-	PP2_TYPE_MAX_FUTURE     PP2Type = 0xFF
+	PP2_TYPE_MIN_CUSTOM     = 0xE0
+	PP2_TYPE_MAX_CUSTOM     = 0xEF
+	PP2_TYPE_MIN_EXPERIMENT = 0xF0
+	PP2_TYPE_MAX_EXPERIMENT = 0xF7
+	PP2_TYPE_MIN_FUTURE     = 0xF8
+	PP2_TYPE_MAX_FUTURE     = 0xFF
 )
 
 var (
-	ErrTruncatedTLV    = errors.New("proxyproto: truncated TLV")
-	ErrMalformedTLV    = errors.New("proxyproto: malformed TLV Value")
-	ErrIncompatibleTLV = errors.New("proxyproto: incompatible TLV type")
+	ErrTruncatedTLV    = errors.New("Truncated TLV")
+	ErrMalformedTLV    = errors.New("Malformed TLV Value")
+	ErrIncompatibleTLV = errors.New("Incompatible TLV type")
 )
 
 // PP2Type is the proxy protocol v2 type
diff --git a/v1.go b/v1.go
index a8ba25b..d21df9a 100644
--- a/v1.go
+++ b/v1.go
@@ -9,8 +9,8 @@ import (
 )
 
 const (
-	crlf      = "\r\n"
-	separator = " "
+	CRLF      = "\r\n"
+	SEPARATOR = " "
 )
 
 func initVersion1() *Header {
@@ -24,10 +24,10 @@ func initVersion1() *Header {
 func parseVersion1(reader *bufio.Reader) (*Header, error) {
 	// Make sure we have a v1 header
 	line, err := reader.ReadString('\n')
-	if !strings.HasSuffix(line, crlf) {
+	if !strings.HasSuffix(line, CRLF) {
 		return nil, ErrCantReadProtocolVersionAndCommand
 	}
-	tokens := strings.Split(line[:len(line)-2], separator)
+	tokens := strings.Split(line[:len(line)-2], SEPARATOR)
 	if len(tokens) < 6 {
 		return nil, ErrCantReadProtocolVersionAndCommand
 	}
@@ -79,17 +79,17 @@ func (header *Header) formatVersion1() ([]byte, error) {
 
 	buf := bytes.NewBuffer(make([]byte, 0, 108))
 	buf.Write(SIGV1)
-	buf.WriteString(separator)
+	buf.WriteString(SEPARATOR)
 	buf.WriteString(proto)
-	buf.WriteString(separator)
+	buf.WriteString(SEPARATOR)
 	buf.WriteString(header.SourceAddress.String())
-	buf.WriteString(separator)
+	buf.WriteString(SEPARATOR)
 	buf.WriteString(header.DestinationAddress.String())
-	buf.WriteString(separator)
+	buf.WriteString(SEPARATOR)
 	buf.WriteString(strconv.Itoa(int(header.SourcePort)))
-	buf.WriteString(separator)
+	buf.WriteString(SEPARATOR)
 	buf.WriteString(strconv.Itoa(int(header.DestinationPort)))
-	buf.WriteString(crlf)
+	buf.WriteString(CRLF)
 
 	return buf.Bytes(), nil
 }
diff --git a/v2.go b/v2.go
index 1450b5d..f404607 100644
--- a/v2.go
+++ b/v2.go
@@ -28,7 +28,7 @@ var (
 		binary.BigEndian.PutUint16(a, lengthUnix)
 		return a
 	}()
-	errUint16Overflow = errors.New("proxyproto: uint16 overflow")
+	errUint16Overflow = errors.New("uint16 overflow")
 )
 
 type _ports struct {
diff --git a/version_cmd.go b/version_cmd.go
index 67ce303..2ee1a05 100644
--- a/version_cmd.go
+++ b/version_cmd.go
@@ -4,8 +4,8 @@ package proxyproto
 type ProtocolVersionAndCommand byte
 
 const (
-	LOCAL ProtocolVersionAndCommand = '\x20'
-	PROXY ProtocolVersionAndCommand = '\x21'
+	LOCAL = '\x20'
+	PROXY = '\x21'
 )
 
 var supportedCommand = map[ProtocolVersionAndCommand]bool{
@@ -30,10 +30,10 @@ func (pvc ProtocolVersionAndCommand) IsUnspec() bool {
 
 func (pvc ProtocolVersionAndCommand) toByte() byte {
 	if pvc.IsLocal() {
-		return byte(LOCAL)
+		return LOCAL
 	} else if pvc.IsProxy() {
-		return byte(PROXY)
+		return PROXY
 	}
 
-	return byte(LOCAL)
+	return LOCAL
 }


Test patch:
diff --git a/header_test.go b/header_test.go
index a9671e8..12e8e6e 100644
--- a/header_test.go
+++ b/header_test.go
@@ -294,211 +294,3 @@ func TestFormat(t *testing.T) {
 		}
 	}
 }
-
-func TestHeaderProxyFromAddrs(t *testing.T) {
-	unspec := &Header{
-		Version:           2,
-		Command:           PROXY,
-		TransportProtocol: UNSPEC,
-	}
-
-	tests := []struct {
-		name                 string
-		version              byte
-		sourceAddr, destAddr net.Addr
-		expected             *Header
-	}{
-		{
-			name: "TCPv4",
-			sourceAddr: &net.TCPAddr{
-				IP:   net.ParseIP("10.1.1.1"),
-				Port: 1000,
-			},
-			destAddr: &net.TCPAddr{
-				IP:   net.ParseIP("20.2.2.2"),
-				Port: 2000,
-			},
-			expected: &Header{
-				Version:            2,
-				Command:            PROXY,
-				TransportProtocol:  TCPv4,
-				SourceAddress:      net.ParseIP("10.1.1.1"),
-				SourcePort:         1000,
-				DestinationAddress: net.ParseIP("20.2.2.2"),
-				DestinationPort:    2000,
-			},
-		},
-		{
-			name: "TCPv6",
-			sourceAddr: &net.TCPAddr{
-				IP:   net.ParseIP("fde7::372"),
-				Port: 1000,
-			},
-			destAddr: &net.TCPAddr{
-				IP:   net.ParseIP("fde7::1"),
-				Port: 2000,
-			},
-			expected: &Header{
-				Version:            2,
-				Command:            PROXY,
-				TransportProtocol:  TCPv6,
-				SourceAddress:      net.ParseIP("fde7::372"),
-				SourcePort:         1000,
-				DestinationAddress: net.ParseIP("fde7::1"),
-				DestinationPort:    2000,
-			},
-		},
-		{
-			name: "UDPv4",
-			sourceAddr: &net.UDPAddr{
-				IP:   net.ParseIP("10.1.1.1"),
-				Port: 1000,
-			},
-			destAddr: &net.UDPAddr{
-				IP:   net.ParseIP("20.2.2.2"),
-				Port: 2000,
-			},
-			expected: &Header{
-				Version:            2,
-				Command:            PROXY,
-				TransportProtocol:  UDPv4,
-				SourceAddress:      net.ParseIP("10.1.1.1"),
-				SourcePort:         1000,
-				DestinationAddress: net.ParseIP("20.2.2.2"),
-				DestinationPort:    2000,
-			},
-		},
-		{
-			name: "UDPv6",
-			sourceAddr: &net.UDPAddr{
-				IP:   net.ParseIP("fde7::372"),
-				Port: 1000,
-			},
-			destAddr: &net.UDPAddr{
-				IP:   net.ParseIP("fde7::1"),
-				Port: 2000,
-			},
-			expected: &Header{
-				Version:            2,
-				Command:            PROXY,
-				TransportProtocol:  UDPv6,
-				SourceAddress:      net.ParseIP("fde7::372"),
-				SourcePort:         1000,
-				DestinationAddress: net.ParseIP("fde7::1"),
-				DestinationPort:    2000,
-			},
-		},
-		{
-			name: "UnixStream",
-			sourceAddr: &net.UnixAddr{
-				Net: "unix",
-			},
-			destAddr: &net.UnixAddr{
-				Net: "unix",
-			},
-			expected: &Header{
-				Version:           2,
-				Command:           PROXY,
-				TransportProtocol: UnixStream,
-			},
-		},
-		{
-			name: "UnixDatagram",
-			sourceAddr: &net.UnixAddr{
-				Net: "unixgram",
-			},
-			destAddr: &net.UnixAddr{
-				Net: "unixgram",
-			},
-			expected: &Header{
-				Version:           2,
-				Command:           PROXY,
-				TransportProtocol: UnixDatagram,
-			},
-		},
-		{
-			name:    "Version1",
-			version: 1,
-			sourceAddr: &net.UnixAddr{
-				Net: "unix",
-			},
-			destAddr: &net.UnixAddr{
-				Net: "unix",
-			},
-			expected: &Header{
-				Version:           1,
-				Command:           PROXY,
-				TransportProtocol: UnixStream,
-			},
-		},
-		{
-			name: "TCPInvalidIP",
-			sourceAddr: &net.TCPAddr{
-				IP:   nil,
-				Port: 1000,
-			},
-			destAddr: &net.TCPAddr{
-				IP:   nil,
-				Port: 2000,
-			},
-			expected: unspec,
-		},
-		{
-			name: "UDPInvalidIP",
-			sourceAddr: &net.UDPAddr{
-				IP:   nil,
-				Port: 1000,
-			},
-			destAddr: &net.UDPAddr{
-				IP:   nil,
-				Port: 2000,
-			},
-			expected: unspec,
-		},
-		{
-			name: "TCPAddrTypeMismatch",
-			sourceAddr: &net.TCPAddr{
-				IP:   net.ParseIP("10.1.1.1"),
-				Port: 1000,
-			},
-			destAddr: &net.UDPAddr{
-				IP:   net.ParseIP("20.2.2.2"),
-				Port: 2000,
-			},
-			expected: unspec,
-		},
-		{
-			name: "UDPAddrTypeMismatch",
-			sourceAddr: &net.UDPAddr{
-				IP:   net.ParseIP("10.1.1.1"),
-				Port: 1000,
-			},
-			destAddr: &net.TCPAddr{
-				IP:   net.ParseIP("20.2.2.2"),
-				Port: 2000,
-			},
-			expected: unspec,
-		},
-		{
-			name: "UnixAddrTypeMismatch",
-			sourceAddr: &net.UnixAddr{
-				Net: "unix",
-			},
-			destAddr: &net.TCPAddr{
-				IP:   net.ParseIP("20.2.2.2"),
-				Port: 2000,
-			},
-			expected: unspec,
-		},
-	}
-
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			h := HeaderProxyFromAddrs(tt.version, tt.sourceAddr, tt.destAddr)
-
-			if !h.EqualsTo(tt.expected) {
-				t.Errorf("expected %+v, actual %+v for source %+v and destination %+v", tt.expected, h, tt.sourceAddr, tt.destAddr)
-			}
-		})
-	}
-}
diff --git a/tlv_test.go b/tlv_test.go
index e699cdd..b0fa576 100644
--- a/tlv_test.go
+++ b/tlv_test.go
@@ -8,10 +8,10 @@ import (
 )
 
 var (
-	fixtureOneByteTLV    = []byte{byte(PP2_TYPE_MIN_CUSTOM) + 1}
-	fixtureTwoByteTLV    = []byte{byte(PP2_TYPE_MIN_CUSTOM) + 2, 0x00}
-	fixtureEmptyLenTLV   = []byte{byte(PP2_TYPE_MIN_CUSTOM) + 3, 0x00, 0x01}
-	fixturePartialLenTLV = []byte{byte(PP2_TYPE_MIN_CUSTOM) + 3, 0x00, 0x02, 0x00}
+	fixtureOneByteTLV    = []byte{PP2_TYPE_MIN_CUSTOM + 1}
+	fixtureTwoByteTLV    = []byte{PP2_TYPE_MIN_CUSTOM + 2, 0x00}
+	fixtureEmptyLenTLV   = []byte{PP2_TYPE_MIN_CUSTOM + 3, 0x00, 0x01}
+	fixturePartialLenTLV = []byte{PP2_TYPE_MIN_CUSTOM + 3, 0x00, 0x02, 0x00}
 )
 
 func checkTLVs(t *testing.T, name string, raw []byte, expected []PP2Type) []TLV {
@@ -52,25 +52,25 @@ var invalidTLVTests = []struct {
 }{
 	{
 		name: "One byte TLV",
-		reader: newBufioReader(append(append(SIGV2, byte(PROXY), byte(TCPv4)), fixtureWithTLV(lengthV4Bytes, fixtureIPv4Address,
+		reader: newBufioReader(append(append(SIGV2, PROXY, TCPv4), fixtureWithTLV(lengthV4Bytes, fixtureIPv4Address,
 			fixtureOneByteTLV)...)),
 		expectedError: ErrTruncatedTLV,
 	},
 	{
 		name: "Two byte TLV",
-		reader: newBufioReader(append(append(SIGV2, byte(PROXY), byte(TCPv4)), fixtureWithTLV(lengthV4Bytes, fixtureIPv4Address,
+		reader: newBufioReader(append(append(SIGV2, PROXY, TCPv4), fixtureWithTLV(lengthV4Bytes, fixtureIPv4Address,
 			fixtureTwoByteTLV)...)),
 		expectedError: ErrTruncatedTLV,
 	},
 	{
 		name: "Empty Len TLV",
-		reader: newBufioReader(append(append(SIGV2, byte(PROXY), byte(TCPv4)), fixtureWithTLV(lengthV4Bytes, fixtureIPv4Address,
+		reader: newBufioReader(append(append(SIGV2, PROXY, TCPv4), fixtureWithTLV(lengthV4Bytes, fixtureIPv4Address,
 			fixtureEmptyLenTLV)...)),
 		expectedError: ErrTruncatedTLV,
 	},
 	{
 		name: "Partial Len TLV",
-		reader: newBufioReader(append(append(SIGV2, byte(PROXY), byte(TCPv4)), fixtureWithTLV(lengthV4Bytes, fixtureIPv4Address,
+		reader: newBufioReader(append(append(SIGV2, PROXY, TCPv4), fixtureWithTLV(lengthV4Bytes, fixtureIPv4Address,
 			fixturePartialLenTLV)...)),
 		expectedError: ErrTruncatedTLV,
 	},
diff --git a/v1_test.go b/v1_test.go
index 4a35df7..2e54da0 100644
--- a/v1_test.go
+++ b/v1_test.go
@@ -9,12 +9,12 @@ import (
 )
 
 var (
-	TCP4AddressesAndPorts        = strings.Join([]string{IP4_ADDR, IP4_ADDR, strconv.Itoa(PORT), strconv.Itoa(PORT)}, separator)
-	TCP4AddressesAndInvalidPorts = strings.Join([]string{IP4_ADDR, IP4_ADDR, strconv.Itoa(INVALID_PORT), strconv.Itoa(INVALID_PORT)}, separator)
-	TCP6AddressesAndPorts        = strings.Join([]string{IP6_ADDR, IP6_ADDR, strconv.Itoa(PORT), strconv.Itoa(PORT)}, separator)
+	TCP4AddressesAndPorts        = strings.Join([]string{IP4_ADDR, IP4_ADDR, strconv.Itoa(PORT), strconv.Itoa(PORT)}, SEPARATOR)
+	TCP4AddressesAndInvalidPorts = strings.Join([]string{IP4_ADDR, IP4_ADDR, strconv.Itoa(INVALID_PORT), strconv.Itoa(INVALID_PORT)}, SEPARATOR)
+	TCP6AddressesAndPorts        = strings.Join([]string{IP6_ADDR, IP6_ADDR, strconv.Itoa(PORT), strconv.Itoa(PORT)}, SEPARATOR)
 
-	fixtureTCP4V1 = "PROXY TCP4 " + TCP4AddressesAndPorts + crlf + "GET /"
-	fixtureTCP6V1 = "PROXY TCP6 " + TCP6AddressesAndPorts + crlf + "GET /"
+	fixtureTCP4V1 = "PROXY TCP4 " + TCP4AddressesAndPorts + CRLF + "GET /"
+	fixtureTCP6V1 = "PROXY TCP6 " + TCP6AddressesAndPorts + CRLF + "GET /"
 )
 
 var invalidParseV1Tests = []struct {
@@ -38,15 +38,15 @@ var invalidParseV1Tests = []struct {
 		ErrCantReadProtocolVersionAndCommand,
 	},
 	{
-		newBufioReader([]byte("PROXY TCP6 " + TCP4AddressesAndPorts + crlf)),
+		newBufioReader([]byte("PROXY TCP6 " + TCP4AddressesAndPorts + CRLF)),
 		ErrInvalidAddress,
 	},
 	{
-		newBufioReader([]byte("PROXY TCP4 " + TCP6AddressesAndPorts + crlf)),
+		newBufioReader([]byte("PROXY TCP4 " + TCP6AddressesAndPorts + CRLF)),
 		ErrInvalidAddress,
 	},
 	// PROXY TCP IPv4
-	{newBufioReader([]byte("PROXY TCP4 " + TCP4AddressesAndInvalidPorts + crlf)),
+	{newBufioReader([]byte("PROXY TCP4 " + TCP4AddressesAndInvalidPorts + CRLF)),
 		ErrInvalidPortNumber,
 	},
 }
diff --git a/v2_test.go b/v2_test.go
index e812e46..7b44b12 100644
--- a/v2_test.go
+++ b/v2_test.go
@@ -78,35 +78,35 @@ var invalidParseV2Tests = []struct {
 		ErrUnsupportedProtocolVersionAndCommand,
 	},
 	{
-		newBufioReader(append(SIGV2, byte(PROXY))),
+		newBufioReader(append(SIGV2, PROXY)),
 		ErrCantReadAddressFamilyAndProtocol,
 	},
 	{
-		newBufioReader(append(SIGV2, byte(PROXY), invalidRune)),
+		newBufioReader(append(SIGV2, PROXY, invalidRune)),
 		ErrUnsupportedAddressFamilyAndProtocol,
 	},
 	{
-		newBufioReader(append(SIGV2, byte(PROXY), byte(TCPv4))),
+		newBufioReader(append(SIGV2, PROXY, TCPv4)),
 		ErrCantReadLength,
 	},
 	{
-		newBufioReader(append(SIGV2, byte(PROXY), byte(TCPv4), invalidRune)),
+		newBufioReader(append(SIGV2, PROXY, TCPv4, invalidRune)),
 		ErrCantReadLength,
 	},
 	{
-		newBufioReader(append(append(SIGV2, byte(PROXY), byte(TCPv4)), lengthV4Bytes...)),
+		newBufioReader(append(append(SIGV2, PROXY, TCPv4), lengthV4Bytes...)),
 		ErrInvalidLength,
 	},
 	{
-		newBufioReader(append(append(SIGV2, byte(PROXY), byte(TCPv6)), lengthV6Bytes...)),
+		newBufioReader(append(append(SIGV2, PROXY, TCPv6), lengthV6Bytes...)),
 		ErrInvalidLength,
 	},
 	{
-		newBufioReader(append(append(append(SIGV2, byte(PROXY), byte(TCPv4)), lengthEmptyBytes...), fixtureIPv6Address...)),
+		newBufioReader(append(append(append(SIGV2, PROXY, TCPv4), lengthEmptyBytes...), fixtureIPv6Address...)),
 		ErrInvalidLength,
 	},
 	{
-		newBufioReader(append(append(append(SIGV2, byte(PROXY), byte(TCPv6)), lengthV6Bytes...), fixtureIPv4Address...)),
+		newBufioReader(append(append(append(SIGV2, PROXY, TCPv6), lengthV6Bytes...), fixtureIPv4Address...)),
 		ErrInvalidLength,
 	},
 }
@@ -125,7 +125,7 @@ var validParseAndWriteV2Tests = []struct {
 }{
 	// LOCAL
 	{
-		newBufioReader(append(append(SIGV2, byte(LOCAL), byte(TCPv4)), fixtureIPv4V2...)),
+		newBufioReader(append(append(SIGV2, LOCAL, TCPv4), fixtureIPv4V2...)),
 		&Header{
 			Version:            2,
 			Command:            LOCAL,
@@ -138,7 +138,7 @@ var validParseAndWriteV2Tests = []struct {
 	},
 	// PROXY TCP IPv4
 	{
-		newBufioReader(append(append(SIGV2, byte(PROXY), byte(TCPv4)), fixtureIPv4V2...)),
+		newBufioReader(append(append(SIGV2, PROXY, TCPv4), fixtureIPv4V2...)),
 		&Header{
 			Version:            2,
 			Command:            PROXY,
@@ -151,7 +151,7 @@ var validParseAndWriteV2Tests = []struct {
 	},
 	// PROXY TCP IPv6
 	{
-		newBufioReader(append(append(SIGV2, byte(PROXY), byte(TCPv6)), fixtureIPv6V2...)),
+		newBufioReader(append(append(SIGV2, PROXY, TCPv6), fixtureIPv6V2...)),
 		&Header{
 			Version:            2,
 			Command:            PROXY,
@@ -164,7 +164,7 @@ var validParseAndWriteV2Tests = []struct {
 	},
 	// PROXY TCP IPv4 with TLV
 	{
-		newBufioReader(append(append(SIGV2, byte(PROXY), byte(TCPv4)), fixtureIPv4V2TLV...)),
+		newBufioReader(append(append(SIGV2, PROXY, TCPv4), fixtureIPv4V2TLV...)),
 		&Header{
 			Version:            2,
 			Command:            PROXY,
@@ -178,7 +178,7 @@ var validParseAndWriteV2Tests = []struct {
 	},
 	// PROXY TCP IPv6 with TLV
 	{
-		newBufioReader(append(append(SIGV2, byte(PROXY), byte(TCPv6)), fixtureIPv6V2TLV...)),
+		newBufioReader(append(append(SIGV2, PROXY, TCPv6), fixtureIPv6V2TLV...)),
 		&Header{
 			Version:            2,
 			Command:            PROXY,
@@ -192,7 +192,7 @@ var validParseAndWriteV2Tests = []struct {
 	},
 	// PROXY UDP IPv4
 	{
-		newBufioReader(append(append(SIGV2, byte(PROXY), byte(UDPv4)), fixtureIPv4V2...)),
+		newBufioReader(append(append(SIGV2, PROXY, UDPv4), fixtureIPv4V2...)),
 		&Header{
 			Version:            2,
 			Command:            PROXY,
@@ -205,7 +205,7 @@ var validParseAndWriteV2Tests = []struct {
 	},
 	// PROXY UDP IPv6
 	{
-		newBufioReader(append(append(SIGV2, byte(PROXY), byte(UDPv6)), fixtureIPv6V2...)),
+		newBufioReader(append(append(SIGV2, PROXY, UDPv6), fixtureIPv6V2...)),
 		&Header{
 			Version:            2,
 			Command:            PROXY,
@@ -259,7 +259,7 @@ var validParseV2PaddedTests = []struct {
 }{
 	// PROXY TCP IPv4
 	{
-		append(append(SIGV2, byte(PROXY), byte(TCPv4)), fixtureIPv4V2Padded...),
+		append(append(SIGV2, PROXY, TCPv4), fixtureIPv4V2Padded...),
 		&Header{
 			Version:            2,
 			Command:            PROXY,
@@ -273,7 +273,7 @@ var validParseV2PaddedTests = []struct {
 	},
 	// PROXY TCP IPv6
 	{
-		append(append(SIGV2, byte(PROXY), byte(TCPv6)), fixtureIPv6V2Padded...),
+		append(append(SIGV2, PROXY, TCPv6), fixtureIPv6V2Padded...),
 		&Header{
 			Version:            2,
 			Command:            PROXY,
@@ -287,7 +287,7 @@ var validParseV2PaddedTests = []struct {
 	},
 	// PROXY UDP IPv4
 	{
-		append(append(SIGV2, byte(PROXY), byte(UDPv4)), fixtureIPv4V2Padded...),
+		append(append(SIGV2, PROXY, UDPv4), fixtureIPv4V2Padded...),
 		&Header{
 			Version:            2,
 			Command:            PROXY,
@@ -301,7 +301,7 @@ var validParseV2PaddedTests = []struct {
 	},
 	// PROXY UDP IPv6
 	{
-		append(append(SIGV2, byte(PROXY), byte(UDPv6)), fixtureIPv6V2Padded...),
+		append(append(SIGV2, PROXY, UDPv6), fixtureIPv6V2Padded...),
 		&Header{
 			Version:            2,
 			Command:            PROXY,
@@ -348,7 +348,7 @@ func TestV2EqualsToTLV(t *testing.T) {
 		SourcePort:         PORT,
 		DestinationPort:    PORT,
 	}
-	hdr, err := Read(newBufioReader(append(append(SIGV2, byte(PROXY), byte(TCPv4)), fixtureIPv4V2TLV...)))
+	hdr, err := Read(newBufioReader(append(append(SIGV2, PROXY, TCPv4), fixtureIPv4V2TLV...)))
 	if err != nil {
 		t.Fatal("TestV2EqualsToTLV: Unexpected error ", err)
 	}