How to specify source address in multicast connection in Haskell?

In the Haskell multicast documentation, I see a function

setInterface :: Socket -> HostName -> IO ()
Set the outgoing interface address of the multicast.

How can I use this to indicate the source address in a multicast connection? The following code, at startup, produces this output .. (IP addresses are masked to ensure confidentiality)

The code

import Network.BSD
import Network.Socket hiding (send, sendTo, recv, recvFrom)
import Network.Socket.ByteString
import Network.Multicast hiding (multicastReceiver)
import Text.Printf
import Data.ByteString as B hiding (putStrLn)

sourceIP = "192.168.MMM.NNN"
mcastIP = "224.0.XXX.YYY"
mcastPort = 32101

mcastLoop :: Socket -> IO ()
mcastLoop sock = do
    (msg, addr) <- recvFrom sock 1024
    printf "%s-> %s\n" (show addr) (show . B.unpack $ msg)
    mcastLoop sock 

multicastReceiver :: HostName -> PortNumber -> IO Socket
multicastReceiver host port = do
    proto <- getProtocolNumber "udp"
    sock  <- socket AF_INET Datagram proto
    setInterface sock sourceIP

{-# LINE 81 "src/Network/Multicast.hsc" #-}
    setInterface sock sourceIP
    bindSocket sock $ SockAddrInet port 0
    setInterface sock sourceIP
{-# LINE 82 "src/Network/Multicast.hsc" #-}
    setInterface sock sourceIP
    addMembership sock host
    return sock

main :: IO ()
main = withSocketsDo $ do
    sock <- multicastReceiver mcastIP mcastPort
    dropMembership sock mcastIP
    setInterface sock sourceIP
    addMembership sock mcastIP
    mcastLoop sock

Output

~ - sudo tcpdump -n -nn -i any "host 224.0.XXX.YYY"
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
08:00:44.463153 IP 10.52.ZZZ.WWW > 224.0.XXX.YYY: igmp v2 report 224.0.XXX.YYY
08:00:52.498722 IP 10.52.ZZZ.WWW > 224.0.XXX.YYY: igmp v2 report 224.0.XXX.YYY
08:00:58.301711 IP 10.52.ZZZ.WWW > 224.0.XXX.YYY: igmp v2 report 224.0.XXX.YYY
08:01:08.408710 IP 10.52.ZZZ.WWW > 224.0.XXX.YYY: igmp v2 report 224.0.XXX.YYY
08:02:04.104707 IP 10.52.ZZZ.WWW > 224.0.XXX.YYY: igmp v2 report 224.0.XXX.YYY
08:03:08.545718 IP 10.52.ZZZ.WWW > 224.0.XXX.YYY: igmp v2 report 224.0.XXX.YYY
08:04:02.634709 IP 10.52.ZZZ.WWW > 224.0.XXX.YYY: igmp v2 report 224.0.XXX.YYY
08:05:03.757718 IP 10.52.ZZZ.WWW > 224.0.XXX.YYY: igmp v2 report 224.0.XXX.YYY
08:06:10.600716 IP 10.52.ZZZ.WWW > 224.0.XXX.YYY: igmp v2 report 224.0.XXX.YYY
08:07:07.248707 IP 10.52.ZZZ.WWW > 224.0.XXX.YYY: igmp v2 report 224.0.XXX.YYY
08:08:10.202708 IP 10.52.ZZZ.WWW > 224.0.XXX.YYY: igmp v2 report 224.0.XXX.YYY
08:09:02.390708 IP 10.52.ZZZ.WWW > 224.0.XXX.YYY: igmp v2 report 224.0.XXX.YYY

This is a comparison of running C ++ / Haskell applications (as requested by EJP)

~/sandbox - sudo tcpdump -i any "host 192.168.MMM.NNN"        
[sudo] password for gresko: 
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes

# C++ application started
16:15:55.490156 IP 192.168.MMM.NNN > 224.0.62.108: igmp v2 report 224.0.62.108
# C++ application killed
16:16:04.689342 IP 192.168.MMM.NNN > all-routers.mcast.net: igmp leave 224.0.62.108

# Haskell application started
# Haskell application killed
+4
source share
1 answer

Haskell authors did not allow this in their constructor. It should not accept a group parameter at all, as it does not allow you to set up a multicast interface before joining a group. Or a group should be optional.

, addMembership(), NIC-, . Sockets .

, Haskell setInterface() , ,

dropMembership()
setInterface()
addMembership()

.

, - IGMP, , , setInterface() .

, , .

+1

All Articles