peermanager.c File Reference


Detailed Description

CDiameterPeer Peer Management.

Author:
Dragos Vingarzan vingarzan -at- fokus dot fraunhofer dot de

Definition in file peermanager.c.

#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include "diameter.h"
#include "timer.h"
#include "peermanager.h"
#include "globals.h"
#include "peerstatemachine.h"

Go to the source code of this file.

Functions

int peer_manager_init (dp_config *config)
 Initializes the Peer Manager.
void peer_manager_destroy ()
 Destroys the Peer Manager and disconnects all peer sockets.
void log_peer_list (int level)
 Logs the list of peers.
void add_peer (peer *p)
 Adds a peer to the peer list.
void remove_peer (peer *p)
 Removes a peer from the peer list.
peerget_peer_from_sock (int sock)
 Finds a peer based on the TCP socket.
peerget_peer_from_fqdn (str fqdn, str realm)
 Finds a peer based on the FQDN and Realm.
peerget_peer_by_fqdn (str *fqdn)
 Finds a peer based on the FQDN.
void peer_timer (time_t now, void *ptr)
 Timer function for peer management.
AAAMsgIdentifier next_hopbyhop ()
 Generates the next Hop-by-hop identifier.
AAAMsgIdentifier next_endtoend ()
 Generates the next End-to-end identifier.

Variables

peer_list_tpeer_list = 0
 list of peers
gen_lock_t * peer_list_lock = 0
 lock for the list of peers
dp_configconfig
 Configuration for this diameter peer.
char * dp_states []
 Strings for the peer states.
AAAMsgIdentifierhopbyhop_id = 0
 Current id for Hop-by-hop.
AAAMsgIdentifierendtoend_id = 0
 Current id for End-to-end.
gen_lock_t * msg_id_lock
 lock for the message identifier changes


Function Documentation

int peer_manager_init ( dp_config config  ) 

Initializes the Peer Manager.

The initial list of peers is taken from the configuration provided

Parameters:
config - configuration for initial peers
Returns:
1

Definition at line 81 of file peermanager.c.

References add_peer(), add_timer(), config, endtoend_id, peer_config::fqdn, peer_list_t::head, hopbyhop_id, if, _peer_t::is_dynamic, msg_id_lock, new_peer(), peer_list, peer_list_lock, PEER_MANAGER_TIMER, peer_timer(), dp_config::peers, dp_config::peers_cnt, peer_config::port, peer_config::realm, and peer_list_t::tail.

Referenced by diameter_peer_init().

00082 {
00083     int i;
00084     peer *p;
00085     LOG(L_DBG,"DBG:peer_manager_init(): Peer Manager initialization...\n");
00086     peer_list = shm_malloc(sizeof(peer_list_t));
00087     peer_list->head = 0; 
00088     peer_list->tail = 0;
00089     peer_list_lock = lock_alloc();
00090     peer_list_lock = lock_init(peer_list_lock);
00091     
00092     hopbyhop_id = shm_malloc(sizeof(AAAMsgIdentifier));
00093     endtoend_id = shm_malloc(sizeof(AAAMsgIdentifier));
00094     msg_id_lock = lock_alloc();
00095     msg_id_lock = lock_init(msg_id_lock);
00096     
00097     srand((unsigned int)time(0));
00098     *hopbyhop_id = rand();
00099     *endtoend_id = (time(0)&0xFFF)<<20;
00100     *endtoend_id |= rand() & 0xFFFFF;   
00101 
00102     for(i=0;i<config->peers_cnt;i++){
00103         p = new_peer(config->peers[i].fqdn,config->peers[i].realm,config->peers[i].port);
00104         if (!p) continue;
00105         p->is_dynamic = 0;
00106         add_peer(p);
00107     }
00108     
00109     add_timer(PEER_MANAGER_TIMER,0,&peer_timer,0);
00110     
00111     return 1;
00112 }

void peer_manager_destroy (  ) 

Destroys the Peer Manager and disconnects all peer sockets.

Definition at line 117 of file peermanager.c.

References endtoend_id, free_peer(), peer_list_t::head, hopbyhop_id, _peer_t::I_sock, msg_id_lock, _peer_t::next, peer_list, peer_list_lock, and _peer_t::R_sock.

