@ -28,7 +28,7 @@ type userspaceEngine struct {
statusCallback StatusCallback
statusCallback StatusCallback
reqCh chan struct { }
reqCh chan struct { }
waitCh chan struct { }
waitCh chan struct { }
tun tap tun . Device
tun dev tun . Device
wgdev * device . Device
wgdev * device . Device
router Router
router Router
magicConn * magicsock . Conn
magicConn * magicsock . Conn
@ -51,13 +51,15 @@ func (l *Loggify) Write(b []byte) (int, error) {
return len ( b ) , nil
return len ( b ) , nil
}
}
func NewFakeUserspaceEngine ( logf logger . Logf , listenPort uint16 , derp bool ) ( Engine , error ) {
func NewFakeUserspaceEngine ( logf logger . Logf , listenPort uint16 ) ( Engine , error ) {
logf ( "Starting userspace wireguard engine (FAKE tuntap device)." )
logf ( "Starting userspace wireguard engine (FAKE tuntap device)." )
tun := NewFakeTun ( )
tun := NewFakeTun ( )
return NewUserspaceEngineAdvanced ( logf , tun , NewFakeRouter , listenPort , derp )
return NewUserspaceEngineAdvanced ( logf , tun , NewFakeRouter , listenPort )
}
}
func NewUserspaceEngine ( logf logger . Logf , tunname string , listenPort uint16 , derp bool ) ( Engine , error ) {
// NewUserspaceEngine creates the named tun device and returns a Tailscale Engine
// running on it.
func NewUserspaceEngine ( logf logger . Logf , tunname string , listenPort uint16 ) ( Engine , error ) {
logf ( "Starting userspace wireguard engine." )
logf ( "Starting userspace wireguard engine." )
logf ( "external packet routing via --tun=%s enabled" , tunname )
logf ( "external packet routing via --tun=%s enabled" , tunname )
@ -65,34 +67,34 @@ func NewUserspaceEngine(logf logger.Logf, tunname string, listenPort uint16, der
return nil , fmt . Errorf ( "--tun name must not be blank" )
return nil , fmt . Errorf ( "--tun name must not be blank" )
}
}
tun tap , err := tun . CreateTUN ( tunname , device . DefaultMTU )
tun dev , err := tun . CreateTUN ( tunname , device . DefaultMTU )
if err != nil {
if err != nil {
logf ( "CreateTUN: %v\n" , err )
logf ( "CreateTUN: %v\n" , err )
return nil , err
return nil , err
}
}
logf ( "CreateTUN ok.\n" )
logf ( "CreateTUN ok.\n" )
e , err := NewUserspaceEngineAdvanced ( logf , tun tap, NewUserspaceRouter , listenPort , derp )
e , err := NewUserspaceEngineAdvanced ( logf , tun dev, newUserspaceRouter , listenPort )
if err != nil {
if err != nil {
logf ( "NewUserspaceEngineAdv: %v\n" , err )
logf ( "NewUserspaceEngineAdv: %v\n" , err )
tundev . Close ( )
return nil , err
return nil , err
}
}
return e , err
return e , err
}
}
type RouterGen func ( logf logger . Logf , tunname string , dev * device . Device , tuntap tun . Device , netStateChanged func ( ) ) Router
// NewUserspaceEngineAdvanced is like NewUserspaceEngine but takes a pre-created TUN device and allows specifing
// a custom router constructor and listening port.
func NewUserspaceEngineAdvanced ( logf logger . Logf , tundev tun . Device , routerGen RouterGen , listenPort uint16 ) ( Engine , error ) {
return newUserspaceEngineAdvanced ( logf , tundev , routerGen , listenPort )
}
func NewUserspaceEngineAdvanced ( logf logger . Logf , tuntap tun . Device , routerGen RouterGen , listenPort uint16 , derp bool ) ( Engine , error ) {
func n ewUserspaceEngineAdvanced( logf logger . Logf , tun dev tun . Device , routerGen RouterGen , listenPort uint16 ) ( _ Engine , reterr error ) {
e := & userspaceEngine {
e := & userspaceEngine {
logf : logf ,
logf : logf ,
reqCh : make ( chan struct { } , 1 ) ,
reqCh : make ( chan struct { } , 1 ) ,
waitCh : make ( chan struct { } ) ,
waitCh : make ( chan struct { } ) ,
tuntap : tuntap ,
tundev : tundev ,
}
tunname , err := tuntap . Name ( )
if err != nil {
return nil , err
}
}
endpointsFn := func ( endpoints [ ] string ) {
endpointsFn := func ( endpoints [ ] string ) {
@ -111,9 +113,7 @@ func NewUserspaceEngineAdvanced(logf logger.Logf, tuntap tun.Device, routerGen R
// TODO(crawshaw): DERP: magicsock.DefaultDERP,
// TODO(crawshaw): DERP: magicsock.DefaultDERP,
EndpointsFunc : endpointsFn ,
EndpointsFunc : endpointsFn ,
}
}
if derp {
var err error
magicsockOpts . DERP = magicsock . DefaultDERP
}
e . magicConn , err = magicsock . Listen ( magicsockOpts )
e . magicConn , err = magicsock . Listen ( magicsockOpts )
if err != nil {
if err != nil {
return nil , fmt . Errorf ( "wgengine: %v" , err )
return nil , fmt . Errorf ( "wgengine: %v" , err )
@ -155,13 +155,23 @@ func NewUserspaceEngineAdvanced(logf logger.Logf, tuntap tun.Device, routerGen R
SkipBindUpdate : true ,
SkipBindUpdate : true ,
}
}
e . wgdev = device . NewDevice ( e . tuntap , opts )
e . wgdev = device . NewDevice ( e . tundev , opts )
defer func ( ) {
if reterr != nil {
e . wgdev . Close ( )
}
} ( )
e . router , err = routerGen ( logf , e . wgdev , e . tundev , func ( ) { e . LinkChange ( false ) } )
if err != nil {
return nil , err
}
go func ( ) {
go func ( ) {
up := false
up := false
for event := range e . tuntap . Events ( ) {
for event := range e . tun dev . Events ( ) {
if event & tun . EventMTUUpdate != 0 {
if event & tun . EventMTUUpdate != 0 {
mtu , err := e . tuntap . MTU ( )
mtu , err := e . tun dev . MTU ( )
e . logf ( "external route MTU: %d (%v)" , mtu , err )
e . logf ( "external route MTU: %d (%v)" , mtu , err )
}
}
if event & tun . EventUp != 0 && ! up {
if event & tun . EventUp != 0 && ! up {
@ -177,7 +187,6 @@ func NewUserspaceEngineAdvanced(logf logger.Logf, tuntap tun.Device, routerGen R
}
}
} ( )
} ( )
e . router = routerGen ( logf , tunname , e . wgdev , e . tuntap , func ( ) { e . LinkChange ( false ) } )
e . wgdev . Up ( )
e . wgdev . Up ( )
if err := e . router . Up ( ) ; err != nil {
if err := e . router . Up ( ) ; err != nil {
e . wgdev . Close ( )
e . wgdev . Close ( )
@ -270,7 +279,7 @@ func (e *userspaceEngine) SetFilter(filt *filter.Filter) {
if filt == nil {
if filt == nil {
e . logf ( "wgengine: nil filter provided; no access restrictions.\n" )
e . logf ( "wgengine: nil filter provided; no access restrictions.\n" )
} else {
} else {
ft , ft_ok := e . tun tap . ( * fakeTun )
ft , ft_ok := e . tun dev . ( * fakeTun )
filtin = func ( b [ ] byte ) device . FilterResult {
filtin = func ( b [ ] byte ) device . FilterResult {
runf := filter . LogDrops
runf := filter . LogDrops
//runf |= filter.HexdumpDrops
//runf |= filter.HexdumpDrops