diff --git a/pkg/sentry/socket/hostinet/stack.go b/pkg/sentry/socket/hostinet/stack.go index 44c3b9a3f..f64809d39 100644 --- a/pkg/sentry/socket/hostinet/stack.go +++ b/pkg/sentry/socket/hostinet/stack.go @@ -84,11 +84,13 @@ func (s *Stack) Configure() error { log.Warningf("Failed to read TCP send buffer size, using default values") } - s.tcpSACKEnabled = false + // SACK is important for performance and even compatibility, assume it's + // enabled if we can't find the actual value. + s.tcpSACKEnabled = true if sack, err := ioutil.ReadFile("/proc/sys/net/ipv4/tcp_sack"); err == nil { s.tcpSACKEnabled = strings.TrimSpace(string(sack)) != "0" } else { - log.Warningf("Failed to read if TCP SACK if enabled, setting to false") + log.Warningf("Failed to read if TCP SACK if enabled, setting to true") } return nil diff --git a/runsc/boot/controller.go b/runsc/boot/controller.go index c6e934e66..fc6ea326a 100644 --- a/runsc/boot/controller.go +++ b/runsc/boot/controller.go @@ -285,7 +285,10 @@ func (cm *containerManager) Restore(o *RestoreOpts, _ *struct{}) error { fs.SetRestoreEnvironment(*renv) // Prepare to load from the state file. - networkStack := newEmptyNetworkStack(cm.l.conf, k) + networkStack, err := newEmptyNetworkStack(cm.l.conf, k) + if err != nil { + return fmt.Errorf("failed to create network: %v", err) + } info, err := o.FilePayload.Files[0].Stat() if err != nil { return err diff --git a/runsc/boot/loader.go b/runsc/boot/loader.go index 2f976cd52..f6c7bf223 100644 --- a/runsc/boot/loader.go +++ b/runsc/boot/loader.go @@ -174,7 +174,10 @@ func New(spec *specs.Spec, conf *Config, controllerFD int, ioFDs []int, console // this point. Netns is configured before Run() is called. Netstack is // configured using a control uRPC message. Host network is configured inside // Run(). - networkStack := newEmptyNetworkStack(conf, k) + networkStack, err := newEmptyNetworkStack(conf, k) + if err != nil { + return nil, fmt.Errorf("failed to create network: %v", err) + } // Initiate the Kernel object, which is required by the Context passed // to createVFS in order to mount (among other things) procfs. @@ -525,16 +528,20 @@ func (l *Loader) WaitExit() kernel.ExitStatus { return l.k.GlobalInit().ExitStatus() } -func newEmptyNetworkStack(conf *Config, clock tcpip.Clock) inet.Stack { +func newEmptyNetworkStack(conf *Config, clock tcpip.Clock) (inet.Stack, error) { switch conf.Network { case NetworkHost: - return hostinet.NewStack() + return hostinet.NewStack(), nil case NetworkNone, NetworkSandbox: // NetworkNone sets up loopback using netstack. netProtos := []string{ipv4.ProtocolName, ipv6.ProtocolName, arp.ProtocolName} protoNames := []string{tcp.ProtocolName, udp.ProtocolName, ping.ProtocolName4} - return &epsocket.Stack{stack.New(netProtos, protoNames, stack.Options{Clock: clock})} + s := &epsocket.Stack{stack.New(netProtos, protoNames, stack.Options{Clock: clock})} + if err := s.Stack.SetTransportProtocolOption(tcp.ProtocolNumber, tcp.SACKEnabled(true)); err != nil { + return nil, fmt.Errorf("failed to enable SACK: %v", err) + } + return s, nil default: panic(fmt.Sprintf("invalid network configuration: %v", conf.Network))