proxy

package
v0.2.6 Latest Latest
Warning

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

Go to latest
Published: May 1, 2017 License: MIT Imports: 19 Imported by: 2

Documentation

Overview

Package proxy provides an intuitive transport level proxy.

The proxy module does not attempt to perform reconnection to remote endpoint.

The discovery backend chosen is etcd https://github.com/coreos/etcd

Layout for the discovery backend should look like the following:

/srv/redis/debug
/srv/redis/debug/10.0.1.134:6379
/srv/redis/debug/10.0.2.15:6379
/srv/redis/debug/10.0.3.41:6379

When nodes' state in service /srv/redis/debug changes e.g. leaving or joining, the proxy will attempt to obtain a new set of nodes, followed by a reset on established connections.

Proxy behaviors can be divided into two modes: ordered, or round-robin.

In ordered mode, the first remote host is attempted, then second, until all were tried, the proxy declare connection failed.

In round-robin node, connections are spread among available candidates.

Index

Examples

Constants

View Source
const (
	MAX_BACKOFF_DELAY = 2 * time.Second
)

Variables

View Source
var (
	// Proxy session ended.
	ErrProxyEnd = errors.New("proxy end")

	// Requested cluster node, but source and destination count does not match
	ErrClusterNodeMismatch = errors.New("Origin and target count mismatch")

	// Requested cluster mode, but I cannot find enough nodes to cluster to
	ErrClusterNotEnoughNodes = errors.New("candidate less then asked")
)

Functions

func ClusterSrv

func ClusterSrv(c ctx.Context, opts *ConnOptions) error

ClusterSrv is a short hand to creating multiple connection endpoints by service key. Proxy behavior behaves like Srv, but each source endpoint maps to one destination endpoint. Instead of managing connections yourself, this function helps you to handle connection as a group.

func ClusterTo

func ClusterTo(c ctx.Context, opts *ConnOptions) error

ClusterTo is a short hand to creating multiple connection endpoints. Proxy behavior behaves like To, but each source endpoint maps to one destination endpoint. Instead of managing connections yourself, this function helps you to handle connection as a group.

Example (Cluster)

Create a proxy that connects each source endpoint to each remote endpoint. Each connection behaves in the same way as proxy.To, but invoking cancel function aborts both.

package main

import (
	"github.com/poddworks/groxy/proxy"

	ctx "context"
	"log"
)

func main() {
	pxyOpts := &proxy.ConnOptions{
		Net:       "tcp4",
		FromRange: []string{":16379", ":16378"},
		To:        []string{"10.0.0.12:6379", "10.0.1.123:6379"},
		Balance:   true,
	}

	context, cancel := ctx.WithCancel(ctx.Background())
	defer cancel()

	err := proxy.ClusterTo(context, pxyOpts)
	log.Warning(err)
}
Output:

func LoadCertificate

func LoadCertificate(opts CertOptions) (*tls.Config, error)

LoadCertificate processes certificate resource for TLSConfg to consume. Reads CA cert chain, Private, and Public key, then returns tls.Config.