Referenced by diameter_peer_destroy().

00118 {
00119     peer *foo,*bar;
00120     lock_get(peer_list_lock);
00121     foo = peer_list->head;
00122     while(foo){
00123         if (foo->I_sock>0) close(foo->I_sock);
00124         if (foo->R_sock>0) close(foo->R_sock);
00125         bar = foo->next;
00126         free_peer(foo,1);
00127         foo = bar;
00128     }
00129 
00130 /*  lock_get(msg_id_lock);  */
00131     shm_free(hopbyhop_id);
00132     shm_free(endtoend_id);  
00133     lock_destroy(msg_id_lock);
00134     lock_dealloc((void*)msg_id_lock);
00135 
00136     shm_free(peer_list);    
00137     lock_destroy(peer_list_lock);
00138     lock_dealloc((void*)peer_list_lock);
00139     LOG(L_DBG,"DBG:peer_manager_init(): ...Peer Manager destroyed\n");
00140 }

void log_peer_list ( int  level  ) 

Logs the list of peers.

Parameters:
level - log level to print to

Definition at line 146 of file peermanager.c.

References ANSI_BLUE, ANSI_GREEN, ANSI_RED, ANSI_YELLOW, _peer_t::applications, _peer_t::applications_cnt, dp_states, _peer_t::fqdn, peer_list_t::head, app_config::id, _peer_t::is_dynamic, _peer_t::next, peer_list, _peer_t::port, _peer_t::state, and app_config::vendor.

Referenced by peer_timer(), and sm_process().

00147 {
00148     /* must have lock on peer_list_lock when calling this!!! */
00149     peer *p;
00150     int i;
00151     LOG(level,"--- Peer List: ---\n");
00152     for(p = peer_list->head;p;p = p->next){
00153         LOG(level,ANSI_GREEN" S["ANSI_YELLOW"%s"ANSI_GREEN"] "ANSI_BLUE"%.*s:%d"ANSI_GREEN" D["ANSI_RED"%c"ANSI_GREEN"]\n",dp_states[p->state],p->fqdn.len,p->fqdn.s,p->port,p->is_dynamic?'X':' ');
00154         for(i=0;i<p->applications_cnt;i++)
00155             LOG(level,ANSI_YELLOW"\t [%d,%d]\n",p->applications[i].id,p->applications[i].vendor);
00156     }
00157     LOG(level,"------------------\n");       
00158 }

void add_peer ( peer p  ) 

Adds a peer to the peer list.

Parameters:
p - peer to add

Definition at line 164 of file peermanager.c.

References peer_list_t::head, _peer_t::next, peer_list, peer_list_lock, _peer_t::prev, and peer_list_t::tail.

Referenced by get_peer_from_fqdn(), and peer_manager_init().

00165 {
00166     if (!p) return;
00167     lock_get(peer_list_lock);
00168     p->next = 0;
00169     p->prev = peer_list->tail;
00170     if (!peer_list->head) peer_list->head = p;
00171     if (peer_list->tail) peer_list->tail->next = p;
00172     peer_list->tail = p;
00173     lock_release(peer_list_lock);
00174 }

void remove_peer ( peer p  ) 

Removes a peer from the peer list.

Parameters:
p - the peer to remove

Definition at line 180 of file peermanager.c.

References peer_list_t::head, _peer_t::next, peer_list, _peer_t::prev, and peer_list_t::tail.

Referenced by peer_timer().

00181 {
00182     peer *i;
00183     if (!p) return;
00184     i = peer_list->head;
00185     while(i&&i!=p) i = i->next;
00186     if (i){
00187         if (i->prev) i->prev->next = i->next;
00188         else peer_list->head = i->next;
00189         if (i->next) i->next->prev = i->prev;
00190         else peer_list->tail = i->prev;
00191     }
00192 }

peer* get_peer_from_sock ( int  sock  ) 

Finds a peer based on the TCP socket.

Parameters:
sock - socket to look for
Returns:
the peer* or NULL if not found

Definition at line 199 of file peermanager.c.

References peer_list_t::head, _peer_t::I_sock, _peer_t::next, peer_list, peer_list_lock, and _peer_t::R_sock.

Referenced by receive_message().

00200 {
00201     peer *i;
00202     lock_get(peer_list_lock);
00203     
00204     i = peer_list->head;
00205     while(i&&i->I_sock!=sock&&i->R_sock!=sock) i = i->next;
00206     lock_release(peer_list_lock);
00207     return i;
00208 }

peer* get_peer_from_fqdn ( str  fqdn,
str  realm 
)

Finds a peer based on the FQDN and Realm.

Parameters:
fqdn - the FQDN to look for
realm - the Realm to look for
Returns:
the peer* or NULL if not found

Definition at line 216 of file peermanager.c.

References dp_config::accept_unknown_peers, add_peer(), config, _peer_t::fqdn, peer_list_t::head, _peer_t::is_dynamic, new_peer(), _peer_t::next, peer_list, peer_list_lock, and touch_peer().

Referenced by receive_message().

00217 {
00218     peer *i;
00219     lock_get(peer_list_lock);
00220     i = peer_list->head;
00221     while(i){
00222         if (fqdn.len == i->fqdn.len && strncasecmp(fqdn.s,i->fqdn.s,fqdn.len)==0) 
00223             break;
00224         i = i->next;
00225     }
00226     lock_release(peer_list_lock);
00227     if (!i&&config->accept_unknown_peers){
00228         i = new_peer(fqdn,realm,3868);
00229         if (i){
00230             i->is_dynamic=1;
00231             touch_peer(i);
00232             add_peer(i);
00233         }
00234     }
00235     return i;
00236 }

peer* get_peer_by_fqdn ( str *  fqdn  ) 

Finds a peer based on the FQDN.

Parameters:
fqdn - the FQDN to look for
Returns:
the peer* or NULL if not found

Definition at line 243 of file peermanager.c.

References _peer_t::fqdn, peer_list_t::head, _peer_t::next, peer_list, and peer_list_lock.

Referenced by AAASendMessageToPeer(), AAASendRecvMessageToPeer(), get_first_connected_route(), and get_routing_peer().

00244 {
00245     peer *i;
00246     lock_get(peer_list_lock);
00247     i = peer_list->head;
00248     while(i){
00249         if (fqdn->len == i->fqdn.len && strncasecmp(fqdn->s,i->fqdn.s,fqdn->len)==0) 
00250             break;
00251         i = i->next;
00252     }
00253     lock_release(peer_list_lock);
00254     return i;
00255 }

void peer_timer ( time_t  now,
void *  ptr 
)

Timer function for peer management.

This is registered as a timer by peer_manager_init() and gets called every PEER_MANAGER_TIMER seconds. Then it looks on what changed and triggers events.

Parameters:
now - time of call
ptr - generic pointer for timers - not used

Definition at line 264 of file peermanager.c.

References _peer_t::activity, Closed, Closing, config, dp_config::drop_unknown_peers, _peer_t::fqdn, free_peer(), peer_list_t::head, I_Open, I_Peer_Disc, _peer_t::is_dynamic, _peer_t::lock, log_peer_list(), _peer_t::next, peer_list, peer_list_lock, R_Open, R_Peer_Disc, remove_peer(), sm_process(), Snd_DWR(), Start, _peer_t::state, dp_config::tc, Timeout, touch_peer(), Wait_Conn_Ack, Wait_I_CEA, Wait_Returns, and _peer_t::waitingDWA.

Referenced by peer_manager_init().

