Skip to content

Commit

Permalink
fix: Utilize hoplimit for multicast
Browse files Browse the repository at this point in the history
If the hoplimit is set, it will be used. If not set, the default
values defined in the [OCF Core Specification](https://openconnectivity.org/specs/OCF_Core_Specification.pdf)
section 12.2.9 will be used.

Default values:
- For "224.0.1.187:5683", the hoplimit is set to 1.
- For "[ff02::158]:5683", the hoplimit is set to 1.
- For "[ff03::158]:5683", the hoplimit is set to 255.
- For "[ff05::158]:5683", the hoplimit is set to 255.
  • Loading branch information
jkralik committed Oct 10, 2023
1 parent 2f1f7eb commit f58dd27
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 6 deletions.
4 changes: 2 additions & 2 deletions client/core/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func WithTLS(tlsConfig *TLSConfig) OptionFunc {

// DiscoveryConfiguration setup discovery configuration
type DiscoveryConfiguration struct {
MulticastHopLimit int // default: 2, min value: 1 - don't pass through router, max value: 255, https://tools.ietf.org/html/rfc2460#section-3
MulticastHopLimit int // default: {224.0.1.187:5683, ff02::158]:5683} = 1, {[ff03::158]:5683, [ff05::158]:5683} = 255, https://openconnectivity.org/specs/OCF_Core_Specification.pdf 12.2.9
MulticastAddressUDP4 []string // default: "[224.0.1.187:5683] (client.DiscoveryAddressUDP4), empty: don't use ipv4 multicast"
MulticastAddressUDP6 []string // default: "[ff02::158]:5683", "[ff03::158]:5683", "[ff05::158]:5683]"] (client.DiscoveryAddressUDP6), empty: don't use ipv6 multicast"
MulticastOptions []coapNet.MulticastOption
Expand Down Expand Up @@ -151,7 +151,7 @@ func (c *Client) getDeviceConfiguration() DeviceConfiguration {

func DefaultDiscoveryConfiguration() DiscoveryConfiguration {
return DiscoveryConfiguration{
MulticastHopLimit: 2,
MulticastHopLimit: 0, // will be set to 1 or 255 based on address
MulticastAddressUDP4: DiscoveryAddressUDP4,
MulticastAddressUDP6: DiscoveryAddressUDP6,
MulticastOptions: []coapNet.MulticastOption{coapNet.WithMulticastInterfaceError(func(iface *net.Interface, err error) {
Expand Down
41 changes: 37 additions & 4 deletions client/core/discover.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,16 @@ import (
// See the section 10.4 on the line 2482 of the Core specification:
// https://openconnectivity.org/specs/OCF_Core_Specification_v2.0.0.pdf
// https://iotivity.org/documentation/linux/programmers-guide
const (
DiscoveryAddressUDP4Local = "224.0.1.187:5683"
DiscoveryAddressUDP6LinkLocal = "[ff02::158]:5683"
DiscoveryAddressUDP6RealmLocal = "[ff03::158]:5683"
DiscoveryAddressUDP6SiteLocal = "[ff05::158]:5683"
)

var (
DiscoveryAddressUDP4 = []string{"224.0.1.187:5683"}
DiscoveryAddressUDP6 = []string{"[ff02::158]:5683", "[ff03::158]:5683", "[ff05::158]:5683"}
DiscoveryAddressUDP4 = []string{DiscoveryAddressUDP4Local}
DiscoveryAddressUDP6 = []string{DiscoveryAddressUDP6LinkLocal, DiscoveryAddressUDP6RealmLocal, DiscoveryAddressUDP6SiteLocal}
)

type DiscoveryHandler = func(conn *client.Conn, req *pool.Message)
Expand Down Expand Up @@ -89,6 +96,24 @@ func (d *DiscoveryClient) Close() error {
return err
}

// See the section 12.2.9 https://openconnectivity.org/specs/OCF_Core_Specification.pdf
var defaultHopLimit = map[string]int{
DiscoveryAddressUDP4Local: 1,
DiscoveryAddressUDP6LinkLocal: 1,
DiscoveryAddressUDP6RealmLocal: 255,
DiscoveryAddressUDP6SiteLocal: 255,
}

func getHopLimit(addr string, desiredHopLimit int) int {
if desiredHopLimit > 0 {
return desiredHopLimit
}
if v, ok := defaultHopLimit[addr]; ok {
return v
}
return 1
}

// DialDiscoveryAddresses connects to discovery endpoints.
func DialDiscoveryAddresses(ctx context.Context, cfg DiscoveryConfiguration, errors func(error)) ([]*DiscoveryClient, error) {
v, ok := ctx.Deadline()
Expand All @@ -105,15 +130,23 @@ func DialDiscoveryAddresses(ctx context.Context, cfg DiscoveryConfiguration, err
msgIDudp6 := msgIDudp4 + ^uint16(0)/2

for _, address := range cfg.MulticastAddressUDP4 {
c, err := newDiscoveryClient("udp4", address, msgIDudp4, timeout, errors, cfg.MulticastOptions)
multicastOptions := []net.MulticastOption{
net.WithMulticastHoplimit(getHopLimit(address, cfg.MulticastHopLimit)),
}
multicastOptions = append(multicastOptions, cfg.MulticastOptions...)
c, err := newDiscoveryClient("udp4", address, msgIDudp4, timeout, errors, multicastOptions)
if err != nil {
errors(err)
continue
}
out = append(out, c)
}
for _, address := range cfg.MulticastAddressUDP6 {
c, err := newDiscoveryClient("udp6", address, msgIDudp6, timeout, errors, cfg.MulticastOptions)
multicastOptions := []net.MulticastOption{
net.WithMulticastHoplimit(getHopLimit(address, cfg.MulticastHopLimit)),
}
multicastOptions = append(multicastOptions, cfg.MulticastOptions...)
c, err := newDiscoveryClient("udp6", address, msgIDudp6, timeout, errors, multicastOptions)
if err != nil {
errors(err)
continue
Expand Down

0 comments on commit f58dd27

Please sign in to comment.