Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,29 @@ c-archive: libtailscale.a ## Builds libtailscale.a for the target platform
.PHONY: shared
shared: libtailscale.so ## Builds libtailscale.so for the target platform

.PHONY: test
test: test-go test-ruby test-swift ## Runs all tests available on the host platform

.PHONY: test-go
test-go: ## Runs Go and C integration tests
go test -v ./...

.PHONY: test-ruby
test-ruby: ## Runs Ruby binding tests (requires ruby, bundler)
@if command -v bundle >/dev/null 2>&1 && [ -f ruby/Gemfile ]; then \
cd ruby && bundle exec rake test; \
else \
echo "skipping ruby tests: bundle not found"; \
fi

.PHONY: test-swift
test-swift: ## Runs Swift binding tests (requires macOS, xcodebuild)
@if [ "$(GOOS)" = "darwin" ] && command -v xcodebuild >/dev/null 2>&1; then \
cd swift && $(MAKE) test; \
else \
echo "skipping swift tests: requires macOS with xcodebuild"; \
fi

.PHONY: clean
clean: ## Clean up build artifacts
rm -f libtailscale*.h
Expand Down
20 changes: 11 additions & 9 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
module github.com/tailscale/libtailscale

go 1.25.5
go 1.25.7

require tailscale.com v1.94.1
require (
golang.org/x/sys v0.40.0
tailscale.com v1.95.0-pre.0.20260227223041-0fb207c3d045
)

