Navigation


Changeset 37:cc3c59fe98fe in freeDiameter


Ignore:
Timestamp:
Nov 5, 2009, 2:28:46 PM (15 years ago)
Author:
Sebastien Decugis <sdecugis@nict.go.jp>
Branch:
default
Phase:
public
Message:

Lot of cleanups in peer structure management

Files:
1 added
10 edited

Legend:

Unmodified
Added
Removed
  • freeDiameter/CMakeLists.txt

    r36 r37  
    2121        peers.c
    2222        p_ce.c
     23        p_cnx.c
    2324        p_dw.c
    2425        p_dp.c
  • freeDiameter/fD.h

    r36 r37  
    119119        /* Some flags influencing the peer state machine */
    120120        struct {
    121                 unsigned pf_responder   : 1;    /* The local peer is responder on the connection */
     121                unsigned pf_responder   : 1;    /* The peer has been created to handle incoming connection */
    122122               
    123123                unsigned pf_dw_pending  : 1;    /* A DWR message was sent and not answered yet */
     
    125125                unsigned pf_cnx_pb      : 1;    /* The peer was disconnected because of watchdogs; must exchange 3 watchdogs before putting back to normal */
    126126                unsigned pf_reopen_cnt  : 2;    /* remaining DW to be exchanged after re-established connection */
    127                
    128                 /* to be completed */
    129127               
    130128        }                p_flags;
     
    144142        /* Sent requests (for fallback), list of struct sentreq ordered by hbh */
    145143        struct sr_list   p_sr;
     144       
     145        /* Data for transitional states before the peer is in OPEN state */
     146        struct {
     147                struct cnxctx * p_initiator;    /* Connection before CEA is received */
     148                struct cnxctx * p_receiver;     /* Only used in case of election */
     149                pthread_t       p_ini_thr;
     150        };
     151               
    146152       
    147153        /* connection context: socket and related information */
     
    176182        ,FDEVP_CNX_EP_CHANGE
    177183       
    178         /* A new connection has been established (data contains the appropriate info) */
     184        /* A new connection (with a CER) has been received */
    179185        ,FDEVP_CNX_INCOMING
     186       
     187        /* A new connection has been established to the remote peer (event data is the cnxctx object) */
     188        ,FDEVP_CNX_ESTABLISHED
    180189       
    181190        /* The PSM state is expired */
     
    196205                case_str(FDEVP_CNX_EP_CHANGE);          \
    197206                case_str(FDEVP_CNX_INCOMING);           \
     207                case_str(FDEVP_CNX_ESTABLISHED);        \
    198208                case_str(FDEVP_PSM_TIMEOUT);            \
    199209        }                                               \
  • freeDiameter/fdd.y

    r36 r37  
    316316connpeer:               {
    317317                                memset(&fddpi, 0, sizeof(fddpi));
     318                                fddpi.config.pic_flags.persist = PI_PRST_ALWAYS;
    318319                                fd_list_init( &fddpi.pi_endpoints, NULL );
    319                                 fd_list_init( &fddpi.pi_apps, NULL );
    320                                 fddpi.pi_flags.persist = PI_PRST_ALWAYS;
    321320                        }
    322321                        CONNPEER '=' QSTRING peerinfo ';'
     
    328327                                /* Now destroy any content in the structure */
    329328                                free(fddpi.pi_diamid);
    330                                 free(fddpi.pi_sec_data.priority);
     329                                free(fddpi.config.pic_realm);
     330                                free(fddpi.config.pic_priority);
    331331                                while (!FD_IS_LIST_EMPTY(&fddpi.pi_endpoints)) {
    332332                                        struct fd_list * li = fddpi.pi_endpoints.next;
     
    344344                        | peerparams NOIP ';'
    345345                        {
    346                                 if ((conf->cnf_flags.no_ip6) || (fddpi.pi_flags.pro3 == PI_P3_IP)) {
     346                                if ((conf->cnf_flags.no_ip6) || (fddpi.config.pic_flags.pro3 == PI_P3_IP)) {
    347347                                        yyerror (&yylloc, conf, "No_IP conflicts with a No_IPv6 directive.");
    348348                                        YYERROR;
    349349                                }
    350350                                got_peer_noip++;
    351                                 fddpi.pi_flags.pro3 = PI_P3_IPv6;
     351                                fddpi.config.pic_flags.pro3 = PI_P3_IPv6;
    352352                        }
    353353                        | peerparams NOIP6 ';'
    354354                        {
    355                                 if ((conf->cnf_flags.no_ip4) || (fddpi.pi_flags.pro3 == PI_P3_IPv6)) {
     355                                if ((conf->cnf_flags.no_ip4) || (fddpi.config.pic_flags.pro3 == PI_P3_IPv6)) {
    356356                                        yyerror (&yylloc, conf, "No_IPv6 conflicts with a No_IP directive.");
    357357                                        YYERROR;
    358358                                }
    359359                                got_peer_noipv6++;
    360                                 fddpi.pi_flags.pro3 = PI_P3_IP;
     360                                fddpi.config.pic_flags.pro3 = PI_P3_IP;
    361361                        }
    362362                        | peerparams NOTCP ';'
     
    366366                                        YYERROR;
    367367                                #endif
    368                                 if ((conf->cnf_flags.no_sctp) || (fddpi.pi_flags.pro4 == PI_P4_TCP)) {
     368                                if ((conf->cnf_flags.no_sctp) || (fddpi.config.pic_flags.pro4 == PI_P4_TCP)) {
    369369                                        yyerror (&yylloc, conf, "No_TCP conflicts with a No_SCTP directive.");
    370370                                        YYERROR;
    371371                                }
    372372                                got_peer_notcp++;
    373                                 fddpi.pi_flags.pro4 = PI_P4_SCTP;
     373                                fddpi.config.pic_flags.pro4 = PI_P4_SCTP;
    374374                        }
    375375                        | peerparams NOSCTP ';'
    376376                        {
    377                                 if ((conf->cnf_flags.no_tcp) || (fddpi.pi_flags.pro4 == PI_P4_SCTP)) {
     377                                if ((conf->cnf_flags.no_tcp) || (fddpi.config.pic_flags.pro4 == PI_P4_SCTP)) {
    378378                                        yyerror (&yylloc, conf, "No_SCTP conflicts with a No_TCP directive.");
    379379                                        YYERROR;
    380380                                }
    381381                                got_peer_nosctp++;
    382                                 fddpi.pi_flags.pro4 = PI_P4_TCP;
     382                                fddpi.config.pic_flags.pro4 = PI_P4_TCP;
    383383                        }
    384384                        | peerparams PREFERTCP ';'
    385385                        {
    386                                 fddpi.pi_flags.alg = PI_ALGPREF_TCP;
     386                                fddpi.config.pic_flags.alg = PI_ALGPREF_TCP;
    387387                        }
    388388                        | peerparams OLDTLS ';'
    389389                        {
    390                                 if (fddpi.pi_flags.sec == PI_SEC_NONE) {
    391                                         yyerror (&yylloc, conf, "ConnectPeer: TLS_old_method conflicts with No_TLS.");
    392                                         YYERROR;
    393                                 }
    394                                 fddpi.pi_flags.sec = PI_SEC_TLS_OLD;
     390                                fddpi.config.pic_flags.sec |= PI_SEC_TLS_OLD;
    395391                        }
    396392                        | peerparams NOTLS ';'
    397393                        {
    398                                 if (fddpi.pi_flags.sec == PI_SEC_TLS_OLD) {
    399                                         yyerror (&yylloc, conf, "ConnectPeer: No_TLS conflicts with TLS_old_method.");
    400                                         YYERROR;
    401                                 }
    402                                 fddpi.pi_flags.sec = PI_SEC_NONE;
     394                                fddpi.config.pic_flags.sec |= PI_SEC_NONE;
     395                        }
     396                        | peerparams REALM '=' QSTRING ';'
     397                        {
     398                                fddpi.config.pic_realm = $4;
    403399                        }
    404400                        | peerparams PORT '=' INTEGER ';'
    405401                        {
    406402                                CHECK_PARAMS_DO( ($4 > 0) && ($4 < 1<<16),
    407                                         { yyerror (&yylloc, conf, "Invalid value"); YYERROR; } );
    408                                 fddpi.pi_port = (uint16_t)$4;
     403                                        { yyerror (&yylloc, conf, "Invalid port value"); YYERROR; } );
     404                                fddpi.config.pic_port = (uint16_t)$4;
    409405                        }
    410406                        | peerparams TCTIMER '=' INTEGER ';'
    411407                        {
    412                                 fddpi.pi_tctimer = $4;
     408                                fddpi.config.pic_tctimer = $4;
     409                        }
     410                        | peerparams TWTIMER '=' INTEGER ';'
     411                        {
     412                                fddpi.config.pic_twtimer = $4;
    413413                        }
    414414                        | peerparams TLS_PRIO '=' QSTRING ';'
    415415                        {
    416                                 fddpi.pi_sec_data.priority = $4;
    417                         }
    418                         | peerparams TWTIMER '=' INTEGER ';'
    419                         {
    420                                 fddpi.pi_twtimer = $4;
     416                                fddpi.config.pic_priority = $4;
    421417                        }
    422418                        | peerparams CONNTO '=' QSTRING ';'
  • freeDiameter/p_ce.c

    r36 r37  
    4747int fd_p_ce_handle_newCER(struct msg ** msg, struct fd_peer * peer, struct cnxctx ** cnx, int valid)
    4848{
    49         switch (peer->p_hdr.info.pi_state) {
     49        switch (peer->p_hdr.info.runtime.pir_state) {
    5050                case STATE_CLOSED:
    5151                        TODO("Handle the CER, validate the peer if needed (and set expiry), set the alt_fifo in the connection, reply a CEA, eventually handshake, move to OPEN or REOPEN state");
  • freeDiameter/p_expiry.c

    r36 r37  
    6161                        struct fd_peer * peer = (struct fd_peer *)li;
    6262                       
    63                         if (peer->p_hdr.info.pi_state != STATE_ZOMBIE)
     63                        if (peer->p_hdr.info.runtime.pir_state != STATE_ZOMBIE)
    6464                                continue;
    6565                       
    66                         if (peer->p_hdr.info.pi_flags.persist == PI_PRST_ALWAYS)
     66                        if (peer->p_hdr.info.config.pic_flags.persist == PI_PRST_ALWAYS)
    6767                                continue; /* This peer was not supposed to terminate, keep it in the list for debug */
    6868                       
     
    158158        CHECK_FCT_DO( fd_thr_term(&exp_thr), );
    159159        CHECK_POSIX( pthread_mutex_lock(&exp_mtx) );
    160        
    161160        while (!FD_IS_LIST_EMPTY(&exp_list)) {
    162161                struct fd_peer * peer = (struct fd_peer *)(exp_list.next->o);
    163162                fd_list_unlink(&peer->p_expiry );
    164163        }
    165        
    166164        CHECK_POSIX( pthread_mutex_unlock(&exp_mtx) );
     165       
    167166        CHECK_FCT_DO( fd_thr_term(&gc_thr), );
    168167        return 0;
     
    180179       
    181180        /* if peer expires */
    182         if (peer->p_hdr.info.pi_flags.exp) {
     181        if (peer->p_hdr.info.config.pic_flags.exp) {
    183182                struct fd_list * li;
    184183               
    185184                /* update the p_exp_timer value */
    186185                CHECK_SYS(  clock_gettime(CLOCK_REALTIME, &peer->p_exp_timer)  );
    187                 peer->p_exp_timer.tv_sec += peer->p_hdr.info.pi_lft;
     186                peer->p_exp_timer.tv_sec += peer->p_hdr.info.config.pic_lft;
    188187               
    189188                /* add to the expiry list in appropriate position (probably around the end) */
  • freeDiameter/p_out.c

    r35 r37  
    140140        CHECK_PARAMS( msg && *msg && (cnx || (peer && peer->p_cnxctx)));
    141141       
    142         if (peer && (peer->p_hdr.info.pi_state == STATE_OPEN)) {
     142        if (peer && (peer->p_hdr.info.runtime.pir_state == STATE_OPEN)) {
    143143                /* Normal case: just queue for the out thread to pick it up */
    144144                CHECK_FCT( fd_fifo_post(peer->p_tosend, msg) );
  • freeDiameter/p_psm.c

    r36 r37  
    9595                        {
    9696                                TRACE_DEBUG(FULL, "Validation failed, moving to state CLOSING");
    97                                 peer->p_hdr.info.pi_state = STATE_CLOSING;
     97                                peer->p_hdr.info.runtime.pir_state = STATE_CLOSING;
    9898                                fd_psm_terminate(peer);
    9999                        } );
     
    123123        CHECK_FCT( fd_out_start(peer) );
    124124       
     125        /* Update the expiry timer now */
     126        CHECK_FCT( fd_p_expi_update(peer) );
     127       
    125128        return 0;
    126129}
     
    145148/*                      Helpers for state changes                       */
    146149/************************************************************************/
     150
     151/* Cleanup pending events in the peer */
     152void fd_psm_events_free(struct fd_peer * peer)
     153{
     154        struct fd_event * ev;
     155        /* Purge all events, and free the associated data if any */
     156        while (fd_fifo_tryget( peer->p_events, &ev ) == 0) {
     157                switch (ev->code) {
     158                        case FDEVP_CNX_ESTABLISHED: {
     159                                fd_cnx_destroy(ev->data);
     160                        }
     161                        break;
     162                       
     163                        case FDEVP_CNX_INCOMING: {
     164                                struct cnx_incoming * evd = ev->data;
     165                                CHECK_FCT_DO( fd_msg_free(evd->cer), /* continue */);
     166                                fd_cnx_destroy(evd->cnx);
     167                        }
     168                        default:
     169                                free(ev->data);
     170                }
     171                free(ev);
     172        }
     173}
     174
     175
    147176/* Change state */
    148177int fd_psm_change_state(struct fd_peer * peer, int new_state)
     
    152181        TRACE_ENTRY("%p %d(%s)", peer, new_state, STATE_STR(new_state));
    153182        CHECK_PARAMS( CHECK_PEER(peer) );
    154         old = peer->p_hdr.info.pi_state;
     183        old = peer->p_hdr.info.runtime.pir_state;
    155184        if (old == new_state)
    156185                return 0;
     
    165194        }
    166195       
    167         peer->p_hdr.info.pi_state = new_state;
     196        peer->p_hdr.info.runtime.pir_state = new_state;
    168197       
    169198        if (new_state == STATE_OPEN) {
     
    171200        }
    172201       
    173         if ((new_state == STATE_CLOSED) && (peer->p_hdr.info.pi_flags.persist == PI_PRST_NONE)) {
    174                 CHECK_FCT( fd_event_send(peer->p_events, FDEVP_TERMINATE, 0, NULL) );
     202        if (new_state == STATE_CLOSED) {
     203                /* Purge event list */
     204                fd_psm_events_free(peer);
     205               
     206                /* If the peer is not persistant, we destroy it */
     207                if (peer->p_hdr.info.config.pic_flags.persist == PI_PRST_NONE) {
     208                        CHECK_FCT( fd_event_send(peer->p_events, FDEVP_TERMINATE, 0, NULL) );
     209                }
    175210        }
    176211       
     
    210245void fd_psm_cleanup(struct fd_peer * peer)
    211246{
    212         /* Move to CLOSED state */
     247        /* Move to CLOSED state: failover messages, stop OUT thread, unlink peer from active list */
    213248        CHECK_FCT_DO( fd_psm_change_state(peer, STATE_CLOSED), /* continue */ );
    214249       
    215         /* Destroy the connection */
     250        /* Destroy data */
     251        CHECK_FCT_DO( fd_thr_term(&peer->p_ini_thr), /* continue */);
    216252        if (peer->p_cnxctx) {
    217253                fd_cnx_destroy(peer->p_cnxctx);
    218254                peer->p_cnxctx = NULL;
    219255        }
    220        
    221         /* What else ? */
    222         TODO("...");
     256        if (peer->p_initiator) {
     257                fd_cnx_destroy(peer->p_initiator);
     258                peer->p_initiator = NULL;
     259        }
     260        if (peer->p_receiver) {
     261                fd_cnx_destroy(peer->p_receiver);
     262                peer->p_receiver = NULL;
     263        }
    223264       
    224265}
     
    233274        struct fd_peer * peer = (struct fd_peer *)arg;
    234275        CHECK_PARAMS_DO( CHECK_PEER(peer), return );
    235         peer->p_hdr.info.pi_state = STATE_ZOMBIE;
     276        peer->p_hdr.info.runtime.pir_state = STATE_ZOMBIE;
    236277        return;
    237278}
     
    258299       
    259300        /* The state machine starts in CLOSED state */
    260         peer->p_hdr.info.pi_state = STATE_CLOSED;
     301        peer->p_hdr.info.runtime.pir_state = STATE_CLOSED;
    261302       
    262303        /* Wait that the PSM are authorized to start in the daemon */
     
    274315        CHECK_FCT_DO( fd_event_timedget(peer->p_events, &peer->p_psm_timer, FDEVP_PSM_TIMEOUT, &event, &ev_sz, &ev_data), goto psm_end );
    275316        TRACE_DEBUG(FULL, "'%s'\t<-- '%s'\t(%p,%zd)\t'%s'",
    276                         STATE_STR(peer->p_hdr.info.pi_state),
     317                        STATE_STR(peer->p_hdr.info.runtime.pir_state),
    277318                        fd_pev_str(event), ev_data, ev_sz,
    278319                        peer->p_hdr.info.pi_diamid);
     
    281322
    282323        /* The following states are impossible */
    283         ASSERT( peer->p_hdr.info.pi_state != STATE_NEW );
    284         ASSERT( peer->p_hdr.info.pi_state != STATE_ZOMBIE );
    285         ASSERT( peer->p_hdr.info.pi_state != STATE_OPEN_HANDSHAKE ); /* because it exists only between two loops */
     324        ASSERT( peer->p_hdr.info.runtime.pir_state != STATE_NEW );
     325        ASSERT( peer->p_hdr.info.runtime.pir_state != STATE_ZOMBIE );
     326        ASSERT( peer->p_hdr.info.runtime.pir_state != STATE_OPEN_HANDSHAKE ); /* because it exists only between two loops */
    286327
    287328        /* Purge invalid events */
     
    299340        /* Requests to terminate the peer object */
    300341        if (event == FDEVP_TERMINATE) {
    301                 switch (peer->p_hdr.info.pi_state) {
     342                switch (peer->p_hdr.info.runtime.pir_state) {
    302343                        case STATE_OPEN:
    303344                        case STATE_REOPEN:
     
    325366                struct msg_hdr * hdr;
    326367               
     368                /* If the current state does not allow receiving messages, just drop it */
     369                if (peer->p_hdr.info.runtime.pir_state == STATE_CLOSED) {
     370                        TRACE_DEBUG(FULL, "Purging message in queue while in CLOSED state (%zdb)", ev_sz);
     371                        free(ev_data);
     372                        goto psm_loop;
     373                }
     374               
    327375                /* Parse the received buffer */
    328376                CHECK_FCT_DO( fd_msg_parse_buffer( (void *)&ev_data, ev_sz, &msg),
     
    339387                CHECK_FCT_DO( fd_msg_hdr(msg, &hdr), goto psm_end );
    340388               
    341                 /* If it is an answer, associate with the request */
     389                /* If it is an answer, associate with the request or drop */
    342390                if (!(hdr->msg_flags & CMD_FLAG_REQUEST)) {
    343391                        struct msg * req;
     
    345393                        CHECK_FCT_DO( fd_p_sr_fetch(&peer->p_sr, hdr->msg_hbhid, &req), goto psm_end );
    346394                        if (req == NULL) {
    347                                 fd_log_debug("Received a Diameter answer message with no corresponding sent request, discarding...\n");
     395                                fd_log_debug("Received a Diameter answer message with no corresponding sent request, discarding.\n");
    348396                                fd_msg_dump_walk(NONE, msg);
    349397                                fd_msg_free(msg);
     
    357405                /* Now handle non-link-local messages */
    358406                if (fd_msg_is_routable(msg)) {
    359                         /* If we are not in OPEN state, discard the message */
    360                         if (peer->p_hdr.info.pi_state != STATE_OPEN) {
    361                                 fd_log_debug("Received a routable message while not in OPEN state from peer '%s', discarded.\n", peer->p_hdr.info.pi_diamid);
    362                                 fd_msg_dump_walk(NONE, msg);
    363                                 fd_msg_free(msg);
    364                         } else {
    365                                 /* We received a valid message, update the expiry timer */
    366                                 CHECK_FCT_DO( fd_p_expi_update(peer), goto psm_end );
    367 
    368                                 /* Set the message source and add the Route-Record */
    369                                 CHECK_FCT_DO( fd_msg_source_set( msg, peer->p_hdr.info.pi_diamid, 1, fd_g_config->cnf_dict ), goto psm_end);
    370 
    371                                 /* Requeue to the global incoming queue */
    372                                 CHECK_FCT_DO(fd_fifo_post(fd_g_incoming, &msg), goto psm_end );
    373                                
    374                                 /* Update the peer timer */
    375                                 if (!peer->p_flags.pf_dw_pending) {
    376                                         fd_psm_next_timeout(peer, 1, peer->p_hdr.info.pi_twtimer ?: fd_g_config->cnf_timer_tw);
    377                                 }
     407                        switch (peer->p_hdr.info.runtime.pir_state) {
     408                                /* To maximize compatibility -- should not be a security issue here */
     409                                case STATE_REOPEN:
     410                                case STATE_SUSPECT:
     411                                case STATE_CLOSING:
     412                                        TRACE_DEBUG(FULL, "Accepted a message while not in OPEN state");
     413                                /* The standard situation : */
     414                                case STATE_OPEN:
     415                                        /* We received a valid message, update the expiry timer */
     416                                        CHECK_FCT_DO( fd_p_expi_update(peer), goto psm_end );
     417
     418                                        /* Set the message source and add the Route-Record */
     419                                        CHECK_FCT_DO( fd_msg_source_set( msg, peer->p_hdr.info.pi_diamid, 1, fd_g_config->cnf_dict ), goto psm_end);
     420
     421                                        /* Requeue to the global incoming queue */
     422                                        CHECK_FCT_DO(fd_fifo_post(fd_g_incoming, &msg), goto psm_end );
     423
     424                                        /* Update the peer timer (only in OPEN state) */
     425                                        if ((peer->p_hdr.info.runtime.pir_state == STATE_OPEN) && (!peer->p_flags.pf_dw_pending)) {
     426                                                fd_psm_next_timeout(peer, 1, peer->p_hdr.info.config.pic_twtimer ?: fd_g_config->cnf_timer_tw);
     427                                        }
     428                                        break;
     429                                       
     430                                /* In other states, we discard the message, it is either old or invalid to send it for the remote peer */
     431                                case STATE_WAITCNXACK:
     432                                case STATE_WAITCNXACK_ELEC:
     433                                case STATE_WAITCEA:
     434                                case STATE_CLOSED:
     435                                default:
     436                                        /* In such case, just discard the message */
     437                                        fd_log_debug("Received a routable message while not in OPEN state from peer '%s', discarded.\n", peer->p_hdr.info.pi_diamid);
     438                                        fd_msg_dump_walk(NONE, msg);
     439                                        fd_msg_free(msg);
    378440                        }
    379441                        goto psm_loop;
    380442                }
    381443               
    382                 /* Link-local message: They must be understood by our dictionary */
     444                /* Link-local message: They must be understood by our dictionary, otherwise we return an error */
    383445                {
    384446                        int ret;
     
    396458                }
    397459               
    398                 ASSERT( hdr->msg_appl == 0 ); /* buggy fd_msg_is_routable() ? */
    399                
    400460                /* Handle the LL message and update the expiry timer appropriately */
    401461                switch (hdr->msg_code) {
    402                         case CC_DEVICE_WATCHDOG:
    403                                 CHECK_FCT_DO( fd_p_dw_handle(&msg, peer), goto psm_end );
     462                        case CC_CAPABILITIES_EXCHANGE:
     463                                CHECK_FCT_DO( fd_p_ce_handle(&msg, peer), goto psm_end );
    404464                                break;
    405465                       
     
    408468                                break;
    409469                       
    410                         case CC_CAPABILITIES_EXCHANGE:
    411                                 CHECK_FCT_DO( fd_p_ce_handle(&msg, peer), goto psm_end );
     470                        case CC_DEVICE_WATCHDOG:
     471                                CHECK_FCT_DO( fd_p_dw_handle(&msg, peer), goto psm_end );
    412472                                break;
    413473                       
    414474                        default:
    415475                                /* Unknown / unexpected / invalid message */
    416                                 TODO("Log, return error message if request");
     476                                fd_log_debug("Received an unknown local message from peer '%s', discarded.\n", peer->p_hdr.info.pi_diamid);
     477                                fd_msg_dump_walk(NONE, msg);
     478                                if (hdr->msg_flags & CMD_FLAG_REQUEST) {
     479                                        do {
     480                                                /* Reply with an error code */
     481                                                CHECK_FCT_DO( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, &msg, MSGFL_ANSW_ERROR ), break );
     482
     483                                                /* Set the error code */
     484                                                CHECK_FCT_DO( fd_msg_rescode_set(msg, "DIAMETER_INVALID_HDR_BITS", NULL, NULL, 1 ), break );
     485
     486                                                /* Send the answer */
     487                                                CHECK_FCT_DO( fd_out_send(&msg, peer->p_cnxctx, peer), break );
     488                                        } while (0);
     489                                } else {
     490                                        /* We did ASK for it ??? */
     491                                        fd_log_debug("Invalid PXY flag in header ?\n");
     492                                }
     493                               
     494                                /* Cleanup the message if not done */
     495                                if (msg) {
     496                                        CHECK_FCT_DO( fd_msg_free(msg), /* continue */);
     497                                        msg = NULL;
     498                                }
    417499                };
    418500               
     
    429511        /* The connection object is broken */
    430512        if (event == FDEVP_CNX_ERROR) {
    431                 /* Cleanup the peer */
    432                 fd_psm_cleanup(peer);
    433                
    434                 /* Mark the connection problem */
    435                 peer->p_flags.pf_cnx_pb = 1;
    436                
    437                 /* Move to CLOSED */
    438                 CHECK_FCT_DO( fd_psm_change_state(peer, STATE_CLOSED), goto psm_end );
    439                
    440                 /* Reset the timer */
    441                 fd_psm_next_timeout(peer, 1, peer->p_hdr.info.pi_tctimer ?: fd_g_config->cnf_timer_tc);
    442                
    443                 /* Loop */
    444                 goto psm_loop;
     513                switch (peer->p_hdr.info.runtime.pir_state) {
     514                        case STATE_WAITCNXACK_ELEC:
     515                                TODO("Reply CEA on the receiver side and go to OPEN state");
     516                                goto psm_loop;
     517                       
     518                        case STATE_OPEN:
     519                        case STATE_REOPEN:
     520                        case STATE_WAITCNXACK:
     521                        case STATE_WAITCEA:
     522                        case STATE_SUSPECT:
     523                        default:
     524                                /* Mark the connection problem */
     525                                peer->p_flags.pf_cnx_pb = 1;
     526                               
     527                        case STATE_CLOSING:
     528                                /* Cleanup the peer */
     529                                fd_psm_cleanup(peer);
     530
     531                                /* Reset the timer */
     532                                fd_psm_next_timeout(peer, 1, peer->p_hdr.info.config.pic_tctimer ?: fd_g_config->cnf_timer_tc);
     533                               
     534                        case STATE_CLOSED:
     535                                /* Go to the next event */
     536                                goto psm_loop;
     537                }
    445538        }
    446539       
    447540        /* The connection notified a change in endpoints */
    448541        if (event == FDEVP_CNX_EP_CHANGE) {
     542                /* We actually don't care if we are in OPEN state here... */
     543               
    449544                /* Cleanup the remote LL and primary addresses */
    450545                CHECK_FCT_DO( fd_ep_filter( &peer->p_hdr.info.pi_endpoints, EP_FL_CONF | EP_FL_DISC | EP_FL_ADV ), /* ignore the error */);
     
    454549                CHECK_FCT_DO( fd_cnx_getendpoints(peer->p_cnxctx, NULL, &peer->p_hdr.info.pi_endpoints), /* ignore the error */);
    455550               
     551                /* We do not support local endpoints change currently, but it could be added here if needed */
     552               
    456553                if (TRACE_BOOL(ANNOYING)) {
    457                         fd_log_debug("New remote endpoint(s):\n");
     554                        TRACE_DEBUG(ANNOYING, "New remote endpoint(s):" );
    458555                        fd_ep_dump(6, &peer->p_hdr.info.pi_endpoints);
    459556                }
     
    488585        /* The timeout for the current state has been reached */
    489586        if (event == FDEVP_PSM_TIMEOUT) {
    490                 switch (peer->p_hdr.info.pi_state) {
     587                switch (peer->p_hdr.info.runtime.pir_state) {
    491588                        case STATE_OPEN:
    492589                        case STATE_REOPEN:
     
    495592                               
    496593                        case STATE_CLOSED:
    497                                 TODO("Initiate a new connection");
     594                                CHECK_FCT_DO( fd_psm_change_state(peer, STATE_WAITCNXACK), goto psm_end );
     595                                fd_psm_next_timeout(peer, 0, CNX_TIMEOUT);
     596                                CHECK_FCT_DO( fd_p_cnx_init(peer), goto psm_end );
    498597                                break;
    499598                               
     
    504603                                /* Destroy the connection, restart the timer to a new connection attempt */
    505604                                fd_psm_cleanup(peer);
    506                                 fd_psm_next_timeout(peer, 1, peer->p_hdr.info.pi_tctimer ?: fd_g_config->cnf_timer_tc);
    507                                 CHECK_FCT_DO( fd_psm_change_state(peer, STATE_CLOSED), goto psm_end );
     605                                fd_psm_next_timeout(peer, 1, peer->p_hdr.info.config.pic_tctimer ?: fd_g_config->cnf_timer_tc);
    508606                                break;
    509607                               
     
    515613       
    516614        /* Default action : the handling has not yet been implemented. [for debug only] */
    517         TODO("Missing handler in PSM : '%s'\t<-- '%s'", STATE_STR(peer->p_hdr.info.pi_state), fd_pev_str(event));
     615        TODO("Missing handler in PSM : '%s'\t<-- '%s'", STATE_STR(peer->p_hdr.info.runtime.pir_state), fd_pev_str(event));
    518616        if (event == FDEVP_PSM_TIMEOUT) {
    519617                /* We have not handled timeout in this state, let's postpone next alert */
     
    525623psm_end:
    526624        fd_psm_cleanup(peer);
     625        CHECK_FCT_DO( fd_fifo_del(&peer->p_events), /* continue */ );
    527626        pthread_cleanup_pop(1); /* set STATE_ZOMBIE */
    528627        peer->p_psm = (pthread_t)NULL;
     
    541640       
    542641        /* Check the peer and state are OK */
    543         CHECK_PARAMS( CHECK_PEER(peer) && (peer->p_hdr.info.pi_state == STATE_NEW) );
     642        CHECK_PARAMS( CHECK_PEER(peer) && (peer->p_hdr.info.runtime.pir_state == STATE_NEW) );
     643       
     644        /* Create the FIFO for events */
     645        CHECK_FCT( fd_fifo_new(&peer->p_events) );
    544646       
    545647        /* Create the PSM controler thread */
     
    556658        CHECK_PARAMS( CHECK_PEER(peer) );
    557659       
    558         if (peer->p_hdr.info.pi_state != STATE_ZOMBIE) {
     660        if (peer->p_hdr.info.runtime.pir_state != STATE_ZOMBIE) {
    559661                CHECK_FCT( fd_event_send(peer->p_events, FDEVP_TERMINATE, 0, NULL) );
    560662        } else {
     
    572674        CHECK_FCT_DO( fd_thr_term(&peer->p_psm), /* continue */ );
    573675       
    574         /* Cancel the OUT thread */
    575         CHECK_FCT_DO( fd_out_stop(peer), /* continue */ );
    576        
    577         /* Cleanup the connection */
    578         if (peer->p_cnxctx) {
    579                 fd_cnx_destroy(peer->p_cnxctx);
    580         }
    581        
    582         /* Failover the messages */
    583         fd_peer_failover_msg(peer);
    584        
    585         /* Empty the events list, this might leak some memory, but we only do it on exit, so... */
    586         fd_event_destroy(&peer->p_events, free);
    587        
    588         /* More cleanups are performed in fd_peer_free */
     676        /* Cleanup the data */
     677        fd_psm_cleanup(peer);
     678       
     679        /* Destroy the event list */
     680        CHECK_FCT_DO( fd_fifo_del(&peer->p_events), /* continue */ );
     681       
     682        /* Remaining cleanups are performed in fd_peer_free */
    589683        return;
    590684}
  • freeDiameter/peers.c

    r36 r37  
    6969        fd_list_init(&p->p_hdr.chain, p);
    7070       
    71         fd_list_init(&p->p_hdr.info.pi_endpoints, NULL);
    72         fd_list_init(&p->p_hdr.info.pi_apps, NULL);
     71        fd_list_init(&p->p_hdr.info.pi_endpoints, p);
     72        fd_list_init(&p->p_hdr.info.runtime.pir_apps, p);
    7373       
    7474        p->p_eyec = EYEC_PEER;
     75        fd_list_init(&p->p_actives, p);
    7576        fd_list_init(&p->p_expiry, p);
    76         fd_list_init(&p->p_actives, p);
     77        CHECK_FCT( fd_fifo_new(&p->p_tosend) );
    7778        p->p_hbh = lrand48();
    78         CHECK_FCT( fd_fifo_new(&p->p_events) );
    79         CHECK_FCT( fd_fifo_new(&p->p_tosend) );
     79       
    8080        fd_list_init(&p->p_sr.srs, p);
    8181        CHECK_POSIX( pthread_mutex_init(&p->p_sr.mtx, NULL) );
     
    9898        /* Copy the informations from the parameters received */
    9999        CHECK_MALLOC( p->p_hdr.info.pi_diamid = strdup(info->pi_diamid) );
    100         if (info->pi_realm) {
    101                 CHECK_MALLOC( p->p_hdr.info.pi_realm = strdup(info->pi_realm) );
    102         }
    103        
    104         p->p_hdr.info.pi_flags.pro3     = info->pi_flags.pro3;
    105         p->p_hdr.info.pi_flags.pro4     = info->pi_flags.pro4;
    106         p->p_hdr.info.pi_flags.alg      = info->pi_flags.alg;
    107         p->p_hdr.info.pi_flags.sec      = info->pi_flags.sec;
    108         p->p_hdr.info.pi_flags.exp      = info->pi_flags.exp;
    109         p->p_hdr.info.pi_flags.persist  = info->pi_flags.persist;
    110        
    111         p->p_hdr.info.pi_lft            = info->pi_lft;
    112         p->p_hdr.info.pi_port           = info->pi_port;
    113         p->p_hdr.info.pi_tctimer        = info->pi_tctimer;
    114         p->p_hdr.info.pi_twtimer        = info->pi_twtimer;
    115        
    116         if (info->pi_sec_data.priority) {
    117                 CHECK_MALLOC( p->p_hdr.info.pi_sec_data.priority = strdup(info->pi_sec_data.priority) );
    118         }
    119        
    120         /* Move the items from one list to the other */
     100       
     101        memcpy( &p->p_hdr.info.config, &info->config, sizeof(p->p_hdr.info.config) );
     102        /* Duplicate the strings if provided */
     103        if (info->config.pic_realm) {
     104                CHECK_MALLOC( p->p_hdr.info.config.pic_realm = strdup(info->config.pic_realm) );
     105        }
     106        if (info->config.pic_priority) {
     107                CHECK_MALLOC( p->p_hdr.info.config.pic_realm = strdup(info->config.pic_priority) );
     108        }
     109       
     110        /* Move the list of endpoints into the peer */
    121111        if (info->pi_endpoints.next)
    122112                while (!FD_IS_LIST_EMPTY( &info->pi_endpoints ) ) {
     
    125115                        fd_list_insert_before(&p->p_hdr.info.pi_endpoints, li);
    126116                }
    127        
    128117       
    129118        /* The internal data */
     
    150139       
    151140        /* We can insert the new peer object */
    152         if (! ret) {
    153                 /* Update expiry list */
    154                 CHECK_FCT_DO( ret = fd_p_expi_update( p ), goto out );
    155                
    156                 /* Insert the new element in the list */
    157                 fd_list_insert_before( li, &p->p_hdr.chain );
    158         }
    159 
    160 out:   
     141        if (! ret)
     142                do {
     143                        /* Update expiry list */
     144                        CHECK_FCT_DO( ret = fd_p_expi_update( p ), break );
     145
     146                        /* Insert the new element in the list */
     147                        fd_list_insert_before( li, &p->p_hdr.chain );
     148                } while (0);
     149
    161150        CHECK_POSIX( pthread_rwlock_unlock(&fd_g_peers_rw) );
    162151        if (ret) {
     
    203192}
    204193
    205 /* Destroy a structure once all cleanups have been performed */
     194/* Destroy a structure once cleanups have been performed (fd_psm_abord, ...) */
    206195int fd_peer_free(struct fd_peer ** ptr)
    207196{
     
    217206        CHECK_PARAMS( FD_IS_LIST_EMPTY(&p->p_hdr.chain) );
    218207       
    219         free_null(p->p_hdr.info.pi_diamid);
    220         free_null(p->p_hdr.info.pi_realm);
     208        free_null(p->p_hdr.info.pi_diamid);
     209       
     210        free_null(p->p_hdr.info.config.pic_realm);
     211        free_null(p->p_hdr.info.config.pic_priority);
     212       
     213        free_null(p->p_hdr.info.runtime.pir_realm);
     214        free_null(p->p_hdr.info.runtime.pir_prodname);
     215        free_list( &p->p_hdr.info.runtime.pir_apps );
     216       
    221217        free_list( &p->p_hdr.info.pi_endpoints );
    222         TODO("Free the security data if any ?");
    223         free_null(p->p_hdr.info.pi_prodname);
    224         free_list( &p->p_hdr.info.pi_apps );
    225218       
    226219        free_null(p->p_dbgorig);
    227         ASSERT(FD_IS_LIST_EMPTY(&p->p_expiry));
    228         ASSERT(FD_IS_LIST_EMPTY(&p->p_actives));
    229        
    230         CHECK_FCT( fd_thr_term(&p->p_psm) );
    231         while ( fd_fifo_tryget(p->p_events, &t) == 0 ) {
    232                 struct fd_event * ev = t;
    233                 TRACE_DEBUG(FULL, "Found event %d(%p) in queue of peer %p being destroyed", ev->code, ev->data, p);
    234                 free(ev);
    235         }
    236         CHECK_FCT( fd_fifo_del(&p->p_events) );
    237        
    238         CHECK_FCT( fd_thr_term(&p->p_outthr) );
    239        
    240         if (p->p_cnxctx) {
    241                 fd_cnx_destroy(p->p_cnxctx);
    242         }
    243        
    244         /* Requeue any remaining message into global structures if possible */
    245         fd_peer_failover_msg(p);
     220       
     221        fd_list_unlink(&p->p_expiry);
     222        fd_list_unlink(&p->p_actives);
     223       
    246224        CHECK_FCT_DO( fd_fifo_del(&p->p_tosend), /* continue */ );
    247225        CHECK_POSIX_DO( pthread_mutex_destroy(&p->p_sr.mtx), /* continue */);
     
    256234}
    257235
    258 /* Terminate peer module (destroy all peers) */
     236/* Terminate peer module (destroy all peers, first gently, then violently) */
    259237int fd_peer_fini()
    260238{
     
    274252                struct fd_peer * peer = (struct fd_peer *)li;
    275253               
    276                 if (peer->p_hdr.info.pi_state != STATE_ZOMBIE) {
     254                if (peer->p_hdr.info.runtime.pir_state != STATE_ZOMBIE) {
    277255                        CHECK_FCT_DO( fd_psm_terminate(peer), /* continue */ );
    278256                } else {
     
    287265        if (!list_empty) {
    288266                CHECK_SYS(  clock_gettime(CLOCK_REALTIME, &now)  );
    289                 TRACE_DEBUG(INFO, "Waiting for connections shutdown... (%d sec max)", DPR_TIMEOUT);
    290                 wait_until.tv_sec  = now.tv_sec + DPR_TIMEOUT;
     267                TRACE_DEBUG(INFO, "Waiting for connections shutdown... (%d sec max)", DPR_TIMEOUT + 1);
     268                wait_until.tv_sec  = now.tv_sec + DPR_TIMEOUT + 1;
    291269                wait_until.tv_nsec = now.tv_nsec;
    292270        }
     
    301279                for (li = fd_g_peers.next; li != &fd_g_peers; li = li->next) {
    302280                        struct fd_peer * peer = (struct fd_peer *)li;
    303                         if (peer->p_hdr.info.pi_state == STATE_ZOMBIE) {
     281                        if (peer->p_hdr.info.runtime.pir_state == STATE_ZOMBIE) {
    304282                                li = li->prev; /* to avoid breaking the loop */
    305283                                fd_list_unlink(&peer->p_hdr.chain);
     
    351329        }
    352330
    353         fd_log_debug(">  %s\t%s", STATE_STR(peer->p_hdr.info.pi_state), peer->p_hdr.info.pi_diamid);
     331        fd_log_debug(">  %s\t%s", STATE_STR(peer->p_hdr.info.runtime.pir_state), peer->p_hdr.info.pi_diamid);
    354332        if (details > INFO) {
    355                 fd_log_debug("\t(rlm:%s)", peer->p_hdr.info.pi_realm);
    356                 if (peer->p_hdr.info.pi_prodname)
    357                         fd_log_debug("\t['%s' %u]", peer->p_hdr.info.pi_prodname, peer->p_hdr.info.pi_firmrev);
     333                fd_log_debug("\t(rlm:%s)", peer->p_hdr.info.runtime.pir_realm ?: "(unknown)");
     334                if (peer->p_hdr.info.runtime.pir_prodname)
     335                        fd_log_debug("\t['%s' %u]", peer->p_hdr.info.runtime.pir_prodname, peer->p_hdr.info.runtime.pir_firmrev);
    358336        }
    359337        fd_log_debug("\n");
    360338        if (details > FULL) {
    361339                /* Dump all info */
    362                 fd_log_debug("\tEntry origin : %s\n", peer->p_dbgorig);
    363                 fd_log_debug("\tFlags : %s%s%s%s%s - %s%s%s\n",
    364                                 peer->p_hdr.info.pi_flags.pro3 == PI_P3_DEFAULT ? "" :
    365                                         (peer->p_hdr.info.pi_flags.pro3 == PI_P3_IP ? "IP." : "IPv6."),
    366                                 peer->p_hdr.info.pi_flags.pro4 == PI_P4_DEFAULT ? "" :
    367                                         (peer->p_hdr.info.pi_flags.pro4 == PI_P4_TCP ? "TCP." : "SCTP."),
    368                                 peer->p_hdr.info.pi_flags.alg ? "PrefTCP." : "",
    369                                 peer->p_hdr.info.pi_flags.sec == PI_SEC_DEFAULT ? "" :
    370                                         (peer->p_hdr.info.pi_flags.sec == PI_SEC_NONE ? "IPSec." : "InbandTLS."),
    371                                 peer->p_hdr.info.pi_flags.exp ? "Expire." : "",
    372                                 peer->p_hdr.info.pi_flags.inband_none ? "InbandIPsec." : "",
    373                                 peer->p_hdr.info.pi_flags.inband_tls ?  "InbandTLS." : "",
    374                                 peer->p_hdr.info.pi_flags.relay ? "Relay (0xffffff)" : "No relay"
     340                fd_log_debug("\tEntry origin : %s\n", peer->p_dbgorig?: "not set");
     341                fd_log_debug("\tConfig flags : %s%s%s%s%s - %s%s%s\n",
     342                                peer->p_hdr.info.config.pic_flags.pro3 == PI_P3_DEFAULT ? "" :
     343                                        (peer->p_hdr.info.config.pic_flags.pro3 == PI_P3_IP ? "IP." : "IPv6."),
     344                                peer->p_hdr.info.config.pic_flags.pro4 == PI_P4_DEFAULT ? "" :
     345                                        (peer->p_hdr.info.config.pic_flags.pro4 == PI_P4_TCP ? "TCP." : "SCTP."),
     346                                peer->p_hdr.info.config.pic_flags.alg ? "PrefTCP." : "",
     347                                peer->p_hdr.info.config.pic_flags.sec & PI_SEC_NONE ? "NoTLSok" :"",
     348                                peer->p_hdr.info.config.pic_flags.sec & PI_SEC_TLS_OLD ? "OldTLS" :"",
     349                                peer->p_hdr.info.config.pic_flags.exp ? "Expire." : "",
     350                                peer->p_hdr.info.config.pic_flags.persist ? "Persist." : ""
    375351                                );
    376                 fd_log_debug("\tLifetime : %d sec\n", peer->p_hdr.info.pi_lft);
    377                
    378                 TODO("Dump remaining useful information");
     352                fd_log_debug("\tLifetime : %d sec\n", peer->p_hdr.info.config.pic_lft);
    379353        }
    380354}
     
    444418               
    445419                /* Set this peer to expire on inactivity */
    446                 peer->p_hdr.info.pi_flags.exp   = PI_EXP_INACTIVE;
    447                 peer->p_hdr.info.pi_lft         = 3600 * 3;     /* 3 hours without any message */
     420                peer->p_hdr.info.config.pic_flags.exp   = PI_EXP_INACTIVE;
     421                peer->p_hdr.info.config.pic_lft         = 3600 * 3;     /* 3 hours without any message */
    448422               
    449423                /* Upgrade the lock to write lock */
  • include/freeDiameter/freeDiameter.h

    r36 r37  
    277277        (((unsigned)(state)) <= STATE_MAX ? peer_state_str[((unsigned)(state)) ] : "<Invalid>")
    278278
    279 /* Information about a remote peer. Same structure is used for creating a new entry, but not all fields are meaningful in that case */
     279/* Information about a remote peer */
    280280struct peer_info {
    281281       
    282         char *          pi_diamid;      /* UTF-8, \0 terminated. The Diameter Identity of the remote peer */
    283         char *          pi_realm;       /* Its realm, as received in CER/CEA exchange. */
     282        char *          pi_diamid;      /* UTF-8, \0 terminated. The Diameter Identity of the remote peer. */
    284283       
    285284        struct {
    286                 #define PI_P3_DEFAULT   0       /* Use the default L3 protocol configured for the host */
    287                 #define PI_P3_IP        1       /* Use only IP to connect to this peer */
    288                 #define PI_P3_IPv6      2       /* resp, IPv6 */
    289                 unsigned        pro3 :2;
    290                
    291                 #define PI_P4_DEFAULT   0       /* Use the default L4 proto configured for the host */
    292                 #define PI_P4_TCP       1       /* Only use TCP */
    293                 #define PI_P4_SCTP      2       /* Only use SCTP */
    294                 unsigned        pro4 :2;
    295                
    296                 #define PI_ALGPREF_SCTP 0       /* SCTP is initially attempted */
    297                 #define PI_ALGPREF_TCP  1       /* TCP is initially attempted */
    298                 unsigned        alg :1;
    299                
    300                 #define PI_SEC_DEFAULT  0       /* New TLS security (dedicated port protecting also CER/CEA) */
    301                 #define PI_SEC_NONE     1       /* Transparent security with this peer (IPsec) */
    302                 #define PI_SEC_TLS_OLD  2       /* Old TLS security (inband on default port) */
    303                 unsigned        sec :2;
    304                
    305                 #define PI_EXP_NONE     0       /* the peer entry does not expire */
    306                 #define PI_EXP_INACTIVE 1       /* the peer entry expires (i.e. is deleted) after pi_lft seconds without activity */
    307                 unsigned        exp :1;
    308                
    309                 #define PI_PRST_NONE    0       /* the peer entry is deleted after disconnection / error */
    310                 #define PI_PRST_ALWAYS  1       /* the peer entry is persistant (will be kept as ZOMBIE in case of error) */
    311                 unsigned        persist :1;
    312                
    313                 unsigned        inband_none :1; /* This is only meaningful with pi_flags.sec == 3 */
    314                 unsigned        inband_tls  :1; /* This is only meaningful with pi_flags.sec == 3 */
    315                
    316                 unsigned        relay :1;       /* The remote peer advertized the relay application */
    317 
    318         }               pi_flags;       /* Some flags */
    319        
    320         /* Additional parameters */
    321         uint32_t        pi_lft;         /* lifetime of this peer when inactive (see pi_flags.exp definition) */
    322         uint16_t        pi_port;        /* port to connect to. 0: default. */
    323         int             pi_tctimer;     /* use this value for TcTimer instead of global, if != 0 */
    324         int             pi_twtimer;     /* use this value for TwTimer instead of global, if != 0 */
     285                struct {
     286                        #define PI_P3_DEFAULT   0       /* Use any available protocol */
     287                        #define PI_P3_IP        1       /* Use only IP to connect to this peer */
     288                        #define PI_P3_IPv6      2       /* resp, IPv6 */
     289                        unsigned        pro3 :2;
     290
     291                        #define PI_P4_DEFAULT   0       /* Attempt any available protocol */
     292                        #define PI_P4_TCP       1       /* Only use TCP */
     293                        #define PI_P4_SCTP      2       /* Only use SCTP */
     294                        unsigned        pro4 :2;
     295
     296                        #define PI_ALGPREF_SCTP 0       /* SCTP is  attempted first (default) */
     297                        #define PI_ALGPREF_TCP  1       /* TCP is attempted first */
     298                        unsigned        alg :1;
     299
     300                        #define PI_SEC_DEFAULT  0       /* New TLS security (handshake after connection, protecting also CER/CEA) */
     301                        #define PI_SEC_NONE     1       /* Transparent security with this peer (IPsec) */
     302                        #define PI_SEC_TLS_OLD  2       /* Old TLS security (use Inband-Security-Id AVP during CER/CEA) */
     303                        unsigned        sec :2;         /* Set sec = 3 to authorize use of (Inband-Security-Id == NONE) with this peer, sec = 2 only authorizing TLS */
     304
     305                        #define PI_EXP_NONE     0       /* the peer entry does not expire */
     306                        #define PI_EXP_INACTIVE 1       /* the peer entry expires (i.e. is deleted) after pi_lft seconds without activity */
     307                        unsigned        exp :1;
     308
     309                        #define PI_PRST_NONE    0       /* the peer entry is deleted after disconnection / error */
     310                        #define PI_PRST_ALWAYS  1       /* the peer entry is persistant (will be kept as ZOMBIE in case of error) */
     311                        unsigned        persist :1;
     312                       
     313                }               pic_flags;      /* Flags influencing the connection to the remote peer */
     314               
     315                char *          pic_realm;      /* If configured, the daemon will match the received realm in CER/CEA matches this. */
     316                uint16_t        pic_port;       /* port to connect to. 0: default. */
     317               
     318                uint32_t        pic_lft;        /* lifetime of this peer when inactive (see pic_flags.exp definition) */
     319                int             pic_tctimer;    /* use this value for TcTimer instead of global, if != 0 */
     320                int             pic_twtimer;    /* use this value for TwTimer instead of global, if != 0 */
     321               
     322                char *          pic_priority;   /* Priority string for GnuTLS if we don't use the default */
     323               
     324        } config;       /* Configured data (static for this peer entry) */
     325       
     326        struct {
     327               
     328                enum peer_state pir_state;      /* Current state of the peer in the state machine */
     329               
     330                char *          pir_realm;      /* The received realm in CER/CEA. */
     331               
     332                uint32_t        pir_vendorid;   /* Content of the Vendor-Id AVP, or 0 by default */
     333                uint32_t        pir_orstate;    /* Origin-State-Id value */
     334                char *          pir_prodname;   /* copy of UTF-8 Product-Name AVP (\0 terminated) */
     335                uint32_t        pir_firmrev;    /* Content of the Firmware-Revision AVP */
     336                int             pir_relay;      /* The remote peer advertized the relay application */
     337                struct fd_list  pir_apps;       /* applications advertised by the remote peer, except relay (pi_flags.relay) */
     338               
     339                int             pir_proto;      /* The L4 protocol currently used with the peer (IPPROTO_TCP or IPPROTO_SCTP) */
     340                const gnutls_datum_t    *pir_cert_list;         /* The (valid) credentials that the peer has presented, or NULL if TLS is not used */
     341                                                                /* This is inspired from http://www.gnu.org/software/gnutls/manual/gnutls.html#ex_003ax509_002dinfo
     342                                                                   see there for example of using this data */
     343                unsigned int    pir_cert_list_size;             /* Number of certificates in the list */
     344               
     345        } runtime;      /* Data populated after connection, may change between 2 connections -- not used by fd_peer_add */
    325346       
    326347        struct fd_list  pi_endpoints;   /* Endpoint(s) of the remote peer (configured, discovered, or advertized). list of struct fd_endpoint. DNS resolved if empty. */
    327        
    328         /* The remaining information must not be modified, and is not used for peer creation */
    329         enum peer_state pi_state;
    330         uint32_t        pi_vendorid;    /* Content of the Vendor-Id AVP, or 0 by default */
    331         uint32_t        pi_orstate;     /* Origin-State-Id value */
    332         char *          pi_prodname;    /* copy of UTF-8 Product-Name AVP (\0 terminated) */
    333         uint32_t        pi_firmrev;     /* Content of the Firmware-Revision AVP */
    334         struct fd_list  pi_apps;        /* applications advertised by the remote peer, except relay (pi_flags.relay) */
    335         struct {
    336                 char                    *priority;      /* In case the default priority is not appropriate */
    337                 /* This is inspired from http://www.gnu.org/software/gnutls/manual/gnutls.html#ex_003ax509_002dinfo see there for example of using this data */
    338                 const gnutls_datum_t    *cert_list;     /* The (valid) credentials that the peer has presented */
    339                 unsigned int             cert_list_size;/* Number of certificates in the list */
    340         }               pi_sec_data;
    341348};
    342349
  • libfreeDiameter/messages.c

    r35 r37  
    10631063       
    10641064        if ( ! msg->msg_routable ) {
    1065                 /* To define if a message is routable, we rely on the "PXY" command flag yet. */
    1066                 msg->msg_routable = (msg->msg_public.msg_flags & CMD_FLAG_PROXIABLE) ? 1 : 2;
     1065                /* To define if a message is routable, we rely on the "PXY" flag (for application 0). */
     1066                msg->msg_routable = ((msg->msg_public.msg_appl != 0) || (msg->msg_public.msg_flags & CMD_FLAG_PROXIABLE)) ? 1 : 2;
    10671067               
    10681068                /* Note : the 'real' criteria according to the Diameter I-D is that the message is
Note: See TracChangeset for help on using the changeset viewer.