diff options
author | Josh Bleecher Snyder <josharian@gmail.com> | 2021-03-31 13:55:18 -0700 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2021-04-02 11:07:08 -0600 |
commit | 10533c3e73cdb6f4c4f19e01464782b69ace739e (patch) | |
tree | c19f5ce9c6785b22e72afec19d2a73a0d818e0c6 /conn/bind_windows.go | |
parent | 8ed83e0427a693db6d909897dc73bf7ce6e22b21 (diff) | |
download | wireguard-go-10533c3e73cdb6f4c4f19e01464782b69ace739e.tar.gz wireguard-go-10533c3e73cdb6f4c4f19e01464782b69ace739e.zip |
all: make conn.Bind.Open return a slice of receive functions
Instead of hard-coding exactly two sources from which
to receive packets (an IPv4 source and an IPv6 source),
allow the conn.Bind to specify a set of sources.
Beneficial consequences:
* If there's no IPv6 support on a system,
conn.Bind.Open can choose not to return a receive function for it,
which is simpler than tracking that state in the bind.
This simplification removes existing data races from both
conn.StdNetBind and bindtest.ChannelBind.
* If there are more than two sources on a system,
the conn.Bind no longer needs to add a separate muxing layer.
Signed-off-by: Josh Bleecher Snyder <josharian@gmail.com>
Diffstat (limited to 'conn/bind_windows.go')
-rw-r--r-- | conn/bind_windows.go | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/conn/bind_windows.go b/conn/bind_windows.go index 1e2712e..6cabee1 100644 --- a/conn/bind_windows.go +++ b/conn/bind_windows.go @@ -266,7 +266,7 @@ func (bind *afWinRingBind) Open(family int32, sa windows.Sockaddr) (windows.Sock return sa, nil } -func (bind *WinRingBind) Open(port uint16) (selectedPort uint16, err error) { +func (bind *WinRingBind) Open(port uint16) (recvFns []ReceiveFunc, selectedPort uint16, err error) { bind.mu.Lock() defer bind.mu.Unlock() defer func() { @@ -275,30 +275,30 @@ func (bind *WinRingBind) Open(port uint16) (selectedPort uint16, err error) { } }() if atomic.LoadUint32(&bind.isOpen) != 0 { - return 0, ErrBindAlreadyOpen + return nil, 0, ErrBindAlreadyOpen } var sa windows.Sockaddr sa, err = bind.v4.Open(windows.AF_INET, &windows.SockaddrInet4{Port: int(port)}) if err != nil { - return 0, err + return nil, 0, err } sa, err = bind.v6.Open(windows.AF_INET6, &windows.SockaddrInet6{Port: sa.(*windows.SockaddrInet4).Port}) if err != nil { - return 0, err + return nil, 0, err } selectedPort = uint16(sa.(*windows.SockaddrInet6).Port) for i := 0; i < packetsPerRing; i++ { err = bind.v4.InsertReceiveRequest() if err != nil { - return 0, err + return nil, 0, err } err = bind.v6.InsertReceiveRequest() if err != nil { - return 0, err + return nil, 0, err } } atomic.StoreUint32(&bind.isOpen, 1) - return + return []ReceiveFunc{bind.receiveIPv4, bind.receiveIPv6}, selectedPort, err } func (bind *WinRingBind) Close() error { @@ -395,13 +395,13 @@ func (bind *afWinRingBind) Receive(buf []byte, isOpen *uint32) (int, Endpoint, e return n, &ep, nil } -func (bind *WinRingBind) ReceiveIPv4(buf []byte) (int, Endpoint, error) { +func (bind *WinRingBind) receiveIPv4(buf []byte) (int, Endpoint, error) { bind.mu.RLock() defer bind.mu.RUnlock() return bind.v4.Receive(buf, &bind.isOpen) } -func (bind *WinRingBind) ReceiveIPv6(buf []byte) (int, Endpoint, error) { +func (bind *WinRingBind) receiveIPv6(buf []byte) (int, Endpoint, error) { bind.mu.RLock() defer bind.mu.RUnlock() return bind.v6.Receive(buf, &bind.isOpen) @@ -482,6 +482,8 @@ func (bind *WinRingBind) Send(buf []byte, endpoint Endpoint) error { } func (bind *StdNetBind) BindSocketToInterface4(interfaceIndex uint32, blackhole bool) error { + bind.mu.Lock() + defer bind.mu.Unlock() sysconn, err := bind.ipv4.SyscallConn() if err != nil { return err @@ -500,6 +502,8 @@ func (bind *StdNetBind) BindSocketToInterface4(interfaceIndex uint32, blackhole } func (bind *StdNetBind) BindSocketToInterface6(interfaceIndex uint32, blackhole bool) error { + bind.mu.Lock() + defer bind.mu.Unlock() sysconn, err := bind.ipv6.SyscallConn() if err != nil { return err |