Exemple #1
0
        // Callback used internally to ferry events from the C++ layer
        static void OnZeroTierEvent(IntPtr msgPtr)
        {
            // Marshal the callback message pointer to a structure that we can inspect
            zts_callback_msg msg =
                (zts_callback_msg)Marshal.PtrToStructure(msgPtr, typeof(zts_callback_msg));

            ZeroTier.Core.Event newEvent = null;

            // Node events
            if (msg.eventCode == Constants.EVENT_NODE_UP)
            {
                newEvent = new ZeroTier.Core.Event(msg.eventCode, "EVENT_NODE_UP");
            }
            if (msg.eventCode == Constants.EVENT_NODE_ONLINE)
            {
                _isOnline = true;
                // Marshal the node details pointer to a structure
                zts_node_details details =
                    (zts_node_details)Marshal.PtrToStructure(msg.node, typeof(zts_node_details));
                _nodeId  = details.address;
                newEvent = new ZeroTier.Core.Event(msg.eventCode, "EVENT_NODE_ONLINE");
            }
            if (msg.eventCode == Constants.EVENT_NODE_OFFLINE)
            {
                _isOnline = false;
                newEvent  = new ZeroTier.Core.Event(msg.eventCode, "EVENT_NODE_OFFLINE");
            }
            if (msg.eventCode == Constants.EVENT_NODE_NORMAL_TERMINATION)
            {
                _isOnline = false;
                newEvent  = new ZeroTier.Core.Event(msg.eventCode, "EVENT_NODE_NORMAL_TERMINATION");
            }
            if (msg.eventCode == Constants.EVENT_NODE_DOWN)
            {
                _isOnline = false;
                newEvent  = new ZeroTier.Core.Event(msg.eventCode, "EVENT_NODE_DOWN");
            }
            if (msg.eventCode == Constants.EVENT_NODE_IDENTITY_COLLISION)
            {
                newEvent  = new ZeroTier.Core.Event(msg.eventCode, "EVENT_NODE_IDENTITY_COLLISION");
                _isOnline = false;
            }
            if (msg.eventCode == Constants.EVENT_NODE_UNRECOVERABLE_ERROR)
            {
                newEvent  = new ZeroTier.Core.Event(msg.eventCode, "EVENT_NODE_UNRECOVERABLE_ERROR");
                _isOnline = false;
            }

            // Network events
            if (msg.eventCode == Constants.EVENT_NETWORK_NOT_FOUND)
            {
                newEvent = new ZeroTier.Core.Event(msg.eventCode, "EVENT_NETWORK_NOT_FOUND");
            }
            if (msg.eventCode == Constants.EVENT_NETWORK_REQ_CONFIG)
            {
                newEvent = new ZeroTier.Core.Event(msg.eventCode, "EVENT_NETWORK_REQ_CONFIG");
            }
            if (msg.eventCode == Constants.EVENT_NETWORK_ACCESS_DENIED)
            {
                newEvent = new ZeroTier.Core.Event(msg.eventCode, "EVENT_NETWORK_ACCESS_DENIED");
            }
            if (msg.eventCode == Constants.EVENT_NETWORK_READY_IP4)
            {
                _joinedAtLeastOneNetwork = true;
                newEvent = new ZeroTier.Core.Event(msg.eventCode, "EVENT_NETWORK_READY_IP4");
            }
            if (msg.eventCode == Constants.EVENT_NETWORK_READY_IP6)
            {
                _joinedAtLeastOneNetwork = true;
                newEvent = new ZeroTier.Core.Event(msg.eventCode, "EVENT_NETWORK_READY_IP6");
            }
            if (msg.eventCode == Constants.EVENT_NETWORK_DOWN)
            {
                newEvent = new ZeroTier.Core.Event(msg.eventCode, "EVENT_NETWORK_DOWN");
            }
            if (msg.eventCode == Constants.EVENT_NETWORK_CLIENT_TOO_OLD)
            {
                newEvent = new ZeroTier.Core.Event(msg.eventCode, "EVENT_NETWORK_CLIENT_TOO_OLD");
            }
            if (msg.eventCode == Constants.EVENT_NETWORK_REQ_CONFIG)
            {
                newEvent = new ZeroTier.Core.Event(msg.eventCode, "EVENT_NETWORK_REQ_CONFIG");
            }
            if (msg.eventCode == Constants.EVENT_NETWORK_OK)
            {
                zts_network_details unmanagedDetails =
                    (zts_network_details)Marshal.PtrToStructure(msg.network, typeof(zts_network_details));
                newEvent = new ZeroTier.Core.Event(msg.eventCode, "EVENT_NETWORK_OK");
                newEvent.networkDetails           = new NetworkDetails();
                newEvent.networkDetails.networkId = unmanagedDetails.nwid;
            }
            if (msg.eventCode == Constants.EVENT_NETWORK_ACCESS_DENIED)
            {
                newEvent = new ZeroTier.Core.Event(msg.eventCode, "EVENT_NETWORK_ACCESS_DENIED");
            }
            if (msg.eventCode == Constants.EVENT_NETWORK_READY_IP4_IP6)
            {
                newEvent = new ZeroTier.Core.Event(msg.eventCode, "EVENT_NETWORK_READY_IP4_IP6");
            }
            if (msg.eventCode == Constants.EVENT_NETWORK_UPDATE)
            {
                newEvent = new ZeroTier.Core.Event(msg.eventCode, "EVENT_NETWORK_UPDATE");
            }

            // Stack events
            if (msg.eventCode == Constants.EVENT_STACK_UP)
            {
                newEvent = new ZeroTier.Core.Event(msg.eventCode, "EVENT_STACK_UP");
            }
            if (msg.eventCode == Constants.EVENT_STACK_DOWN)
            {
                newEvent = new ZeroTier.Core.Event(msg.eventCode, "EVENT_STACK_DOWN");
            }

            // Address events
            if (msg.eventCode == Constants.EVENT_ADDR_ADDED_IP4)
            {
                newEvent = new ZeroTier.Core.Event(msg.eventCode, "EVENT_ADDR_ADDED_IP4");
            }
            if (msg.eventCode == Constants.EVENT_ADDR_ADDED_IP6)
            {
                newEvent = new ZeroTier.Core.Event(msg.eventCode, "EVENT_ADDR_ADDED_IP6");
            }
            if (msg.eventCode == Constants.EVENT_ADDR_REMOVED_IP4)
            {
                newEvent = new ZeroTier.Core.Event(msg.eventCode, "EVENT_ADDR_REMOVED_IP4");
            }
            if (msg.eventCode == Constants.EVENT_ADDR_REMOVED_IP6)
            {
                newEvent = new ZeroTier.Core.Event(msg.eventCode, "EVENT_ADDR_REMOVED_IP6");
            }
            // peer events
            if (msg.eventCode == Constants.EVENT_PEER_DIRECT)
            {
                newEvent = new ZeroTier.Core.Event(msg.eventCode, "EVENT_PEER_DIRECT");
            }
            if (msg.eventCode == Constants.EVENT_PEER_RELAY)
            {
                newEvent = new ZeroTier.Core.Event(msg.eventCode, "EVENT_PEER_RELAY");
            }
            // newEvent = new ZeroTier.Core.Event(msg.eventCode,"EVENT_PEER_UNREACHABLE");
            if (msg.eventCode == Constants.EVENT_PEER_PATH_DISCOVERED)
            {
                newEvent = new ZeroTier.Core.Event(msg.eventCode, "EVENT_PEER_PATH_DISCOVERED");
            }
            if (msg.eventCode == Constants.EVENT_PEER_PATH_DEAD)
            {
                newEvent = new ZeroTier.Core.Event(msg.eventCode, "EVENT_PEER_PATH_DEAD");
            }

            // Route events
            if (msg.eventCode == Constants.EVENT_ROUTE_ADDED)
            {
                newEvent = new ZeroTier.Core.Event(msg.eventCode, "EVENT_ROUTE_ADDED");
            }
            if (msg.eventCode == Constants.EVENT_ROUTE_REMOVED)
            {
                newEvent = new ZeroTier.Core.Event(msg.eventCode, "EVENT_ROUTE_REMOVED");
            }

            // Netif events
            if (msg.eventCode == Constants.EVENT_NETIF_UP)
            {
                newEvent = new ZeroTier.Core.Event(msg.eventCode, "EVENT_NETIF_UP");
            }
            if (msg.eventCode == Constants.EVENT_NETIF_DOWN)
            {
                newEvent = new ZeroTier.Core.Event(msg.eventCode, "EVENT_NETIF_DOWN");
            }
            if (msg.eventCode == Constants.EVENT_NETIF_REMOVED)
            {
                newEvent = new ZeroTier.Core.Event(msg.eventCode, "EVENT_NETIF_REMOVED");
            }
            if (msg.eventCode == Constants.EVENT_NETIF_LINK_UP)
            {
                newEvent = new ZeroTier.Core.Event(msg.eventCode, "EVENT_NETIF_LINK_UP");
            }
            if (msg.eventCode == Constants.EVENT_NETIF_LINK_DOWN)
            {
                newEvent = new ZeroTier.Core.Event(msg.eventCode, "EVENT_NETIF_LINK_DOWN");
            }
            if (msg.eventCode == Constants.EVENT_ADDR_REMOVED_IP6)
            {
                newEvent = new ZeroTier.Core.Event(msg.eventCode, "EVENT_ADDR_REMOVED_IP6");
            }

            // Pass the converted Event to the managed callback (visible to user)
            if (newEvent != null)
            {
                _managedCallback(newEvent);
            }
        }
