Ejemplo n.º 1
0
/// Construct a new ResourceQueue system (you probably only need one)
ResourceQueue*
resourcequeue_new(guint structsize)
{
	AssimObj*		aself;
	ResourceQueue*		self;
	BINDDEBUG(ResourceQueue);

	if (structsize < sizeof(ResourceQueue)) {
		structsize = sizeof(ResourceQueue);
	}
	aself = assimobj_new(structsize);
	self = NEWSUBCLASS(ResourceQueue, aself);
	aself->_finalize = _resource_queue_finalize;
	
	self->Qcmd = _resource_queue_Qcmd;
	self->cancel = _resource_queue_cancel;
	self->cancelall = _resource_queue_cancelall;
	self->resources = g_hash_table_new_full(g_str_hash, g_str_equal
	,		_resource_queue_hash_key_destructor, _resource_queue_hash_data_destructor);
	self->timerid = g_timeout_add_seconds(1, _resource_queue_runqueue, self);
	self->activechildcnt = 0;
	self->shuttingdown = FALSE;

	return self;
}
Ejemplo n.º 2
0
/// Discovery constructor.
/// Note that derived classes <i>must</i> set the discover member function - or things might crash.
/// That is certainly what will happen if you try and construct one of these objects directly and
/// then use it.
Discovery*
discovery_new(const char *	instname,	///<[in] instance name
	      NetGSource*	iosource,	///<[in/out] I/O object
	      ConfigContext*	context,	///<[in/out] configuration context
	      gsize objsize)			///<[in] number of bytes to malloc for the object (or zero)
{
	gsize	size = objsize < sizeof(Discovery) ? sizeof(Discovery) : objsize;
	Discovery * ret = NEWSUBCLASS(Discovery, assimobj_new(size));
	g_return_val_if_fail(ret != NULL, NULL);
	BINDDEBUG(Discovery);
	ret->_instancename		= g_strdup(instname);
	ret->instancename		= _discovery_instancename;
	ret->discoverintervalsecs	= _discovery_discoverintervalsecs;
	ret->baseclass._finalize	= _discovery_finalize;
	ret->sendjson			= _discovery_sendjson;
	ret->discover			= NULL;
	ret->_timerid			= 0;
	ret->_iosource			= iosource;
	ret->_config			= context;
	ret->starttime			= g_get_real_time();
	REF(ret->_config);
	return ret;
}
Ejemplo n.º 3
0
/// Construct a new CryptFrame
/// This can only be used directly for creating subclassed CryptFrame frames because
/// CryptFrame is an abstract class...
CryptFrame*
cryptframe_new( guint16 frame_type,		///<[in] TLV type of CryptFrame
		const char * sender_key_id,	///<[in] Sender key id
		const char * receiver_key_id,	///<[in] Receiver key id
		gsize objsize)			///<[in] size of object
{
	Frame*		baseframe;
	CryptFrame*	self;

	BINDDEBUG(CryptFrame);
	if (objsize < sizeof(CryptFrame)) {
		objsize = sizeof(CryptFrame);
	}
	baseframe = frame_new(frame_type, objsize);
	if (!_parentclass_finalize) {
		_parentclass_finalize = baseframe->baseclass._finalize;
	}
	baseframe->baseclass._finalize = _cryptframe_finalize;
	baseframe->isvalid = _cryptframe_default_isvalid;
	self = NEWSUBCLASS(CryptFrame, baseframe);
	self->sender_key_id = g_strdup(sender_key_id);
	self->receiver_key_id = g_strdup(receiver_key_id);
	return self;
}
Ejemplo n.º 4
0
/// Construct a new CryptCurve25519 object (frame).
CryptCurve25519*
cryptcurve25519_new(guint16 frame_type,	///<[in] TLV type of CryptCurve25519
	  const char * sender_key_id,	///<[in] name of sender's key
	  const char * receiver_key_id,	///<[in] name of receiver's key
	  gboolean     forsending,	///<[in] TRUE if this is for sending
	  gsize objsize)		///<[in] sizeof(this object) - or zero for default
{
	CryptFrame*		baseframe;
	CryptCurve25519*	ret;

	BINDDEBUG(CryptCurve25519);
	if (objsize < sizeof(CryptCurve25519)) {
		objsize = sizeof(CryptCurve25519);
	}
	if (NULL == sender_key_id) {
		sender_key_id = cryptframe_get_signing_key_id();
	}
	DEBUGMSG2("%s.%d:(%s, %s, %d)", __FUNCTION__, __LINE__, sender_key_id, receiver_key_id
	,	(int)objsize);
	g_return_val_if_fail(sender_key_id != NULL && receiver_key_id != NULL, NULL);
	if (!_is_valid_curve25519_key_id(receiver_key_id, PUBLICKEY)) {
		g_critical("%s.%d: public key name [%s] is invalid", __FUNCTION__, __LINE__, receiver_key_id);
		return NULL;
	}
	if (!_is_valid_curve25519_key_id(sender_key_id, PUBLICKEY)) {
		g_critical("%s.%d: public key name [%s] is invalid", __FUNCTION__, __LINE__, sender_key_id);
		return NULL;
	}
	baseframe = cryptframe_new(frame_type, sender_key_id, receiver_key_id, objsize);
	if (!_parentclass_finalize) {
		_parentclass_finalize = baseframe->baseclass.baseclass._finalize;
	}
	baseframe->baseclass.isvalid	= _cryptcurve25519_default_isvalid;
	baseframe->baseclass.updatedata	= _cryptcurve25519_updatedata;
	baseframe->baseclass.length	= TLVLEN(receiver_key_id, sender_key_id);
	baseframe->baseclass.baseclass._finalize = _cryptcurve25519_finalize;
	ret			= NEWSUBCLASS(CryptCurve25519, baseframe);
	ret->forsending		= forsending;
	ret->private_key	= cryptframe_private_key_by_id(forsending ? sender_key_id : receiver_key_id);
	ret->public_key		= cryptframe_public_key_by_id(forsending ? receiver_key_id : sender_key_id);
	if (ret->private_key && ret->public_key) {
		DEBUGCKSUM3("private_key:", ret->private_key->private_key, crypto_box_SECRETKEYBYTES);
		DEBUGCKSUM3("public_key:", ret->public_key->public_key, crypto_box_PUBLICKEYBYTES);
		DUMP3(__FUNCTION__, &ret->baseclass.baseclass.baseclass, " is return value");
		REF(ret->private_key);
		REF(ret->public_key);
	}else{
		if (!ret->private_key) {
			g_warning("%s.%d: Sender private key is NULL for key id %s", __FUNCTION__, __LINE__
			,	sender_key_id);
			abort();
		}
		if (!ret->public_key) {
			g_warning("%s.%d: Receiver public key is NULL for key id %s", __FUNCTION__, __LINE__
			,	receiver_key_id);
		}
		UNREF3(ret);
		return NULL;
	}
	return ret;
}
Ejemplo n.º 5
0
/**
 * @ref ChildProcess constructor.
 * Here's what we're going to do:
 * 1) Create child process using g_spawn_async_with_pipes()
 * 2) ...In child process become our own process group
 * 3) Create LogSourceFd object for stderr
 * 4) Create LogSourceFd or GMainFd object for stdout
 * 5) Set timer (if any)
 * 6) Initialize the child state to running
 * 7) Return.
 */
