Implemented and fixed many issues

This commit is contained in:
Martino Ferrari
2026-08-21 23:24:48 +02:00
parent 14d5351a81
commit e03c60db25
52 changed files with 7726 additions and 769 deletions
+61 -2
View File
@@ -447,6 +447,52 @@ func (u *UDPClient) runSession() error {
}
}
// interfaceForIP returns the interface that owns the given local address, or
// nil if no interface matches (in which case callers fall back to letting the
// kernel choose).
func interfaceForIP(ip net.IP) *net.Interface {
if ip == nil || ip.IsUnspecified() {
return nil
}
ifaces, err := net.Interfaces()
if err != nil {
return nil
}
for i := range ifaces {
addrs, err := ifaces[i].Addrs()
if err != nil {
continue
}
for _, a := range addrs {
var aIP net.IP
switch v := a.(type) {
case *net.IPNet:
aIP = v.IP
case *net.IPAddr:
aIP = v.IP
}
if aIP != nil && aIP.Equal(ip) {
return &ifaces[i]
}
}
}
return nil
}
// interfaceForConn returns the interface a connection's local endpoint sits on.
func interfaceForConn(c net.Conn) *net.Interface {
if c == nil {
return nil
}
switch a := c.LocalAddr().(type) {
case *net.TCPAddr:
return interfaceForIP(a.IP)
case *net.UDPAddr:
return interfaceForIP(a.IP)
}
return nil
}
// runMulticastSession handles the multicast mode session.
func (u *UDPClient) runMulticastSession() error {
tcpAddr, err := net.ResolveTCPAddr("tcp4", u.serverAddr)
@@ -500,7 +546,15 @@ func (u *UDPClient) runMulticastSession() error {
return &net.AddrError{Err: "invalid multicast group IP", Addr: u.multicastGroup}
}
mcastAddr := &net.UDPAddr{IP: mcastIP, Port: mcastPort}
mcastConn, err := net.ListenMulticastUDP("udp4", nil, mcastAddr)
// Join on the interface that reaches the control connection. The UDPStreamer
// pins its multicast sends to its configured Interface (IP_MULTICAST_IF), so
// a join with a nil interface — which leaves imr_interface at INADDR_ANY and
// lets the kernel pick the default-route interface — silently receives
// nothing whenever that is not the sending interface. The local address of
// the control connection is the interface the server is reachable on, which
// is the sending interface in every single-homed and same-host deployment.
ifi := interfaceForConn(tcpConn)
mcastConn, err := net.ListenMulticastUDP("udp4", ifi, mcastAddr)
if err != nil {
return err
}
@@ -508,7 +562,12 @@ func (u *UDPClient) runMulticastSession() error {
if err := mcastConn.SetReadBuffer(udpRcvBufSize); err != nil {
log.Printf("[%s] multicast SetReadBuffer: %v", u.sourceID, err)
}
log.Printf("[%s] joined multicast %s:%s", u.sourceID, u.multicastGroup, strconv.Itoa(mcastPort))
ifName := "default"
if ifi != nil {
ifName = ifi.Name
}
log.Printf("[%s] joined multicast %s:%s on interface %s",
u.sourceID, u.multicastGroup, strconv.Itoa(mcastPort), ifName)
tcpDone := make(chan error, 1)
go func() {