Navigation


Changeset 36:1498b3c7304c in freeDiameter


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

Backup

Files:
2 added
8 edited

Legend:

Unmodified
Added
Removed
  • freeDiameter/CMakeLists.txt

    r35 r36  
    2121        peers.c
    2222        p_ce.c
     23        p_dw.c
     24        p_dp.c
    2325        p_expiry.c
    2426        p_out.c
  • freeDiameter/fD.h

    r35 r36  
    232232int  fd_psm_terminate(struct fd_peer * peer );
    233233void fd_psm_abord(struct fd_peer * peer );
     234void fd_psm_next_timeout(struct fd_peer * peer, int add_random, int delay);
     235int fd_psm_change_state(struct fd_peer * peer, int new_state);
     236void fd_psm_cleanup(struct fd_peer * peer);
    234237
    235238/* Peer out */
     
    243246void fd_p_sr_failover(struct sr_list * srlist);
    244247
    245 /* Capabilities Exchange */
    246 int fd_p_ce_merge(struct fd_peer * peer, struct msg * cer);
     248/* Local Link messages (CER/CEA, DWR/DWA, DPR/DPA) */
     249int fd_p_ce_handle(struct msg ** msg, struct fd_peer * peer);
     250int fd_p_ce_handle_newCER(struct msg ** msg, struct fd_peer * peer, struct cnxctx ** cnx, int valid);
     251int fd_p_dw_handle(struct msg ** msg, struct fd_peer * peer);
     252int fd_p_dw_timeout(struct fd_peer * peer);
     253int fd_p_dp_handle(struct msg ** msg, struct fd_peer * peer);
     254int fd_p_dp_initiate(struct fd_peer * peer);
    247255
    248256/* Active peers -- routing process should only ever take the read lock, the write lock is managed by PSMs */
  • freeDiameter/fdd.y

    r24 r36  
    318318                                fd_list_init( &fddpi.pi_endpoints, NULL );
    319319                                fd_list_init( &fddpi.pi_apps, NULL );
     320                                fddpi.pi_flags.persist = PI_PRST_ALWAYS;
    320321                        }
    321322                        CONNPEER '=' QSTRING peerinfo ';'
  • freeDiameter/p_ce.c

    r35 r36  
    3838/* This file contains code to handle Capabilities Exchange messages (CER and CEA) */
    3939
    40 int fd_p_ce_merge(struct fd_peer * peer, struct msg * cer)
     40int fd_p_ce_handle(struct msg ** msg, struct fd_peer * peer)
    4141{
    42         /* Save all information from the CER into the peer structure, after cleaning old information if any */
     42        TODO("Handle depending on CER or CEA and peer state");
    4343       
    4444        return ENOTSUP;
    4545}
     46
     47int fd_p_ce_handle_newCER(struct msg ** msg, struct fd_peer * peer, struct cnxctx ** cnx, int valid)
     48{
     49        switch (peer->p_hdr.info.pi_state) {
     50                case STATE_CLOSED:
     51                        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");
     52                        /* In case of error : DIAMETER_UNKNOWN_PEER */
     53                        break;
     54
     55                case STATE_WAITCNXACK:
     56                case STATE_WAITCEA:
     57                        TODO("Election");
     58                        break;
     59
     60                default:
     61                        TODO("Reply with error CEA");
     62                        TODO("Close the connection");
     63                        /* reject_incoming_connection */
     64
     65        }
     66                               
     67       
     68        return ENOTSUP;
     69}
  • freeDiameter/p_expiry.c

    r25 r36  
    3636#include "fD.h"
    3737
    38 /* Delay for garbage collection of expired threads, in seconds */
    39 #define GC_TIME         60
     38/* Delay for garbage collection of expired peers, in seconds */
     39#define GC_TIME         120
    4040
    4141static pthread_t       exp_thr;
     
    6464                                continue;
    6565                       
    66                         if (peer->p_hdr.info.pi_flags.exp == PI_EXP_NONE)
    67                                 continue; /* This peer was not supposed to expire, keep it in the list */
     66                        if (peer->p_hdr.info.pi_flags.persist == PI_PRST_ALWAYS)
     67                                continue; /* This peer was not supposed to terminate, keep it in the list for debug */
    6868                       
    6969                        /* Ok, the peer was expired, let's remove it */
  • freeDiameter/p_psm.c

    r35 r36  
    146146/************************************************************************/
    147147/* Change state */
    148 static int change_state(struct fd_peer * peer, int new_state)
     148int fd_psm_change_state(struct fd_peer * peer, int new_state)
    149149{
    150150        int old;
     
    171171        }
    172172       
     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) );
     175        }
     176       
    173177        return 0;
    174178}
    175179
    176180/* Set timeout timer of next event */
    177 static void psm_next_timeout(struct fd_peer * peer, int add_random, int delay)
     181void fd_psm_next_timeout(struct fd_peer * peer, int add_random, int delay)
    178182{
    179183        /* Initialize the timer */
     
    203207}
    204208
     209/* Cleanup the peer */
     210void fd_psm_cleanup(struct fd_peer * peer)
     211{
     212        /* Move to CLOSED state */
     213        CHECK_FCT_DO( fd_psm_change_state(peer, STATE_CLOSED), /* continue */ );
     214       
     215        /* Destroy the connection */
     216        if (peer->p_cnxctx) {
     217                fd_cnx_destroy(peer->p_cnxctx);
     218                peer->p_cnxctx = NULL;
     219        }
     220       
     221        /* What else ? */
     222        TODO("...");
     223       
     224}
     225
    205226
    206227/************************************************************************/
     
    208229/************************************************************************/
    209230/* Cancelation cleanup : set ZOMBIE state in the peer */
    210 void cleanup_state(void * arg)
     231void cleanup_setstate(void * arg)
    211232{
    212233        struct fd_peer * peer = (struct fd_peer *)arg;
     
    227248        CHECK_PARAMS_DO( CHECK_PEER(peer), ASSERT(0) );
    228249       
    229         pthread_cleanup_push( cleanup_state, arg );
     250        pthread_cleanup_push( cleanup_setstate, arg );
    230251       
    231252        /* Set the thread name */
     
    244265        /* Initialize the timer */
    245266        if (peer->p_flags.pf_responder) {
    246                 psm_next_timeout(peer, 0, INCNX_TIMEOUT);
     267                fd_psm_next_timeout(peer, 0, INCNX_TIMEOUT);
    247268        } else {
    248                 psm_next_timeout(peer, created_started, 0);
     269                fd_psm_next_timeout(peer, created_started, 0);
    249270        }
    250271       
     
    279300        if (event == FDEVP_TERMINATE) {
    280301                switch (peer->p_hdr.info.pi_state) {
     302                        case STATE_OPEN:
     303                        case STATE_REOPEN:
     304                                /* We cannot just close the conenction, we have to send a DPR first */
     305                                CHECK_FCT_DO( fd_p_dp_initiate(peer), goto psm_end );
     306                                goto psm_loop;
     307                       
     308                        /*     
    281309                        case STATE_CLOSING:
    282310                        case STATE_WAITCNXACK:
     
    284312                        case STATE_WAITCEA:
    285313                        case STATE_SUSPECT:
    286                                 /* In these cases, we just cleanup the peer object and terminate now */
    287                                 TODO("Cleanup the PSM: terminate connection object, ...");
    288314                        case STATE_CLOSED:
    289                                 /* Then we just terminate the PSM */
     315                        */
     316                        default:
     317                                /* In these cases, we just cleanup the peer object (if needed) and terminate */
    290318                                goto psm_end;
    291                                
    292                         case STATE_OPEN:
    293                         case STATE_REOPEN:
    294                                 /* We cannot just close the conenction, we have to send a DPR first */
    295                                 TODO("Send DPR, mark the peer as CLOSING");
    296                                 goto psm_loop;
    297319                }
    298320        }
     
    311333                        } );
    312334               
    313                 TRACE_DEBUG(FULL, "Received this message from '%s':", peer->p_hdr.info.pi_diamid);
    314                 fd_msg_dump_walk(FULL, msg);
     335                TRACE_DEBUG(FULL, "Received a message (%zdb) from '%s'", ev_sz, peer->p_hdr.info.pi_diamid);
     336                fd_msg_dump_walk(FULL + 1, msg);
    315337       
    316338                /* Extract the header */
     
    333355                }
    334356               
    335                 /* We received a valid message, update the expiry timer */
    336                 CHECK_FCT_DO( fd_p_expi_update(peer), goto psm_end );
    337 
    338357                /* Now handle non-link-local messages */
    339358                if (fd_msg_is_routable(msg)) {
     
    344363                                fd_msg_free(msg);
    345364                        } else {
     365                                /* We received a valid message, update the expiry timer */
     366                                CHECK_FCT_DO( fd_p_expi_update(peer), goto psm_end );
     367
    346368                                /* Set the message source and add the Route-Record */
    347369                                CHECK_FCT_DO( fd_msg_source_set( msg, peer->p_hdr.info.pi_diamid, 1, fd_g_config->cnf_dict ), goto psm_end);
     
    352374                                /* Update the peer timer */
    353375                                if (!peer->p_flags.pf_dw_pending) {
    354                                         psm_next_timeout(peer, 1, peer->p_hdr.info.pi_twtimer ?: fd_g_config->cnf_timer_tw);
     376                                        fd_psm_next_timeout(peer, 1, peer->p_hdr.info.pi_twtimer ?: fd_g_config->cnf_timer_tw);
    355377                                }
    356378                        }
     
    374396                }
    375397               
     398                ASSERT( hdr->msg_appl == 0 ); /* buggy fd_msg_is_routable() ? */
     399               
    376400                /* Handle the LL message and update the expiry timer appropriately */
    377                 TODO("...");
     401                switch (hdr->msg_code) {
     402                        case CC_DEVICE_WATCHDOG:
     403                                CHECK_FCT_DO( fd_p_dw_handle(&msg, peer), goto psm_end );
     404                                break;
     405                       
     406                        case CC_DISCONNECT_PEER:
     407                                CHECK_FCT_DO( fd_p_dp_handle(&msg, peer), goto psm_end );
     408                                break;
     409                       
     410                        case CC_CAPABILITIES_EXCHANGE:
     411                                CHECK_FCT_DO( fd_p_ce_handle(&msg, peer), goto psm_end );
     412                                break;
     413                       
     414                        default:
     415                                /* Unknown / unexpected / invalid message */
     416                                TODO("Log, return error message if request");
     417                };
     418               
     419                /* At this point the message must have been fully handled already */
     420                if (msg) {
     421                        fd_log_debug("Internal error: unhandled message (discarded)!\n");
     422                        fd_msg_dump_walk(NONE, msg);
     423                        fd_msg_free(msg);
     424                }
     425               
     426                goto psm_loop;
    378427        }
    379428       
    380429        /* The connection object is broken */
    381430        if (event == FDEVP_CNX_ERROR) {
    382                 TODO("Destroy the connection object");
    383                 TODO("Mark the error in the peer (pf_cnx_pb)");
    384                 TODO("Move to closed state, Requeue all messages to a different connection (failover)");
    385                 TODO("If pi_flags.exp, terminate the peer");
     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;
    386445        }
    387446       
     
    409468                ASSERT(params);
    410469               
    411                 switch (peer->p_hdr.info.pi_state) {
    412                         case STATE_CLOSED:
    413                                 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");
    414                                 /* In case of error : DIAMETER_UNKNOWN_PEER */
    415                                
    416                                 CHECK_FCT_DO( fd_p_ce_merge(peer, params->cer),
    417                                         {
    418                                                
    419                                         } );
    420                                
    421                                 break;
    422                                
    423                         case STATE_WAITCNXACK:
    424                         case STATE_WAITCEA:
    425                                 TODO("Election");
    426                                 break;
    427                                
    428                         default:
    429                                 TODO("Reply with error CEA");
    430                                 TODO("Close the connection");
    431                                 /* reject_incoming_connection */
    432                        
    433                 }
    434                
     470                /* Handle the message */
     471                CHECK_FCT_DO( fd_p_ce_handle_newCER(&params->cer, peer, &params->cnx, params->validate), goto psm_end );
     472               
     473                /* Cleanup if needed */
     474                if (params->cnx) {
     475                        fd_cnx_destroy(params->cnx);
     476                        params->cnx = NULL;
     477                }
     478                if (params->cer) {
     479                        CHECK_FCT_DO( fd_msg_free(params->cer), );
     480                        params->cer = NULL;
     481                }
     482               
     483                /* Loop */
    435484                free(ev_data);
    436485                goto psm_loop;
     
    440489        if (event == FDEVP_PSM_TIMEOUT) {
    441490                switch (peer->p_hdr.info.pi_state) {
    442                        
    443                        
     491                        case STATE_OPEN:
     492                        case STATE_REOPEN:
     493                                CHECK_FCT_DO( fd_p_dw_timeout(peer), goto psm_end );
     494                                break;
     495                               
     496                        case STATE_CLOSED:
     497                                TODO("Initiate a new connection");
     498                                break;
     499                               
     500                        case STATE_CLOSING:
     501                        case STATE_SUSPECT:
     502                        case STATE_WAITCNXACK:
     503                        case STATE_WAITCEA:
     504                                /* Destroy the connection, restart the timer to a new connection attempt */
     505                                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 );
     508                                break;
     509                               
     510                        case STATE_WAITCNXACK_ELEC:
     511                                TODO("Abort initiating side, handle the receiver side");
     512                                break;
    444513                }
    445514        }
     
    449518        if (event == FDEVP_PSM_TIMEOUT) {
    450519                /* We have not handled timeout in this state, let's postpone next alert */
    451                 psm_next_timeout(peer, 0, 60);
     520                fd_psm_next_timeout(peer, 0, 60);
    452521        }
    453522       
     
    455524
    456525psm_end:
     526        fd_psm_cleanup(peer);
    457527        pthread_cleanup_pop(1); /* set STATE_ZOMBIE */
    458528        peer->p_psm = (pthread_t)NULL;
  • freeDiameter/peers.c

    r34 r36  
    102102        }
    103103       
    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        
    110         p->p_hdr.info.pi_lft     = info->pi_lft;
    111         p->p_hdr.info.pi_port    = info->pi_port;
    112         p->p_hdr.info.pi_tctimer = info->pi_tctimer;
    113         p->p_hdr.info.pi_twtimer = info->pi_twtimer;
     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;
    114115       
    115116        if (info->pi_sec_data.priority) {
     
    442443                peer->p_flags.pf_responder = 1;
    443444               
     445                /* 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 */
     448               
    444449                /* Upgrade the lock to write lock */
    445450                CHECK_POSIX_DO( ret = pthread_rwlock_wrlock(&fd_g_peers_rw), goto out );
  • include/freeDiameter/freeDiameter.h

    r34 r36  
    248248                                   If we win the election, we must disconnect the initiated connection and send a CEA on the other => we go to OPEN state.
    249249                                   If we lose, we disconnect the other connection (receiver) and fallback to WAITCEA state. */
    250         STATE_OPEN_HANDSHAKE,   /* TLS Handshake and validation are in progress in open state */
     250        STATE_OPEN_HANDSHAKE,   /* TLS Handshake and validation are in progress in open state -- we show the state because it can last a long time */
    251251       
    252252        /* Failover state machine */
     
    307307                unsigned        exp :1;
    308308               
     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               
    309313                unsigned        inband_none :1; /* This is only meaningful with pi_flags.sec == 3 */
    310314                unsigned        inband_tls  :1; /* This is only meaningful with pi_flags.sec == 3 */
Note: See TracChangeset for help on using the changeset viewer.