Пример #1
0
/* Register a new hook callback */
int fd_hook_register (  uint32_t type_mask,
                        void (*fd_hook_cb)(enum fd_hook_type type, struct msg * msg, struct peer_hdr * peer, void * other, struct fd_hook_permsgdata *pmd, void * regdata),
                        void  *regdata,
                        struct fd_hook_data_hdl *data_hdl,
                        struct fd_hook_hdl ** handler )
{
    struct fd_hook_hdl * newhdl = NULL;
    int i;

    TRACE_ENTRY("%x %p %p %p %p", type_mask, fd_hook_cb, regdata, data_hdl, handler);

    CHECK_PARAMS( fd_hook_cb && handler );

    CHECK_MALLOC( newhdl = malloc(sizeof(struct fd_hook_hdl)) );
    memset(newhdl, 0, sizeof(struct fd_hook_hdl));

    newhdl->fd_hook_cb = fd_hook_cb;
    newhdl->regdata = regdata;
    newhdl->data_hdl = data_hdl;

    for (i=0; i <= HOOK_LAST; i++) {
        fd_list_init(&newhdl->chain[i], newhdl);
        if (type_mask & (1<<i)) {
            CHECK_POSIX( pthread_rwlock_wrlock(&HS_array[i].rwlock) );
            fd_list_insert_before( &HS_array[i].sentinel, &newhdl->chain[i]);
            CHECK_POSIX( pthread_rwlock_unlock(&HS_array[i].rwlock) );
        }
    }

    *handler = newhdl;
    return 0;
}
Пример #2
0
/* Get a slot in the array */
int fd_hook_data_register(
    size_t permsgdata_size,
    void (*permsgdata_init_cb) (struct fd_hook_permsgdata *),
    void (*permsgdata_fini_cb) (struct fd_hook_permsgdata *),
    struct fd_hook_data_hdl **new_handle)
{
    int ret = ENOSPC, idx;
    TRACE_ENTRY("%zd %p %p %p", permsgdata_size, permsgdata_init_cb, permsgdata_fini_cb, new_handle);

    CHECK_PARAMS( permsgdata_size && new_handle );

    CHECK_POSIX( pthread_mutex_lock(&HDH_lock) );
    if (max_index < FD_HOOK_HANDLE_LIMIT) {
        idx = max_index++;
        ret = 0;
    }
    CHECK_POSIX( pthread_mutex_unlock(&HDH_lock) );

    if (ret == 0) {
        HDH_array[idx].pmd_size = permsgdata_size;
        HDH_array[idx].pmd_init_cb = permsgdata_init_cb;
        HDH_array[idx].pmd_fini_cb = permsgdata_fini_cb;
        *new_handle = &HDH_array[idx];
    }

