4
4
"context"
5
5
"errors"
6
6
"fmt"
7
- "log"
7
+ "log/slog "
8
8
"net"
9
9
"net/netip"
10
10
"os"
@@ -20,7 +20,6 @@ const singleMTU = 1400
20
20
const doubleMTU = 1320
21
21
22
22
type WarpOptions struct {
23
- LogLevel string
24
23
Bind netip.AddrPort
25
24
Endpoint string
26
25
License string
@@ -37,7 +36,7 @@ type ScanOptions struct {
37
36
MaxRTT time.Duration
38
37
}
39
38
40
- func RunWarp (ctx context.Context , opts WarpOptions ) error {
39
+ func RunWarp (ctx context.Context , l * slog. Logger , opts WarpOptions ) error {
41
40
if opts .Psiphon != nil && opts .Gool {
42
41
return errors .New ("can't use psiphon and gool at the same time" )
43
42
}
@@ -50,16 +49,16 @@ func RunWarp(ctx context.Context, opts WarpOptions) error {
50
49
if err := makeDirs (); err != nil {
51
50
return err
52
51
}
53
- log . Println ("'primary' and 'secondary' directories are ready" )
52
+ l . Debug ("'primary' and 'secondary' directories are ready" )
54
53
55
54
// Change the current working directory to 'stuff'
56
55
if err := os .Chdir ("stuff" ); err != nil {
57
56
return fmt .Errorf ("error changing to 'stuff' directory: %w" , err )
58
57
}
59
- log . Println ("Changed working directory to 'stuff'" )
58
+ l . Debug ("Changed working directory to 'stuff'" )
60
59
61
60
// create identities
62
- if err := createPrimaryAndSecondaryIdentities (opts .License ); err != nil {
61
+ if err := createPrimaryAndSecondaryIdentities (l . With ( "subsystem" , "warp/account" ), opts .License ); err != nil {
63
62
return err
64
63
}
65
64
@@ -72,112 +71,146 @@ func RunWarp(ctx context.Context, opts WarpOptions) error {
72
71
return err
73
72
}
74
73
75
- log . Printf ("scan results: %+v " , res )
74
+ l . Info ("scan results" , "endpoints " , res )
76
75
77
76
endpoints = make ([]string , len (res ))
78
77
for i := 0 ; i < len (res ); i ++ {
79
78
endpoints [i ] = res [i ].AddrPort .String ()
80
79
}
81
80
}
82
- log . Printf ("using warp endpoints: %+v " , endpoints )
81
+ l . Info ("using warp endpoints" , "endpoints " , endpoints )
83
82
84
83
var warpErr error
85
84
switch {
86
85
case opts .Psiphon != nil :
86
+ l .Info ("running in Psiphon (cfon) mode" )
87
87
// run primary warp on a random tcp port and run psiphon on bind address
88
- warpErr = runWarpWithPsiphon (ctx , opts .Bind , endpoints , opts .Psiphon .Country , opts . LogLevel == "debug" )
88
+ warpErr = runWarpWithPsiphon (ctx , l , opts .Bind , endpoints [ 0 ] , opts .Psiphon .Country )
89
89
case opts .Gool :
90
+ l .Info ("running in warp-in-warp (gool) mode" )
90
91
// run warp in warp
91
- warpErr = runWarpInWarp (ctx , opts .Bind , endpoints , opts . LogLevel == "debug" )
92
+ warpErr = runWarpInWarp (ctx , l , opts .Bind , endpoints )
92
93
default :
94
+ l .Info ("running in normal warp mode" )
93
95
// just run primary warp on bindAddress
94
- _ , warpErr = runWarp (ctx , opts . Bind , endpoints , "./primary/wgcf-profile.ini" , opts .LogLevel == "debug" , true , true , singleMTU )
96
+ warpErr = runWarp (ctx , l , opts .Bind , endpoints [ 0 ] )
95
97
}
96
98
97
99
return warpErr
98
100
}
99
101
100
- func runWarp (ctx context.Context , bind netip.AddrPort , endpoints [] string , confPath string , verbose , startProxy bool , trick bool , mtu int ) ( * wiresocks. VirtualTun , error ) {
101
- conf , err := wiresocks .ParseConfig (confPath , endpoints [ 0 ] )
102
+ func runWarp (ctx context.Context , l * slog. Logger , bind netip.AddrPort , endpoint string ) error {
103
+ conf , err := wiresocks .ParseConfig ("./primary/wgcf-profile.ini" , endpoint )
102
104
if err != nil {
103
- log .Println (err )
104
- return nil , err
105
+ return err
105
106
}
106
- conf .Interface .MTU = mtu
107
+ conf .Interface .MTU = singleMTU
107
108
108
109
for i , peer := range conf .Peers {
109
- peer .KeepAlive = 10
110
- if trick {
111
- peer .Trick = true
112
- peer .KeepAlive = 3
113
- }
114
-
110
+ peer .Trick = true
111
+ peer .KeepAlive = 3
115
112
conf .Peers [i ] = peer
116
113
}
117
114
118
- tnet , err := wiresocks .StartWireguard (ctx , conf , verbose )
115
+ tnet , err := wiresocks .StartWireguard (ctx , l , conf )
119
116
if err != nil {
120
- log .Println (err )
121
- return nil , err
117
+ return err
122
118
}
123
119
124
- if startProxy {
125
- tnet .StartProxy (bind )
126
- }
120
+ tnet .StartProxy (bind )
121
+ l .Info ("Serving proxy" , "address" , bind )
127
122
128
- return tnet , nil
123
+ return nil
129
124
}
130
125
131
- func runWarpWithPsiphon (ctx context.Context , bind netip.AddrPort , endpoints [] string , country string , verbose bool ) error {
126
+ func runWarpWithPsiphon (ctx context.Context , l * slog. Logger , bind netip.AddrPort , endpoint string , country string ) error {
132
127
// make a random bind address for warp
133
128
warpBindAddress , err := findFreePort ("tcp" )
134
129
if err != nil {
135
- log .Println ("There are no free tcp ports on Device!" )
136
130
return err
137
131
}
138
132
139
- _ , err = runWarp (ctx , warpBindAddress , endpoints , "./primary/wgcf-profile.ini" , verbose , true , true , singleMTU )
133
+ conf , err := wiresocks .ParseConfig ("./primary/wgcf-profile.ini" , endpoint )
134
+ if err != nil {
135
+ return err
136
+ }
137
+ conf .Interface .MTU = singleMTU
138
+
139
+ for i , peer := range conf .Peers {
140
+ peer .Trick = true
141
+ peer .KeepAlive = 3
142
+ conf .Peers [i ] = peer
143
+ }
144
+
145
+ tnet , err := wiresocks .StartWireguard (ctx , l , conf )
140
146
if err != nil {
141
147
return err
142
148
}
143
149
150
+ tnet .StartProxy (warpBindAddress )
151
+
144
152
// run psiphon
145
- err = psiphon .RunPsiphon (warpBindAddress .String (), bind .String (), country , ctx )
153
+ err = psiphon .RunPsiphon (ctx , l . With ( "subsystem" , "psiphon" ), warpBindAddress .String (), bind .String (), country )
146
154
if err != nil {
147
- log .Printf ("unable to run psiphon %v" , err )
148
155
return fmt .Errorf ("unable to run psiphon %w" , err )
149
156
}
150
157
151
- log . Printf ("Serving on %s " , bind )
158
+ l . Info ("Serving proxy" , "address " , bind )
152
159
153
160
return nil
154
161
}
155
162
156
- func runWarpInWarp (ctx context.Context , bind netip.AddrPort , endpoints []string , verbose bool ) error {
163
+ func runWarpInWarp (ctx context.Context , l * slog. Logger , bind netip.AddrPort , endpoints []string ) error {
157
164
// Run outer warp
158
- vTUN , err := runWarp (ctx , netip.AddrPort {}, endpoints , "./secondary/wgcf-profile.ini" , verbose , false , true , singleMTU )
165
+ conf , err := wiresocks .ParseConfig ("./primary/wgcf-profile.ini" , endpoints [0 ])
166
+ if err != nil {
167
+ return err
168
+ }
169
+ conf .Interface .MTU = singleMTU
170
+
171
+ for i , peer := range conf .Peers {
172
+ peer .Trick = true
173
+ peer .KeepAlive = 3
174
+ conf .Peers [i ] = peer
175
+ }
176
+
177
+ tnet , err := wiresocks .StartWireguard (ctx , l .With ("gool" , "outer" ), conf )
159
178
if err != nil {
160
179
return err
161
180
}
162
181
163
182
// Run virtual endpoint
164
183
virtualEndpointBindAddress , err := findFreePort ("udp" )
165
184
if err != nil {
166
- log .Println ("There are no free udp ports on Device!" )
167
185
return err
168
186
}
169
- addr := endpoints [1 ]
170
- err = wiresocks .NewVtunUDPForwarder (virtualEndpointBindAddress .String (), addr , vTUN , singleMTU , ctx )
187
+
188
+ // Create a UDP port forward between localhost and the remote endpoint
189
+ err = wiresocks .NewVtunUDPForwarder (ctx , virtualEndpointBindAddress .String (), endpoints [1 ], tnet , singleMTU )
171
190
if err != nil {
172
- log .Println (err )
173
191
return err
174
192
}
175
193
176
194
// Run inner warp
177
- _ , err = runWarp (ctx , bind , []string {virtualEndpointBindAddress .String ()}, "./primary/wgcf-profile.ini" , verbose , true , false , doubleMTU )
195
+ conf , err = wiresocks .ParseConfig ("./secondary/wgcf-profile.ini" , virtualEndpointBindAddress .String ())
196
+ if err != nil {
197
+ return err
198
+ }
199
+ conf .Interface .MTU = doubleMTU
200
+
201
+ for i , peer := range conf .Peers {
202
+ peer .KeepAlive = 10
203
+ conf .Peers [i ] = peer
204
+ }
205
+
206
+ tnet , err = wiresocks .StartWireguard (ctx , l .With ("gool" , "inner" ), conf )
178
207
if err != nil {
179
208
return err
180
209
}
210
+
211
+ tnet .StartProxy (bind )
212
+
213
+ l .Info ("Serving proxy" , "address" , bind )
181
214
return nil
182
215
}
183
216
@@ -207,22 +240,20 @@ func findFreePort(network string) (netip.AddrPort, error) {
207
240
return netip .MustParseAddrPort (listener .Addr ().String ()), nil
208
241
}
209
242
210
- func createPrimaryAndSecondaryIdentities (license string ) error {
243
+ func createPrimaryAndSecondaryIdentities (l * slog. Logger , license string ) error {
211
244
// make primary identity
212
245
warp .UpdatePath ("./primary" )
213
246
if ! warp .CheckProfileExists (license ) {
214
- err := warp .LoadOrCreateIdentity (license )
247
+ err := warp .LoadOrCreateIdentity (l , license )
215
248
if err != nil {
216
- log .Printf ("error: %v" , err )
217
249
return err
218
250
}
219
251
}
220
252
// make secondary
221
253
warp .UpdatePath ("./secondary" )
222
254
if ! warp .CheckProfileExists (license ) {
223
- err := warp .LoadOrCreateIdentity (license )
255
+ err := warp .LoadOrCreateIdentity (l , license )
224
256
if err != nil {
225
- log .Printf ("error: %v" , err )
226
257
return err
227
258
}
228
259
}
0 commit comments