Skip to content

Commit 24b6a19

Browse files
committed
Filter unusable network interfaces
1 parent 84b8d1e commit 24b6a19

File tree

3 files changed

+135
-59
lines changed

3 files changed

+135
-59
lines changed

pkg/sslnet/interfaces.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package sslnet
2+
3+
import (
4+
"log"
5+
"net"
6+
)
7+
8+
func interfaces(skipInterfaces []string) (interfaces []net.Interface) {
9+
interfaces = []net.Interface{}
10+
ifis, err := net.Interfaces()
11+
if err != nil {
12+
log.Println("Could not get available interfaces: ", err)
13+
}
14+
for _, ifi := range ifis {
15+
if skipInterface(ifi, skipInterfaces) {
16+
continue
17+
}
18+
interfaces = append(interfaces, ifi)
19+
}
20+
return
21+
}
22+
23+
func hasIpv4Net(ifi net.Interface) bool {
24+
addrs, err := ifi.Addrs()
25+
if err != nil {
26+
log.Printf("Could not get addresses for interface %v: %v", ifi.Name, err)
27+
return false
28+
}
29+
30+
for _, addr := range addrs {
31+
if ipNet, ok := addr.(*net.IPNet); ok {
32+
ip := ipNet.IP
33+
if ip.To4() != nil {
34+
return true
35+
}
36+
}
37+
}
38+
39+
return false
40+
}
41+
42+
func skipInterface(ifi net.Interface, skipInterfaces []string) bool {
43+
for _, skipIfi := range skipInterfaces {
44+
if skipIfi == ifi.Name {
45+
return true
46+
}
47+
}
48+
49+
if ifi.Flags&net.FlagMulticast == 0 ||
50+
ifi.Flags&net.FlagUp == 0 {
51+
return true
52+
}
53+
54+
if !hasIpv4Net(ifi) {
55+
return true
56+
}
57+
58+
return false
59+
}

pkg/sslnet/multicast_server.go

