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

Added site support for CoAP client including example #132

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

lcoudeville
Copy link

I've added support to supply a coap site to a coap client. I needed this because I want to communicate with CoAP nodes in a private network (NAT).

Also added a small tcp example to use this feature. I'm aware of the fact that quality of this test is not that high. I guess this library misses the support as server to handle access the incoming connections. Something I've realised by hacking the TcpServer by using the ._pool variable. I'll only use this library as CoAP client that's why I not further investigated this.

Problems that still exists. As client you have to make a request to the server first to open an connection (I'm not 100% sure that this not possible with this library, but I wasn't able to reveal how). Something which is not really required by the RFC. It's not required that Connection Initiator sends a request first.

I'm curious to receive your first feedback.

Laurens Coudeville added 2 commits November 23, 2018 10:29
…at can be interrogated by the TCP server which is in this case also a coap client.
@chrysn
Copy link
Owner

chrysn commented Nov 23, 2018

That functionality is conceptually already present: If your client also exposes renderable resources, just create a server context. The server context is just as capable of launching client requests, it just also has a server site attached to it. (Although it does have the side effect of binding to the default port that currently can't be circumvented; if you actually need a random port, the suggested workaround is like in contrib/aiocoap-widgets after if args.anyport, but really that shouldn't be needed often).

Once you're using that, there's still the quirk that you need to construct your request messages to the server-behind-a-client-socket by setting the message's remote to the incoming request's remote -- I'm open to cleaner ways of doing this, but URIs don't easily accomodate those yet.

The changes from the first commit can be replaced with just using a server context.

As for the looping through the pool in the second commit -- that's information that'd come out of nowhere in the CoAP data model, as "connections" don't exist there. Rather than having the client access any resource and snooping through the "connections", can your application also work with the remote device accessing a particular resource, and that resource's handler storing out the request.remote property for further use? (A resource directory as already implemented in aiocoap, with additional proxying functionality currently not fully implemented or specified yet, would do just that).

@lcoudeville
Copy link
Author

The problem is that when starting a server context that it would listen for incoming connections also (as you've mentioned). This is something I want to avoid absolutely. Of course I can create an iptables rule to block incoming connections or bind to localhost.

My explanation was probably not clear enough. The problem I've encountered is that the coap clients are in a private network and thus behind a router. If those clients would be servers, their listing port would unreachable for my server which is not a part of that private network except I configure port forwarding on the router. Therefore I preferred to leave the connection initiative to the (coap/tcit) clients. When they are connected to a coap server they act as coap server as well.

Using the resource to access the remote, when a response is rendered, could help me a lot. Thank you. As mentioned I'm not intending to implement a server so I'll not further investigate this. I thought it might be interesting to support client sites as well, so from that point of view it might be interesting to merge the first commit. I'm also aware that the second commit is trash, that's why I've split them up.

So it's up to now, if you're convinced that this is not interesting I'll close my pull request. I'd like to thank you for your help.

@chrysn
Copy link
Owner

chrysn commented Nov 23, 2018

Now that's something different -- avoiding to listen. Probably you'll also want to avoid opening a UDP port? That's fine, but even the client process would do that.

What you can do is limit the transports that are available using the AIOCOAP_SERVER_TRANSPORT environment variable (you can also set that from Python -- I'm not yet sure how those configuration options are managed best) to the very transports you want -- probably just "oscore:tcpclient:tlsclient" (or even just "tcpclient" if you're not using any of the crypto options). That'd exclude you from all the rest of the CoAP world, but if that's what you're trying, this is the way to go. (Then, also, you don't have to worry about binding to the default port, and can simply start multiple server_context processes on the same device).

(That being said, I'd recommend against using tunneling as the only approach as it precludes local applications and is barely more secure than having the port open, given that other network participants can often intercept an outgoing TCP connection -- but that's a discussion that does not belong in the pull request, but I'm happy to continue by mail.)

If it's all the same to you, I'll leave the PR open as a reminder to make the things you've been looking for easier to find in the documentation.

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

Successfully merging this pull request may close these issues.

2 participants