-
Notifications
You must be signed in to change notification settings - Fork 18.5k
Open
Description
Background
Sometimes we need to dial inside another net namespace and switch back. On linux, namespace is thread-level, so a thread lock is needed.
With "github.com/vishvananda/netns" for example:
func connect(target string, network, addr string) net.Conn {
dialer := &net.Dialer{}
runtime.LockOSThread()
defer runtime.UnlockOSThread()
origNS, _ := netns.Get()
targetNS, _ := netns.GetFromName(target)
netns.Set(targetNS)
defer netns.Set(origNS)
conn, _ := dialer.Dial(network, addr)
return conn
}However, this blocks the current thread until Dial() returns. A workaround may be moving the unlocking stuff into dialer.Control:
dialer.Control = func(network, address string, c syscall.RawConn) error {
netns.Set(origNS)
runtime.UnlockOSThread()
return nil
}This doesn't work well because dialParallel() dials in new goroutines which are out of control.
Proposal
Add callback before and after the connection (socket) is created in net.Dialer:
type Dialer struct {
PreControl func(network, address string) error
PostControl func(network, address string) error
}The call of PreControl - PostControl pair should be in the same goroutine and surround the socket syscall. PostControl should be called regardless of whether the conn is successfully created.
Similar thing can be done with net.ListenConfig.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
Incoming