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

How to deal with scenarios that requires cancelling? #255

Open
CCRcmcpe opened this issue Sep 7, 2023 · 5 comments
Open

How to deal with scenarios that requires cancelling? #255

CCRcmcpe opened this issue Sep 7, 2023 · 5 comments
Labels

Comments

@CCRcmcpe
Copy link

CCRcmcpe commented Sep 7, 2023

I'm building a port forwarding application using the .NET binding, but struggled to let it complete an iperf3 test because an issue when dealing with cleanups, like shutdown and close.

After the forwarded service send a 0 length packet to the app, the app call shutdown (send) for the zerotier socket. But the other end does not receive the 0 length packet. So it basically has no effect. The Python example does not call shutdown either.

If you call close, the other end receive a 0 length packet, which means the other end stops receiving. However, on this end, the thread that receives the data from the zerotier socket does not stop, in other words, stuck in receive method. I don't have a way to cancel it, except to kill the thread. I think is this a last resort, and is no longer possible to acheive with current .NET API.

Any advice? Should I use poll instead to determine whether there are data to receive? I don't really understand how poll works with zerotier sockets.

@CCRcmcpe
Copy link
Author

CCRcmcpe commented Sep 7, 2023

BTW I'm not very familiar with socket programming. Trying to point out the core issue, per https://stackoverflow.com/questions/60083939/what-is-the-best-way-to-cancel-a-socket-receive-request I basically have to close the socket to cancel receiving. But in libzt closing the socket does not have this effect. oops.

@CCRcmcpe
Copy link
Author

CCRcmcpe commented Sep 7, 2023

And to clarify, the other end did execute close after receiving the 0 length packet. So on this end it should receive a 0 length packet to indicate that too (?), but it doesn't.

@joseph-henry
Copy link
Contributor

Normally when you're trying to react to a socket closure you need to be polling either via poll, select, or by setting the socket to non-blocking and just seeing what you get back. There is a C example here: https://github.com/zerotier/libzt/blob/2f0f25a15870ac0ae52815558c539e63d656d506/examples/c/nonblockingserver.c that should help with the concept. Unfortunately I don't have a good C# example currently.

I did a quick check of the C# wrapper and it looks like I implemented Poll(), it is intended to work just like the native C# function so I'd try that and if you find any missing or incorrect behavior I am interested in fixing that so please bring it to my attention.

Also, feel free to make a PR if you find anything else broken in that wrapper, we are interested in improving it.

P.S. Polling a set of OS and ZT sockets together in the same FD set doesn't work but I'm introducing a new "fused polling" mode to help with this and I'll try to add it to the C# wrapper if needed.

@CCRcmcpe
Copy link
Author

CCRcmcpe commented Sep 7, 2023

Thanks for the response. Polling is certainly considered, but I don't really understand the return value of it. Even if the socket is already closed (by remote), poll(can recv) still returns true.

@chadrockey
Copy link

@CCRcmcpe how did your port forwarder work out for you?

I do feel that this is one of the most common use cases of this library (open a local port but forward it to a ZeroTier end point). Maybe it could be done in the base library and exposed to the client libraries?

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

No branches or pull requests

3 participants