connect

package
v0.0.0-...-8fa2440 Latest Latest
Warning

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

Go to latest
Published: Oct 11, 2016 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package connect provides functions for connecting to services using SRV records, TLS, etc.

Connection Method Description String

A connection method descripton string consists of a series of application name descriptors, which correspond to a scheme specified in an URL.

XALPHA = ALPHA / "_" / "-"
NAME = XALPHA *(XALPHA / DIGIT)
NZDIGIT = %x31-39
port = NZDIGIT *DIGIT
PALPHA = XALPHA / "+"
PNAME = ALPHA *(PALPHA / DIGIT)

cmds = app *(1*SP app)

app  = PNAME "=" [meta_method ";"] *(method ";") method
method = conn_method / "fail"
meta_method = "@" app_name
conn_method = (app_proto_name / port) [implicit_method] explicit_method
implicit_method = "$" implicit_method_name
explicit_method = "+" explicit_method_name

app_proto_name = NAME
app_name = NAME

implicit_method_name = "tls" / "zmq"
  // (all allocated security method names shall also match NAME)
explicit_method_name = "tcp" / "udp" / "sctp"
  // (all allocated security method names shall also match NAME)

The principal difference between implicit methods and explicit methods is that implicit methods are not used in the DNS SRV hierarchy. Always use the method name sigil specified above for a given method name.

Meta methods support the following lookup convention to correct for deficiencies in the design of the DNS SRV system:

DNS SRV looks up *application protocol name/transport protocol name* pairs. However what we really want to look up is an *application/service name*, which may be provided via many different *application and transport protocols*. (For example, the World Wide Web service may run over HTTP or SPDY, so there is a distinction between the WWW service and HTTP, which is a specific means of realisation.)

In order to correct this shortcoming, the following scheme is proposed:

An application/service name is looked up by prepending an underscore to the service name, then appending "._svc." followed by the domain name, and doing a lookup for PTR records. Each PTR record, if present, will point to a DNS SRV record name. For example:

_www._svc  IN PTR  _spdys._tcp
_www._svc  IN PTR  _https._tcp
_www._svc  IN PTR  _http._tcp

_spdys._tcp IN SRV ...
_https._tcp IN SRV ...
_http._tcp  IN SRV ...

Because PTR records cannot be used to express a preference, the preference of each protocol is determined by the application. This is desirable anyway.

Examples:

"www=https$tls+tcp;http+tcp;443$tls+tcp;80+tcp"
Meaning:
  To connect to an URL of scheme www, first try SRV at _https._tcp and use
  TLS. Failing that, try SRV at _http._tcp, plain TCP. Failing that, try a
  direct connection to the hostname on port 443 using TLS and TCP. Failing
  that, try a direct connection to the hostname on port 80 using TCP.
  Failing that, fail.

"www=@www;spdy$tls+tcp;https$tls+tcp;http+tcp;443$tls+tcp;80+tcp"
Meaning:
  As above, but the PTR lookup scheme above is done for the service name
  "www". The results are used to crop the SRV lookup methods specified.
  SRV methods specified in the PTR results but not in the CMDS will not be
  used.

If an URL is specified with a port, this is interpreted using the last method specified in the CMDS for that scheme. The port number specified in the method is substituted for the port number specified by the user. Thus when a port number is specified it customizes the last method entry. If the last method entry does not name a port, connection fails; the URL cannot be used with an explicitly specified port.

Connection fails implicitly when the end of the method list is reached. However failure can also be specified explicitly using the "fail" method. This is useful if a different method should be used when a port is explicitly specified, as explicit port specification always customizes the last entry, even if it is after a fail method. If fail is specified as the last entry, explicit port specification is not possible, because explicit port specification can only occur when the last entry names a port.

All SRV and PTR methods fail when an IP address is specified. In some cases failure of a SRV method may result in execution of the methods not continuing, e.g. when a non-zero number of SRV records exists for a method but connection to all of them fails.

Currently not implemented: _svc, ZMQ, SCTP.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Connect

func Connect(urlString string, cfg Config) (io.Closer, error)

This connects to an URL using the information specified in Config. It's like Dial on steroids. It can automatically do SRV lookups and fallback to a conventional hostname lookup as appropriate. It can also automatically wrap the connection in TLS.

The connection process is primarily controlled via a Connection Method Description String, which describes how to connect to various URL schemes.

func ConnectConn

func ConnectConn(urlString string, cfg Config) (net.Conn, error)

func ConnectFrame

func ConnectFrame(urlString string, cfg Config) (bsda.FrameReadWriterCloser, error)

func RegisterMethod

func RegisterMethod(name string, implicit bool, f MethodFunc)

Registers a connection method function.

For implicit methods, a function will be called once a connection has been established. The function can then wrap the connection as it wishes, and should return the wrapped connection.

For explicit methods, the net.Conn passed will be nil. The method function should initiate a connection and return net.Conn or an error, using the information passed in MethodInfo, particularly NetAddress.

Types

type Config

type Config struct {
	// The connection method description string.
	MethodDescriptor string

	// If nil, a zero net.Dialer is used.
	Dialer Dialer

	// Method-specific information.
	//
	// Items for known methods:
	//
	//   "tls": *tls.Config.
	//     If not set, a zero value will be used.
	//     If ServerName is not set, a default will be used.
	//
	//   "curvecp": *curvecp.Config.
	//     If client private key is not set, a random one will be generated.
	//     Server key must be set in config or failing that, in URL.
	//
	//   "ws-headers": http.Header.
	//     Websocket request headers.
	//
	Pragma map[string]interface{}
}

Connection configuration information.

type Dialer

type Dialer interface {
	Dial(network, addr string) (net.Conn, error)
}

A dialer used to make underlying network connections.

type MethodFunc

type MethodFunc func(conn io.Closer, info *MethodInfo) (io.Closer, error)

type MethodInfo

type MethodInfo struct {
	// Method-specific information. Shared between all methods.
	Pragma map[string]interface{}

	// The logical hostname, suitable for use with e.g. TLS for server name
	// validation.
	Hostname string

	// The actual hostname:port or IP:port string. For explicit methods, this
	// is used to create the connection.
	NetAddress string

	// The connection URL.
	URL *url.URL
}

Information passed to a method function.

type WSFrameAdaptor

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

func NewWSFrameAdaptor

func NewWSFrameAdaptor(ws *websocket.Conn, req *http.Request, res *http.Response) *WSFrameAdaptor

func (*WSFrameAdaptor) Close

func (a *WSFrameAdaptor) Close() error

func (*WSFrameAdaptor) ReadFrame

func (a *WSFrameAdaptor) ReadFrame() ([]byte, error)

func (*WSFrameAdaptor) WSHTTPRequest

func (a *WSFrameAdaptor) WSHTTPRequest() *http.Request

func (*WSFrameAdaptor) WSHTTPResponse

func (a *WSFrameAdaptor) WSHTTPResponse() *http.Response

func (*WSFrameAdaptor) WSUnderlying

func (a *WSFrameAdaptor) WSUnderlying() *websocket.Conn

func (*WSFrameAdaptor) WriteFrame

func (a *WSFrameAdaptor) WriteFrame(b []byte) error

Jump to

Keyboard shortcuts

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