コード例 #1
0
ファイル: hooks.c プロジェクト: KaushikBh/freeDiameter
/* 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
ファイル: hooks.c プロジェクト: KaushikBh/freeDiameter
/* Return the location of the permsgdata area corresponding to this handle, after eventually having created it. Return NULL in case of failure */
static struct fd_hook_permsgdata * get_or_create_pmd(struct fd_msg_pmdl *pmdl, struct fd_hook_data_hdl * h)
{
    struct fd_hook_permsgdata * ret = NULL;
    struct fd_list * li;

    CHECK_POSIX_DO( pthread_mutex_lock(&pmdl->lock), );

    if (pmdl->sentinel.o == NULL) {
        pmdl->sentinel.o = pmdl_free;
    }

    /* Search in the list for an item with the same handle. The list is ordered by this handle */
    for (li=pmdl->sentinel.next; li != &pmdl->sentinel; li = li->next) {
        struct pmd_list_item * pli = (struct pmd_list_item *) li;
        if (pli->hdl == h)
            ret = &pli->pmd;
        if (pli->hdl >= h)
            break;
    }
    if (!ret) {
        /* we need to create a new one and insert before li */
        struct pmd_list_item * pli;
        CHECK_MALLOC_DO( pli = malloc(sizeof_pmd(h)), );
        if (pli) {
            memset(pli, 0, sizeof_pmd(h));
            fd_list_init(&pli->chain, pli);
            pli->hdl = h;
            ret = &pli->pmd;
            if (h->pmd_init_cb) {
                (*h->pmd_init_cb)(ret);
            }
            fd_list_insert_before(li, &pli->chain);
        }
    }

    CHECK_POSIX_DO( pthread_mutex_unlock(&pmdl->lock), );
    return ret;
}
コード例 #3
0
ファイル: peers.c プロジェクト: Lucky7Studio/freeDiameter
/* 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;
}