WINEXPORT ChildProcess*
childprocess_new(gsize cpsize		///< Size of created ChildProcess object
,		char** argv		///< NULL-terminated argv for the ChildProcess
,		const char** envp	///< Environment for the ChildProcess
,		ConfigContext* envmod	///< Modifications to the ChildProcess environment
,		const char* curdir	///< Current directory to start the child in
,		void (*notify)(ChildProcess*, enum HowDied, int rc, int signal, gboolean core_dumped)
					///< Function to call if/when the child terminates
,		gboolean save_stdout	///< TRUE to save stdout, FALSE to log it
,		const char*logdomain	///< Glib log domain
,		const char*logprefix	///< Prefix to prepend to log entries
,		GLogLevelFlags loglevel	///< Glib Log level
,		guint32 timeout_seconds	///< How long to wait before killing it - zero for no timeout
,		gpointer user_data	///< Data our user wants us to keep
,		enum ChildErrLogMode logmode ///< How to log child exits
,		const char* logname)	///< Name to use when logging child exits as requested
{
	AssimObj*	aself;
	ChildProcess*	self;
	gint		stdoutfd;
	gint		stderrfd;
	GError*		failcode = NULL;
	gchar**		childenv = NULL;

	BINDDEBUG(ChildProcess);
	g_return_val_if_fail(logprefix != NULL, NULL);
	if (cpsize < sizeof(ChildProcess)) {
		cpsize = sizeof(ChildProcess);
	}
	aself = assimobj_new(cpsize);
	g_return_val_if_fail(aself != NULL, NULL);
	self = NEWSUBCLASS(ChildProcess, aself);
	childenv = assim_merge_environ(envp, envmod);
	if (!g_spawn_async_with_pipes(
		curdir,				// Current directory
		argv,				// Arguments
		childenv,			// environment
		G_SPAWN_DO_NOT_REAP_CHILD,	// GSpawnFlags flags,
		_childprocess_setup_child,	// GSpawnChildSetupFunc child_setup,
		self,				// gpointer user_data,
		&self->child_pid,		// GPid *child_pid,
		NULL,				// gint *standard_input,
		&stdoutfd,			// gint *standard_output,
		&stderrfd,			// gint *standard_error,
		&failcode)) {			// GError **error

		// OOPS!  Failed!
		const char *	msg = "unknown exec error";
		if (failcode && failcode->message) {
			msg = failcode->message;
		}
		g_critical("%s.%d: %s", __FUNCTION__, __LINE__, msg);
		if (failcode) {
			g_clear_error(&failcode);	// sets failcode back to NULL
		}
		assim_free_environ(childenv); childenv = NULL;
		UNREF(self);
		aself = NULL;
		return NULL;
	}
	DEBUGMSG2("%s.%d: Spawned process with user_data = %p", __FUNCTION__, __LINE__, self);

	aself->_finalize = _childprocess_finalize;
	aself->toString = _childprocess_toString;
	self->stderr_src = logsourcefd_new(0, stderrfd, G_PRIORITY_HIGH, g_main_context_default()
	,		                   logdomain, loglevel, logprefix);
	self->user_data = user_data;
	self->logmode = logmode;
	if (NULL == logname) {
		logname = argv[0];
	}
	self->loggingname = g_strdup(logname);
	assim_free_environ(childenv);
	childenv = NULL;

	if (!save_stdout) {
		LogSourceFd*	logsrc;
		logsrc = logsourcefd_new(0, stdoutfd, G_PRIORITY_HIGH
		,		g_main_context_default(), logdomain, loglevel, logprefix);
		self->stdout_src = &logsrc->baseclass;
	}else{
		self->stdout_src = gmainfd_new(0, stdoutfd, G_PRIORITY_HIGH, g_main_context_default());
	}
	self->childsrc_id = g_child_watch_add(self->child_pid, _childprocess_childexit, self);

	self->notify = notify;

	if (0 == timeout_seconds) {
		DEBUGMSG2("No timeout for process with user_data = %p", self);
		self->timeoutsrc_id = 0;
	}else{
		self->timeoutsrc_id = g_timeout_add_seconds(timeout_seconds
		,			                   _childprocess_timeout, self);
		DEBUGMSG3("%s.%d: Set %d second timeout %d for process with user_data = %p"
		,	__FUNCTION__, __LINE__, timeout_seconds, self->timeoutsrc_id, self);
	}
	self->child_state = CHILDSTATE_RUNNING;
	DEBUGMSG5("%s.%d: REF child: %p", __FUNCTION__,__LINE__, self);
	REF(self);	// We do this because we need to still be here when the process exits
	return self;
}
Ejemplo n.º 6
0
/**
 *  Set up pcap listener for the given interfaces and protocols.
 *  @return a properly configured pcap_t* object for listening for the given protocols - NULL on error
 *  @see pcap_protocols
 */
