NewUserspaceEngine creates the named tun device and returns a Tailscale Engine running on it.
(logf logger.Logf, conf Config)
| 319 | // NewUserspaceEngine creates the named tun device and returns a |
| 320 | // Tailscale Engine running on it. |
| 321 | func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error) { |
| 322 | var closePool closeOnErrorPool |
| 323 | defer closePool.closeAllIfError(&reterr) |
| 324 | |
| 325 | if testenv.InTest() && conf.HealthTracker == nil { |
| 326 | panic("NewUserspaceEngine called without HealthTracker (being strict in tests)") |
| 327 | } |
| 328 | |
| 329 | if conf.Metrics == nil { |
| 330 | return nil, errors.New("NewUserspaceEngine: opts.Metrics is required, please pass a *usermetric.Registry") |
| 331 | } |
| 332 | |
| 333 | if conf.Tun == nil { |
| 334 | logf("[v1] using fake (no-op) tun device") |
| 335 | conf.Tun = tstun.NewFake() |
| 336 | } |
| 337 | if conf.Router == nil { |
| 338 | logf("[v1] using fake (no-op) OS network configurator") |
| 339 | conf.Router = router.NewFake(logf) |
| 340 | } |
| 341 | if conf.DNS == nil { |
| 342 | logf("[v1] using fake (no-op) DNS configurator") |
| 343 | d, err := dns.NewNoopManager() |
| 344 | if err != nil { |
| 345 | return nil, err |
| 346 | } |
| 347 | conf.DNS = d |
| 348 | } |
| 349 | if conf.Dialer == nil { |
| 350 | conf.Dialer = &tsdial.Dialer{Logf: logf} |
| 351 | if conf.EventBus != nil { |
| 352 | conf.Dialer.SetBus(conf.EventBus) |
| 353 | } |
| 354 | } |
| 355 | |
| 356 | var tsTUNDev *tstun.Wrapper |
| 357 | if conf.IsTAP { |
| 358 | tsTUNDev = tstun.WrapTAP(logf, conf.Tun, conf.Metrics, conf.EventBus) |
| 359 | } else { |
| 360 | tsTUNDev = tstun.Wrap(logf, conf.Tun, conf.Metrics, conf.EventBus) |
| 361 | } |
| 362 | closePool.add(tsTUNDev) |
| 363 | |
| 364 | rtr := conf.Router |
| 365 | if version.IsMobile() { |
| 366 | // Android and iOS don't handle large numbers of routes well, so we |
| 367 | // wrap the Router with one that consolidates routes down to the |
| 368 | // smallest number possible. |
| 369 | // |
| 370 | // On Android, too many routes at VPN configuration time result in an |
| 371 | // android.os.TransactionTooLargeException because Android's VPNBuilder |
| 372 | // tries to send the entire set of routes to the VPNService as a single |
| 373 | // Bundle, which is typically limited to 1 MB. The number of routes |
| 374 | // that's too much seems to be very roughly around 4000. |
| 375 | // |
| 376 | // On iOS, the VPNExtension is limited to only 50 MB of memory, so |
| 377 | // keeping the number of routes down helps with memory consumption. |
| 378 | rtr = router.ConsolidatingRoutes(logf, rtr) |
searching dependent graphs…