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;
}
Esempio n. 5
0
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);
    }
}
Esempio n. 6
0
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);
}    
Esempio n. 7
0
/* 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)");
    }
}
Esempio n. 8
0
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);
}    
Esempio n. 9
0
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);
}
Esempio n. 12
0
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;
}
Esempio n. 14
0
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.");
}
Esempio n. 15
0
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;
}
Esempio n. 16
0
int PluginLoop(void *) {
  PLUGIN_INFO("thread started");
  g_plugin->OnThreadEntry();

  unsigned int last_time = Base::Time::GetTimeMs();
  while(g_running) {
    Notification notif;
    if(GetNotification(&notif, 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;
}