diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4513e8ed41dcda0c07ba83ff5dc6e3b4080971a2..f2e3e35935808bce1511ef1ba48fb0d4b743cc45 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,30 @@
 # IPtProxy Changelog
 
+## 1.7.1
+- Fixed Snowflake Proxy support.
+
+## 1.7.0
+- Update Snowflake to latest version 2.3.0.
+- Added `IPtProxySnowflakeVersion` returning the version of the used Snowflake.
+
+## 1.6.0
+- Update Snowflake to latest version 2.2.0.
+- Added `IPtProxyObfs4ProxyVersion` returning the version of the used Obfs4proxy.
+- Use latest Android NDK v24.0 which raises the minimally supported Android API level to 19.
+- Added support for MacOS.
+
+## 1.5.1
+- Update Snowflake to latest main. Contains a crash fix.
+- Added `IsSnowflakeProxyRunning` method to easily check,
+  if the Snowflake Proxy is running.
+- Exposed `IsPortAvailable` so consumers don't need to 
+  implement this themselves, if they happen to do something similar.
+
+## 1.5.0
+- Updated Obfs4proxy to latest version 0.0.13.
+- Updated Snowflake to latest version 2.1.0.
+- Fixed bug when stopping Snowflake proxy. (Thanks bitmold!)
+
 ## 1.4.0
 - Updated Obfs4proxy to latest 0.0.13-dev which fixes a bug which made prior 
   versions distinguishable.
diff --git a/IPtProxy-sources.jar b/IPtProxy-sources.jar
index fcbad6de6016e254f4a5af1ac44deb343cd0d1eb..7b86497135e18d4b69280959ba858a5f4d6c6b19 100644
Binary files a/IPtProxy-sources.jar and b/IPtProxy-sources.jar differ
diff --git a/IPtProxy.aar b/IPtProxy.aar
index 3f437fd572e421339741dfb6111769cd32b6f7f0..0b1a777b1ed672e0ffd6a6a400ed7dc00f101e01 100644
Binary files a/IPtProxy.aar and b/IPtProxy.aar differ
diff --git a/IPtProxy.go/IPtProxy.go b/IPtProxy.go/IPtProxy.go
index 977166b18c126c89445b2c086cc3f946158035bd..c2b9b2f5b1a5511ebf5a5f80fa839b40fb0c41c5 100644
--- a/IPtProxy.go/IPtProxy.go
+++ b/IPtProxy.go/IPtProxy.go
@@ -12,12 +12,14 @@ import (
 	"runtime"
 	"strconv"
 	"time"
+	"runtime/debug"
 )
 
 var meekPort = 47000
 
 // MeekPort - Port where Obfs4proxy will provide its Meek service.
 // Only use this after calling StartObfs4Proxy! It might have changed after that!
