Skip to content

Commit 523279e

Browse files
committed
Detect multicast sources from different network interfaces
1 parent 1111c6a commit 523279e

File tree

1 file changed

+61
-22
lines changed

1 file changed

+61
-22
lines changed

cmd/ssl-multicast-sources/main.go

Lines changed: 61 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,66 +4,105 @@ import (
44
"flag"
55
"log"
66
"net"
7-
"time"
7+
"os"
8+
"os/signal"
9+
"sync"
10+
"syscall"
811
)
912

1013
const maxDatagramSize = 8192
1114

12-
var detectedRemotes map[string][]string
15+
type Source struct {
16+
nif string
17+
ip string
18+
port int
19+
}
20+
21+
var detectedRemotes map[string][]Source
22+
var detectedRemotesMutex sync.Mutex
1323

1424
func main() {
1525
flag.Parse()
1626

17-
detectedRemotes = map[string][]string{}
27+
detectedRemotes = map[string][]Source{}
1828
mcAddresses := flag.Args()
1929
if len(mcAddresses) == 0 {
2030
mcAddresses = []string{"224.5.23.1:10003", "224.5.23.2:10006", "224.5.23.2:10010", "224.5.23.2:10012"}
2131
}
2232

33+
ifiList := interfaces()
2334
for _, address := range mcAddresses {
24-
go watchAddress(address)
35+
for _, ifi := range ifiList {
36+
go receiveOnInterface(address, ifi)
37+
}
2538
}
2639

27-
for {
28-
time.Sleep(1 * time.Second)
40+
signals := make(chan os.Signal, 1)
41+
signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM)
42+
<-signals
43+
}
44+
45+
func interfaces() (interfaces []net.Interface) {
46+
interfaces = []net.Interface{}
47+
ifis, err := net.Interfaces()
48+
if err != nil {
49+
log.Println("Could not get available interfaces: ", err)
50+
}
51+
for _, ifi := range ifis {
52+
interfaces = append(interfaces, ifi)
2953
}
54+
return
3055
}
3156

32-
func watchAddress(address string) {
57+
func receiveOnInterface(address string, ifi net.Interface) {
3358
addr, err := net.ResolveUDPAddr("udp", address)
3459
if err != nil {
35-
log.Fatal(err)
60+
log.Printf("Could resolve multicast address %v: %v", address, err)
61+
return
3662
}
37-
conn, err := net.ListenMulticastUDP("udp", nil, addr)
63+
64+
conn, err := net.ListenMulticastUDP("udp", &ifi, addr)
3865
if err != nil {
39-
log.Fatal(err)
66+
log.Printf("Could not listen at %v: %v", address, err)
67+
return
4068
}
69+
4170
if err := conn.SetReadBuffer(maxDatagramSize); err != nil {
42-
log.Printf("Could not set read buffer to %v.", maxDatagramSize)
71+
log.Println("Could not set read buffer: ", err)
4372
}
44-
log.Println("Receiving from", address)
73+
74+
log.Printf("Listening on %s (%s)", address, ifi.Name)
75+
76+
data := make([]byte, maxDatagramSize)
4577
for {
46-
_, udpAddr, err := conn.ReadFromUDP([]byte{0})
78+
_, remoteAddr, err := conn.ReadFromUDP(data)
4779
if err != nil {
48-
log.Print("Could not read: ", err)
49-
time.Sleep(1 * time.Second)
50-
continue
80+
log.Println("ReadFromUDP failed:", err)
81+
return
5182
}
52-
addRemote(address, udpAddr.IP.String())
83+
84+
addRemote(address, Source{
85+
nif: ifi.Name,
86+
ip: remoteAddr.IP.String(),
87+
port: remoteAddr.Port,
88+
})
5389
}
5490
}
5591

56-
func addRemote(address string, remote string) {
92+
func addRemote(address string, source Source) {
93+
detectedRemotesMutex.Lock()
94+
defer detectedRemotesMutex.Unlock()
95+
5796
remotes, ok := detectedRemotes[address]
5897
if !ok {
59-
detectedRemotes[address] = []string{}
98+
detectedRemotes[address] = []Source{}
6099
}
61100
for _, a := range remotes {
62-
if a == remote {
101+
if a == source {
63102
return
64103
}
65104
}
66105

67-
detectedRemotes[address] = append(detectedRemotes[address], remote)
68-
log.Printf("remote ip on %v: %v\n", address, remote)
106+
detectedRemotes[address] = append(detectedRemotes[address], source)
107+
log.Printf("New source on %v: %+v\n", address, source)
69108
}

0 commit comments

Comments
 (0)