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

IPv6 Multicast #16

Open
adrian-nicolau opened this issue Aug 4, 2016 · 4 comments
Open

IPv6 Multicast #16

adrian-nicolau opened this issue Aug 4, 2016 · 4 comments

Comments

@adrian-nicolau
Copy link

This issue was tested on IPv6, but it (probably) applies to IPv4 as well.
When sending a request to an IPv6 multicast address, IMO there are two aspects that need to be updated:

  1. Every response to the multicast will be unrecognized because the source will be a unicast address , so resetUnrecognized() shouldn't be sent.
  2. A multicast socket will have a default TTL of 1, so the request won't cross multiple hops. I think class Message should have a ttl field which would set a socket option before sendMessage(), i.e.:
    sock = self.protocol.transport.getHandle()
    sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, request.ttl) # IPv4
    sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_HOPS, request.ttl) # IPv6
    self.protocol.sendMessage(request)
@sjlongland
Copy link

Also worth considering, is how to specify which interface to send a multicast message on. For example, I'd like to send a message to ff02::1%wpan0. The examples use the ipaddress module which doesn't understand this notation.

Without the %wpan0, the kernel just sends the packet whereever it chooses, which is so far, not the direction I need it to go. I see there's an interface parameter when you create the socket, but that's not helpful when you know an interface's name and not its address.

@sjlongland
Copy link

For what it's worth… I've just spent the last 12 hours trying to get multicast working… this was the result:

2017-09-11 21:20:15+0000 [-] Log opened.
2017-09-11 21:20:15+0000 [-] Coap starting on 64000
2017-09-11 21:20:15+0000 [-] Starting protocol <txthings.coap.Coap instance at 0x7f0f241eee60>
2017-09-11 21:20:16+0000 [-] Sending message to ff02::1:5683
2017-09-11 21:20:16+0000 [-] Exchange added, Message ID: 39215.
2017-09-11 21:20:16+0000 [-] Message 'D\x01\x99/\x00\x00\xf2+`Sobs' sent successfully
2017-09-11 21:20:16+0000 [-] Sending request - Token: 0000f22b, Host: ff02::1, Port: 5683
2017-09-11 21:20:19+0000 [-] Retransmission, Message ID: 39215.
2017-09-11 21:20:23+0000 [-] Retransmission, Message ID: 39215.
2017-09-11 21:20:31+0000 [-] Retransmission, Message ID: 39215.
2017-09-11 21:20:48+0000 [-] Retransmission, Message ID: 39215.
2017-09-11 21:21:49+0000 [-] Request timed out
2017-09-11 21:21:49+0000 [-] Failed to fetch resource:
2017-09-11 21:21:49+0000 [-] [Failure instance: Traceback (failure with no frames): <class 'txthings.error.RequestTimedOut'>: 
2017-09-11 21:21:49+0000 [-] ]

and this is the code

import sys

from twisted.internet.defer import Deferred
from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor
from twisted.python import log

import txthings.coap as coap
import txthings.resource as resource

from ipaddress import ip_address

class Agent():
    def __init__(self, protocol):
        self.protocol = protocol
        reactor.callLater(1, self.requestResource)

    def requestResource(self):
        request = coap.Message(code=coap.GET)
        #Send request to "coap://coap.me:5683/test"
        request.opt.uri_path = ('obs',)
        request.opt.observe = 0
        request.remote = (ip_address("ff02::1"), coap.COAP_PORT)
        d = protocol.request(request, observeCallback=self.printLaterResponse)
        d.addCallback(self.printResponse)
        d.addErrback(self.noResponse)

    def printResponse(self, response):
        print 'First result: ' + response.payload
        #reactor.stop()

    def printLaterResponse(self, response):
        print 'Observe result: ' + response.payload

    def noResponse(self, failure):
        print 'Failed to fetch resource:'
        print failure
        #reactor.stop()

log.startLogging(sys.stdout)

endpoint = resource.Endpoint(None)
protocol = coap.Coap(endpoint)
client = Agent(protocol)

reactor.listenUDP(64000, protocol, interface="fd7e:7b8c:6f0b:b77e::1")
reactor.run()

run under Python 2.7 with Twisted 16.2.0 (Debian Jessie).

https://stackoverflow.com/questions/36034258/ipv6-link-local-multicast-on-twisted seems to suggest Twisted itself has a lot missing.

@dcomins
Copy link

dcomins commented Jul 12, 2018

Did you find a solution to multicast link-local ipv6 @sjlongland ?

@sjlongland
Copy link

@dcomins I did… sort of… I re-wrote my application in NodeJS using the coap module off NPM.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants