mirror of https://github.com/vishvananda/netlink
Allow setting socket timeout on Handle
Signed-off-by: Alessandro Boch <aboch@docker.com>
This commit is contained in:
parent
ffec63e1f1
commit
17ea11b5a1
|
@ -1,7 +1,9 @@
|
||||||
package netlink
|
package netlink
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/vishvananda/netlink/nl"
|
"github.com/vishvananda/netlink/nl"
|
||||||
"github.com/vishvananda/netns"
|
"github.com/vishvananda/netns"
|
||||||
|
@ -33,6 +35,29 @@ func NewHandle(nlFamilies ...int) (*Handle, error) {
|
||||||
return newHandle(netns.None(), netns.None(), nlFamilies...)
|
return newHandle(netns.None(), netns.None(), nlFamilies...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetSocketTimeout sets the send and receive timeout for each socket in the
|
||||||
|
// netlink handle. Although the socket timeout has granularity of one
|
||||||
|
// microsecond, the effective granularity is floored by the kernel timer tick,
|
||||||
|
// which default value is four milliseconds.
|
||||||
|
func (h *Handle) SetSocketTimeout(to time.Duration) error {
|
||||||
|
if to < time.Microsecond {
|
||||||
|
return fmt.Errorf("invalid timeout, minimul value is %s", time.Microsecond)
|
||||||
|
}
|
||||||
|
tv := syscall.NsecToTimeval(to.Nanoseconds())
|
||||||
|
for _, sh := range h.sockets {
|
||||||
|
fd := sh.Socket.GetFd()
|
||||||
|
err := syscall.SetsockoptTimeval(fd, syscall.SOL_SOCKET, syscall.SO_RCVTIMEO, &tv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = syscall.SetsockoptTimeval(fd, syscall.SOL_SOCKET, syscall.SO_SNDTIMEO, &tv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// NewHandle returns a netlink handle on the network namespace
|
// NewHandle returns a netlink handle on the network namespace
|
||||||
// specified by ns. If ns=netns.None(), current network namespace
|
// specified by ns. If ns=netns.None(), current network namespace
|
||||||
// will be assumed
|
// will be assumed
|
||||||
|
|
|
@ -8,7 +8,10 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
"github.com/vishvananda/netlink/nl"
|
"github.com/vishvananda/netlink/nl"
|
||||||
"github.com/vishvananda/netns"
|
"github.com/vishvananda/netns"
|
||||||
|
@ -107,6 +110,48 @@ func TestHandleCreateNetns(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestHandleTimeout(t *testing.T) {
|
||||||
|
h, err := NewHandle()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer h.Delete()
|
||||||
|
|
||||||
|
for _, sh := range h.sockets {
|
||||||
|
verifySockTimeVal(t, sh.Socket.GetFd(), syscall.Timeval{Sec: 0, Usec: 0})
|
||||||
|
}
|
||||||
|
|
||||||
|
h.SetSocketTimeout(2*time.Second + 8*time.Millisecond)
|
||||||
|
|
||||||
|
for _, sh := range h.sockets {
|
||||||
|
verifySockTimeVal(t, sh.Socket.GetFd(), syscall.Timeval{Sec: 2, Usec: 8000})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func verifySockTimeVal(t *testing.T, fd int, tv syscall.Timeval) {
|
||||||
|
var (
|
||||||
|
tr syscall.Timeval
|
||||||
|
v = uint32(0x10)
|
||||||
|
)
|
||||||
|
_, _, errno := syscall.Syscall6(syscall.SYS_GETSOCKOPT, uintptr(fd), syscall.SOL_SOCKET, syscall.SO_SNDTIMEO, uintptr(unsafe.Pointer(&tr)), uintptr(unsafe.Pointer(&v)), 0)
|
||||||
|
if errno != 0 {
|
||||||
|
t.Fatal(errno)
|
||||||
|
}
|
||||||
|
|
||||||
|
if tr.Sec != tv.Sec || tr.Usec != tv.Usec {
|
||||||
|
t.Fatalf("Unexpected timeout value read: %v. Expected: %v", tr, tv)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _, errno = syscall.Syscall6(syscall.SYS_GETSOCKOPT, uintptr(fd), syscall.SOL_SOCKET, syscall.SO_RCVTIMEO, uintptr(unsafe.Pointer(&tr)), uintptr(unsafe.Pointer(&v)), 0)
|
||||||
|
if errno != 0 {
|
||||||
|
t.Fatal(errno)
|
||||||
|
}
|
||||||
|
|
||||||
|
if tr.Sec != tv.Sec || tr.Usec != tv.Usec {
|
||||||
|
t.Fatalf("Unexpected timeout value read: %v. Expected: %v", tr, tv)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
iter = 10
|
iter = 10
|
||||||
numThread = uint32(4)
|
numThread = uint32(4)
|
||||||
|
|
Loading…
Reference in New Issue