Skip to content

Commit

Permalink
WIP Implement proxy-protocol v1 support for TCP server
Browse files Browse the repository at this point in the history
  • Loading branch information
Nico Schieder committed Jul 26, 2017
1 parent 5c51b0c commit e7c4f7b
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 3 deletions.
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ deps: clean-deps
github.com/inconshreveable/mousetrap \
github.com/gin-contrib/cors \
github.com/lxc/lxd \
github.com/jtopjian/lxdhelpers
github.com/jtopjian/lxdhelpers \
github.com/pires/go-proxyproto

clean-dist:
rm -rf ./dist/${VERSION}
Expand All @@ -98,7 +99,7 @@ dist:
else \
cd $$distpath && zip -r ../../${NAME}_${VERSION}_$$1_$$2.zip . && cd - ;\
fi \
done
done

build-container-latest: build
@echo Building docker container LATEST
Expand All @@ -107,4 +108,3 @@ build-container-latest: build
build-container-tagged: build
@echo Building docker container ${VERSION}
docker build -t yyyar/gobetween:${VERSION} .

3 changes: 3 additions & 0 deletions src/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ type Server struct {
// tcp | udp | tls
Protocol string `toml:"protocol" json:"protocol"`

// v1
ProxyProtocol string `toml:"proxy_protocol" json:"proxy_protocol"`

// weight | leastconn | roundrobin
Balance string `toml:"balance" json:"balance"`

Expand Down
8 changes: 8 additions & 0 deletions src/server/tcp/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"../../logging"
"../../stats"
"../../utils"
"../../utils/proxyprotocol"
tlsutil "../../utils/tls"
"../../utils/tls/sni"
"../modules/access"
Expand Down Expand Up @@ -342,6 +343,13 @@ func (this *Server) handle(ctx *core.TcpContext) {
defer this.scheduler.DecrementConnection(*backend)

/* Stat proxying */
if this.cfg.ProxyProtocol == "v1" {
log.Debug("Sending proxy-protocol header ", clientConn.RemoteAddr(), " -> ", this.listener.Addr(), " -> ", backendConn.RemoteAddr())
err := proxyprotocol.SendProxyProtocolV1(clientConn, backendConn)
if err != nil {
log.Error(err)
}
}
log.Debug("Begin ", clientConn.RemoteAddr(), " -> ", this.listener.Addr(), " -> ", backendConn.RemoteAddr())
cs := proxy(clientConn, backendConn, utils.ParseDurationOrDefault(*this.cfg.BackendIdleTimeout, 0))
bs := proxy(backendConn, clientConn, utils.ParseDurationOrDefault(*this.cfg.ClientIdleTimeout, 0))
Expand Down
62 changes: 62 additions & 0 deletions src/utils/proxyprotocol/proxyprotocol.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package proxyprotocol

import (
"fmt"
"net"
"strconv"

proxyproto "github.com/pires/go-proxyproto"
)

func addrToIPAndPort(addr net.Addr) (ip net.IP, port uint16, err error) {
ipString, portString, err := net.SplitHostPort(addr.String())
if err != nil {
return
}

ip = net.ParseIP(ipString)
if ip == nil {
err = fmt.Errorf("Could not parse IP")
return
}

p, err := strconv.ParseInt(portString, 10, 64)
if err != nil {
return
}
port = uint16(p)
return
}

/// SendProxyProtocolV1 sends a proxy protocol v1 header to initialize the connection
/// https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt
func SendProxyProtocolV1(client net.Conn, backend net.Conn) error {
sourceIP, sourcePort, err := addrToIPAndPort(client.RemoteAddr())
if err != nil {
return err
}

destinationIP, destinationPort, err := addrToIPAndPort(client.LocalAddr())
if err != nil {
return err
}

h := proxyproto.Header{
Version: 1,
SourceAddress: sourceIP,
SourcePort: sourcePort,
DestinationAddress: destinationIP,
DestinationPort: destinationPort,
}
if sourceIP.To4() != nil {
h.TransportProtocol = proxyproto.TCPv4
} else {
h.TransportProtocol = proxyproto.TCPv6
}

_, err = h.WriteTo(backend)
if err != nil {
return nil
}
return nil
}

0 comments on commit e7c4f7b

Please sign in to comment.