Skip to content

Commit 830c227

Browse files
committed
intra/tunnel: impl Restart
1 parent 5589498 commit 830c227

1 file changed

Lines changed: 53 additions & 2 deletions

File tree

intra/tunnel.go

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ var bar = core.NewKeyedBarrier[*x.NetStat, string](30 * time.Second)
5454
var (
5555
errNoStatCache = errors.New("netstat: stat in cache is nil")
5656
errClosed = errors.New("tunnel closed for business")
57+
errMakeTunnel = errors.New("could not make tunnel")
5758
)
5859

5960
type Bridge interface {
@@ -92,6 +93,8 @@ type Tunnel interface {
9293
SetRoute(engine int) error
9394
// SetLinkAndRoutes sets the tun fd as link with mtu & engine as routes for the tunnel.
9495
SetLinkAndRoutes(fd, mtu, engine int) error
96+
// Restart restarts the tunnel with the given fd, mtu, and engine.
97+
Restart(fd, mtu, engine int) error
9598

9699
// Sets pcap output to fpcap which is the absolute filepath
97100
// to which a PCAP file will be written to.
@@ -105,6 +108,7 @@ type rtunnel struct {
105108
tunmu sync.Mutex // serializes access to tunnel.Tunnel
106109
ctx context.Context
107110
done context.CancelFunc
111+
handlers netstack.GConnHandler
108112
proxies ipn.Proxies
109113
resolver dnsx.Resolver
110114
services rnet.Services
@@ -183,19 +187,21 @@ func NewTunnel(fd, mtu int, fakedns string, dtr DefaultDNS, bdg Bridge) (t Tunne
183187

184188
gt, revhdl, err := tunnel.NewGTunnel(ctx, fd, mtu, dualstack, hdl)
185189

186-
if err != nil {
190+
if gt == nil || err != nil {
187191
log.W("tun: <<< new >>>; err(%v)", err)
188-
return nil, err
192+
return nil, core.OneErr(err, errMakeTunnel)
189193
}
190194

191195
log.D("tun: <<< new >>>; netstack: ok")
192196

197+
// TODO: err on reverser errors too?
193198
rerr := proxies.Reverser(revhdl)
194199

195200
t = &rtunnel{
196201
Tunnel: gt,
197202
ctx: ctx,
198203
done: cancel,
204+
handlers: hdl,
199205
proxies: proxies,
200206
resolver: resolver,
201207
services: services,
@@ -244,6 +250,51 @@ func (t *rtunnel) SetLinkAndRoutes(fd, mtu, engine int) error {
244250
if l3diff {
245251
t.resolver.Add(newMDNSTransport(t.ctx, l3, t.proxies))
246252
}
253+
})
254+
255+
return err
256+
}
257+
258+
func (t *rtunnel) Restart(fd, mtu, engine int) error {
259+
if t.closed.Load() {
260+
log.W("tun: <<< restart >>>; already closed")
261+
return errClosed
262+
}
263+
264+
countdown := make(chan struct{})
265+
defer close(countdown)
266+
267+
ontimeout := func() {
268+
log.E("tun: <<< restart >>>; timed out ...")
269+
t.done()
270+
}
271+
272+
go core.EitherOr(countdown, ontimeout, mktunTimeout)
273+
274+
l3 := settings.L3(engine)
275+
l3diff := dialers.IPProtos(l3)
276+
277+
gt, revhdl, err := tunnel.NewGTunnel(t.ctx, fd, mtu, l3, t.handlers)
278+
279+
if gt == nil || err != nil {
280+
log.W("tun: <<< restart >>>; err(%v)", err)
281+
t.Tunnel.Disconnect()
282+
return core.OneErr(err, errMakeTunnel)
283+
}
284+
285+
t.tunmu.Lock()
286+
t.Tunnel.Disconnect()
287+
t.Tunnel = gt
288+
t.tunmu.Unlock()
289+
290+
// TODO: err on reverser errors too?
291+
rerr := t.proxies.Reverser(revhdl)
292+
293+
log.D("tun: <<< restart >>>; netstack: ok; rev err? %v", rerr)
294+
295+
core.Gx("i.RestartRefresh", func() {
296+
// Refresh proxies to update to the new reverser
297+
go t.proxies.RefreshProto(l3, mtu, true /*force; reverser changed*/) // also updates reverser
247298
if l3diff {
248299
t.resolver.Add(newMDNSTransport(t.ctx, l3, t.proxies))
249300
}

0 commit comments

Comments
 (0)