+//
 //goland:noinspection GoUnusedExportedFunction
 func MeekPort() int {
 	return meekPort
@@ -27,6 +29,7 @@ var obfs2Port = 47100
 
 // Obfs2Port - Port where Obfs4proxy will provide its Obfs2 service.
 // Only use this property after calling StartObfs4Proxy! It might have changed after that!
+//
 //goland:noinspection GoUnusedExportedFunction
 func Obfs2Port() int {
 	return obfs2Port
@@ -36,6 +39,7 @@ var obfs3Port = 47200
 
 // Obfs3Port - Port where Obfs4proxy will provide its Obfs3 service.
 // Only use this property after calling StartObfs4Proxy! It might have changed after that!
+//
 //goland:noinspection GoUnusedExportedFunction
 func Obfs3Port() int {
 	return obfs3Port
@@ -45,6 +49,7 @@ var obfs4Port = 47300
 
 // Obfs4Port - Port where Obfs4proxy will provide its Obfs4 service.
 // Only use this property after calling StartObfs4Proxy! It might have changed after that!
+//
 //goland:noinspection GoUnusedExportedFunction
 func Obfs4Port() int {
 	return obfs4Port
@@ -54,6 +59,7 @@ var scramblesuitPort = 47400
 
 // ScramblesuitPort - Port where Obfs4proxy will provide its Scramblesuit service.
 // Only use this property after calling StartObfs4Proxy! It might have changed after that!
+//
 //goland:noinspection GoUnusedExportedFunction
 func ScramblesuitPort() int {
 	return scramblesuitPort
@@ -63,6 +69,7 @@ var snowflakePort = 52000
 
 // SnowflakePort - Port where Snowflake will provide its service.
 // Only use this property after calling StartSnowflake! It might have changed after that!
+//
 //goland:noinspection GoUnusedExportedFunction
 func SnowflakePort() int {
 	return snowflakePort
@@ -85,6 +92,36 @@ func init() {
 	StateLocation += "/pt_state"
 }
 
+// Obfs4ProxyVersion - The version of Obfs4Proxy bundled with IPtProxy.
+//
+//goland:noinspection GoUnusedExportedFunction
+func Obfs4ProxyVersion() string {
+    return obfs4proxy.Obfs4proxyVersion
+}
+
+// SnowflakeVersion  - The version of Snowflake bundled with IPtProxy.
+//
+//goland:noinspection GoUnusedExportedFunction
+func SnowflakeVersion() string {
+    bi, ok := debug.ReadBuildInfo()
+    if !ok {
+        log.Printf("Failed to read build info")
+        return ""
+    }
+
+    for _, dep := range bi.Deps {
+    	if dep.Path == "git.torproject.org/pluggable-transports/snowflake.git/v2" {
+    	    if dep.Version[0:1] == "v" {
+        		return dep.Version[1:len(dep.Version)]
+    	    } else {
+    	        return dep.Version
+    	    }
+    	}
+    }
+
+    return ""
+}
+
 // StartObfs4Proxy - Start the Obfs4Proxy.
 //
 // This will test, if the default ports are available. If not, it will increment them until there is.
@@ -101,7 +138,6 @@ func init() {
 // @return Port number where Obfs4Proxy will listen on for Obfs4(!), if no error happens during start up.
 //	If you need the other ports, check MeekPort, Obfs2Port, Obfs3Port and ScramblesuitPort properties!
 //
-//
 //goland:noinspection GoUnusedExportedFunction
 func StartObfs4Proxy(logLevel string, enableLogging, unsafeLogging bool, proxy string) int {
 	if obfs4ProxyRunning {
@@ -110,7 +146,7 @@ func StartObfs4Proxy(logLevel string, enableLogging, unsafeLogging bool, proxy s
 
 	obfs4ProxyRunning = true
 
-	for !isAvailable(meekPort) {
+	for !IsPortAvailable(meekPort) {
 		meekPort++
 	}
 
@@ -118,7 +154,7 @@ func StartObfs4Proxy(logLevel string, enableLogging, unsafeLogging bool, proxy s
 		obfs2Port = meekPort + 1
 	}
 
-	for !isAvailable(obfs2Port) {
+	for !IsPortAvailable(obfs2Port) {
 		obfs2Port++
 	}
 
@@ -126,7 +162,7 @@ func StartObfs4Proxy(logLevel string, enableLogging, unsafeLogging bool, proxy s
 		obfs3Port = obfs2Port + 1
 	}
 
-	for !isAvailable(obfs3Port) {
+	for !IsPortAvailable(obfs3Port) {
 		obfs3Port++
 	}
 
@@ -134,7 +170,7 @@ func StartObfs4Proxy(logLevel string, enableLogging, unsafeLogging bool, proxy s
 		obfs4Port = obfs3Port + 1
 	}
 
-	for !isAvailable(obfs4Port) {
+	for !IsPortAvailable(obfs4Port) {
 		obfs4Port++
 	}
 
@@ -142,7 +178,7 @@ func StartObfs4Proxy(logLevel string, enableLogging, unsafeLogging bool, proxy s
 		scramblesuitPort = obfs4Port + 1
 	}
 
-	for !isAvailable(scramblesuitPort) {
+	for !IsPortAvailable(scramblesuitPort) {
 		scramblesuitPort++
 	}
 
@@ -160,6 +196,7 @@ func StartObfs4Proxy(logLevel string, enableLogging, unsafeLogging bool, proxy s
 }
 
 // StopObfs4Proxy - Stop the Obfs4Proxy.
+//
 //goland:noinspection GoUnusedExportedFunction
 func StopObfs4Proxy() {
 	if !obfs4ProxyRunning {
@@ -202,7 +239,7 @@ func StartSnowflake(ice, url, front, ampCache, logFile string, logToStateDir, ke
 
 	snowflakeRunning = true
 
-	for !isAvailable(snowflakePort) {
+	for !IsPortAvailable(snowflakePort) {
 		snowflakePort++
 	}
 
@@ -214,6 +251,7 @@ func StartSnowflake(ice, url, front, ampCache, logFile string, logToStateDir, ke
 }
 
 // StopSnowflake - Stop the Snowflake client.
+//
 //goland:noinspection GoUnusedExportedFunction
 func StopSnowflake() {
 	if !snowflakeRunning {
@@ -264,13 +302,16 @@ func StartSnowflakeProxy(capacity int, broker, relay, stun, natProbe, logFile st
 		capacity = 0
 	}
 
-	snowflakeProxy = &sfp.SnowflakeProxy{
+	snowflakeProxy = &sfp.SnowflakeProxy {
 		Capacity:           uint(capacity),
 		STUNURL:            stun,
 		BrokerURL:          broker,
 		KeepLocalAddresses: keepLocalAddresses,
 		RelayURL:           relay,
 		NATProbeURL:        natProbe,
+		ProxyType:          "iptproxy",
+		RelayDomainNamePattern: "snowflake.torproject.net$",
+		AllowNonTLSRelay: false,
 		ClientConnectedCallback: func() {
 			if clientConnected != nil {
 				clientConnected.Connected()
@@ -284,9 +325,8 @@ func StartSnowflakeProxy(capacity int, broker, relay, stun, natProbe, logFile st
 		var logOutput io.Writer = os.Stderr
 		log.SetFlags(log.LstdFlags | log.LUTC)
 
-		log.SetFlags(log.LstdFlags | log.LUTC)
 		if logFile != "" {
-			f, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
+			f, err := os.OpenFile(logFile, os.O_CREATE | os.O_WRONLY | os.O_APPEND, 0600)
 			if err != nil {
 				log.Fatal(err)
 			}
@@ -308,17 +348,40 @@ func StartSnowflakeProxy(capacity int, broker, relay, stun, natProbe, logFile st
 	}(snowflakeProxy)
 }
 
+// IsSnowflakeProxyRunning - Checks to see if a snowflake proxy is running in your app.
+func IsSnowflakeProxyRunning() bool {
+	return snowflakeProxy != nil
+}
 // StopSnowflakeProxy - Stop the Snowflake proxy.
+//
 //goland:noinspection GoUnusedExportedFunction
 func StopSnowflakeProxy() {
 	if snowflakeProxy == nil {
 		return
 	}
 
-	go func() {
+	go func(snowflakeProxy *sfp.SnowflakeProxy) {
 		snowflakeProxy.Stop()
-		snowflakeProxy = nil
-	}()
+	}(snowflakeProxy)
+
+    snowflakeProxy = nil
+}
+
+// IsPortAvailable - Checks to see if a given port is not in use.
+//
+// @param port The port to check.
+func IsPortAvailable(port int) bool {
+	address := net.JoinHostPort("127.0.0.1", strconv.Itoa(port))
+
+	conn, err := net.DialTimeout("tcp", address, 500 * time.Millisecond)
+
+	if err != nil {
+		return true
+	}
+
+	_ = conn.Close()
+
+	return false
 }
 
 // Hack: Set some environment variables that are either
@@ -336,17 +399,3 @@ func fixEnv() {
 
 	_ = os.Setenv("TOR_PT_STATE_LOCATION", StateLocation)
 }
-
-func isAvailable(port int) bool {
-	address := net.JoinHostPort("127.0.0.1", strconv.Itoa(port))
-
-	conn, err := net.DialTimeout("tcp", address, 500*time.Millisecond)
-
-	if err != nil {
-		return true
-	}
-
-	_ = conn.Close()
-
-	return false
-}
diff --git a/IPtProxy.go/go.mod b/IPtProxy.go/go.mod
index 67a97f656101a9d8d948762f864965fed2763c46..f6b888f4c7810131ef918004337e9592ed8df6be 100644
--- a/IPtProxy.go/go.mod
+++ b/IPtProxy.go/go.mod
@@ -9,7 +9,8 @@ replace (
 )
 
 require (
-	git.torproject.org/pluggable-transports/snowflake.git/v2 v2.0.1
-	gitlab.com/yawning/obfs4.git v0.0.0-20210511220700-e330d1b7024b
-	golang.org/x/mobile v0.0.0-20211207041440-4e6c2922fdee // indirect
+	git.torproject.org/pluggable-transports/snowflake.git/v2 v2.3.0
+	gitlab.com/yawning/obfs4.git v0.0.0-20220204003609-77af0cba934d
+	golang.org/x/mobile v0.0.0-20220518205345-8578da9835fd // indirect
+	golang.org/x/tools v0.1.8-0.20211022200916-316ba0b74098 // indirect
 )
diff --git a/IPtProxy.go/go.sum b/IPtProxy.go/go.sum
index d67c167e1c8493fed883756566c5e58db53340de..a6d72e9a94e0fe64949c3942f15751bef087b6a6 100644
--- a/IPtProxy.go/go.sum
+++ b/IPtProxy.go/go.sum
@@ -34,6 +34,7 @@ github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n
 github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/clarkduvall/hyperloglog v0.0.0-20171127014514-a0107a5d8004/go.mod h1:drodPoQNro6QBO6TJ/MpMZbz8Bn2eSDtRN6jpG4VGw8=
 github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
 github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
@@ -44,13 +45,11 @@ github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfc
 github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
 github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
 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 h1:4cLinnzVJDKxTCl9B01807Yiy+W7ZzVHj/KIroQRvT4=
 github.com/dchest/siphash v1.2.1/go.mod h1:q+IRvb2gOSrUnYoPqHiyHXS0FOBBOdl6tONBlVnOnt4=
 github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
-github.com/dsnet/compress v0.0.1 h1:PlZu0n3Tuv04TzpfPbrnI0HW/YwodEXDS+oPKahKF0Q=
-github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo=
-github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=
 github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
 github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
 github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
@@ -73,6 +72,7 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V
 github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
 github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
 github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
 github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
 github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
@@ -91,6 +91,8 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W
 github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
 github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
 github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
+github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
 github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
@@ -99,12 +101,13 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
 github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
 github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/google/uuid v1.1.5/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
-github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
+github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
 github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
 github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
@@ -146,13 +149,12 @@ github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV
 github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
 github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
 github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
 github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
 github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
-github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
 github.com/klauspost/cpuid v1.2.4/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
 github.com/klauspost/cpuid v1.3.1 h1:5JNjFYYQrZeKRJ0734q51WCEEn2huer72Dc7K+R/b6s=
 github.com/klauspost/cpuid v1.3.1/go.mod h1:bYW4mA6ZgKPob1/Dlai2LviZJO7KGI3uoWLd42rAQw4=
@@ -196,17 +198,19 @@ github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi
 github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
 github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
 github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
+github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
 github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
 github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
 github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
-github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
+github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
+github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
 github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
 github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
 github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
-github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
+github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
 github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
 github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
 github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
@@ -222,50 +226,49 @@ github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtP
 github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
 github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
 github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
-github.com/pion/datachannel v1.4.21 h1:3ZvhNyfmxsAqltQrApLPQMhSFNA+aT87RqyCq4OXmf0=
-github.com/pion/datachannel v1.4.21/go.mod h1:oiNyP4gHx2DIwRzX/MFyH0Rz/Gz05OgBlayAI2hAWjg=
+github.com/pion/datachannel v1.5.2 h1:piB93s8LGmbECrpO84DnkIVWasRMk3IimbcXkTQLE6E=
+github.com/pion/datachannel v1.5.2/go.mod h1:FTGQWaHrdCwIJ1rw6xBIfZVkslikjShim5yr05XFuCQ=
 github.com/pion/dtls/v2 v2.0.12 h1:QMSvNht7FM/XDXij3Ic90SCbl5yL7kppeI4ghfF4in8=
 github.com/pion/dtls/v2 v2.0.12/go.mod h1:5Pe3QJI0Ajsx+uCfxREeewGFlKYBzLrXe9ku7Y0oRXM=
-github.com/pion/ice/v2 v2.0.15 h1:KZrwa2ciL9od8+TUVJiYTNsCW9J5lktBjGwW1MacEnQ=
-github.com/pion/ice/v2 v2.0.15/go.mod h1:ZIiVGevpgAxF/cXiIVmuIUtCb3Xs4gCzCbXB6+nFkSI=
-github.com/pion/interceptor v0.0.10 h1:dXFyFWRJFwmzQqyn0U8dUAbOJu+JJnMVAqxmvTu30B4=
-github.com/pion/interceptor v0.0.10/go.mod h1:qzeuWuD/ZXvPqOnxNcnhWfkCZ2e1kwwslicyyPnhoK4=
+github.com/pion/ice/v2 v2.2.6 h1:R/vaLlI1J2gCx141L5PEwtuGAGcyS6e7E0hDeJFq5Ig=
+github.com/pion/ice/v2 v2.2.6/go.mod h1:SWuHiOGP17lGromHTFadUe1EuPgFh/oCU6FCMZHooVE=
+github.com/pion/interceptor v0.1.11 h1:00U6OlqxA3FFB50HSg25J/8cWi7P6FbSzw4eFn24Bvs=
+github.com/pion/interceptor v0.1.11/go.mod h1:tbtKjZY14awXd7Bq0mmWvgtHB5MDaRN7HV3OZ/uy7s8=
 github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY=
 github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms=
-github.com/pion/mdns v0.0.4 h1:O4vvVqr4DGX63vzmO6Fw9vpy3lfztVWHGCQfyw0ZLSY=
-github.com/pion/mdns v0.0.4/go.mod h1:R1sL0p50l42S5lJs91oNdUL58nm0QHrhxnSegr++qC0=
+github.com/pion/mdns v0.0.5 h1:Q2oj/JB3NqfzY9xGZ1fPzZzK7sDSD8rZPOvcIQ10BCw=
+github.com/pion/mdns v0.0.5/go.mod h1:UgssrvdD3mxpi8tMxAXbsppL3vJ4Jipw1mTCW+al01g=
 github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA=
 github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8=
-github.com/pion/rtcp v1.2.6 h1:1zvwBbyd0TeEuuWftrd/4d++m+/kZSeiguxU61LFWpo=
-github.com/pion/rtcp v1.2.6/go.mod h1:52rMNPWFsjr39z9B9MhnkqhPLoeHTv1aN63o/42bWE0=
-github.com/pion/rtp v1.6.2 h1:iGBerLX6JiDjB9NXuaPzHyxHFG9JsIEdgwTC0lp5n/U=
-github.com/pion/rtp v1.6.2/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko=
-github.com/pion/sctp v1.7.10/go.mod h1:EhpTUQu1/lcK3xI+eriS6/96fWetHGCvBi9MSsnaBN0=
-github.com/pion/sctp v1.7.11 h1:UCnj7MsobLKLuP/Hh+JMiI/6W5Bs/VF45lWKgHFjSIE=
-github.com/pion/sctp v1.7.11/go.mod h1:EhpTUQu1/lcK3xI+eriS6/96fWetHGCvBi9MSsnaBN0=
-github.com/pion/sdp/v3 v3.0.4 h1:2Kf+dgrzJflNCSw3TV5v2VLeI0s/qkzy2r5jlR0wzf8=
-github.com/pion/sdp/v3 v3.0.4/go.mod h1:bNiSknmJE0HYBprTHXKPQ3+JjacTv5uap92ueJZKsRk=
-github.com/pion/srtp/v2 v2.0.2 h1:664iGzVmaY7KYS5M0gleY0DscRo9ReDfTxQrq4UgGoU=
-github.com/pion/srtp/v2 v2.0.2/go.mod h1:VEyLv4CuxrwGY8cxM+Ng3bmVy8ckz/1t6A0q/msKOw0=
+github.com/pion/rtcp v1.2.9 h1:1ujStwg++IOLIEoOiIQ2s+qBuJ1VN81KW+9pMPsif+U=
+github.com/pion/rtcp v1.2.9/go.mod h1:qVPhiCzAm4D/rxb6XzKeyZiQK69yJpbUDJSF7TgrqNo=
+github.com/pion/rtp v1.7.13 h1:qcHwlmtiI50t1XivvoawdCGTP4Uiypzfrsap+bijcoA=
+github.com/pion/rtp v1.7.13/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko=
+github.com/pion/sctp v1.8.0/go.mod h1:xFe9cLMZ5Vj6eOzpyiKjT9SwGM4KpK/8Jbw5//jc+0s=
+github.com/pion/sctp v1.8.2 h1:yBBCIrUMJ4yFICL3RIvR4eh/H2BTTvlligmSTy+3kiA=
+github.com/pion/sctp v1.8.2/go.mod h1:xFe9cLMZ5Vj6eOzpyiKjT9SwGM4KpK/8Jbw5//jc+0s=
+github.com/pion/sdp/v3 v3.0.5 h1:ouvI7IgGl+V4CrqskVtr3AaTrPvPisEOxwgpdktctkU=
+github.com/pion/sdp/v3 v3.0.5/go.mod h1:iiFWFpQO8Fy3S5ldclBkpXqmWy02ns78NOKoLLL0YQw=
+github.com/pion/srtp/v2 v2.0.9 h1:JJq3jClmDFBPX/F5roEb0U19jSU7eUhyDqR/NZ34EKQ=
+github.com/pion/srtp/v2 v2.0.9/go.mod h1:5TtM9yw6lsH0ppNCehB/EjEUli7VkUgKSPJqWVqbhQ4=
 github.com/pion/stun v0.3.5 h1:uLUCBCkQby4S1cf6CGuR9QrVOKcvUwFeemaC865QHDg=
 github.com/pion/stun v0.3.5/go.mod h1:gDMim+47EeEtfWogA37n6qXZS88L5V6LqFcf+DZA2UA=
-github.com/pion/transport v0.8.10/go.mod h1:tBmha/UCjpum5hqTWhfAEs3CO4/tHSg0MYRhSzR+CZ8=
-github.com/pion/transport v0.10.1/go.mod h1:PBis1stIILMiis0PewDw91WJeLJkyIMcEk+DwKOzf4A=
-github.com/pion/transport v0.12.1/go.mod h1:N3+vZQD9HlDP5GWkZ85LohxNsDcNgofQmyL6ojX5d8Q=
 github.com/pion/transport v0.12.2/go.mod h1:N3+vZQD9HlDP5GWkZ85LohxNsDcNgofQmyL6ojX5d8Q=
-github.com/pion/transport v0.12.3 h1:vdBfvfU/0Wq8kd2yhUMSDB/x+O4Z9MYVl2fJ5BT4JZw=
 github.com/pion/transport v0.12.3/go.mod h1:OViWW9SP2peE/HbwBvARicmAVnesphkNkCVZIWJ6q9A=
-github.com/pion/turn/v2 v2.0.5 h1:iwMHqDfPEDEOFzwWKT56eFmh6DYC6o/+xnLAEzgISbA=
-github.com/pion/turn/v2 v2.0.5/go.mod h1:APg43CFyt/14Uy7heYUOGWdkem/Wu4PhCO/bjyrTqMw=
+github.com/pion/transport v0.13.0 h1:KWTA5ZrQogizzYwPEciGtHPLwpAjE91FgXnyu+Hv2uY=
+github.com/pion/transport v0.13.0/go.mod h1:yxm9uXpK9bpBBWkITk13cLo1y5/ur5VQpG22ny6EP7g=
+github.com/pion/turn/v2 v2.0.8 h1:KEstL92OUN3k5k8qxsXHpr7WWfrdp7iJZHx99ud8muw=
+github.com/pion/turn/v2 v2.0.8/go.mod h1:+y7xl719J8bAEVpSXBXvTxStjJv3hbz9YFflvkpcGPw=
 github.com/pion/udp v0.1.1 h1:8UAPvyqmsxK8oOjloDk4wUt63TzFe9WEJkg5lChlj7o=
 github.com/pion/udp v0.1.1/go.mod h1:6AFo+CMdKQm7UiA0eUPA8/eVCTx8jBIITLZHc9DWX5M=
-github.com/pion/webrtc/v3 v3.0.15 h1:g8MMJohjQoj0+pTrU329tWM6dvCieNTgnjtqv1kmEdY=
-github.com/pion/webrtc/v3 v3.0.15/go.mod h1:uUt2nRSsCnK/nfzTAfOmaeLan26ZJ0aP9iwjc/gcC2Y=
+github.com/pion/webrtc/v3 v3.1.41 h1:QogLjtriu+OwerRp4r6emTg4+zDWUy5R6EqthDBy7c0=
+github.com/pion/webrtc/v3 v3.1.41/go.mod h1:sUcW9SFPEWerDqGOBmdYEMfRvbdd7rgwo4bNzfsXww4=
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
 github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
 github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
@@ -292,6 +295,8 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx
 github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
 github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
 github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
+github.com/refraction-networking/utls v1.0.0 h1:6XQHSjDmeBCF9sPq8p2zMVGq7Ud3rTD2q88Fw8Tz1tA=
+github.com/refraction-networking/utls v1.0.0/go.mod h1:tz9gX959MEFfFN5whTIocCLUG57WiILqtdVxI8c6Wj0=
 github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
 github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
@@ -303,7 +308,9 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV
 github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
 github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
 github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
 github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
 github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
 github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
@@ -317,8 +324,11 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/templexxx/cpu v0.0.1/go.mod h1:w7Tb+7qgcAlIyX4NhLuDKt78AHA5SzPmq0Wj6HiEnnk=
 github.com/templexxx/cpu v0.0.7 h1:pUEZn8JBy/w5yzdYWgx+0m0xL9uk6j4K91C5kOViAzo=
 github.com/templexxx/cpu v0.0.7/go.mod h1:w7Tb+7qgcAlIyX4NhLuDKt78AHA5SzPmq0Wj6HiEnnk=
@@ -327,23 +337,21 @@ github.com/templexxx/xorsimd v0.4.1/go.mod h1:W+ffZz8jJMH2SXwuKu9WhygqBMbFnp14G2
 github.com/tjfoc/gmsm v1.3.2 h1:7JVkAn5bvUJ7HtU08iW6UiD+UTmJTIToHCfeFzkcCxM=
 github.com/tjfoc/gmsm v1.3.2/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w=
 github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
-github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
 github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
 github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
 github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
 github.com/xtaci/kcp-go/v5 v5.6.1 h1:Pwn0aoeNSPF9dTS7IgiPXn0HEtaIlVb6y5UKWPsx8bI=
 github.com/xtaci/kcp-go/v5 v5.6.1/go.mod h1:W3kVPyNYwZ06p79dNwFWQOVFrdcBpDBsdyvK8moQrYo=
+github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae h1:J0GxkO96kL4WF+AIT3M4mfUVinOCPgf2uUWYFUzN0sM=
 github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE=
 github.com/xtaci/smux v1.5.15 h1:6hMiXswcleXj5oNfcJc+DXS8Vj36XX2LaX98udog6Kc=
 github.com/xtaci/smux v1.5.15/go.mod h1:OMlQbT5vcgl2gb49mFkYo6SMf+zP3rcjcwQz7ZU7IGY=
 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
-gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec h1:FpfFs4EhNehiVfzQttTuxanPIT43FtkkCFypIod8LHo=
-gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec/go.mod h1:BZ1RAoRPbCxum9Grlv5aeksu2H8BiKehBYooU2LFiOQ=
+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/utls.git v0.0.12-1 h1:RL6O0MP2YI0KghuEU/uGN6+8b4183eqNWoYgx7CXD0U=
-gitlab.com/yawning/utls.git v0.0.12-1/go.mod h1:3ONKiSFR9Im/c3t5RKmMJTVdmZN496FNyk3mjrY1dyo=
 gitlab.torproject.org/tpo/anti-censorship/geoip v0.0.0-20210928150955-7ce4b3d98d01/go.mod h1:K3LOI4H8fa6j+7E10ViHeGEQV10304FG4j94ypmKLjY=
 go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
 go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
@@ -361,17 +369,16 @@ golang.org/x/arch v0.0.0-20190909030613-46d78d1859ac/go.mod h1:flIaEI6LNU6xOCD5P
 golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20210317152858-513c2a44f670/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
 golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 h1:/pEO3GD/ABYAjuakUS6xSEmmlyVS4kxBNkeA9tLJiTI=
 golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.0.0-20220516162934-403b01795ae8 h1:y+mHpWoQJNAHt26Nhh6JP7hvM71IRZureyvZhoVALIs=
+golang.org/x/crypto v0.0.0-20220516162934-403b01795ae8/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4=
 golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
@@ -382,8 +389,8 @@ golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTk
 golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
 golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
 golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
-golang.org/x/mobile v0.0.0-20211207041440-4e6c2922fdee h1:/tShaw8UTf0XzI8DOZwQHzC7d6Vi3EtrBnftiZ4vAvU=
-golang.org/x/mobile v0.0.0-20211207041440-4e6c2922fdee/go.mod h1:pe2sM7Uk+2Su1y7u/6Z8KJ24D7lepUjFZbhFOrmDfuQ=
+golang.org/x/mobile v0.0.0-20220518205345-8578da9835fd h1:x1GptNaTtxPAlTVIAJk61fuXg0y17h09DTxyb+VNC/k=
+golang.org/x/mobile v0.0.0-20220518205345-8578da9835fd/go.mod h1:pe2sM7Uk+2Su1y7u/6Z8KJ24D7lepUjFZbhFOrmDfuQ=
 golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
 golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
 golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
@@ -402,26 +409,26 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r
 golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190328230028-74de082e2cca/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
 golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
 golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
 golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
-golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20201201195509-5d6afe98e0b7/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
+golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
 golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20211201190559-0a0e4e1bb54c h1:WtYZ93XtWSO5KlOMgPZu7hXY9WhMZpprvlm5VwvAl8c=
 golang.org/x/net v0.0.0-20211201190559-0a0e4e1bb54c/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20220401154927-543a649e0bdd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
+golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA=
+golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -431,6 +438,7 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -446,7 +454,6 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190804053845-51ab0e2deafa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -454,26 +461,27 @@ golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200808120158-1030fc2bf1d9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210317225723-c4fcb01b228e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e h1:WUoyKPm6nCo1BnNUvPGnFG3T5DUVem42yDJZZ4CNxMA=
 golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
+golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -493,6 +501,7 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
 golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20200425043458-8463f397d07c/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20200808161706-5bf02b21f123/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
 golang.org/x/tools v0.1.8-0.20211022200916-316ba0b74098 h1:YuekqPskqwCCPM79F1X5Dhv4ezTCj+Ki1oNwiafxkA0=
 golang.org/x/tools v0.1.8-0.20211022200916-316ba0b74098/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -524,6 +533,8 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ
 google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
 google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
+google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -541,6 +552,8 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/IPtProxy.podspec b/IPtProxy.podspec
index dcb7283e9e8c9e59a6d10de3b6ed47d635de7e68..2a0af9dca9abbd86f70bb163dda0260eeee1872a 100644
--- a/IPtProxy.podspec
+++ b/IPtProxy.podspec
@@ -8,8 +8,8 @@
 
 Pod::Spec.new do |s|
   s.name             = 'IPtProxy'
-  s.version          = '1.4.0'
-  s.summary          = 'Obfs4proxy and Snowflake Pluggable Transports for iOS'
+  s.version          = '1.7.1'
+  s.summary          = 'Obfs4proxy and Snowflake Pluggable Transports for iOS and macOS'
 
   s.description      = <<-DESC
     Both Obfs4proxy and Snowflake Pluggable Transports are written in Go, which
@@ -33,7 +33,13 @@ Pod::Spec.new do |s|
     - Snowflake and Obfs4proxy are patched to accept all configuration parameters
       directly.
 
-    Both PTs are contained at their latest `master` commit, as per 2021-07-14.
+    Contained transport versions:
+
+    | Transport  | Version |
+    |------------|--------:|
+    | Obfs4proxy |  0.0.13 |
+    | Snowflake  |   2.3.0 |
+
                        DESC
 
   s.homepage         = 'https://github.com/tladesignz/IPtProxy'
@@ -43,6 +49,7 @@ Pod::Spec.new do |s|
   s.social_media_url = 'https://twitter.com/tladesignz'
 
   s.ios.deployment_target = '11.0'
+  s.osx.deployment_target = '12'
 
   s.preserve_paths = 'build.sh', '*.patch', 'IPtProxy.go/*'
 
diff --git a/IPtProxy.xcframework/Info.plist b/IPtProxy.xcframework/Info.plist
index f559237aeef2bdc7a474047e0ad5306f91ae084e..ba015a463cc599e571604feb65d01905df4d8219 100644
--- a/IPtProxy.xcframework/Info.plist
+++ b/IPtProxy.xcframework/Info.plist
@@ -6,15 +6,16 @@
 	<array>
 		<dict>
 			<key>LibraryIdentifier</key>
-			<string>ios-arm64</string>
+			<string>macos-arm64_x86_64</string>
 			<key>LibraryPath</key>
 			<string>IPtProxy.framework</string>
 			<key>SupportedArchitectures</key>
 			<array>
 				<string>arm64</string>
+				<string>x86_64</string>
 			</array>
 			<key>SupportedPlatform</key>
-			<string>ios</string>
+			<string>macos</string>
 		</dict>
 		<dict>
 			<key>LibraryIdentifier</key>
@@ -31,6 +32,18 @@
 			<key>SupportedPlatformVariant</key>
 			<string>simulator</string>
 		</dict>
+		<dict>
+			<key>LibraryIdentifier</key>
+			<string>ios-arm64</string>
+			<key>LibraryPath</key>
+			<string>IPtProxy.framework</string>
+			<key>SupportedArchitectures</key>
+			<array>
+				<string>arm64</string>
+			</array>
+			<key>SupportedPlatform</key>
+			<string>ios</string>
+		</dict>
 	</array>
 	<key>CFBundlePackageType</key>
 	<string>XFWK</string>
diff --git a/IPtProxy.xcframework/ios-arm64/IPtProxy.framework/Versions/A/Headers/IPtProxy.objc.h b/IPtProxy.xcframework/ios-arm64/IPtProxy.framework/Versions/A/Headers/IPtProxy.objc.h
index 7cebb9b64cded6bffd4a61d0b48d3e0f45685f93..09324fabf4e99595e8897ffff628e5618629eaa7 100644
--- a/IPtProxy.xcframework/ios-arm64/IPtProxy.framework/Versions/A/Headers/IPtProxy.objc.h
+++ b/IPtProxy.xcframework/ios-arm64/IPtProxy.framework/Versions/A/Headers/IPtProxy.objc.h
@@ -15,6 +15,9 @@
 @class IPtProxySnowflakeClientConnected;
 
 @protocol IPtProxySnowflakeClientConnected <NSObject>
+/**
+ * Connected - callback method to handle snowflake proxy client connections.
+ */
 - (void)connected;
 @end
 
@@ -27,6 +30,18 @@
 
 @end
 
+/**
+ * IsPortAvailable - Checks to see if a given port is not in use.
+
+@param port The port to check.
+ */
+FOUNDATION_EXPORT BOOL IPtProxyIsPortAvailable(long port);
+
+/**
+ * IsSnowflakeProxyRunning - Checks to see if a snowflake proxy is running in your app.
+ */
+FOUNDATION_EXPORT BOOL IPtProxyIsSnowflakeProxyRunning(void);
+
 /**
  * MeekPort - Port where Obfs4proxy will provide its Meek service.
 Only use this after calling StartObfs4Proxy! It might have changed after that!
@@ -51,6 +66,11 @@ Only use this property after calling StartObfs4Proxy! It might have changed afte
  */
 FOUNDATION_EXPORT long IPtProxyObfs4Port(void);
 
+/**
+ * Obfs4ProxyVersion - The version of Obfs4Proxy bundled with IPtProxy.
+ */
+FOUNDATION_EXPORT NSString* _Nonnull IPtProxyObfs4ProxyVersion(void);
+
 /**
  * ScramblesuitPort - Port where Obfs4proxy will provide its Scramblesuit service.
 Only use this property after calling StartObfs4Proxy! It might have changed after that!
@@ -63,6 +83,11 @@ Only use this property after calling StartSnowflake! It might have changed after
  */
 FOUNDATION_EXPORT long IPtProxySnowflakePort(void);
 
+/**
+ * SnowflakeVersion  - The version of Snowflake bundled with IPtProxy.
+ */
+FOUNDATION_EXPORT NSString* _Nonnull IPtProxySnowflakeVersion(void);
+
 /**
  * StartObfs4Proxy - Start the Obfs4Proxy.
 
diff --git a/IPtProxy.xcframework/ios-arm64/IPtProxy.framework/Versions/A/IPtProxy b/IPtProxy.xcframework/ios-arm64/IPtProxy.framework/Versions/A/IPtProxy
index 31af4b8efbe42b1cda8c96ed2f8b729546189794..b3bbffe0aca39dc79c395501aa6d99b07daf7764 100644
Binary files a/IPtProxy.xcframework/ios-arm64/IPtProxy.framework/Versions/A/IPtProxy and b/IPtProxy.xcframework/ios-arm64/IPtProxy.framework/Versions/A/IPtProxy differ
diff --git a/IPtProxy.xcframework/ios-arm64_x86_64-simulator/IPtProxy.framework/Versions/A/Headers/IPtProxy.objc.h b/IPtProxy.xcframework/ios-arm64_x86_64-simulator/IPtProxy.framework/Versions/A/Headers/IPtProxy.objc.h
index 7cebb9b64cded6bffd4a61d0b48d3e0f45685f93..09324fabf4e99595e8897ffff628e5618629eaa7 100644
--- a/IPtProxy.xcframework/ios-arm64_x86_64-simulator/IPtProxy.framework/Versions/A/Headers/IPtProxy.objc.h
+++ b/IPtProxy.xcframework/ios-arm64_x86_64-simulator/IPtProxy.framework/Versions/A/Headers/IPtProxy.objc.h
@@ -15,6 +15,9 @@
 @class IPtProxySnowflakeClientConnected;
 
 @protocol IPtProxySnowflakeClientConnected <NSObject>
+/**
+ * Connected - callback method to handle snowflake proxy client connections.
+ */
 - (void)connected;
 @end
 
@@ -27,6 +30,18 @@
 
 @end
 
+/**
+ * IsPortAvailable - Checks to see if a given port is not in use.
+
+@param port The port to check.
+ */
+FOUNDATION_EXPORT BOOL IPtProxyIsPortAvailable(long port);
+
+/**
+ * IsSnowflakeProxyRunning - Checks to see if a snowflake proxy is running in your app.
+ */
+FOUNDATION_EXPORT BOOL IPtProxyIsSnowflakeProxyRunning(void);
+
 /**
  * MeekPort - Port where Obfs4proxy will provide its Meek service.
 Only use this after calling StartObfs4Proxy! It might have changed after that!
@@ -51,6 +66,11 @@ Only use this property after calling StartObfs4Proxy! It might have changed afte
  */
 FOUNDATION_EXPORT long IPtProxyObfs4Port(void);
 
+/**
+ * Obfs4ProxyVersion - The version of Obfs4Proxy bundled with IPtProxy.
+ */
+FOUNDATION_EXPORT NSString* _Nonnull IPtProxyObfs4ProxyVersion(void);
+
 /**
  * ScramblesuitPort - Port where Obfs4proxy will provide its Scramblesuit service.
 Only use this property after calling StartObfs4Proxy! It might have changed after that!
@@ -63,6 +83,11 @@ Only use this property after calling StartSnowflake! It might have changed after
  */
 FOUNDATION_EXPORT long IPtProxySnowflakePort(void);
 
+/**
+ * SnowflakeVersion  - The version of Snowflake bundled with IPtProxy.
+ */
+FOUNDATION_EXPORT NSString* _Nonnull IPtProxySnowflakeVersion(void);
+
 /**
  * StartObfs4Proxy - Start the Obfs4Proxy.
 
diff --git a/IPtProxy.xcframework/ios-arm64_x86_64-simulator/IPtProxy.framework/Versions/A/IPtProxy b/IPtProxy.xcframework/ios-arm64_x86_64-simulator/IPtProxy.framework/Versions/A/IPtProxy
index 270e9649ad53539c3aab73f02eb6a63ef1cf1ddc..5a625f67d1514273850a5201a3ce62453bf66ee7 100644
Binary files a/IPtProxy.xcframework/ios-arm64_x86_64-simulator/IPtProxy.framework/Versions/A/IPtProxy and b/IPtProxy.xcframework/ios-arm64_x86_64-simulator/IPtProxy.framework/Versions/A/IPtProxy differ
diff --git a/IPtProxy.xcframework/macos-arm64_x86_64/IPtProxy.framework/Headers b/IPtProxy.xcframework/macos-arm64_x86_64/IPtProxy.framework/Headers
new file mode 120000
index 0000000000000000000000000000000000000000..a177d2a6b92600696030834c319f5e1434f9ee6a
--- /dev/null
+++ b/IPtProxy.xcframework/macos-arm64_x86_64/IPtProxy.framework/Headers
@@ -0,0 +1 @@
+Versions/Current/Headers
\ No newline at end of file
diff --git a/IPtProxy.xcframework/macos-arm64_x86_64/IPtProxy.framework/IPtProxy b/IPtProxy.xcframework/macos-arm64_x86_64/IPtProxy.framework/IPtProxy
new file mode 120000
index 0000000000000000000000000000000000000000..540a5c6fb381d72c2b75e268b357bd66c2934451
--- /dev/null
+++ b/IPtProxy.xcframework/macos-arm64_x86_64/IPtProxy.framework/IPtProxy
@@ -0,0 +1 @@
+Versions/Current/IPtProxy
\ No newline at end of file
diff --git a/IPtProxy.xcframework/macos-arm64_x86_64/IPtProxy.framework/Modules b/IPtProxy.xcframework/macos-arm64_x86_64/IPtProxy.framework/Modules
new file mode 120000
index 0000000000000000000000000000000000000000..5736f3186e797b8b787748c9979d0fed3b0536c3
--- /dev/null
+++ b/IPtProxy.xcframework/macos-arm64_x86_64/IPtProxy.framework/Modules
@@ -0,0 +1 @@
+Versions/Current/Modules
\ No newline at end of file
diff --git a/IPtProxy.xcframework/macos-arm64_x86_64/IPtProxy.framework/Resources b/IPtProxy.xcframework/macos-arm64_x86_64/IPtProxy.framework/Resources
new file mode 120000
index 0000000000000000000000000000000000000000..953ee36f3bb709faf58a351e0b33c353e337c0a2
--- /dev/null
+++ b/IPtProxy.xcframework/macos-arm64_x86_64/IPtProxy.framework/Resources
@@ -0,0 +1 @@
+Versions/Current/Resources
\ No newline at end of file
diff --git a/IPtProxy.xcframework/macos-arm64_x86_64/IPtProxy.framework/Versions/A/Headers/IPtProxy.h b/IPtProxy.xcframework/macos-arm64_x86_64/IPtProxy.framework/Versions/A/Headers/IPtProxy.h
new file mode 100644
index 0000000000000000000000000000000000000000..c9b6f40fc052c4aa1834ff0df9360980531d3577
--- /dev/null
+++ b/IPtProxy.xcframework/macos-arm64_x86_64/IPtProxy.framework/Versions/A/Headers/IPtProxy.h
@@ -0,0 +1,13 @@
+
+// Objective-C API for talking to the following Go packages
+//
+//	github.com/tladesignz/IPtProxy.git
+//
+// File is generated by gomobile bind. Do not edit.
+#ifndef __IPtProxy_FRAMEWORK_H__
+#define __IPtProxy_FRAMEWORK_H__
+
+#include "IPtProxy.objc.h"
+#include "Universe.objc.h"
+
+#endif
diff --git a/IPtProxy.xcframework/macos-arm64_x86_64/IPtProxy.framework/Versions/A/Headers/IPtProxy.objc.h b/IPtProxy.xcframework/macos-arm64_x86_64/IPtProxy.framework/Versions/A/Headers/IPtProxy.objc.h
new file mode 100644
index 0000000000000000000000000000000000000000..09324fabf4e99595e8897ffff628e5618629eaa7
--- /dev/null
+++ b/IPtProxy.xcframework/macos-arm64_x86_64/IPtProxy.framework/Versions/A/Headers/IPtProxy.objc.h
@@ -0,0 +1,193 @@
+// Objective-C API for talking to github.com/tladesignz/IPtProxy.git Go package.
+//   gobind -lang=objc github.com/tladesignz/IPtProxy.git
+//
+// File is generated by gobind. Do not edit.
+
+#ifndef __IPtProxy_H__
+#define __IPtProxy_H__
+
+@import Foundation;
+#include "ref.h"
+#include "Universe.objc.h"
+
+
+@protocol IPtProxySnowflakeClientConnected;
+@class IPtProxySnowflakeClientConnected;
+
+@protocol IPtProxySnowflakeClientConnected <NSObject>
+/**
+ * Connected - callback method to handle snowflake proxy client connections.
+ */
+- (void)connected;
+@end
+
+@interface IPtProxy : NSObject
+/**
+ * StateLocation - Override TOR_PT_STATE_LOCATION, which defaults to "$TMPDIR/pt_state".
+ */
++ (NSString* _Nonnull) stateLocation;
++ (void) setStateLocation:(NSString* _Nonnull)v;
+
+@end
+
+/**
+ * IsPortAvailable - Checks to see if a given port is not in use.
+
+@param port The port to check.
+ */
+FOUNDATION_EXPORT BOOL IPtProxyIsPortAvailable(long port);
+
+/**
+ * IsSnowflakeProxyRunning - Checks to see if a snowflake proxy is running in your app.
+ */
+FOUNDATION_EXPORT BOOL IPtProxyIsSnowflakeProxyRunning(void);
+
+/**
+ * MeekPort - Port where Obfs4proxy will provide its Meek service.
+Only use this after calling StartObfs4Proxy! It might have changed after that!
+ */
+FOUNDATION_EXPORT long IPtProxyMeekPort(void);
+
+/**
+ * Obfs2Port - Port where Obfs4proxy will provide its Obfs2 service.
+Only use this property after calling StartObfs4Proxy! It might have changed after that!
+ */
+FOUNDATION_EXPORT long IPtProxyObfs2Port(void);
+
+/**
+ * Obfs3Port - Port where Obfs4proxy will provide its Obfs3 service.
+Only use this property after calling StartObfs4Proxy! It might have changed after that!
+ */
+FOUNDATION_EXPORT long IPtProxyObfs3Port(void);
+
+/**
+ * Obfs4Port - Port where Obfs4proxy will provide its Obfs4 service.
+Only use this property after calling StartObfs4Proxy! It might have changed after that!
+ */
+FOUNDATION_EXPORT long IPtProxyObfs4Port(void);
+
+/**
+ * Obfs4ProxyVersion - The version of Obfs4Proxy bundled with IPtProxy.
+ */
+FOUNDATION_EXPORT NSString* _Nonnull IPtProxyObfs4ProxyVersion(void);
+
+/**
+ * ScramblesuitPort - Port where Obfs4proxy will provide its Scramblesuit service.
+Only use this property after calling StartObfs4Proxy! It might have changed after that!
+ */
+FOUNDATION_EXPORT long IPtProxyScramblesuitPort(void);
+
+/**
+ * SnowflakePort - Port where Snowflake will provide its service.
+Only use this property after calling StartSnowflake! It might have changed after that!
+ */
+FOUNDATION_EXPORT long IPtProxySnowflakePort(void);
+
+/**
+ * SnowflakeVersion  - The version of Snowflake bundled with IPtProxy.
+ */
+FOUNDATION_EXPORT NSString* _Nonnull IPtProxySnowflakeVersion(void);
+
+/**
+ * StartObfs4Proxy - Start the Obfs4Proxy.
+
+This will test, if the default ports are available. If not, it will increment them until there is.
+Only use the port properties after calling this, they might have been changed!
+
+@param logLevel Log level (ERROR/WARN/INFO/DEBUG). Defaults to ERROR if empty string.
+
+@param enableLogging Log to TOR_PT_STATE_LOCATION/obfs4proxy.log.
+
+@param unsafeLogging Disable the address scrubber.
+
+@param proxy HTTP, SOCKS4 or SOCKS5 proxy to be used behind Obfs4proxy. E.g. "socks5://127.0.0.1:12345"
+
+@return Port number where Obfs4Proxy will listen on for Obfs4(!), if no error happens during start up.
+	If you need the other ports, check MeekPort, Obfs2Port, Obfs3Port and ScramblesuitPort properties!
+ */
+FOUNDATION_EXPORT long IPtProxyStartObfs4Proxy(NSString* _Nullable logLevel, BOOL enableLogging, BOOL unsafeLogging, NSString* _Nullable proxy);
+
+/**
+ * StartSnowflake - Start the Snowflake client.
+
+@param ice Comma-separated list of ICE servers.
+
+@param url URL of signaling broker.
+
+@param front Front domain.
+
+@param ampCache OPTIONAL. URL of AMP cache to use as a proxy for signaling.
+       Only needed when you want to do the rendezvous over AMP instead of a domain fronted server.
+
+@param logFile Name of log file. OPTIONAL. Defaults to no log.
+
+@param logToStateDir Resolve the log file relative to Tor's PT state dir.
+
+@param keepLocalAddresses Keep local LAN address ICE candidates.
+
+@param unsafeLogging Prevent logs from being scrubbed.
+
+@param maxPeers Capacity for number of multiplexed WebRTC peers. DEFAULTs to 1 if less than that.
+
+@return Port number where Snowflake will listen on, if no error happens during start up.
+ */
+FOUNDATION_EXPORT long IPtProxyStartSnowflake(NSString* _Nullable ice, NSString* _Nullable url, NSString* _Nullable front, NSString* _Nullable ampCache, NSString* _Nullable logFile, BOOL logToStateDir, BOOL keepLocalAddresses, BOOL unsafeLogging, long maxPeers);
+
+/**
+ * StartSnowflakeProxy - Start the Snowflake proxy.
+
+@param capacity Maximum concurrent clients. OPTIONAL. Defaults to 10, if 0.
+
+@param broker Broker URL. OPTIONAL. Defaults to https://snowflake-broker.torproject.net/, if empty.
+
+@param relay WebSocket relay URL. OPTIONAL. Defaults to wss://snowflake.bamsoftware.com/, if empty.
+
+@param stun STUN URL. OPTIONAL. Defaults to stun:stun.stunprotocol.org:3478, if empty.
+
+@param natProbe OPTIONAL. Defaults to https://snowflake-broker.torproject.net:8443/probe, if empty.
+
+@param logFile Name of log file. OPTIONAL. Defaults to STDERR.
+
+@param keepLocalAddresses Keep local LAN address ICE candidates.
+
+@param unsafeLogging Prevent logs from being scrubbed.
+
+@param clientConnected A delegate which is called when a client successfully connected.
+      Will be called on its own thread! You will need to switch to your own UI thread,
+      if you want to do UI stuff!! OPTIONAL
+ */
+FOUNDATION_EXPORT void IPtProxyStartSnowflakeProxy(long capacity, NSString* _Nullable broker, NSString* _Nullable relay, NSString* _Nullable stun, NSString* _Nullable natProbe, NSString* _Nullable logFile, BOOL keepLocalAddresses, BOOL unsafeLogging, id<IPtProxySnowflakeClientConnected> _Nullable clientConnected);
+
+/**
+ * StopObfs4Proxy - Stop the Obfs4Proxy.
+ */
+FOUNDATION_EXPORT void IPtProxyStopObfs4Proxy(void);
+
+/**
+ * StopSnowflake - Stop the Snowflake client.
+ */
+FOUNDATION_EXPORT void IPtProxyStopSnowflake(void);
+
+/**
+ * StopSnowflakeProxy - Stop the Snowflake proxy.
+ */
+FOUNDATION_EXPORT void IPtProxyStopSnowflakeProxy(void);
+
+@class IPtProxySnowflakeClientConnected;
+
+/**
+ * SnowflakeClientConnected - Interface to use when clients connect
+to the snowflake proxy. For use with StartSnowflakeProxy
+ */
+@interface IPtProxySnowflakeClientConnected : NSObject <goSeqRefInterface, IPtProxySnowflakeClientConnected> {
+}
+@property(strong, readonly) _Nonnull id _ref;
+
+- (nonnull instancetype)initWithRef:(_Nonnull id)ref;
+/**
+ * Connected - callback method to handle snowflake proxy client connections.
+ */
+- (void)connected;
+@end
+
+#endif
diff --git a/IPtProxy.xcframework/macos-arm64_x86_64/IPtProxy.framework/Versions/A/Headers/Universe.objc.h b/IPtProxy.xcframework/macos-arm64_x86_64/IPtProxy.framework/Versions/A/Headers/Universe.objc.h
new file mode 100644
index 0000000000000000000000000000000000000000..019e7502d581983722a15bf30799e85cbc5dd766
--- /dev/null
+++ b/IPtProxy.xcframework/macos-arm64_x86_64/IPtProxy.framework/Versions/A/Headers/Universe.objc.h
@@ -0,0 +1,29 @@
+// Objective-C API for talking to  Go package.
+//   gobind -lang=objc 
+//
+// File is generated by gobind. Do not edit.
+
+#ifndef __Universe_H__
+#define __Universe_H__
+
+@import Foundation;
+#include "ref.h"
+
+@protocol Universeerror;
+@class Universeerror;
+
+@protocol Universeerror <NSObject>
+- (NSString* _Nonnull)error;
+@end
+
+@class Universeerror;
+
+@interface Universeerror : NSError <goSeqRefInterface, Universeerror> {
+}
+@property(strong, readonly) _Nonnull id _ref;
+
+- (nonnull instancetype)initWithRef:(_Nonnull id)ref;
+- (NSString* _Nonnull)error;
+@end
+
+#endif
diff --git a/IPtProxy.xcframework/macos-arm64_x86_64/IPtProxy.framework/Versions/A/Headers/ref.h b/IPtProxy.xcframework/macos-arm64_x86_64/IPtProxy.framework/Versions/A/Headers/ref.h
new file mode 100644
index 0000000000000000000000000000000000000000..b8036a4d85c7387f3def61473a071b5d8c4c8208
--- /dev/null
+++ b/IPtProxy.xcframework/macos-arm64_x86_64/IPtProxy.framework/Versions/A/Headers/ref.h
@@ -0,0 +1,35 @@
+// Copyright 2015 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.
+
+#ifndef __GO_REF_HDR__
+#define __GO_REF_HDR__
+
+#include <Foundation/Foundation.h>
+
+// GoSeqRef is an object tagged with an integer for passing back and
+// forth across the language boundary. A GoSeqRef may represent either
+// an instance of a Go object, or an Objective-C object passed to Go.
+// The explicit allocation of a GoSeqRef is used to pin a Go object
+// when it is passed to Objective-C. The Go seq package maintains a
+// reference to the Go object in a map keyed by the refnum along with
+// a reference count. When the reference count reaches zero, the Go
+// seq package will clear the corresponding entry in the map.
+@interface GoSeqRef : NSObject {
+}
+@property(readonly) int32_t refnum;
+@property(strong) id obj; // NULL when representing a Go object.
+
+// new GoSeqRef object to proxy a Go object. The refnum must be
+// provided from Go side.
+- (instancetype)initWithRefnum:(int32_t)refnum obj:(id)obj;
+
+- (int32_t)incNum;
+
+@end
+
+@protocol goSeqRefInterface
+-(GoSeqRef*) _ref;
+@end
+
+#endif
diff --git a/IPtProxy.xcframework/macos-arm64_x86_64/IPtProxy.framework/Versions/A/IPtProxy b/IPtProxy.xcframework/macos-arm64_x86_64/IPtProxy.framework/Versions/A/IPtProxy
new file mode 100644
index 0000000000000000000000000000000000000000..900e6ae88238501126c60d1339d1dd206a40a747
Binary files /dev/null and b/IPtProxy.xcframework/macos-arm64_x86_64/IPtProxy.framework/Versions/A/IPtProxy differ
diff --git a/IPtProxy.xcframework/macos-arm64_x86_64/IPtProxy.framework/Versions/A/Modules/module.modulemap b/IPtProxy.xcframework/macos-arm64_x86_64/IPtProxy.framework/Versions/A/Modules/module.modulemap
new file mode 100644
index 0000000000000000000000000000000000000000..7e2b8915090b67d2c5aaa06c69296102e92277ac
--- /dev/null
+++ b/IPtProxy.xcframework/macos-arm64_x86_64/IPtProxy.framework/Versions/A/Modules/module.modulemap
@@ -0,0 +1,8 @@
+framework module "IPtProxy" {
+	header "ref.h"
+    header "IPtProxy.objc.h"
+    header "Universe.objc.h"
+    header "IPtProxy.h"
+
+    export *
+}
\ No newline at end of file
diff --git a/IPtProxy.xcframework/macos-arm64_x86_64/IPtProxy.framework/Versions/A/Resources/Info.plist b/IPtProxy.xcframework/macos-arm64_x86_64/IPtProxy.framework/Versions/A/Resources/Info.plist
new file mode 100644
index 0000000000000000000000000000000000000000..0d1a4b8ab9b1fc8e9357197398f73353470cb636
--- /dev/null
+++ b/IPtProxy.xcframework/macos-arm64_x86_64/IPtProxy.framework/Versions/A/Resources/Info.plist
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+    <plist version="1.0">
+      <dict>
+      </dict>
+    </plist>
diff --git a/IPtProxy.xcframework/macos-arm64_x86_64/IPtProxy.framework/Versions/Current b/IPtProxy.xcframework/macos-arm64_x86_64/IPtProxy.framework/Versions/Current
new file mode 120000
index 0000000000000000000000000000000000000000..8c7e5a667f1b771847fe88c01c3de34413a1b220
--- /dev/null
+++ b/IPtProxy.xcframework/macos-arm64_x86_64/IPtProxy.framework/Versions/Current
@@ -0,0 +1 @@
+A
\ No newline at end of file
diff --git a/README.md b/README.md
index a46d395a303791d7d628f2cb0c684e5f1c0b203c..dfa06b8cffe800cc266a9b8825d8f7530eadd9e4 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,17 @@
 # IPtProxy
 
-Obfs4proxy and Snowflake Pluggable Transports for iOS and Android
+Obfs4proxy and Snowflake Pluggable Transports for iOS, MacOS and Android
 
 [![JitPack](https://jitpack.io/v/tladesignz/IPtProxy.svg)](https://jitpack.io/#tladesignz/IPtProxy)
 [![Version](https://img.shields.io/cocoapods/v/IPtProxy.svg?style=flat)](https://cocoapods.org/pods/IPtProxy)
 [![License](https://img.shields.io/cocoapods/l/IPtProxy.svg?style=flat)](https://cocoapods.org/pods/IPtProxy)
 [![Platform](https://img.shields.io/cocoapods/p/IPtProxy.svg?style=flat)](https://cocoapods.org/pods/IPtProxy)
 
+| Transport  | Version |
+|------------|--------:|
+| Obfs4proxy |  0.0.13 |
+| Snowflake  |   2.3.0 |
+
 Both Obfs4proxy and Snowflake Pluggable Transports are written in Go, which
 is a little annoying to use on iOS and Android.
 This project encapsulates all the machinations to make it work and provides an
@@ -31,9 +36,7 @@ Problems solved in particular are:
   on a multi-user Android), you should first start the transports and then use the 
   returned ports for configuration of other components (e.g. Tor). 
 
-Both PTs are contained at their latest `master` commit, as per 2021-07-14.
-
-## iOS
+## iOS/macOS
 
 ### Installation
 
@@ -41,7 +44,7 @@ IPtProxy is available through [CocoaPods](https://cocoapods.org). To install
 it, simply add the following line to your `Podfile`:
 
 ```ruby
-pod 'IPtProxy', '~> 1.4'
+pod 'IPtProxy', '~> 1.7'
 ```
 
 ### Getting Started
@@ -59,7 +62,7 @@ IPtProxy is available through [JitPack](https://jitpack.io). To install
 it, simply add the following line to your `build.gradle` file:
 
 ```groovy
-implementation 'com.github.tladesignz:IPtProxy:1.4.0'
+implementation 'com.github.tladesignz:IPtProxy:1.7.1'
 ```
 
 And this to your root `build.gradle` at the end of repositories:
@@ -193,4 +196,4 @@ for the Guardian Project https://guardianproject.info
 
 ## License
 
-IPtProxy is available under the MIT license. See the LICENSE file for more info.
+IPtProxy is available under the MIT license. See the [LICENSE](LICENSE) file for more info.
diff --git a/build.sh b/build.sh
index 15396e4913e9fa5a51aa949f40a931d6b4d39628..e35e70552ca97b04adc2bd5d2be42efa69fca0b6 100755
--- a/build.sh
+++ b/build.sh
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-TARGET=ios
+TARGET=ios,iossimulator,macos
 OUTPUT=IPtProxy.xcframework
 
 if test "$1" = "android"; then
@@ -34,11 +34,11 @@ else
     # No .git directory - That's a normal install.
     git clone https://gitlab.com/yawning/obfs4.git
     cd obfs4 || exit 1
-    git checkout --force --quiet cbf3f3cf
+    git checkout --force --quiet 77af0cba
     cd ..
     git clone https://git.torproject.org/pluggable-transports/snowflake.git
     cd snowflake || exit 1
-    git checkout --force --quiet ead5a960
+    git checkout --force --quiet c983c13a
     cd ..
 fi
 
@@ -54,6 +54,6 @@ cd IPtProxy.go || exit 1
 
 gomobile init
 
-gomobile bind -target=$TARGET -o ../$OUTPUT -iosversion 11.0 -v
+gomobile bind -target=$TARGET -o ../$OUTPUT -iosversion 11.0 -androidapi 19 -v
 
 printf '\n\n--- Done.\n\n'
diff --git a/jitpack.yml b/jitpack.yml
index 87d04bf877436ccafff9ae827265f63cb06279cf..85b437188b835da3a8250e2fcaef03aef0ab5aac 100644
--- a/jitpack.yml
+++ b/jitpack.yml
@@ -1,3 +1,3 @@
 install:
   - FILE="-Dfile=IPtProxy.aar"
-  - mvn install:install-file $FILE -DgroupId=com.github.tladesignz -DartifactId=IPtProxy -Dversion=1.4.0 -Dpackaging=aar -DgeneratePom=true -Dsources=IPtProxy-sources.jar
+  - mvn install:install-file $FILE -DgroupId=com.github.tladesignz -DartifactId=IPtProxy -Dversion=1.7.1 -Dpackaging=aar -DgeneratePom=true -Dsources=IPtProxy-sources.jar
diff --git a/obfs4 b/obfs4
index cbf3f3cfa09cf48c42aebd1b96fd7952f1ddb25d..77af0cba934d73c4baeb709560bcfc9a9fbc661c 160000
--- a/obfs4
+++ b/obfs4
@@ -1 +1 @@
-Subproject commit cbf3f3cfa09cf48c42aebd1b96fd7952f1ddb25d
+Subproject commit 77af0cba934d73c4baeb709560bcfc9a9fbc661c
diff --git a/obfs4.patch b/obfs4.patch
index 274b5b5e1e80826060f29ecd4926563fc5a58e03..1776f08c010dd12f68a8970344123160c88d28db 100644
--- a/obfs4.patch
+++ b/obfs4.patch
@@ -1,5 +1,5 @@
 diff --git a/obfs4proxy/obfs4proxy.go b/obfs4proxy/obfs4proxy.go
-index 628f56b..be2cc55 100644
+index d92f5f5..d849b80 100644
 --- a/obfs4proxy/obfs4proxy.go
 +++ b/obfs4proxy/obfs4proxy.go
 @@ -27,10 +27,9 @@
@@ -22,7 +22,15 @@ index 628f56b..be2cc55 100644
  	"sync"
  	"syscall"
  
-@@ -58,7 +58,7 @@ const (
+@@ -51,6 +51,7 @@ import (
+ 
+ const (
+ 	obfs4proxyVersion = "0.0.13"
++	Obfs4proxyVersion = obfs4proxyVersion
+ 	obfs4proxyLogFile = "obfs4proxy.log"
+ 	socksAddr         = "127.0.0.1:0"
+ )
+@@ -58,7 +59,7 @@ const (
  var stateDir string
  var termMon *termMonitor
  
@@ -31,7 +39,7 @@ index 628f56b..be2cc55 100644
  	ptClientInfo, err := pt.ClientSetup(transports.Transports())
  	if err != nil {
  		golog.Fatal(err)
-@@ -85,7 +85,20 @@ func clientSetup() (launched bool, listeners []net.Listener) {
+@@ -85,7 +86,20 @@ func clientSetup() (launched bool, listeners []net.Listener) {
  			continue
  		}
  
@@ -53,7 +61,7 @@ index 628f56b..be2cc55 100644
  		if err != nil {
  			_ = pt.CmethodError(name, err.Error())
  			continue
-@@ -304,22 +317,16 @@ func getVersion() string {
+@@ -304,22 +318,16 @@ func getVersion() string {
  	return fmt.Sprintf("obfs4proxy-%s", obfs4proxyVersion)
  }
  
@@ -82,7 +90,7 @@ index 628f56b..be2cc55 100644
  	if err := log.SetLogLevel(*logLevelStr); err != nil {
  		golog.Fatalf("[ERROR]: %s - failed to set log level: %s", execName, err)
  	}
-@@ -338,8 +345,7 @@ func main() {
+@@ -338,8 +346,7 @@ func main() {
  		golog.Fatalf("[ERROR]: %s - failed to initialize logging", execName)
  	}
  	if err = transports.Init(); err != nil {
@@ -92,7 +100,7 @@ index 628f56b..be2cc55 100644
  	}
  
  	log.Noticef("%s - launched", getVersion())
-@@ -347,7 +353,7 @@ func main() {
+@@ -347,7 +354,7 @@ func main() {
  	// Do the managed pluggable transport protocol configuration.
  	if isClient {
  		log.Infof("%s - initializing client transport listeners", execName)
@@ -101,7 +109,7 @@ index 628f56b..be2cc55 100644
  	} else {
  		log.Infof("%s - initializing server transport listeners", execName)
  		launched, ptListeners = serverSetup()
-@@ -379,3 +385,11 @@ func main() {
+@@ -379,3 +386,11 @@ func main() {
  	}
  	termMon.wait(true)
  }
diff --git a/pom.xml b/pom.xml
index a6061f3b284c3223ec2c544c4d1ff91e5d159282..1184fa066de6daa5dccd6a49082d055ad7fd664c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,5 +5,5 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.github.tladesignz</groupId>
   <artifactId>IPtProxy</artifactId>
-  <version>1.4.0</version>
+  <version>1.7.1</version>
 </project>
diff --git a/snowflake b/snowflake
index ead5a960d7fa19dc890ccbfc0765c5ab6629eaa9..c983c13a84554d0ba1ffcdd054491090c0eafc54 160000
--- a/snowflake
+++ b/snowflake
@@ -1 +1 @@
-Subproject commit ead5a960d7fa19dc890ccbfc0765c5ab6629eaa9
+Subproject commit c983c13a84554d0ba1ffcdd054491090c0eafc54
diff --git a/snowflake.patch b/snowflake.patch
index 024c73e1572a9c0ed785a1f5b09ccb7b720fb5bf..307866a0f7ceb2b4a8510689732e20fd3c9ed94d 100644
--- a/snowflake.patch
+++ b/snowflake.patch
@@ -1,5 +1,5 @@
 diff --git a/client/snowflake.go b/client/snowflake.go
-index d76efbf..dd28681 100644
+index 2cb6549..060a639 100644
 --- a/client/snowflake.go
 +++ b/client/snowflake.go
 @@ -1,8 +1,7 @@
@@ -12,16 +12,16 @@ index d76efbf..dd28681 100644
  	"io"
  	"io/ioutil"
  	"log"
-@@ -24,6 +23,8 @@ const (
- 	DefaultSnowflakeCapacity = 1
- )
+@@ -36,6 +35,8 @@ func (p ptEventLogger) OnNewSnowflakeEvent(e event.SnowflakeEvent) {
+ 	pt.Log(pt.LogSeverityNotice, e.String())
+ }
  
 +var sigChan = make(chan os.Signal, 1)
 +
  // Exchanges bytes between two ReadWriters.
  // (In this case, between a SOCKS connection and a snowflake transport conn)
  func copyLoop(socks, sfconn io.ReadWriter) {
-@@ -119,23 +120,13 @@ func socksAcceptLoop(ln *pt.SocksListener, config sf.ClientConfig, shutdown chan
+@@ -146,23 +147,13 @@ func socksAcceptLoop(ln *pt.SocksListener, config sf.ClientConfig, shutdown chan
  	}
  }
  
@@ -51,7 +51,7 @@ index d76efbf..dd28681 100644
  
  	log.SetFlags(log.LstdFlags | log.LUTC)
  
-@@ -195,7 +186,7 @@ func main() {
+@@ -222,7 +213,7 @@ func main() {
  		switch methodName {
  		case "snowflake":
  			// TODO: Be able to recover when SOCKS dies.
@@ -60,7 +60,7 @@ index d76efbf..dd28681 100644
  			if err != nil {
  				pt.CmethodError(methodName, err.Error())
  				break
-@@ -210,7 +201,6 @@ func main() {
+@@ -237,7 +228,6 @@ func main() {
  	}
  	pt.CmethodsDone()
  
@@ -68,7 +68,7 @@ index d76efbf..dd28681 100644
  	signal.Notify(sigChan, syscall.SIGTERM)
  
  	if os.Getenv("TOR_PT_EXIT_ON_STDIN_CLOSE") == "1" {
-@@ -237,3 +227,8 @@ func main() {
+@@ -264,3 +254,8 @@ func main() {
  	wg.Wait()
  	log.Println("snowflake is done.")
  }
@@ -78,28 +78,18 @@ index d76efbf..dd28681 100644
 +	sigChan <- syscall.SIGTERM
 +}
 diff --git a/proxy/lib/snowflake.go b/proxy/lib/snowflake.go
-index e39fcfb..d8b72fa 100644
+index 34f8abe..ec22f45 100644
 --- a/proxy/lib/snowflake.go
 +++ b/proxy/lib/snowflake.go
-@@ -102,6 +102,8 @@ type SnowflakeProxy struct {
- 	// NATProbeURL is the URL of the probe service we use for NAT checks
- 	NATProbeURL string
- 	shutdown    chan struct{}
-+
-+	ClientConnectedCallback func()
+@@ -128,6 +128,7 @@ type SnowflakeProxy struct {
+ 	ProxyType       string
+ 	EventDispatcher event.SnowflakeEventDispatcher
+ 	shutdown        chan struct{}
++	ClientConnectedCallback    func()
  }
  
  // Checks whether an IP address is a remote address for the client
-@@ -183,7 +185,7 @@ func (s *SignalingServer) pollOffer(sid string, shutdown chan struct{}) *webrtc.
- 			return nil
- 		default:
- 			numClients := int((tokens.count() / 8) * 8) // Round down to 8
--			body, err := messages.EncodePollRequest(sid, "standalone", currentNATType, numClients)
-+			body, err := messages.EncodePollRequest(sid, "iptproxy", currentNATType, numClients)
- 			if err != nil {
- 				log.Printf("Error encoding poll message: %s", err.Error())
- 				return nil
-@@ -474,6 +476,8 @@ func (sf *SnowflakeProxy) runSession(sid string) {
+@@ -531,6 +532,8 @@ func (sf *SnowflakeProxy) runSession(sid string) {
  	select {
  	case <-dataChan:
  		log.Println("Connection successful.")