    return ret;
}
Пример #3
0
/* The callback called on new messages */
static int rtereg_out(void * cbdata, struct msg ** pmsg, struct fd_list * candidates)
{
	struct msg * msg = *pmsg;
	struct avp * avp = NULL;
	
	TRACE_ENTRY("%p %p %p", cbdata, msg, candidates);
	
	CHECK_PARAMS(msg && candidates);
	
	/* Check if it is worth processing the message */
	if (FD_IS_LIST_EMPTY(candidates)) {
		return 0;
	}
	
	/* Now search the AVP in the message */
	CHECK_FCT( fd_msg_search_avp ( msg, rtereg_conf.avp, &avp ) );
	if (avp != NULL) {
		struct avp_hdr * ahdr = NULL;
		CHECK_FCT( fd_msg_avp_hdr ( avp, &ahdr ) );
		if (ahdr->avp_value != NULL) {
#ifndef HAVE_REG_STARTEND
			int ret;
		
			/* Lock the buffer */
			CHECK_POSIX( pthread_mutex_lock(&mtx) );
			
			/* Augment the buffer if needed */
			if (ahdr->avp_value->os.len >= bufsz) {
				CHECK_MALLOC_DO( buf = realloc(buf, ahdr->avp_value->os.len + 1), 
					{ pthread_mutex_unlock(&mtx); return ENOMEM; } );
Пример #4
0
/* Initialize the array of sentinels for the hooks */
int fd_hooks_init(void)
{
    int i;
    for (i=0; i <= HOOK_LAST; i++) {
        fd_list_init(&HS_array[i].sentinel, NULL);
        CHECK_POSIX( pthread_rwlock_init(&HS_array[i].rwlock, NULL) );
    }
    return 0;
}
Пример #5
0
/* free this hook callback */
int fd_hook_unregister( struct fd_hook_hdl * handler )
{
    int i;
    TRACE_ENTRY("%p", handler);
    CHECK_PARAMS( handler );

    for (i=0; i <= HOOK_LAST; i++) {
        if ( ! FD_IS_LIST_EMPTY(&handler->chain[i])) {
            CHECK_POSIX( pthread_rwlock_wrlock(&HS_array[i].rwlock) );
            fd_list_unlink(&handler->chain[i]);
            CHECK_POSIX( pthread_rwlock_unlock(&HS_array[i].rwlock) );
        }
    }

    free(handler);

    return 0;
}
Пример #6
0
/* Alloc / reinit a peer structure. if *ptr is not NULL, it must already point to a valid struct fd_peer. */
int fd_peer_alloc(struct fd_peer ** ptr)
{
	struct fd_peer *p;
	
	TRACE_ENTRY("%p", ptr);
	CHECK_PARAMS(ptr);
	
	if (*ptr) {
		p = *ptr;
	} else {
		CHECK_MALLOC( p = malloc(sizeof(struct fd_peer)) );
		*ptr = p;
	}
	
	/* Now initialize the content */
	memset(p, 0, sizeof(struct fd_peer));
	
	fd_list_init(&p->p_hdr.chain, p);
	
	fd_list_init(&p->p_hdr.info.pi_endpoints, p);
	fd_list_init(&p->p_hdr.info.runtime.pir_apps, p);
	
	p->p_eyec = EYEC_PEER;
	CHECK_POSIX( pthread_mutex_init(&p->p_state_mtx, NULL) );
	
	fd_list_init(&p->p_actives, p);
	fd_list_init(&p->p_expiry, p);
	CHECK_FCT( fd_fifo_new(&p->p_tosend, 5) );
	CHECK_FCT( fd_fifo_new(&p->p_tofailover, 0) );
	p->p_hbh = lrand48();
	
	fd_list_init(&p->p_sr.srs, p);
	fd_list_init(&p->p_sr.exp, p);
	CHECK_POSIX( pthread_mutex_init(&p->p_sr.mtx, NULL) );
	CHECK_POSIX( pthread_cond_init(&p->p_sr.cnd, NULL) );
	
	fd_list_init(&p->p_connparams, p);
	
	return 0;
}
Пример #7
0
/* Search for a peer */
int fd_peer_getbyid( DiamId_t diamid, size_t diamidlen, int igncase, struct peer_hdr ** peer )
{
	struct fd_list * li;
	TRACE_ENTRY("%p %zd %d %p", diamid, diamidlen, igncase, peer);
	CHECK_PARAMS( diamid && diamidlen && peer );
	
	*peer = NULL;
	
	/* Search in the list */
	CHECK_POSIX( pthread_rwlock_rdlock(&fd_g_peers_rw) );
	if (igncase) {
		for (li = fd_g_peers.next; li != &fd_g_peers; li = li->next) {
			struct fd_peer * next = (struct fd_peer *)li;
			int cmp, cont;
			cmp = fd_os_almostcasesrch( diamid, diamidlen, next->p_hdr.info.pi_diamid, next->p_hdr.info.pi_diamidlen, &cont );
			if (cmp == 0) {
				*peer = &next->p_hdr;
				break;
			}
			if (!cont)
				break;
		}
	} else {
		for (li = fd_g_peers.next; li != &fd_g_peers; li = li->next) {
			struct fd_peer * next = (struct fd_peer *)li;
			int cmp = fd_os_cmp( diamid, diamidlen, next->p_hdr.info.pi_diamid, next->p_hdr.info.pi_diamidlen );
			if (cmp > 0)
				continue;
			if (cmp == 0)
				*peer = &next->p_hdr;
			break;
		}
	}
	CHECK_POSIX( pthread_rwlock_unlock(&fd_g_peers_rw) );
	
	return 0;
}
Пример #8
0
// Remove a peer entry.
int fd_peer_remove ( DiamId_t diamid, size_t diamidlen )
{
	struct fd_list * li;

	// Find the peer in the peer list from its pi_diamid.
	CHECK_POSIX( pthread_rwlock_wrlock(&fd_g_peers_rw) );
	for (li = fd_g_peers.next; li != &fd_g_peers; li = li->next) {
		struct fd_peer * peer = (struct fd_peer *)li;
		int cmp = fd_os_cmp( diamid, diamidlen, peer->p_hdr.info.pi_diamid, peer->p_hdr.info.pi_diamidlen );

		if (cmp == 0) {
			/* update the peer lifetime, set the expiry flag and call fd_p_expi_update so that the
			 * p_exp_timer value is updated and the peer expires immediately. */
			peer->p_hdr.info.config.pic_flags.exp = PI_EXP_INACTIVE;
			peer->p_hdr.info.config.pic_lft = 0;
			CHECK_FCT( fd_p_expi_update(peer) );
			break;
		}
	}

	CHECK_POSIX( pthread_rwlock_unlock(&fd_g_peers_rw) );

	return 0;
}
Пример #9
0
static int ta_conf_init(void)
{
	ta_conf = &_conf;
	memset(ta_conf, 0, sizeof(struct ta_conf));
	
	/* Set the default values */
	ta_conf->vendor_id  = 999999;		/* Dummy value */
	ta_conf->appli_id   = 0xffffff;	/* dummy value */
	ta_conf->cmd_id     = 0xfffffe;	/* Experimental */
	ta_conf->avp_id     = 0xffffff;	/* dummy value */
	ta_conf->long_avp_len = 5000;
	ta_conf->mode       = MODE_SERV | MODE_CLI;
	ta_conf->dest_realm = strdup(fd_g_config->cnf_diamrlm);
	ta_conf->dest_host  = NULL;
	ta_conf->signal     = TEST_APP_DEFAULT_SIGNAL;
	ta_conf->bench_concur   = 100;
	ta_conf->bench_duration = 10;
	
	/* Initialize the mutex */
	CHECK_POSIX( pthread_mutex_init(&ta_conf->stats_lock, NULL) );
	
	return 0;
}
Пример #10
0
/* Add a new peer entry */
int fd_peer_add ( struct peer_info * info, const char * orig_dbg, void (*cb)(struct peer_info *, void *), void * cb_data )
{
	struct fd_peer *p = NULL;
	struct fd_list * li, *li_inf;
	int ret = 0;
	
	TRACE_ENTRY("%p %p %p %p", info, orig_dbg, cb, cb_data);
	CHECK_PARAMS(info && info->pi_diamid);
	
	if (info->config.pic_realm) {
		if (!fd_os_is_valid_DiameterIdentity((os0_t)info->config.pic_realm, strlen(info->config.pic_realm))) {
			TRACE_DEBUG(INFO, "'%s' is not a valid DiameterIdentity.", info->config.pic_realm);
			return EINVAL;
		}
	}
	
	/* Create a structure to contain the new peer information */
	CHECK_FCT( fd_peer_alloc(&p) );
	
	/* Copy the informations from the parameters received */
	p->p_hdr.info.pi_diamid = info->pi_diamid;
	CHECK_FCT( fd_os_validate_DiameterIdentity(&p->p_hdr.info.pi_diamid, &p->p_hdr.info.pi_diamidlen, 1) );
	
	memcpy( &p->p_hdr.info.config, &info->config, sizeof(p->p_hdr.info.config) );
	
	/* Duplicate the strings if provided */
	if (info->config.pic_realm) {
		CHECK_MALLOC( p->p_hdr.info.config.pic_realm = strdup(info->config.pic_realm) );
	}
	if (info->config.pic_priority) {
		CHECK_MALLOC( p->p_hdr.info.config.pic_priority = strdup(info->config.pic_priority) );
	}
	
	/* Move the list of endpoints into the peer */
	if (info->pi_endpoints.next)
		while (!FD_IS_LIST_EMPTY( &info->pi_endpoints ) ) {
			li = info->pi_endpoints.next;
			fd_list_unlink(li);
			fd_list_insert_before(&p->p_hdr.info.pi_endpoints, li);
		}
	
	/* The internal data */
	if (orig_dbg) {
		CHECK_MALLOC( p->p_dbgorig = strdup(orig_dbg) );
	} else {
		CHECK_MALLOC( p->p_dbgorig = strdup("unspecified") );
	}
	p->p_cb = cb;
	p->p_cb_data = cb_data;
	
	/* Ok, now check if we don't already have an entry with the same Diameter Id, and insert this one */
	CHECK_POSIX( pthread_rwlock_wrlock(&fd_g_peers_rw) );
	li_inf = &fd_g_peers;
	for (li = fd_g_peers.next; li != &fd_g_peers; li = li->next) {
		struct fd_peer * next = (struct fd_peer *)li;
		int cont;
		int cmp = fd_os_almostcasesrch( p->p_hdr.info.pi_diamid, p->p_hdr.info.pi_diamidlen, 
						next->p_hdr.info.pi_diamid, next->p_hdr.info.pi_diamidlen,
						&cont );
		if (cmp > 0)
			li_inf = li; /* it will come after this element, for sure */
		
		if (cmp == 0) {
			ret = EEXIST; /* we have a duplicate */
			break;
		}
		if (!cont)
			break;
	}
	
	/* We can insert the new peer object */
	if (! ret)
		do {
			/* Update expiry list */
			CHECK_FCT_DO( ret = fd_p_expi_update( p ), break );

			/* Insert the new element in the list */
			fd_list_insert_after( li_inf, &p->p_hdr.chain );
		} while (0);

	CHECK_POSIX( pthread_rwlock_unlock(&fd_g_peers_rw) );
	if (ret) {
		CHECK_FCT( fd_peer_free(&p) );
	} else {
		CHECK_FCT( fd_psm_begin(p) );
	}
	return ret;
}
Пример #11
0
Condition::Condition()
{
  CHECK_POSIX(::pthread_cond_init(&m_condition, 0));
}
Пример #12
0
void Condition::Wait()
{
  CHECK_POSIX(::pthread_cond_wait(&m_condition, &m_mutex.m_mutex));
}
Пример #13
0
void Condition::SignalAll()
{
  CHECK_POSIX(::pthread_cond_broadcast(&m_condition));
}
Пример #14
0
void Condition::Signal()
{
  CHECK_POSIX(::pthread_cond_signal(&m_condition));
}
Пример #15
0
Condition::~Condition()
{
  CHECK_POSIX(::pthread_cond_destroy(&m_condition));
}