Ejemplo n.º 1
0
char * __mod_ssl_sni_common_handler (MyQttCtx   * myqtt_ctx,
				     MyQttConn  * conn,
				     const char * serverName,
				     axlPointer   user_data,
				     const char * attr_name)
{
	MyQttdCtx * ctx = user_data;
	axlNode   * node;

	/* find certificate node by Name */
	node = __mod_ssl_get_certificate_node_by_name (ctx, serverName);
	if (! node) {
		wrn ("No certificate was found for serverName=%s, requested by connecting ip=%s",
		     serverName, myqtt_conn_get_host_ip (conn));
		return NULL; /* no node certificate was found, finish
			      * here */
	} /* end if */

	if (! HAS_ATTR (node, attr_name)) {
		wrn ("No certificate was found for serverName=%s, requested by connecting ip=%s, node %s attribute was not defined",
		     serverName, myqtt_conn_get_host_ip (conn), attr_name);
		return NULL; /* no crt attr was found, finish here */
	} /* end if */

	/* ok, now report certificate location */
	if (__mod_ssl_debug)
		msg ("Reporting certificate %s=%s for serverName=%s", attr_name, ATTR_VALUE (node, attr_name), serverName);

	/* report certificate */
	return axl_strdup (ATTR_VALUE (node, attr_name));
}
Ejemplo n.º 2
0
void CClientInfo::Config(const string& fileName)
{
	ifstream inFile(fileName.c_str(), ifstream::in);
	string inXml, inLine;
	while (getline(inFile, inLine))
		inXml += inLine;
	XmlVec confData(inXml.begin(), inXml.end());
	confData.push_back('\0');
	XmlDoc xmlDoc;
	try {
		xmlDoc.parse<0>(&confData[0]);
	} catch (...) {
		LOG("ERROR: failed to load the server config file.");
		return;
	}

	XmlNodePtr pNode = NULL;
	if ((pNode = xmlDoc.first_node("server_list"))) {
		XmlNodePtr pItem = pNode->first_node("server");
		while (pItem) {
			int    pId   = HAS_ATTR(pItem, "id")   ? atoi(ATTR_VALUE(pItem, "id")) : -1;
			string ipStr = HAS_ATTR(pItem, "ip")   ? ATTR_VALUE(pItem, "ip") : "127.0.0.1";
			int    port  = HAS_ATTR(pItem, "port") ? atoi(ATTR_VALUE(pItem, "port")) : 12345;
			m_svrMap[pId] = pair<string, int>(ipStr, port);
			pItem = pItem->next_sibling("server");
		}
	}
	if ((pNode = xmlDoc.first_node("parameters"))) {
		m_connNum = HAS_NODE(pNode, "conn_num") ? atoi(NODE_VALUE(pNode, "conn_num")) : 1;
		m_fixRate = HAS_NODE(pNode, "fix_rate") ? atoi(NODE_VALUE(pNode, "fix_rate")) : 0;
		m_initTimeout = HAS_NODE(pNode, "init_timeout") ? atoi(NODE_VALUE(pNode, "init_timeout")) : 20;
		m_videoLen = HAS_NODE(pNode, "video_len") ? atoi(NODE_VALUE(pNode, "video_len")) : 278;
		m_initBufferSize = HAS_NODE(pNode, "init_buffer_size") ? atoi(NODE_VALUE(pNode, "init_buffer_size")) : 10;
	}
	LOG("--------------------------------------------------");
	svrMap_t::const_iterator cIt = m_svrMap.begin();
	for (; cIt != m_svrMap.end(); ++cIt) {
		LOG("|server: id=%d, %s:%d.", (*cIt).first, (*cIt).second.first.c_str(), (*cIt).second.second);
	}
	LOG("|number of connections: %d.", m_connNum);
	LOG("|video length: %d.", m_videoLen);
	LOG("|fix rate: %d.", m_fixRate);
	LOG("|init buffer timeout: %d.", m_initTimeout);
	LOG("|init buffer size: %d.", m_initBufferSize);
	LOG("--------------------------------------------------");
	xmlDoc.clear();

	m_rateVec.push_back(350);
    m_rateVec.push_back(470);
    m_rateVec.push_back(630);
    m_rateVec.push_back(845);
    m_rateVec.push_back(1130);
    m_rateVec.push_back(1520);
    m_rateVec.push_back(2040);


}
Ejemplo n.º 3
0
/** 
 * @brief Allows to send a SMTP message using the configuration found
 * on the provided smtp_conf declaration. This smtp_conf declaration
 * is found at the turbulence configuration file. See \ref
 * turbulence_smtp_notifications
 *
 * @param ctx The turbulence context where the operation will be
 * implemented.
 *
 * @param smtp_conf_id The string identifying the smtp configuration (id
 * declaration inside <smtp-server> node) or NULL. If NULL is used,
 * then the first smtp server with is-default=yes declared is used.
 *
 * @param subject Optional subject to be configured on mail body
 * message.
 * 
 * @param body The message body to be configured. If NULL is provided
 * no body will be sent.
 *
 * @param body_file Optional reference to a file that contains the
 * body of the message.
 *
 * @return axl_true if the mail message was submited or axl_false if
 * something failed.
 */
