github.com/gdamore/mangos@v1.4.0/transport.go (about)

     1  // Copyright 2016 The Mangos Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use file except in compliance with the License.
     5  // You may obtain a copy of the license at
     6  //
     7  //    http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package mangos
    16  
    17  import (
    18  	"net"
    19  	"strings"
    20  )
    21  
    22  // Pipe behaves like a full-duplex message-oriented connection between two
    23  // peers.  Callers may call operations on a Pipe simultaneously from
    24  // different goroutines.  (These are different from net.Conn because they
    25  // provide message oriented semantics.)
    26  //
    27  // Pipe is only intended for use by transport implementors, and should
    28  // not be directly used in applications.
    29  type Pipe interface {
    30  
    31  	// Send sends a complete message.  In the event of a partial send,
    32  	// the Pipe will be closed, and an error is returned.  For reasons
    33  	// of efficiency, we allow the message to be sent in a scatter/gather
    34  	// list.
    35  	Send(*Message) error
    36  
    37  	// Recv receives a complete message.  In the event that either a
    38  	// complete message could not be received, an error is returned
    39  	// to the caller and the Pipe is closed.
    40  	//
    41  	// To mitigate Denial-of-Service attacks, we limit the max message
    42  	// size to 1M.
    43  	Recv() (*Message, error)
    44  
    45  	// Close closes the underlying transport.  Further operations on
    46  	// the Pipe will result in errors.  Note that messages that are
    47  	// queued in transport buffers may still be received by the remote
    48  	// peer.
    49  	Close() error
    50  
    51  	// LocalProtocol returns the 16-bit SP protocol number used by the
    52  	// local side.  This will normally be sent to the peer during
    53  	// connection establishment.
    54  	LocalProtocol() uint16
    55  
    56  	// RemoteProtocol returns the 16-bit SP protocol number used by the
    57  	// remote side.  This will normally be received from the peer during
    58  	// connection establishment.
    59  	RemoteProtocol() uint16
    60  
    61  	// IsOpen returns true if the underlying connection is open.
    62  	IsOpen() bool
    63  
    64  	// GetProp returns an arbitrary transport specific property.
    65  	// These are like options, but are read-only and specific to a single
    66  	// connection.  If the property doesn't exist, then ErrBadProperty
    67  	// should be returned.
    68  	GetProp(string) (interface{}, error)
    69  }
    70  
    71  // PipeDialer represents the client side of a connection.  Clients initiate
    72  // the connection.
    73  //
    74  // PipeDialer is only intended for use by transport implementors, and should
    75  // not be directly used in applications.
    76  type PipeDialer interface {
    77  	// Dial is used to initiate a connection to a remote peer.
    78  	Dial() (Pipe, error)
    79  
    80  	// SetOption sets a local option on the dialer.
    81  	// ErrBadOption can be returned for unrecognized options.
    82  	// ErrBadValue can be returned for incorrect value types.
    83  	SetOption(name string, value interface{}) error
    84  
    85  	// GetOption gets a local option from the dialer.
    86  	// ErrBadOption can be returned for unrecognized options.
    87  	GetOption(name string) (value interface{}, err error)
    88  }
    89  
    90  // PipeListener represents the server side of a connection.  Servers respond
    91  // to a connection request from clients.
    92  //
    93  // PipeListener is only intended for use by transport implementors, and should
    94  // not be directly used in applications.
    95  type PipeListener interface {
    96  
    97  	// Listen actually begins listening on the interface.  It is
    98  	// called just prior to the Accept() routine normally. It is
    99  	// the socket equivalent of bind()+listen().
   100  	Listen() error
   101  
   102  	// Accept completes the server side of a connection.  Once the
   103  	// connection is established and initial handshaking is complete,
   104  	// the resulting connection is returned to the client.
   105  	Accept() (Pipe, error)
   106  
   107  	// Close ceases any listening activity, and will specifically close
   108  	// any underlying file descriptor.  Once this is done, the only way
   109  	// to resume listening is to create a new Server instance.  Presumably
   110  	// this function is only called when the last reference to the server
   111  	// is about to go away.  Established connections are unaffected.
   112  	Close() error
   113  
   114  	// SetOption sets a local option on the listener.
   115  	// ErrBadOption can be returned for unrecognized options.
   116  	// ErrBadValue can be returned for incorrect value types.
   117  	SetOption(name string, value interface{}) error
   118  
   119  	// GetOption gets a local option from the listener.
   120  	// ErrBadOption can be returned for unrecognized options.
   121  	GetOption(name string) (value interface{}, err error)
   122  
   123  	// Address gets the local address.  The value may not be meaningful
   124  	// until Listen() has been called.
   125  	Address() string
   126  }
   127  
   128  // Transport is the interface for transport suppliers to implement.
   129  type Transport interface {
   130  	// Scheme returns a string used as the prefix for SP "addresses".
   131  	// This is similar to a URI scheme.  For example, schemes can be
   132  	// "tcp" (for "tcp://xxx..."), "ipc", "inproc", etc.
   133  	Scheme() string
   134  
   135  	// NewDialer creates a new Dialer for this Transport.
   136  	NewDialer(url string, sock Socket) (PipeDialer, error)
   137  
   138  	// NewListener creates a new PipeListener for this Transport.
   139  	// This generally also arranges for an OS-level file descriptor to be
   140  	// opened, and bound to the the given address, as well as establishing
   141  	// any "listen" backlog.
   142  	NewListener(url string, sock Socket) (PipeListener, error)
   143  }
   144  
   145  // StripScheme removes the leading scheme (such as "http://") from an address
   146  // string.  This is mostly a utility for benefit of transport providers.
   147  func StripScheme(t Transport, addr string) (string, error) {
   148  	if !strings.HasPrefix(addr, t.Scheme()+"://") {
   149  		return addr, ErrBadTran
   150  	}
   151  	return addr[len(t.Scheme()+"://"):], nil
   152  }
   153  
   154  // ResolveTCPAddr is like net.ResolveTCPAddr, but it handles the
   155  // wildcard used in nanomsg URLs, replacing it with an empty
   156  // string to indicate that all local interfaces be used.
   157  func ResolveTCPAddr(addr string) (*net.TCPAddr, error) {
   158  	if strings.HasPrefix(addr, "*") {
   159  		addr = addr[1:]
   160  	}
   161  	return net.ResolveTCPAddr("tcp", addr)
   162  }