Skip to content

Commit ec27e31

Browse files
committed
Add Dependabot configuration and adjust WireGuard spelling
Added a new `.github/dependabot.yml` file to enable automated dependency updates for gomod and GitHub Actions on a weekly schedule. Corrected the spelling of "Wireguard" to "WireGuard" in multiple files for consistency: - `.goreleaser.yaml` - `README.md` - `cmd/wush/cp.go` - `cmd/wush/serve.go` - `cmd/wush/ssh.go` Simplified `install.sh` by removing the `pipefail` option. Updated license and import statements, cleaned up `server.go` in the `tsserver` package, and refactored peer management to use `xsync.MapOf` for better concurrency handling.
1 parent 0d16e64 commit ec27e31

File tree

9 files changed

+52
-74
lines changed

9 files changed

+52
-74
lines changed

.github/dependabot.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: "gomod"
4+
directory: "/"
5+
schedule:
6+
interval: "weekly"
7+
- package-ecosystem: "github-actions"
8+
directory: "/"
9+
schedule:
10+
interval: "weekly"

.goreleaser.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ nfpms:
3131
maintainer: Colin Adler <[email protected]>
3232
description: |-
3333
Wush installer package.
34-
Wush creates secure Wireguard tunnels between two devices.
34+
Wush creates secure WireGuard tunnels between two devices.
3535
license: CC0-1.0
3636
contents:
3737
- src: LICENSE

