chrysn/aiocoap

Issues while bumping aiocoap version from 0.3 -> 0.4

Closed this issue · 7 comments

In an old project I used aiocoap 0.3. I tried bumping the version to aiocoap 0.4 and stumbled across some issue when binding:

future: <Task finished name='Task-2' coro=<Context.create_server_context() done, defined at /home/francisco/.virtualenvs/pyaiot/lib/python3.8/site-packages/aiocoap/protocol.py:211> exception=OSError(98, "error while attempting to bind on address ('::', 5684, 0, 0): address already in use")>
Traceback (most recent call last):
  File "/home/francisco/.virtualenvs/pyaiot/lib/python3.8/site-packages/aiocoap/protocol.py", line 270, in create_server_context
    await self._append_tokenmanaged_transport(
  File "/home/francisco/.virtualenvs/pyaiot/lib/python3.8/site-packages/aiocoap/protocol.py", line 156, in _append_tokenmanaged_transport
    transport = await token_interface_constructor(tman)
  File "/home/francisco/.virtualenvs/pyaiot/lib/python3.8/site-packages/aiocoap/transports/tcp.py", line 297, in create_server
    server = await loop.create_server(new_connection, bind[0], bind[1],
  File "/usr/lib/python3.8/asyncio/base_events.py", line 1463, in create_server
    raise OSError(err.errno, 'error while attempting '
OSError: [Errno 98] error while attempting to bind on address ('::', 5684, 0, 0): address already in use
2021-02-22 11:27:57,286 -        asyncio - ERROR - Task exception was never retrieved

It was hard for me to understand what was going on but after searching a bit it seems to be related to:

def get_default_clienttransports(*, loop=None, use_env=True):

or:

def has_reuse_port(*, use_env=True):

Since I'm using aiocoap in a 6LoWPAN application messages are sent over UDP, so I thought I needed to set:

export AIOCOAP_CLIENT_TRANSPORT=udp6
export AIOCOAP_SERVER_TRANSPORT=udp6

Doing this allowed me to run the script at least, but I seem to still be missing things. Before it seems the default UDP6 endpoint had ipv6:

 remote <UDP6EndpointAddress [::ffff:127.0.0.1]:5683 with local address>

now then point is only ipv4

 <UDP6EndpointAddress 127.0.0.1:5685>

Is it simply a matter that now for every setup I need to configure interface and transport?

Thanks for the feddback @chrysn!

aiocoap 0.3 did not support DTLS (which is what port 5684 is used for).
As you probably installed aiocoap 0.4.1 with all extras, DTLS gets added
by default.

This happens with whatever PORT I specify, I've also used 5688 and others.

Possibly. Can you give me the output of python3 -m aiocoap.cli.defaults to get some base values here?

Python version: 3.8.5 (default, Jul 28 2020, 12:59:40)
[GCC 9.3.0]
aiocoap version: 0.4.1
Modules missing for subsystems:
    dtls: missing DTLSSocket
    oscore: missing cbor2, filelock, ge25519
    linkheader: missing LinkHeader
    prettyprint: missing LinkHeader, cbor2, termcolor, pygments
Python platform: linux
Default server transports:  tcpserver:tcpclient:tlsserver:tlsclient:ws:udp6
Selected server transports: udp6
Default client transports:  tcpclient:tlsclient:ws:udp6
Selected client transports: udp6
SO_REUSEPORT available (default, selected): True, True

Also, how do you create your server transport? Do you put any specific
address in to bind to, or just leave it at the default value in the
create_server_context call?

https://github.com/pyaiot/pyaiot/blob/1533b69e828fc1fc3cdaa442d7225b49d131b7f3/pyaiot/gateway/coap/gateway.py#L127-L152

In an old project I used aiocoap 0.3.

I'm more of a user of the project, @aabadie was the main contributor.

I see -- yes, this is a known shortcoming of how the ports are specified so far. Specifying to only use udp6 (or tcpserver:tcpclient:udp6) is a good workaround. To get the problem itself on: How'd you like to specify ports for CoAP protocols that do use different ports?

aiocoap 0.3 did not support DTLS (which is what port 5684 is used for). > As you probably installed aiocoap 0.4.1 with all extras, DTLS gets added > by default. This happens with whatever PORT I specify, I've also used 5688 and others.
I see -- yes, this is a known shortcoming of how the ports are specified so far. Specifying to only use udp6 (or tcpserver:tcpclient:udp6) is a good workaround. To get the problem itself on: How'd you like to specify ports for CoAP protocols that do use different ports?

For starters how should it be done now?

Thanks for the input @chrysn this helped me understand the different transports, but anyway the issue I was having was actually due to a bug in our code that was just exposed by the version bump, so I'm closing this one.