axl_bool        turbulence_support_simple_smtp_send (TurbulenceCtx * ctx,
						     const char    * smtp_conf_id,
						     const char    * subject,
						     const char    * body,
						     const char    * body_file)
{
	axlNode * node;
	axlNode * default_node;

	if (ctx == NULL)
		return axl_false;

	/* find smtp mail notification conf */
	node         = axl_doc_get (turbulence_config_get (ctx), "/turbulence/global-settings/notify-failures/smtp-server");
	default_node = NULL;
	while (node) {
		/* check for declaration with the smtp conf requested */
		if (HAS_ATTR_VALUE (node, "id", smtp_conf_id))
			break;

		/* check for default node declaration */
		if (HAS_ATTR_VALUE (node, "is-default", "yes") && default_node == NULL)
			default_node = node;

		/* node not found, go next */
		node = axl_node_get_next_called (node, "smtp-server");
	} /* end while */

	/* set to default node found (if any) when node is null */
	if (node == NULL)
		node = default_node;

	/* check if the smtp configuration was found */
	if (node == NULL) {
		error ("Failed to send mail notification, unable to find default smtp configuration or smtp configuration associated to id '%s'",
		       smtp_conf_id ? smtp_conf_id : "NULL");
		return axl_false;
	}
	
	/* now use SMTP send values */
	return turbulence_support_smtp_send (ctx, ATTR_VALUE (node, "mail-from"), 
					     ATTR_VALUE (node, "mail-to"), subject, body, body_file, 
					     ATTR_VALUE (node, "server"), ATTR_VALUE (node, "port"));
}
Ejemplo n.º 4
0
MyQttConn * __mod_ssl_start_listener (MyQttdCtx * ctx, MyQttCtx * my_ctx, axlNode * port_node, 
				      const char * bind_addr, const char * port, axlPointer user_data)
{
	MyQttConn   * listener;
	axlNode     * node;
	const char  * crt, * key, * chain;

	/* create listener on the port indicated */
	listener = myqtt_tls_listener_new (
		 /* the context where the listener will
		  * be started */
		  my_ctx,
		  /* listener name */
		  bind_addr ? bind_addr : "0.0.0.0",
		  /* port to use */
		  port,
		  /* opts */
		  NULL,
		  /* on ready callbacks */
		  NULL, NULL);

	/* configure default certificates from store */
	node = __mod_ssl_get_default_certificate (ctx, my_ctx);
	if (node) {
		/* configure certificates */
		crt   = ATTR_VALUE (node, "crt");
		key   = ATTR_VALUE (node, "key");
		chain = ATTR_VALUE (node, "chain");
		msg ("mod-ssl: configuring default crt=%s, key=%s, chain=%s", crt, key, chain);
		     
		if (! myqtt_tls_set_certificate (listener, crt, key, chain)) {
			error ("unable to configure certificates for TLS mqtt (myqtt_tls_set_certificate failed)..");
			return NULL;
		} /* end if */
	} else {
		wrn ("Unable to configure any certificate. No default certificate was found. __mod_ssl_get_default_certificate() reported NULL");
	} /* end if */

	return listener; /* basic configuration done */
}
Ejemplo n.º 5
0
/** 
 * @internal Init function, perform all the necessary code to register
 * profiles, configure Vortex, and any other init task. The function
 * must return true to signal that the module was properly initialized
 * Otherwise, false must be returned.
 */