README.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
[![Go Reference](https://pkg.go.dev/badge/github.com/coder/wush.svg)](https://pkg.go.dev/github.com/coder/wush)
44

55
`wush` is a command line tool that lets you easily transfer files and open
6-
shells over a peer-to-peer wireguard connection. It's similar to
6+
shells over a peer-to-peer WireGuard connection. It's similar to
77
[magic-wormhole](https://github.com/magic-wormhole/magic-wormhole) but:
88

99
1. No requirement to set up or trust a relay server for authentication.
10-
1. Powered by Wireguard for secure, fast, and reliable connections.
10+
1. Powered by WireGuard for secure, fast, and reliable connections.
1111
1. Automatic peer-to-peer connections over UDP.
1212
1. Endless possibilities; rsync, ssh, etc.
1313

@@ -47,7 +47,7 @@ Picked DERP region Toronto as overlay home
4747
Your auth key is:
4848
> 112v1RyL5KPzsbMbhT7fkEGrcfpygxtnvwjR5kMLGxDHGeLTK1BvoPqsUcjo7xyMkFn46KLTdedKuPCG5trP84mz9kx
4949
Use this key to authenticate other wush commands to this instance.
50-
05:18:59 Wireguard is ready
50+
05:18:59 WireGuard is ready
5151
05:18:59 SSH server listening
5252
```
5353
@@ -61,8 +61,8 @@ Auth information:
6161
> Server overlay DERP home: Toronto
6262
> Server overlay public key: [NFWN0]
6363
> Server overlay auth key: [mTbpN]
64-
Bringing Wireguard up..
65-
Wireguard is ready!
64+
Bringing WireGuard up..
65+
WireGuard is ready!
6666
Received peer
6767
Peer active with relay nyc
6868
Peer active over p2p 172.20.0.8:53768
@@ -77,8 +77,8 @@ Auth information:
7777
> Server overlay DERP home: Toronto
7878
> Server overlay public key: [sEIS1]
7979
> Server overlay auth key: [w/sYF]
80-
Bringing Wireguard up..
81-
Wireguard is ready!
80+
Bringing WireGuard up..
81+
WireGuard is ready!
8282
Received peer
8383
Peer active with relay nyc
8484
Peer active over p2p 172.20.0.8:44483
@@ -106,10 +106,10 @@ runs over one of two currently implemented mediums; UDP or DERP. Each message
106106
over the relay is encrypted with the sender's private key.
107107
108108
**UDP**: The receiver creates a NAT holepunch to allow senders to connect
109-
directly. Wireguard nodes are exchanged peer-to-peer. This mode will only work
109+
directly. WireGuard nodes are exchanged peer-to-peer. This mode will only work
110110
if the receiver doesn't have hard NAT.
111111

112-
**DERP**: The receiver connects to the closet DERP relay server. Wireguard nodes
112+
**DERP**: The receiver connects to the closet DERP relay server. WireGuard nodes
113113
are exchanged through the relay.
114114

115115
In both cases auth is handled the same way. The receiver will only accept
@@ -131,4 +131,4 @@ way more functionality.
131131

132132
1. [Tailscale](https://tailscale.com)
133133
1. [Headscale](https://github.com/juanfont/headscale)
134-
1. [Wireguard-go](https://github.com/WireGuard/wireguard-go)
134+
1. [WireGuard-go](https://github.com/WireGuard/wireguard-go)

cmd/wush/cp.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,9 @@ func cpCmd() *serpent.Command {
145145
ts.Logf = func(string, ...any) {}
146146
ts.UserLogf = func(string, ...any) {}
147147

148-
logf("Bringing Wireguard up..")
148+
logf("Bringing WireGuard up..")
149149
ts.Up(ctx)
150-
logf("Wireguard is ready!")
150+
logf("WireGuard is ready!")
151151

152152
lc, err := ts.LocalClient()
153153
if err != nil {

cmd/wush/serve.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ func serveCmd() *serpent.Command {
8787
ts.Up(ctx)
8888
fs := afero.NewOsFs()
8989

90-
fmt.Println(cliui.Timestamp(time.Now()), "Wireguard is ready")
90+
fmt.Println(cliui.Timestamp(time.Now()), "WireGuard is ready")
9191

9292
sshSrv, err := agentssh.NewServer(ctx,
9393
cslog.Make(csloghuman.Sink(logSink)),

cmd/wush/ssh.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,9 @@ func sshCmd() *serpent.Command {
6464
ts.Logf = func(string, ...any) {}
6565
ts.UserLogf = func(string, ...any) {}
6666

67-
logf("Bringing Wireguard up..")
67+
logf("Bringing WireGuard up..")
6868
ts.Up(ctx)
69-
logf("Wireguard is ready!")
69+
logf("WireGuard is ready!")
7070

7171
lc, err := ts.LocalClient()
7272
if err != nil {

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ require (
1414
github.com/coder/pretty v0.0.0-20230908205945-e89ba86370e0
1515
github.com/coder/serpent v0.8.0
1616
github.com/go-chi/chi/v5 v5.1.0
17-
github.com/google/uuid v1.6.0
1817
github.com/klauspost/compress v1.17.9
1918
github.com/mattn/go-isatty v0.0.20
2019
github.com/mitchellh/go-wordwrap v1.0.1
@@ -107,6 +106,7 @@ require (
107106
github.com/google/go-cmp v0.6.0 // indirect
108107
github.com/google/nftables v0.2.1-0.20240414091927-5e242ec57806 // indirect
109108
github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd // indirect
109+
github.com/google/uuid v1.6.0 // indirect
110110
github.com/gorilla/csrf v1.7.2 // indirect
111111
github.com/gorilla/securecookie v1.1.2 // indirect
112112
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect

install.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env bash
22

3-
set -euo pipefail
3+
set -eu
44

55
GITHUB_REPO="coder/wush"
66
BINARY_NAME="wush"

tsserver/server.go

Lines changed: 24 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
// SPDX-License-Identifier: BSD-3-Clause, CC0-1.0
12
// Package tsserver implements the Tailscale coordination protocol for a single
2-
// client. Heavy inspiration was taken from https://github.com/juanfont/headscale
3+
// client. Heavy inspiration and code was taken from https://github.com/juanfont/headscale.
4+
// As such, this file is dual licensed under BSD-3-Clause and CC0-1.0.
35
package tsserver
46

57
import (
@@ -22,9 +24,7 @@ import (
2224
"sync/atomic"
2325
"time"
2426

25-
"github.com/coder/wush/overlay"
2627
"github.com/go-chi/chi/v5"
27-
"github.com/google/uuid"
2828
"github.com/klauspost/compress/zstd"
2929
"github.com/puzpuzpuz/xsync/v3"
3030
"github.com/valyala/fasthttp/fasthttputil"
@@ -39,6 +39,8 @@ import (
3939
"tailscale.com/types/key"
4040
"tailscale.com/types/opt"
4141
"tailscale.com/types/ptr"
42+
43+
"github.com/coder/wush/overlay"
4244
)
4345

4446
func DERPMapTailscale(ctx context.Context) (*tailcfg.DERPMap, error) {
@@ -242,7 +244,8 @@ func (s *server) NoiseUpgradeHandler(w http.ResponseWriter, r *http.Request) {
242244
logger: s.logger,
243245
derpMap: s.derpMap,
244246
challenge: key.NewChallenge(),
245-
updates: s.peerMapUpdate,
247+
peers: xsync.NewMapOf[tailcfg.NodeID, *tailcfg.Node](),
248+
peerUpdate: s.peerMapUpdate,
246249
node: &s.node,
247250
nodeUpdate: s.nodeUpdate,
248251
getIP: s.overlay.IP,
@@ -332,7 +335,9 @@ type noiseServer struct {
332335
derpMap *tailcfg.DERPMap
333336
getIP func() netip.Addr
334337

335-
updates chan update
338+
peers *xsync.MapOf[tailcfg.NodeID, *tailcfg.Node]
339+
peerUpdate chan update
340+
336341
node *atomic.Pointer[tailcfg.Node]
337342
nodeUpdate chan struct{}
338343

@@ -341,37 +346,6 @@ type noiseServer struct {
341346
protocolVersion int
342347
}
343348

344-
func maskUUID(uid uuid.UUID) uuid.UUID {
345-
// This is Tailscale's ephemeral service prefix. This can be changed easily
346-
// later-on, because all of our nodes are ephemeral.
347-
// fd7a:115c:a1e0
348-
uid[0] = 0xfd
349-
uid[1] = 0x7a
350-
uid[2] = 0x11
351-
uid[3] = 0x5c
352-
uid[4] = 0xa1
353-
uid[5] = 0xe0
354-
return uid
355-
}
356-
357-
// IP generates a random IP with a static service prefix.
358-
func IP() netip.Addr {
359-
uid := maskUUID(uuid.New())
360-
return netip.AddrFrom16(uid)
361-
}
362-
363-
// func IP4r() netip.Addr {
364-
// return netip.AddrFrom4([4]byte{100, 64, 1, 1})
365-
// }
366-
// func IP4s() netip.Addr {
367-
// return netip.AddrFrom4([4]byte{100, 64, 2, 2})
368-
// }
369-
370-
// IP generates a new IP from a UUID.
371-
func IPFromUUID(uid uuid.UUID) netip.Addr {
372-
return netip.AddrFrom16(maskUUID(uid))
373-
}
374-
375349
func (ns *noiseServer) notifyUpdate() {
376350
ns.nodeUpdate <- struct{}{}
377351
}
@@ -389,17 +363,6 @@ func (ns *noiseServer) NoiseRegistrationHandler(w http.ResponseWriter, r *http.R
389363
sp := strings.SplitN(registerRequest.Auth.AuthKey, "-", 2)
390364

391365
ip := ns.getIP()
392-
// var ip netip.Addr
393-
// switch registerRequest.Auth.AuthKey {
394-
// case "receive":
395-
// ip = IP4r()
396-
// case "send":
397-
// ip = IP4s()
398-
// default:
399-
// http.Error(w, fmt.Sprintf("unknown authkey: %q", registerRequest.Auth.AuthKey), http.StatusBadRequest)
400-
// return
401-
// }
402-
// try insecureskipverify
403366

404367
resp := tailcfg.RegisterResponse{}
405368
resp.MachineAuthorized = true
@@ -506,17 +469,21 @@ func (ns *noiseServer) NoisePollNetMapHandler(
506469
func (ns *noiseServer) peerMap() []*tailcfg.Node {
507470
peers := []*tailcfg.Node{}
508471

509-
// TOOD: get peers
472+
ns.peers.Range(func(key tailcfg.NodeID, value *tailcfg.Node) bool {
473+
peers = append(peers, value.Clone())
474+
return true
475+
})
476+
xslices.SortFunc(peers, func(a, b *tailcfg.Node) int {
477+
return cmp.Compare(a.ID, b.ID)
478+
})
510479

511480
return peers
512481
}
513482

514483
func (ns *noiseServer) handleStreaming(ctx context.Context, w http.ResponseWriter, req *tailcfg.MapRequest) {
515-
// Upgrade the writer to a ResponseController
516484
rc := http.NewResponseController(w)
517-
518-
// Longpolling will break if there is a write timeout,
519-
// so it needs to be disabled.
485+
// Longpolling will break if there is a write timeout, so it needs to be
486+
// disabled.
520487
rc.SetWriteDeadline(time.Time{})
521488

522489
node := ns.getSelfNode()
@@ -552,13 +519,14 @@ func (ns *noiseServer) handleStreaming(ctx context.Context, w http.ResponseWrite
552519
select {
553520
case <-ctx.Done():
554521
return
555-
case upd := <-ns.updates:
522+
case upd := <-ns.peerUpdate:
556523
res := &tailcfg.MapResponse{
557524
KeepAlive: false,
558525
ControlTime: ptr.To(time.Now()),
559526
}
560527
if upd.ty == updateTypeNewPeer {
561-
res.Peers = []*tailcfg.Node{upd.node}
528+
ns.peers.Store(upd.node.ID, upd.node.Clone())
529+
res.Peers = ns.peerMap()
562530
} else if upd.ty == updateTypePeerUpdate {
563531
res.PeersChangedPatch = []*tailcfg.PeerChange{upd.update}
564532
}
@@ -590,7 +558,6 @@ func (ns *noiseServer) handleStreaming(ctx context.Context, w http.ResponseWrite
590558
}
591559
}
592560
}
593-
594561
}
595562

596563
func writeMapResponse(w http.ResponseWriter, req *tailcfg.MapRequest, res *tailcfg.MapResponse) error {
@@ -751,7 +718,6 @@ func peerChange(req *tailcfg.MapRequest, node *tailcfg.Node) tailcfg.PeerChange
751718
}
752719
}
753720

754-
// TODO(kradalby): Find a good way to compare updates
755721
ret.Endpoints = req.Endpoints
756722

757723
ret.LastSeen = ptr.To(time.Now())
@@ -831,6 +797,8 @@ const (
831797
earlyPayloadMagic = "\xff\xff\xffTS"
832798
)
833799

800+
var _ = (*noiseServer)(nil).earlyNoise
801+
834802
func (ns *noiseServer) earlyNoise(protocolVersion int, writer io.Writer) error {
835803
ns.logger.Info("early noise")
836804
if protocolVersion < earlyNoiseCapabilityVersion {

0 commit comments

Comments
 (0)