Exemple #2
0
        void OnZeroTierEvent(IntPtr msgPtr)
        {
            zts_event_msg_t msg = (zts_event_msg_t)Marshal.PtrToStructure(msgPtr, typeof(zts_event_msg_t));

            ZeroTier.Core.Event newEvent = null;

            // Node

            if (msg.node != IntPtr.Zero)
            {
                zts_node_info_t details = (zts_node_info_t)Marshal.PtrToStructure(msg.node, typeof(zts_node_info_t));
                newEvent       = new ZeroTier.Core.Event();
                newEvent.Code  = msg.event_code;
                _id            = details.node_id;
                _primaryPort   = details.primary_port;
                _secondaryPort = details.secondary_port;
                _tertiaryPort  = details.tertiary_port;
                _versionMajor  = details.ver_major;
                _versionMinor  = details.ver_minor;
                _versionRev    = details.ver_rev;
                _isOnline      = Convert.ToBoolean(zts_node_is_online());

                if (msg.event_code == Constants.EVENT_NODE_UP)
                {
                    newEvent.Name = "EVENT_NODE_UP";
                }
                if (msg.event_code == Constants.EVENT_NODE_ONLINE)
                {
                    newEvent.Name = "EVENT_NODE_ONLINE";
                }
                if (msg.event_code == Constants.EVENT_NODE_OFFLINE)
                {
                    newEvent.Name = "EVENT_NODE_OFFLINE";
                }
                if (msg.event_code == Constants.EVENT_NODE_DOWN)
                {
                    newEvent.Name = "EVENT_NODE_DOWN";
                }
                if (msg.event_code == Constants.ZTS_EVENT_NODE_FATAL_ERROR)
                {
                    newEvent.Name = "EVENT_NODE_FATAL_ERROR";
                }
            }

            // Network

            if (msg.network != IntPtr.Zero)
            {
                zts_net_info_t net_info = (zts_net_info_t)Marshal.PtrToStructure(msg.network, typeof(zts_net_info_t));
                newEvent      = new ZeroTier.Core.Event();
                newEvent.Code = msg.event_code;

                // Update network info as long as we aren't tearing down the network
                if (msg.event_code != Constants.EVENT_NETWORK_DOWN)
                {
                    ulong       networkId = net_info.net_id;
                    NetworkInfo ni        = _networks.GetOrAdd(networkId, new NetworkInfo());

                    newEvent.NetworkInfo                  = ni;
                    newEvent.NetworkInfo.Id               = net_info.net_id;
                    newEvent.NetworkInfo.MACAddress       = net_info.mac;
                    newEvent.NetworkInfo.Name             = System.Text.Encoding.UTF8.GetString(net_info.name);
                    newEvent.NetworkInfo.Status           = net_info.status;
                    newEvent.NetworkInfo.Type             = net_info.type;
                    newEvent.NetworkInfo.MTU              = net_info.mtu;
                    newEvent.NetworkInfo.DHCP             = net_info.dhcp;
                    newEvent.NetworkInfo.Bridge           = Convert.ToBoolean(net_info.bridge);
                    newEvent.NetworkInfo.BroadcastEnabled = Convert.ToBoolean(net_info.broadcast_enabled);

                    zts_core_lock_obtain();

                    // Get assigned addresses

                    ConcurrentDictionary <string, IPAddress> newAddrsDict =
                        new ConcurrentDictionary <string, IPAddress>();
                    IntPtr addrBuffer = Marshal.AllocHGlobal(ZeroTier.Constants.INET6_ADDRSTRLEN);
                    int    addr_count = zts_core_query_addr_count(networkId);

                    for (int idx = 0; idx < addr_count; idx++)
                    {
                        zts_core_query_addr(networkId, idx, addrBuffer, ZeroTier.Constants.INET6_ADDRSTRLEN);
                        // Convert buffer to managed string
                        string    str  = Marshal.PtrToStringAnsi(addrBuffer);
                        IPAddress addr = IPAddress.Parse(str);
                        newAddrsDict[addr.ToString()] = addr;
                    }

                    // Update addresses in NetworkInfo object

                    // TODO: This update block works but could use a re-think, I think.
                    // Step 1. Remove addresses not present in new concurrent dict.
                    if (!ni._addrs.IsEmpty)
                    {
                        foreach (string key in ni._addrs.Keys)
                        {
                            if (!newAddrsDict.Keys.Contains(key))
                            {
                                ni._addrs.TryRemove(key, out _);
                            }
                        }
                    }
                    else
                    {
                        ni._addrs = newAddrsDict;
                    }
                    // Step 2. Add addresses not present in existing concurrent dict.
                    foreach (string key in newAddrsDict.Keys)
                    {
                        if (!ni._addrs.Keys.Contains(key))
                        {
                            ni._addrs[key] = newAddrsDict[key];
                        }
                    }

                    Marshal.FreeHGlobal(addrBuffer);
                    addrBuffer = IntPtr.Zero;

                    // Get managed routes

                    ConcurrentDictionary <string, RouteInfo> newRoutesDict =
                        new ConcurrentDictionary <string, RouteInfo>();
                    IntPtr targetBuffer = Marshal.AllocHGlobal(ZeroTier.Constants.INET6_ADDRSTRLEN);
                    IntPtr viaBuffer    = Marshal.AllocHGlobal(ZeroTier.Constants.INET6_ADDRSTRLEN);

                    int route_count = zts_core_query_route_count(networkId);

                    ushort flags = 0, metric = 0;

                    for (int idx = 0; idx < route_count; idx++)
                    {
                        zts_core_query_route(
                            networkId,
                            idx,
                            targetBuffer,
                            viaBuffer,
                            ZeroTier.Constants.INET6_ADDRSTRLEN,
                            ref flags,
                            ref metric);

                        // Convert buffer to managed string

                        try {
                            string    targetStr  = Marshal.PtrToStringAnsi(targetBuffer);
                            IPAddress targetAddr = IPAddress.Parse(targetStr);
                            string    viaStr     = Marshal.PtrToStringAnsi(viaBuffer);
                            IPAddress viaAddr    = IPAddress.Parse(viaStr);
                            RouteInfo route      = new RouteInfo(targetAddr, viaAddr, flags, metric);
                            // Add to NetworkInfo object
                            newRoutesDict[targetStr] = route;
                        }
                        catch {
                            Console.WriteLine("error while parsing route");
                        }
                    }

                    // TODO: This update block works but could use a re-think, I think.
                    // Step 1. Remove routes not present in new concurrent dict.
                    if (!ni._routes.IsEmpty)
                    {
                        foreach (string key in ni._routes.Keys)
                        {
                            if (!newRoutesDict.Keys.Contains(key))
                            {
                                ni._routes.TryRemove(key, out _);
                            }
                        }
                    }
                    else
                    {
                        ni._routes = newRoutesDict;
                    }
                    // Step 2. Add routes not present in existing concurrent dict.
                    foreach (string key in newRoutesDict.Keys)
                    {
                        if (!ni._routes.Keys.Contains(key))
                        {
                            ni._routes[key] = newRoutesDict[key];
                        }
                    }

                    Marshal.FreeHGlobal(targetBuffer);
                    Marshal.FreeHGlobal(viaBuffer);
                    targetBuffer = IntPtr.Zero;
                    viaBuffer    = IntPtr.Zero;

                    // Get multicast subscriptions

                    zts_core_lock_release();

                    // Update synthetic "readiness" value
                    ni.transportReady = (route_count > 0) && (addr_count > 0) ? true : false;
                }   // EVENT_NETWORK_DOWN

                if (msg.event_code == Constants.EVENT_NETWORK_NOT_FOUND)
                {
                    newEvent.Name = "EVENT_NETWORK_NOT_FOUND " + net_info.net_id.ToString("x16");
                }
                if (msg.event_code == Constants.EVENT_NETWORK_REQ_CONFIG)
                {
                    newEvent.Name = "EVENT_NETWORK_REQ_CONFIG " + net_info.net_id.ToString("x16");
                }
                if (msg.event_code == Constants.EVENT_NETWORK_ACCESS_DENIED)
                {
                    newEvent.Name = "EVENT_NETWORK_ACCESS_DENIED " + net_info.net_id.ToString("x16");
                }
                if (msg.event_code == Constants.EVENT_NETWORK_READY_IP4)
                {
                    newEvent.Name = "EVENT_NETWORK_READY_IP4 " + net_info.net_id.ToString("x16");
                }
                if (msg.event_code == Constants.EVENT_NETWORK_READY_IP6)
                {
                    newEvent.Name = "EVENT_NETWORK_READY_IP6 " + net_info.net_id.ToString("x16");
                }
                if (msg.event_code == Constants.EVENT_NETWORK_DOWN)
                {
                    newEvent.Name = "EVENT_NETWORK_DOWN " + net_info.net_id.ToString("x16");
                }
                if (msg.event_code == Constants.EVENT_NETWORK_CLIENT_TOO_OLD)
                {
                    newEvent.Name = "EVENT_NETWORK_CLIENT_TOO_OLD " + net_info.net_id.ToString("x16");
                }
                if (msg.event_code == Constants.EVENT_NETWORK_REQ_CONFIG)
                {
                    newEvent.Name = "EVENT_NETWORK_REQ_CONFIG " + net_info.net_id.ToString("x16");
                }
                if (msg.event_code == Constants.EVENT_NETWORK_OK)
                {
                    newEvent.Name = "EVENT_NETWORK_OK " + net_info.net_id.ToString("x16");
                }
                if (msg.event_code == Constants.EVENT_NETWORK_ACCESS_DENIED)
                {
                    newEvent.Name = "EVENT_NETWORK_ACCESS_DENIED " + net_info.net_id.ToString("x16");
                }
                if (msg.event_code == Constants.EVENT_NETWORK_READY_IP4_IP6)
                {
                    newEvent.Name = "EVENT_NETWORK_READY_IP4_IP6 " + net_info.net_id.ToString("x16");
                }
                if (msg.event_code == Constants.EVENT_NETWORK_UPDATE)
                {
                    newEvent.Name = "EVENT_NETWORK_UPDATE " + net_info.net_id.ToString("x16");
                }
            }

            // Route

            if (msg.route != IntPtr.Zero)
            {
                zts_route_info_t route_info =
                    (zts_route_info_t)Marshal.PtrToStructure(msg.route, typeof(zts_route_info_t));
                newEvent      = new ZeroTier.Core.Event();
                newEvent.Code = msg.event_code;
                // newEvent.RouteInfo = default;   // new RouteInfo();

                if (msg.event_code == Constants.EVENT_ROUTE_ADDED)
                {
                    newEvent.Name = "EVENT_ROUTE_ADDED";
                }
                if (msg.event_code == Constants.EVENT_ROUTE_REMOVED)
                {
                    newEvent.Name = "EVENT_ROUTE_REMOVED";
                }
            }

            // Peer

            if (msg.peer != IntPtr.Zero)
            {
                zts_peer_info_t peer_info = (zts_peer_info_t)Marshal.PtrToStructure(msg.peer, typeof(zts_peer_info_t));
                newEvent      = new ZeroTier.Core.Event();
                newEvent.Code = msg.event_code;
                // newEvent.PeerInfo = default;   // new PeerInfo();

                if (peer_info.role == Constants.PEER_ROLE_PLANET)
                {
                    newEvent.Name = "PEER_ROLE_PLANET";
                }
                if (msg.event_code == Constants.EVENT_PEER_DIRECT)
                {
                    newEvent.Name = "EVENT_PEER_DIRECT";
                }
                if (msg.event_code == Constants.EVENT_PEER_RELAY)
                {
                    newEvent.Name = "EVENT_PEER_RELAY";
                }
                // newEvent = new ZeroTier.Core.Event(msg.event_code,"EVENT_PEER_UNREACHABLE");
                if (msg.event_code == Constants.EVENT_PEER_PATH_DISCOVERED)
                {
                    newEvent.Name = "EVENT_PEER_PATH_DISCOVERED";
                }
                if (msg.event_code == Constants.EVENT_PEER_PATH_DEAD)
                {
                    newEvent.Name = "EVENT_PEER_PATH_DEAD";
                }
            }

            // Address

            if (msg.addr != IntPtr.Zero)
            {
                zts_addr_info_t unmanagedDetails =
                    (zts_addr_info_t)Marshal.PtrToStructure(msg.addr, typeof(zts_addr_info_t));
                newEvent      = new ZeroTier.Core.Event();
                newEvent.Code = msg.event_code;
                // newEvent.AddressInfo = default;   // new AddressInfo();

                if (msg.event_code == Constants.EVENT_ADDR_ADDED_IP4)
                {
                    newEvent.Name = "EVENT_ADDR_ADDED_IP4";
                }
                if (msg.event_code == Constants.EVENT_ADDR_ADDED_IP6)
                {
                    newEvent.Name = "EVENT_ADDR_ADDED_IP6";
                }
                if (msg.event_code == Constants.EVENT_ADDR_REMOVED_IP4)
                {
                    newEvent.Name = "EVENT_ADDR_REMOVED_IP4";
                }
                if (msg.event_code == Constants.EVENT_ADDR_REMOVED_IP6)
                {
                    newEvent.Name = "EVENT_ADDR_REMOVED_IP6";
                }
            }

            // Storage

            if (msg.cache != IntPtr.Zero)
            {
                newEvent      = new ZeroTier.Core.Event();
                newEvent.Code = msg.event_code;
                // newEvent.AddressInfo = default;   // new AddressInfo();

                if (msg.event_code == Constants.EVENT_STORE_IDENTITY_SECRET)
                {
                    newEvent.Name = "EVENT_STORE_IDENTITY_SECRET";
                }
                if (msg.event_code == Constants.EVENT_STORE_IDENTITY_PUBLIC)
                {
                    newEvent.Name = "EVENT_STORE_IDENTITY_PUBLIC";
                }
                if (msg.event_code == Constants.EVENT_STORE_PLANET)
                {
                    newEvent.Name = "EVENT_STORE_PLANET";
                }
                if (msg.event_code == Constants.EVENT_STORE_PEER)
                {
                    newEvent.Name = "EVENT_STORE_PEER";
                }
                if (msg.event_code == Constants.EVENT_STORE_NETWORK)
                {
                    newEvent.Name = "EVENT_STORE_NETWORK";
                }
            }

            // Pass the converted Event to the managed callback (visible to user)
            if (newEvent != null)
            {
                _managedCallback(newEvent);
            }
        }