UDP

449 views
Skip to first unread message

Andrew Deane

unread,
Jul 12, 2012, 11:16:04 AM7/12/12
to golan...@googlegroups.com
Hello,

Apologies if this has been answered before, but I cannot find the answer.

Prior to Go 1 to read UDP we would do something like:

connection, _ := net.ListenUDP("udp4", address)
_ = connection.JoinGroup(group)

This would then result in a UDP listen on the full group, meaning that you would see something like this from a netstat:

udp 0 0 239.1.1.50:10000 0.0.0.0:*

Since Go 1 we do:

address, _ := net.ResolveUDPAddr("udp4", fmt.Sprintf("%v:%v", udpGroup, udpPort))
connection, _ := net.ListenMulticastUDP("udp4", nil, address)

This results in a listen on all groups i.e. in netstat we get:

udp 0 0 0.0.0.0:10000 0.0.0.0:*

net.ListenUDP gives similar results.

Is it no longer possible to listen to individual groups? If not, is it possible to listen to all traffic on a port and derive the group so that I can filter?

I'm sure I'm missing something.

Thanks,
Andy.

Andrew Deane

unread,
Jul 13, 2012, 2:52:03 AM7/13/12
to golan...@googlegroups.com
Hello,

I have done some more testing and seen that the issue happens when there are multiple multicast listeners on the same box. Single listeners receive message just for their group but once a second listener joins any other group all listeners receive all groups messages.

Here is the code I'm testing with:

package main

import (
"flag"
"fmt"
"net"
"strings"
)

func main() {

gf := flag.String("group", "", "UDP group")
pf := flag.Int("port", 0, "UDP port")

flag.Parse()

g := *gf
p := *pf

if a, e := net.ResolveUDPAddr("udp4", fmt.Sprintf("%v:%v", g, p)); e == nil {

if c, e := net.ListenMulticastUDP("udp4", nil, a); e == nil {
b := make([]byte, 1024)
for {
n, _, _ := c.ReadFromUDP(b)
fmt.Printf("Read %v\n", strings.TrimSpace(string(b[0:n])))
}
} else {
fmt.Printf("%v\n", e)
}
} else {
fmt.Printf("%v\n", e)
}
}

I run 1 instance up:
go run ut.go -group 239.1.1.50 -port 10000

and then:
netcat -v -u 239.1.1.50 10000
50   

gives 50 on stdout.

If I then start another instance:
go run ut.go -group 239.1.1.51 -port 10000

and

netcat -v -u 239.1.1.51 10000
51   

both instances get 51 on their stdout.

Likewise if I then
netcat -v -u 239.1.1.50 10000
50   

both instance get 50 on their stdout.

netstat shows:

sudo netstat -napug
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
udp        0      0 0.0.0.0:10000           0.0.0.0:*                           3661/a.out      
udp        0      0 0.0.0.0:10000           0.0.0.0:*                           3650/a.out      
IPv6/IPv4 Group Memberships
Interface       RefCnt Group
--------------- ------ ---------------------
eth0            1      239.1.1.51
eth0            1      239.1.1.50

Kyle Lemons

unread,
Jul 13, 2012, 3:30:11 AM7/13/12
to Andrew Deane, golan...@googlegroups.com
It has been a long time since I toyed with multicast, so I can't give you an authoritative answer, but I think it's safe to say that if the behavior you describe worked before and doesn't work now, it's a regression and a bug should be filed on the issue tracker.

Stephen Day

unread,
Jul 13, 2012, 1:35:06 PM7/13/12
to golan...@googlegroups.com
This behavior is correct. Multicast "listeners" operate at the interface level. The address passed to net.ListenMulticastUDP sets the group membership, which sets the address sent out in igmp packets that are sent out on the local network.

Use ReadFrom and filter on the Addr returned (also make sure you check the error condition).

Andrew Deane

unread,
Jul 13, 2012, 2:12:49 PM7/13/12
to golan...@googlegroups.com
Previously when I did this (admittedly with ReadFromUDP) the Addr returned seemed to be the local address of the sender i.e. 192.168.etc.etc and not the UDP group. Was I doing something else wrong?

I'll adapt the ut.go code and re-test.

Andrew Deane

unread,
Jul 16, 2012, 9:18:06 AM7/16/12
to golan...@googlegroups.com
Hello,

I have re-tried this and the Addr returned from ReadFrom is the local address of the sender i.e. 192.168.1.67:54107.

Am I missing something; I don't see how I can filter on this? I'm not being difficult. I just don't understand.

If this is how ListenMulticastUDP (or indeed multicast UDP) works then I'll simply use alternative ports and groups for my actual implementation and avoid the functionality.

Thanks again,
Andy.


On Friday, July 13, 2012 6:35:06 PM UTC+1, Stephen Day wrote:

Mikio Hara

unread,
Jul 17, 2012, 10:25:31 AM7/17/12
to Andrew Deane, golan...@googlegroups.com
Hi,

Sorry for the late response.

On Mon, Jul 16, 2012 at 10:18 PM, Andrew Deane
<andrew....@googlemail.com> wrote:

> If this is how ListenMulticastUDP (or indeed multicast UDP) works then I'll
> simply use alternative ports and groups for my actual implementation and
> avoid the functionality.

net.ListenMulticastUDP in Go 1 listens to wildcard address on the given
port, then joins the given group address. For now the solution to avoid
cross-talk would be choosing each different port for each service.

FWIW lastest Linux is okay to listen to a multicast address, perhaps latest
BSD variants too, but I'm not sure for Windows, especially old 2000 and XP.

-- Mikio

andrew deane

unread,
Jul 17, 2012, 10:40:53 AM7/17/12
to Mikio Hara, golan...@googlegroups.com

Hello,

Nothing to apologise for. Thanks for the response.

Was the thinking behind this to remove the manual call too JoinGroup?

Are there plans to stop the cross talking in the future, with you saying "for now"?

Thanks again,
Andy.

Message has been deleted
Message has been deleted

Stephen Day

unread,
Jul 17, 2012, 11:37:03 AM7/17/12
to golan...@googlegroups.com
Andrew:

What platform are you on (uname -a)?

I've worked out some example code that seems to bind the port and filter the packets correctly, but I'm on Mac OS X. I'll post it when I have a chance.

Stephen.

Andrew Deane

unread,
Jul 17, 2012, 2:31:19 PM7/17/12
to golan...@googlegroups.com
Hello,

Sorry I should have linked back to the issue I raised on the project tracker it has all the information on.


Andy

Mikio Hara

unread,
Jul 18, 2012, 11:11:09 AM7/18/12
to andrew deane, golan...@googlegroups.com
On Tue, Jul 17, 2012 at 11:40 PM, andrew deane
<andrew....@googlemail.com> wrote:

> Are there plans to stop the cross talking in the future, with you saying
> "for now"?

I guess it's hard to avoid cross-talking issue directly because
that behavior depends on each platform you run. Instead I think
that adding both WriteMsg and ReadMsg API and enables to
determine packet level information via ancillary data might help
us.

-- Mikio

Andrew Deane

unread,
Jul 18, 2012, 11:19:40 AM7/18/12
to golan...@googlegroups.com, andrew deane
Something like conn.ReadMsg(bytes,addr) where addr is the group/port combination?

On Wednesday, July 18, 2012 4:11:09 PM UTC+1, Mikio Hara wrote:
On Tue, Jul 17, 2012 at 11:40 PM, andrew deane
Reply all
Reply to author
Forward
0 new messages