static int  slm_init (ValvuladCtx * _ctx)
{
	axlNode    * node;
	const char * mode;

	/* configure the module */
	ctx = _ctx;

	msg ("Valvulad slm module: init");
	
	/* get node */
	node = axl_doc_get (_ctx->config, "/valvula/enviroment/sender-login-mismatch");
	mode = ATTR_VALUE (node, "mode");

	/* configure module */
	if (axl_cmp (mode, "full"))
		__slm_mode = VALVULA_MOD_SLM_FULL;
	else if (axl_cmp (mode, "same-domain"))
		__slm_mode = VALVULA_MOD_SLM_SAME_DOMAIN;
	else if (axl_cmp (mode, "valid-mail-from"))
		__slm_mode = VALVULA_MOD_SLM_VALID_MAIL_FROM;
	else if (axl_cmp (mode, "disabled"))
		__slm_mode = VALVULA_MOD_SLM_DISABLED;

	/* get allow empty mail from */
	if (HAS_ATTR_VALUE (node, "allow-empty-mail-from", "no")) 
		__slm_allow_empty_mail_from = axl_false;

	/* ensure tables */
	if (! valvulad_db_ensure_table (ctx, "slm_exception",
					/* attributes */
					"id", "autoincrement int", 
					"is_active", "int",  
					"description", "text",  
					"mail_from", "text", 
					"sasl_username", "text", NULL)) {
		printf ("ERROR: unable to create slm_exception table..\n");
		return axl_false;
	} /* end if */

	return axl_true;
}
Ejemplo n.º 6
0
axlNode *  __mod_ssl_get_certificate_node_by_name (MyQttdCtx * ctx, const char * serverName)
{
	axlNode * node;

	node = axl_doc_get (mod_ssl_conf, "/mod-ssl/certificates/cert");
	if (node == NULL)
		return NULL;
	while (node) {
		if (axl_cmp (serverName, ATTR_VALUE (node, "serverName"))) {
			/* node found, report it */
			return node;
		} /* end if */

		/* get next <cert> node */
		node = axl_node_get_next_called (node, "cert");
	} /* end while */

	/* reached this point no certificate was found, so report NULL */
	return NULL;
}
Ejemplo n.º 7
0
axl_bool mod_sasl_mysql_load_auth_db (TurbulenceCtx     * ctx,
				      SaslAuthBackend   * sasl_backend,
				      axlNode           * auth_db_node_conf,
				      axlError         ** err)
{
	MYSQL      * conn;
	const char * location;
	char       * basedir = NULL;
	axlDoc     * doc;
	axlError   * local_err = NULL;

	/* check if location is defined */
	if (! HAS_ATTR (auth_db_node_conf, "location")) {
		axl_error_report (err, -1, "Unable to open auth mysql database, 'location' attribute is not defined");
		return axl_false;
	} /* end if */

	/* find the node that holds the connection configuration */
	location = ATTR_VALUE (auth_db_node_conf, "location");

	/* check if the location is relative or not */
	if (! turbulence_file_is_fullpath (location)) {
		/* get base dir of the sasl.conf that represents this
		   backend */
		basedir  = turbulence_base_dir (common_sasl_get_file_path (sasl_backend));

		/* now build a new path */
		location = axl_strdup_printf ("%s%s%s", basedir, VORTEX_FILE_SEPARATOR, location);
		msg ("Found relative file to auth mysql db settings, resolved to: %s", location);
	} /* end if */

	/* now load the file */
	doc      = axl_doc_parse_from_file (location, &local_err);
	/* check for error and report */
	if (doc == NULL) {
		axl_error_report (err, -1, "Failed to open auth mysql db at %s error was %s", location, axl_error_get (local_err));
		axl_error_free (local_err);
	} /* end if */

	/* dealloc some variables */
	if (basedir) {
		axl_free (basedir);
		axl_free ((char *) location);
	} /* end if */

	/* return if error */
	if (doc == NULL) {
		return axl_false;
	} /* end if */

	/* do DTD validation */
        if (! axl_dtd_validate (doc, mysql_sasl_dtd, &local_err)) {
		axl_error_report (err, -1, "Failed to open auth mysql db at %s, found DTD error %s", location, axl_error_get (local_err));
		axl_error_free (local_err);
		axl_doc_free (doc);
		return axl_false;
	} /* end if */

	/* link the document to this node so we can reuse it later */
	axl_node_annotate_data_full (auth_db_node_conf, "mysql-conf", NULL, doc, (axlDestroyFunc) axl_doc_free);

	/* request to load msyql database */
	conn = mod_sasl_mysql_get_connection (ctx, auth_db_node_conf, err);
	if (conn == NULL) 
		return axl_false;

	msg ("load database ok");

	/* connection ok, this means we have loaded the database */
	return axl_true;
}
Ejemplo n.º 8
0
axl_bool mod_sasl_mysql_do_auth (TurbulenceCtx    * ctx, 
				 VortexConnection * conn,
				 axlNode          * auth_db_node_conf,
				 const char       * auth_id,
				 const char       * authorization_id,
				 const char       * formated_password,
				 const char       * password,
				 const char       * serverName,
				 const char       * sasl_method,
				 axlError        ** err)
{
	char        * query; 
	axlDoc      * doc;
	axlNode     * node;
	axl_bool      _result = axl_false;

	/* check import parameters without doing anything */
	if (! mod_sasl_mysql_check_unallowed_sequence (ctx, conn, auth_id))
		return axl_false;
	if (! mod_sasl_mysql_check_unallowed_sequence (ctx, conn, password))
		return axl_false;
	if (! mod_sasl_mysql_check_unallowed_sequence (ctx, conn, formated_password))
		return axl_false;
	if (! mod_sasl_mysql_check_unallowed_sequence (ctx, conn, serverName))
		return axl_false;
	if (! mod_sasl_mysql_check_unallowed_sequence (ctx, conn, authorization_id))
		return axl_false;
	if (! mod_sasl_mysql_check_unallowed_sequence (ctx, conn, sasl_method))
		return axl_false;
	if (! mod_sasl_mysql_check_unallowed_sequence (ctx, conn, auth_id))
		return axl_false;
	if (! mod_sasl_mysql_check_unallowed_sequence (ctx, conn, vortex_connection_get_host (conn)))
		return axl_false;

	/* get the auth query */
	doc  = axl_node_annotate_get (auth_db_node_conf, "mysql-conf", axl_false);
	if (doc == NULL) {
		axl_error_report (err, -1, "Found no xml document defining MySQL settings to connect to the database");
		return axl_false;
	} /* end if */

	/* check for ip filter reference */
	node  = axl_doc_get (doc, "/sasl-auth-db/ip-filter");
	if (node && HAS_ATTR (node, "query")) {
		/* ip filter defined, get query */
		query = axl_strdup (ATTR_VALUE (node, "query"));

		/* replace query with recognized tokens */
		axl_replace (query, "%u", auth_id);
		axl_replace (query, "%n", serverName);
		axl_replace (query, "%i", authorization_id);
		axl_replace (query, "%m", sasl_method);

		msg ("Checking IP filter for auth id [%s], query [%s]", auth_id, query);
		
		if (! mod_sasl_mysql_check_ip_filter_query (ctx, query, conn, auth_db_node_conf)) {
			error ("login failure: %s, ip filtered by defined expression associated to user: %s denied connection from %s", 
			       auth_id, auth_id, vortex_connection_get_host_ip (conn));
			axl_free (query);
			return 0;
		}
		msg ("IP not filtered by defined expression associated to user: %s allowed connection from %s", 
		       auth_id, vortex_connection_get_host_ip (conn));
		
		/* ip not filtered, now let the auth continue */
		axl_free (query);
	} /* end if */

	/***** ALT AUTHENTICATION *****/
	/* get alt password if defined <get-password-alt> */
	node =  axl_doc_get (doc, "/sasl-auth-db/get-password-alt");
	if (node) {
		/* get query */
		query = (char *) ATTR_VALUE_TRANS (node, "query");

		/* call to do auth operation */
		_result = __mod_sasl_mysql_prepare_query_and_auth (ctx, query, conn, auth_db_node_conf, auth_id, authorization_id,
								   formated_password, password,
								   serverName, sasl_method, axl_false, 
								   /* skip login error reporting */ axl_true, err);		

		/* clean for cleanup node <get-password-alt-cleanup> */
		node =  axl_doc_get (doc, "/sasl-auth-db/get-password-alt-cleanup");
		if (node) {
			/* get query */
			query = (char *) ATTR_VALUE_TRANS (node, "query");

			/* call and skip getting value reported */
			if (! __mod_sasl_mysql_prepare_query_and_auth (ctx, query, conn, auth_db_node_conf, auth_id, authorization_id,
								       formated_password, password,
								       serverName, sasl_method, axl_true, 
								       /* skip login error reporting */ axl_true, err))
				error ("Cleanup query failed, please, review <get-password-alt-cleanup>..");
			
		} /* end if */
	} /* end if */

	/**** MAIN AUTHENTICATION ****/
	/* if authentication failed, try with main table */
	if (! _result) {
		/* get the node that contains the configuration */
		node  = axl_doc_get (doc, "/sasl-auth-db/get-password");
		query = (char *) ATTR_VALUE (node, "query");

		/* call to do auth operation */
		_result = __mod_sasl_mysql_prepare_query_and_auth (ctx, query, conn, auth_db_node_conf, auth_id, authorization_id,
								   formated_password, password,
								   serverName, sasl_method, axl_false, 
								   /* skip login error reporting */ axl_false, err);
	} /* end if */
	
	/* now check for auth-log declaration to report it */
	node = axl_doc_get (doc, "/sasl-auth-db/auth-log");
	if (node) {
		/* log auth defined */
		query = axl_strdup (ATTR_VALUE (node, "query"));
	
		/* replace query with recognized tokens */
		axl_replace (query, "%t", _result ? "ok" : "failed");
		axl_replace (query, "%u", auth_id);
		axl_replace (query, "%n", serverName);
		axl_replace (query, "%i", authorization_id);
		axl_replace (query, "%m", sasl_method);
		axl_replace (query, "%p", vortex_connection_get_host (conn));
		
		msg ("Trying to auth-log %s:%s with query string %s", auth_id, _result ? "ok" : "failed", query);
		/* exec query */
		if (! mod_sasl_mysql_do_query (ctx, auth_db_node_conf, query, axl_true, err)) {
			error ("Unable to auth-log, failed query configured, error was: %d:%s",
			       axl_error_get_code (*err), axl_error_get (*err));
			axl_error_free (*err);
		}
		axl_free (query);
		
	} /* end if */

	if (!_result)
		error ("login failure: %s, failed from: %s", auth_id, vortex_connection_get_host_ip (conn));
	
	return _result ? 1 : 0;
}
Ejemplo n.º 9
0
/** 
 * @internal Function that creates a connection to the MySQL database
 * configured on the xml node.
 */ 
