zerotier / libzt

Encrypted P2P sockets over ZeroTier
https://zerotier.com
Other
180 stars 54 forks source link

Java process does not exit after finishing libzt work #242

Closed bostick closed 1 year ago

bostick commented 1 year ago

With this basic example:

import com.zerotier.sockets.*;

public class ExitTest {

    public static void main(String[] args) throws InterruptedException {

        long networkId = Long.parseUnsignedLong("ebe7fbd445e76ac6", 16);
        String storagePath = "exittest_storage";

        ZeroTierNode node = new ZeroTierNode();
        node.initFromStorage(storagePath);
        node.initSetEventHandler(new ZeroTierEventListener() {
            @Override
            public void onZeroTierEvent(long l, int eventCode) {
                if (eventCode == ZeroTierNative.ZTS_EVENT_NODE_UP) {
                    System.err.println("ZTS_EVENT_NODE_UP");
                }
                if (eventCode == ZeroTierNative.ZTS_EVENT_NODE_ONLINE) {
                    System.err.println("ZTS_EVENT_NODE_ONLINE");
                }
                if (eventCode == ZeroTierNative.ZTS_EVENT_NODE_OFFLINE) {
                    System.err.println("ZTS_EVENT_NODE_OFFLINE");
                }
                if (eventCode == ZeroTierNative.ZTS_EVENT_NODE_DOWN) {
                    System.err.println("ZTS_EVENT_NODE_DOWN");
                }
                if (eventCode == ZeroTierNative.ZTS_EVENT_NETWORK_READY_IP4) {
                    System.err.println("ZTS_EVENT_NETWORK_READY_IP4");
                }
                if (eventCode == ZeroTierNative.ZTS_EVENT_NETWORK_READY_IP6) {
                    System.err.println("ZTS_EVENT_NETWORK_READY_IP6");
                }
                if (eventCode == ZeroTierNative.ZTS_EVENT_NETWORK_DOWN) {
                    System.err.println("ZTS_EVENT_NETWORK_DOWN");
                }
                if (eventCode == ZeroTierNative.ZTS_EVENT_NETWORK_OK) {
                    System.err.println("ZTS_EVENT_NETWORK_OK");
                }
                if (eventCode == ZeroTierNative.ZTS_EVENT_NETWORK_ACCESS_DENIED) {
                    System.err.println("ZTS_EVENT_NETWORK_ACCESS_DENIED");
                }
                if (eventCode == ZeroTierNative.ZTS_EVENT_NETWORK_NOT_FOUND) {
                    System.err.println("ZTS_EVENT_NETWORK_NOT_FOUND");
                }
            }
        });

        System.err.println("start");
        node.start();

        System.err.println("delay until online");
        while (!node.isOnline()) {
            ZeroTierNative.zts_util_delay(50);
        }
        System.err.println("done delaying");

        System.out.println("join");
        node.join(networkId);

        System.out.println("delaying until transport ready");
        while (! node.isNetworkTransportReady(networkId)) {
            ZeroTierNative.zts_util_delay(50);
        }

        System.err.println("stop");
        node.stop();

        System.err.println("exiting");
    }
}

We can compile and run:

% java ExitTest
start
delay until online
ZTS_EVENT_NODE_UP
ZTS_EVENT_NODE_ONLINE
done delaying
join
delaying until transport ready
ZTS_EVENT_NETWORK_READY_IP4
ZTS_EVENT_NETWORK_READY_IP6
ZTS_EVENT_NETWORK_OK
stop
exiting

The expected behavior is that the process exits, but crucially, the process does not actually exit.

janvanbouwel commented 1 year ago

Have you tried ZeroTierNative.zts_node_free() ? (Haven't tested this but might work)

bostick commented 1 year ago

@janvanbouwel Thanks for looking. I have fix (https://github.com/zerotier/libzt/pull/243) but wanted to create proper issue for this.

joseph-henry commented 1 year ago

Thank you for fixing this, definitely needed.

Funny bit of history: since we use lwip and it was designed for embedded systems which are usually just turned off when you're done (so it had no actual thread shutdown mechanism) for a long time we didn't have a proper cleanup of resources and this was generally ok in userspace on mobile since the libzt instance usually had the same lifetime as the mobile application itself.