Skip to content

Commit

Permalink
Detect multicast sources from different network interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
g3force committed Jun 15, 2023
1 parent 1111c6a commit 523279e
Showing 1 changed file with 61 additions and 22 deletions.
83 changes: 61 additions & 22 deletions cmd/ssl-multicast-sources/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,66 +4,105 @@ import (
"flag"
"log"
"net"
"time"
"os"
"os/signal"
"sync"
"syscall"
)

const maxDatagramSize = 8192

var detectedRemotes map[string][]string
type Source struct {
nif string
ip string
port int
}

var detectedRemotes map[string][]Source
var detectedRemotesMutex sync.Mutex

func main() {
flag.Parse()

detectedRemotes = map[string][]string{}
detectedRemotes = map[string][]Source{}
mcAddresses := flag.Args()
if len(mcAddresses) == 0 {
mcAddresses = []string{"224.5.23.1:10003", "224.5.23.2:10006", "224.5.23.2:10010", "224.5.23.2:10012"}
}

ifiList := interfaces()
for _, address := range mcAddresses {
go watchAddress(address)
for _, ifi := range ifiList {
go receiveOnInterface(address, ifi)
}
}

for {
time.Sleep(1 * time.Second)
signals := make(chan os.Signal, 1)
signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM)
<-signals
}

func interfaces() (interfaces []net.Interface) {
interfaces = []net.Interface{}
ifis, err := net.Interfaces()
if err != nil {
log.Println("Could not get available interfaces: ", err)
}
for _, ifi := range ifis {
interfaces = append(interfaces, ifi)
}
return
}

func watchAddress(address string) {
func receiveOnInterface(address string, ifi net.Interface) {
addr, err := net.ResolveUDPAddr("udp", address)
if err != nil {
log.Fatal(err)
log.Printf("Could resolve multicast address %v: %v", address, err)
return
}
conn, err := net.ListenMulticastUDP("udp", nil, addr)

conn, err := net.ListenMulticastUDP("udp", &ifi, addr)
if err != nil {
log.Fatal(err)
log.Printf("Could not listen at %v: %v", address, err)
return
}

if err := conn.SetReadBuffer(maxDatagramSize); err != nil {
log.Printf("Could not set read buffer to %v.", maxDatagramSize)
log.Println("Could not set read buffer: ", err)
}
log.Println("Receiving from", address)

log.Printf("Listening on %s (%s)", address, ifi.Name)

data := make([]byte, maxDatagramSize)
for {
_, udpAddr, err := conn.ReadFromUDP([]byte{0})
_, remoteAddr, err := conn.ReadFromUDP(data)
if err != nil {
log.Print("Could not read: ", err)
time.Sleep(1 * time.Second)
continue
log.Println("ReadFromUDP failed:", err)
return
}
addRemote(address, udpAddr.IP.String())

addRemote(address, Source{
nif: ifi.Name,
ip: remoteAddr.IP.String(),
port: remoteAddr.Port,
})
}
}

func addRemote(address string, remote string) {
func addRemote(address string, source Source) {
detectedRemotesMutex.Lock()
defer detectedRemotesMutex.Unlock()

remotes, ok := detectedRemotes[address]
if !ok {
detectedRemotes[address] = []string{}
detectedRemotes[address] = []Source{}
}
for _, a := range remotes {
if a == remote {
if a == source {
return
}
}

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

0 comments on commit 523279e

Please sign in to comment.