require (
9fans.net/go v0.0.8-0.20250307142834-96bdba94b63f // indirect
filippo.io/edwards25519 v1.1.0 // indirect
filippo.io/edwards25519 v1.2.0 // indirect
github.com/BurntSushi/toml v1.5.0 // indirect
github.com/akutz/memconn v0.1.0 // indirect
github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa // indirect
Expand All @@ -29,13 +32,13 @@ require (
github.com/coder/websocket v1.8.12 // indirect
github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6 // indirect
github.com/creachadair/msync v0.7.1 // indirect
github.com/creack/pty v1.1.23 // indirect
github.com/creack/pty v1.1.24 // indirect
github.com/dblohm7/wingoes v0.0.0-20240119213807-a09d6be7affa // indirect
github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc // indirect
github.com/digitalocean/go-smbios v0.0.0-20180907143718-390a4f403a8e // indirect
github.com/djherbis/times v1.6.0 // indirect
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
github.com/gaissmai/bart v0.18.0 // indirect
github.com/gaissmai/bart v0.26.1 // indirect
github.com/go-json-experiment/json v0.0.0-20250813024750-ebf49471dced // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/go4org/plan9netshell v0.0.0-20250324183649-788daa080737 // indirect
Expand All @@ -61,7 +64,7 @@ require (
github.com/mdlayher/sdnotify v1.0.0 // indirect
github.com/mdlayher/socket v0.5.0 // indirect
github.com/mitchellh/go-ps v1.0.0 // indirect
github.com/pierrec/lz4/v4 v4.1.21 // indirect
github.com/pierrec/lz4/v4 v4.1.25 // indirect
github.com/pires/go-proxyproto v0.8.1 // indirect
github.com/pkg/sftp v1.13.6 // indirect
github.com/prometheus-community/pro-bing v0.4.0 // indirect
Expand All @@ -86,16 +89,15 @@ require (
golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f // indirect
golang.org/x/mod v0.30.0 // indirect
golang.org/x/net v0.48.0 // indirect
golang.org/x/oauth2 v0.32.0 // indirect
golang.org/x/oauth2 v0.33.0 // indirect
golang.org/x/sync v0.19.0 // indirect
golang.org/x/sys v0.40.0 // indirect
golang.org/x/term v0.38.0 // indirect
golang.org/x/text v0.32.0 // indirect
golang.org/x/time v0.12.0 // indirect
golang.org/x/tools v0.39.0 // indirect
golang.org/x/tools/go/expect v0.1.1-deprecated // indirect
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
golang.zx2c4.com/wireguard/windows v0.5.3 // indirect
gvisor.dev/gvisor v0.0.0-20250205023644-9414b50a5633 // indirect
gvisor.dev/gvisor v0.0.0-20260224225140-573d5e7127a8 // indirect
honnef.co/go/tools v0.7.0-0.dev.0.20251022135355-8273271481d0 // indirect
)
30 changes: 16 additions & 14 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
9fans.net/go v0.0.8-0.20250307142834-96bdba94b63f h1:1C7nZuxUMNz7eiQALRfiqNOm04+m3edWlRff/BYHf0Q=
9fans.net/go v0.0.8-0.20250307142834-96bdba94b63f/go.mod h1:hHyrZRryGqVdqrknjq5OWDLGCTJ2NeEvtrpR96mjraM=
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
filippo.io/edwards25519 v1.2.0 h1:crnVqOiS4jqYleHd9vaKZ+HKtHfllngJIiOpNpoJsjo=
filippo.io/edwards25519 v1.2.0/go.mod h1:xzAOLCNug/yB62zG1bQ8uziwrIqIuxhctzJT18Q77mc=
filippo.io/mkcert v1.4.4 h1:8eVbbwfVlaqUM7OwuftKc2nuYOoTDQWqsoXmzoXZdbc=
filippo.io/mkcert v1.4.4/go.mod h1:VyvOchVuAye3BoUsPUOOofKygVwLV2KQMVFJNRq+1dA=
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
Expand Down Expand Up @@ -50,12 +50,14 @@ github.com/coder/websocket v1.8.12 h1:5bUXkEPPIbewrnkU8LTCLVaxi4N4J8ahufH2vlo4NA
github.com/coder/websocket v1.8.12/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs=
github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6 h1:8h5+bWd7R6AYUslN6c6iuZWTKsKxUFDlpnmilO6R2n0=
github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q=
github.com/creachadair/mds v0.25.9 h1:080Hr8laN2h+l3NeVCGMBpXtIPnl9mz8e4HLraGPqtA=
github.com/creachadair/mds v0.25.9/go.mod h1:4hatI3hRM+qhzuAmqPRFvaBM8mONkS7nsLxkcuTYUIs=
github.com/creachadair/msync v0.7.1 h1:SeZmuEBXQPe5GqV/C94ER7QIZPwtvFbeQiykzt/7uho=
github.com/creachadair/msync v0.7.1/go.mod h1:8CcFlLsSujfHE5wWm19uUBLHIPDAUr6LXDwneVMO008=
github.com/creachadair/taskgroup v0.13.2 h1:3KyqakBuFsm3KkXi/9XIb0QcA8tEzLHLgaoidf0MdVc=
github.com/creachadair/taskgroup v0.13.2/go.mod h1:i3V1Zx7H8RjwljUEeUWYT30Lmb9poewSb2XI1yTwD0g=
github.com/creack/pty v1.1.23 h1:4M6+isWdcStXEf15G/RbrMPOQj1dZ7HPZCGwE4kOeP0=
github.com/creack/pty v1.1.23/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE=
github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s=
github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
Expand All @@ -72,8 +74,8 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
github.com/gaissmai/bart v0.18.0 h1:jQLBT/RduJu0pv/tLwXE+xKPgtWJejbxuXAR+wLJafo=
github.com/gaissmai/bart v0.18.0/go.mod h1:JJzMAhNF5Rjo4SF4jWBrANuJfqY+FvsFhW7t1UZJ+XY=
github.com/gaissmai/bart v0.26.1 h1:+w4rnLGNlA2GDVn382Tfe3jOsK5vOr5n4KmigJ9lbTo=
github.com/gaissmai/bart v0.26.1/go.mod h1:GREWQfTLRWz/c5FTOsIw+KkscuFkIV5t8Rp7Nd1Td5c=
github.com/github/fakeca v0.1.0 h1:Km/MVOFvclqxPM9dZBC4+QE564nU4gz4iZ0D9pMw28I=
github.com/github/fakeca v0.1.0/go.mod h1:+bormgoGMMuamOscx7N91aOuUST7wdaJ2rNjeohylyo=
github.com/go-json-experiment/json v0.0.0-20250813024750-ebf49471dced h1:Q311OHjMh/u5E2TITc++WlTP5We0xNseRMkHDyvhW7I=
Expand Down Expand Up @@ -142,8 +144,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pierrec/lz4/v4 v4.1.25 h1:kocOqRffaIbU5djlIBr7Wh+cx82C0vtFb0fOurZHqD0=
github.com/pierrec/lz4/v4 v4.1.25/go.mod h1:EoQMVJgeeEOMsCqCzqFm2O0cJvljX2nGZjcRIPL34O4=
github.com/pires/go-proxyproto v0.8.1 h1:9KEixbdJfhrbtjpz/ZwCdWDD2Xem0NZ38qMYaASJgp0=
github.com/pires/go-proxyproto v0.8.1/go.mod h1:ZKAAyp3cgy5Y5Mo4n9AlScrkCZwUy0g3Jf+slqQVcuU=
github.com/pkg/sftp v1.13.6 h1:JFZT4XbOU7l77xGSpOdW+pwIMqP044IyjXX6FGyEKFo=
Expand Down Expand Up @@ -229,8 +231,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
golang.org/x/oauth2 v0.32.0 h1:jsCblLleRMDrxMN29H3z/k1KliIvpLgCkE6R8FXXNgY=
golang.org/x/oauth2 v0.32.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo=
golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand Down Expand Up @@ -283,13 +285,13 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gvisor.dev/gvisor v0.0.0-20250205023644-9414b50a5633 h1:2gap+Kh/3F47cO6hAu3idFvsJ0ue6TRcEi2IUkv/F8k=
gvisor.dev/gvisor v0.0.0-20250205023644-9414b50a5633/go.mod h1:5DMfjtclAbTIjbXqO1qCe2K5GKKxWz2JHvCChuTcJEM=
gvisor.dev/gvisor v0.0.0-20260224225140-573d5e7127a8 h1:Zy8IV/+FMLxy6j6p87vk/vQGKcdnbprwjTxc8UiUtsA=
gvisor.dev/gvisor v0.0.0-20260224225140-573d5e7127a8/go.mod h1:QkHjoMIBaYtpVufgwv3keYAbln78mBoCuShZrPrer1Q=
honnef.co/go/tools v0.7.0-0.dev.0.20251022135355-8273271481d0 h1:5SXjd4ET5dYijLaf0O3aOenC0Z4ZafIWSpjUzsQaNho=
honnef.co/go/tools v0.7.0-0.dev.0.20251022135355-8273271481d0/go.mod h1:EPDDhEZqVHhWuPI5zPAsjU0U7v9xNIWjoOVyZ5ZcniQ=
howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM=
howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g=
software.sslmate.com/src/go-pkcs12 v0.4.0 h1:H2g08FrTvSFKUj+D309j1DPfk5APnIdAQAB8aEykJ5k=
software.sslmate.com/src/go-pkcs12 v0.4.0/go.mod h1:Qiz0EyvDRJjjxGyUQa2cCNZn/wMyzrRJ/qcDXOQazLI=
tailscale.com v1.94.1 h1:0dAst/ozTuFkgmxZULc3oNwR9+qPIt5ucvzH7kaM0Jw=
tailscale.com v1.94.1/go.mod h1:gLnVrEOP32GWvroaAHHGhjSGMPJ1i4DvqNwEg+Yuov4=
tailscale.com v1.95.0-pre.0.20260227223041-0fb207c3d045 h1:J2hFIY00F331g30O7kDKNhYSg0SqZCiLs4N652x0fhU=
tailscale.com v1.95.0-pre.0.20260227223041-0fb207c3d045/go.mod h1:QrwJC+xjDyQAPDm26LxbMcTZPETjg2McDBAV4nxD8xM=
115 changes: 55 additions & 60 deletions ruby/test/tailscale/test_tailscale.rb
Original file line number Diff line number Diff line change
Expand Up @@ -130,73 +130,59 @@ def new_closed_ts
end
end

# TestTailscaleNetwork tests operations that require running servers.
# Two shared servers (s1, s2) are brought up once, matching the approach
# used by the Go C integration test (tsnetctest): s1 listens, s2 dials.
# TestTailscaleNetwork tests operations that require a running server.
# A single shared server is brought up once and used for all tests,
# including self-dial (listen + dial to own IP on the same node).
class TestTailscaleNetwork < Minitest::Test
@@mu = Mutex.new
@@s1 = nil
@@s2 = nil
@@s1_ip = nil
@@s2_ip = nil
@@server = nil
@@ip = nil
@@tmpdir = nil

def self.ensure_servers
def self.ensure_server
@@mu.synchronize do
return if @@s1
return if @@server
@@tmpdir = Dir.mktmpdir

@@s1 = make_server(File.join(@@tmpdir, "s1"))
@@s2 = make_server(File.join(@@tmpdir, "s2"))

wait_running(@@s1)
wait_running(@@s2)

@@s1_ip = @@s1.local_api.status["Self"]["TailscaleIPs"][0]
@@s2_ip = @@s2.local_api.status["Self"]["TailscaleIPs"][0]
end
end

def self.make_server(dir)
FileUtils.mkdir_p(dir)
ts = Tailscale.new
unless ENV["VERBOSE"]
logfd = IO.sysopen("/dev/null", "w+")
ts.set_log_fd(logfd)
end
ts.set_ephemeral(true)
ts.set_dir(dir)
ts.set_control_url($testcontrol_url)
ts.up
ts
end
dir = File.join(@@tmpdir, "s")
FileUtils.mkdir_p(dir)
ts = Tailscale.new
unless ENV["VERBOSE"]
logfd = IO.sysopen("/dev/null", "w+")
ts.set_log_fd(logfd)
end
ts.set_ephemeral(true)
ts.set_dir(dir)
ts.set_control_url($testcontrol_url)
ts.up

deadline = Time.now + 30
loop do
break if ts.local_api.status["BackendState"] == "Running"
raise "timed out waiting for BackendState Running" if Time.now > deadline
sleep 0.05
end

def self.wait_running(ts)
deadline = Time.now + 30
loop do
break if ts.local_api.status["BackendState"] == "Running"
raise "timed out waiting for BackendState Running" if Time.now > deadline
sleep 0.05
@@server = ts
@@ip = ts.local_api.status["Self"]["TailscaleIPs"][0]
end
end

Minitest.after_run do
@@mu.synchronize do
[@@s1, @@s2].compact.each { |s| s.close rescue nil }
@@s1 = @@s2 = nil
@@server&.close rescue nil
@@server = nil
FileUtils.remove_entry_secure(@@tmpdir) if @@tmpdir
end
end

def setup
super
self.class.ensure_servers
self.class.ensure_server
end

def s1; @@s1; end
def s2; @@s2; end
def s1_ip; @@s1_ip; end
def s2_ip; @@s2_ip; end
def ts; @@server; end
def ip; @@ip; end

def test_start_async
tmpdir = Dir.mktmpdir
Expand All @@ -211,7 +197,7 @@ def test_up_and_close
tmpdir = Dir.mktmpdir
t = newts(tmpdir)
t.up
self.class.wait_running(t)
wait_running(t)
assert_equal "Running", t.local_api.status["BackendState"]
t.close
assert_raises(Tailscale::ClosedError) { t.set_hostname("fail") }
Expand All @@ -223,29 +209,29 @@ def test_set_hostname_visible_in_status
t = newts(tmpdir)
t.set_hostname("my-ruby-host")
t.up
self.class.wait_running(t)
wait_running(t)
assert_match(/my-ruby-host/, t.local_api.status["Self"]["HostName"])
t.close
FileUtils.remove_entry_secure(tmpdir)
end

def test_get_ips
ips = s1.get_ips
ips = ts.get_ips
assert_kind_of Array, ips
refute_empty ips
assert ips.any? { |i| i.start_with?("100.") },
"expected a 100.x.y.z tailscale IPv4, got: #{ips}"
end

def test_loopback
addr, proxy_cred, local_cred = s1.loopback
addr, proxy_cred, local_cred = ts.loopback
assert_match(/:\d+$/, addr)
assert_equal 32, proxy_cred.length
assert_equal 32, local_cred.length
end

def test_local_api_client
client = s1.local_api_client
client = ts.local_api_client
assert_kind_of Tailscale::LocalAPIClient, client
refute_nil client.address
refute_nil client.credential
Expand All @@ -254,27 +240,27 @@ def test_local_api_client
end

def test_local_api_status
status = s1.local_api.status
status = ts.local_api.status
assert_kind_of Hash, status
assert_equal "Running", status["BackendState"]
assert_kind_of Hash, status["Self"]
refute_empty status["Self"]["TailscaleIPs"]
end

def test_listen_and_close
s = s1.listen("tcp", ":1999")
s = ts.listen("tcp", ":1999")
s.close
end

def test_dial_udp
c = s2.dial("udp", "100.100.100.100:53")
c = ts.dial("udp", "100.100.100.100:53")
c.close
end

def test_listen_accept_dial_data_transfer
Timeout.timeout(30) do
ln = s1.listen("tcp", "#{s1_ip}:8081")
c = s2.dial("tcp", "#{s1_ip}:8081")
ln = ts.listen("tcp", "#{ip}:8081")
c = ts.dial("tcp", "#{ip}:8081")
c.sync = true
ss = ln.accept
ss.sync = true
Expand All @@ -290,8 +276,8 @@ def test_listen_accept_dial_data_transfer

def test_listen_accept_dial_large_data
Timeout.timeout(30) do
ln = s1.listen("tcp", "#{s1_ip}:8082")
c = s2.dial("tcp", "#{s1_ip}:8082")
ln = ts.listen("tcp", "#{ip}:8082")
c = ts.dial("tcp", "#{ip}:8082")
c.sync = true
ss = ln.accept
ss.sync = true
Expand All @@ -314,8 +300,8 @@ def test_listen_accept_dial_large_data

def test_get_remote_addr
Timeout.timeout(30) do
ln = s1.listen("tcp", "#{s1_ip}:8083")
c = s2.dial("tcp", "#{s1_ip}:8083")
ln = ts.listen("tcp", "#{ip}:8083")
c = ts.dial("tcp", "#{ip}:8083")
ss = ln.accept
remote_addr = ln.get_remote_addr(ss)
refute_nil remote_addr
Expand All @@ -329,6 +315,15 @@ def test_get_remote_addr

private

def wait_running(t)
deadline = Time.now + 30
loop do
break if t.local_api.status["BackendState"] == "Running"
raise "timed out waiting for BackendState Running" if Time.now > deadline
sleep 0.05
end
end

def newts(dir)
t = Tailscale.new
unless ENV["VERBOSE"]
Expand Down
Loading