Supported URI:

  • Local file on disk (file://)
  • Amazon Web Services S3 object (s3://)

If left unspecified, URI is treated as if its a file reating on disk

The default authentication rule is to verify cert key pair.

Example

Create a proxy that encrypts outbound connection to TLS enabled endpoint

package main

import (
	"github.com/poddworks/groxy/proxy"

	ctx "context"
	"log"
)

func main() {
	tlscfg, err := proxy.LoadCertificate(proxy.CertOptions{
		"s3://devops.org/cert/ca.pem",
		"file://cert.pem",
		"key.pem",
	})
	if err != nil {
		log.Fatal(err)
	}

	// prepare proxy option with TLS enabled
	pxyOpts := &proxy.ConnOptions{
		// Conneciton initiator does not encrypt data
		Net:  "tcp4",
		From: ":6379",

		// destination endpoint must accept TLS encrypted data
		To: []string{"10.0.0.12:6379"},

		// instructs go-proxy to establish TLS connection with config
		TLSConfig: proxy.TLSConfig{
			Client: tlscfg,
		},
	}

	context, cancel := ctx.WithCancel(ctx.Background())
	defer cancel()

	err := proxy.To(context, pxyOpts)
	log.Warning(err)
}
Output:

func LogLevel

func LogLevel(level string)

LogLevel sets logging level of go-proxy runtime

func Srv

func Srv(c ctx.Context, opts *ConnOptions) error

Srv takes a Context and ConnOptions and begin listening for request to proxy. Srv obtains origin candidates through discovery service by key. If the candidate list changes in discovery record, Srv will reject current connections and obtain new origin candidates. Review https://godoc.org/golang.org/x/net/context for understanding the control flow.

Example (Discovery)

Create a proxy that listens on 0.0.0.0:27017 and foward to hosts registered under service key /srv/mongo_router/debug, trying them in order.

New set of hosts is obtained on nodes joining or leaving service /srv/mongo_router/debug, followed by connection reset.

See coreos/etcd https://github.com/coreos/etcd for more information on discovery backend

package main

import (
	"github.com/poddworks/groxy/proxy"

	ctx "context"
	"log"
)

func main() {
	pxyOpts := &proxy.ConnOptions{
		Net:  "tcp4",
		From: ":27017",
		Discovery: &proxy.DiscOptions{
			Service:   "/srv/mongo_router/debug",
			Endpoints: []string{"http://10.0.1.11:2379", "http://10.0.2.13:2379"},
		},
	}

	context, cancel := ctx.WithCancel(ctx.Background())
	defer cancel()

	err := proxy.Srv(context, pxyOpts)
	log.Warning(err)
}
Output:

func To

func To(c ctx.Context, opts *ConnOptions) error

To takes a Context and ConnOptions and begin listening for request to proxy. To obtains origin candidates through static listing. Review https://godoc.org/golang.org/x/net/context for understanding the control flow.

Example (Static)

Create a proxy that listens on 0.0.0.0:6379 and foward to two remote host, balance connections

package main

import (
	"github.com/poddworks/groxy/proxy"

	ctx "context"
	"log"
)

func main() {
	pxyOpts := &proxy.ConnOptions{
		Net:     "tcp4",
		From:    ":6379",
		To:      []string{"10.0.0.12:6379", "10.0.1.123:6379"},
		Balance: true,
	}

	context, cancel := ctx.WithCancel(ctx.Background())
	defer cancel()

	err := proxy.To(context, pxyOpts)
	log.Warning(err)
}
Output:

Types

type Backoff

type Backoff struct {
	// contains filtered or unexported fields
}

Backoff provides stepped delay on each failed attempts. Maximum delay time is capped off at 2 seconds.

func (*Backoff) Attempts

func (b *Backoff) Attempts() int64

Attempts reports current failed attempts

func (*Backoff) Delay

func (b *Backoff) Delay()

Delay marks this attempt failed, increments counter, and sleep for no more then 2 seconds in this goroutine

func (*Backoff) Reset

func (b *Backoff) Reset()

Reset clears failed attempt counter

type CertOptions

type CertOptions struct {
	// Certificate path information
	CA      string
	TlsCert string
	TlsKey  string

	// Setup tls.Config so we are listening server, otherwise we are connecting
	// client
	Server bool
}

CertOptions provides specification to path of certificate and whether this is for listening server or connecting client

type ConnOptions

type ConnOptions struct {
	// Type of network transport
	// See https://godoc.org/net
	Net string

	// Listening origin
	From string
	// Listening origin list for cluster mode
	FromRange []string

	// Balacnce forwarding host using round robin
	Balance bool
	// List of forwarding host
	To []string

	// TLS config
	TLSConfig TLSConfig

	// Discovery backend setting
	Discovery *DiscOptions

	// Read timeout
	ReadTimeout time.Duration

	// Write timeout
	WriteTimeout time.Duration
}

ConnOptions defines how the proxy should behave

type CopyIO

type CopyIO struct {
	// contains filtered or unexported fields
}

CopyIO extends upon io.Copy but with added support to Read and Write deadline

func NewCopyIO

func NewCopyIO() *CopyIO

func (*CopyIO) Copy

func (cio *CopyIO) Copy(dst net.Conn, src net.Conn) (int64, error)

Copy moves data from src to dst until io.EOF Depending on the configuration, each Read and/or Write will be stamped with a expected deadline before it should complete

func (*CopyIO) CopyBuffer

func (cio *CopyIO) CopyBuffer(dst net.Conn, src net.Conn, buf []byte) (int64, error)

CopyBuffer moves data from src to dst until io.EOF using the buffer provided by caller Depending on the configuration, each Read and/or Write will be stamped with a expected deadline before it should complete

func (*CopyIO) ReadDeadline

func (cio *CopyIO) ReadDeadline(d time.Duration)

ReadDeadline sets the duration to deadline from time of Read

func (*CopyIO) WriteDeadline

func (cio *CopyIO) WriteDeadline(d time.Duration)

ReadDeadline sets the duration to deadline from time of Write

type DiscOptions

type DiscOptions struct {
	// Service key to registered host
	Service string

	// Discovery host netloc
	Endpoints []string

	// etcd index for event propagation
	// See https://godoc.org/github.com/coreos/etcd/client#WatcherOptions
	AfterIndex uint64
}

type TLSConfig

type TLSConfig struct {
	// If non nil Client enables sending of TLS encrypted data
	Client *tls.Config

	// If non nil Server enables receiving TLS encrypted data
	Server *tls.Config
}

Jump to

Keyboard shortcuts

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