Skip to content

Commit 44a07d1

Browse files
committed
ipn/auto: impl remote Probe, Accept
1 parent 2f7466e commit 44a07d1

1 file changed

Lines changed: 122 additions & 26 deletions

File tree

intra/ipn/auto.go

Lines changed: 122 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -281,12 +281,14 @@ func (h *auto) Announce(network, local string) (protect.PacketConn, error) {
281281
return nil, err
282282
}
283283

284+
// TODO: settings.AutoDialsParallel
285+
remoteOnly := settings.AutoAlwaysRemote()
286+
284287
exit, exerr := h.pxr.ProxyFor(Exit)
285288
win, winerr := h.pxr.mainRpnProxyOf(RpnWin)
286289

287290
previdx, recent := h.exp.Get(local)
288291

289-
// TODO: announceIfHealthy
290292
c, who, err := core.Race(
291293
network+".announce-auto."+local,
292294
tlsHandshakeTimeout,
@@ -295,6 +297,9 @@ func (h *auto) Announce(network, local string) (protect.PacketConn, error) {
295297
if exit == nil {
296298
return nil, exerr
297299
}
300+
if remoteOnly {
301+
return nil, errNotRemote
302+
}
298303
if recent {
299304
if previdx != myidx {
300305
return nil, errNotPinned
@@ -315,10 +320,13 @@ func (h *auto) Announce(network, local string) (protect.PacketConn, error) {
315320
// ip pinned to this proxy
316321
return h.announceIfHealthy(win, network, local)
317322
}
318-
select {
319-
case <-ctx.Done():
320-
return nil, ctx.Err()
321-
case <-time.After(shortdelay * myidx): // 100ms
323+
// delay if not dialing remote exclusively
324+
if !remoteOnly {
325+
select {
326+
case <-ctx.Done():
327+
return nil, ctx.Err()
328+
case <-time.After(shortdelay * myidx): // 100ms
329+
}
322330
}
323331
return h.announceIfHealthy(win, network, local)
324332
},
@@ -330,41 +338,113 @@ func (h *auto) Announce(network, local string) (protect.PacketConn, error) {
330338
}
331339

332340
// Accept implements Proxy.
333-
func (h *auto) Accept(network, local string) (l protect.Listener, err error) {
341+
func (h *auto) Accept(network, local string) (protect.Listener, error) {
334342
if err := candial(h.status); err != nil {
335343
return nil, err
336344
}
337-
if settings.AutoAlwaysRemote() {
338-
log.E("proxy: auto: accept(%s) on %s remote-dial unimplemented", network, local)
339-
return nil, errNoAutoSupport
340-
}
341-
exit, err := h.pxr.ProxyFor(Exit)
342-
if err == nil {
343-
l, err = exit.Dialer().Accept(network, local)
344-
}
345+
346+
// TODO: settings.AutoDialsParallel
347+
remoteOnly := settings.AutoAlwaysRemote()
348+
349+
exit, exerr := h.pxr.ProxyFor(Exit)
350+
win, winerr := h.pxr.mainRpnProxyOf(RpnWin)
351+
352+
previdx, recent := h.exp.Get(local)
353+
354+
l, who, err := core.Race(
355+
network+".accept-auto."+local,
356+
tlsHandshakeTimeout,
357+
func(ctx context.Context) (protect.Listener, error) {
358+
const myidx = 0
359+
if exit == nil {
360+
return nil, exerr
361+
}
362+
if remoteOnly {
363+
return nil, errNotRemote
364+
}
365+
if recent {
366+
if previdx != myidx {
367+
return nil, errNotPinned
368+
}
369+
return h.acceptIfHealthy(exit, network, local)
370+
}
371+
return h.acceptIfHealthy(exit, network, local)
372+
}, func(ctx context.Context) (protect.Listener, error) {
373+
const myidx = 1
374+
if win == nil {
375+
return nil, winerr
376+
}
377+
if recent {
378+
if previdx != myidx {
379+
return nil, errNotPinned
380+
}
381+
return h.acceptIfHealthy(win, network, local)
382+
}
383+
// delay if not dialing remote exclusively
384+
if !remoteOnly {
385+
select {
386+
case <-ctx.Done():
387+
return nil, ctx.Err()
388+
case <-time.After(shortdelay * myidx): // 100ms
389+
}
390+
}
391+
return h.acceptIfHealthy(win, network, local)
392+
},
393+
)
345394
defer localDialStatus(h.status, err)
346395

347-
log.I("proxy: auto: accept(%s) on %s; err? %v", network, local, err)
396+
log.I("proxy: auto: w(%d) accept(%s) on %s; err? %v", who, network, local, err)
348397
return l, err
349398
}
350399

351400
// Probe implements Proxy.
352-
func (h *auto) Probe(network, local string) (pc protect.PacketConn, err error) {
401+
func (h *auto) Probe(network, local string) (protect.PacketConn, error) {
353402
if err := candial(h.status); err != nil {
354403
return nil, err
355404
}
356-
if settings.AutoAlwaysRemote() {
357-
log.E("proxy: auto: probe(%s) on %s remote-dial unimplemented", network, local)
358-
return nil, errNoAutoSupport
359-
}
360-
// todo: rpnwg, rpnamz, rpnwin
361-
exit, err := h.pxr.ProxyFor(Exit)
362-
if err == nil {
363-
pc, err = exit.Dialer().Probe(network, local)
364-
}
405+
406+
exit, exerr := h.pxr.ProxyFor(Exit)
407+
win, winerr := h.pxr.mainRpnProxyOf(RpnWin)
408+
409+
previdx, recent := h.exp.Get(local)
410+
411+
pc, who, err := core.Race(
412+
network+".probe-auto."+local,
413+
tlsHandshakeTimeout,
414+
func(ctx context.Context) (protect.PacketConn, error) {
415+
const myidx = 0
416+
if exit == nil {
417+
return nil, exerr
418+
}
419+
if recent {
420+
if previdx != myidx {
421+
return nil, errNotPinned
422+
}
423+
return h.probeIfHealthy(exit, network, local)
424+
}
425+
return h.probeIfHealthy(exit, network, local)
426+
}, func(ctx context.Context) (protect.PacketConn, error) {
427+
const myidx = 1
428+
if win == nil {
429+
return nil, winerr
430+
}
431+
if recent {
432+
if previdx != myidx {
433+
return nil, errNotPinned
434+
}
435+
return h.probeIfHealthy(win, network, local)
436+
}
437+
select {
438+
case <-ctx.Done():
439+
return nil, ctx.Err()
440+
case <-time.After(shortdelay * myidx): // 100ms
441+
}
442+
return h.probeIfHealthy(win, network, local)
443+
},
444+
)
365445
defer localDialStatus(h.status, err)
366446

367-
log.I("proxy: auto: probe(%s) on %s; err? %v", network, local, err)
447+
log.I("proxy: auto: w(%d) probe(%s) on %s; err? %v", who, network, local, err)
368448
return pc, err
369449
}
370450

@@ -495,6 +575,22 @@ func (*auto) announceIfHealthy(p Proxy, network, local string) (net.PacketConn,
495575
return p.Dialer().Announce(network, local)
496576
}
497577

578+
func (*auto) acceptIfHealthy(p Proxy, network, local string) (net.Listener, error) {
579+
if err := healthy(p); err != nil {
580+
log.E("auto accept; %s %s not ok; %v: %s", p.ID(), network, err, local)
581+
time.Sleep(delayForUnhealthyProxies)
582+
}
583+
return p.Dialer().Accept(network, local)
584+
}
585+
586+
func (*auto) probeIfHealthy(p Proxy, network, local string) (net.PacketConn, error) {
587+
if err := healthy(p); err != nil {
588+
log.E("auto probe; %s %s not ok; %v: %s", p.ID(), network, err, local)
589+
time.Sleep(delayForUnhealthyProxies)
590+
}
591+
return p.Dialer().Probe(network, local)
592+
}
593+
498594
func maybeKeepAlive(c net.Conn) (keepingalive bool) {
499595
keepingalive, _ = maybeKeepAlive2(c)
500596
return

0 commit comments

Comments
 (0)