Documentation ¶
Index ¶
- Constants
- Variables
- func Base36toBigInt(a []byte) (*big.Int, []byte, error)
- func BigIntToBase36(val *big.Int) ([]byte, string)
- func BytesToSerial(p []byte) int64
- func CheckSha1HMAC(message, messageMAC, key []byte) bool
- func CheckSha256HMAC(message, messageMAC, key []byte) bool
- func EncodeBytesBase36(by []byte) []byte
- func FetchUrl(url string) ([]byte, error)
- func GenAddress() string
- func GenPelicanKey() []byte
- func GenPelicanKeyString() string
- func GetAvailPort() int
- func GetExternalIP() string
- func GetExternalIPAsInt() int
- func IsAlphaBase36(ru []rune) bool
- func IsLegitPelicanKey(alpha_signed_key []byte) bool
- func IsRoutableIPv4(ip string) bool
- func IsTimeout(err error) bool
- func NewTunnelPacket(reqSer int64, respSer int64, key string) *tunnelPacket
- func NewTunnelPacketFromPpReq(ppReq *PelicanPacket) *tunnelPacket
- func ParseRequestHeader(header []byte) (key []byte, ser int64)
- func PollExpecting(desc string, toHold func() bool, within time.Duration) bool
- func PortIsBound(addr string) bool
- func RandBytes(n int) []byte
- func SerialToBytes(serialNum int64) []byte
- func SetChaserConfigDefaults(cfg *ChaserConfig)
- func Sha1HMAC(message, key []byte) []byte
- func Sha256HMAC(message, key []byte) []byte
- func SplitOutHostFromUrl(url string) (suffix string, err error)
- func StripNanomsgAddressPrefix(nanomsgAddr string) (suffix string, err error)
- func TSPrintf(format string, a ...interface{})
- func VPrintf(format string, a ...interface{})
- func WaitUntilServerDown(addr string)
- func WaitUntilServerUp(addr string)
- type Addr
- type BcastClient
- type BcastServer
- type Chaser
- func (s *Chaser) DoRequestResponse(work []byte, urlPath string) (back []byte, recvSerial int64, err error)
- func (r *Chaser) NoteTmRecv()
- func (r *Chaser) NoteTmSent()
- func (s *Chaser) RequestStop() bool
- func (s *Chaser) ResetActiveTimer()
- func (r *Chaser) ShowTmHistory()
- func (s *Chaser) Start()
- func (s *Chaser) Stop()
- func (s *Chaser) StopWithoutReporting()
- type ChaserConfig
- type ClientHome
- type ClientRW
- func (s *ClientRW) Close()
- func (s *ClientRW) IsDone() bool
- func (s *ClientRW) RecvCh() chan []byte
- func (s *ClientRW) RecvFromDownCh() chan []byte
- func (s *ClientRW) SendCh() chan []byte
- func (s *ClientRW) SendToDownCh() chan []byte
- func (s *ClientRW) Start()
- func (s *ClientRW) Stop()
- func (s *ClientRW) StopWithoutNotify()
- type CountingTestClient
- func (cli *CountingTestClient) Expect(msg string) bool
- func (r *CountingTestClient) IsStopRequested() bool
- func (cli *CountingTestClient) LastMsgReceived() string
- func (r *CountingTestClient) NoteTmRecv()
- func (r *CountingTestClient) NoteTmSent()
- func (s *CountingTestClient) RequestStop() bool
- func (r *CountingTestClient) ShowTmHistory()
- func (cli *CountingTestClient) Start()
- func (r *CountingTestClient) Stop()
- func (cli *CountingTestClient) WaitForMsg() string
- type CountingTestServer
- func (r *CountingTestServer) IsStopRequested() bool
- func (r *CountingTestServer) Nonecho(msg string)
- func (r *CountingTestServer) NoteTmRecv()
- func (r *CountingTestServer) NoteTmSent()
- func (s *CountingTestServer) RequestStop() bool
- func (r *CountingTestServer) ShowTmHistory()
- func (r *CountingTestServer) Start() error
- func (r *CountingTestServer) Stop()
- type CustomHttpServer
- func (s *CustomHttpServer) CA(ca string) error
- func (s *CustomHttpServer) ClientCA(ca string) error
- func (s *CustomHttpServer) Close() error
- func (s *CustomHttpServer) ListenAndServe() error
- func (s *CustomHttpServer) ListenAndServeTLS(cert, key string) error
- func (s *CustomHttpServer) Serve(l net.Listener) error
- func (s *CustomHttpServer) TLS(cert, key string) error
- type EchoServer
- type HistoryLog
- type HttpClientWithTimeout
- func (s *HttpClientWithTimeout) CancelAllReq()
- func (s *HttpClientWithTimeout) CloseIdleConnections()
- func (s *HttpClientWithTimeout) NumDials() int64
- func (s *HttpClientWithTimeout) Post(url string, contentType string, body *bytes.Buffer) (*http.Response, error)
- func (s *HttpClientWithTimeout) SetConnectTimeout(duration time.Duration)
- type Log
- type LongPoller
- type LongPollerConfig
- type MockResponseWriter
- type NetConnReader
- func (r *NetConnReader) IsDone() bool
- func (r *NetConnReader) IsStopRequested() bool
- func (s *NetConnReader) RecvFromDownCh() chan []byte
- func (s *NetConnReader) RequestStop() bool
- func (s *NetConnReader) Start()
- func (s *NetConnReader) Stop()
- func (s *NetConnReader) StopAndNotify()
- func (s *NetConnReader) StopWithoutNotify()
- type NetConnWriter
- func (r *NetConnWriter) IsDone() bool
- func (r *NetConnWriter) IsStopRequested() bool
- func (s *NetConnWriter) RequestStop() bool
- func (s *NetConnWriter) SendToDownCh() chan []byte
- func (s *NetConnWriter) Start()
- func (s *NetConnWriter) Stop()
- func (s *NetConnWriter) StopAndNotify()
- func (s *NetConnWriter) StopWithoutNotify()
- type PelicanSocksProxy
- func (f *PelicanSocksProxy) ConnectDownstreamHttp() (string, error)
- func (f *PelicanSocksProxy) CountOfOpenClients() int
- func (f *PelicanSocksProxy) LastRemote() (net.Addr, error)
- func (s *PelicanSocksProxy) RequestStop() bool
- func (f *PelicanSocksProxy) SetDefault()
- func (f *PelicanSocksProxy) Start() error
- func (f *PelicanSocksProxy) Stop()
- func (f *PelicanSocksProxy) WaitForClientCount(target int, maxElap time.Duration) error
- type PelicanSocksProxyConfig
- type RequestFifo
- type ReverseProxy
- type ReverseProxyConfig
- type ServerRW
- func (s *ServerRW) Close()
- func (s *ServerRW) IsDone() bool
- func (s *ServerRW) RecvCh() chan []byte
- func (s *ServerRW) RecvFromDownCh() chan []byte
- func (s *ServerRW) SendCh() chan []byte
- func (s *ServerRW) SendToDownCh() chan []byte
- func (s *ServerRW) Start()
- func (s *ServerRW) Stop()
- func (s *ServerRW) StopWithoutNotify()
- type Shovel
- type ShovelPair
- type TcpUpstreamReceiver
- type TimeoutTransport
- type WebServer
- type WebServerConfig
Constants ¶
const Alpha who = 1
const Beta who = 2
const Both who = 3
const DefaultWebReadTimeout time.Duration = 60e9
const HeaderLen = KeyLen + SerialLen
const KeyLen = 149
const NetConnReaderDefaultBufSizeBytes = 1 * 1024 * 1024
NetConnReaderDefaultBufSizeBytes declares the default read buffer size. It may be overriden in the call to NewNetConnReader by setting the bufsz parameter.
const SerialLen = 8
const ShovelInternalBufSize = 256 << 10
Internally buffer ShovelInternalBufSize bytes. Currently we use 256K byte internal buffers.
const Verbose bool = false
for debug output var Verbose bool = true
Variables ¶
var ReverseProxyIp string = ""
var ReverseProxyPort int = 8888
var TempDisablePortIsBoundChecks bool = true
Functions ¶
func Base36toBigInt ¶
inverse of BigIntToBase36. the []byte return argument is padded on the left with zeros to reach the largest possible big.Int number for len(a) bytes.
func BigIntToBase36 ¶
returns both a []byte and a string encoding of the bigInt val using only a-z0-9 characters. Assumes a positive bigInt val. Negative val results are undefined.
func BytesToSerial ¶
func CheckSha1HMAC ¶
CheckMAC returns true if messageMAC is a valid HMAC tag for message.
func CheckSha256HMAC ¶
CheckMAC returns true if messageMAC is a valid HMAC tag for message.
func EncodeBytesBase36 ¶
func GenAddress ¶
func GenAddress() string
GenAddress generates a local address by calling GetAvailPort() and GetExternalIP(), then prefixing them with 'tcp://'.
func GenPelicanKey ¶
func GenPelicanKey() []byte
func GenPelicanKeyString ¶
func GenPelicanKeyString() string
func GetAvailPort ¶
func GetAvailPort() int
GetAvailPort asks the OS for an unused port. There's a race here, where the port could be grabbed by someone else before the caller gets to Listen on it, but in practice such races are rare. Uses net.Listen("tcp", ":0") to determine a free port, then releases it back to the OS with Listener.Close().
func GetExternalIP ¶
func GetExternalIP() string
GetExternalIP tries to determine the external IP address used on this host.
func GetExternalIPAsInt ¶
func GetExternalIPAsInt() int
GetExternalIPAsInt calls GetExternalIP() and then converts the resulting IPv4 string into an integer.
func IsAlphaBase36 ¶
check to see if all runes are in the enc36 range
func IsLegitPelicanKey ¶
func IsRoutableIPv4 ¶
IsRoutableIPv4 returns true if the string in ip represents an IPv4 address that is not private. See http://en.wikipedia.org/wiki/Private_network#Private_IPv4_address_spaces for the numeric ranges that are private. 127.0.0.1, 192.168.0.1, and 172.16.0.1 are examples of non-routables IP addresses.
func NewTunnelPacket ¶
func NewTunnelPacketFromPpReq ¶
func NewTunnelPacketFromPpReq(ppReq *PelicanPacket) *tunnelPacket
func ParseRequestHeader ¶
the sequence number is the request sequence going from client -> server,
func PollExpecting ¶
poll up to 'within' time, every 20 milliseconds, for the predicate 'toHold'. If it does not hold, panic. Else return true.
func PortIsBound ¶
func SerialToBytes ¶
func SetChaserConfigDefaults ¶
func SetChaserConfigDefaults(cfg *ChaserConfig)
func Sha256HMAC ¶
func SplitOutHostFromUrl ¶
SplitOutHostFromUrl() returns the host, given a url of form host:port/blah.
func StripNanomsgAddressPrefix ¶
StripNanomsgAddressPrefix removes the 'tcp://' prefix from nanomsgAddr.
func VPrintf ¶
func VPrintf(format string, a ...interface{})
print debug/status conditionally on having Verbose on
func WaitUntilServerDown ¶
func WaitUntilServerDown(addr string)
func WaitUntilServerUp ¶
func WaitUntilServerUp(addr string)
Types ¶
type Addr ¶
func NewAddr1panicOnError ¶
type BcastClient ¶
type BcastClient struct { Dest Addr Ready chan bool Done chan bool MsgRecvd chan bool // contains filtered or unexported fields }
BcastClient long polls for a single message.
func NewBcastClient ¶
func NewBcastClient(dest Addr) *BcastClient
func (*BcastClient) Expect ¶
func (cli *BcastClient) Expect(msg string) bool
func (*BcastClient) IsStopRequested ¶
func (r *BcastClient) IsStopRequested() bool
func (*BcastClient) LastMsgReceived ¶
func (cli *BcastClient) LastMsgReceived() string
func (*BcastClient) RequestStop ¶
func (s *BcastClient) RequestStop() bool
RequestStop makes sure we only close the s.reqStop channel once. Returns true iff we closed s.reqStop on this call.
func (*BcastClient) Start ¶
func (cli *BcastClient) Start()
func (*BcastClient) Stop ¶
func (r *BcastClient) Stop()
func (*BcastClient) WaitForMsg ¶
func (cli *BcastClient) WaitForMsg() string
type BcastServer ¶
type BcastServer struct { Listen Addr Ready chan bool Done chan bool FirstClient chan bool SecondClient chan bool FirstHelloClient chan bool // actual bcast_cliet will start with hello. then close this. // contains filtered or unexported fields }
BcastServer accumulates clients and then on queue (Bcast() call)
sends the same message to all waiting clients. This simulates long polling.
func NewBcastServer ¶
func NewBcastServer(a Addr) *BcastServer
func (*BcastServer) Bcast ¶
func (r *BcastServer) Bcast(msg string)
func (*BcastServer) CloseClientConnections ¶
func (r *BcastServer) CloseClientConnections()
func (*BcastServer) IsStopRequested ¶
func (r *BcastServer) IsStopRequested() bool
func (*BcastServer) RequestStop ¶
func (s *BcastServer) RequestStop() bool
RequestStop makes sure we only close the s.reqStop channel once. Returns true iff we closed s.reqStop on this call.
func (*BcastServer) Start ¶
func (r *BcastServer) Start() error
func (*BcastServer) Stop ¶
func (r *BcastServer) Stop()
type Chaser ¶
type Chaser struct { Done chan bool // contains filtered or unexported fields }
Similar in spirit to Comet, Ajax-long-polling, and BOSH (http://en.wikipedia.org/wiki/BOSH), the following struct and methods for Chaser comprises the two-socket (two http transactions open at most at once) long-polling implementation for the client (pelican socks proxy) end. See tunnel.go and LongPoller for server side.
The story: alpha and beta are a pair of room-mates who hate to be home together. They represent our two possible http request-response sockets. The job of Chaser is to figure out when to initiate an http request.
If alpha arrives home and beta is present, alpha kicks out beta and beta goes on a data retrieval mission. Even without data on the request, this mission allows the server to initiate data send by delaying the reply to the request for some time until data becomes available to send.
When beta gets back if alpha is home, alpha is forced to go himself on a data retrieval mission.
If they both find themselves at home at once, then the tie is arbitrarily broken and alpha goes (hence the name, 'alpha').
In this way we implement the ping-pong of long-polling. Within the constraints of only having two http connections open, each party can send whenever they so desire, with as low latency as we can muster within the constraints of only using two http connections and the given traffic profile of pauses on either end.
The actual logic is implemented in Home, which has its own goroutine. The startAlpha() and startBeta() methods each start their own goroutines respectively, and the three communicate over the channels held in Chaser and Home.
See also the diagram in tunnel.go in front of the LongPoller struct description.
func (*Chaser) DoRequestResponse ¶
func (s *Chaser) DoRequestResponse(work []byte, urlPath string) (back []byte, recvSerial int64, err error)
DoRequestResponse(): issue a post to the urlPath (omit the leading slash! deault to ""), submitting 'work', returning 'back' and any error. the urlPath should normally be "", but can be "closekey" to tell the server to return any outstanding request for key immediately and to shutdown the downstream connection to target server. We don't want to actually close the actual physical net.Conn because other keys/clients can re-use it for other/on-going work. Indeed it might be in use right now for another key's packets.
func (*Chaser) NoteTmRecv ¶
func (r *Chaser) NoteTmRecv()
func (*Chaser) NoteTmSent ¶
func (r *Chaser) NoteTmSent()
func (*Chaser) RequestStop ¶
RequestStop makes sure we only close the s.reqStop channel once. Returns true iff we closed s.reqStop on this call.
func (*Chaser) ResetActiveTimer ¶
func (s *Chaser) ResetActiveTimer()
func (*Chaser) ShowTmHistory ¶
func (r *Chaser) ShowTmHistory()
func (*Chaser) StopWithoutReporting ¶
func (s *Chaser) StopWithoutReporting()
Stops without reporting anything on the notifyDone channel passed to NewChaser().
type ChaserConfig ¶
type ChaserConfig struct { ConnectTimeout time.Duration TransportTimeout time.Duration BufSize int ShutdownInactiveDur time.Duration }
func DefaultChaserConfig ¶
func DefaultChaserConfig() *ChaserConfig
type ClientHome ¶
type ClientHome struct { Done chan bool IsAlphaHome chan bool IsBetaHome chan bool // contains filtered or unexported fields }
func NewClientHome ¶
func NewClientHome() *ClientHome
func (*ClientHome) RequestStop ¶
func (s *ClientHome) RequestStop() bool
RequestStop makes sure we only close the s.reqStop channel once. Returns true iff we closed s.reqStop on this call.
func (*ClientHome) Start ¶
func (s *ClientHome) Start()
func (*ClientHome) Stop ¶
func (s *ClientHome) Stop()
func (*ClientHome) String ¶
func (s *ClientHome) String() string
type ClientRW ¶
type ClientRW struct {
// contains filtered or unexported fields
}
===========================================
ClientRW
===========================================
RW packages up a reader and a writer for a specific net.Conn connection along with a copy of that net connection.
The NetConnReader and the NetConnWriter work as a pair to move data from a net.Conn into the corresponding channels supplied by SendCh() and RecvCh() for access to the connection via channels/goroutines.
func NewClientRW ¶
func NewClientRW(name string, netconn net.Conn, bufsz int, notifyReaderDone chan *NetConnReader, notifyWriterDone chan *NetConnWriter) *ClientRW
make a new RW, passing bufsz to NewNetConnReader(). If the notifyWriterDone and/or notifyReaderDone channels are not nil, then they will receive a pointer to the NetConnReader (NetConnWriter) at Stop() time.
func (*ClientRW) Close ¶
func (s *ClientRW) Close()
Close is the same as Stop(). Both shutdown the running ClientRW service. Start must have been called first.
func (*ClientRW) RecvFromDownCh ¶
func (*ClientRW) SendToDownCh ¶
func (*ClientRW) Stop ¶
func (s *ClientRW) Stop()
Stop the ClientRW service. Start must be called prior to Stop.
func (*ClientRW) StopWithoutNotify ¶
func (s *ClientRW) StopWithoutNotify()
type CountingTestClient ¶
type CountingTestClient struct { Dest Addr Ready chan bool Done chan bool MsgRecvd chan string // contains filtered or unexported fields }
func NewCountingTestClient ¶
func NewCountingTestClient(dest Addr) *CountingTestClient
func (*CountingTestClient) Expect ¶
func (cli *CountingTestClient) Expect(msg string) bool
func (*CountingTestClient) IsStopRequested ¶
func (r *CountingTestClient) IsStopRequested() bool
func (*CountingTestClient) LastMsgReceived ¶
func (cli *CountingTestClient) LastMsgReceived() string
func (*CountingTestClient) NoteTmRecv ¶
func (r *CountingTestClient) NoteTmRecv()
func (*CountingTestClient) NoteTmSent ¶
func (r *CountingTestClient) NoteTmSent()
func (*CountingTestClient) RequestStop ¶
func (s *CountingTestClient) RequestStop() bool
RequestStop makes sure we only close the s.reqStop channel once. Returns true iff we closed s.reqStop on this call.
func (*CountingTestClient) ShowTmHistory ¶
func (r *CountingTestClient) ShowTmHistory()
func (*CountingTestClient) Start ¶
func (cli *CountingTestClient) Start()
func (*CountingTestClient) Stop ¶
func (r *CountingTestClient) Stop()
func (*CountingTestClient) WaitForMsg ¶
func (cli *CountingTestClient) WaitForMsg() string
type CountingTestServer ¶
type CountingTestServer struct { Listen Addr Ready chan bool Done chan bool FirstClient chan bool FirstCountingClientSeen chan bool // contains filtered or unexported fields }
func NewCountingTestServer ¶
func NewCountingTestServer(a Addr) *CountingTestServer
func (*CountingTestServer) IsStopRequested ¶
func (r *CountingTestServer) IsStopRequested() bool
func (*CountingTestServer) Nonecho ¶
func (r *CountingTestServer) Nonecho(msg string)
func (*CountingTestServer) NoteTmRecv ¶
func (r *CountingTestServer) NoteTmRecv()
func (*CountingTestServer) NoteTmSent ¶
func (r *CountingTestServer) NoteTmSent()
func (*CountingTestServer) RequestStop ¶
func (s *CountingTestServer) RequestStop() bool
RequestStop makes sure we only close the s.reqStop channel once. Returns true iff we closed s.reqStop on this call.
func (*CountingTestServer) ShowTmHistory ¶
func (r *CountingTestServer) ShowTmHistory()
func (*CountingTestServer) Start ¶
func (r *CountingTestServer) Start() error
func (*CountingTestServer) Stop ¶
func (r *CountingTestServer) Stop()
type CustomHttpServer ¶
CustomHttpServer is an http.Server with better defaults and built-in graceful stop.
func NewCustomHttpServer ¶
func NewCustomHttpServer(addr string, handler http.Handler, readTimeout time.Duration) *CustomHttpServer
NewCustomHttpServer returns an http.Server with better defaults and built-in graceful stop. Default for readTimeout could be 60 * time.Second, or as you need.
func NewTLSServer ¶
func NewTLSServer( addr, cert, key string, handler http.Handler, ) (*CustomHttpServer, error)
NewTLSServer returns an http.Server with better defaults configured to use the certificate and private key files.
func (*CustomHttpServer) CA ¶
func (s *CustomHttpServer) CA(ca string) error
CA overrides the certificate authority on the CustomHttpServer's TLSConfig field.
func (*CustomHttpServer) ClientCA ¶
func (s *CustomHttpServer) ClientCA(ca string) error
ClientCA configures the CA pool for verifying client side certificates.
func (*CustomHttpServer) Close ¶
func (s *CustomHttpServer) Close() error
Close closes all the net.Listeners passed to Serve (even via ListenAndServe) and signals open connections to close at their earliest convenience. That is either after responding to the current request or after a short grace period for idle keepalive connections. Close blocks until all connections have been closed.
func (*CustomHttpServer) ListenAndServe ¶
func (s *CustomHttpServer) ListenAndServe() error
ListenAndServe calls net.Listen with s.Addr and then calls s.Serve.
func (*CustomHttpServer) ListenAndServeTLS ¶
func (s *CustomHttpServer) ListenAndServeTLS(cert, key string) error
ListenAndServeTLS calls s.TLS with the given certificate and private key files and then calls s.ListenAndServe.
func (*CustomHttpServer) Serve ¶
func (s *CustomHttpServer) Serve(l net.Listener) error
Serve behaves like http.Server.Serve with the added option to stop the Server gracefully with the s.Close method.
func (*CustomHttpServer) TLS ¶
func (s *CustomHttpServer) TLS(cert, key string) error
TLS configures this Server to be a TLS server using the given certificate and private key files.
type EchoServer ¶
type EchoServer struct { Listen Addr Ready chan bool Done chan bool FirstClient chan bool // contains filtered or unexported fields }
func NewEchoServer ¶
func NewEchoServer(a Addr) *EchoServer
func (*EchoServer) IsStopRequested ¶
func (r *EchoServer) IsStopRequested() bool
func (*EchoServer) Nonecho ¶
func (r *EchoServer) Nonecho(msg string)
func (*EchoServer) RequestStop ¶
func (s *EchoServer) RequestStop() bool
RequestStop makes sure we only close the s.reqStop channel once. Returns true iff we closed s.reqStop on this call.
func (*EchoServer) Start ¶
func (r *EchoServer) Start() error
func (*EchoServer) Stop ¶
func (r *EchoServer) Stop()
type HistoryLog ¶
type HistoryLog struct {
// contains filtered or unexported fields
}
func NewHistoryLog ¶
func NewHistoryLog(name string) *HistoryLog
func (*HistoryLog) CountAbsorbs ¶
func (s *HistoryLog) CountAbsorbs() int
func (*HistoryLog) CountGenerates ¶
func (s *HistoryLog) CountGenerates() int
func (*HistoryLog) DeepCopy ¶
func (r *HistoryLog) DeepCopy() *HistoryLog
func (*HistoryLog) GetHistory ¶
func (r *HistoryLog) GetHistory() *HistoryLog
func (*HistoryLog) RecordAbs ¶
func (s *HistoryLog) RecordAbs(what []byte)
func (*HistoryLog) RecordGen ¶
func (s *HistoryLog) RecordGen(what []byte)
func (*HistoryLog) ShowHistory ¶
func (s *HistoryLog) ShowHistory()
type HttpClientWithTimeout ¶
func NewHttpClientWithTimeout ¶
func NewHttpClientWithTimeout(roundTo time.Duration) *HttpClientWithTimeout
func (*HttpClientWithTimeout) CancelAllReq ¶
func (s *HttpClientWithTimeout) CancelAllReq()
func (*HttpClientWithTimeout) CloseIdleConnections ¶
func (s *HttpClientWithTimeout) CloseIdleConnections()
func (*HttpClientWithTimeout) NumDials ¶
func (s *HttpClientWithTimeout) NumDials() int64
func (*HttpClientWithTimeout) SetConnectTimeout ¶
func (s *HttpClientWithTimeout) SetConnectTimeout(duration time.Duration)
could be a global, but put on http client to be clear what it affects.
type LongPoller ¶
type LongPoller struct { Done chan bool ClientPacketRecvd chan *tunnelPacket Dest Addr CloseKeyChan chan string // contains filtered or unexported fields }
A LongPoller (aka tunnel) is the server-side implementation of long-polling. We connect the http client (our pelican socks proxy) with the downstream target, typically an http server or sshd. For the client side implementation of long polling, see the file alphabeta.go and the Chaser structure and methods.
Inside the reverse proxy, the LongPoller represents a 1:1, one client to one (downstream target) server connection, if you ignore the socks-proxy and reverse-proxy in the middle. A ReverseProxy can have many LongPollers, mirroring the number of connections on the client side to the socks proxy. The key distinguishes them. The LongerPoller is where we implement the server side of the long polling.
http request flow (client initiating direction), http replies flow in the opposite direction of the arrows below.
"upstream" "downstream" V ^ e.g. web-browser e.g. web-server | ^ v |
----------------------- ------------------------- | TcpUpstreamReceiver | | net.Conn TCP connect | | | | | ^ | | v | | ServerRW | | ClientRW | | ^ | | v | http | | | | Chaser->alpha/beta->|------------>|WebServer--> LongPoller| ----------------------- -------------------------
pelican-socks-proxy pelican-reverse-proxy
func NewLongPoller ¶
func NewLongPoller(cfg LongPollerConfig) *LongPoller
Make a new LongPoller as a part of the server (ReverseProxy is the server; PelicanSocksProxy is the client).
If a CloseKeyChan receives a key, we return any associated client -> server http request immediately for that key, to facilitate quick shutdown.
func (*LongPoller) NoteTmRecv ¶
func (r *LongPoller) NoteTmRecv()
func (*LongPoller) NoteTmSent ¶
func (r *LongPoller) NoteTmSent()
func (*LongPoller) RequestStop ¶
func (s *LongPoller) RequestStop() bool
RequestStop makes sure we only close the s.reqStop channel once. Returns true iff we closed s.reqStop on this call.
func (*LongPoller) ShowTmHistory ¶
func (r *LongPoller) ShowTmHistory()
func (*LongPoller) Start ¶
func (s *LongPoller) Start() error
LongPoller::Start() implements the long-polling logic.
When a new client request comes in (2nd one), we bump any already waiting long-poll into replying to its request.
new reader ------> bumps waiting/long-polling reader & takes its place. ^ | | V ^ | | V client <-- returns to <---/
it's a closed loop track with only one goroutine per tunnel actively holding on a long poll.
There are only ever two client (http) requests outstanding at any given moment in time.
func (*LongPoller) Stop ¶
func (s *LongPoller) Stop()
type MockResponseWriter ¶
type MockResponseWriter struct {
// contains filtered or unexported fields
}
func NewMockResponseWriter ¶
func NewMockResponseWriter() *MockResponseWriter
func (*MockResponseWriter) Header ¶
func (m *MockResponseWriter) Header() http.Header
Header returns the header map that will be sent by WriteHeader. Changing the header after a call to WriteHeader (or Write) has no effect.
func (*MockResponseWriter) Write ¶
func (m *MockResponseWriter) Write(p []byte) (int, error)
Write writes the data to the connection as part of an HTTP reply. If WriteHeader has not yet been called, Write calls WriteHeader(http.StatusOK) before writing the data. If the Header does not contain a Content-Type line, Write adds a Content-Type set to the result of passing the initial 512 bytes of written data to DetectContentType.
func (*MockResponseWriter) WriteHeader ¶
func (m *MockResponseWriter) WriteHeader(status int)
WriteHeader sends an HTTP response header with status code. If WriteHeader is not called explicitly, the first call to Write will trigger an implicit WriteHeader(http.StatusOK). Thus explicit calls to WriteHeader are mainly used to send error codes.
type NetConnReader ¶
type NetConnReader struct { Done chan bool Ready chan bool LastErr error // contains filtered or unexported fields }
===========================================
NetConnReader
===========================================
NetConnReader and NetConnWriter work as a pair to move data from a net.Conn into go channels. Each maintains its own independent goroutine.
NetConnReader represents a goroutine dedicated to reading from conn and writing to the dnReadToUpWrite channel.
NetConnReader is used as the downstream most reader in the reverse proxy. It is also used as the most upstream reader in the forward (socks) proxy. Thus in the socks proxy, the dnReadToUpWrite channel should be actually called upReadToDnWrite, assuming the client is upstream and the server is downstream. Hence the names are meaningful only in the reverse proxy context.
func NewNetConnReader ¶
func NewNetConnReader( name string, netconn net.Conn, dnReadToUpWrite chan []byte, bufsz int, notifyDone chan *NetConnReader, parent *ServerRW) *NetConnReader
make a new NetConnReader. if bufsz is 0 then we default to using a buffer of size NetConnReaderDefaultBufSizeBytes.
func (*NetConnReader) IsDone ¶
func (r *NetConnReader) IsDone() bool
func (*NetConnReader) IsStopRequested ¶
func (r *NetConnReader) IsStopRequested() bool
func (*NetConnReader) RecvFromDownCh ¶
func (s *NetConnReader) RecvFromDownCh() chan []byte
return the internal s.dnReadToUpWrite channel which allows clients of NetConnReader to receive data from the downstream server.
func (*NetConnReader) RequestStop ¶
func (s *NetConnReader) RequestStop() bool
RequestStop makes sure we only close the s.reqStop channel once. Returns true iff we closed s.reqStop on this call.
func (*NetConnReader) Start ¶
func (s *NetConnReader) Start()
Start the NetConnReader. Use Stop() to shut it down.
func (*NetConnReader) Stop ¶
func (s *NetConnReader) Stop()
Stop the NetConnReader goroutine. Start() must have been called first or this will hang your program.
func (*NetConnReader) StopAndNotify ¶
func (s *NetConnReader) StopAndNotify()
Stops the reader and reports a pointer to itself on the notifyDoneCh if supplied with NewNetConnReader.
func (*NetConnReader) StopWithoutNotify ¶
func (s *NetConnReader) StopWithoutNotify()
Stop the reader without reporting on notifyDoneCh.
type NetConnWriter ¶
type NetConnWriter struct { Done chan bool Ready chan bool LastErr error // contains filtered or unexported fields }
===========================================
NetConnWriter
===========================================
NetConnWriter is the downstream most writer in the reverse proxy. It represents a goroutine dedicated to reading from UpReadToDnWrite channel and then writing conn.
func NewNetConnWriter ¶
func NewNetConnWriter(name string, netconn net.Conn, upReadToDnWrite chan []byte, notifyDone chan *NetConnWriter, parent interface{}) *NetConnWriter
make a new NetConnWriter
func (*NetConnWriter) IsDone ¶
func (r *NetConnWriter) IsDone() bool
func (*NetConnWriter) IsStopRequested ¶
func (r *NetConnWriter) IsStopRequested() bool
func (*NetConnWriter) RequestStop ¶
func (s *NetConnWriter) RequestStop() bool
RequestStop makes sure we only close the s.reqStop channel once. Returns true iff we closed s.reqStop on this call.
func (*NetConnWriter) SendToDownCh ¶
func (s *NetConnWriter) SendToDownCh() chan []byte
returns the channel on which to send data to the downstream server.
func (*NetConnWriter) Stop ¶
func (s *NetConnWriter) Stop()
Stop the NetConnWriter. Start() must have been called first or else you will hang your program waiting for s.Done to be closed.
func (*NetConnWriter) StopAndNotify ¶
func (s *NetConnWriter) StopAndNotify()
Stops the writer and reports a pointer to itself on the notifyDoneCh if supplied with NewNetConnWriter.
func (*NetConnWriter) StopWithoutNotify ¶
func (s *NetConnWriter) StopWithoutNotify()
Stop the writer without reporting on notifyDoneCh.
type PelicanSocksProxy ¶
type PelicanSocksProxy struct { Cfg PelicanSocksProxyConfig Ready chan bool Done chan bool Up *TcpUpstreamReceiver LastRemoteReq chan net.Addr OpenClientReq chan int ChaserDoneCh chan *Chaser // contains filtered or unexported fields }
func NewPelicanSocksProxy ¶
func NewPelicanSocksProxy(cfg PelicanSocksProxyConfig) *PelicanSocksProxy
func (*PelicanSocksProxy) ConnectDownstreamHttp ¶
func (f *PelicanSocksProxy) ConnectDownstreamHttp() (string, error)
func (*PelicanSocksProxy) CountOfOpenClients ¶
func (f *PelicanSocksProxy) CountOfOpenClients() int
CountOfOpenClients returns -1 if PSP is shutting down.
func (*PelicanSocksProxy) LastRemote ¶
func (f *PelicanSocksProxy) LastRemote() (net.Addr, error)
func (*PelicanSocksProxy) RequestStop ¶
func (s *PelicanSocksProxy) RequestStop() bool
RequestStop makes sure we only close the s.reqStop channel once. Returns true iff we closed s.reqStop on this call.
func (*PelicanSocksProxy) SetDefault ¶
func (f *PelicanSocksProxy) SetDefault()
func (*PelicanSocksProxy) Start ¶
func (f *PelicanSocksProxy) Start() error
func (*PelicanSocksProxy) Stop ¶
func (f *PelicanSocksProxy) Stop()
func (*PelicanSocksProxy) WaitForClientCount ¶
func (f *PelicanSocksProxy) WaitForClientCount(target int, maxElap time.Duration) error
returns nil if the open client count hits target within the maxElap time. otherwise a non-nil error is returned. Sleeps in 10 msec increments.
type PelicanSocksProxyConfig ¶
type PelicanSocksProxyConfig struct { Listen Addr Dest Addr ChaserCfg ChaserConfig // contains filtered or unexported fields }
type RequestFifo ¶
type RequestFifo struct {
// contains filtered or unexported fields
}
request queue can be empty
func NewRequestFifo ¶
func NewRequestFifo(capacity int) *RequestFifo
func (*RequestFifo) Empty ¶
func (s *RequestFifo) Empty() bool
func (*RequestFifo) Len ¶
func (s *RequestFifo) Len() int
func (*RequestFifo) PeekRight ¶
func (s *RequestFifo) PeekRight() *tunnelPacket
func (*RequestFifo) PopRight ¶
func (s *RequestFifo) PopRight() *tunnelPacket
func (*RequestFifo) PushLeft ¶
func (s *RequestFifo) PushLeft(by *tunnelPacket)
func (*RequestFifo) PushRight ¶
func (s *RequestFifo) PushRight(by *tunnelPacket)
type ReverseProxy ¶
type ReverseProxy struct { Cfg ReverseProxyConfig Done chan bool // contains filtered or unexported fields }
one ReverseProxy can contain many tunnels
func NewReverseProxy ¶
func NewReverseProxy(cfg ReverseProxyConfig) *ReverseProxy
func (*ReverseProxy) RequestStop ¶
func (s *ReverseProxy) RequestStop() bool
RequestStop makes sure we only close the s.reqStop channel once. Returns true iff we closed s.reqStop on this call.
func (*ReverseProxy) Stop ¶
func (p *ReverseProxy) Stop()
type ReverseProxyConfig ¶
type ServerRW ¶
type ServerRW struct {
// contains filtered or unexported fields
}
===========================================
ServerRW
===========================================
ServerRW packages up a reader and a writer for a specific net.Conn connection along with a copy of that net connection.
The NetConnReader and the NetConnWriter work as a pair to move data from a net.Conn into the corresponding channels supplied by SendCh() and RecvCh() for access to the connection via channels/goroutines.
func NewServerRW ¶
func NewServerRW(name string, netconn net.Conn, bufsz int, notifyReaderDone chan *NetConnReader, notifyWriterDone chan *NetConnWriter, parent *LongPoller) *ServerRW
make a new ServerRW, passing bufsz to NewNetConnReader(). If the notifyWriterDone and/or notifyReaderDone channels are not nil, then they will receive a pointer to the NetConnReader (NetConnWriter) at Stop() time.
func (*ServerRW) Close ¶
func (s *ServerRW) Close()
Close is the same as Stop(). Both shutdown the running ServerRW service. Start must have been called first.
func (*ServerRW) RecvFromDownCh ¶
func (*ServerRW) SendToDownCh ¶
func (*ServerRW) Stop ¶
func (s *ServerRW) Stop()
Stop the ServerRW service. Start must be called prior to Stop.
func (*ServerRW) StopWithoutNotify ¶
func (s *ServerRW) StopWithoutNotify()
type Shovel ¶
Shovel shovels data from an io.ReadCloser to an io.WriteCloser in an independent go routine started by Shovel::Start(). You can request that the shovel stop by calling RequestStop() and wait until Done is closed to know that it is finished.
func (*Shovel) RequestStop ¶
RequestStop makes sure we only close the s.reqStop channel once. Returns true iff we closed s.reqStop on this call.
func (*Shovel) Start ¶
func (s *Shovel) Start(w io.WriteCloser, r io.ReadCloser, label string)
Start starts the shovel doing an io.Copy from r to the internal rbuf, and from rbuf to w. The goroutine that is running the copy will close the Ready channel just before starting the io.Copy. The label parameter allows reporting on when a specific shovel was shut down.
type ShovelPair ¶
type ShovelPair struct { AB *Shovel BA *Shovel Done chan bool Ready chan bool // contains filtered or unexported fields }
a ShovelPair manages the forwarding of a bidirectional channel, such as that in forwarding an ssh connection.
func (*ShovelPair) RequestStop ¶
func (s *ShovelPair) RequestStop() bool
RequestStop makes sure we only close the s.reqStop channel once. Returns true iff we closed s.reqStop on this call.
func (*ShovelPair) Start ¶
func (s *ShovelPair) Start(a io.ReadWriteCloser, b io.ReadWriteCloser, ab_label string, ba_label string)
Start the pair of shovels. ab_label will label the a<-b shovel. ba_label will label the b<-a shovel.
func (*ShovelPair) Stop ¶
func (s *ShovelPair) Stop()
type TcpUpstreamReceiver ¶
type TcpUpstreamReceiver struct { Listen Addr UpstreamTcpConnChan chan net.Conn Ready chan bool Done chan bool // contains filtered or unexported fields }
There is one TcpUpstreamReceiver per port that the PelicanSocksProxy listens on. It blocks on the socket Accept() call so that the main goroutine of the PelicanSocksProxy doesn't have to block.
func NewTcpUpstreamReceiver ¶
func NewTcpUpstreamReceiver(a Addr) *TcpUpstreamReceiver
func (*TcpUpstreamReceiver) IsStopRequested ¶
func (r *TcpUpstreamReceiver) IsStopRequested() bool
func (*TcpUpstreamReceiver) RequestStop ¶
func (s *TcpUpstreamReceiver) RequestStop() bool
RequestStop makes sure we only close the s.reqStop channel once. Returns true iff we closed s.reqStop on this call.
func (*TcpUpstreamReceiver) Start ¶
func (r *TcpUpstreamReceiver) Start() error
func (*TcpUpstreamReceiver) Stop ¶
func (r *TcpUpstreamReceiver) Stop()
type TimeoutTransport ¶
type TimeoutTransport struct { http.Transport RoundTripTimeout time.Duration ReqCancel chan bool NumDials int64 }
func NewTimeoutTransport ¶
func NewTimeoutTransport(roundTo time.Duration) *TimeoutTransport
type WebServer ¶
type WebServer struct { ServerReady chan bool // closed once server is listening on Addr Done chan bool // closed when server shutdown. Cfg WebServerConfig Name string // distinguish for debug prints the various web server uses/at Start() // contains filtered or unexported fields }
func NewWebServer ¶
func NewWebServer(cfg WebServerConfig, mux *http.ServeMux) (*WebServer, error)
func (*WebServer) IsStopRequested ¶
func (*WebServer) RequestStop ¶
RequestStop makes sure we only close the s.requestStop channel once. Returns true iff we closed s.requestStop on this call.