Lines changed: 46 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,23 @@ type MulticastServer struct {
2222
func NewMulticastServer(multicastAddress string) (r *MulticastServer) {
2323
r = new(MulticastServer)
2424
r.multicastAddress = multicastAddress
25-
r.Consumer = func([]byte, *net.UDPAddr) {}
25+
r.Consumer = func([]byte, *net.UDPAddr) {
26+
// noop by default
27+
}
2628
return
2729
}
2830

2931
func (r *MulticastServer) Start() {
3032
r.running = true
31-
go r.receive(r.multicastAddress)
33+
34+
ifis := interfaces(r.SkipInterfaces)
35+
var ifiNames []string
36+
for _, ifi := range ifis {
37+
ifiNames = append(ifiNames, ifi.Name)
38+
}
39+
log.Printf("Listening on %s %s", r.multicastAddress, ifiNames)
40+
41+
go r.receive()
3242
}
3343

3444
func (r *MulticastServer) Stop() {
@@ -40,14 +50,13 @@ func (r *MulticastServer) Stop() {
4050
}
4151
}
4252

43-
func (r *MulticastServer) receive(multicastAddress string) {
44-
log.Printf("Receiving multicast traffic on %v", multicastAddress)
53+
func (r *MulticastServer) receive() {
4554
var currentIfiIdx = 0
4655
for r.isRunning() {
47-
ifis := r.interfaces()
56+
ifis := interfaces(r.SkipInterfaces)
4857
currentIfiIdx = currentIfiIdx % len(ifis)
4958
ifi := ifis[currentIfiIdx]
50-
r.receiveOnInterface(multicastAddress, ifi)
59+
r.receiveOnInterface(ifi)
5160
currentIfiIdx++
5261
if currentIfiIdx >= len(ifis) {
5362
// cycled though all interfaces once, make a short break to avoid producing endless log messages
@@ -62,51 +71,37 @@ func (r *MulticastServer) isRunning() bool {
6271
return r.running
6372
}
6473

65-
func (r *MulticastServer) interfaces() (interfaces []net.Interface) {
66-
interfaces = []net.Interface{}
67-
ifis, err := net.Interfaces()
68-
if err != nil {
69-
log.Println("Could not get available interfaces: ", err)
70-
}
71-
for _, ifi := range ifis {
72-
if ifi.Flags&net.FlagMulticast == 0 || // No multicast support
73-
r.skipInterface(ifi.Name) {
74-
continue
75-
}
76-
interfaces = append(interfaces, ifi)
77-
}
78-
return
79-
}
80-
81-
func (r *MulticastServer) skipInterface(ifiName string) bool {
82-
for _, skipIfi := range r.SkipInterfaces {
83-
if skipIfi == ifiName {
84-
return true
85-
}
86-
}
87-
return false
88-
}
89-
90-
func (r *MulticastServer) receiveOnInterface(multicastAddress string, ifi net.Interface) {
91-
addr, err := net.ResolveUDPAddr("udp", multicastAddress)
74+
func (r *MulticastServer) connectToInterface(ifi net.Interface) bool {
75+
addr, err := net.ResolveUDPAddr("udp", r.multicastAddress)
9276
if err != nil {
93-
log.Printf("Could resolve multicast address %v: %v", multicastAddress, err)
94-
return
77+
log.Printf("Could resolve multicast address %v: %v", r.multicastAddress, err)
78+
return false
9579
}
9680

9781
r.connection, err = net.ListenMulticastUDP("udp", &ifi, addr)
9882
if err != nil {
99-
log.Printf("Could not listen at %v: %v", multicastAddress, err)
100-
return
83+
log.Printf("Could not listen at %v on %v: %v", r.multicastAddress, ifi.Name, err)
84+
return false
10185
}
10286

10387
if err := r.connection.SetReadBuffer(maxDatagramSize); err != nil {
10488
log.Println("Could not set read buffer: ", err)
10589
}
10690

10791
if r.Verbose {
108-
log.Printf("Listening on %s (%s)", multicastAddress, ifi.Name)
109-
defer log.Printf("Stop listening on %s (%s)", multicastAddress, ifi.Name)
92+
log.Printf("Listening on %s (%s)", r.multicastAddress, ifi.Name)
93+
}
94+
95+
return true
96+
}
97+
98+
func (r *MulticastServer) receiveOnInterface(ifi net.Interface) {
99+
if !r.connectToInterface(ifi) {
100+
return
101+
}
102+
103+
if r.Verbose {
104+
defer log.Printf("Stop listening on %s (%s)", r.multicastAddress, ifi.Name)
110105
}
111106

112107
first := true
@@ -120,14 +115,23 @@ func (r *MulticastServer) receiveOnInterface(multicastAddress string, ifi net.In
120115
if r.Verbose {
121116
log.Println("ReadFromUDP failed:", err)
122117
}
123-
return
118+
break
124119
}
125120

126-
if first {
127-
log.Printf("Got first data packets from %s (%s)", multicastAddress, ifi.Name)
121+
if first && r.Verbose {
122+
log.Printf("Got first data packets from %s (%s)", r.multicastAddress, ifi.Name)
128123
first = false
129124
}
130125

131126
r.Consumer(data[:n], remoteAddr)
132127
}
128+
129+
if r.Verbose {
130+
log.Printf("Stop listening on %s (%s)", r.multicastAddress, ifi.Name)
131+
}
132+
133+
if err := r.connection.Close(); err != nil {
134+
log.Println("Could not close listener: ", err)
135+
}
136+
return
133137
}

pkg/sslnet/udp_client.go

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package sslnet
22

33
import (
4+
"errors"
45
"log"
56
"net"
67
"sync"
@@ -24,7 +25,9 @@ func NewUdpClient(address string, nif string) (t *UdpClient) {
2425
t.Name = "UdpClient"
2526
t.address = address
2627
t.nif = nif
27-
t.Consumer = func([]byte) {}
28+
t.Consumer = func([]byte) {
29+
// noop by default
30+
}
2831
return
2932
}
3033

@@ -69,6 +72,28 @@ func (c *UdpClient) Send(data []byte) {
6972
}
7073
}
7174

75+
func (c *UdpClient) interfaceAddresses() (addrs []*net.UDPAddr) {
76+
ifis := interfaces([]string{})
77+
78+
for _, ifi := range ifis {
79+
iaddrs, err := ifi.Addrs()
80+
if err != nil {
81+
log.Printf("%v - Could not retrieve interface addresses: %v", c.Name, err)
82+
return
83+
}
84+
85+
for _, iaddr := range iaddrs {
86+
ip := iaddr.(*net.IPNet).IP
87+
if c.nif != "" && ip.String() != c.nif {
88+
continue
89+
}
90+
laddr := &net.UDPAddr{IP: ip}
91+
addrs = append(addrs, laddr)
92+
}
93+
}
94+
return
95+
}
96+
7297
func (c *UdpClient) connect() {
7398
log.Printf("%v - Connecting to %v", c.Name, c.address)
7499
addr, err := net.ResolveUDPAddr("udp", c.address)
@@ -77,22 +102,9 @@ func (c *UdpClient) connect() {
77102
return
78103
}
79104

80-
iaddrs, err := net.InterfaceAddrs()
81-
if err != nil {
82-
log.Printf("%v - Could not retrieve interface addresses: %v", c.Name, err)
83-
return
84-
}
105+
addrs := c.interfaceAddresses()
85106

86-
for _, iaddr := range iaddrs {
87-
ip := iaddr.(*net.IPNet).IP
88-
if ip.To4() == nil {
89-
// Ignore IPv6 for now
90-
continue
91-
}
92-
if c.nif != "" && ip.String() != c.nif {
93-
continue
94-
}
95-
laddr := &net.UDPAddr{IP: ip}
107+
for _, laddr := range addrs {
96108
conn, err := net.DialUDP("udp", laddr, addr)
97109
if err != nil {
98110
log.Printf("%v - Could not connect to %v at %v: %v", c.Name, addr, laddr, err)
@@ -119,7 +131,8 @@ func (c *UdpClient) receive(conn *net.UDPConn) {
119131
for {
120132
n, _, err := conn.ReadFrom(data)
121133
if err != nil {
122-
if opErr, ok := err.(*net.OpError); !ok || opErr.Err.Error() != "use of closed network connection" {
134+
var opErr *net.OpError
135+
if !errors.As(err, &opErr) || opErr.Err.Error() != "use of closed network connection" {
123136
log.Printf("%v - Could not receive data from %s at %s: %s", c.Name, conn.RemoteAddr(), conn.LocalAddr(), err)
124137
}
125138
return

0 commit comments

Comments
 (0)