package iroh
import (
"time"
"github.com/tmc/go-iroh/internal/socket"
"github.com/tmc/go-iroh/key"
"github.com/tmc/go-iroh/netaddr"
)
type PathCandidate struct {
Addr netaddr .TransportAddr
RTT time .Duration
}
type PathSelector interface {
Select (current netaddr .TransportAddr , candidates []PathCandidate ) (selected netaddr .TransportAddr , ok bool )
}
type BiasedRttPathSelector struct {}
var _ PathSelector = BiasedRttPathSelector {}
func (BiasedRttPathSelector ) Select (current netaddr .TransportAddr , candidates []PathCandidate ) (netaddr .TransportAddr , bool ) {
scandidates := make ([]socket .PathCandidate , 0 , len (candidates ))
for _ , c := range candidates {
addr , ok := socketAddrFromTransportAddr (c .Addr )
if !ok {
continue
}
scandidates = append (scandidates , socket .PathCandidate {Addr : addr , RTT : c .RTT })
}
var scurrent *socket .Addr
if current != nil {
if addr , ok := socketAddrFromTransportAddr (current ); ok {
scurrent = &addr
}
}
selected , ok := socket .BiasedRttPathSelector {}.Select (scurrent , scandidates )
if !ok {
return nil , false
}
addr , _ := transportAddrFromSocket (selected )
if addr == nil {
return nil , false
}
return addr , true
}
type pathSelectorAdapter struct {
selector PathSelector
}
func (a pathSelectorAdapter ) Select (current *socket .Addr , candidates []socket .PathCandidate ) (socket .Addr , bool ) {
publicCandidates := make ([]PathCandidate , 0 , len (candidates ))
socketCandidates := make ([]socket .Addr , 0 , len (candidates ))
for _ , c := range candidates {
addr , _ := transportAddrFromSocket (c .Addr )
if addr == nil {
continue
}
publicCandidates = append (publicCandidates , PathCandidate {Addr : addr , RTT : c .RTT })
socketCandidates = append (socketCandidates , c .Addr )
}
var publicCurrent netaddr .TransportAddr
if current != nil {
publicCurrent , _ = transportAddrFromSocket (*current )
}
selected , ok := a .selector .Select (publicCurrent , publicCandidates )
if !ok || selected == nil {
return socket .Addr {}, false
}
for i , c := range publicCandidates {
if c .Addr .Compare (selected ) == 0 {
return socketCandidates [i ], true
}
}
return socket .Addr {}, false
}
func socketAddrFromTransportAddr(addr netaddr .TransportAddr ) (socket .Addr , bool ) {
switch a := addr .(type ) {
case netaddr .IPAddr :
return socket .IPAddr (a .Addr ), true
case netaddr .RelayAddr :
return socket .RelayAddr (a .URL , key .EndpointID {}), true
case netaddr .CustomAddr :
return socket .CustomAddr (a ), true
default :
return socket .Addr {}, false
}
}
The pages are generated with Golds v0.8.4 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .