Changeset 13:ef9ef3bf4752 in freeDiameter
- Timestamp:
- Sep 30, 2009, 6:25:46 PM (15 years ago)
- Branch:
- default
- Phase:
- public
- Files:
-
- 2 added
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/freediameter.conf.sample
r12 r13 163 163 LoadExtension = "extensions/dict_eap.fdx"; 164 164 ConnectPeer = "jules.nautilus6.org" ; 165 ConnectPeer = "aaa.nautilus6.org" { No_TLS; No_IP; No_TCP; SCTP_streams = 60; } ; -
freeDiameter/CMakeLists.txt
r11 r13 15 15 dict_base_proto.c 16 16 messages.c 17 queues.c 17 18 peers.c 18 queues.c 19 p_expiry.c 20 p_psm.c 19 21 ) 20 22 -
freeDiameter/fD.h
r12 r13 127 127 struct cnxctx *p_cnxctx; 128 128 129 /* Callback on initial connection success / failure */ 130 void (*p_cb)(struct peer_info *, void *); 131 void *p_cb_data; 132 129 133 }; 130 134 #define CHECK_PEER( _p ) \ … … 151 155 /* Functions */ 152 156 int fd_peer_init(); 157 int fd_peer_fini(); 153 158 void fd_peer_dump_list(int details); 154 int fd_peer_start(); 155 int fd_peer_ waitstart();159 /* fd_peer_add declared in freeDiameter.h */ 160 int fd_peer_rc_decr(struct fd_peer **ptr, int locked); 156 161 162 /* Peer expiry */ 163 int fd_p_expi_init(void); 164 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 ); 157 167 168 /* Peer state machine */ 169 int fd_psm_start(); 170 int fd_psm_begin(struct fd_peer * peer ); 171 int fd_psm_terminate(struct fd_peer * peer ); 172 void fd_psm_abord(struct fd_peer * peer ); 158 173 159 174 #endif /* _FD_H */ -
freeDiameter/fdd.y
r12 r13 210 210 memset(ep, 0, sizeof(struct fd_endpoint)); 211 211 fd_list_init(&ep->chain, NULL); 212 ep->meta.conf = 1; 212 213 213 214 memset(&hints, 0, sizeof(hints)); 214 215 hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; 215 216 ret = getaddrinfo($3, NULL, &hints, &ai); 216 if (ret) { yyerror (&yylloc, conf, gai_strerror(ret)); YYERROR; }217 217 if (ret) { yyerror (&yylloc, conf, gai_strerror(ret)); free(ep); YYERROR; } 218 ASSERT( ai->ai_addrlen <= sizeof(sSS) ); 218 219 memcpy(&ep->ss, ai->ai_addr, ai->ai_addrlen); 219 220 free($3); … … 426 427 memset(ep, 0, sizeof(struct fd_endpoint)); 427 428 fd_list_init(&ep->chain, NULL); 428 429 ep->meta.conf = 1; 429 430 memset(&hints, 0, sizeof(hints)); 430 hints.ai_flags = AI_ADDRCONFIG ;431 hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICHOST; 431 432 ret = getaddrinfo($4, NULL, &hints, &ai); 432 if (ret) { yyerror (&yylloc, conf, gai_strerror(ret)); YYERROR; } 433 if (ret == EAI_NONAME) { 434 /* The name was maybe not numeric, try again */ 435 ep->meta.disc = 1; 436 hints.ai_flags &= ~ AI_NUMERICHOST; 437 ret = getaddrinfo($4, NULL, &hints, &ai); 438 } 439 if (ret) { yyerror (&yylloc, conf, gai_strerror(ret)); free(ep); YYERROR; } 433 440 434 441 memcpy(&ep->ss, ai->ai_addr, ai->ai_addrlen); -
freeDiameter/main.c
r12 r13 89 89 90 90 /* Start the peer state machines */ 91 CHECK_FCT( fd_p eer_start() );91 CHECK_FCT( fd_psm_start() ); 92 92 93 93 /* Now, just wait for events */ -
freeDiameter/peers.c
r12 r13 51 51 pthread_rwlock_t fd_g_peers_rw; 52 52 53 static int started = 0;54 static pthread_mutex_t started_mtx = PTHREAD_MUTEX_INITIALIZER;55 static pthread_cond_t started_cnd = PTHREAD_COND_INITIALIZER;56 57 /* Wait for start signal */58 int fd_peer_waitstart()59 {60 CHECK_POSIX( pthread_mutex_lock(&started_mtx) );61 awake:62 if (! started) {63 pthread_cleanup_push( fd_cleanup_mutex, &started_mtx );64 CHECK_POSIX( pthread_cond_wait(&started_cnd, &started_mtx) );65 pthread_cleanup_pop( 0 );66 goto awake;67 }68 CHECK_POSIX( pthread_mutex_unlock(&started_mtx) );69 return 0;70 }71 72 /* Allow the state machines to start */73 int fd_peer_start()74 {75 CHECK_POSIX( pthread_mutex_lock(&started_mtx) );76 started = 1;77 CHECK_POSIX( pthread_cond_broadcast(&started_cnd) );78 CHECK_POSIX( pthread_mutex_unlock(&started_mtx) );79 return 0;80 }81 82 53 /* Initialize the peers list */ 83 54 int fd_peer_init() … … 87 58 fd_list_init(&fd_g_peers, NULL); 88 59 CHECK_POSIX( pthread_rwlock_init(&fd_g_peers_rw, NULL) ); 60 61 CHECK_FCT(fd_p_expi_init()); 62 63 return 0; 64 } 65 66 /* Terminate peer module (destroy all peers) */ 67 int fd_peer_fini() 68 { 69 TRACE_ENTRY(); 70 71 CHECK_FCT_DO(fd_p_expi_fini(), /* continue */); 72 73 TODO("Complete this function") 89 74 90 75 return 0; … … 119 104 } 120 105 106 /* Alloc / reinit a peer structure. if *ptr is not NULL, it must already point to a valid struct fd_peer. */ 107 static int fd_sp_reinit(struct fd_peer ** ptr) 108 { 109 struct fd_peer *p; 110 111 TRACE_ENTRY("%p", ptr); 112 CHECK_PARAMS(ptr); 113 114 if (*ptr) { 115 p = *ptr; 116 } else { 117 CHECK_MALLOC( p = malloc(sizeof(struct fd_peer)) ); 118 *ptr = p; 119 } 120 121 /* Now initialize the content */ 122 memset(p, 0, sizeof(struct fd_peer)); 123 124 fd_list_init(&p->p_hdr.chain, p); 125 126 fd_list_init(&p->p_hdr.info.pi_endpoints, NULL); 127 p->p_hdr.info.pi_state = STATE_DISABLED; 128 fd_list_init(&p->p_hdr.info.pi_apps, NULL); 129 130 p->p_eyec = EYEC_PEER; 131 CHECK_POSIX( pthread_mutex_init(&p->p_mtx, NULL) ); 132 fd_list_init(&p->p_expiry, p); 133 fd_list_init(&p->p_actives, p); 134 p->p_hbh = lrand48(); 135 CHECK_FCT( fd_fifo_new(&p->p_events) ); 136 CHECK_FCT( fd_fifo_new(&p->p_recv) ); 137 CHECK_FCT( fd_fifo_new(&p->p_tosend) ); 138 fd_list_init(&p->p_sentreq, p); 139 140 return 0; 141 } 142 143 #define free_null( _v ) \ 144 if (_v) { \ 145 free(_v); \ 146 (_v) = NULL; \ 147 } 148 149 #define free_list( _l ) \ 150 while (!FD_IS_LIST_EMPTY(_l)) { \ 151 struct fd_list * __li = ((struct fd_list *)(_l))->next; \ 152 fd_list_unlink(__li); \ 153 free(__li); \ 154 } 155 156 /* Destroy a structure once all cleanups have been performed */ 157 static int fd_sp_destroy(struct fd_peer ** ptr) 158 { 159 struct fd_peer *p; 160 void * t; 161 162 TRACE_ENTRY("%p", ptr); 163 CHECK_PARAMS(ptr); 164 p = *ptr; 165 *ptr = NULL; 166 CHECK_PARAMS(p); 167 168 CHECK_PARAMS( (p->p_refcount == 0) && FD_IS_LIST_EMPTY(&p->p_hdr.chain) ); 169 170 free_null(p->p_hdr.info.pi_diamid); 171 free_null(p->p_hdr.info.pi_realm); 172 free_list( &p->p_hdr.info.pi_endpoints ); 173 /* Assume the security data is already freed */ 174 free_null(p->p_hdr.info.pi_prodname); 175 free_list( &p->p_hdr.info.pi_apps ); 176 177 free_null(p->p_dbgorig); 178 CHECK_POSIX( pthread_mutex_destroy(&p->p_mtx) ); 179 ASSERT(FD_IS_LIST_EMPTY(&p->p_expiry)); 180 ASSERT(FD_IS_LIST_EMPTY(&p->p_actives)); 181 182 CHECK_FCT( fd_thr_term(&p->p_psm) ); 183 while ( fd_fifo_tryget(p->p_events, &t) == 0 ) { 184 struct fd_event * ev = t; 185 TRACE_DEBUG(FULL, "Found event %d(%p) in queue of peer %p being destroyed", ev->code, ev->data, p); 186 free(ev); 187 } 188 CHECK_FCT( fd_fifo_del(&p->p_events) ); 189 190 CHECK_FCT( fd_thr_term(&p->p_inthr) ); 191 while ( fd_fifo_tryget(p->p_recv, &t) == 0 ) { 192 struct msg * m = t; 193 TRACE_DEBUG(FULL, "Found message %p in incoming queue of peer %p being destroyed", m, p); 194 /* We simply destroy, the remote peer will re-send to someone else...*/ 195 CHECK_FCT(fd_msg_free(m)); 196 } 197 CHECK_FCT( fd_fifo_del(&p->p_recv) ); 198 199 CHECK_FCT( fd_thr_term(&p->p_outthr) ); 200 while ( fd_fifo_tryget(p->p_tosend, &t) == 0 ) { 201 struct msg * m = t; 202 TRACE_DEBUG(FULL, "Found message %p in outgoing queue of peer %p being destroyed, requeue", m, p); 203 /* We simply requeue in global, the routing thread will re-handle it. */ 204 205 } 206 CHECK_FCT( fd_fifo_del(&p->p_tosend) ); 207 208 while (!FD_IS_LIST_EMPTY(&p->p_sentreq)) { 209 struct sentreq * sr = (struct sentreq *)(p->p_sentreq.next); 210 fd_list_unlink(&sr->chain); 211 TRACE_DEBUG(FULL, "Found message %p in list of sent requests to peer %p being destroyed, requeue (fallback)", sr->req, p); 212 CHECK_FCT(fd_fifo_post(fd_g_outgoing, &sr->req)); 213 free(sr); 214 } 215 216 TRACE_DEBUG(NONE, "TODO: destroy p->p_cnxctx here"); 217 218 if (p->p_cb) 219 (*p->p_cb)(NULL, p->p_cb_data); 220 221 free(p); 222 223 return 0; 224 } 225 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 121 255 /* Add a new peer entry */ 122 256 int fd_peer_add ( struct peer_info * info, char * orig_dbg, void (*cb)(struct peer_info *, void *), void * cb_data ) 123 257 { 124 return ENOTSUP; 125 } 258 struct fd_peer *p = NULL; 259 struct fd_list * li; 260 int ret = 0; 261 TRACE_ENTRY("%p %p %p %p", info, orig_dbg, cb, cb_data); 262 CHECK_PARAMS(info && info->pi_diamid); 263 264 /* Create a structure to contain the new peer information */ 265 CHECK_FCT( fd_sp_reinit(&p) ); 266 267 /* Copy the informations from the parameters received */ 268 CHECK_MALLOC( p->p_hdr.info.pi_diamid = strdup(info->pi_diamid) ); 269 if (info->pi_realm) { 270 CHECK_MALLOC( p->p_hdr.info.pi_realm = strdup(info->pi_realm) ); 271 } 272 273 p->p_hdr.info.pi_flags.pro3 = info->pi_flags.pro3; 274 p->p_hdr.info.pi_flags.pro4 = info->pi_flags.pro4; 275 p->p_hdr.info.pi_flags.alg = info->pi_flags.alg; 276 p->p_hdr.info.pi_flags.sec = info->pi_flags.sec; 277 p->p_hdr.info.pi_flags.exp = info->pi_flags.exp; 278 279 p->p_hdr.info.pi_lft = info->pi_lft; 280 p->p_hdr.info.pi_streams = info->pi_streams; 281 p->p_hdr.info.pi_port = info->pi_port; 282 p->p_hdr.info.pi_tctimer = info->pi_tctimer; 283 p->p_hdr.info.pi_twtimer = info->pi_twtimer; 284 285 /* 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 } 291 292 p->p_hdr.info.pi_sec_module = info->pi_sec_module; 293 memcpy(&p->p_hdr.info.pi_sec_data, &info->pi_sec_data, sizeof(info->pi_sec_data)); 294 295 /* The internal data */ 296 if (orig_dbg) { 297 CHECK_MALLOC( p->p_dbgorig = strdup(orig_dbg) ); 298 } else { 299 CHECK_MALLOC( p->p_dbgorig = strdup("unknown") ); 300 } 301 p->p_cb = cb; 302 p->p_cb_data = cb_data; 303 304 /* Ok, now check if we don't already have an entry with the same Diameter Id, and insert this one */ 305 CHECK_POSIX( pthread_rwlock_wrlock(&fd_g_peers_rw) ); 306 CHECK_POSIX( pthread_mutex_lock( &p->p_mtx ) ); 307 308 for (li = fd_g_peers.next; li != &fd_g_peers; li = li->next) { 309 struct fd_peer * prev = (struct fd_peer *)li; 310 int cmp = strcasecmp( p->p_hdr.info.pi_diamid, prev->p_hdr.info.pi_diamid ); 311 if (cmp < 0) 312 continue; 313 if (cmp == 0) 314 ret = EEXIST; 315 break; 316 } 317 318 /* We can insert the new peer object */ 319 if (! ret) { 320 /* Update expiry list */ 321 CHECK_FCT_DO( ret = fd_p_expi_update( p, 1 ), goto out ); 322 323 /* Insert the new element in the list */ 324 fd_list_insert_before( li, &p->p_hdr.chain ); 325 p->p_refcount++; 326 } 327 328 out: 329 CHECK_POSIX( pthread_mutex_unlock( &p->p_mtx ) ); 330 CHECK_POSIX( pthread_rwlock_unlock(&fd_g_peers_rw) ); 331 if (ret) { 332 CHECK_FCT( fd_sp_destroy(&p) ); 333 } else { 334 CHECK_FCT( fd_psm_start(p) ); 335 } 336 return ret; 337 } -
freeDiameter/queues.c
r10 r13 57 57 58 58 /* Stop the providing threads */ 59 TODO("Stop the providing threads"); 60 59 61 /* Empty all contents */ 62 TODO("Empty all contents (dump to log file ?)"); 63 60 64 /* Now, delete the queues */ 61 65 CHECK_FCT( fd_fifo_del ( &fd_g_incoming ) ); 62 66 CHECK_FCT( fd_fifo_del ( &fd_g_outgoing ) ); 63 67 CHECK_FCT( fd_fifo_del ( &fd_g_local ) ); 68 64 69 return 0; 65 70 } -
include/freeDiameter/CMakeLists.txt
r8 r13 11 11 # Disable SCTP support completly ? 12 12 OPTION(DISABLE_SCTP "Disable SCTP support?") 13 14 # Disable SCTP support completly ? 15 OPTION(ERRORS_ON_TODO "(development) Generate compilation errors on TODO items ?" OFF) 13 16 14 17 -
include/freeDiameter/freeDiameter-host.h.in
r9 r13 45 45 46 46 #cmakedefine DISABLE_SCTP 47 47 #cmakedefine ERRORS_ON_TODO 48 48 #cmakedefine DEBUG 49 49 -
include/freeDiameter/freeDiameter.h
r12 r13 81 81 struct fd_list chain; /* link in cnf_endpoints list */ 82 82 sSS ss; /* the socket information. */ 83 struct { 84 unsigned conf : 1; /* This endpoint is statically configured in a configuration file */ 85 unsigned disc : 1; /* This endpoint was resolved from the Diameter Identity or other DNS query */ 86 unsigned adv : 1; /* This endpoint was advertized in Diameter CER/CEA exchange */ 87 unsigned ll : 1; /* Lower layer mechanism provided this endpoint */ 88 89 /* To add: a validity timestamp for DNS records ? How do we retrieve this lifetime from DNS ? */ 90 91 } meta; /* Additional information about the endpoint */ 83 92 }; 84 93 … … 164 173 peer_state_str[ ((unsigned)(state)) <= STATE_REOPEN ? ((unsigned)(state)) : 0 ] 165 174 166 /* Information about a remote peer , used both for query and for creating a new entry*/175 /* Information about a remote peer. Same structure is used for creating a new entry, but not all fields are meaningful in that case */ 167 176 struct peer_info { 168 177 169 char * pi_diamid; /* UTF-8, \0 terminated. The Diameter Identity of the remote peer */170 char * pi_realm; /* idem, its realm. */178 char * pi_diamid; /* UTF-8, \0 terminated. The Diameter Identity of the remote peer */ 179 char * pi_realm; /* Its realm, as received in CER/CEA exchange. */ 171 180 172 181 struct { … … 191 200 192 201 #define PI_EXP_NONE 0 /* the peer entry does not expire */ 193 #define PI_EXP_INACTIVE 1 /* the peer entry expires after pi_lft seconds without activity */202 #define PI_EXP_INACTIVE 1 /* the peer entry expires (i.e. is deleted) after pi_lft seconds without activity */ 194 203 unsigned exp :1; 195 204 … … 199 208 unsigned inband :2; /* This is only meaningful with pi_flags.sec == 3 */ 200 209 201 unsigned relay :1; /* The remote peer advertized the relay application */ 202 } pi_flags; 210 unsigned relay :1; /* The remote peer advertized the relay application */ 211 212 } pi_flags; /* Some flags */ 203 213 204 214 /* Additional parameters */ 205 uint32_t pi_lft; /* lifetime of entry without activity (except watchdogs)(see pi_flags.exp definition) */215 uint32_t pi_lft; /* lifetime of this peer when inactive (see pi_flags.exp definition) */ 206 216 uint16_t pi_streams; /* number of streams for SCTP. 0 = default */ 207 217 uint16_t pi_port; /* port to connect to. 0: default. */ … … 209 219 int pi_twtimer; /* use this value for TwTimer instead of global, if != 0 */ 210 220 211 struct fd_list pi_endpoints; /* Endpoint(s) of the remote peer (discovered or advertized). list of struct fd_endpoint. DNS resolved if empty. */ 221 struct fd_list pi_endpoints; /* Endpoint(s) of the remote peer (configured, discovered, or advertized). list of struct fd_endpoint. DNS resolved if empty. */ 222 223 /* TLS specific data -- the exact data pointed here depends on the security module in use (ex: gnutls, ...) */ 224 enum { 225 PI_SEC_GNUTLS = 0, /* The security module is GNUTLS, this is the default */ 226 PI_SEC_OTHER /* Another security module (TBD) */ 227 } pi_sec_module; 228 union { 229 /* Security data when pi_sec_module == PI_SEC_GNUTLS */ 230 struct { 231 void * CA; /* Authority to use to validate this peer credentials (a CA or root certificate) -- use default if NULL */ 232 void * cred; /* The (valid) credentials that the peer has presented */ 233 } gnutls; 234 /* Security data when pi_sec_module == PI_SEC_OTHER */ 235 struct { 236 void * dummy; /* Something meaningful for the other security module */ 237 } other; 238 } pi_sec_data; 212 239 213 240 /* The remaining information is read-only, not used for peer creation */ … … 244 271 * DESCRIPTION: 245 272 * Add a peer to the list of peers to which the daemon must maintain a connexion. 246 * If cb is not null, the callback is called when the connection is in OPEN state or 273 * 274 * The content of info parameter is copied, except for the list of endpoints if 275 * not empty, which is simply moved into the created object. It means that the list 276 * items must have been malloc'd, so that they can be freed. 277 * 278 * If cb is not null, the callback is called when the connection is in OPEN state or 247 279 * when an error has occurred. The callback should use the pi_state information to 248 * determine which one it is. 280 * determine which one it is. If the first parameter of the called callback is NULL, it 281 * means that the peer is being destroyed before attempt success / failure. 282 * cb is called to allow freeing cb_data in * this case. 283 * 284 * The orig_dbg string is only useful for easing debug, and can be left to NULL. 249 285 * 250 286 * RETURN VALUE: -
include/freeDiameter/libfreeDiameter.h
r10 r13 189 189 #define TRACE_DEBUG_ALL( str ) \ 190 190 TRACE_DEBUG(CALL, str ); 191 192 /* For development only, to keep track of TODO locations in the code */ 193 #ifndef ERRORS_ON_TODO 194 #define TODO( _msg, _args... ) \ 195 TRACE_DEBUG(NONE, _msg , ##_args); 196 #else /* ERRORS_ON_TODO */ 197 #define TODO( _msg, _args... ) \ 198 "TODO" = _msg ## _args; /* just a stupid compilation error to spot the todo */ 199 #endif /* ERRORS_ON_TODO */ 191 200 192 201
Note: See TracChangeset
for help on using the changeset viewer.