Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support unicast responses #155

Closed
edaniels opened this issue May 2, 2023 · 3 comments
Closed

Support unicast responses #155

edaniels opened this issue May 2, 2023 · 3 comments
Labels
enhancement New feature or request

Comments

@edaniels
Copy link
Member

edaniels commented May 2, 2023

See https://rtcweb-wg.github.io/mdns-ice-candidates/mmusic/draft-ietf-mmusic-mdns-ice-candidates.html#implementation-guidance-1. It can help with security in addition to chattiness. I had implemented it in 17c664e but it was out of scope of the actual fix and I did not have a test to complement it. Also see https://datatracker.ietf.org/doc/html/draft-ietf-rtcweb-mdns-ice-candidates-04#section-3.2.1 point 2

Good reference at https://pkg.go.dev/golang.org/x/net/ipv4

@edaniels edaniels added the enhancement New feature or request label May 2, 2023
@edaniels
Copy link
Member Author

edaniels commented Feb 6, 2024

Did some initial investigation and I think this should slot behind IPv6 support which may end up exposing a new way to construct a server and possibly a client too with specific ipv4/6 sockets.

@edaniels
Copy link
Member Author

edaniels commented Feb 6, 2024

For future Eric, here's some useful unicast and multicast reading/writing:

package main

import (
	"fmt"
	"net"
	"time"

	"golang.org/x/net/ipv4"
)

func main() {
	c, err := net.ListenPacket("udp4", "0.0.0.0:1024")
	if err != nil {
		fmt.Println("err0", err)
		return
	}
	defer c.Close()

	fmt.Println("Local Address", c.LocalAddr())

	en0, err := net.InterfaceByName("en0")
	if err != nil {
		// error handling
	}
	group := net.IPv4(224, 0, 0, 250)

	addrs, err := en0.Addrs()
	fmt.Println("en0 address", addrs, err)

	p := ipv4.NewPacketConn(c)
	if err := p.JoinGroup(en0, &net.UDPAddr{IP: group}); err != nil {
		// error handling
	}

	go func() {
		b := make([]byte, 1500)
		for {
			fmt.Println("Reading...")
			n, cm, src, err := p.ReadFrom(b)
			if err != nil {
				fmt.Println("err1", err)
				continue
			}
			fmt.Println("Read!", b[:n], n, cm, src)
		}
	}()

	// TODO(erd): helpful?
	if err := p.SetControlMessage(ipv4.FlagDst, true); err != nil {
		fmt.Println("p.SetControlMessage(ipv4.FlagDst, true)", err)
	}

	// unicast writer
	go func() {
		data := []byte{1, 2, 3}
		for {
			time.Sleep(time.Second)
			// p.SetTOS(0x0)
			// p.SetTTL(16)
			var cm ipv4.ControlMessage
			cm.Dst = addrs[0].(*net.IPNet).IP
			someAddr := &net.UDPAddr{
				IP:   cm.Dst,
				Port: 1024,
			}
			fmt.Println("writing to", someAddr)
			if n, err := p.WriteTo(data, &cm, someAddr); err != nil {
				// error handling
				fmt.Println("err2", err)
				continue
			} else {
				fmt.Println("wrote unicast1", n)
			}
		}
	}()

	c2, err := net.ListenPacket("udp4", "0.0.0.0:0")
	if err != nil {
		fmt.Println("err0", err)
		return
	}
	defer c2.Close()
	p2 := ipv4.NewPacketConn(c2)
	if err := p2.JoinGroup(en0, &net.UDPAddr{IP: group}); err != nil {
		// error handling
	}

	// unicast writer
	go func() {
		data := []byte{7, 8, 9}
		for {
			time.Sleep(time.Second)
			// p.SetTOS(0x0)
			// p.SetTTL(16)
			var cm ipv4.ControlMessage
			cm.Dst = addrs[0].(*net.IPNet).IP
			someAddr := &net.UDPAddr{
				IP:   cm.Dst,
				Port: 1024,
			}
			fmt.Println("writing to", someAddr)
			if n, err := p2.WriteTo(data, &cm, someAddr); err != nil {
				// error handling
				fmt.Println("err5", err)
				continue
			} else {
				fmt.Println("wrote unicast2", n)
			}
		}
	}()

	// multicast writer
	go func() {
		data := []byte{4, 5, 6}
		dst := &net.UDPAddr{IP: group, Port: 1024}
		for {
			time.Sleep(time.Second)
			for _, ifi := range []*net.Interface{en0} {
				if err := p.SetMulticastInterface(ifi); err != nil {
					fmt.Println("err3", err)
				}
				// p.SetMulticastTTL(2)
				fmt.Println("writing to", dst)
				if n, err := p.WriteTo(data, nil, dst); err != nil {
					fmt.Println("err4", err)
					continue
				} else {
					fmt.Println("wrote multicast", n)
				}
			}
		}
	}()

	select {}
}

@edaniels
Copy link
Member Author

edaniels commented Feb 7, 2024

edaniels added a commit to edaniels/mdns that referenced this issue Feb 8, 2024
edaniels added a commit to edaniels/mdns that referenced this issue Feb 8, 2024
edaniels added a commit to edaniels/mdns that referenced this issue Feb 8, 2024
edaniels added a commit to edaniels/mdns that referenced this issue Feb 8, 2024
edaniels added a commit to edaniels/mdns that referenced this issue Feb 8, 2024
edaniels added a commit to edaniels/mdns that referenced this issue Feb 8, 2024
edaniels added a commit to edaniels/mdns that referenced this issue Feb 8, 2024
edaniels added a commit to edaniels/mdns that referenced this issue Feb 8, 2024
edaniels added a commit that referenced this issue Feb 8, 2024
@edaniels edaniels closed this as completed Feb 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant