Documentation ¶
Overview ¶
Package psiphon implements the core tunnel functionality of a Psiphon client. The main function is RunForever, which runs a Controller that obtains lists of servers, establishes tunnel connections, and runs local proxies through which tunneled traffic may be sent.
Index ¶
- Constants
- Variables
- func Contains(list []string, target string) bool
- func ContextError(err error) error
- func CountServerEntries(region, protocol string) int
- func CustomTLSDial(network, addr string, config *CustomTLSConfig) (*tls.Conn, error)
- func DecodeCertificate(encodedCertificate string) (certificate *x509.Certificate, err error)
- func FetchRemoteServerList(config *Config, dialConfig *DialConfig) (err error)
- func FilterUrlError(err error) error
- func GetKeyValue(key string) (value string, err error)
- func GetNotice(notice []byte) (noticeType string, payload map[string]interface{}, err error)
- func GetServerEntryIpAddresses() (ipAddresses []string, err error)
- func GetSplitTunnelRoutesData(region string) (data []byte, err error)
- func GetSplitTunnelRoutesETag(region string) (etag string, err error)
- func GetUrlETag(url string) (etag string, err error)
- func HttpProxyConnect(rawConn net.Conn, addr string) (err error)
- func InitDataStore(config *Config) (err error)
- func IsAddressInUseError(err error) bool
- func LookupIP(host string, config *DialConfig) (addrs []net.IP, err error)
- func MakeRandomPeriod(min, max time.Duration) (duration time.Duration)
- func MakeSecureRandomBytes(length int) ([]byte, error)
- func MakeSecureRandomInt(max int) (int, error)
- func MakeSecureRandomInt64(max int64) (int64, error)
- func MakeSecureRandomPadding(minLength, maxLength int) []byte
- func MakeSessionId() (sessionId string, err error)
- func NewNetworkList(routesData []byte) (networkList, error)
- func NoticeActiveTunnel(ipAddress string)
- func NoticeAlert(format string, args ...interface{})
- func NoticeAvailableEgressRegions(regions []string)
- func NoticeBuildInfo()
- func NoticeCandidateServers(region, protocol string, count int)
- func NoticeClientUpgradeAvailable(version string)
- func NoticeConnectingServer(ipAddress, region, protocol, frontingAddress string)
- func NoticeCoreVersion(version string)
- func NoticeError(format string, args ...interface{})
- func NoticeHomepage(url string)
- func NoticeHttpProxyPortInUse(port int)
- func NoticeInfo(format string, args ...interface{})
- func NoticeListeningHttpProxyPort(port int)
- func NoticeListeningSocksProxyPort(port int)
- func NoticeSocksProxyPortInUse(port int)
- func NoticeSplitTunnelRegion(region string)
- func NoticeTunnels(count int)
- func NoticeUntunneled(address string)
- func NoticeUpstreamProxyError(err error)
- func PromoteServerEntry(ipAddress string) error
- func ReadAuthenticatedDataPackage(rawPackage []byte, signingPublicKey string) (data string, err error)
- func Relay(localConn, remoteConn net.Conn)
- func ReportAvailableRegions()
- func ResolveIP(host string, conn net.Conn) (addrs []net.IP, ttls []time.Duration, err error)
- func SetKeyValue(key, value string) error
- func SetNoticeOutput(output io.Writer)
- func SetSplitTunnelRoutes(region, etag string, data []byte) error
- func SetUrlETag(url, etag string) error
- func StoreServerEntries(serverEntries []*ServerEntry, replaceIfExists bool) error
- func StoreServerEntry(serverEntry *ServerEntry, replaceIfExists bool) error
- func TrimError(err error) error
- func ValidateServerEntry(serverEntry *ServerEntry) error
- func WaitForNetworkConnectivity(connectivityChecker NetworkConnectivityChecker, stopBroadcast <-chan struct{}) bool
- type AuthenticatedDataPackage
- type Config
- type Conn
- type Conns
- type Controller
- func (controller *Controller) Dial(remoteAddr string, alwaysTunnel bool, downstreamConn net.Conn) (conn net.Conn, err error)
- func (controller *Controller) Run(shutdownBroadcast <-chan struct{})
- func (controller *Controller) SignalComponentFailure()
- func (controller *Controller) SignalTunnelFailure(tunnel *Tunnel)
- type CustomTLSConfig
- type DeviceBinder
- type DialConfig
- type Dialer
- type DnsServerGetter
- type ExtraParam
- type HttpProxy
- type MeekConn
- func (meek *MeekConn) Close() (err error)
- func (meek *MeekConn) LocalAddr() net.Addr
- func (meek *MeekConn) Read(buffer []byte) (n int, err error)
- func (meek *MeekConn) RemoteAddr() net.Addr
- func (meek *MeekConn) SetClosedSignal(closedSignal chan struct{}) bool
- func (meek *MeekConn) SetDeadline(t time.Time) error
- func (meek *MeekConn) SetReadDeadline(t time.Time) error
- func (meek *MeekConn) SetWriteDeadline(t time.Time) error
- func (meek *MeekConn) Write(buffer []byte) (n int, err error)
- type NetworkConnectivityChecker
- type NoticeReceiver
- type ObfuscatedSshConn
- type ObfuscatedSshReadState
- type ObfuscatedSshWriteState
- type Obfuscator
- type ObfuscatorConfig
- type ServerEntry
- type ServerEntryIterator
- type Session
- type SocksProxy
- type SplitTunnelClassifier
- type TCPConn
- func (conn *TCPConn) Close() (err error)
- func (conn *TCPConn) Read(buffer []byte) (n int, err error)
- func (conn *TCPConn) SetClosedSignal(closedSignal chan struct{}) bool
- func (conn *TCPConn) SetDeadline(t time.Time) error
- func (conn *TCPConn) SetReadDeadline(t time.Time) error
- func (conn *TCPConn) SetWriteDeadline(t time.Time) error
- func (conn *TCPConn) Write(buffer []byte) (n int, err error)
- type Tunnel
- type TunnelOwner
- type TunneledConn
- type Tunneler
Constants ¶
const ( VERSION = "0.0.9" DATA_STORE_FILENAME = "psiphon.db" CONNECTION_WORKER_POOL_SIZE = 10 TUNNEL_POOL_SIZE = 1 TUNNEL_CONNECT_TIMEOUT = 15 * time.Second TUNNEL_READ_TIMEOUT = 0 * time.Second TUNNEL_WRITE_TIMEOUT = 5 * time.Second TUNNEL_OPERATE_SHUTDOWN_TIMEOUT = 2 * time.Second TUNNEL_SSH_KEEP_ALIVE_PAYLOAD_MAX_BYTES = 256 TUNNEL_SSH_KEEP_ALIVE_PERIOD_MIN = 60 * time.Second TUNNEL_SSH_KEEP_ALIVE_PERIOD_MAX = 120 * time.Second ESTABLISH_TUNNEL_TIMEOUT_SECONDS = 300 ESTABLISH_TUNNEL_WORK_TIME_SECONDS = 60 * time.Second ESTABLISH_TUNNEL_PAUSE_PERIOD = 5 * time.Second PORT_FORWARD_FAILURE_THRESHOLD = 10 HTTP_PROXY_ORIGIN_SERVER_TIMEOUT = 15 * time.Second HTTP_PROXY_MAX_IDLE_CONNECTIONS_PER_HOST = 50 FETCH_REMOTE_SERVER_LIST_TIMEOUT = 10 * time.Second FETCH_REMOTE_SERVER_LIST_RETRY_PERIOD = 5 * time.Second FETCH_REMOTE_SERVER_LIST_STALE_PERIOD = 6 * time.Hour PSIPHON_API_CLIENT_SESSION_ID_LENGTH = 16 PSIPHON_API_SERVER_TIMEOUT = 20 * time.Second PSIPHON_API_STATUS_REQUEST_PERIOD_MIN = 5 * time.Minute PSIPHON_API_STATUS_REQUEST_PERIOD_MAX = 10 * time.Minute PSIPHON_API_STATUS_REQUEST_PADDING_MAX_BYTES = 256 PSIPHON_API_CONNECTED_REQUEST_PERIOD = 24 * time.Hour PSIPHON_API_CONNECTED_REQUEST_RETRY_PERIOD = 5 * time.Second FETCH_ROUTES_TIMEOUT = 10 * time.Second )
const ( URL_PROXY_TUNNELED_REQUEST_PATH = "/tunneled/" URL_PROXY_DIRECT_REQUEST_PATH = "/direct/" )
const ( MEEK_PROTOCOL_VERSION = 2 MEEK_COOKIE_MAX_PADDING = 32 MAX_SEND_PAYLOAD_LENGTH = 65536 FULL_RECEIVE_BUFFER_LENGTH = 4194304 READ_PAYLOAD_CHUNK_LENGTH = 65536 MIN_POLL_INTERVAL = 100 * time.Millisecond MAX_POLL_INTERVAL = 5 * time.Second POLL_INTERNAL_MULTIPLIER = 1.5 MEEK_ROUND_TRIP_RETRY_DEADLINE = 1 * time.Second MEEK_ROUND_TRIP_RETRY_DELAY = 50 * time.Millisecond )
const ( OBFUSCATION_READ_STATE_SERVER_IDENTIFICATION_LINE = iota OBFUSCATION_READ_STATE_SERVER_KEX_PACKETS OBFUSCATION_READ_STATE_FLUSH OBFUSCATION_READ_STATE_FINISHED )
const ( OBFUSCATION_WRITE_STATE_SEND_CLIENT_SEED_MESSAGE = iota OBFUSCATION_WRITE_STATE_CLIENT_IDENTIFICATION_LINE OBFUSCATION_WRITE_STATE_CLIENT_KEX_PACKETS OBFUSCATION_WRITE_STATE_FINISHED )
const ( SSH_MAX_SERVER_LINE_LENGTH = 1024 SSH_PACKET_PREFIX_LENGTH = 5 // uint32 + byte SSH_MAX_PACKET_LENGTH = 256 * 1024 // OpenSSH max packet length SSH_MSG_NEWKEYS = 21 SSH_MAX_PADDING_LENGTH = 255 // RFC 4253 sec. 6 SSH_PADDING_MULTIPLE = 16 // Default cipher block size )
const ( OBFUSCATE_SEED_LENGTH = 16 OBFUSCATE_KEY_LENGTH = 16 OBFUSCATE_HASH_ITERATIONS = 6000 OBFUSCATE_MAX_PADDING = 8192 OBFUSCATE_MAGIC_VALUE = 0x0BF5CA7E OBFUSCATE_CLIENT_TO_SERVER_IV = "client_to_server" OBFUSCATE_SERVER_TO_CLIENT_IV = "server_to_client" )
const ( TUNNEL_PROTOCOL_SSH = "SSH" TUNNEL_PROTOCOL_OBFUSCATED_SSH = "OSSH" TUNNEL_PROTOCOL_UNFRONTED_MEEK = "UNFRONTED-MEEK-OSSH" TUNNEL_PROTOCOL_FRONTED_MEEK = "FRONTED-MEEK-OSSH" )
const DNS_PORT = 53
Variables ¶
var SupportedTunnelProtocols = []string{ TUNNEL_PROTOCOL_FRONTED_MEEK, TUNNEL_PROTOCOL_UNFRONTED_MEEK, TUNNEL_PROTOCOL_OBFUSCATED_SSH, TUNNEL_PROTOCOL_SSH, }
This is a list of supported tunnel protocols, in default preference order
Functions ¶
func Contains ¶
Contains is a helper function that returns true if the target string is in the list.
func ContextError ¶
ContextError prefixes an error message with the current function name
func CountServerEntries ¶
CountServerEntries returns a count of stored servers for the specified region and protocol.
func CustomTLSDial ¶
func CustomTLSDial(network, addr string, config *CustomTLSConfig) (*tls.Conn, error)
CustomTLSDialWithDialer is a customized replacement for tls.Dial. Based on tlsdialer.DialWithDialer which is based on crypto/tls.DialWithDialer.
tlsdialer comment:
Note - if sendServerName is false, the VerifiedChains field on the connection's ConnectionState will never get populated.
func DecodeCertificate ¶
func DecodeCertificate(encodedCertificate string) (certificate *x509.Certificate, err error)
func FetchRemoteServerList ¶
func FetchRemoteServerList(config *Config, dialConfig *DialConfig) (err error)
FetchRemoteServerList downloads a remote server list JSON record from config.RemoteServerListUrl; validates its digital signature using the public key config.RemoteServerListSignaturePublicKey; and parses the data field into ServerEntry records.
func FilterUrlError ¶
FilterUrlError transforms an error, when it is a url.Error, removing the URL value. This is to avoid logging private user data in cases where the URL may be a user input value. This function is used with errors returned by net/http and net/url, which are (currently) of type url.Error. In particular, the round trip function used by our HttpProxy, http.Client.Do, returns errors of type url.Error, with the URL being the url sent from the user's tunneled applications: https://github.com/golang/go/blob/release-branch.go1.4/src/net/http/client.go#L394
func GetKeyValue ¶
GetKeyValue retrieves the value for a given key. If not found, it returns an empty string value.
func GetNotice ¶
GetNotice receives a JSON encoded object and attempts to parse it as a Notice. The type is returned as a string and the payload as a generic map.
func GetServerEntryIpAddresses ¶
GetServerEntryIpAddresses returns an array containing all stored server IP addresses.
func GetSplitTunnelRoutesData ¶
GetSplitTunnelRoutesData retrieves the cached routes data for the specified region. If not found, it returns a nil value.
func GetSplitTunnelRoutesETag ¶
GetSplitTunnelRoutesETag retrieves the etag for cached routes data for the specified region. If not found, it returns an empty string value.
func GetUrlETag ¶
GetUrlETag retrieves a previously stored an ETag for the specfied URL. If not found, it returns an empty string value.
func HttpProxyConnect ¶
HttpProxyConnect establishes a HTTP CONNECT tunnel to addr through an established network connection to an HTTP proxy. It is assumed that no payload bytes have been sent through the connection to the proxy.
func InitDataStore ¶
InitDataStore initializes the singleton instance of dataStore. This function uses a sync.Once and is safe for use by concurrent goroutines. The underlying sql.DB connection pool is also safe.
Note: the sync.Once was more useful when initDataStore was private and called on-demand by the public functions below. Now we require an explicit InitDataStore() call with the filename passed in. The on-demand calls have been replaced by checkInitDataStore() to assert that Init was called.
func IsAddressInUseError ¶
IsAddressInUseError returns true when the err is due to EADDRINUSE/WSAEADDRINUSE.
func LookupIP ¶
func LookupIP(host string, config *DialConfig) (addrs []net.IP, err error)
LookupIP resolves a hostname. When BindToDevice is not required, it simply uses net.LookupIP. When BindToDevice is required, LookupIP explicitly creates a UDP socket, binds it to the device, and makes an explicit DNS request to the specified DNS resolver.
func MakeRandomPeriod ¶
MakeRandomPeriod returns a random duration, within a given range. In the unlikely case where an underlying MakeRandom functions fails, the period is the minimum.
func MakeSecureRandomBytes ¶
MakeSecureRandomBytes is a helper function that wraps crypto/rand.Read.
func MakeSecureRandomInt ¶
MakeSecureRandomInt is a helper function that wraps MakeSecureRandomInt64.
func MakeSecureRandomInt64 ¶
MakeSecureRandomInt64 is a helper function that wraps crypto/rand.Int, which returns a uniform random value in [0, max).
func MakeSecureRandomPadding ¶
MakeSecureRandomPadding selects a random padding length in the indicated range and returns a random byte array of the selected length. In the unlikely case where an underlying MakeRandom functions fails, the padding is length 0.
func MakeSessionId ¶
MakeSessionId creates a new session ID. Making the session ID is not done in NewSession because: (1) the transport needs to send the ID in the SSH credentials before the tunnel
is established and NewSession performs a handshake on an established tunnel.
(2) the same session ID is used across multi-tunnel controller runs, where each
tunnel has its own Session instance.
func NewNetworkList ¶
NewNetworkList parses text routes data and produces a networkList for fast ContainsIpAddress lookup. The input format is expected to be text lines where each line is, e.g., "1.2.3.0\t255.255.255.0\n"
func NoticeActiveTunnel ¶
func NoticeActiveTunnel(ipAddress string)
NoticeActiveTunnel is a successful connection that is used as an active tunnel for port forwarding
func NoticeAlert ¶
func NoticeAlert(format string, args ...interface{})
NoticeInfo is an alert message; typically a recoverable error condition
func NoticeAvailableEgressRegions ¶
func NoticeAvailableEgressRegions(regions []string)
NoticeAvailableEgressRegions is what regions are available for egress from
func NoticeBuildInfo ¶
func NoticeBuildInfo()
func NoticeCandidateServers ¶
NoticeCandidateServers is how many possible servers are available for the selected region and protocol
func NoticeClientUpgradeAvailable ¶
func NoticeClientUpgradeAvailable(version string)
NoticeClientUpgradeAvailable is an available client upgrade, as per the handshake. The client should download and install an upgrade.
func NoticeConnectingServer ¶
func NoticeConnectingServer(ipAddress, region, protocol, frontingAddress string)
NoticeConnectingServer is details on a connection attempt
func NoticeCoreVersion ¶
func NoticeCoreVersion(version string)
NoticeCoreVersion is the version string of the core
func NoticeError ¶
func NoticeError(format string, args ...interface{})
NoticeInfo is an error message; typically an unrecoverable error condition
func NoticeHomepage ¶
func NoticeHomepage(url string)
NoticeClientUpgradeAvailable is a sponsor homepage, as per the handshake. The client should display the sponsor's homepage.
func NoticeHttpProxyPortInUse ¶
func NoticeHttpProxyPortInUse(port int)
NoticeSocksProxyPortInUse is a failure to use the configured LocalHttpProxyPort
func NoticeInfo ¶
func NoticeInfo(format string, args ...interface{})
NoticeInfo is an informational message
func NoticeListeningHttpProxyPort ¶
func NoticeListeningHttpProxyPort(port int)
NoticeListeningSocksProxyPort is the selected port for the listening local HTTP proxy
func NoticeListeningSocksProxyPort ¶
func NoticeListeningSocksProxyPort(port int)
NoticeListeningSocksProxyPort is the selected port for the listening local SOCKS proxy
func NoticeSocksProxyPortInUse ¶
func NoticeSocksProxyPortInUse(port int)
NoticeSocksProxyPortInUse is a failure to use the configured LocalSocksProxyPort
func NoticeSplitTunnelRegion ¶
func NoticeSplitTunnelRegion(region string)
NoticeSplitTunnelRegion reports that split tunnel is on for the given region.
func NoticeTunnels ¶
func NoticeTunnels(count int)
NoticeTunnels is how many active tunnels are available. The client should use this to determine connecting/unexpected disconnect state transitions. When count is 0, the core is disconnected; when count > 1, the core is connected.
func NoticeUntunneled ¶
func NoticeUntunneled(address string)
NoticeUntunneled indicates than an address has been classified as untunneled and is being accessed directly.
Note: "address" should remain private; this notice should only be used for alerting users, not for diagnostics logs.
func NoticeUpstreamProxyError ¶
func NoticeUpstreamProxyError(err error)
NoticeUpstreamProxyError reports an error when connecting to an upstream proxy. The user may have input, for example, an incorrect address or incorrect credentials.
func PromoteServerEntry ¶
PromoteServerEntry assigns the top rank (one more than current max rank) to the specified server entry. Server candidates are iterated in decending rank order, so this server entry will be the first candidate in a subsequent tunnel establishment.
func Relay ¶
Relay sends to remoteConn bytes received from localConn, and sends to localConn bytes received from remoteConn.
func ReportAvailableRegions ¶
func ReportAvailableRegions()
ReportAvailableRegions prints a notice with the available egress regions. Note that this report ignores config.TunnelProtocol.
func ResolveIP ¶
ResolveIP uses a custom dns stack to make a DNS query over the given TCP or UDP conn. This is used, e.g., when we need to ensure that a DNS connection bypasses a VPN interface (BindToDevice) or when we need to ensure that a DNS connection is tunneled. Caller must set timeouts or interruptibility as required for conn.
func SetNoticeOutput ¶
SetNoticeOutput sets a target writer to receive notices. By default, notices are written to stderr.
Notices are encoded in JSON. Here's an example:
{"data":{"message":"shutdown operate tunnel"},"noticeType":"Info","showUser":false,"timestamp":"2015-01-28T17:35:13Z"}
All notices have the following fields: - "noticeType": the type of notice, which indicates the meaning of the notice along with what's in the data payload. - "data": additional structured data payload. For example, the "ListeningSocksProxyPort" notice type has a "port" integer data in its payload. - "showUser": whether the information should be displayed to the user. For example, this flag is set for "SocksProxyPortInUse" as the user should be informed that their configured choice of listening port could not be used. Core clients should anticipate that the core will add additional "showUser"=true notices in the future and emit at least the raw notice. - "timestamp": UTC timezone, RFC3339 format timestamp for notice event
See the Notice* functions for details on each notice meaning and payload.
func SetSplitTunnelRoutes ¶
SetSplitTunnelRoutes updates the cached routes data for the given region. The associated etag is also stored and used to make efficient web requests for updates to the data.
func SetUrlETag ¶
SetUrlETag stores an ETag for the specfied URL. Note: input URL is treated as a string, and is not encoded or decoded or otherwise canonicalized.
func StoreServerEntries ¶
func StoreServerEntries(serverEntries []*ServerEntry, replaceIfExists bool) error
StoreServerEntries shuffles and stores a list of server entries. Shuffling is performed on imported server entrues as part of client-side load balancing. There is an independent transaction for each entry insert/update.
func StoreServerEntry ¶
func StoreServerEntry(serverEntry *ServerEntry, replaceIfExists bool) error
StoreServerEntry adds the server entry to the data store. A newly stored (or re-stored) server entry is assigned the next-to-top rank for iteration order (the previous top ranked entry is promoted). The purpose of inserting at next-to-top is to keep the last selected server as the top ranked server. When replaceIfExists is true, an existing server entry record is overwritten; otherwise, the existing record is unchanged. If the server entry data is malformed, an alert notice is issued and the entry is skipped; no error is returned.
func ValidateServerEntry ¶
func ValidateServerEntry(serverEntry *ServerEntry) error
ValidateServerEntry checks for malformed server entries. Currently, it checks for a valid ipAddress. This is important since handshake requests submit back to the server a list of known server IP addresses and the handshake API expects well-formed inputs. TODO: validate more fields
func WaitForNetworkConnectivity ¶
func WaitForNetworkConnectivity( connectivityChecker NetworkConnectivityChecker, stopBroadcast <-chan struct{}) bool
WaitForNetworkConnectivity uses a NetworkConnectivityChecker to periodically check for network connectivity. It returns true if no NetworkConnectivityChecker is provided (waiting is disabled) or if NetworkConnectivityChecker.HasNetworkConnectivity() indicates connectivity. It polls the checker once a second. If a stop is broadcast, false is returned.
Types ¶
type AuthenticatedDataPackage ¶
type AuthenticatedDataPackage struct { Data string `json:"data"` SigningPublicKeyDigest string `json:"signingPublicKeyDigest"` Signature string `json:"signature"` }
AuthenticatedDataPackage is a JSON record containing some Psiphon data payload, such as list of Psiphon server entries. As it may be downloaded from various sources, it is digitally signed so that the data may be authenticated.
type Config ¶
type Config struct { LogFilename string DataStoreDirectory string DataStoreTempDirectory string PropagationChannelId string SponsorId string RemoteServerListUrl string RemoteServerListSignaturePublicKey string ClientVersion string ClientPlatform string TunnelWholeDevice int EgressRegion string TunnelProtocol string EstablishTunnelTimeoutSeconds *int LocalSocksProxyPort int LocalHttpProxyPort int ConnectionWorkerPoolSize int TunnelPoolSize int PortForwardFailureThreshold int UpstreamHttpProxyAddress string NetworkConnectivityChecker NetworkConnectivityChecker DeviceBinder DeviceBinder DnsServerGetter DnsServerGetter TargetServerEntry string DisableApi bool DisableRemoteServerListFetcher bool SplitTunnelRoutesUrlFormat string SplitTunnelRoutesSignaturePublicKey string SplitTunnelDnsServer string }
func LoadConfig ¶
LoadConfig parses and validates a JSON format Psiphon config JSON string and returns a Config struct populated with config values.
type Conn ¶
type Conn interface { net.Conn // SetClosedSignal sets the channel which will be signaled // when the connection is closed. This function returns false // if the connection is already closed (and would never send // the signal). SetClosedSignal and Close may be called by // concurrent goroutines. SetClosedSignal(closedSignal chan struct{}) bool }
Conn is a net.Conn which supports sending a signal to a channel when it is closed. In Psiphon, this interface is implemented by tunnel connection types (DirectConn and MeekConn) and the close signal is used as one trigger for tearing down the tunnel.
type Conns ¶
type Conns struct {
// contains filtered or unexported fields
}
Conns is a synchronized list of Conns that is used to coordinate interrupting a set of goroutines establishing connections, or close a set of open connections, etc. Once the list is closed, no more items may be added to the list (unless it is reset).
type Controller ¶
type Controller struct {
// contains filtered or unexported fields
}
Controller is a tunnel lifecycle coordinator. It manages lists of servers to connect to; establishes and monitors tunnels; and runs local proxies which route traffic through the tunnels.
func NewController ¶
func NewController(config *Config) (controller *Controller, err error)
NewController initializes a new controller.
func (*Controller) Dial ¶
func (controller *Controller) Dial( remoteAddr string, alwaysTunnel bool, downstreamConn net.Conn) (conn net.Conn, err error)
Dial selects an active tunnel and establishes a port forward connection through the selected tunnel. Failure to connect is considered a port foward failure, for the purpose of monitoring tunnel health.
func (*Controller) Run ¶
func (controller *Controller) Run(shutdownBroadcast <-chan struct{})
Run executes the controller. It launches components and then monitors for a shutdown signal; after receiving the signal it shuts down the controller. The components include: - the periodic remote server list fetcher - the connected reporter - the tunnel manager - a local SOCKS proxy that port forwards through the pool of tunnels - a local HTTP proxy that port forwards through the pool of tunnels
func (*Controller) SignalComponentFailure ¶
func (controller *Controller) SignalComponentFailure()
SignalComponentFailure notifies the controller that an associated component has failed. This will terminate the controller.
func (*Controller) SignalTunnelFailure ¶
func (controller *Controller) SignalTunnelFailure(tunnel *Tunnel)
SignalTunnelFailure implements the TunnelOwner interface. This function is called by Tunnel.operateTunnel when the tunnel has detected that it has failed. The Controller will signal runTunnels to create a new tunnel and/or remove the tunnel from the list of active tunnels.
type CustomTLSConfig ¶
type CustomTLSConfig struct { // Dial is the network connection dialer. TLS is layered on // top of a new network connection created with dialer. Dial Dialer // Timeout is and optional timeout for combined network // connection dial and TLS handshake. Timeout time.Duration // FrontingAddr overrides the "addr" input to Dial when specified FrontingAddr string // SendServerName specifies whether to use SNI // (tlsdialer functionality) SendServerName bool // SkipVerify completely disables server certificate verification. SkipVerify bool // VerifyLegacyCertificate is a special case self-signed server // certificate case. Ignores IP SANs and basic constraints. No // certificate chain. Just checks that the server presented the // specified certificate. VerifyLegacyCertificate *x509.Certificate // TlsConfig is a tls.Config to use in the // non-verifyLegacyCertificate case. TlsConfig *tls.Config }
CustomTLSConfig contains parameters to determine the behavior of CustomTLSDial.
type DeviceBinder ¶
DeviceBinder defines the interface to the external BindToDevice provider
type DialConfig ¶
type DialConfig struct { // UpstreamHttpProxyAddress specifies an HTTP proxy to connect through // (the proxy must support HTTP CONNECT). The address may be a hostname // or IP address and must include a port number. UpstreamHttpProxyAddress string ConnectTimeout time.Duration ReadTimeout time.Duration WriteTimeout time.Duration // PendingConns is used to interrupt dials in progress. // The dial may be interrupted using PendingConns.CloseAll(): on platforms // that support this, the new conn is added to pendingConns before the network // connect begins and removed from pendingConns once the connect succeeds or fails. PendingConns *Conns // BindToDevice parameters are used to exclude connections and // associated DNS requests from VPN routing. // When DeviceBinder is set, any underlying socket is // submitted to the device binding servicebefore connecting. // The service should bind the socket to a device so that it doesn't route // through a VPN interface. This service is also used to bind UDP sockets used // for DNS requests, in which case DnsServerGetter is used to get the // current active untunneled network DNS server. DeviceBinder DeviceBinder DnsServerGetter DnsServerGetter }
DialConfig contains parameters to determine the behavior of a Psiphon dialer (TCPDial, MeekDial, etc.)
type Dialer ¶
Dialer is a custom dialer compatible with http.Transport.Dial.
func NewCustomTLSDialer ¶
func NewCustomTLSDialer(config *CustomTLSConfig) Dialer
type DnsServerGetter ¶
type DnsServerGetter interface {
GetDnsServer() string
}
DnsServerGetter defines the interface to the external GetDnsServer provider
type ExtraParam ¶
type ExtraParam struct {
// contains filtered or unexported fields
}
type HttpProxy ¶
type HttpProxy struct {
// contains filtered or unexported fields
}
HttpProxy is a HTTP server that relays HTTP requests through the Psiphon tunnel. It includes support for HTTP CONNECT.
This proxy also offers a "URL proxy" mode that relays requests for HTTP or HTTPS or URLs specified in the proxy request path. This mode relays either through the Psiphon tunnel, or directly.
An example use case for tunneled URL proxy relays is to craft proxied URLs to pass to components that don't support HTTP or SOCKS proxy settings. For example, the Android Media Player (http://developer.android.com/reference/android/media/MediaPlayer.html). To make the Media Player use the Psiphon tunnel, construct a URL such as: "http://127.0.0.1:<proxy-port>/tunneled/<origin media URL>"; and pass this to the player. TODO: add ICY protocol to support certain streaming media (e.g., https://gist.github.com/tulskiy/1008126)
An example use case for direct, untunneled, relaying is to make use of Go's TLS stack for HTTPS requests in cases where the native TLS stack is lacking (e.g., WinHTTP on Windows XP). The URL for direct relaying is: "http://127.0.0.1:<proxy-port>/direct/<origin URL>".
Origin URLs must include the scheme prefix ("http://" or "https://") and must be URL encoded.
func NewHttpProxy ¶
func NewHttpProxy( config *Config, untunneledDialConfig *DialConfig, tunneler Tunneler) (proxy *HttpProxy, err error)
NewHttpProxy initializes and runs a new HTTP proxy server.
func (*HttpProxy) ServeHTTP ¶
func (proxy *HttpProxy) ServeHTTP(responseWriter http.ResponseWriter, request *http.Request)
ServeHTTP receives HTTP requests and proxies them. CONNECT requests are hijacked and all data is relayed. Other HTTP requests are proxied with explicit round trips. In both cases, the tunnel is used for proxied traffic.
Implementation is based on:
https://github.com/justmao945/mallory Copyright (c) 2014 JianjunMao The MIT License (MIT)
https://golang.org/src/pkg/net/http/httputil/reverseproxy.go Copyright 2011 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
type MeekConn ¶
type MeekConn struct {
// contains filtered or unexported fields
}
MeekConn is a network connection that tunnels TCP over HTTP and supports "fronting". Meek sends client->server flow in HTTP request bodies and receives server->client flow in HTTP response bodies. Polling is used to achieve full duplex TCP.
Fronting is an obfuscation technique in which the connection to a web server, typically a CDN, is indistinguishable from any other HTTPS connection to the generic "fronting domain" -- the HTTP Host header is used to route the requests to the actual destination. See https://trac.torproject.org/projects/tor/wiki/doc/meek for more details.
MeekConn also operates in unfronted mode, in which plain HTTP connections are made without routing through a CDN.
func DialMeek ¶
func DialMeek( serverEntry *ServerEntry, sessionId string, frontingAddress string, config *DialConfig) (meek *MeekConn, err error)
DialMeek returns an initialized meek connection. A meek connection is an HTTP session which does not depend on an underlying socket connection (although persistent HTTP connections are used for performance). This function does not wait for the connection to be "established" before returning. A goroutine is spawned which will eventually start HTTP polling. When frontingAddress is not "", fronting is used. This option assumes caller has already checked server entry capabilities.
func (*MeekConn) Close ¶
Close terminates the meek connection. Close waits for the relay processing goroutine to stop and releases HTTP transport resources. A mutex is required to support psiphon.Conn.SetClosedSignal concurrency semantics.
func (*MeekConn) Read ¶
Read reads data from the connection. net.Conn Deadlines are ignored. net.Conn concurrency semantics are supported.
func (*MeekConn) RemoteAddr ¶
Stub implementation of net.Conn.RemoteAddr
func (*MeekConn) SetClosedSignal ¶
SetClosedSignal implements psiphon.Conn.SetClosedSignal
func (*MeekConn) SetDeadline ¶
Stub implementation of net.Conn.SetDeadline
func (*MeekConn) SetReadDeadline ¶
Stub implementation of net.Conn.SetReadDeadline
func (*MeekConn) SetWriteDeadline ¶
Stub implementation of net.Conn.SetWriteDeadline
type NetworkConnectivityChecker ¶
type NetworkConnectivityChecker interface { // TODO: change to bool return value once gobind supports that type HasNetworkConnectivity() int }
NetworkConnectivityChecker defines the interface to the external HasNetworkConnectivity provider
type NoticeReceiver ¶
type NoticeReceiver struct {
// contains filtered or unexported fields
}
NoticeReceiver consumes a notice input stream and invokes a callback function for each discrete JSON notice object byte sequence.
func NewNoticeConsoleRewriter ¶
func NewNoticeConsoleRewriter(writer io.Writer) *NoticeReceiver
NewNoticeConsoleRewriter consumes JSON-format notice input and parses each notice and rewrites in a more human-readable format more suitable for console output. The data payload field is left as JSON.
func NewNoticeReceiver ¶
func NewNoticeReceiver(callback func([]byte)) *NoticeReceiver
NewNoticeReceiver initializes a new NoticeReceiver
type ObfuscatedSshConn ¶
ObfuscatedSshConn wraps a Conn and applies the obfuscated SSH protocol to the traffic on the connection: https://github.com/brl/obfuscated-openssh/blob/master/README.obfuscation ObfuscatedSshConn is used to add obfuscation to go's stock ssh client without modification to that standard library code. The underlying connection must be used for SSH client traffic. This code injects the obfuscated seed message, applies obfuscated stream cipher transformations, and performs minimal parsing of the SSH protocol to determine when to stop obfuscation (after the first SSH_MSG_NEWKEYS is sent by the client and received from the server).
WARNING: doesn't fully conform to net.Conn concurrency semantics: there's no synchronization of access to the read/writeBuffers, so concurrent calls to one of Read or Write will result in undefined behavior.
func NewObfuscatedSshConn ¶
func NewObfuscatedSshConn(conn net.Conn, obfuscationKeyword string) (*ObfuscatedSshConn, error)
NewObfuscatedSshConn creates a new ObfuscatedSshConn. The underlying conn must be used for SSH client traffic and must have transferred no traffic.
type ObfuscatedSshReadState ¶
type ObfuscatedSshReadState int
type ObfuscatedSshWriteState ¶
type ObfuscatedSshWriteState int
type Obfuscator ¶
type Obfuscator struct {
// contains filtered or unexported fields
}
Obfuscator implements the seed message, key derivation, and stream ciphers for: https://github.com/brl/obfuscated-openssh/blob/master/README.obfuscation
func NewObfuscator ¶
func NewObfuscator(config *ObfuscatorConfig) (obfuscator *Obfuscator, err error)
NewObfuscator creates a new Obfuscator, initializes it with a seed message, derives client and server keys, and creates RC4 stream ciphers to obfuscate data.
func (*Obfuscator) ConsumeSeedMessage ¶
func (obfuscator *Obfuscator) ConsumeSeedMessage() []byte
ConsumeSeedMessage returns the seed message created in NewObfuscator, removing the reference so that it may be garbage collected.
func (*Obfuscator) ObfuscateClientToServer ¶
func (obfuscator *Obfuscator) ObfuscateClientToServer(buffer []byte)
ObfuscateClientToServer applies the client RC4 stream to the bytes in buffer.
func (*Obfuscator) ObfuscateServerToClient ¶
func (obfuscator *Obfuscator) ObfuscateServerToClient(buffer []byte)
ObfuscateServerToClient applies the server RC4 stream to the bytes in buffer.
type ObfuscatorConfig ¶
type ServerEntry ¶
type ServerEntry struct { IpAddress string `json:"ipAddress"` WebServerPort string `json:"webServerPort"` // not an int WebServerSecret string `json:"webServerSecret"` WebServerCertificate string `json:"webServerCertificate"` SshPort int `json:"sshPort"` SshUsername string `json:"sshUsername"` SshPassword string `json:"sshPassword"` SshHostKey string `json:"sshHostKey"` SshObfuscatedPort int `json:"sshObfuscatedPort"` SshObfuscatedKey string `json:"sshObfuscatedKey"` Capabilities []string `json:"capabilities"` Region string `json:"region"` MeekServerPort int `json:"meekServerPort"` MeekCookieEncryptionPublicKey string `json:"meekCookieEncryptionPublicKey"` MeekObfuscatedKey string `json:"meekObfuscatedKey"` MeekFrontingHost string `json:"meekFrontingHost"` MeekFrontingDomain string `json:"meekFrontingDomain"` MeekFrontingAddresses []string `json:"meekFrontingAddresses"` }
ServerEntry represents a Psiphon server. It contains information about how to estalish a tunnel connection to the server through several protocols. ServerEntry are JSON records downloaded from various sources.
func DecodeAndValidateServerEntryList ¶
func DecodeAndValidateServerEntryList(encodedServerEntryList string) (serverEntries []*ServerEntry, err error)
DecodeAndValidateServerEntryList extracts server entries from the list encoding used by remote server lists and Psiphon server handshake requests. Each server entry is validated and invalid entries are skipped.
func DecodeServerEntry ¶
func DecodeServerEntry(encodedServerEntry string) (serverEntry *ServerEntry, err error)
DecodeServerEntry extracts server entries from the encoding used by remote server lists and Psiphon server handshake requests.
func MakeCompatibleServerEntry ¶
func MakeCompatibleServerEntry(serverEntry *ServerEntry) *ServerEntry
MakeCompatibleServerEntry provides backwards compatibility with old server entries which have a single meekFrontingDomain and not a meekFrontingAddresses array. By copying this one meekFrontingDomain into meekFrontingAddresses, this client effectively uses that single value as legacy clients do.
type ServerEntryIterator ¶
type ServerEntryIterator struct {
// contains filtered or unexported fields
}
ServerEntryIterator is used to iterate over stored server entries in rank order.
func NewServerEntryIterator ¶
func NewServerEntryIterator(config *Config) (iterator *ServerEntryIterator, err error)
NewServerEntryIterator creates a new ServerEntryIterator
func (*ServerEntryIterator) Close ¶
func (iterator *ServerEntryIterator) Close()
Close cleans up resources associated with a ServerEntryIterator.
func (*ServerEntryIterator) Next ¶
func (iterator *ServerEntryIterator) Next() (serverEntry *ServerEntry, err error)
Next returns the next server entry, by rank, for a ServerEntryIterator. Returns nil with no error when there is no next item.
func (*ServerEntryIterator) Reset ¶
func (iterator *ServerEntryIterator) Reset() error
Reset a NewServerEntryIterator to the start of its cycle. The next call to Next will return the first server entry.
type Session ¶
type Session struct {
// contains filtered or unexported fields
}
Session is a utility struct which holds all of the data associated with a Psiphon session. In addition to the established tunnel, this includes the session ID (used for Psiphon API requests) and a http client configured to make tunneled Psiphon API requests.
func NewSession ¶
NewSession makes the tunnelled handshake request to the Psiphon server and returns a Session struct, initialized with the session ID, for use with subsequent Psiphon server API requests (e.g., periodic connected and status requests).
func (*Session) DoConnectedRequest ¶
DoConnectedRequest performs the connected API request. This request is used for statistics. The server returns a last_connected token for the client to store and send next time it connects. This token is a timestamp (using the server clock, and should be rounded to the nearest hour) which is used to determine when a connection represents a unique user for a time period.
func (*Session) DoStatusRequest ¶
DoStatusRequest makes a /status request to the server, sending session stats.
func (*Session) StatsRegexps ¶
func (session *Session) StatsRegexps() *transferstats.Regexps
StatsRegexps gets the Regexps used for the statistics for this tunnel.
func (*Session) StatsServerID ¶
ServerID provides a unique identifier for the server the session connects to. This ID is consistent between multiple sessions/tunnels connected to that server.
type SocksProxy ¶
type SocksProxy struct {
// contains filtered or unexported fields
}
SocksProxy is a SOCKS server that accepts local host connections and, for each connection, establishes a port forward through the tunnel SSH client and relays traffic through the port forward.
func NewSocksProxy ¶
func NewSocksProxy(config *Config, tunneler Tunneler) (proxy *SocksProxy, err error)
NewSocksProxy initializes a new SOCKS server. It begins listening for connections, starts a goroutine that runs an accept loop, and returns leaving the accept loop running.
func (*SocksProxy) Close ¶
func (proxy *SocksProxy) Close()
Close terminates the listener and waits for the accept loop goroutine to complete.
type SplitTunnelClassifier ¶
type SplitTunnelClassifier struct {
// contains filtered or unexported fields
}
SplitTunnelClassifier determines whether a network destination should be accessed through a tunnel or accessed directly.
The classifier uses tables of IP address data, routes data, to determine if a given IP is to be tunneled or not. If presented with a hostname, the classifier performs a tunneled (uncensored) DNS request to first determine the IP address for that hostname; then a classification is made based on the IP address.
Classification results (both the hostname resolution and the following IP address classification) are cached for the duration of the DNS record TTL.
Classification is by geographical region (country code). When the split tunnel feature is configured to be on, and if the IP address is within the user's region, it may be accessed untunneled. Otherwise, the IP address must be accessed through a tunnel. The user's current region is revealed to a Tunnel via the Psiphon server API handshake.
When a Tunnel has a blank region (e.g., when DisableApi is set and the tunnel registers without performing a handshake) then no routes data is set and all IP addresses are classified as requiring tunneling.
Split tunnel is made on a best effort basis. After the classifier is started, but before routes data is available for the given region, all IP addresses will be classified as requiring tunneling.
Routes data is fetched asynchronously after Start() is called. Routes data is cached in the data store so it need not be downloaded in full when fresh data is in the cache.
func NewSplitTunnelClassifier ¶
func NewSplitTunnelClassifier(config *Config, tunneler Tunneler) *SplitTunnelClassifier
func (*SplitTunnelClassifier) IsUntunneled ¶
func (classifier *SplitTunnelClassifier) IsUntunneled(targetAddress string) bool
IsUntunneled takes a destination hostname or IP address and determines if it should be accessed through a tunnel. When a hostname is presented, it is first resolved to an IP address which can be matched against the routes data. Multiple goroutines may invoke RequiresTunnel simultaneously. Multi-reader locks are used in the implementation to enable concurrent access, with no locks held during network access.
func (*SplitTunnelClassifier) Shutdown ¶
func (classifier *SplitTunnelClassifier) Shutdown()
Shutdown waits until the background setRoutes() goroutine is finished. There is no explicit shutdown signal sent to setRoutes() -- instead we assume that in an overall shutdown situation, the tunnel used for network access in setRoutes() is closed and network events won't delay the completion of the goroutine.
func (*SplitTunnelClassifier) Start ¶
func (classifier *SplitTunnelClassifier) Start(fetchRoutesTunnel *Tunnel)
Start resets the state of the classifier. In the default state, all IP addresses are classified as requiring tunneling. With sufficient configuration and region info, this function starts a goroutine to asynchronously fetch and install the routes data.
type TCPConn ¶
TCPConn is a customized TCP connection that:
- can be interrupted while connecting;
- implements idle read/write timeouts;
- can be bound to a specific system device (for Android VpnService routing compatibility, for example).
- implements the psiphon.Conn interface
func DialTCP ¶
func DialTCP(addr string, config *DialConfig) (conn *TCPConn, err error)
TCPConn creates a new, connected TCPConn.
func (*TCPConn) Close ¶
Close terminates a connected (net.Conn) or connecting (socketFd) TCPConn. A mutex is required to support psiphon.Conn.SetClosedSignal concurrency semantics.
func (*TCPConn) Read ¶
Read wraps standard Read to add an idle timeout. The connection is explicitly closed on timeout.
func (*TCPConn) SetClosedSignal ¶
SetClosedSignal implements psiphon.Conn.SetClosedSignal.
func (*TCPConn) SetDeadline ¶
Override implementation of net.Conn.SetDeadline
func (*TCPConn) SetReadDeadline ¶
Override implementation of net.Conn.SetReadDeadline
func (*TCPConn) SetWriteDeadline ¶
Override implementation of net.Conn.SetWriteDeadline
type Tunnel ¶
type Tunnel struct {
// contains filtered or unexported fields
}
Tunnel is a connection to a Psiphon server. An established tunnel includes a network connection to the specified server and an SSH session built on top of that transport.
func EstablishTunnel ¶
func EstablishTunnel( config *Config, sessionId string, pendingConns *Conns, serverEntry *ServerEntry, tunnelOwner TunnelOwner) (tunnel *Tunnel, err error)
EstablishTunnel first makes a network transport connection to the Psiphon server and then establishes an SSH client session on top of that transport. The SSH server is authenticated using the public key in the server entry. Depending on the server's capabilities, the connection may use plain SSH over TCP, obfuscated SSH over TCP, or obfuscated SSH over HTTP (meek protocol). When requiredProtocol is not blank, that protocol is used. Otherwise, the first protocol in SupportedTunnelProtocols that's also in the server capabilities is used.
func (*Tunnel) Close ¶
func (tunnel *Tunnel) Close()
Close stops operating the tunnel and closes the underlying connection. Supports multiple and/or concurrent calls to Close().
func (*Tunnel) Dial ¶
func (tunnel *Tunnel) Dial( remoteAddr string, alwaysTunnel bool, downstreamConn net.Conn) (conn net.Conn, err error)
Dial establishes a port forward connection through the tunnel This Dial doesn't support split tunnel, so alwaysTunnel is not referenced
func (*Tunnel) SignalComponentFailure ¶
func (tunnel *Tunnel) SignalComponentFailure()
SignalComponentFailure notifies the tunnel that an associated component has failed. This will terminate the tunnel.
type TunnelOwner ¶
type TunnelOwner interface {
SignalTunnelFailure(tunnel *Tunnel)
}
TunnerOwner specifies the interface required by Tunnel to notify its owner when it has failed. The owner may, as in the case of the Controller, remove the tunnel from its list of active tunnels.
type TunneledConn ¶
TunneledConn implements net.Conn and wraps a port foward connection. It is used to hook into Read and Write to observe I/O errors and report these errors back to the tunnel monitor as port forward failures. TunneledConn optionally tracks a peer connection to be explictly closed when the TunneledConn is closed.
func (*TunneledConn) Close ¶
func (conn *TunneledConn) Close() error
type Tunneler ¶
type Tunneler interface { Dial(remoteAddr string, alwaysTunnel bool, downstreamConn net.Conn) (conn net.Conn, err error) SignalComponentFailure() }
Tunneler specifies the interface required by components that use a tunnel. Components which use this interface may be serviced by a single Tunnel instance, or a Controller which manages a pool of tunnels, or any other object which implements Tunneler. alwaysTunnel indicates that the connection should always be tunneled. If this is not set, the connection may be made directly, depending on split tunnel classification, when that feature is supported and active. downstreamConn is an optional parameter which specifies a connection to be explictly closed when the Dialed connection is closed. For instance, this is used to close downstreamConn App<->LocalProxy connections when the related LocalProxy<->SshPortForward connections close.
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
Package stats counts and keeps track of session stats.
|
Package stats counts and keeps track of session stats. |