00265 {
00266     peer *p,*n;
00267     LOG(L_DBG,"DBG:peer_timer(): taking care of peers...\n");
00268     lock_get(peer_list_lock);
00269     p = peer_list->head;
00270     while(p){
00271         lock_get(p->lock);
00272         n = p->next;
00273         if (p->activity+config->tc<=now){
00274             LOG(L_INFO,"DBG:peer_timer(): Peer %.*s \tState %d \n",p->fqdn.len,p->fqdn.s,p->state);
00275             switch (p->state){
00276                 /* initiating connection */
00277                 case Closed:
00278                     if (p->is_dynamic && config->drop_unknown_peers){
00279                         remove_peer(p);
00280                         free_peer(p,1);
00281                         break;
00282                     }
00283                     touch_peer(p);
00284                     sm_process(p,Start,0,1,0);
00285                     break;
00286                 /* timeouts */  
00287                 case Wait_Conn_Ack:
00288                 case Wait_I_CEA:
00289                 case Closing:
00290                 case Wait_Returns:
00291                     touch_peer(p);
00292                     sm_process(p,Timeout,0,1,0);
00293                     break;  
00294                 /* inactivity detected */
00295                 case I_Open:
00296                 case R_Open:
00297                     if (p->waitingDWA){
00298                         p->waitingDWA = 0;
00299                         if (p->state==I_Open) sm_process(p,I_Peer_Disc,0,1,p->I_sock);
00300                         if (p->state==R_Open) sm_process(p,R_Peer_Disc,0,1,p->R_sock);
00301                     } else {
00302                         p->waitingDWA = 1;
00303                         Snd_DWR(p);
00304                         touch_peer(p);
00305                     }
00306                     break;
00307                 /* ignored states */    
00308                 /* unknown states */
00309                 default:
00310                     LOG(L_ERR,"ERROR:peer_timer(): Peer %.*s inactive  in state %d\n",
00311                         p->fqdn.len,p->fqdn.s,p->state);
00312             }               
00313         }
00314         lock_release(p->lock);
00315         p = n;
00316     }
00317     lock_release(peer_list_lock);
00318     log_peer_list(L_INFO);  
00319 }

AAAMsgIdentifier next_hopbyhop (  )  [inline]

Generates the next Hop-by-hop identifier.

Returns:
the new identifier to be used in messages

Definition at line 325 of file peermanager.c.

References hopbyhop_id, and msg_id_lock.

Referenced by AAACreateRequest(), I_Snd_CER(), Snd_DPR(), and Snd_DWR().

00326 {
00327     AAAMsgIdentifier x;
00328     lock_get(msg_id_lock);
00329     *hopbyhop_id = (*hopbyhop_id)+1;
00330     x = *hopbyhop_id;
00331     lock_release(msg_id_lock);
00332     return x;
00333 }

AAAMsgIdentifier next_endtoend (  )  [inline]

Generates the next End-to-end identifier.

Returns:
the new identifier to be used in messages

Definition at line 339 of file peermanager.c.

References endtoend_id, and msg_id_lock.

Referenced by AAACreateRequest(), I_Snd_CER(), Snd_DPR(), and Snd_DWR().

00340 {
00341     AAAMsgIdentifier x;
00342     lock_get(msg_id_lock);
00343     *endtoend_id = (*endtoend_id)+1;
00344     x = *endtoend_id;
00345     lock_release(msg_id_lock);
00346     return x;
00347 }


Variable Documentation

peer_list_t* peer_list = 0

list of peers

Definition at line 66 of file peermanager.c.

Referenced by add_peer(), get_peer_by_fqdn(), get_peer_from_fqdn(), get_peer_from_sock(), log_peer_list(), peer_manager_destroy(), peer_manager_init(), peer_timer(), and remove_peer().

gen_lock_t* peer_list_lock = 0

lock for the list of peers

Definition at line 67 of file peermanager.c.

Referenced by add_peer(), get_peer_by_fqdn(), get_peer_from_fqdn(), get_peer_from_sock(), peer_manager_destroy(), peer_manager_init(), and peer_timer().

dp_config* config

Configuration for this diameter peer.

Definition at line 76 of file diameter_peer.c.

char* dp_states[]

Strings for the peer states.

Definition at line 69 of file peerstatemachine.c.

Referenced by log_peer_list(), and sm_process().

AAAMsgIdentifier* hopbyhop_id = 0

Current id for Hop-by-hop.

Definition at line 71 of file peermanager.c.

Referenced by next_hopbyhop(), peer_manager_destroy(), and peer_manager_init().

AAAMsgIdentifier* endtoend_id = 0

Current id for End-to-end.

Definition at line 72 of file peermanager.c.

Referenced by next_endtoend(), peer_manager_destroy(), and peer_manager_init().

gen_lock_t* msg_id_lock

lock for the message identifier changes

Definition at line 73 of file peermanager.c.

Referenced by next_endtoend(), next_hopbyhop(), peer_manager_destroy(), and peer_manager_init().


Generated on Fri Jul 18 04:14:01 2008 for Open IMS Core CSCFs by  doxygen 1.5.2