diff --git a/go.mod b/go.mod index c8e4eebd..a68230bc 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,6 @@ go 1.19 require ( cloud.google.com/go/errorreporting v0.3.0 - git.torproject.org/pluggable-transports/goptlib.git v1.2.0 github.com/Jigsaw-Code/outline-ss-server v1.4.0 github.com/OperatorFoundation/Replicant-go/Replicant/v3 v3.0.23 github.com/OperatorFoundation/Starbridge-go/Starbridge/v3 v3.0.17 @@ -41,20 +40,17 @@ require ( github.com/getlantern/tlsmasq v0.4.7-0.20230302000139-6e479a593298 github.com/getlantern/tlsutil v0.5.3 github.com/getlantern/waitforserver v1.0.1 - github.com/getlantern/withtimeout v0.0.0-20160829163843-511f017cd913 github.com/go-redis/redis/v8 v8.11.5 github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da github.com/hashicorp/golang-lru v0.5.4 github.com/mitchellh/panicwrap v1.0.0 github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 - github.com/quic-go/quic-go v0.40.0 github.com/refraction-networking/utls v1.3.3 github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726 github.com/spaolacci/murmur3 v1.1.0 github.com/stretchr/testify v1.8.4 github.com/vharitonsky/iniflags v0.0.0-20180513140207-a33cd0b5f3de github.com/xtaci/smux v1.5.24 - gitlab.com/yawning/obfs4.git v0.0.0-20220204003609-77af0cba934d go.opentelemetry.io/otel v1.19.0 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.42.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 @@ -70,7 +66,6 @@ require ( require ( cloud.google.com/go/compute v1.23.0 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect - filippo.io/edwards25519 v1.0.0 // indirect github.com/OperatorFoundation/ghostwriter-go v1.0.6 // indirect github.com/OperatorFoundation/go-bloom v1.0.1 // indirect github.com/OperatorFoundation/go-shadowsocks2 v1.2.1 // indirect @@ -81,7 +76,6 @@ require ( github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/dchest/siphash v1.2.3 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect github.com/dvyukov/go-fuzz v0.0.0-20210429054444-fca39067bc72 // indirect @@ -159,6 +153,7 @@ require ( github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/quic-go/qtls-go1-20 v0.4.1 // indirect + github.com/quic-go/quic-go v0.40.0 // indirect github.com/shadowsocks/go-shadowsocks2 v0.1.4-0.20201002022019-75d43273f5a5 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8 // indirect @@ -172,7 +167,6 @@ require ( github.com/ulikunitz/xz v0.5.10 // indirect github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect - gitlab.com/yawning/edwards25519-extra.git v0.0.0-20211229043746-2f91fcc9fbdb // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.42.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.42.0 // indirect diff --git a/go.sum b/go.sum index df6415f7..f2904d88 100644 --- a/go.sum +++ b/go.sum @@ -6,12 +6,6 @@ cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGB cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/errorreporting v0.3.0 h1:kj1XEWMu8P0qlLhm3FwcaFsUvXChV/OraZwA70trRR0= cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU= -filippo.io/edwards25519 v1.0.0-rc.1.0.20210721174708-390f27c3be20/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= -filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= -filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= -git.torproject.org/pluggable-transports/goptlib.git v1.0.0/go.mod h1:YT4XMSkuEXbtqlydr9+OxqFAyspUv0Gr9qhM3B++o/Q= -git.torproject.org/pluggable-transports/goptlib.git v1.2.0 h1:0qRF7Dw5qXd0FtZkjWUiAh5GTutRtDGL4GXUDJ4qMHs= -git.torproject.org/pluggable-transports/goptlib.git v1.2.0/go.mod h1:4PBMl1dg7/3vMWSoWb46eGWlrxkUyn/CAJmxhDLAlDs= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/OperatorFoundation/Replicant-go/Replicant/v3 v3.0.23 h1:g0kC1BDonLwNse78HRsudElKEDfXHusLQ9Nfekl/l0o= github.com/OperatorFoundation/Replicant-go/Replicant/v3 v3.0.23/go.mod h1:QVlygHzbNc/fX+OHurCRC0AFwISJAUQbPaqdEfAkUio= @@ -47,9 +41,6 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dchest/siphash v1.2.1/go.mod h1:q+IRvb2gOSrUnYoPqHiyHXS0FOBBOdl6tONBlVnOnt4= -github.com/dchest/siphash v1.2.3 h1:QXwFc8cFOR2dSa/gE6o/HokBMWtLUaNDVd+22aKHeEA= -github.com/dchest/siphash v1.2.3/go.mod h1:0NvQU092bT0ipiFN++/rXm69QG9tVxLAlQHIXMPAkHc= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 h1:iFaUwBSo5Svw6L7HYpRu/0lE3e0BaElwnNO1qkNQxBY= @@ -517,10 +508,6 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= -gitlab.com/yawning/edwards25519-extra.git v0.0.0-20211229043746-2f91fcc9fbdb h1:qRSZHsODmAP5qDvb3YsO7Qnf3TRiVbGxNG/WYnlM4/o= -gitlab.com/yawning/edwards25519-extra.git v0.0.0-20211229043746-2f91fcc9fbdb/go.mod h1:gvdJuZuO/tPZyhEV8K3Hmoxv/DWud5L4qEQxfYjEUTo= -gitlab.com/yawning/obfs4.git v0.0.0-20220204003609-77af0cba934d h1:tJ8F7ABaQ3p3wjxwXiWSktVDgjZEXkvaRawd2rIq5ws= -gitlab.com/yawning/obfs4.git v0.0.0-20220204003609-77af0cba934d/go.mod h1:9GcM8QNU9/wXtEEH2q8bVOnPI7FtIF6VVLzZ1l6Hgf8= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.42.0 h1:pginetY7+onl4qN1vl0xW/V/v6OBZ0vVdH+esuJgvmM= @@ -570,7 +557,6 @@ golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= diff --git a/http-proxy/main.go b/http-proxy/main.go index f4fc54fb..9f93e793 100644 --- a/http-proxy/main.go +++ b/http-proxy/main.go @@ -28,7 +28,6 @@ import ( proxy "github.com/getlantern/http-proxy-lantern/v2" "github.com/getlantern/http-proxy-lantern/v2/blacklist" "github.com/getlantern/http-proxy-lantern/v2/googlefilter" - "github.com/getlantern/http-proxy-lantern/v2/obfs4listener" lanternredis "github.com/getlantern/http-proxy-lantern/v2/redis" "github.com/getlantern/http-proxy-lantern/v2/shadowsocks" "github.com/getlantern/http-proxy-lantern/v2/stackdrivererror" @@ -56,12 +55,9 @@ var ( wssAddr = flag.String("wss-addr", "", "Address at which to listen for WSS connections.") kcpConf = flag.String("kcpconf", "", "Path to file configuring kcp") - obfs4Addr = flag.String("obfs4-addr", "", "Provide an address here in order to listen with obfs4") - obfs4MultiplexAddr = flag.String("obfs4-multiplexaddr", "", "Provide an address here in order to listen with multiplexed obfs4") - obfs4Dir = flag.String("obfs4-dir", ".", "Directory where obfs4 can store its files") - obfs4HandshakeConcurrency = flag.Int("obfs4-handshake-concurrency", obfs4listener.DefaultHandshakeConcurrency, "How many concurrent OBFS4 handshakes to process") - obfs4MaxPendingHandshakesPerClient = flag.Int("obfs4-max-pending-handshakes-per-client", obfs4listener.DefaultMaxPendingHandshakesPerClient, "How many pending OBFS4 handshakes to allow per client") - obfs4HandshakeTimeout = flag.Duration("obfs4-handshake-timeout", obfs4listener.DefaultHandshakeTimeout, "How long to wait before timing out an OBFS4 handshake") + obfs4Addr = flag.String("obfs4-addr", "", "Provide an address here in order to listen with obfs4") + obfs4MultiplexAddr = flag.String("obfs4-multiplexaddr", "", "Provide an address here in order to listen with multiplexed obfs4") + obfs4Dir = flag.String("obfs4-dir", ".", "Directory where obfs4 can store its files") enhttpAddr = flag.String("enhttp-addr", "", "Address at which to accept encapsulated HTTP requests") enhttpServerURL = flag.String("enhttp-server-url", "", "specify a full URL for domain-fronting to this server with enhttp, required for sticky routing with CloudFront") @@ -374,100 +370,97 @@ func main() { } p := &proxy.Proxy{ - HTTPAddr: *addr, - HTTPMultiplexAddr: *multiplexAddr, - CertFile: *certfile, - CfgSvrAuthToken: *cfgSvrAuthToken, - ConnectOKWaitsForUpstream: *connectOKWaitsForUpstream, - EnableMultipath: *enableMultipath, - ThrottleRefreshInterval: *throttleRefreshInterval, - TracesSampleRate: *tracesSampleRate, - TeleportSampleRate: *teleportSampleRate, - ExternalIP: *externalIP, - HTTPS: *https, - IdleTimeout: time.Duration(*idleClose) * time.Second, - KeyFile: *keyfile, - SessionTicketKeys: *sessionTicketKeys, - SessionTicketKeyFile: *sessionTicketKeyFile, - FirstSessionTicketKey: *firstSessionTicketKey, - Track: *track, - Pro: *pro, - ProxiedSitesSamplePercentage: *proxiedSitesSamplePercentage, - ProxiedSitesTrackingID: *proxiedSitesTrackingId, - ReportingRedisClient: reportingRedisClient, - Token: *token, - TunnelPorts: *tunnelPorts, - Obfs4Addr: *obfs4Addr, - Obfs4MultiplexAddr: *obfs4MultiplexAddr, - Obfs4Dir: *obfs4Dir, - Obfs4HandshakeConcurrency: *obfs4HandshakeConcurrency, - Obfs4MaxPendingHandshakesPerClient: *obfs4MaxPendingHandshakesPerClient, - Obfs4HandshakeTimeout: *obfs4HandshakeTimeout, - KCPConf: *kcpConf, - ENHTTPAddr: *enhttpAddr, - ENHTTPServerURL: *enhttpServerURL, - ENHTTPReapIdleTime: *enhttpReapIdleTime, - Benchmark: *bench, - DiffServTOS: *tos, - LampshadeAddr: *lampshadeAddr, - LampshadeKeyCacheSize: *lampshadeKeyCacheSize, - LampshadeMaxClientInitAge: *lampshadeMaxClientInitAge, - VersionCheck: *versionCheck != "", - VersionCheckRange: *versionCheck, - VersionCheckRedirectURL: "https://lantern.io/outdated", - VersionCheckRedirectPercentage: *versionCheckRedirectPercentage, - GoogleSearchRegex: *googleSearchRegex, - GoogleCaptchaRegex: *googleCaptchaRegex, - BlacklistMaxIdleTime: *blacklistMaxIdleTime, - BlacklistMaxConnectInterval: *blacklistMaxConnectInterval, - BlacklistAllowedFailures: *blacklistAllowedFailures, - BlacklistExpiration: *blacklistExpiration, - ProxyName: *proxyName, - ProxyProtocol: *proxyProtocol, - Provider: *provider, - DC: *dc, - FrontendProvider: *frontendProvider, - FrontendDC: *frontendDC, - BuildType: build_type, - BBRUpstreamProbeURL: *bbrUpstreamProbeURL, - QUICIETFAddr: *quicIETFAddr, - QUICUseBBR: *quicBBR, - WSSAddr: *wssAddr, - PacketForwardAddr: *packetForwardAddr, - ExternalIntf: *externalIntf, - RequireSessionTickets: *requireSessionTickets, - MissingTicketReaction: reaction, - TLSListenerAllowTLS13: *tlsListenerAllowTLS13, - TLSMasqAddr: *tlsmasqAddr, - TLSMasqOriginAddr: *tlsmasqOriginAddr, - TLSMasqSecret: *tlsmasqSecret, - TLSMasqTLSMinVersion: tlsmasqTLSMinVersion, - TLSMasqTLSCipherSuites: tlsmasqTLSSuites, - ShadowsocksAddr: *shadowsocksAddr, - ShadowsocksMultiplexAddr: *shadowsocksMultiplexAddr, - ShadowsocksSecret: *shadowsocksSecret, - ShadowsocksCipher: *shadowsocksCipher, - ShadowsocksReplayHistory: *shadowsocksReplayHistory, - StarbridgeAddr: *starbridgeAddr, - StarbridgePrivateKey: *starbridgePrivateKey, - MultiplexProtocol: *multiplexProtocol, - SmuxVersion: *smuxVersion, - SmuxMaxFrameSize: *smuxMaxFrameSize, - SmuxMaxReceiveBuffer: *smuxMaxReceiveBuffer, - SmuxMaxStreamBuffer: *smuxMaxStreamBuffer, - PsmuxVersion: *psmuxVersion, - PsmuxMaxFrameSize: *psmuxMaxFrameSize, - PsmuxMaxReceiveBuffer: *psmuxMaxReceiveBuffer, - PsmuxMaxStreamBuffer: *psmuxMaxStreamBuffer, - PsmuxDisablePadding: *psmuxDisablePadding, - PsmuxMaxPaddingRatio: *psmuxMaxPaddingRatio, - PsmuxMaxPaddedSize: *psmuxMaxPaddedSize, - PsmuxDisableAggressivePadding: *psmuxDisableAggressivePadding, - PsmuxAggressivePadding: *psmuxAggressivePadding, - PsmuxAggressivePaddingRatio: *psmuxAggressivePaddingRatio, - BroflakeAddr: *broflakeAddr, - BroflakeCert: os.Getenv("BROFLAKE_CERT"), - BroflakeKey: os.Getenv("BROFLAKE_KEY"), + HTTPAddr: *addr, + HTTPMultiplexAddr: *multiplexAddr, + CertFile: *certfile, + CfgSvrAuthToken: *cfgSvrAuthToken, + ConnectOKWaitsForUpstream: *connectOKWaitsForUpstream, + EnableMultipath: *enableMultipath, + ThrottleRefreshInterval: *throttleRefreshInterval, + TracesSampleRate: *tracesSampleRate, + TeleportSampleRate: *teleportSampleRate, + ExternalIP: *externalIP, + HTTPS: *https, + IdleTimeout: time.Duration(*idleClose) * time.Second, + KeyFile: *keyfile, + SessionTicketKeys: *sessionTicketKeys, + SessionTicketKeyFile: *sessionTicketKeyFile, + FirstSessionTicketKey: *firstSessionTicketKey, + Track: *track, + Pro: *pro, + ProxiedSitesSamplePercentage: *proxiedSitesSamplePercentage, + ProxiedSitesTrackingID: *proxiedSitesTrackingId, + ReportingRedisClient: reportingRedisClient, + Token: *token, + TunnelPorts: *tunnelPorts, + Obfs4Addr: *obfs4Addr, + Obfs4MultiplexAddr: *obfs4MultiplexAddr, + Obfs4Dir: *obfs4Dir, + KCPConf: *kcpConf, + ENHTTPAddr: *enhttpAddr, + ENHTTPServerURL: *enhttpServerURL, + ENHTTPReapIdleTime: *enhttpReapIdleTime, + Benchmark: *bench, + DiffServTOS: *tos, + LampshadeAddr: *lampshadeAddr, + LampshadeKeyCacheSize: *lampshadeKeyCacheSize, + LampshadeMaxClientInitAge: *lampshadeMaxClientInitAge, + VersionCheck: *versionCheck != "", + VersionCheckRange: *versionCheck, + VersionCheckRedirectURL: "https://lantern.io/outdated", + VersionCheckRedirectPercentage: *versionCheckRedirectPercentage, + GoogleSearchRegex: *googleSearchRegex, + GoogleCaptchaRegex: *googleCaptchaRegex, + BlacklistMaxIdleTime: *blacklistMaxIdleTime, + BlacklistMaxConnectInterval: *blacklistMaxConnectInterval, + BlacklistAllowedFailures: *blacklistAllowedFailures, + BlacklistExpiration: *blacklistExpiration, + ProxyName: *proxyName, + ProxyProtocol: *proxyProtocol, + Provider: *provider, + DC: *dc, + FrontendProvider: *frontendProvider, + FrontendDC: *frontendDC, + BuildType: build_type, + BBRUpstreamProbeURL: *bbrUpstreamProbeURL, + QUICIETFAddr: *quicIETFAddr, + QUICUseBBR: *quicBBR, + WSSAddr: *wssAddr, + PacketForwardAddr: *packetForwardAddr, + ExternalIntf: *externalIntf, + RequireSessionTickets: *requireSessionTickets, + MissingTicketReaction: reaction, + TLSListenerAllowTLS13: *tlsListenerAllowTLS13, + TLSMasqAddr: *tlsmasqAddr, + TLSMasqOriginAddr: *tlsmasqOriginAddr, + TLSMasqSecret: *tlsmasqSecret, + TLSMasqTLSMinVersion: tlsmasqTLSMinVersion, + TLSMasqTLSCipherSuites: tlsmasqTLSSuites, + ShadowsocksAddr: *shadowsocksAddr, + ShadowsocksMultiplexAddr: *shadowsocksMultiplexAddr, + ShadowsocksSecret: *shadowsocksSecret, + ShadowsocksCipher: *shadowsocksCipher, + ShadowsocksReplayHistory: *shadowsocksReplayHistory, + StarbridgeAddr: *starbridgeAddr, + StarbridgePrivateKey: *starbridgePrivateKey, + MultiplexProtocol: *multiplexProtocol, + SmuxVersion: *smuxVersion, + SmuxMaxFrameSize: *smuxMaxFrameSize, + SmuxMaxReceiveBuffer: *smuxMaxReceiveBuffer, + SmuxMaxStreamBuffer: *smuxMaxStreamBuffer, + PsmuxVersion: *psmuxVersion, + PsmuxMaxFrameSize: *psmuxMaxFrameSize, + PsmuxMaxReceiveBuffer: *psmuxMaxReceiveBuffer, + PsmuxMaxStreamBuffer: *psmuxMaxStreamBuffer, + PsmuxDisablePadding: *psmuxDisablePadding, + PsmuxMaxPaddingRatio: *psmuxMaxPaddingRatio, + PsmuxMaxPaddedSize: *psmuxMaxPaddedSize, + PsmuxDisableAggressivePadding: *psmuxDisableAggressivePadding, + PsmuxAggressivePadding: *psmuxAggressivePadding, + PsmuxAggressivePaddingRatio: *psmuxAggressivePaddingRatio, + BroflakeAddr: *broflakeAddr, + BroflakeCert: os.Getenv("BROFLAKE_CERT"), + BroflakeKey: os.Getenv("BROFLAKE_KEY"), } if *maxmindLicenseKey != "" { log.Debug("Will use Maxmind for geolocating clients") diff --git a/http_proxy.go b/http_proxy.go index 514dad7f..94edc3b8 100644 --- a/http_proxy.go +++ b/http_proxy.go @@ -56,7 +56,6 @@ import ( "github.com/getlantern/http-proxy-lantern/v2/instrument" "github.com/getlantern/http-proxy-lantern/v2/lampshade" "github.com/getlantern/http-proxy-lantern/v2/mimic" - "github.com/getlantern/http-proxy-lantern/v2/obfs4listener" "github.com/getlantern/http-proxy-lantern/v2/ping" "github.com/getlantern/http-proxy-lantern/v2/redis" "github.com/getlantern/http-proxy-lantern/v2/throttle" @@ -294,13 +293,6 @@ func (p *Proxy) ListenAndServe(ctx context.Context) error { } addListenersForBaseTransport := func(baseListen func(string) (net.Listener, error), addrs *addresses) error { - if err := addListenerIfNecessary("obfs4", addrs.obfs4, p.listenOBFS4(baseListen)); err != nil { - return err - } - if err := addListenerIfNecessary("obfs4_multiplex", addrs.obfs4Multiplex, p.wrapMultiplexing(p.listenOBFS4(baseListen))); err != nil { - return err - } - // We pass onListenerError to lampshade so that we can count errors in its // internal connection handling. var err error @@ -789,22 +781,6 @@ func (p *Proxy) listenHTTP(baseListen func(string) (net.Listener, error)) listen } } -func (p *Proxy) listenOBFS4(baseListen func(string) (net.Listener, error)) listenerBuilderFN { - return func(addr string) (net.Listener, error) { - l, err := baseListen(addr) - if err != nil { - return nil, errors.New("Unable to listen for OBFS4: %v", err) - } - wrapped, err := obfs4listener.Wrap(l, p.Obfs4Dir, p.Obfs4HandshakeConcurrency, p.Obfs4MaxPendingHandshakesPerClient, p.Obfs4HandshakeTimeout) - if err != nil { - l.Close() - return nil, errors.New("Unable to wrap listener with OBFS4: %v", err) - } - log.Debugf("Listening for OBFS4 at %v", wrapped.Addr()) - return wrapped, nil - } -} - func (p *Proxy) listenLampshade(onListenerError func(net.Conn, error), baseListen func(string) (net.Listener, error)) listenerBuilderFN { return func(addr string) (net.Listener, error) { l, err := baseListen(addr) diff --git a/obfs4listener/obfs4listener.go b/obfs4listener/obfs4listener.go deleted file mode 100644 index d6245fa1..00000000 --- a/obfs4listener/obfs4listener.go +++ /dev/null @@ -1,233 +0,0 @@ -package obfs4listener - -import ( - "fmt" - "net" - "os" - "sync" - "sync/atomic" - "time" - - "github.com/getlantern/golog" - "github.com/getlantern/withtimeout" - - pt "git.torproject.org/pluggable-transports/goptlib.git" - "gitlab.com/yawning/obfs4.git/transports/base" - "gitlab.com/yawning/obfs4.git/transports/obfs4" -) - -const ( - DefaultHandshakeConcurrency = 1024 - DefaultMaxPendingHandshakesPerClient = 512 - DefaultHandshakeTimeout = 10 * time.Second -) - -var ( - log = golog.LoggerFor("obfs4listener") -) - -func Wrap(wrapped net.Listener, stateDir string, handshakeConcurrency int, maxPendingHandshakesPerClient int, handshakeTimeout time.Duration) (net.Listener, error) { - err := os.MkdirAll(stateDir, 0700) - if err != nil { - return nil, fmt.Errorf("Unable to make statedir at %v: %v", stateDir, err) - } - - tr := &obfs4.Transport{} - sf, err := tr.ServerFactory(stateDir, &pt.Args{}) - if err != nil { - return nil, fmt.Errorf("Unable to create obfs4 server factory: %v", err) - } - - if handshakeConcurrency <= 0 { - handshakeConcurrency = DefaultHandshakeConcurrency - } - if maxPendingHandshakesPerClient <= 0 { - maxPendingHandshakesPerClient = DefaultMaxPendingHandshakesPerClient - } - if handshakeTimeout <= 0 { - handshakeTimeout = DefaultHandshakeTimeout - } - - log.Debugf("Handshake Concurrency: %d", handshakeConcurrency) - log.Debugf("Max Pending Handshakes Per Client: %d", maxPendingHandshakesPerClient) - log.Debugf("Handshake Timeout: %v", handshakeTimeout) - - var clientsFinished sync.WaitGroup - - ol := &obfs4listener{ - handshakeTimeout: handshakeTimeout, - maxPendingHandshakesPerClient: maxPendingHandshakesPerClient, - wrapped: wrapped, - sf: sf, - clientsFinished: &clientsFinished, - clients: make(map[string]*client), - pending: make(chan net.Conn, handshakeConcurrency), - ready: make(chan *result), - } - - go ol.accept() - for i := 0; i < handshakeConcurrency; i++ { - go ol.wrapPending() - } - go ol.monitor() - return ol, nil -} - -type client struct { - newConns chan net.Conn - wg *sync.WaitGroup -} - -type result struct { - conn net.Conn - err error -} - -type obfs4listener struct { - handshakeTimeout time.Duration - maxPendingHandshakesPerClient int - wrapped net.Listener - sf base.ServerFactory - clientsFinished *sync.WaitGroup - clients map[string]*client - pending chan net.Conn - ready chan *result - numClients int64 - handshaking int64 - closeMx sync.Mutex - closed bool -} - -func (l *obfs4listener) Accept() (net.Conn, error) { - r, ok := <-l.ready - if !ok { - return nil, fmt.Errorf("Closed") - } - return r.conn, r.err -} - -func (l *obfs4listener) Addr() net.Addr { - return l.wrapped.Addr() -} - -func (l *obfs4listener) Close() error { - l.closeMx.Lock() - defer l.closeMx.Unlock() - - if l.closed { - return nil - } - l.closed = true - - err := l.wrapped.Close() - go func() { - // Drain ready - for result := range l.ready { - if result.conn != nil { - result.conn.Close() - } - } - }() - return err -} - -func (l *obfs4listener) accept() { - defer func() { - for _, client := range l.clients { - close(client.newConns) - } - l.clientsFinished.Wait() - close(l.pending) - close(l.ready) - }() - - for { - conn, err := l.wrapped.Accept() - if err != nil { - l.ready <- &result{nil, err} - return - } - // WrapConn does a handshake with the client, which involves io operations - // and can time out. We do it on a separate goroutine, but we limit it to - // one goroutine per remote address. - remoteAddr := conn.RemoteAddr().String() - remoteHost, _, err := net.SplitHostPort(remoteAddr) - if err != nil { - log.Errorf("Unable to determine host for address %v: %v", remoteAddr, err) - conn.Close() - continue - } - cl := l.clients[remoteHost] - if cl == nil { - cl = &client{ - newConns: make(chan net.Conn, l.maxPendingHandshakesPerClient), - wg: l.clientsFinished, - } - l.clientsFinished.Add(1) - l.clients[remoteHost] = cl - atomic.AddInt64(&l.numClients, 1) - go cl.wrapIncoming(l.pending) - } - select { - case cl.newConns <- conn: - // will handshake - default: - log.Errorf("Too many pending handshakes for client at %v, ignoring new connections", remoteAddr) - conn.Close() - } - } -} - -func (c *client) wrapIncoming(pending chan net.Conn) { - for conn := range c.newConns { - pending <- conn - } -} - -func (l *obfs4listener) wrapPending() { - for conn := range l.pending { - l.wrap(conn) - } -} - -func (l *obfs4listener) wrap(conn net.Conn) { - atomic.AddInt64(&l.handshaking, 1) - defer atomic.AddInt64(&l.handshaking, -1) - start := time.Now() - _wrapped, timedOut, err := withtimeout.Do(l.handshakeTimeout, func() (interface{}, error) { - o, err := l.sf.WrapConn(conn) - if err != nil { - return nil, err - } - return &obfs4Conn{Conn: o, wrapped: conn}, nil - }) - - if timedOut { - log.Tracef("Handshake with %v timed out", conn.RemoteAddr()) - conn.Close() - } else if err != nil { - log.Tracef("Handshake error with %v: %v", conn.RemoteAddr(), err) - conn.Close() - } else { - log.Tracef("Successful obfs4 handshake in %v", time.Now().Sub(start)) - l.ready <- &result{_wrapped.(net.Conn), err} - } -} - -func (l *obfs4listener) monitor() { - for { - time.Sleep(5 * time.Second) - log.Debugf("Number of clients: %d", atomic.LoadInt64(&l.numClients)) - log.Debugf("Connections waiting to start handshaking: %d", len(l.pending)) - log.Debugf("Currently handshaking connections: %d", atomic.LoadInt64(&l.handshaking)) - } -} - -type obfs4Conn struct { - net.Conn - wrapped net.Conn -} - -func (conn *obfs4Conn) Wrapped() net.Conn { - return conn.wrapped -} diff --git a/obfs4listener/obfs4listener_test.go b/obfs4listener/obfs4listener_test.go deleted file mode 100644 index 51e545b3..00000000 --- a/obfs4listener/obfs4listener_test.go +++ /dev/null @@ -1,74 +0,0 @@ -package obfs4listener - -import ( - "io" - "io/ioutil" - "net" - _ "net/http/pprof" - "os" - "testing" - - "github.com/stretchr/testify/assert" - "gitlab.com/yawning/obfs4.git/transports/obfs4" -) - -func TestRoundTrip(t *testing.T) { - tmpDir, err := ioutil.TempDir("", "obfs4listener-test") - if !assert.NoError(t, err, "Unable to create tempdir") { - return - } - defer os.RemoveAll(tmpDir) - - wrapped, err := net.Listen("tcp", "localhost:0") - if !assert.NoError(t, err, "Unable to create listener") { - return - } - - l, err := Wrap(wrapped, tmpDir, 1, 100, DefaultHandshakeTimeout) - if !assert.NoError(t, err, "Unable to wrap listener") { - return - } - defer l.Close() - - go func() { - for { - conn, err := l.Accept() - if err == nil { - // Echo - io.Copy(conn, conn) - } - } - }() - - b := []byte("Hi There") - - tr := &obfs4.Transport{} - cf, err := tr.ClientFactory("") - if !assert.NoError(t, err, "Unable to create client factory") { - return - } - - args, err := cf.ParseArgs(l.(*obfs4listener).sf.Args()) - if !assert.NoError(t, err, "Unable to parse client args") { - return - } - - conn, err := cf.Dial("tcp", l.Addr().String(), func(network, addr string) (net.Conn, error) { - return net.Dial(network, addr) - }, args) - if !assert.NoError(t, err, "Unable to dial good conn") { - return - } - defer conn.Close() - - _, err = conn.Write(b) - if !assert.NoError(t, err, "Unable to write") { - return - } - e := make([]byte, len(b)) - _, err = conn.Read(e) - if !assert.NoError(t, err, "Unable to read") { - return - } - assert.Equal(t, string(b), string(e), "Echoed did not match written") -}