pcap_t*
create_pcap_listener(const char * dev		///<[in] Device name to listen on
                     ,		     gboolean blocking		///<[in] TRUE if this is a blocking connection
                     ,		     unsigned listenmask	///<[in] Bit mask of protocols to listen for
                     ///< (see @ref pcap_protocols "list of valid bits")
                     ,		     struct bpf_program*prog)	///<[out] Compiled PCAP program
{
    pcap_t*			pcdescr = NULL;
    bpf_u_int32		maskp = 0;
    bpf_u_int32		netp = 0;
    char			errbuf[PCAP_ERRBUF_SIZE];
    char *			expr = NULL;
    int			filterlen = 1;
    unsigned		j;
    int			cnt=0;
    int			rc;
    const char ORWORD [] = " or ";
    gboolean		need_promisc = FALSE;

    BINDDEBUG(pcap_t);
//	setbuf(stdout, NULL);
    setvbuf(stdout, NULL, _IONBF, 0);
    errbuf[0] = '\0';

    // Search the list of valid bits so we can construct the libpcap filter
    // for the given set of protocols on the fly...
    // On this pass we just compute the amount of memory we'll need...
    for (j = 0, cnt = 0; j < DIMOF(filterinfo); ++j) {
        if (listenmask & filterinfo[j].filterbit) {
            ++cnt;
            if (cnt > 1) {
                filterlen += sizeof(ORWORD);
            }
            filterlen += strlen(filterinfo[j].filter);
        }
    }

    if (filterlen < 2) {
        g_warning("Constructed filter is too short - invalid mask argument.");
        return NULL;
    }
    if (NULL == (expr = malloc(filterlen))) {
        g_error("Out of memory!");
        return NULL;
    }
    // Same song, different verse...
    // This time around, we construct the filter
    expr[0] = '\0';
    for (j = 0, cnt = 0; j < DIMOF(filterinfo); ++j) {
        if (listenmask & filterinfo[j].filterbit) {
            ++cnt;
            if (cnt > 1) {
                g_strlcat(expr, ORWORD, filterlen);
            }
            g_strlcat(expr, filterinfo[j].filter, filterlen);
        }
    }
    if (pcap_lookupnet(dev, &netp, &maskp, errbuf) != 0) {
        // This is not a problem for non-IPv4 protocols...
        // It just looks up the ipv4 address - which we mostly don't care about.
        g_info("%s.%d: pcap_lookupnet(\"%s\") failed: [%s]"
               ,	__FUNCTION__, __LINE__, dev, errbuf);
    }

    if (NULL == (pcdescr = pcap_create(dev, errbuf))) {
        g_warning("pcap_create failed: [%s]", errbuf);
        goto oopsie;
    }
    //pcap_set_promisc(pcdescr, FALSE);
    for (j = 0; j < DIMOF(filterinfo); ++j) {
        if (listenmask & filterinfo[j].filterbit) {
            const char * addrstring = filterinfo[j].mcastaddr;
            if (addrstring && !_enable_mcast_address(addrstring, dev, TRUE)) {
                need_promisc = TRUE;
            }
        }
    }
    pcap_set_promisc(pcdescr, need_promisc);
#ifdef HAVE_PCAP_SET_RFMON
    pcap_set_rfmon(pcdescr, FALSE);
#endif
    pcap_setdirection(pcdescr, PCAP_D_IN);
    // Weird bug - returns -3 and doesn't show an error message...
    // And pcap_getnonblock also returns -3... Neither should happen AFAIK...
    errbuf[0] = '\0';
    if ((rc = pcap_setnonblock(pcdescr, !blocking, errbuf)) < 0 && errbuf[0] != '\0') {
        g_warning("pcap_setnonblock(%d) failed: [%s] [rc=%d]", !blocking, errbuf, rc);
        g_warning("Have no idea why this happens - current blocking state is: %d."
                  ,	pcap_getnonblock(pcdescr, errbuf));
    }
    pcap_set_snaplen(pcdescr, 1500);
    /// @todo deal with pcap_set_timeout() call here.
    if (blocking) {
        pcap_set_timeout(pcdescr, 240*1000);
    } else {
        pcap_set_timeout(pcdescr, 1);
    }
    //pcap_set_buffer_size(pcdescr, 1500);

    if (pcap_activate(pcdescr) != 0) {
        g_warning("pcap_activate failed: [%s]", pcap_geterr(pcdescr));
        goto oopsie;
    }
    if (pcap_compile(pcdescr, prog, expr, FALSE, maskp) < 0) {
        g_warning("pcap_compile of [%s] failed: [%s]", expr, pcap_geterr(pcdescr));
        goto oopsie;
    }
    if (pcap_setfilter(pcdescr, prog) < 0) {
        g_warning("pcap_setfilter on [%s] failed: [%s]", expr, pcap_geterr(pcdescr));
        goto oopsie;
    }
    DEBUGMSG1("Compile of [%s] worked!", expr);
    free(expr);
    expr = NULL;
    return(pcdescr);

oopsie:	// Some kind of failure - free things up and return NULL

    g_warning("%s.%d: Could not set up PCAP on %s"
              ,	__FUNCTION__, __LINE__, dev);
    if (expr) {
        free(expr);
        expr = NULL;
    }
    if (pcdescr) {
        close_pcap_listener(pcdescr, dev, listenmask);
        pcdescr = NULL;
    }
    return NULL;
}