@@ -3,6 +3,7 @@ package sslnet
3
3
import (
4
4
"log"
5
5
"net"
6
+ "net/netip"
6
7
"sync"
7
8
"time"
8
9
)
@@ -40,11 +41,20 @@ func (r *MulticastServer) Stop() {
40
41
41
42
func (r * MulticastServer ) receive (multicastAddress string ) {
42
43
var currentIfiIdx = 0
44
+ var badIfis []string
43
45
for r .isRunning () {
44
- ifis := r .interfaces ()
46
+ ifis := r .interfaces (badIfis )
47
+ if len (ifis ) == 0 {
48
+ log .Println ("No valid interfaces found to listen on" )
49
+ return
50
+ }
45
51
currentIfiIdx = currentIfiIdx % len (ifis )
46
52
ifi := ifis [currentIfiIdx ]
47
- r .receiveOnInterface (multicastAddress , ifi )
53
+ badIfi := r .receiveOnInterface (multicastAddress , ifi )
54
+ if badIfi {
55
+ badIfis = append (badIfis , ifi .Name )
56
+ }
57
+
48
58
currentIfiIdx ++
49
59
if currentIfiIdx >= len (ifis ) {
50
60
// cycled though all interfaces once, make a short break to avoid producing endless log messages
@@ -59,41 +69,65 @@ func (r *MulticastServer) isRunning() bool {
59
69
return r .running
60
70
}
61
71
62
- func (r * MulticastServer ) interfaces () (interfaces []net.Interface ) {
72
+ func (r * MulticastServer ) interfaces (ignoreIfis [] string ) (interfaces []net.Interface ) {
63
73
interfaces = []net.Interface {}
64
74
ifis , err := net .Interfaces ()
65
75
if err != nil {
66
76
log .Println ("Could not get available interfaces: " , err )
67
77
}
68
78
for _ , ifi := range ifis {
69
79
if ifi .Flags & net .FlagMulticast == 0 || // No multicast support
70
- r .skipInterface (ifi .Name ) {
80
+ ifi .Flags & net .FlagUp == 0 || // Not up
81
+ ifi .Flags & net .FlagRunning == 0 || // Not running
82
+ r .skipInterface (r .SkipInterfaces , ifi .Name ) ||
83
+ r .skipInterface (ignoreIfis , ifi .Name ) ||
84
+ isInvalidInterface (& ifi ) {
71
85
continue
72
86
}
73
87
interfaces = append (interfaces , ifi )
74
88
}
75
89
return
76
90
}
77
91
78
- func (r * MulticastServer ) skipInterface (ifiName string ) bool {
79
- for _ , skipIfi := range r .SkipInterfaces {
92
+ func isInvalidInterface (ifi * net.Interface ) bool {
93
+ addrs , err := ifi .Addrs ()
94
+ if err != nil {
95
+ log .Printf ("Could not get addresses of interface %v: %v" , ifi , err )
96
+ return false
97
+ }
98
+ for _ , addr := range addrs {
99
+ ipNet := addr .(* net.IPNet )
100
+ ip := netip .MustParseAddr (ipNet .IP .String ())
101
+ if ip .Is4 () {
102
+ return false
103
+ }
104
+ }
105
+ return true
106
+ }
107
+
108
+ func (r * MulticastServer ) skipInterface (ifis []string , ifiName string ) bool {
109
+ for _ , skipIfi := range ifis {
80
110
if skipIfi == ifiName {
81
111
return true
82
112
}
83
113
}
84
114
return false
85
115
}
86
116
87
- func (r * MulticastServer ) receiveOnInterface (multicastAddress string , ifi net.Interface ) {
117
+ func (r * MulticastServer ) receiveOnInterface (multicastAddress string , ifi net.Interface ) (badIfi bool ) {
118
+ badIfi = false
119
+
88
120
addr , err := net .ResolveUDPAddr ("udp" , multicastAddress )
89
121
if err != nil {
90
122
log .Printf ("Could resolve multicast address %v: %v" , multicastAddress , err )
123
+ badIfi = true
91
124
return
92
125
}
93
126
94
127
r .connection , err = net .ListenMulticastUDP ("udp" , & ifi , addr )
95
128
if err != nil {
96
- log .Printf ("Could not listen at %v: %v" , multicastAddress , err )
129
+ log .Printf ("Could not listen at %v (%v): %v" , multicastAddress , ifi .Name , err )
130
+ badIfi = true
97
131
return
98
132
}
99
133
@@ -109,6 +143,7 @@ func (r *MulticastServer) receiveOnInterface(multicastAddress string, ifi net.In
109
143
data := make ([]byte , maxDatagramSize )
110
144
for {
111
145
if err := r .connection .SetDeadline (time .Now ().Add (300 * time .Millisecond )); err != nil {
146
+ badIfi = true
112
147
log .Println ("Could not set deadline on connection: " , err )
113
148
}
114
149
n , _ , err := r .connection .ReadFromUDP (data )
@@ -132,6 +167,7 @@ func (r *MulticastServer) receiveOnInterface(multicastAddress string, ifi net.In
132
167
}
133
168
134
169
if err := r .connection .Close (); err != nil {
170
+ badIfi = true
135
171
log .Println ("Could not close listener: " , err )
136
172
}
137
173
return
0 commit comments