MYSQL * mod_sasl_mysql_get_connection (TurbulenceCtx  * ctx,
				       axlNode        * auth_db_node_conf, 
				       axlError      ** err)
{
	MYSQL   * conn;
	int       port = 0;
	int       reconnect = 1;
	axlDoc  * doc;
	axlNode * node;

	if (ctx == NULL || auth_db_node_conf == NULL) {
		axl_error_report (err, -1, "Received null ctx, auth db node or sql query, failed to run SQL command");
		return NULL;
	} /* end if */

	/* check if the connection is already defined */
	conn = axl_node_annotate_get (auth_db_node_conf, "mysql-conn", axl_false);
	if (conn) {
		/* reuse connection */
		return conn;
	} /* end if */

	/* get document containing MySQL settings */
	doc  = axl_node_annotate_get (auth_db_node_conf, "mysql-conf", axl_false);
	if (doc == NULL) {
		axl_error_report (err, -1, "Found no xml document defining MySQL settings to connect to the database");
		return NULL;
	} /* end if */

	/* get the node that contains the configuration */
	node = axl_doc_get (doc, "/sasl-auth-db/connection-settings");

	/* create a mysql connection */
	conn = mysql_init (NULL);

	/* get port */
	if (HAS_ATTR (node, "port") && strlen (ATTR_VALUE (node, "port")) > 0) {
		/* get port configured by the user */
		port = atoi (ATTR_VALUE (node, "port"));
	}
	
	/* create a connection */
	if (mysql_real_connect (conn, 
				/* get host */
				ATTR_VALUE (node, "host"), 
				/* get user */
				ATTR_VALUE (node, "user"), 
				/* get password */
				ATTR_VALUE (node, "password"), 
				/* get database */
				ATTR_VALUE (node, "database"), 
				port, NULL, 0) == NULL) {
		axl_error_report (err, mysql_errno (conn), "Mysql connect error: %s, failed to run SQL command", mysql_error (conn));
		return NULL;
	} /* end if */

	/* flag here to reconnect in case of lost connection */
	mysql_options (conn, MYSQL_OPT_RECONNECT, (const char *) &reconnect);

	/* record connection */
	axl_node_annotate_data_full (auth_db_node_conf, "mysql-conn", NULL, conn, (axlDestroyFunc) mysql_close);

	return conn;
}
Ejemplo n.º 10
0
/**
 * @internal Places current process identifier into the file provided
 * by the user.
 */
