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 }