Navigation



Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • freeDiameter/peers.c

    r20 r29  
    101101       
    102102        p->p_hdr.info.pi_lft     = info->pi_lft;
    103         p->p_hdr.info.pi_streams = info->pi_streams;
    104103        p->p_hdr.info.pi_port    = info->pi_port;
    105104        p->p_hdr.info.pi_tctimer = info->pi_tctimer;
    106105        p->p_hdr.info.pi_twtimer = info->pi_twtimer;
     106       
     107        if (info->pi_sec_data.priority) {
     108                CHECK_MALLOC( p->p_hdr.info.pi_sec_data.priority = strdup(info->pi_sec_data.priority) );
     109        }
    107110       
    108111        /* Move the items from one list to the other */
     
    114117                }
    115118       
     119       
    116120        /* The internal data */
    117121        if (orig_dbg) {
     
    127131       
    128132        for (li = fd_g_peers.next; li != &fd_g_peers; li = li->next) {
    129                 struct fd_peer * prev = (struct fd_peer *)li;
    130                 int cmp = strcasecmp( p->p_hdr.info.pi_diamid, prev->p_hdr.info.pi_diamid );
    131                 if (cmp < 0)
     133                struct fd_peer * next = (struct fd_peer *)li;
     134                int cmp = strcasecmp( p->p_hdr.info.pi_diamid, next->p_hdr.info.pi_diamid );
     135                if (cmp > 0)
    132136                        continue;
    133137                if (cmp == 0)
     
    229233       
    230234        if (p->p_cnxctx) {
    231                 TODO("destroy p->p_cnxctx");
     235                fd_cnx_destroy(p->p_cnxctx);
    232236        }
    233237       
     
    293297                list_empty = FD_IS_LIST_EMPTY(&fd_g_peers);
    294298                CHECK_FCT_DO( pthread_rwlock_unlock(&fd_g_peers_rw), /* continue */ );
     299                CHECK_SYS(  clock_gettime(CLOCK_REALTIME, &now)  );
    295300        }
    296301       
     
    370375}
    371376
     377/* Handle an incoming CER request on a new connection */
     378int fd_peer_handle_newCER( struct msg ** cer, struct cnxctx ** cnx )
     379{
     380        struct msg * msg;
     381        struct dict_object *avp_oh_model;
     382        avp_code_t code = AC_ORIGIN_HOST;
     383        struct avp *avp_oh;
     384        struct avp_hdr * avp_hdr;
     385        struct fd_list * li;
     386        int found = 0;
     387        int ret = 0;
     388        struct fd_peer * peer;
     389        struct cnx_incoming * ev_data;
     390       
     391        TRACE_ENTRY("%p %p", cer, cnx);
     392        CHECK_PARAMS(cer && *cer && cnx && *cnx);
     393       
     394        msg = *cer;
     395       
     396        /* Find the Diameter Identity of the remote peer in the message */
     397        CHECK_FCT( fd_dict_search ( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_CODE, &code, &avp_oh_model, ENOENT) );
     398        CHECK_FCT( fd_msg_search_avp ( msg, avp_oh_model, &avp_oh ) );
     399        CHECK_FCT( fd_msg_avp_hdr ( avp_oh, &avp_hdr ) );
     400       
     401        /* Search if we already have this peer id in our list */
     402        CHECK_POSIX( pthread_rwlock_rdlock(&fd_g_peers_rw) );
     403       
     404        for (li = fd_g_peers.next; li != &fd_g_peers; li = li->next) {
     405                peer = (struct fd_peer *)li;
     406                int cmp = strncasecmp( avp_hdr->avp_value->os.data, peer->p_hdr.info.pi_diamid, avp_hdr->avp_value->os.len );
     407                if (cmp > 0)
     408                        continue;
     409                if (cmp == 0)
     410                        found = 1;
     411                break;
     412        }
     413       
     414        if (!found) {
     415                /* Create a new peer entry for this new remote peer */
     416                peer = NULL;
     417                CHECK_FCT_DO( ret = fd_peer_alloc(&peer), goto out );
     418               
     419                /* Set the peer Diameter Id and the responder flag parameters */
     420                CHECK_MALLOC_DO( peer->p_hdr.info.pi_diamid = malloc(avp_hdr->avp_value->os.len + 1), { ret = ENOMEM; goto out; } );
     421                CHECK_MALLOC_DO( peer->p_dbgorig = strdup(fd_cnx_getid(*cnx)), { ret = ENOMEM; goto out; } );
     422                peer->p_flags.pf_responder = 1;
     423               
     424                /* Upgrade the lock to write lock */
     425                CHECK_POSIX_DO( ret = pthread_rwlock_wrlock(&fd_g_peers_rw), goto out );
     426               
     427                /* Insert the new peer in the list (the PSM will take care of setting the expiry after validation) */
     428                fd_list_insert_before( li, &peer->p_hdr.chain );
     429               
     430                /* Release the write lock */
     431                CHECK_POSIX_DO( ret = pthread_rwlock_unlock(&fd_g_peers_rw), goto out );
     432               
     433                /* Start the PSM, which will receive the event bellow */
     434                CHECK_FCT_DO( ret = fd_psm_begin(peer), goto out );
     435        }
     436               
     437        /* Send the new connection event to the PSM */
     438        CHECK_MALLOC_DO( ev_data = malloc(sizeof(struct cnx_incoming)), { ret = ENOMEM; goto out; } );
     439        memset(ev_data, 0, sizeof(ev_data));
     440       
     441        ev_data->cer = msg;
     442        ev_data->cnx = *cnx;
     443        ev_data->validate = !found;
     444       
     445        CHECK_FCT_DO( ret = fd_event_send(peer->p_events, FDEVP_CNX_INCOMING, sizeof(ev_data), ev_data), goto out );
     446       
     447out:   
     448        CHECK_POSIX( pthread_rwlock_unlock(&fd_g_peers_rw) );
     449
     450        if (ret == 0) {
     451                /* Reset the "out" parameters, so that they are not cleanup on function return. */
     452                *cer = NULL;
     453                *cnx = NULL;
     454        }
     455       
     456        return ret;
     457}
     458
     459/* Save a callback to accept / reject incoming unknown peers */
     460int fd_peer_validate_register ( int (*peer_validate)(struct peer_info * /* info */, int * /* auth */, int (**cb2)(struct peer_info *)) )
     461{
     462       
     463        TODO("...");
     464        return ENOTSUP;
     465}
     466
     467/* Validate a peer by calling the callbacks in turn -- return 0 if the peer is validated, ! 0 in case of error or if the peer is rejected */
     468int fd_peer_validate( struct fd_peer * peer )
     469{
     470        TODO("Default to reject");
     471        TODO("Call all callbacks in turn");
     472        TODO("Save cb2 in the peer if needed");
     473        return ENOTSUP;
     474}
Note: See TracChangeset for help on using the changeset viewer.