static struct in6_addr * get_ip6_next_hop (gchar * next_hop) { gchar *tmp; struct in6_addr *tmp_ip6_addr = g_slice_new0 (struct in6_addr); if (!next_hop) return 0; tmp = find_gateway_str (next_hop); if (!tmp) { PLUGIN_WARN (IFNET_PLUGIN_NAME, "Couldn't obtain next_hop in \"%s\"", next_hop); return 0; } tmp = g_strdup (tmp); strip_string (tmp, ' '); strip_string (tmp, '"'); g_strstrip (tmp); if (!inet_pton (AF_INET6, tmp, tmp_ip6_addr)) goto error; g_free (tmp); return tmp_ip6_addr; error: if (!is_ip4_address (tmp)) PLUGIN_WARN (IFNET_PLUGIN_NAME, "Can't handle IPv6 next_hop: %s", tmp); g_free (tmp); g_slice_free (struct in6_addr, tmp_ip6_addr); return NULL; }
static guint32 get_ip4_gateway (gchar * gateway) { gchar *tmp, *split; struct in_addr tmp_ip4_addr; if (!gateway) return 0; tmp = find_gateway_str (gateway); if (!tmp) { PLUGIN_WARN (IFNET_PLUGIN_NAME, "Couldn't obtain gateway in \"%s\"", gateway); return 0; } tmp = g_strdup (tmp); strip_string (tmp, ' '); strip_string (tmp, '"'); if ((split = strstr (tmp, "\"")) != NULL) *split = '\0'; if (!inet_pton (AF_INET, tmp, &tmp_ip4_addr)) goto error; g_free (tmp); return tmp_ip4_addr.s_addr; error: if (!is_ip6_address (tmp)) PLUGIN_WARN (IFNET_PLUGIN_NAME, "Can't handle IPv4 gateway: %s", tmp); g_free (tmp); return 0; }
static ip_block * create_ip4_block (gchar * ip) { ip_block *iblock = g_slice_new0 (ip_block); struct in_addr tmp_ip4_addr; int i; guint length; gchar **ip_mask; /* prefix format */ if (strstr (ip, "/")) { gchar *prefix; ip_mask = g_strsplit (ip, "/", 0); length = g_strv_length (ip_mask); if (!inet_pton (AF_INET, ip_mask[0], &tmp_ip4_addr)) goto error; iblock->ip = tmp_ip4_addr.s_addr; prefix = ip_mask[1]; i = 0; while (i < length && isdigit (prefix[i])) i++; prefix[i] = '\0'; iblock->netmask = nm_utils_ip4_prefix_to_netmask ((guint32) atoi (ip_mask [1])); } else if (strstr (ip, "netmask")) { ip_mask = g_strsplit (ip, " ", 0); length = g_strv_length (ip_mask); if (!inet_pton (AF_INET, ip_mask[0], &tmp_ip4_addr)) goto error; iblock->ip = tmp_ip4_addr.s_addr; i = 0; while (i < length && !strstr (ip_mask[++i], "netmask")) ; while (i < length && ip_mask[++i][0] == '\0') ; if (i >= length) goto error; if (!inet_pton (AF_INET, ip_mask[i], &tmp_ip4_addr)) goto error; iblock->netmask = tmp_ip4_addr.s_addr; } else { g_slice_free (ip_block, iblock); if (!is_ip6_address (ip) && !strstr (ip, "dhcp")) PLUGIN_WARN (IFNET_PLUGIN_NAME, "Can't handle ipv4 address: %s, missing netmask or prefix", ip); return NULL; } g_strfreev (ip_mask); return iblock; error: if (!is_ip6_address (ip)) PLUGIN_WARN (IFNET_PLUGIN_NAME, "Can't handle IPv4 address: %s", ip); g_strfreev (ip_mask); g_slice_free (ip_block, iblock); return NULL; }
static GFileMonitor * monitor_file_changes (const char *filename, FileChangedFn callback, gpointer user_data) { GFile *file; GFileMonitor *monitor; FileMonitorInfo *info; GError **error = NULL; if (!g_file_test (filename, G_FILE_TEST_IS_REGULAR)) return NULL; file = g_file_new_for_path (filename); monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, error); g_object_unref (file); if (monitor) { info = g_new0 (FileMonitorInfo, 1); info->callback = callback; info->user_data = user_data; g_object_weak_ref (G_OBJECT (monitor), (GWeakNotify) g_free, info); g_signal_connect (monitor, "changed", G_CALLBACK (file_changed), info); PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Monitoring %s", filename); } else PLUGIN_WARN (IFNET_PLUGIN_NAME, "Monitoring %s failed, error: %s", filename, error == NULL ? "nothing" : (*error)->message); return monitor; }
static void read_connections (SCPluginIfcfg *plugin) { GDir *dir; GError *err = NULL; dir = g_dir_open (IFCFG_DIR, 0, &err); if (dir) { const char *item; while ((item = g_dir_read_name (dir))) { char *full_path; if (utils_should_ignore_file (item, TRUE)) continue; full_path = g_build_filename (IFCFG_DIR, item, NULL); if (utils_get_ifcfg_name (full_path, TRUE)) _internal_new_connection (plugin, full_path, NULL, NULL); g_free (full_path); } g_dir_close (dir); } else { PLUGIN_WARN (IFCFG_PLUGIN_NAME, "Can not read directory '%s': %s", IFCFG_DIR, err->message); g_error_free (err); } }
static void bind_device_to_connection (SCPluginIfupdown *self, GUdevDevice *device, NMIfupdownConnection *exported) { GByteArray *mac_address; NMSetting *s_wired = NULL; NMSetting *s_wifi = NULL; const char *iface, *address; struct ether_addr *tmp_mac; iface = g_udev_device_get_name (device); if (!iface) { PLUGIN_WARN ("SCPluginIfupdown", "failed to get ifname for device."); return; } address = g_udev_device_get_sysfs_attr (device, "address"); if (!address || !strlen (address)) { PLUGIN_WARN ("SCPluginIfupdown", "failed to get MAC address for %s", iface); return; } tmp_mac = ether_aton (address); if (!tmp_mac) { PLUGIN_WARN ("SCPluginIfupdown", "failed to parse MAC address '%s' for %s", address, iface); return; } mac_address = g_byte_array_sized_new (ETH_ALEN); g_byte_array_append (mac_address, &(tmp_mac->ether_addr_octet[0]), ETH_ALEN); s_wired = nm_connection_get_setting (NM_CONNECTION (exported), NM_TYPE_SETTING_WIRED); s_wifi = nm_connection_get_setting (NM_CONNECTION (exported), NM_TYPE_SETTING_WIRELESS); if (s_wired) { PLUGIN_PRINT ("SCPluginIfupdown", "locking wired connection setting"); g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac_address, NULL); } else if (s_wifi) { PLUGIN_PRINT ("SCPluginIfupdown", "locking wireless connection setting"); g_object_set (s_wifi, NM_SETTING_WIRELESS_MAC_ADDRESS, mac_address, NULL); } g_byte_array_free (mac_address, TRUE); nm_settings_connection_commit_changes (NM_SETTINGS_CONNECTION (exported), ignore_cb, NULL); }
/* Callback for nm_settings_connection_replace_and_commit. Report any errors * encountered when commiting connection settings updates. */ static void commit_cb (NMSettingsConnection *connection, GError *error, gpointer unused) { if (error) { PLUGIN_WARN (IFCFG_PLUGIN_NAME, " error updating: %s", (error && error->message) ? error->message : "(unknown)"); } }
static void bind_device_to_connection (SCPluginIfupdown *self, GUdevDevice *device, NMIfupdownConnection *exported) { GByteArray *mac_address; NMSettingWired *s_wired; NMSettingWireless *s_wifi; const char *iface, *address; iface = g_udev_device_get_name (device); if (!iface) { PLUGIN_WARN ("SCPluginIfupdown", "failed to get ifname for device."); return; } address = g_udev_device_get_sysfs_attr (device, "address"); if (!address || !strlen (address)) { PLUGIN_WARN ("SCPluginIfupdown", "failed to get MAC address for %s", iface); return; } mac_address = nm_utils_hwaddr_atoba (address, ARPHRD_ETHER); if (!mac_address) { PLUGIN_WARN ("SCPluginIfupdown", "failed to parse MAC address '%s' for %s", address, iface); return; } s_wired = nm_connection_get_setting_wired (NM_CONNECTION (exported)); s_wifi = nm_connection_get_setting_wireless (NM_CONNECTION (exported)); if (s_wired) { PLUGIN_PRINT ("SCPluginIfupdown", "locking wired connection setting"); g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac_address, NULL); } else if (s_wifi) { PLUGIN_PRINT ("SCPluginIfupdown", "locking wireless connection setting"); g_object_set (s_wifi, NM_SETTING_WIRELESS_MAC_ADDRESS, mac_address, NULL); } g_byte_array_free (mac_address, TRUE); nm_settings_connection_commit_changes (NM_SETTINGS_CONNECTION (exported), ignore_cb, NULL); }
static gboolean handle_as_path (GByteArray *array, NMSetting *setting, const char *key, const char *keyfile_path) { gsize validate_len = array->len; GByteArray *val; char *path; gboolean exists, success = FALSE; if (array->len > 500 || array->len < 1) return FALSE; /* If there's a trailing NULL tell g_utf8_validate() to to until the NULL */ if (array->data[array->len - 1] == '\0') validate_len = -1; if (g_utf8_validate ((const char *) array->data, validate_len, NULL) == FALSE) return FALSE; /* Might be a bare path without the file:// prefix; in that case * if it's an absolute path, use that, otherwise treat it as a * relative path to the current directory. */ path = get_cert_path (keyfile_path, array); exists = g_file_test (path, G_FILE_TEST_EXISTS); if ( exists || memchr (array->data, '/', array->len) || has_cert_ext (path)) { /* Construct the proper value as required for the PATH scheme */ val = g_byte_array_sized_new (strlen (SCHEME_PATH) + strlen (path) + 1); g_byte_array_append (val, (const guint8 *) SCHEME_PATH, strlen (SCHEME_PATH)); g_byte_array_append (val, (const guint8 *) path, strlen (path)); g_byte_array_append (val, (const guint8 *) "\0", 1); g_object_set (setting, key, val, NULL); g_byte_array_free (val, TRUE); success = TRUE; /* Warn if the certificate didn't exist */ if (exists == FALSE) PLUGIN_WARN (KEYFILE_PLUGIN_NAME, " certificate or key %s does not exist", path); } g_free (path); return success; }
static void update_old_connection (gchar * conn_name, NMIfnetConnection * old_conn, NMIfnetConnection * new_conn, SCPluginIfnetPrivate * priv) { GError **error = NULL; if (!nm_sysconfig_connection_update (NM_SYSCONFIG_CONNECTION (old_conn), NM_CONNECTION (new_conn), TRUE, error)) { PLUGIN_WARN (IFNET_PLUGIN_NAME, "error updating: %s", (error && (*error)) ? (*error)->message : "(unknown)"); } else PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Connection %s updated", conn_name); g_object_unref (new_conn); }
static void write_system_hostname (NMSystemConfigInterface * config, const gchar * newhostname) { SCPluginIfnetPrivate *priv = SC_PLUGIN_IFNET_GET_PRIVATE (config); g_return_if_fail (newhostname); PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Write system hostname: %s", newhostname); if (write_hostname (newhostname, IFNET_SYSTEM_HOSTNAME_FILE)) { if (priv->hostname) g_free (priv->hostname); priv->hostname = g_strdup (newhostname); g_object_notify (G_OBJECT (config), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME); } else PLUGIN_WARN (IFNET_PLUGIN_NAME, "Write system hostname: %s failed", newhostname); }
static void read_connections (NMSystemConfigInterface *config) { SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (config); GDir *dir; GError *error = NULL; const char *item; dir = g_dir_open (KEYFILE_DIR, 0, &error); if (!dir) { PLUGIN_WARN (KEYFILE_PLUGIN_NAME, "Cannot read directory '%s': (%d) %s", KEYFILE_DIR, error ? error->code : -1, error && error->message ? error->message : "(unknown)"); g_clear_error (&error); return; } while ((item = g_dir_read_name (dir))) { NMSettingsConnection *connection; char *full_path; if (nm_keyfile_plugin_utils_should_ignore_file (item)) continue; full_path = g_build_filename (KEYFILE_DIR, item, NULL); PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "parsing %s ... ", item); connection = _internal_new_connection (self, full_path, NULL, &error); if (connection) { PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, " read connection '%s'", nm_connection_get_id (NM_CONNECTION (connection))); } else { PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, " error: %s", (error && error->message) ? error->message : "(unknown)"); } g_clear_error (&error); g_free (full_path); } g_dir_close (dir); }
static ip6_block * create_ip6_block (gchar * ip) { ip6_block *iblock = g_slice_new0 (ip6_block); gchar *dup_ip = g_strdup (ip); struct in6_addr *tmp_ip6_addr = g_slice_new0 (struct in6_addr); gchar *prefix = NULL; if ((prefix = strstr (dup_ip, "/")) != NULL) { *prefix = '\0'; prefix++; } if (!inet_pton (AF_INET6, dup_ip, tmp_ip6_addr)) { goto error; } iblock->ip = tmp_ip6_addr; if (prefix) { errno = 0; iblock->prefix = strtol (prefix, NULL, 10); if (errno || iblock->prefix <= 0 || iblock->prefix > 128) { goto error; } } else iblock->prefix = 64; g_free (dup_ip); return iblock; error: if (!is_ip4_address (ip)) PLUGIN_WARN (IFNET_PLUGIN_NAME, "Can't handle IPv6 address: %s", ip); g_slice_free (ip6_block, iblock); g_slice_free (struct in6_addr, tmp_ip6_addr); g_free (dup_ip); return NULL; }
static void SCPluginIfupdown_init (NMSystemConfigInterface *config) { SCPluginIfupdown *self = SC_PLUGIN_IFUPDOWN (config); SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (self); GHashTable *auto_ifaces; if_block *block = NULL; NMInotifyHelper *inotify_helper; GKeyFile* keyfile; GError *error = NULL; GList *keys, *iter; const char *subsys[2] = { "net", NULL }; auto_ifaces = g_hash_table_new (g_str_hash, g_str_equal); if(!priv->iface_connections) priv->iface_connections = g_hash_table_new (g_str_hash, g_str_equal); if(!priv->well_known_ifaces) priv->well_known_ifaces = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); if(!priv->well_known_interfaces) priv->well_known_interfaces = g_hash_table_new (g_str_hash, g_str_equal); PLUGIN_PRINT("SCPlugin-Ifupdown", "init!"); priv->client = g_udev_client_new (subsys); if (!priv->client) { PLUGIN_WARN ("SCPlugin-Ifupdown", " error initializing libgudev"); } else g_signal_connect (priv->client, "uevent", G_CALLBACK (handle_uevent), self); priv->unmanage_well_known = IFUPDOWN_UNMANAGE_WELL_KNOWN_DEFAULT; inotify_helper = nm_inotify_helper_get (); priv->inotify_event_id = g_signal_connect (inotify_helper, "event", G_CALLBACK (update_system_hostname), config); priv->inotify_system_hostname_wd = nm_inotify_helper_add_watch (inotify_helper, IFUPDOWN_SYSTEM_HOSTNAME_FILE); update_system_hostname (inotify_helper, NULL, NULL, config); /* Read in all the interfaces */ ifparser_init (ENI_INTERFACES_FILE, 0); block = ifparser_getfirst (); while (block) { if(!strcmp ("auto", block->type) || !strcmp ("allow-hotplug", block->type)) g_hash_table_insert (auto_ifaces, block->name, GUINT_TO_POINTER (1)); else if (!strcmp ("iface", block->type)) { NMIfupdownConnection *exported; /* Bridge configuration */ if(!strncmp ("br", block->name, 2)) { /* Try to find bridge ports */ const char *ports = ifparser_getkey (block, "bridge-ports"); if (ports) { int i; int state = 0; char **port_ifaces; PLUGIN_PRINT("SCPlugin-Ifupdown", "found bridge ports %s for %s", ports, block->name); port_ifaces = g_strsplit_set (ports, " \t", -1); for (i = 0; i < g_strv_length (port_ifaces); i++) { char *token = port_ifaces[i]; /* Skip crazy stuff like regex or all */ if (!strcmp ("all", token)) { continue; } /* Small SM to skip everything inside regex */ if (!strcmp ("regex", token)) { state++; continue; } if (!strcmp ("noregex", token)) { state--; continue; } if (state == 0 && strlen (token) > 0) { PLUGIN_PRINT("SCPlugin-Ifupdown", "adding bridge port %s to well_known_interfaces", token); g_hash_table_insert (priv->well_known_interfaces, g_strdup (token), "known"); } } g_strfreev (port_ifaces); } goto next; } /* Skip loopback configuration */ if(!strcmp ("lo", block->name)) { goto next; } /* Remove any connection for this block that was previously found */ exported = g_hash_table_lookup (priv->iface_connections, block->name); if (exported) { PLUGIN_PRINT("SCPlugin-Ifupdown", "deleting %s from iface_connections", block->name); nm_settings_connection_delete (NM_SETTINGS_CONNECTION (exported), ignore_cb, NULL); g_hash_table_remove (priv->iface_connections, block->name); } /* add the new connection */ exported = nm_ifupdown_connection_new (block); if (exported) { PLUGIN_PRINT("SCPlugin-Ifupdown", "adding %s to iface_connections", block->name); g_hash_table_insert (priv->iface_connections, block->name, exported); } PLUGIN_PRINT("SCPlugin-Ifupdown", "adding iface %s to well_known_interfaces", block->name); g_hash_table_insert (priv->well_known_interfaces, block->name, "known"); } else if (!strcmp ("mapping", block->type)) { g_hash_table_insert (priv->well_known_interfaces, block->name, "known"); PLUGIN_PRINT("SCPlugin-Ifupdown", "adding mapping %s to well_known_interfaces", block->name); } next: block = block->next; } /* Make 'auto' interfaces autoconnect=TRUE */ keys = g_hash_table_get_keys (priv->iface_connections); for (iter = keys; iter; iter = g_list_next (iter)) { NMIfupdownConnection *exported; NMSetting *setting; if (!g_hash_table_lookup (auto_ifaces, iter->data)) continue; exported = g_hash_table_lookup (priv->iface_connections, iter->data); setting = NM_SETTING (nm_connection_get_setting (NM_CONNECTION (exported), NM_TYPE_SETTING_CONNECTION)); g_object_set (setting, NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NULL); nm_settings_connection_commit_changes (NM_SETTINGS_CONNECTION (exported), ignore_cb, NULL); PLUGIN_PRINT("SCPlugin-Ifupdown", "autoconnect"); } g_list_free (keys); g_hash_table_destroy (auto_ifaces); /* Find the config file */ if (g_file_test (IFUPDOWN_SYSTEM_SETTINGS_KEY_FILE, G_FILE_TEST_EXISTS)) priv->conf_file = IFUPDOWN_SYSTEM_SETTINGS_KEY_FILE; else priv->conf_file = IFUPDOWN_OLD_SYSTEM_SETTINGS_KEY_FILE; keyfile = g_key_file_new (); if (!g_key_file_load_from_file (keyfile, priv->conf_file, G_KEY_FILE_NONE, &error)) { nm_log_info (LOGD_SETTINGS, "loading system config file (%s) caused error: (%d) %s", priv->conf_file, error ? error->code : -1, error && error->message ? error->message : "(unknown)"); } else { gboolean manage_well_known; error = NULL; manage_well_known = g_key_file_get_boolean (keyfile, IFUPDOWN_KEY_FILE_GROUP, IFUPDOWN_KEY_FILE_KEY_MANAGED, &error); if (error) { nm_log_info (LOGD_SETTINGS, "getting keyfile key '%s' in group '%s' failed: (%d) %s", IFUPDOWN_KEY_FILE_GROUP, IFUPDOWN_KEY_FILE_KEY_MANAGED, error ? error->code : -1, error && error->message ? error->message : "(unknown)"); } else priv->unmanage_well_known = !manage_well_known; } PLUGIN_PRINT ("SCPluginIfupdown", "management mode: %s", priv->unmanage_well_known ? "unmanaged" : "managed"); if (keyfile) g_key_file_free (keyfile); /* Add well-known interfaces */ keys = g_udev_client_query_by_subsystem (priv->client, "net"); for (iter = keys; iter; iter = g_list_next (iter)) { udev_device_added (self, G_UDEV_DEVICE (iter->data)); g_object_unref (G_UDEV_DEVICE (iter->data)); } g_list_free (keys); /* Now if we're running in managed mode, let NM know there are new connections */ if (!priv->unmanage_well_known) { GList *con_list = g_hash_table_get_values (priv->iface_connections); GList *cl_iter; for (cl_iter = con_list; cl_iter; cl_iter = g_list_next (cl_iter)) { g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, NM_SETTINGS_CONNECTION (cl_iter->data)); } g_list_free (con_list); } PLUGIN_PRINT("SCPlugin-Ifupdown", "end _init."); }
bool GatePlugin::OnStartup(const char *config, streamsize nbytes) { if(!RegisterCommand(&m_list_cmd) || !RegisterCommand(&m_disconnect_cmd) || !RegisterCommand(&m_logout_cmd)) { return false; } if(!config || nbytes == 0) { PLUGIN_ERROR("no config"); return false; } tinyxml2::XMLDocument doc; tinyxml2::XMLError err = doc.Parse(config, nbytes); if(err != tinyxml2::XML_SUCCESS) { PLUGIN_ERROR("problem parsing config: %s(%d)", doc.ErrorName(), err); return false; } u16 port = 0; u32 max_connections = 0; std::string redis_hostname("localhost"); u16 redis_port = 6379; { tinyxml2::XMLElement *root = doc.RootElement(); if(root->Attribute("port")) { port = root->IntAttribute("port"); PLUGIN_INFO("port read %d", port); } else { PLUGIN_WARN("no port specified, defaulting to 0"); } if(!root->Attribute("max_connections")) { PLUGIN_ERROR("maximum connection count not specified"); return false; } max_connections = root->IntAttribute("max_connections"); PLUGIN_INFO("maximum number of connections: %d", max_connections); if(max_connections == 0) { PLUGIN_ERROR("invalid number of max connections: %d", max_connections); return false; } tinyxml2::XMLElement *redis = root->FirstChildElement("redis"); if(redis && redis->Attribute("hostname") && redis->Attribute("port")) { redis_hostname = redis->Attribute("hostname"); redis_port = redis->IntAttribute("port"); } else { PLUGIN_WARN("failed to load redis config"); } } m_users = new Users(max_connections); if(m_users == nullptr) { PLUGIN_ERROR("problem creating users data"); return false; } TCPServer::Callbacks callbacks = {Link::Gate::OnConnected, Link::Gate::OnDisconnected, Link::Gate::OnMessage}; m_conn = new TCPServer(max_connections, callbacks, this); if(!m_conn->CreateListenSocket(port)) { delete m_conn; PLUGIN_ERROR("failed to create listen port"); return false; } PLUGIN_INFO("gate listening on port: %d", port); RedisConnectBlocking(redis_hostname.c_str(), redis_port); return true; }
int PluginLoop(void *) { PLUGIN_INFO("thread started"); g_plugin->OnThreadEntry(); unsigned int last_time = Base::Time::GetTimeMs(); while(g_running) { Notification notif; if(GetNotification(¬if, g_plugin->IdleDt())) { // PLUGIN_INFO("notification received: %d.", notif.type); g_plugin->OnNotification(notif); switch(notif.type) { case kShutdown: g_plugin->OnShutdown(notif.content.shutdown); g_running = false; break; case kWatch: { PluginInfo info; if(0 == GetPluginInfo(notif.content.watch.plugin, &info)) { PLUGIN_INFO("watch plugin match %s(%s) for %p", info.name, info.version, notif.content.watch.handle); } else { PLUGIN_WARN("unknown plugin match for %p", notif.content.connection.endpoint); } g_plugin->OnWatchMatch(notif.content.watch); break; } case kConfigChanged: g_plugin->OnConfigChange(notif.content.config); break; case kEstablished: { PluginInfo info; if(0 == GetPluginInfo(notif.content.connection.endpoint, &info)) { PLUGIN_INFO("connected to %s(%s)", info.name, info.version); } else { PLUGIN_WARN("connected to unknown plugin %p", notif.content.connection.endpoint); } g_plugin->OnConnected(notif.content.connection); break; } case kConnected: { PluginInfo info; if(0 == GetPluginInfo(notif.content.connection.endpoint, &info)) { PLUGIN_INFO("plugin connected %s(%s)", info.name, info.version); } else { PLUGIN_WARN("unknown plugin connected %p", notif.content.connection.endpoint); } g_plugin->OnPluginConnected(notif.content.connection); break; } case kDisconnected: PluginInfo info; if(0 == GetPluginInfo(notif.content.connection.endpoint, &info)) { PLUGIN_INFO("plugin disconnected %s(%s)", info.name, info.version); } else { PLUGIN_WARN("unknown plugin disconnected %p", notif.content.connection.endpoint); } g_plugin->OnDisconnected(notif.content.connection); break; case kRecvReady: g_plugin->OnRecvReady(notif.content.connection); default: break; } } unsigned int now = Base::Time::GetTimeMs(); unsigned int dt = now - last_time; g_plugin->OnUpdate(dt); last_time = now; } g_plugin->OnThreadExit(); PLUGIN_INFO("thread exiting"); return 0; }