Changeset 14:14cf6daf716d in freeDiameter
- Timestamp:
- Oct 1, 2009, 6:24:07 PM (14 years ago)
- Branch:
- default
- Phase:
- public
- Files:
-
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
freeDiameter/extensions.c
r10 r14 50 50 51 51 /* list of extensions */ 52 static struct fd_list ext_list; 53 54 /* Initialize the module */ 55 int fd_ext_init() 56 { 57 TRACE_ENTRY(); 58 fd_list_init(&ext_list, NULL); 59 return 0; 60 } 52 static struct fd_list ext_list = FD_LIST_INITIALIZER(ext_list); 61 53 62 54 /* Add new extension */ -
freeDiameter/fD.h
r13 r14 42 42 #include <freeDiameter/freeDiameter.h> 43 43 44 /* Timeout for establishing a connection */ 45 #ifndef CNX_TIMEOUT 46 #define CNX_TIMEOUT 10 /* in seconds */ 47 #endif /* CNX_TIMEOUT */ 48 49 /* Timeout for receiving a CER after incoming connection is established */ 50 #ifndef INCNX_TIMEOUT 51 #define INCNX_TIMEOUT 20 /* in seconds */ 52 #endif /* INCNX_TIMEOUT */ 53 54 /* Timeout for receiving a CEA after CER is sent */ 55 #ifndef CEA_TIMEOUT 56 #define CEA_TIMEOUT 10 /* in seconds */ 57 #endif /* CEA_TIMEOUT */ 58 59 /* The timeout value to wait for answer to a DPR */ 60 #ifndef DPR_TIMEOUT 61 #define DPR_TIMEOUT 15 /* in seconds */ 62 #endif /* DPR_TIMEOUT */ 63 44 64 /* Configuration */ 45 65 int fd_conf_init(); … … 49 69 50 70 /* Extensions */ 51 int fd_ext_init();52 71 int fd_ext_add( char * filename, char * conffile ); 53 72 int fd_ext_load(); … … 82 101 char *p_dbgorig; 83 102 84 /* Mutex that protect this peer structure */85 pthread_mutex_t p_mtx;86 87 /* Reference counter -- freed only when this reaches 0 */88 unsigned p_refcount;89 90 103 /* Chaining in peers sublists */ 104 struct fd_list p_actives; /* list of peers in the STATE_OPEN state -- faster routing creation */ 91 105 struct fd_list p_expiry; /* list of expiring peers, ordered by their timeout value */ 92 struct fd_list p_actives; /* list of peers in the STATE_OPEN state -- faster routing creation */ 93 94 /* The next hop-by-hop id value for the link */ 95 uint32_t p_hbh; 106 struct timespec p_exp_timer; /* Timestamp where the peer will expire; updated each time activity is seen on the peer (except DW) */ 96 107 97 108 /* Some flags influencing the peer state machine */ … … 109 120 110 121 /* The events queue, peer state machine thread, timer for states timeouts */ 111 struct fifo *p_events; 122 struct fifo *p_events; /* The mutex of this FIFO list protects also the state and timer information */ 112 123 pthread_t p_psm; 113 124 struct timespec p_psm_timer; … … 121 132 pthread_t p_outthr; 122 133 134 /* The next hop-by-hop id value for the link, only read & modified by p_outthr */ 135 uint32_t p_hbh; 136 123 137 /* Sent requests (for fallback), list of struct sentreq ordered by hbh */ 124 138 struct fd_list p_sentreq; 125 139 126 /* connection context: socket & other metadata*/140 /* connection context: socket, callbacks and so on */ 127 141 struct cnxctx *p_cnxctx; 128 142 … … 145 159 /* A message was received in the peer */ 146 160 ,FDEVP_MSG_INCOMING 161 162 /* The PSM state is expired */ 163 ,FDEVP_PSM_TIMEOUT 147 164 }; 165 const char * fd_pev_str(int event); 148 166 149 167 /* Structure to store a sent request */ … … 154 172 155 173 /* Functions */ 156 int fd_peer_init();157 174 int fd_peer_fini(); 158 175 void fd_peer_dump_list(int details); 159 176 /* fd_peer_add declared in freeDiameter.h */ 160 int fd_peer_rc_decr(struct fd_peer **ptr, int locked);161 177 162 178 /* Peer expiry */ 163 179 int fd_p_expi_init(void); 164 180 int fd_p_expi_fini(void); 165 int fd_p_expi_update(struct fd_peer * peer, int locked ); 166 int fd_p_expi_unlink(struct fd_peer * peer, int locked ); 181 int fd_p_expi_update(struct fd_peer * peer ); 167 182 168 183 /* Peer state machine */ -
freeDiameter/fdd.y
r13 r14 315 315 connpeer: { 316 316 memset(&fddpi, 0, sizeof(fddpi)); 317 fd_list_init( &fddpi.pi_endpoints, NULL ); 318 fd_list_init( &fddpi.pi_apps, NULL ); 317 319 } 318 320 CONNPEER '=' QSTRING peerinfo ';' -
freeDiameter/main.c
r13 r14 42 42 static void * sig_hdl(void * arg); 43 43 static int main_cmdline(int argc, char *argv[]); 44 static void main_version(void); 45 static void main_help( void ); 44 46 45 47 /* The static configuration structure */ … … 77 79 78 80 /* Initialize other modules */ 79 CHECK_FCT( fd_ext_init() );80 81 CHECK_FCT( fd_queues_init() ); 81 82 CHECK_FCT( fd_msg_init() ); 82 CHECK_FCT( fd_p eer_init() );83 CHECK_FCT( fd_p_expi_init() ); 83 84 84 85 /* Parse the configuration file */ … … 133 134 134 135 /* cleanups */ 135 CHECK_FCT_DO( fd_ext_fini(), /* continue */ ); 136 TODO("Stop dispatch thread(s) properly (no cancel yet)"); 137 CHECK_FCT_DO( fd_peer_fini(), /* Stop all connections */ ); 138 TODO("Stop dispatch & routing threads"); 139 CHECK_FCT_DO( fd_ext_fini(), /* Cleaup all extensions */ ); 140 TODO("Cleanup queues (dump all remaining messages ?)"); 141 136 142 CHECK_FCT_DO( fd_thr_term(&sig_th), /* continue */ ); 137 143 138 144 return ret; 145 } 146 147 const char * fd_ev_str(int event) 148 { 149 switch (event) { 150 #define case_str( _val )\ 151 case _val : return #_val 152 case_str(FDEV_TERMINATE); 153 case_str(FDEV_DUMP_DICT); 154 case_str(FDEV_DUMP_EXT); 155 case_str(FDEV_DUMP_QUEUES); 156 case_str(FDEV_DUMP_CONFIG); 157 case_str(FDEV_DUMP_PEERS); 158 159 default: 160 TRACE_DEBUG(FULL, "Unknown event : %d", event); 161 return "Unknown event"; 162 } 163 } 164 165 /* Parse the command-line */ 166 static int main_cmdline(int argc, char *argv[]) 167 { 168 int c; 169 int option_index = 0; 170 171 struct option long_options[] = { 172 { "help", 0, NULL, 'h' }, 173 { "version", 0, NULL, 'V' }, 174 { "config", 1, NULL, 'c' }, 175 { "debug", 0, NULL, 'd' }, 176 { "quiet", 0, NULL, 'q' }, 177 { NULL, 0, NULL, 0 } 178 }; 179 180 TRACE_ENTRY("%d %p", argc, argv); 181 182 /* Loop on arguments */ 183 while (1) { 184 c = getopt_long (argc, argv, "hVc:dq", long_options, &option_index); 185 if (c == -1) 186 break; /* Exit from the loop. */ 187 188 switch (c) { 189 case 'h': /* Print help and exit. */ 190 main_help(); 191 exit(0); 192 193 case 'V': /* Print version and exit. */ 194 main_version(); 195 exit(0); 196 197 case 'c': /* Read configuration from this file instead of the default location.. */ 198 CHECK_PARAMS( optarg ); 199 fd_g_config->cnf_file = optarg; 200 break; 201 202 case 'd': /* Increase verbosity of debug messages. */ 203 fd_g_debug_lvl++; 204 break; 205 206 case 'q': /* Decrease verbosity then remove debug messages. */ 207 fd_g_debug_lvl--; 208 break; 209 210 case '?': /* Invalid option. */ 211 /* `getopt_long' already printed an error message. */ 212 TRACE_DEBUG(INFO, "getopt_long found an invalid character\n"); 213 return EINVAL; 214 215 default: /* bug: option not considered. */ 216 TRACE_DEBUG(INFO, "A command-line option is missing in parser: %c\n", c); 217 ASSERT(0); 218 return EINVAL; 219 } 220 } 221 222 return 0; 139 223 } 140 224 … … 187 271 } 188 272 189 /* Parse the command-line */190 static int main_cmdline(int argc, char *argv[])191 {192 int c;193 int option_index = 0;194 195 struct option long_options[] = {196 { "help", 0, NULL, 'h' },197 { "version", 0, NULL, 'V' },198 { "config", 1, NULL, 'c' },199 { "debug", 0, NULL, 'd' },200 { "quiet", 0, NULL, 'q' },201 { NULL, 0, NULL, 0 }202 };203 204 TRACE_ENTRY("%d %p", argc, argv);205 206 /* Loop on arguments */207 while (1) {208 c = getopt_long (argc, argv, "hVc:dq", long_options, &option_index);209 if (c == -1)210 break; /* Exit from the loop. */211 212 switch (c) {213 case 'h': /* Print help and exit. */214 main_help();215 exit(0);216 217 case 'V': /* Print version and exit. */218 main_version();219 exit(0);220 221 case 'c': /* Read configuration from this file instead of the default location.. */222 CHECK_PARAMS( optarg );223 fd_g_config->cnf_file = optarg;224 break;225 226 case 'd': /* Increase verbosity of debug messages. */227 fd_g_debug_lvl++;228 break;229 230 case 'q': /* Decrease verbosity then remove debug messages. */231 fd_g_debug_lvl--;232 break;233 234 case '?': /* Invalid option. */235 /* `getopt_long' already printed an error message. */236 TRACE_DEBUG(INFO, "getopt_long found an invalid character\n");237 return EINVAL;238 239 default: /* bug: option not considered. */240 TRACE_DEBUG(INFO, "A command-line option is missing in parser: %c\n", c);241 ASSERT(0);242 return EINVAL;243 }244 }245 246 return 0;247 248 }249 250 273 #ifdef HAVE_SIGNALENT_H 251 274 const char *const signalstr[] = { -
freeDiameter/p_expiry.c
r13 r14 36 36 #include "fD.h" 37 37 38 static pthread_t exp_thr; 39 static struct fd_list exp_list = FD_LIST_INITIALIZER( exp_list ); 40 static pthread_cond_t exp_cnd = PTHREAD_COND_INITIALIZER; 41 static pthread_mutex_t exp_mtx = PTHREAD_MUTEX_INITIALIZER; 38 42 43 static void * exp_th_fct(void * arg) 44 { 45 fd_log_threadname ( "Peers/expire" ); 46 TRACE_ENTRY( "" ); 47 48 CHECK_POSIX_DO( pthread_mutex_lock(&exp_mtx), goto error ); 49 pthread_cleanup_push( fd_cleanup_mutex, &exp_mtx ); 50 51 do { 52 struct timespec now; 53 struct fd_peer * first; 54 55 /* Check if there are expiring sessions available */ 56 if (FD_IS_LIST_EMPTY(&exp_list)) { 57 /* Just wait for a change or cancelation */ 58 CHECK_POSIX_DO( pthread_cond_wait( &exp_cnd, &exp_mtx ), goto error ); 59 /* Restart the loop on wakeup */ 60 continue; 61 } 62 63 /* Get the pointer to the peer that expires first */ 64 first = (struct fd_peer *)(exp_list.next->o); 65 ASSERT( CHECK_PEER(first) ); 66 67 /* Get the current time */ 68 CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &now), goto error ); 39 69 70 /* If first peer is not expired, we just wait until it happens */ 71 if ( TS_IS_INFERIOR( &now, &first->p_exp_timer ) ) { 72 73 CHECK_POSIX_DO2( pthread_cond_timedwait( &exp_cnd, &exp_mtx, &first->p_exp_timer ), 74 ETIMEDOUT, /* ETIMEDOUT is a normal error, continue */, 75 /* on other error, */ goto error ); 76 77 /* on wakeup, loop */ 78 continue; 79 } 80 81 /* Now, the first peer in the list is expired; signal it */ 82 fd_list_unlink( &first->p_expiry ); 83 CHECK_FCT_DO( fd_event_send(first->p_events, FDEVP_TERMINATE, NULL), goto error ); 84 85 } while (1); 86 87 pthread_cleanup_pop( 1 ); 88 error: 89 TRACE_DEBUG(INFO, "An error occurred in peers module! Expiry thread is terminating..."); 90 ASSERT(0); 91 CHECK_FCT_DO(fd_event_send(fd_g_config->cnf_main_ev, FDEV_TERMINATE, NULL), ); 92 return NULL; 93 } 40 94 41 95 /* Initialize peers expiry mechanism */ 42 96 int fd_p_expi_init(void) 43 97 { 44 TODO(""); 45 return ENOTSUP; 98 TRACE_ENTRY(); 99 CHECK_FCT( pthread_create( &exp_thr, NULL, exp_th_fct, NULL ) ); 100 return 0; 46 101 } 47 102 … … 49 104 int fd_p_expi_fini(void) 50 105 { 51 TODO(""); 52 return ENOTSUP; 106 CHECK_FCT_DO( fd_thr_term(&exp_thr), ); 107 CHECK_POSIX( pthread_mutex_lock(&exp_mtx) ); 108 109 while (!FD_IS_LIST_EMPTY(&exp_list)) { 110 struct fd_peer * peer = (struct fd_peer *)(exp_list.next->o); 111 fd_list_unlink(&peer->p_expiry ); 112 } 113 114 CHECK_POSIX( pthread_mutex_unlock(&exp_mtx) ); 115 return 0; 53 116 } 54 117 55 /* Add a peer in the expiry list if needed*/56 int fd_p_expi_update(struct fd_peer * peer , int locked)118 /* Add / requeue a peer in the expiry list */ 119 int fd_p_expi_update(struct fd_peer * peer ) 57 120 { 58 TODO(""); 121 TRACE_ENTRY("%p", peer); 122 CHECK_PARAMS( CHECK_PEER(peer) ); 123 124 CHECK_POSIX( pthread_mutex_lock(&exp_mtx) ); 125 126 fd_list_unlink(&peer->p_expiry ); 59 127 60 128 /* if peer expires */ 61 /* add to the expiry list in appropriate position */ 62 /* increment peer refcount */ 129 if (peer->p_hdr.info.pi_flags.exp) { 130 struct fd_list * li; 131 132 /* update the p_exp_timer value */ 133 CHECK_SYS( clock_gettime(CLOCK_REALTIME, &peer->p_exp_timer) ); 134 peer->p_exp_timer.tv_sec += peer->p_hdr.info.pi_lft; 135 136 /* add to the expiry list in appropriate position (probably around the end) */ 137 for (li = exp_list.prev; li != &exp_list; li = li->prev) { 138 struct fd_peer * p = (struct fd_peer *)(li->o); 139 if (TS_IS_INFERIOR( &p->p_exp_timer, &peer->p_exp_timer ) ) 140 break; 141 } 142 143 fd_list_insert_after(li, &peer->p_expiry); 144 63 145 /* signal the expiry thread if we added in first position */ 146 if (li == &exp_list) { 147 CHECK_POSIX( pthread_cond_signal(&exp_cnd) ); 148 } 149 } 64 150 65 return ENOTSUP; 151 CHECK_POSIX( pthread_mutex_unlock(&exp_mtx) ); 152 return 0; 66 153 } 67 154 68 /* Remove a peer from expiry list if needed */69 int fd_p_expi_unlink(struct fd_peer * peer, int locked )70 {71 TODO("");72 /* if peer is in expiry list */73 /* remove from the list */74 /* decrement peer refcount */75 /* no need to signal the expiry thread ... */76 77 return ENOTSUP;78 } -
freeDiameter/p_psm.c
r13 r14 36 36 #include "fD.h" 37 37 38 const char *peer_state_str[] = { 39 "STATE_ZOMBIE" 40 , "STATE_OPEN" 41 , "STATE_CLOSED" 42 , "STATE_CLOSING" 43 , "STATE_WAITCNXACK" 44 , "STATE_WAITCNXACK_ELEC" 45 , "STATE_WAITCEA" 46 , "STATE_SUSPECT" 47 , "STATE_REOPEN" 48 }; 49 50 const char * fd_pev_str(int event) 51 { 52 switch (event) { 53 #define case_str( _val )\ 54 case _val : return #_val 55 case_str(FDEVP_TERMINATE); 56 case_str(FDEVP_DUMP_ALL); 57 case_str(FDEVP_MSG_INCOMING); 58 case_str(FDEVP_PSM_TIMEOUT); 59 60 default: 61 TRACE_DEBUG(FULL, "Unknown event : %d", event); 62 return "Unknown event"; 63 } 64 } 65 66 38 67 static int started = 0; 39 68 static pthread_mutex_t started_mtx = PTHREAD_MUTEX_INITIALIZER; … … 56 85 } 57 86 87 /* Cancelation cleanup : set ZOMBIE state in the peer */ 88 void cleanup_state(void * arg) 89 { 90 struct fd_peer * peer = (struct fd_peer *)arg; 91 CHECK_PARAMS_DO( CHECK_PEER(peer), return ); 92 peer->p_hdr.info.pi_state = STATE_ZOMBIE; 93 return; 94 } 95 96 /* Set timeout timer of next event */ 97 static void psm_next_timeout(struct fd_peer * peer, int add_random, int delay) 98 { 99 /* Initialize the timer */ 100 CHECK_POSIX_DO( clock_gettime( CLOCK_REALTIME, &peer->p_psm_timer ), ASSERT(0) ); 101 102 if (add_random) { 103 if (delay > 2) 104 delay -= 2; 105 else 106 delay = 0; 107 108 /* Add a random value between 0 and 4sec */ 109 peer->p_psm_timer.tv_sec += random() % 4; 110 peer->p_psm_timer.tv_nsec+= random() % 1000000000L; 111 if (peer->p_psm_timer.tv_nsec > 1000000000L) { 112 peer->p_psm_timer.tv_nsec -= 1000000000L; 113 peer->p_psm_timer.tv_sec ++; 114 } 115 } 116 117 peer->p_psm_timer.tv_sec += delay; 118 119 #if 0 120 /* temporary for debug */ 121 peer->p_psm_timer.tv_sec += 10; 122 #endif 123 } 124 125 static int psm_ev_timedget(struct fd_peer * peer, int *code, void ** data) 126 { 127 struct fd_event * ev; 128 int ret = 0; 129 130 TRACE_ENTRY("%p %p %p", peer, code, data); 131 132 ret = fd_fifo_timedget(peer->p_events, &ev, &peer->p_psm_timer); 133 if (ret == ETIMEDOUT) { 134 *code = FDEVP_PSM_TIMEOUT; 135 *data = NULL; 136 } else { 137 CHECK_FCT( ret ); 138 *code = ev->code; 139 *data = ev->data; 140 free(ev); 141 } 142 143 return 0; 144 } 145 146 /* The state machine thread */ 147 static void * p_psm_th( void * arg ) 148 { 149 struct fd_peer * peer = (struct fd_peer *)arg; 150 int created_started = started; 151 152 CHECK_PARAMS_DO( CHECK_PEER(peer), ASSERT(0) ); 153 154 pthread_cleanup_push( cleanup_state, arg ); 155 156 /* Set the thread name */ 157 { 158 char buf[48]; 159 sprintf(buf, "PSM/%.*s", sizeof(buf) - 5, peer->p_hdr.info.pi_diamid); 160 fd_log_threadname ( buf ); 161 } 162 163 /* Wait that the PSM are authorized to start in the daemon */ 164 CHECK_FCT_DO( fd_psm_waitstart(), goto end ); 165 166 /* The state machine starts in CLOSED state */ 167 peer->p_hdr.info.pi_state = STATE_CLOSED; 168 169 /* Initialize the timer */ 170 if (peer->p_flags.pf_responder) { 171 psm_next_timeout(peer, 0, INCNX_TIMEOUT); 172 } else { 173 psm_next_timeout(peer, created_started ? 0 : 1, 0); 174 } 175 176 psm: 177 do { 178 int event; 179 void * ev_data; 180 181 /* Get next event */ 182 CHECK_FCT_DO( psm_ev_timedget(peer, &event, &ev_data), goto end ); 183 TRACE_DEBUG(FULL, "'%s'\t<-- '%s'\t(%p)\t'%s'", 184 STATE_STR(peer->p_hdr.info.pi_state), 185 fd_pev_str(event), ev_data, 186 peer->p_hdr.info.pi_diamid); 187 188 /* Now, the action depends on the current state and the incoming event */ 189 190 191 } while (1); 192 193 194 end: 195 /* set STATE_ZOMBIE */ 196 pthread_cleanup_pop(1); 197 return NULL; 198 } 199 200 201 202 203 /* Create the PSM thread of one peer structure */ 204 int fd_psm_begin(struct fd_peer * peer ) 205 { 206 TRACE_ENTRY("%p", peer); 207 TODO(""); 208 return ENOTSUP; 209 } 210 211 /* End the PSM (clean ending) */ 212 int fd_psm_terminate(struct fd_peer * peer ) 213 { 214 TRACE_ENTRY("%p", peer); 215 CHECK_PARAMS( CHECK_PEER(peer) ); 216 CHECK_FCT( fd_event_send(peer->p_events, FDEVP_TERMINATE, NULL) ); 217 return 0; 218 } 219 220 /* End the PSM violently */ 221 void fd_psm_abord(struct fd_peer * peer ) 222 { 223 TRACE_ENTRY("%p", peer); 224 TODO("Cancel PSM thread"); 225 TODO("Cancel IN thread"); 226 TODO("Cancel OUT thread"); 227 TODO("Cleanup the connection"); 228 return; 229 } 230 58 231 /* Allow the state machines to start */ 59 232 int fd_psm_start() … … 67 240 } 68 241 69 /* Create the PSM thread of one peer structure */70 int fd_psm_begin(struct fd_peer * peer )71 {72 TRACE_ENTRY("%p", peer);73 TODO("");74 return ENOTSUP;75 }76 77 /* End the PSM (clean ending) */78 int fd_psm_terminate(struct fd_peer * peer )79 {80 TRACE_ENTRY("%p", peer);81 TODO("");82 return ENOTSUP;83 }84 85 /* End the PSM violently */86 void fd_psm_abord(struct fd_peer * peer )87 {88 TRACE_ENTRY("%p", peer);89 TODO("");90 return;91 }92 -
freeDiameter/peers.c
r13 r14 36 36 #include "fD.h" 37 37 38 const char *peer_state_str[] = { "<error>" 39 , "STATE_DISABLED" 40 , "STATE_OPEN" 41 , "STATE_CLOSED" 42 , "STATE_CLOSING" 43 , "STATE_WAITCNXACK" 44 , "STATE_WAITCNXACK_ELEC" 45 , "STATE_WAITCEA" 46 , "STATE_SUSPECT" 47 , "STATE_REOPEN" 48 }; 49 50 struct fd_list fd_g_peers; 51 pthread_rwlock_t fd_g_peers_rw; 52 53 /* Initialize the peers list */ 54 int fd_peer_init() 55 { 56 TRACE_ENTRY(); 57 58 fd_list_init(&fd_g_peers, NULL); 59 CHECK_POSIX( pthread_rwlock_init(&fd_g_peers_rw, NULL) ); 60 61 CHECK_FCT(fd_p_expi_init()); 62 63 return 0; 64 } 38 struct fd_list fd_g_peers = FD_LIST_INITIALIZER(fd_g_peers); 39 pthread_rwlock_t fd_g_peers_rw = PTHREAD_RWLOCK_INITIALIZER; 65 40 66 41 /* Terminate peer module (destroy all peers) */ 67 42 int fd_peer_fini() 68 43 { 44 struct fd_list * li; 69 45 TRACE_ENTRY(); 70 46 71 47 CHECK_FCT_DO(fd_p_expi_fini(), /* continue */); 72 48 73 TODO("Complete this function") 49 TRACE_DEBUG(INFO, "Sending signal to terminate to all peer connections"); 50 51 CHECK_FCT_DO( pthread_rwlock_rdlock(&fd_g_peers_rw), /* continue */ ); 52 /* For each peer in the list, ... */ 53 for (li = fd_g_peers.next; li != &fd_g_peers; li = li->next) { 54 struct fd_peer * np = (struct fd_peer *)li; 55 CHECK_FCT_DO( fd_psm_terminate(np), /* continue */ ); 56 } 57 CHECK_FCT_DO( pthread_rwlock_unlock(&fd_g_peers_rw), /* continue */ ); 58 59 TODO("Give some time to all PSM, then destroy remaining threads"); 60 /* fd_psm_abord(struct fd_peer * peer ) */ 74 61 75 62 return 0; … … 125 112 126 113 fd_list_init(&p->p_hdr.info.pi_endpoints, NULL); 127 p->p_hdr.info.pi_state = STATE_DISABLED;128 114 fd_list_init(&p->p_hdr.info.pi_apps, NULL); 129 115 130 116 p->p_eyec = EYEC_PEER; 131 CHECK_POSIX( pthread_mutex_init(&p->p_mtx, NULL) );132 117 fd_list_init(&p->p_expiry, p); 133 118 fd_list_init(&p->p_actives, p); … … 166 151 CHECK_PARAMS(p); 167 152 168 CHECK_PARAMS( (p->p_refcount == 0) &&FD_IS_LIST_EMPTY(&p->p_hdr.chain) );153 CHECK_PARAMS( FD_IS_LIST_EMPTY(&p->p_hdr.chain) ); 169 154 170 155 free_null(p->p_hdr.info.pi_diamid); … … 176 161 177 162 free_null(p->p_dbgorig); 178 CHECK_POSIX( pthread_mutex_destroy(&p->p_mtx) );179 163 ASSERT(FD_IS_LIST_EMPTY(&p->p_expiry)); 180 164 ASSERT(FD_IS_LIST_EMPTY(&p->p_actives)); … … 214 198 } 215 199 216 TRACE_DEBUG(NONE, "TODO: destroy p->p_cnxctx here"); 200 if (p->p_cnxctx) { 201 TODO("destroy p->p_cnxctx"); 202 } 217 203 218 204 if (p->p_cb) … … 224 210 } 225 211 226 /* Decrement refcount, delete if 0 */227 int fd_peer_rc_decr(struct fd_peer **ptr, int locked)228 {229 int count;230 struct fd_peer *p;231 TRACE_ENTRY("%p %d", p, locked);232 233 CHECK_PARAMS(ptr && CHECK_PEER( *ptr ));234 p = *ptr;235 236 if (!locked) {237 CHECK_POSIX( pthread_rwlock_rdlock(&fd_g_peers_rw) );238 CHECK_POSIX( pthread_mutex_lock( &p->p_mtx ) );239 CHECK_POSIX( pthread_rwlock_unlock(&fd_g_peers_rw) );240 }241 242 count = --(p->p_refcount);243 244 if (!locked) {245 CHECK_POSIX( pthread_mutex_unlock( &p->p_mtx ) );246 }247 248 if (count <= 0) {249 /* All links have already been removed, we can destroy */250 CHECK_FCT( fd_sp_destroy(ptr) );251 }252 return 0;253 }254 212 255 213 /* Add a new peer entry */ … … 284 242 285 243 /* Move the items from one list to the other */ 286 while (!FD_IS_LIST_EMPTY( &info->pi_endpoints ) ) { 287 li = info->pi_endpoints.next; 288 fd_list_unlink(li); 289 fd_list_insert_before(&p->p_hdr.info.pi_endpoints, li); 290 } 244 if (info->pi_endpoints.next) 245 while (!FD_IS_LIST_EMPTY( &info->pi_endpoints ) ) { 246 li = info->pi_endpoints.next; 247 fd_list_unlink(li); 248 fd_list_insert_before(&p->p_hdr.info.pi_endpoints, li); 249 } 291 250 292 251 p->p_hdr.info.pi_sec_module = info->pi_sec_module; … … 304 263 /* Ok, now check if we don't already have an entry with the same Diameter Id, and insert this one */ 305 264 CHECK_POSIX( pthread_rwlock_wrlock(&fd_g_peers_rw) ); 306 CHECK_POSIX( pthread_mutex_lock( &p->p_mtx ) );307 265 308 266 for (li = fd_g_peers.next; li != &fd_g_peers; li = li->next) { … … 319 277 if (! ret) { 320 278 /* Update expiry list */ 321 CHECK_FCT_DO( ret = fd_p_expi_update( p , 1), goto out );279 CHECK_FCT_DO( ret = fd_p_expi_update( p ), goto out ); 322 280 323 281 /* Insert the new element in the list */ 324 282 fd_list_insert_before( li, &p->p_hdr.chain ); 325 p->p_refcount++;326 283 } 327 284 328 285 out: 329 CHECK_POSIX( pthread_mutex_unlock( &p->p_mtx ) );330 286 CHECK_POSIX( pthread_rwlock_unlock(&fd_g_peers_rw) ); 331 287 if (ret) { 332 288 CHECK_FCT( fd_sp_destroy(&p) ); 333 289 } else { 334 CHECK_FCT( fd_psm_ start(p) );290 CHECK_FCT( fd_psm_begin(p) ); 335 291 } 336 292 return ret; -
include/freeDiameter/freeDiameter.h
r13 r14 141 141 ,FDEV_DUMP_PEERS /* Dump the list of peers */ 142 142 }; 143 143 const char * fd_ev_str(int event); 144 144 145 145 … … 151 151 enum peer_state { 152 152 /* Stable states */ 153 STATE_ DISABLED = 1, /* No connexion must be attempted / only this state means that the peer PSM thread is not running*/153 STATE_ZOMBIE = 0, /* The threads handling the peer are not running for some reason */ 154 154 STATE_OPEN, /* Connexion established */ 155 155 … … 167 167 /* Failover state machine */ 168 168 STATE_SUSPECT, /* A DWR was sent and not answered within TwTime. Failover in progress. */ 169 STATE_REOPEN /* Connection has been re-established, waiting for 3 DWR/DWA exchanges before putting back to service */169 STATE_REOPEN, /* Connection has been re-established, waiting for 3 DWR/DWA exchanges before putting back to service */ 170 170 }; 171 171 extern const char *peer_state_str[]; 172 172 #define STATE_STR(state) \ 173 peer_state_str[ ((unsigned)(state)) <= STATE_REOPEN ? ((unsigned)(state)) : 0 ]173 (((unsigned)(state)) <= STATE_REOPEN ? peer_state_str[((unsigned)(state)) ] : "<Invalid>") 174 174 175 175 /* Information about a remote peer. Same structure is used for creating a new entry, but not all fields are meaningful in that case */ … … 238 238 } pi_sec_data; 239 239 240 /* The remaining information is read-only,not used for peer creation */240 /* The remaining information must not be modified, and is not used for peer creation */ 241 241 enum peer_state pi_state; 242 242 uint32_t pi_vendorid; /* Content of the Vendor-Id AVP, or 0 by default */ -
include/freeDiameter/libfreeDiameter.h
r13 r14 193 193 #ifndef ERRORS_ON_TODO 194 194 #define TODO( _msg, _args... ) \ 195 TRACE_DEBUG(NONE, _msg , ##_args);195 TRACE_DEBUG(NONE, "TODO: " _msg , ##_args); 196 196 #else /* ERRORS_ON_TODO */ 197 197 #define TODO( _msg, _args... ) \ … … 446 446 }; 447 447 448 #define FD_LIST( _li ) ((struct fd_list *)( _li ))449 450 448 /* Initialize a list element */ 449 #define FD_LIST_INITIALIZER( _list_name ) \ 450 { .next = & _list_name, .prev = & _list_name, .head = & _list_name, .o = NULL } 451 #define FD_LIST_INITIALIZER_O( _list_name, _obj ) \ 452 { .next = & _list_name, .prev = & _list_name, .head = & _list_name, .o = _obj } 451 453 void fd_list_init ( struct fd_list * list, void *obj ); 452 454 453 455 /* Return boolean, true if the list is empty */ 454 #define FD_IS_LIST_EMPTY( _list ) ((( FD_LIST(_list))->head == (_list)) && ((FD_LIST(_list))->next == (_list)))456 #define FD_IS_LIST_EMPTY( _list ) ((((struct fd_list *)(_list))->head == (_list)) && (((struct fd_list *)(_list))->next == (_list))) 455 457 456 458 /* Insert an item in a list at known position */ -
libfreeDiameter/dispatch.c
r7 r14 44 44 45 45 /* List of all registered handlers -- useful if we want to cleanup properly at some point... */ 46 static struct fd_list all_handlers ;46 static struct fd_list all_handlers = FD_LIST_INITIALIZER( all_handlers ); 47 47 48 48 /* List of handlers registered for DISP_HOW_ANY. Other handlers are stored in the dictionary */ 49 static struct fd_list any_handlers ;49 static struct fd_list any_handlers = FD_LIST_INITIALIZER( any_handlers ); 50 50 51 51 /* The structure to store a callback */ … … 64 64 65 65 /**************************************************************************************/ 66 /* Initialize the module lists */67 void fd_disp_init(void)68 {69 TRACE_ENTRY();70 fd_list_init(&all_handlers, NULL);71 fd_list_init(&any_handlers, NULL);72 /* if PTHREAD_RWLOCK_INITIALIZER is not supported on all platforms, we may initialize the lock here */73 }74 66 75 67 /* Call CBs from a given list (any_handlers if cb_list is NULL) -- must have locked fd_disp_lock before */ -
libfreeDiameter/fifo.c
r11 r14 65 65 void (*l_cb)(struct fifo *, void **); 66 66 int highest;/* The highest count value for which h_cb has been called */ 67 int highest_ever; /* The max count value this queue has reached (for tweaking) */ 67 68 }; 68 69 … … 118 119 CHECK_POSIX_DO( pthread_mutex_lock( &queue->mtx ), /* continue */ ); 119 120 fd_log_debug(" %d elements in queue / %d threads waiting\n", queue->count, queue->thrs); 120 fd_log_debug(" thresholds: %d / %d , cb: %p /%p (%p), highest: %d\n",121 queue->high, queue->low, 121 fd_log_debug(" thresholds: %d / %d (h:%d), cb: %p,%p (%p), highest: %d\n", 122 queue->high, queue->low, queue->highest, 122 123 queue->h_cb, queue->l_cb, queue->data, 123 queue->highest );124 queue->highest_ever); 124 125 125 126 if (dump_item) { … … 251 252 fd_list_insert_before( &queue->list, new); 252 253 queue->count++; 254 if (queue->highest_ever < queue->count) 255 queue->highest_ever = queue->count; 253 256 if (queue->high && ((queue->count % queue->high) == 0)) { 254 257 call_cb = 1; -
libfreeDiameter/init.c
r7 r14 49 49 /* Initialize the modules that need it */ 50 50 fd_msg_eteid_init(); 51 fd_disp_init();52 51 CHECK_FCT( fd_sess_init() ); 53 52 -
libfreeDiameter/libfD.h
r7 r14 45 45 extern const char * type_base_name[]; 46 46 void fd_msg_eteid_init(void); 47 void fd_disp_init(void);48 47 int fd_sess_init(void); 49 48 -
libfreeDiameter/lists.c
r1 r14 47 47 48 48 #define CHECK_SINGLE( li ) { \ 49 ASSERT( FD_LIST(li)->next == (li) ); \50 ASSERT( FD_LIST(li)->prev == (li) ); \51 ASSERT( FD_LIST(li)->head == (li) ); \49 ASSERT( ((struct fd_list *)(li))->next == (li) ); \ 50 ASSERT( ((struct fd_list *)(li))->prev == (li) ); \ 51 ASSERT( ((struct fd_list *)(li))->head == (li) ); \ 52 52 } 53 53 -
libfreeDiameter/sessions.c
r7 r14 117 117 118 118 /* Expiring sessions management */ 119 static struct fd_list exp_sentinel ; /* list of sessions ordered by their timeout date */119 static struct fd_list exp_sentinel = FD_LIST_INITIALIZER(exp_sentinel); /* list of sessions ordered by their timeout date */ 120 120 static pthread_mutex_t exp_lock = PTHREAD_MUTEX_INITIALIZER; /* lock protecting the list. */ 121 121 static pthread_cond_t exp_cond = PTHREAD_COND_INITIALIZER; /* condvar used by the expiry mecahinsm. */ … … 231 231 } 232 232 233 /* Initialize expiry management */ 234 fd_list_init( &exp_sentinel, NULL ); 233 /* Start session garbage collector (expiry) */ 235 234 CHECK_POSIX( pthread_create(&exp_thr, NULL, exp_fct, NULL) ); 236 235 … … 266 265 { 267 266 struct session_handler * del; 268 struct fd_list deleted_states; /* Save the list of states to be cleaned up. We do it after finding them to avoid deadlocks. the "o" field becomes a copy of the sid. */ 267 /* place to save the list of states to be cleaned up. We do it after finding them to avoid deadlocks. the "o" field becomes a copy of the sid. */ 268 struct fd_list deleted_states = FD_LIST_INITIALIZER( deleted_states ); 269 269 int i; 270 270 … … 274 274 del = *handler; 275 275 *handler = NULL; 276 fd_list_init(&deleted_states, NULL);277 276 278 277 del->eyec = 0xdead; /* The handler is not valid anymore for any other operation */ … … 413 412 fd_list_insert_after( li, &sess->expire ); 414 413 414 /* We added a new expiring element, we must signal */ 415 if (li == &exp_sentinel) { 416 CHECK_POSIX( pthread_cond_signal(&exp_cond) ); 417 } 418 415 419 #if 0 416 420 if (TRACE_BOOL(ANNOYING)) { … … 424 428 #endif 425 429 426 /* We added a new expiring element, we must signal */427 CHECK_POSIX( pthread_cond_signal(&exp_cond) );428 429 430 /* We're done */ 430 431 CHECK_POSIX( pthread_mutex_unlock( &exp_lock ) ); … … 506 507 fd_list_insert_before( li, &session->expire ); 507 508 508 /* We added a new expiring element, we must signal */ 509 CHECK_POSIX( pthread_cond_signal(&exp_cond) ); 509 /* We added a new expiring element, we must signal if it was in first position */ 510 if (session->expire.prev == &exp_sentinel) { 511 CHECK_POSIX( pthread_cond_signal(&exp_cond) ); 512 } 510 513 511 514 #if 0 … … 588 591 } 589 592 590 591 592 593 /* Save a state information with a session */ 593 594 int fd_sess_state_store_internal ( struct session_handler * handler, struct session * session, session_state ** state )
Note: See TracChangeset
for help on using the changeset viewer.