mirror of
https://github.com/k8snetworkplumbingwg/multus-cni.git
synced 2025-08-28 12:51:01 +00:00
Connection limit for thick daemon.
Signed-off-by: Julius Hinze <juliusmh@proton.me>
This commit is contained in:
parent
00adf22482
commit
adf5818016
@ -29,6 +29,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
"golang.org/x/net/netutil"
|
||||||
utilwait "k8s.io/apimachinery/pkg/util/wait"
|
utilwait "k8s.io/apimachinery/pkg/util/wait"
|
||||||
|
|
||||||
"gopkg.in/k8snetworkplumbingwg/multus-cni.v4/pkg/logging"
|
"gopkg.in/k8snetworkplumbingwg/multus-cni.v4/pkg/logging"
|
||||||
@ -106,7 +107,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := startMultusDaemon(ctx, daemonConf, ignoreReadinessIndicator); err != nil {
|
if err := startMultusDaemon(ctx, daemonConf, ignoreReadinessIndicator, daemonConf.ConnectionLimit); err != nil {
|
||||||
logging.Panicf("failed start the multus thick-plugin listener: %v", err)
|
logging.Panicf("failed start the multus thick-plugin listener: %v", err)
|
||||||
os.Exit(3)
|
os.Exit(3)
|
||||||
}
|
}
|
||||||
@ -140,7 +141,7 @@ func main() {
|
|||||||
logging.Verbosef("multus daemon is exited")
|
logging.Verbosef("multus daemon is exited")
|
||||||
}
|
}
|
||||||
|
|
||||||
func startMultusDaemon(ctx context.Context, daemonConfig *srv.ControllerNetConf, ignoreReadinessIndicator bool) error {
|
func startMultusDaemon(ctx context.Context, daemonConfig *srv.ControllerNetConf, ignoreReadinessIndicator bool, connectionLimit *int) error {
|
||||||
if user, err := user.Current(); err != nil || user.Uid != "0" {
|
if user, err := user.Current(); err != nil || user.Uid != "0" {
|
||||||
return fmt.Errorf("failed to run multus-daemon with root: %v, now running in uid: %s", err, user.Uid)
|
return fmt.Errorf("failed to run multus-daemon with root: %v, now running in uid: %s", err, user.Uid)
|
||||||
}
|
}
|
||||||
@ -167,6 +168,11 @@ func startMultusDaemon(ctx context.Context, daemonConfig *srv.ControllerNetConf,
|
|||||||
return fmt.Errorf("failed to start the CNI server using socket %s. Reason: %+v", api.SocketPath(daemonConfig.SocketDir), err)
|
return fmt.Errorf("failed to start the CNI server using socket %s. Reason: %+v", api.SocketPath(daemonConfig.SocketDir), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if limit := connectionLimit; limit != nil && *limit > 0 {
|
||||||
|
logging.Debugf("connection limit: %d", *limit)
|
||||||
|
l = netutil.LimitListener(l, *limit)
|
||||||
|
}
|
||||||
|
|
||||||
server.Start(ctx, l)
|
server.Start(ctx, l)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
|
@ -77,6 +77,7 @@ type ControllerNetConf struct {
|
|||||||
LogLevel string `json:"logLevel"`
|
LogLevel string `json:"logLevel"`
|
||||||
LogToStderr bool `json:"logToStderr,omitempty"`
|
LogToStderr bool `json:"logToStderr,omitempty"`
|
||||||
PerNodeCertificate *PerNodeCertificate `json:"perNodeCertificate,omitempty"`
|
PerNodeCertificate *PerNodeCertificate `json:"perNodeCertificate,omitempty"`
|
||||||
|
ConnectionLimit *int `json:"connectionLimit,omitempty"`
|
||||||
|
|
||||||
MetricsPort *int `json:"metricsPort,omitempty"`
|
MetricsPort *int `json:"metricsPort,omitempty"`
|
||||||
|
|
||||||
|
87
vendor/golang.org/x/net/netutil/listen.go
generated
vendored
Normal file
87
vendor/golang.org/x/net/netutil/listen.go
generated
vendored
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
// Copyright 2013 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package netutil provides network utility functions, complementing the more
|
||||||
|
// common ones in the net package.
|
||||||
|
package netutil // import "golang.org/x/net/netutil"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
// LimitListener returns a Listener that accepts at most n simultaneous
|
||||||
|
// connections from the provided Listener.
|
||||||
|
func LimitListener(l net.Listener, n int) net.Listener {
|
||||||
|
return &limitListener{
|
||||||
|
Listener: l,
|
||||||
|
sem: make(chan struct{}, n),
|
||||||
|
done: make(chan struct{}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type limitListener struct {
|
||||||
|
net.Listener
|
||||||
|
sem chan struct{}
|
||||||
|
closeOnce sync.Once // ensures the done chan is only closed once
|
||||||
|
done chan struct{} // no values sent; closed when Close is called
|
||||||
|
}
|
||||||
|
|
||||||
|
// acquire acquires the limiting semaphore. Returns true if successfully
|
||||||
|
// acquired, false if the listener is closed and the semaphore is not
|
||||||
|
// acquired.
|
||||||
|
func (l *limitListener) acquire() bool {
|
||||||
|
select {
|
||||||
|
case <-l.done:
|
||||||
|
return false
|
||||||
|
case l.sem <- struct{}{}:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (l *limitListener) release() { <-l.sem }
|
||||||
|
|
||||||
|
func (l *limitListener) Accept() (net.Conn, error) {
|
||||||
|
if !l.acquire() {
|
||||||
|
// If the semaphore isn't acquired because the listener was closed, expect
|
||||||
|
// that this call to accept won't block, but immediately return an error.
|
||||||
|
// If it instead returns a spurious connection (due to a bug in the
|
||||||
|
// Listener, such as https://golang.org/issue/50216), we immediately close
|
||||||
|
// it and try again. Some buggy Listener implementations (like the one in
|
||||||
|
// the aforementioned issue) seem to assume that Accept will be called to
|
||||||
|
// completion, and may otherwise fail to clean up the client end of pending
|
||||||
|
// connections.
|
||||||
|
for {
|
||||||
|
c, err := l.Listener.Accept()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
c.Close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c, err := l.Listener.Accept()
|
||||||
|
if err != nil {
|
||||||
|
l.release()
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &limitListenerConn{Conn: c, release: l.release}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *limitListener) Close() error {
|
||||||
|
err := l.Listener.Close()
|
||||||
|
l.closeOnce.Do(func() { close(l.done) })
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type limitListenerConn struct {
|
||||||
|
net.Conn
|
||||||
|
releaseOnce sync.Once
|
||||||
|
release func()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *limitListenerConn) Close() error {
|
||||||
|
err := l.Conn.Close()
|
||||||
|
l.releaseOnce.Do(l.release)
|
||||||
|
return err
|
||||||
|
}
|
1
vendor/modules.txt
vendored
1
vendor/modules.txt
vendored
@ -213,6 +213,7 @@ golang.org/x/net/http2/hpack
|
|||||||
golang.org/x/net/idna
|
golang.org/x/net/idna
|
||||||
golang.org/x/net/internal/httpcommon
|
golang.org/x/net/internal/httpcommon
|
||||||
golang.org/x/net/internal/timeseries
|
golang.org/x/net/internal/timeseries
|
||||||
|
golang.org/x/net/netutil
|
||||||
golang.org/x/net/trace
|
golang.org/x/net/trace
|
||||||
# golang.org/x/oauth2 v0.28.0
|
# golang.org/x/oauth2 v0.28.0
|
||||||
## explicit; go 1.23.0
|
## explicit; go 1.23.0
|
||||||
|
Loading…
Reference in New Issue
Block a user