void valvulad_place_pidfile (ValvuladCtx * ctx)
{
	FILE    * pid_file = NULL;
	int       pid      = getpid ();
	char      buffer[20];
	int       size;
	axlNode * node;
	int       gid, uid;

	/* check if pid file exists */
	if  (! exarg_is_defined ("skip-pid-check")) {
		if (valvula_support_file_test (pid_file_path, FILE_EXISTS)) {
			abort_error ("Unable to start server, found pid file in place %s. There is a valvula server running. If not, remove file %s",
				     pid_file_path, pid_file_path);
			exit (-1);
			return;
		} /* end if */ 
	} else {
		wrn ("Skipping pid file checking..");
	} /* end if */

	/* open pid file or create it to place the pid file */
	pid_file = fopen (pid_file_path, "w");
	if (pid_file == NULL) {
		abort_error ("Unable to open pid file at: %s", pid_file_path);
		return;
	} /* end if */
	
	/* stringfy pid */
	size = axl_stream_printf_buffer (buffer, 20, NULL, "%d", pid);
	msg ("signaling PID %d at %s", pid, pid_file_path);
	if (fwrite (buffer, size, 1, pid_file) <= 0) {
	        abort_error ("Unable to write pid file content at %s, error was: errno=%d : %s",
			     pid_file, errno, strerror (errno));
		return;
	}

	fclose (pid_file);

	pid_file = fopen (valvula_status, "w");
	if (pid_file == NULL) {
		abort_error ("Unable to open valvula status file at: %s (errno=%d)", valvula_status, errno);
		return;
	} /* end if */

	fprintf (pid_file, "<valvula-state>\n");
	fprintf (pid_file, "  <attr name='valvula pid' value='%d' />\n", getpid ());
	fprintf (pid_file, "</valvula-state>\n");

	fclose (pid_file);

	/* now change permissions (if required) */
	node = axl_doc_get (ctx->config, "/valvula/global-settings/running");
	if (node && ATTR_VALUE (node, "user") && ATTR_VALUE (node, "group") && HAS_ATTR_VALUE (node, "enabled", "yes")) {
		/* change group first */
		gid = valvulad_get_system_id (ctx, ATTR_VALUE (node, "group"), axl_false);
		uid = valvulad_get_system_id (ctx, ATTR_VALUE (node, "user"), axl_true);
		msg ("Attempting to update pid ownership to %d:%d", uid, gid);
		if (gid > 0 && uid > 0) {
			if (chown (valvula_status, uid, gid) != 0) {
				error ("Unable to change permissions to file %s (%d:%d), error was errno=%d (%s)",
				       valvula_status, uid, gid, errno, strerror (errno));
			} /* end if */

			/**** do no change pid file ownership is a security problem ****/

		} /* end if */
	} /* end if */

	return;
}
Ejemplo n.º 11
0
void valvulad_ping_server (void) {
	axl_bool           result;
	axlNode          * node;
	VALVULA_SOCKET     _socket;
	int                timeout = 10;
	char               buffer[20];
	const char       * host;
	const char       * port;
	int                event;

	/* init here valvula library and valvulaD context */
	if (! valvulad_init (&ctx)) {
		error ("Failed to initialize ValvulaD context, unable to start server");
		exit (-1);
	} /* end if */

	/* parse configuration file */
	if (exarg_is_defined ("config"))
		result = valvulad_config_load (ctx, exarg_get_string ("config"));
	else
		result = valvulad_config_load (ctx, "/etc/valvula/valvula.conf");

	if (! result) { 
		printf ("ERROR: unable to load valvula configuration, failed to locate server to ping it\n");
		exit (-1);
	} /* end if */

	/* get node */
	node = axl_doc_get (ctx->config, "/valvula/general/listen");
	if (! node ) {
		printf ("ERROR: nothing to test, no listener was found defined\n");
		exit (-1);
	} /* end if */

	while (node) {

		/* connect to the server */
		port = ATTR_VALUE (node, "port");
		host = ATTR_VALUE (node, "host");
		
		if (! port)
			continue;
		if (! host)
			host = "127.0.0.1";

		/* ensure that in 10 seconds we get called */
		event = valvula_thread_pool_new_event (ctx->ctx, 10000000, catch_ping_server_timeout, NULL, NULL);
		 
		_socket = valvula_connection_sock_connect (ctx->ctx, host, port, &timeout, NULL);
		if (_socket <= 0) {
			printf ("ERROR: unable to connect to %s:%s, _socket=%d, error=%d\n", 
				host, port, _socket, errno);
			exit (-1);
		} /* end if */
		valvula_connection_set_sock_block (_socket, axl_true);

		/* send check server request */
		if (send (_socket, "checkserver\n", 12, 0) != 12) {
			printf ("ERROR: failed to send checkserver request, bytes expected weren't 11, errno=%d\n", errno);
			exit (-1);
		} /* end if */

		/* ensure that in 10 seconds we get called */
		valvula_thread_pool_remove (ctx->ctx, event);
		event = valvula_thread_pool_new_event (ctx->ctx, 10000000, catch_ping_server_timeout, NULL, NULL);

		/* wait for reply */
		memset (buffer, 0, 20);
		if (recv (_socket, buffer, 17, 0) != 17) {
			printf ("ERROR: expected to receive 20 bytes but found: %s, errno=%d : %s\n", buffer, errno, strerror (errno));
			exit (-1);
		} /* end if */

		/* check content here */
		valvula_close_socket (_socket);

		if (! axl_cmp (buffer, "I'm running right")) {
			printf ("ERROR: expected to receive different values but found: %s\n", buffer);
			exit (-1);
		} /* end if */

		printf ("%s:%s working right!\n", host, port);

		/* get next <listen /> node */
		node = axl_node_get_next_called (node, "listen");
	} /* end while */

	printf ("Valvula server working OK\n");

	exit (0);
}
Ejemplo n.º 12
0
void valvulad_show_current_server_status (void)
{
	axlDoc   * doc;
	axlError * err = NULL;
	axlNode  * node;
	int        pid = -1;

	doc = axl_doc_parse_from_file (valvula_status, &err);
	if (doc == NULL) {
		printf ("ERROR: unable to open file %s, error was: %s\n",
			valvula_status, axl_error_get (err));
		axl_error_free (err);
		exit (-1);
	}  /* end if */

	/* find the pid file to send the signal */
	node = axl_doc_get (doc, "/valvula-state/attr");
	while (node) {
		if (HAS_ATTR_VALUE (node, "name", "valvula pid")) {
			/* get pid */
			pid = valvula_support_strtod (ATTR_VALUE (node, "value"), NULL);
			break;
		}

		/* get next node */
		node = axl_node_get_next_called (node, "attr");
	} /* end while */

	/* release document */
	axl_doc_free (doc);

	if (pid == -1) {
		printf ("ERROR: unable to find running pid..\n");
		exit (-1);
	} /* end if */

	printf ("--== Found pid %d, sending signal..==--\n", pid); 
	kill (pid, SIGUSR1);
	
	sleep (1);

	/* reparse file */
	doc = axl_doc_parse_from_file (valvula_status, &err);
	if (doc == NULL) {
		printf ("ERROR: unable to open file %s, error was: %s\n",
			valvula_status, axl_error_get (err));
		axl_error_free (err);
		exit (-1);
	}  /* end if */

	/* find the pid file to send the signal */
	node = axl_doc_get (doc, "/valvula-state");
	node = axl_node_get_first_child (node);
	while (node) {
		/* show values */
		if (NODE_CMP_NAME (node, "attr"))
			printf ("%s: %s\n", ATTR_VALUE (node, "name"), ATTR_VALUE (node, "value"));
		else if (NODE_CMP_NAME (node, "section"))
			printf ("\n--== %s ==--\n\n", ATTR_VALUE (node, "title"));

		/* get next node */
		node = axl_node_get_next (node);
	}
	printf ("\n");

	exit (0);

	return;
}
Ejemplo n.º 13
0
/** 
 * @internal Terminates the myqttd excution, returing the exit signal
 * provided as first parameter. This function is used to notify a
 * context that a signal was received.
 * 
 * @param ctx The myqttd context to terminate.
 * @param _signal The exit code to return.
 */
