@@ -17,9 +17,10 @@ package ipn
17
17
18
18
import (
19
19
"bufio"
20
+ "bytes"
20
21
"context"
22
+ "encoding/base64"
21
23
"fmt"
22
- "math/rand/v2"
23
24
"net"
24
25
"net/netip"
25
26
"os"
@@ -80,6 +81,7 @@ type wgtun struct {
80
81
ingress chan * buffer.View // pipes ep writes to wg
81
82
events chan tun.Event // wg specific tun (interface) events
82
83
finalize chan struct {} // close signal for incomingPacket
84
+ clientid [3 ]byte // client id; applicable only for warp
83
85
mtu int // mtu of this interface
84
86
ba * core.Barrier [[]netip.Addr , string ] // request barrier for dns lookups
85
87
once sync.Once // exec fn exactly once
@@ -313,7 +315,7 @@ func (w *wgproxy) update(id, txt string) bool {
313
315
314
316
// str copy: go.dev/play/p/eO814kGGNtO
315
317
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 )
317
319
if err != nil {
318
320
log .W ("proxy: wg: !update(%s): err: %v" , w .id , err )
319
321
return anew
@@ -324,6 +326,11 @@ func (w *wgproxy) update(id, txt string) bool {
324
326
return anew
325
327
}
326
328
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
+
327
334
actualmtu := calcTunMtu (mtu )
328
335
if w .mtu != actualmtu {
329
336
log .D ("proxy: wg: !update(%s): mtu %d != %d" , w .id , actualmtu , w .mtu )
@@ -382,7 +389,7 @@ func wglogger(id string) *device.Logger {
382
389
return logger
383
390
}
384
391
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 ) {
386
393
txt := * txtptr
387
394
pcfg := strings.Builder {}
388
395
r := bufio .NewScanner (strings .NewReader (txt ))
@@ -421,6 +428,15 @@ func wgIfConfigOf(id string, txtptr *string) (ifaddrs []netip.Prefix, allowedadd
421
428
if mtu , err = strconv .Atoi (v ); err != nil {
422
429
return
423
430
}
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
+ }
424
440
case "allowed_ip" : // may exist more than once
425
441
if err = loadIPNets (& allowedaddrs , v ); err != nil {
426
442
return
@@ -505,38 +521,27 @@ func (w *wgproxy) StopThenNew(ctl protect.Controller, rev netstack.GConnHandler)
505
521
// ref: github.com/WireGuard/wireguard-android/blob/713947e432/tunnel/tools/libwg-go/api-android.go#L76
506
522
func NewWgProxy (id string , ctl protect.Controller , rev netstack.GConnHandler , cfg string ) (* wgproxy , error ) {
507
523
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 )
509
525
uapicfg := cfg
510
526
if err != nil {
511
527
log .E ("proxy: wg: %s failed to get addrs from config %v" , id , err )
512
528
return nil , err
513
529
}
514
530
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 )
516
532
if err != nil {
517
533
log .E ("proxy: wg: %s failed to create tun %v" , id , err )
518
534
return nil , err
519
535
}
520
536
521
537
id = wgtun .id // has stripped prefix FAST, if any
522
538
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
-
534
539
var wgep wgconn
535
540
if wgtun .preferOffload {
536
541
// todo: use wgtun.serve fn instead of ctl
537
542
wgep = wg .NewEndpoint2 (id , ctl , endpointh , wgtun .listener )
538
543
} else {
539
- wgep = wg .NewEndpoint (id , wgtun .serve , endpointh , wgtun .listener , reservedBytes )
544
+ wgep = wg .NewEndpoint (id , wgtun .serve , endpointh , wgtun .listener , wgtun . clientid )
540
545
}
541
546
542
547
wgdev := device .NewDevice (wgtun , wgep , wglogger (id ))
@@ -571,7 +576,7 @@ func NewWgProxy(id string, ctl protect.Controller, rev netstack.GConnHandler, cf
571
576
}
572
577
573
578
// 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 ) {
575
580
if rev == nil {
576
581
return nil , errMissingRev
577
582
}
@@ -610,6 +615,7 @@ func makeWgTun(id, cfg string, ctl protect.Controller, rev netstack.GConnHandler
610
615
rt : x .NewIpTree (), // must be set to allowedaddrs
611
616
ba : core.NewBarrier [[]netip.Addr ](wgbarrierttl ),
612
617
mtu : tunmtu ,
618
+ clientid : clientid ,
613
619
status : core .NewVolatile (TUP ),
614
620
preferOffload : preferOffload (id ),
615
621
refreshBa : core.NewBarrier [bool ](2 * time .Minute ),
0 commit comments