Skip to content

Commit 8081c0e

Browse files
committed
ipn/wg: warp client id
1 parent 37073cf commit 8081c0e

File tree

2 files changed

+25
-19
lines changed

2 files changed

+25
-19
lines changed

intra/ipn/proxy.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ func (pxr *proxifier) addProxy(id, txt string) (p Proxy, err error) {
4545
if wgp, ok := p.(WgProxy); ok && wgp.update(id, txt) {
4646
log.I("proxy: updating wg %s/%s", id, p.GetAddr())
4747

48-
ifaddrs, _, _, dnsh, _, mtu, err0 := wgIfConfigOf(id, &txt) // removes wg ifconfig from txt
48+
ifaddrs, _, _, dnsh, _, mtu, _, err0 := wgIfConfigOf(id, &txt) // removes wg ifconfig from txt
4949
if err0 != nil {
5050
log.W("proxy: err0 updating wg(%s); %v", id, err0)
5151
return nil, err0

intra/ipn/wgproxy.go

+24-18
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@ package ipn
1717

1818
import (
1919
"bufio"
20+
"bytes"
2021
"context"
22+
"encoding/base64"
2123
"fmt"
22-
"math/rand/v2"
2324
"net"
2425
"net/netip"
2526
"os"
@@ -80,6 +81,7 @@ type wgtun struct {
8081
ingress chan *buffer.View // pipes ep writes to wg
8182
events chan tun.Event // wg specific tun (interface) events
8283
finalize chan struct{} // close signal for incomingPacket
84+
clientid [3]byte // client id; applicable only for warp
8385
mtu int // mtu of this interface
8486
ba *core.Barrier[[]netip.Addr, string] // request barrier for dns lookups
8587
once sync.Once // exec fn exactly once
@@ -313,7 +315,7 @@ func (w *wgproxy) update(id, txt string) bool {
313315

314316
// str copy: go.dev/play/p/eO814kGGNtO
315317
cptxt := txt
316-
ifaddrs, allowed, peers, dnsh, peersh, mtu, err := wgIfConfigOf(w.id, &cptxt)
318+
ifaddrs, allowed, peers, dnsh, peersh, mtu, clientid, err := wgIfConfigOf(w.id, &cptxt)
317319
if err != nil {
318320
log.W("proxy: wg: !update(%s): err: %v", w.id, err)
319321
return anew
@@ -324,6 +326,11 @@ func (w *wgproxy) update(id, txt string) bool {
324326
return anew
325327
}
326328

329+
if !bytes.Equal(clientid[:], w.clientid[:]) {
330+
log.D("proxy: wg: !update(%s): clientid %v != %v", w.id, clientid, w.clientid)
331+
return anew
332+
}
333+
327334
actualmtu := calcTunMtu(mtu)
328335
if w.mtu != actualmtu {
329336
log.D("proxy: wg: !update(%s): mtu %d != %d", w.id, actualmtu, w.mtu)
@@ -382,7 +389,7 @@ func wglogger(id string) *device.Logger {
382389
return logger
383390
}
384391

385-
func wgIfConfigOf(id string, txtptr *string) (ifaddrs []netip.Prefix, allowedaddrs []netip.Prefix, peers map[string]device.NoisePublicKey, dnsh, endpointh *multihost.MH, mtu int, err error) {
392+
func wgIfConfigOf(id string, txtptr *string) (ifaddrs []netip.Prefix, allowedaddrs []netip.Prefix, peers map[string]device.NoisePublicKey, dnsh, endpointh *multihost.MH, mtu int, clientid [3]byte, err error) {
386393
txt := *txtptr
387394
pcfg := strings.Builder{}
388395
r := bufio.NewScanner(strings.NewReader(txt))
@@ -421,6 +428,15 @@ func wgIfConfigOf(id string, txtptr *string) (ifaddrs []netip.Prefix, allowedadd
421428
if mtu, err = strconv.Atoi(v); err != nil {
422429
return
423430
}
431+
case "client_id":
432+
// only for warp: blog.cloudflare.com/warp-technical-challenges
433+
// When we begin a WireGuard session we include our clientid field
434+
// which is provided by our authentication server which has to be
435+
// communicated with to begin a WARP session.
436+
if b, err := base64.StdEncoding.DecodeString(v); err == nil {
437+
n := copy(clientid[:], b)
438+
log.D("proxy: wg: %s ifconfig: clientid(%d) %v", id, n, clientid)
439+
}
424440
case "allowed_ip": // may exist more than once
425441
if err = loadIPNets(&allowedaddrs, v); err != nil {
426442
return
@@ -505,38 +521,27 @@ func (w *wgproxy) StopThenNew(ctl protect.Controller, rev netstack.GConnHandler)
505521
// ref: github.com/WireGuard/wireguard-android/blob/713947e432/tunnel/tools/libwg-go/api-android.go#L76
506522
func NewWgProxy(id string, ctl protect.Controller, rev netstack.GConnHandler, cfg string) (*wgproxy, error) {
507523
ogcfg := cfg
508-
ifaddrs, allowedaddrs, peers, dnsh, endpointh, mtu, err := wgIfConfigOf(id, &cfg)
524+
ifaddrs, allowedaddrs, peers, dnsh, endpointh, mtu, clientid, err := wgIfConfigOf(id, &cfg)
509525
uapicfg := cfg
510526
if err != nil {
511527
log.E("proxy: wg: %s failed to get addrs from config %v", id, err)
512528
return nil, err
513529
}
514530

515-
wgtun, err := makeWgTun(id, ogcfg, ctl, rev, ifaddrs, allowedaddrs, peers, dnsh, endpointh, mtu)
531+
wgtun, err := makeWgTun(id, ogcfg, ctl, rev, ifaddrs, allowedaddrs, peers, dnsh, endpointh, mtu, clientid)
516532
if err != nil {
517533
log.E("proxy: wg: %s failed to create tun %v", id, err)
518534
return nil, err
519535
}
520536

521537
id = wgtun.id // has stripped prefix FAST, if any
522538

523-
// github.com/bepass-org/warp-plus/blob/19ac233cc6/wiresocks/config.go#L184
524-
var reservedBytes [3]byte
525-
if isRPN(id) {
526-
// reservedBytes[0] = uint8(rand.UintN(0x100))
527-
// reservedBytes[1] = uint8(rand.UintN(0x100))
528-
// reservedBytes[2] = uint8(rand.UintN(0x100))
529-
reservedBytes[0] = uint8(rand.UintN(0x1))
530-
reservedBytes[1] = uint8(rand.UintN(0x2))
531-
reservedBytes[2] = uint8(rand.UintN(0x3))
532-
}
533-
534539
var wgep wgconn
535540
if wgtun.preferOffload {
536541
// todo: use wgtun.serve fn instead of ctl
537542
wgep = wg.NewEndpoint2(id, ctl, endpointh, wgtun.listener)
538543
} else {
539-
wgep = wg.NewEndpoint(id, wgtun.serve, endpointh, wgtun.listener, reservedBytes)
544+
wgep = wg.NewEndpoint(id, wgtun.serve, endpointh, wgtun.listener, wgtun.clientid)
540545
}
541546

542547
wgdev := device.NewDevice(wgtun, wgep, wglogger(id))
@@ -571,7 +576,7 @@ func NewWgProxy(id string, ctl protect.Controller, rev netstack.GConnHandler, cf
571576
}
572577

573578
// ref: github.com/WireGuard/wireguard-go/blob/469159ecf7/tun/netstack/tun.go#L54
574-
func makeWgTun(id, cfg string, ctl protect.Controller, rev netstack.GConnHandler, ifaddrs, allowedaddrs []netip.Prefix, peers map[string]device.NoisePublicKey, dnsm, endpointm *multihost.MH, mtu int) (*wgtun, error) {
579+
func makeWgTun(id, cfg string, ctl protect.Controller, rev netstack.GConnHandler, ifaddrs, allowedaddrs []netip.Prefix, peers map[string]device.NoisePublicKey, dnsm, endpointm *multihost.MH, mtu int, clientid [3]byte) (*wgtun, error) {
575580
if rev == nil {
576581
return nil, errMissingRev
577582
}
@@ -610,6 +615,7 @@ func makeWgTun(id, cfg string, ctl protect.Controller, rev netstack.GConnHandler
610615
rt: x.NewIpTree(), // must be set to allowedaddrs
611616
ba: core.NewBarrier[[]netip.Addr](wgbarrierttl),
612617
mtu: tunmtu,
618+
clientid: clientid,
613619
status: core.NewVolatile(TUP),
614620
preferOffload: preferOffload(id),
615621
refreshBa: core.NewBarrier[bool](2 * time.Minute),

0 commit comments

Comments
 (0)