void myqttd_signal_exit (MyQttdCtx * ctx, int _signal)
{
	/* get myqttd context */
	axlDoc           * doc;
	axlNode          * node;
	MyQttAsyncQueue  * queue;
	char             * backtrace_file;

	/* lock the mutex and check */
	myqtt_mutex_lock (&ctx->exit_mutex);
	if (ctx->is_exiting) {
		msg ("process already existing, signal received=%d, doing nothing...", _signal);

		/* other thread is already cleaning */
		myqtt_mutex_unlock (&ctx->exit_mutex);
		return;
	} /* end if */

	msg ("received termination signal (%d) on PID %d, preparing exit process", _signal, getpid ()); 

	/* flag that myqttd is existing and do all cleanup
	 * operations */
	ctx->is_exiting = axl_true;
	myqtt_mutex_unlock (&ctx->exit_mutex);
	
	switch (_signal) {
	case SIGINT:
		msg ("caught SIGINT, terminating myqttd..");
		break;
	case SIGTERM:
		msg ("caught SIGTERM, terminating myqttd..");
		break;
#if defined(AXL_OS_UNIX)
	case SIGKILL:
		msg ("caught SIGKILL, terminating myqttd..");
		break;
	case SIGQUIT:
		msg ("caught SIGQUIT, terminating myqttd..");
		break;
#endif
	case SIGSEGV:
	case SIGABRT:
		error ("caught %s, anomalous termination (this is an internal myqttd or module error)",
		       _signal == SIGSEGV ? "SIGSEGV" : "SIGABRT");
		
		/* check current termination option */
		doc  = myqttd_config_get (ctx);
		node = axl_doc_get (doc, "/myqtt/global-settings/on-bad-signal");
		error ("applying configured action %s", (node && HAS_ATTR (node, "action")) ? ATTR_VALUE (node, "action") : "not defined");
		if (HAS_ATTR_VALUE (node, "action", "ignore")) {
			/* do notify if enabled */
			CHECK_AND_REPORT_MAIL_TO ("Bad signal received at myqttd process, default action: ignore",
						  "Received termination signal but it was ignored.",
						  NULL);

			/* ignore the signal emision */
			return;
		} else if (HAS_ATTR_VALUE (node, "action", "hold")) {
			/* lock the process */
			error ("Bad signal found, locking process, now you can attach or terminate pid: %d", 
			       getpid ());
			CHECK_AND_REPORT_MAIL_TO ("Bad signal received a myqttd process, default action: hold",
						  "Received termination signal and the process was hold for examination",
						  NULL);
			queue = myqtt_async_queue_new ();
			myqtt_async_queue_pop (queue);
			return;
		} else if (HAS_ATTR_VALUE (node, "action", "backtrace")) {
			/* create temporal file */
			error ("Bad signal found, creating backtrace for current process: %d", getpid ());
			backtrace_file = myqttd_support_get_backtrace (ctx, getpid ());
			if (backtrace_file == NULL)
				error ("..backtrace error, unable to produce backtrace..");
			else
				error ("..backtrace created at: %s", backtrace_file);

			/* check if we have to do a mail notification */
			CHECK_AND_REPORT_MAIL_TO ("Bad signal received a myqttd process, default action: backtrace",
						  NULL, backtrace_file);
			/* release backtrace */
			axl_free (backtrace_file);
		}

		/* signal myqtt to not terminate threads (to avoid
		 * deadlocks) */
		exit (-1);
		break;
	default:
		msg ("terminating myqttd..");
		break;
	} /* end if */

	/* Unlock the listener here. Do not perform any deallocation
	 * operation here because we are in the middle of a signal
	 * handler execution. By unlocking the listener, the
	 * myqttd_cleanup is called cleaning the room. */
	msg ("Unlocking myqttd listener: %p", ctx);
	/* unlock the current listener */
	myqtt_listener_unlock (MYQTTD_MYQTT_CTX (ctx));

	return;
} /* end if */
Ejemplo n.º 14
0
int  tbc_mod_gen_compile ()
{
	axlDtd   * dtd;
	axlDoc   * doc;
	axlError * error;
	axlNode  * node;
	axlNode  * moddef;
	char     * mod_name;
	char     * tolower;
	char     * toupper;
	char     * description;

	/* parse DTD document */
	dtd = axl_dtd_parse (TBC_MOD_GEN_DTD, -1, &error);
	if (dtd == NULL) {
		/* report error and dealloc resources */
		error ("Failed to parse DTD, error found: %s", axl_error_get (error));
		axl_error_free (error);

		return axl_false;
	} /* end if */
	
	/* nice, now parse the xml file */
	doc = axl_doc_parse_from_file (exarg_get_string ("compile"), &error);
	if (doc == NULL) {
		/* report error and dealloc resources */
		error ("unable to parse file: %s, error found: %s", 
		       exarg_get_string ("compile"),
		       axl_error_get (error));
		axl_error_free (error);
		axl_dtd_free (dtd);
	} /* end if */

	/* nice, now validate content */
	if (! axl_dtd_validate (doc, dtd, &error)) {
		/* report error and dealloc */
		error ("failed to validate module description provided: %s, error found: %s",
		       exarg_get_string ("compile"),
		       axl_error_get (error));
		axl_error_free (error);
		axl_doc_free (doc);
		axl_dtd_free (dtd);
		return axl_false;
	} /* end if */

	/* ok, now produce source code  */
	axl_dtd_free (dtd);

	/* open file */
	moddef   = axl_doc_get_root (doc);
	node     = axl_doc_get (doc, "/mod-def/name");
	mod_name = (char *) axl_node_get_content (node, NULL);
	mod_name = support_clean_name (mod_name);
	tolower  = support_to_lower (mod_name);
	toupper  = support_to_upper (mod_name);

	/* out dir */
	support_open_file (ctx, "%s%s.c", get_out_dir (), mod_name);

	/* place copyright if found */
	node     = axl_doc_get (doc, "/mod-def/copyright");
	if (node != NULL) {
		/* place the copyright */
	}  /* end if */
	
	write ("/* %s implementation */\n", mod_name);
	write ("#include <turbulence.h>\n\n");

	write ("/* use this declarations to avoid c++ compilers to mangle exported\n");
	write (" * names. */\n");
	write ("BEGIN_C_DECLS\n\n");

	write ("/* global turbulence context reference */\n");
	write ("TurbulenceCtx * ctx = NULL;\n\n");

	/* place here additional content */
	node    = axl_doc_get (doc, "/mod-def/source-code/additional-content");
	if (node != NULL) {
		write ("%s\n", axl_node_get_content (node, NULL));
	} /* end if */

	/* init handler */
	write ("/* %s init handler */\n", mod_name);
	write ("static int  %s_init (TurbulenceCtx * _ctx) {\n", tolower);

	push_indent ();
	write ("/* configure the module */\n");
	write ("TBC_MOD_PREPARE (_ctx);\n\n");
	pop_indent ();

	node = axl_doc_get (doc, "/mod-def/source-code/init");
	if (axl_node_get_content (node, NULL)) {
		/* write the content defined */
		write ("%s\n", axl_node_get_content (node, NULL));
	}
	write ("} /* end %s_init */\n\n", tolower);

	/* close handler */
	write ("/* %s close handler */\n", mod_name);
	write ("static void %s_close (TurbulenceCtx * _ctx) {\n", tolower);
	node = axl_doc_get (doc, "/mod-def/source-code/close");
	if (axl_node_get_content (node, NULL)) {
		/* write the content defined */
		write ("%s\n", axl_node_get_content (node, NULL));
	}
	write ("} /* end %s_close */\n\n", tolower);

	/* reconf handler */
	write ("/* %s reconf handler */\n", mod_name);
	write ("static void %s_reconf (TurbulenceCtx * _ctx) {\n", tolower);
	node = axl_doc_get (doc, "/mod-def/source-code/reconf");
	if (axl_node_get_content (node, NULL)) {
		/* write the content defined */
		write ("%s\n", axl_node_get_content (node, NULL));
	}
	write ("} /* end %s_reconf */\n\n", tolower);

	/* unload handler */
	write ("/* %s unload handler */\n", mod_name);
	write ("static void %s_unload (TurbulenceCtx * _ctx) {\n", tolower);
	node = axl_doc_get (doc, "/mod-def/source-code/unload");
	if (axl_node_get_content (node, NULL)) {
		/* write the content defined */
		write ("%s\n", axl_node_get_content (node, NULL));
	}
	write ("} /* end %s_unload */\n\n", tolower);

	/* ppath_selected handler */
	write ("/* %s ppath-selected handler */\n", mod_name);
	write ("static axl_bool %s_ppath_selected (TurbulenceCtx * _ctx, TurbulencePPathDef * ppath_selected, VortexConnection * conn) {\n", tolower);
	node = axl_doc_get (doc, "/mod-def/source-code/ppath-selected");
	if (axl_node_get_content (node, NULL)) {
		/* write the content defined */
		write ("%s\n", axl_node_get_content (node, NULL));
	}
	write ("} /* end %s_ppath_selected */\n\n", tolower);

	/* write handler description */
	write ("/* Entry point definition for all handlers included in this module */\n");
	write ("TurbulenceModDef module_def = {\n");

	push_indent ();

	write ("\"%s\",\n", mod_name);
	node        = axl_doc_get (doc, "/mod-def/description");
	description = (char *) axl_node_get_content (node, NULL);
	write ("\"%s\",\n", description ? description : "");
	write ("%s_init,\n", tolower);
	write ("%s_close,\n", tolower);
	write ("%s_reconf,\n", tolower);
	write ("%s_unload,\n", tolower);
	write ("%s_ppath_selected\n", tolower);
	pop_indent ();

	write ("};\n\n");

	write ("END_C_DECLS\n\n");
	
	/* close content */
	support_close_file (ctx);

	/* create the makefile required */
	support_open_file (ctx, "%sMakefile.am", get_out_dir ());
	
	write ("# Module definition\n");
	write ("EXTRA_DIST = %s\n\n", exarg_get_string ("compile"));
	
	       
	write ("INCLUDES = -Wall -g -ansi $(TURBULENCE_CFLAGS) -I../../src -DCOMPILATION_DATE=`date +%%s` \\\n");
	push_indent ();
	
	write ("-DVERSION=\\\"$(VERSION)\\\" \\\n");
	write ("$(AXL_CFLAGS) $(VORTEX_CFLAGS) $(EXARG_CFLAGS)\n\n");
	pop_indent ();
	
	write ("# configure module binary\n");
	write ("lib_LTLIBRARIES      = %s.la\n", mod_name);
	write ("%s_la_SOURCES  = %s.c %s\n", mod_name, mod_name,
	       HAS_ATTR (moddef, "sources") ? ATTR_VALUE (moddef, "sources") : "");
	write ("%s_la_LDFLAGS  = -module -ldl\n\n", mod_name);
	
	write ("# reconfigure module installation directory\n");
	write ("libdir = `turbulence-config --mod-dir`\n\n");
	
	write ("# configure site module installation\n");
	write ("modconfdir   = `turbulence-config --mod-xml`\n");
	write ("modconf_DATA = %s.xml %s.win32.xml\n\n", mod_name, mod_name);
	
	write ("%s.xml %s.win32.xml:\n", mod_name, mod_name);
	push_indent ();
	write ("echo \"<mod-turbulence location=\\\"`turbulence-config --mod-dir`/%s.so\\\"/>\" > %s.xml\n", mod_name, mod_name);
	write ("echo \"<mod-turbulence location=\\\"../modules/%s.dll\\\"/>\" > %s.win32.xml\n", mod_name, mod_name);
	pop_indent ();

	support_close_file (ctx);

	/* create autoconf if defined */
	if (exarg_is_defined ("enable-autoconf")) {

		msg ("found autoconf support files request..");
		
		/* create the autogen.sh */
		support_open_file (ctx, "%sautogen.sh", get_out_dir ());

		write ("# autogen.sh file created by tbc-mod-gen\n");
		write ("PACKAGE=\"%s: %s\"\n\n", mod_name, description);

		write ("(automake --version) < /dev/null > /dev/null 2>&1 || {\n");

		push_indent ();
		write ("echo;\n");
		write ("echo \"You must have automake installed to compile $PACKAGE\";\n");
		write ("echo;\n");
		write ("exit;\n");
		pop_indent ();

		write ("}\n\n");

		write ("(autoconf --version) < /dev/null > /dev/null 2>&1 || {\n");
		push_indent ();
		write ("echo;\n");
		write ("echo \"You must have autoconf installed to compile $PACKAGE\";\n");
		write ("echo;\n");
		write ("exit;\n");
		pop_indent ();
		write ("}\n\n");

		write ("echo \"Generating configuration files for $PACKAGE, please wait....\"\n");
		write ("echo;\n\n");

		write ("touch NEWS README AUTHORS ChangeLog\n");
		write ("libtoolize --force;\n");
		write ("aclocal $ACLOCAL_FLAGS;\n");
		write ("autoheader;\n");
		write ("automake --add-missing;\n");
		write ("autoconf;\n\n");

		write ("./configure $@ --enable-maintainer-mode --enable-compile-warnings\n");

		support_close_file (ctx);

		support_make_executable (ctx, "%sautogen.sh", get_out_dir ());

		/* now create the configure.ac file */

		support_open_file (ctx, "%sconfigure.ac", get_out_dir ());

		write ("dnl configure.ac template file created by tbc-mod-gen\n");
		write ("AC_INIT(%s.c)\n\n", mod_name);

		write ("dnl declare a global version value\n");
		write ("%s_VERSION=\"0.0.1\"\n", toupper);
		write ("AC_SUBST(%s_VERSION)\n\n", toupper);

		write ("AC_CONFIG_AUX_DIR(.)\n");
		write ("AM_INIT_AUTOMAKE(%s, $%s_VERSION)\n\n", mod_name, toupper);

		write ("AC_CONFIG_HEADER(config.h)\n");
		write ("AM_MAINTAINER_MODE\n");
		write ("AC_PROG_CC\n");
		write ("AC_ISC_POSIX\n");
		write ("AC_HEADER_STDC\n");
		write ("AM_PROG_LIBTOOL\n\n");

		write ("dnl external dependencies\n");
		write ("PKG_CHECK_MODULES(AXL, axl >= %s)\n\n", AXL_VERSION);

		write ("dnl general libries subsitution\n");
		write ("AC_SUBST(AXL_CFLAGS)\n");
		write ("AC_SUBST(AXL_LIBS)\n\n");

		write ("dnl external dependencies\n");
		write ("PKG_CHECK_MODULES(VORTEX, vortex >= %s) \n\n", VORTEX_VERSION);

		write ("dnl general libries subsitution\n");
		write ("AC_SUBST(VORTEX_CFLAGS)\n");
		write ("AC_SUBST(VORTEX_LIBS)\n\n");

		write ("dnl external dependencies\n");
		write ("PKG_CHECK_MODULES(EXARG, exarg)\n\n");

		write ("dnl general libries subsitution\n");
		write ("AC_SUBST(EXARG_CFLAGS)\n");
		write ("AC_SUBST(EXARG_LIBS)\n\n");
		
		write ("dnl external dependencies\n");
		write ("PKG_CHECK_MODULES(TURBULENCE, turbulence >= %s)\n\n", VERSION);

		write ("dnl general libries subsitution\n");
		write ("AC_SUBST(TURBULENCE_CFLAGS)\n");
		write ("AC_SUBST(TURBULENCE_LIBS)\n\n");

		write ("AC_OUTPUT([\n");
		write ("Makefile\n");
		write ("])\n\n");

		write ("echo \"------------------------------------------\"\n");
		write ("echo \"--       mod_template Settings          --\"\n");
		write ("echo \"------------------------------------------\"\n");
		write ("echo \"------------------------------------------\"\n");
		write ("echo \"--            Let it BEEP!              --\"\n");
		write ("echo \"--                                      --\"\n");
		write ("echo \"--     NOW TYPE: make; make install     --\"\n");
		write ("echo \"------------------------------------------\"\n");

		support_close_file (ctx);
		
	} /* end if */

	/* dealloc */
	axl_free (tolower);
	axl_free (toupper);
	axl_doc_free (doc);

	/* create the script file */
	support_open_file (ctx, "%sgen-code", get_out_dir ());

	write ("#!/bin/sh\n\n");

	/* write the mod gen */
	write ("tbc-mod-gen --compile %s --out-dir %s\n", exarg_get_string ("compile"), exarg_get_string ("out-dir"));
	
	support_close_file (ctx);

	support_make_executable (ctx, "%sgen-code", get_out_dir ());

	msg ("%s created!", mod_name);
	axl_free (mod_name);

	return axl_true;
}