peerstatemachine.h File Reference


Detailed Description

CDiameterPeer Diameter base protocol state-machine definition.

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

Definition in file peerstatemachine.h.

#include "utils.h"
#include "peer.h"
#include "diameter.h"

Go to the source code of this file.

Functions

int sm_process (peer *p, peer_event_t event, AAAMessage *msg, int peer_locked, int sock)
 Diameter base protocol state-machine processing.
peer_state_t I_Snd_Conn_Req (peer *p)
 Initiator - Send Connection Request.
void Cleanup (peer *p, int sock)
 Cleans a socket by closing it and removing the reference.
void Error (peer *p, int sock)
 Error action for a peer, triggers a Cleanup action.
void I_Snd_CER (peer *p)
 Send a Capability Exchange Request.
int Process_CEA (peer *p, AAAMessage *cea)
 Process a Capability Exchange Answer.
void I_Disc (peer *p)
 Initiator - disconnect peer.
void R_Disc (peer *p)
 Receiver - disconnect peer.
int Process_DWR (peer *p, AAAMessage *dwr)
 Process a Diameter Watch-dog Request.
void Process_DWA (peer *p, AAAMessage *dwa)
 Process a Diameter Watch-dog Answer.
void Snd_DWR (peer *p)
 Sends a Diameter Watch-dog Request.
void Snd_DWA (peer *p, AAAMessage *dwr, int result_code, int sock)
 Sends a Diameter Watch-dog Answer.
void Snd_DPR (peer *p)
 Sends a Disconnect Peer Request.
void Snd_DPA (peer *p, AAAMessage *dpr, int result_code, int sock)
 Sends a Disconnect Peer Answer.
void R_Accept (peer *p, int sock)
 Receiver - Accept a connection.
void R_Reject (peer *p, int sock)
 Receiver - Reject a connection.
int Process_CER (peer *p, AAAMessage *cer)
 Process a Capabilities Exchange Request.
void Snd_CEA (peer *p, AAAMessage *cer, int result_code, int sock)
 Send a Capabilities Exchange Answer.
int Elect (peer *p, AAAMessage *cer)
 Perform the Election mechanism.
void Snd_Message (peer *p, AAAMessage *msg)
 Sends a message to the peer.
void Rcv_Process (peer *p, AAAMessage *msg)
 Processes an incoming message.


Function Documentation

int sm_process ( peer p,
peer_event_t  event,
AAAMessage msg,
int  peer_locked,
int  sock 
)

Diameter base protocol state-machine processing.

This function get's called for every event. It updates the states and can trigger other events.

Parameters:
p - the peer for which the event happened
event - the event that happened
msg - if a Diameter message was received this is it, or NULL if not
peer_locked - if the peer lock is already aquired
sock - socket that this event happened on, or NULL if unrelated
Returns:
1 on success, 0 on error. Also the peer states are updated

Definition at line 88 of file peerstatemachine.c.

References AAA_SUCCESS, Cleanup(), Closed, Closing, dp_events, dp_states, Elect(), Error(), _peer_t::fqdn, I_Disc(), I_Open, I_Peer_Disc, I_Rcv_CEA, I_Rcv_CER, I_Rcv_Conn_Ack, I_Rcv_Conn_NAck, I_Rcv_DPA, I_Rcv_DPR, I_Rcv_DWA, I_Rcv_DWR, I_Rcv_Message, I_Rcv_Non_CEA, I_Snd_CER(), I_Snd_Conn_Req(), _peer_t::I_sock, _peer_t::lock, log_peer_list(), Process_CEA(), Process_CER(), Process_DWA(), Process_DWR(), R_Accept(), R_Conn_CER, R_Disc(), R_Open, R_Peer_Disc, R_Rcv_CEA, R_Rcv_CER, R_Rcv_DPA, R_Rcv_DPR, R_Rcv_DWA, R_Rcv_DWR, R_Rcv_Message, R_Reject(), _peer_t::R_sock, Rcv_Process(), Send_Message, sm_process(), Snd_CEA(), Snd_DPA(), Snd_DPR(), Snd_DWA(), Snd_Message(), Start, _peer_t::state, Stop, Timeout, Wait_Conn_Ack, Wait_Conn_Ack_Elect, Wait_I_CEA, Wait_Returns, and Win_Election.

Referenced by peer_send(), peer_timer(), receive_loop(), receive_message(), and sm_process().

00089 {
00090     int result_code;
00091     peer_event_t next_event;
00092     int msg_received=0;
00093         
00094     if (!peer_locked) lock_get(p->lock);
00095     LOG(L_INFO,"DBG:sm_process(): Peer %.*s \tState %s \tEvent %s\n",
00096         p->fqdn.len,p->fqdn.s,dp_states[p->state],dp_events[event-101]);
00097 
00098     switch (p->state){
00099         case Closed:
00100             switch (event){
00101                 case Start:
00102                     p->state = Wait_Conn_Ack;
00103                     next_event = I_Snd_Conn_Req(p);
00104                     sm_process(p,next_event,0,1,p->I_sock);
00105                     break;  
00106                 case R_Conn_CER:
00107                     R_Accept(p,sock);
00108                     result_code = Process_CER(p,msg);
00109                     Snd_CEA(p,msg,result_code,p->R_sock);
00110                     if (result_code>=2000 && result_code<3000)
00111                         p->state = R_Open;
00112                     else {
00113                         R_Disc(p);
00114                         p->state = Closed;
00115                     }
00116                     log_peer_list(L_INFO);
00117                     break;
00118                 case Stop:
00119                     /* just ignore this state */
00120                     p->state = Closed;
00121                     break;
00122                 default:
00123                     LOG(L_DBG,"DBG:sm_process(): In state %s invalid event %s\n",
00124                         dp_states[p->state],dp_events[event-101]);
00125                     goto error;
00126             }
00127             break;      
00128         case Wait_Conn_Ack:
00129             switch(event){
00130                 case I_Rcv_Conn_Ack:
00131                     I_Snd_CER(p);
00132                     p->state = Wait_I_CEA;
00133                     break;  
00134                 case I_Rcv_Conn_NAck:
00135                     Cleanup(p,p->I_sock);
00136                     p->state = Closed;
00137                     break;
00138 /* Commented as not reachable*/                     
00139                 case R_Conn_CER:
00140                     R_Accept(p,sock);
00141                     result_code = Process_CER(p,msg);
00142                     if (result_code>=2000 && result_code<3000)
00143                         p->state = Wait_Conn_Ack_Elect;
00144                     else {
00145                         p->state = Wait_Conn_Ack;
00146                         close(sock);
00147                     }
00148                     break;
00149                 case Timeout:
00150                     Error(p,p->I_sock);
00151                     p->state = Closed;
00152                 default:
00153                     LOG(L_DBG,"DBG:sm_process(): In state %s invalid event %s\n",
00154                         dp_states[p->state],dp_events[event-101]);
00155                     goto error;
00156             }
00157             break;
00158             
00159         case Wait_I_CEA:
00160             switch(event){
00161                 case I_Rcv_CEA:
00162                     result_code = Process_CEA(p,msg);
00163                     if (result_code>=2000 && result_code<3000)
00164                         p->state = I_Open;                                              
00165                     else {
00166                         Cleanup(p,p->I_sock);
00167                         p->state = Closed;
00168                     }
00169                     log_peer_list(L_INFO);
00170                     break;
00171                 case R_Conn_CER:
00172                     R_Accept(p,sock);
00173                     result_code = Process_CER(p,msg);
00174                     p->state = Wait_Returns;
00175                     if (Elect(p,msg))
00176                         sm_process(p,Win_Election,msg,1,sock);
00177                     break;
00178                 case I_Peer_Disc:
00179                     I_Disc(p);
00180                     p->state = Closed;
00181                     break;
00182                 case I_Rcv_Non_CEA:
00183                     Error(p,p->I_sock);
00184                     p->state = Closed;
00185                     break;
00186                 case Timeout:
00187                     Error(p,p->I_sock);
00188                     p->state = Closed;
00189                     break;
00190                 default:
00191                     LOG(L_DBG,"DBG:sm_process(): In state %s invalid event %s\n",
00192                         dp_states[p->state],dp_events[event-101]);
00193                     goto error;
00194             }
00195             break;  
00196 /* commented as not reachable */
00197         case Wait_Conn_Ack_Elect:
00198             switch(event){
00199                 default:
00200                     LOG(L_DBG,"DBG:sm_process(): In state %s invalid event %s\n",
00201                         dp_states[p->state],dp_events[event-101]);
00202                     goto error;
00203             }
00204             break;
00205         case Wait_Returns:
00206             switch(event){
00207                 case Win_Election:
00208                     I_Disc(p);
00209                     result_code = Process_CER(p,msg);
00210                     Snd_CEA(p,msg,result_code,p->R_sock);
00211                     if (result_code>=2000 && result_code<3000){
00212                         p->state = R_Open;
00213                     }else{
00214                         R_Disc(p);
00215                         p->state = Closed;
00216                     }
00217                     break;
00218                 case I_Peer_Disc:
00219                     I_Disc(p);
00220                     result_code = Process_CER(p,msg);
00221                     Snd_CEA(p,msg,result_code,p->R_sock);
00222                     if (result_code>=2000 && result_code<3000){
00223                         p->state = R_Open;
00224                     }else{
00225                         R_Disc(p);
00226                         p->state = Closed;
00227                     }
00228                     break;
00229                 case I_Rcv_CEA:
00230                     R_Disc(p);
00231                     result_code = Process_CEA(p,msg);
00232                     if (result_code>=2000 && result_code<3000)
00233                         p->state = I_Open; 
00234                     else {
00235                         Cleanup(p,p->I_sock);
00236                         p->state = Closed;
00237                     }
00238                     break;
00239                 case R_Peer_Disc:
00240                     R_Disc(p);
00241                     p->state = Wait_I_CEA;
00242                     break;
00243                 case R_Conn_CER:
00244                     R_Reject(p,p->R_sock);
00245                     p->state = Wait_Returns;
00246                     break;
00247                 case Timeout:
00248                     if (p->I_sock>=0) Error(p,p->I_sock);
00249                     if (p->R_sock>=0) Error(p,p->R_sock);
00250                     p->state = Closed;
00251                 default:
00252                     LOG(L_DBG,"DBG:sm_process(): In state %s invalid event %s\n",
00253                         dp_states[p->state],dp_events[event-101]);
00254                     goto error;
00255             }
00256             break;
00257         case R_Open:
00258             switch (event){
00259                 case Send_Message:
00260                     Snd_Message(p,msg);
00261                     p->state = R_Open;
00262                     break;
00263                 case R_Rcv_Message:
00264                     // delayed processing until out of the critical zone
00265                     //Rcv_Process(p,msg);
00266                     msg_received = 1;
00267                     p->state = R_Open;
00268                     break;
00269                 case R_Rcv_DWR:
00270                     result_code = Process_DWR(p,msg);
00271                     Snd_DWA(p,msg,result_code,p->R_sock);
00272                     p->state = R_Open;
00273                     break;
00274                 case R_Rcv_DWA:
00275                     Process_DWA(p,msg);
00276                     p->state = R_Open;
00277                     break;
00278                 case R_Conn_CER:
00279                     R_Reject(p,sock);
00280                     p->state = R_Open;
00281                     break;
00282                 case Stop:
00283                     Snd_DPR(p);
00284                     p->state = Closing;
00285                     break;
00286                 case R_Rcv_DPR:
00287                     Snd_DPA(p,msg,AAA_SUCCESS,p->R_sock);
00288                     R_Disc(p);
00289                     p->state = Closed;
00290                     log_peer_list(L_INFO);
00291                     break;
00292                 case R_Peer_Disc:
00293                     R_Disc(p);
00294                     p->state = Closed;
00295                     log_peer_list(L_INFO);
00296                     break;
00297                 case R_Rcv_CER:
00298                     result_code = Process_CER(p,msg);
00299                     Snd_CEA(p,msg,result_code,p->R_sock);
00300                     if (result_code>=2000 && result_code<3000)
00301                         p->state = R_Open;
00302                     else {
00303                         /*R_Disc(p);p.state = Closed;*/
00304                         p->state = R_Open; /* Or maybe I should disconnect it?*/
00305                     }
00306                     break;
00307                 case R_Rcv_CEA:
00308                     result_code = Process_CEA(p,msg);
00309                     if (result_code>=2000 && result_code<3000)
00310                         p->state = R_Open;
00311                     else {
00312                         /*R_Disc(p);p.state = Closed;*/
00313                         p->state = R_Open; /* Or maybe I should disconnect it?*/
00314                     }
00315                     log_peer_list(L_INFO);
00316                     break;
00317                 default:
00318                     LOG(L_DBG,"DBG:sm_process(): In state %s invalid event %s\n",
00319                         dp_states[p->state],dp_events[event-101]);
00320                     goto error;
00321             }
00322             break;          
00323         case I_Open:
00324             switch (event){
00325                 case Send_Message:
00326                     Snd_Message(p,msg);
00327                     p->state = I_Open;
00328                     break;
00329                 case I_Rcv_Message:
00330                     // delayed processing until out of the critical zone
00331                     //Rcv_Process(p,msg);
00332                     msg_received = 1;
00333                     p->state = I_Open;
00334                     break;
00335                 case I_Rcv_DWR:
00336                     result_code = Process_DWR(p,msg);
00337                     Snd_DWA(p,msg,result_code,p->I_sock);                       
00338                     p->state =I_Open;
00339                     break;
00340                 case I_Rcv_DWA:
00341                     Process_DWA(p,msg);
00342                     p->state =I_Open;
00343                     break;
00344                 case R_Conn_CER:
00345                     R_Reject(p,sock);
00346                     p->state = I_Open;
00347                     break;
00348                 case Stop:
00349                     Snd_DPR(p);
00350                     p->state = Closing;
00351                     break;
00352                 case I_Rcv_DPR:
00353                     Snd_DPA(p,msg,2001,p->I_sock);
00354                     R_Disc(p);
00355                     p->state = Closed;
00356                     log_peer_list(L_INFO);
00357                     break;
00358                 case I_Peer_Disc:
00359                     I_Disc(p);
00360                     p->state = Closed;
00361                     log_peer_list(L_INFO);
00362                     break;
00363                 case I_Rcv_CER:
00364                     result_code = Process_CER(p,msg);
00365                     Snd_CEA(p,msg,result_code,p->I_sock);
00366                     if (result_code>=2000 && result_code<3000)
00367                         p->state = I_Open;
00368                     else {
00369                         /*I_Disc(p);p.state = Closed;*/
00370                         p->state = I_Open; /* Or maybe I should disconnect it?*/
00371                     }
00372                     break;
00373                 case I_Rcv_CEA:
00374                     result_code = Process_CEA(p,msg);
00375                     if (result_code>=2000 && result_code<3000)
00376                         p->state = I_Open;
00377                     else {
00378                         /*I_Disc(p);p.state = Closed;*/
00379                         p->state = I_Open; /* Or maybe I should disconnect it?*/
00380                     }
00381                     break;
00382                 default:
00383                     LOG(L_DBG,"DBG:sm_process(): In state %s invalid event %s\n",
00384                         dp_states[p->state],dp_events[event-101]);
00385                     goto error;
00386             }
00387             break;              
00388         case Closing:
00389             switch(event){
00390                 case I_Rcv_DPA:
00391                     I_Disc(p);
00392                     p->state = Closed;
00393                     break;
00394                 case R_Rcv_DPA:
00395                     R_Disc(p);
00396                     p->state = Closed;
00397                     break;
00398                 case Timeout:
00399                     if (p->I_sock>=0) Error(p,p->I_sock);
00400                     if (p->R_sock>=0) Error(p,p->R_sock);
00401                     p->state = Closed;
00402                     break;
00403                 case I_Peer_Disc:
00404                     I_Disc(p);
00405                     p->state = Closed;
00406                     break;
00407                 case R_Peer_Disc:
00408                     R_Disc(p);
00409                     p->state = Closed;
00410                     break;
00411                 default:
00412                     LOG(L_DBG,"DBG:sm_process(): In state %s invalid event %s\n",
00413                         dp_states[p->state],dp_events[event-101]);
00414                     goto error;
00415             }
00416             break;              
00417     }
00418     if (!peer_locked) lock_release(p->lock);
00419     
00420     if (msg_received)
00421         Rcv_Process(p,msg);
00422     
00423     return 1;   
00424 error:
00425     if (!peer_locked) lock_release(p->lock);
00426     return 0;   
00427 }

peer_state_t I_Snd_Conn_Req ( peer p  ) 

Initiator - Send Connection Request.

Tries to connect to the remote peer's socket. If the connection is refused, the new state is I_Rcv_Conn_NAck, else I_Rcv_Conn_Ack.

Note:
Must be called with a lock on the peer.
Parameters:
p - peer to send to
Returns:
the new state for the peer

Definition at line 437 of file peerstatemachine.c.

References _peer_t::fqdn, I_Rcv_Conn_Ack, I_Rcv_Conn_NAck, _peer_t::I_sock, and peer_connect().

Referenced by sm_process().

00438 {
00439     LOG(L_INFO,"DBG:I_Snd_Conn_Req(): Peer %.*s \n",
00440         p->fqdn.len,p->fqdn.s);
00441 
00442     if (p->I_sock>0) close(p->I_sock);
00443     p->I_sock = -1;
00444     p->I_sock = peer_connect(p);
00445     if (p->I_sock<0){
00446         return I_Rcv_Conn_NAck;
00447     }
00448     
00449     return I_Rcv_Conn_Ack;
00450 }

void Cleanup ( peer p,
int  sock 
)

Cleans a socket by closing it and removing the reference.

Note:
Must be called with a lock on the peer.
Parameters:
p - the peer
sock - socket to close

Definition at line 458 of file peerstatemachine.c.

References _peer_t::I_sock, and _peer_t::R_sock.

Referenced by Error(), and sm_process().

00459 {
00460     if (sock<0) return;
00461     close(sock);
00462     if (p->I_sock == sock) p->I_sock = -1;
00463     if (p->R_sock == sock) p->R_sock = -1;
00464 }

void Error ( peer p,
int  sock 
)

Error action for a peer, triggers a Cleanup action.

Note:
Must be called with a lock on the peer.
Parameters:
p - the peer
sock - socket to close

Definition at line 472 of file peerstatemachine.c.

References Cleanup().

Referenced by sm_process().

00473 {
00474     Cleanup(p,sock);
00475 }

void I_Snd_CER ( peer p  ) 

Send a Capability Exchange Request.

Note:
Must be called with a lock on the peer.
Parameters:
p - the peer to send to

Definition at line 526 of file peerstatemachine.c.

References AAA_AVP_FLAG_MANDATORY, AAACreateAndAddAVPToMessage, AAANewMessage(), AVP_Host_IP_Address, AVP_Product_Name, AVP_Vendor_Id, Code_CE, config, _message_t::endtoendId, errno, _message_t::hopbyhopId, _peer_t::I_sock, next_endtoend(), next_hopbyhop(), peer_send_msg(), dp_config::product_name, set_2bytes, set_4bytes, Snd_CE_add_applications(), and dp_config::vendor_id.

Referenced by sm_process().

00527 {
00528     AAAMessage *cer=0;
00529 //  AAA_AVP *avp;
00530     unsigned long ip;
00531     struct sockaddr_in6 addr;
00532     socklen_t addrlen;
00533     char x[18];
00534     
00535     cer = AAANewMessage(Code_CE,0,0,0);
00536     if (!cer) return;
00537     cer->hopbyhopId = next_hopbyhop();
00538     cer->endtoendId = next_endtoend();
00539     addrlen = sizeof(struct sockaddr_in6);
00540     if (getsockname(p->I_sock,(struct sockaddr*) &addr, &addrlen) == -1) { 
00541         LOG(L_ERR,"ERROR:I_Snd_CER(): Error on finding local host address > %s\n",strerror(errno));
00542     }else{
00543         switch(addr.sin6_family){
00544             case AF_INET:
00545                 set_2bytes(x,1);
00546                 ip = htonl(((struct sockaddr_in*)&addr)->sin_addr.s_addr);
00547                 set_4bytes(x+2,ip);
00548                 AAACreateAndAddAVPToMessage(cer,AVP_Host_IP_Address,AAA_AVP_FLAG_MANDATORY,0,x,6);
00549                 break;
00550             case AF_INET6:
00551                 set_2bytes(x,2);
00552                 memcpy(x+2,addr.sin6_addr.s6_addr,16);
00553                 AAACreateAndAddAVPToMessage(cer,AVP_Host_IP_Address,AAA_AVP_FLAG_MANDATORY,0,x,18);
00554                 break;
00555             default:
00556                 LOG(L_ERR,"ERROR:I_Snd_CER(): unknown address type with family %d\n",addr.sin6_family);
00557         }
00558     }
00559 
00560     set_4bytes(x,config->vendor_id);
00561     AAACreateAndAddAVPToMessage(cer,AVP_Vendor_Id,AAA_AVP_FLAG_MANDATORY,0,x,4);
00562             
00563     AAACreateAndAddAVPToMessage(cer,AVP_Product_Name,AAA_AVP_FLAG_MANDATORY,0,config->product_name.s,config->product_name.len);
00564 
00565     Snd_CE_add_applications(cer,p);
00566 //  peer_send(p,p->I_sock,cer,1);
00567     peer_send_msg(p,cer);
00568 }

int Process_CEA ( peer p,
AAAMessage cea 
)

Process a Capability Exchange Answer.

Note:
Must be called with a lock on the peer.
Parameters:
p - the peer that the CEA was received from
cea - the CEA message
Returns:
the result-code from CEA or AAA_UNABLE_TO_COMPLY if no result-code found

Definition at line 653 of file peerstatemachine.c.

References AAA_UNABLE_TO_COMPLY, AAAFindMatchingAVP(), AAAFreeMessage(), AVP_Result_Code, _message_t::avpList, avp::data, get_4bytes, _avp_list_t::head, and save_peer_applications().

Referenced by sm_process().

00654 {
00655     AAA_AVP *avp;
00656     avp = AAAFindMatchingAVP(cea,cea->avpList.head,AVP_Result_Code,0,0);
00657     save_peer_applications(p,cea);
00658     AAAFreeMessage(&cea);
00659     if (!avp) return AAA_UNABLE_TO_COMPLY;
00660     else return get_4bytes(avp->data.s);
00661 }   

void I_Disc ( peer p  ) 

Initiator - disconnect peer.

Note:
Must be called with a lock on the peer.
Parameters:
p - the peer to disconnect

Definition at line 668 of file peerstatemachine.c.

References _peer_t::I_sock.

Referenced by sm_process().

00669 {
00670     if (p->I_sock>=0){
00671         close(p->I_sock);
00672         p->I_sock = -1;
00673     }
00674 }

void R_Disc ( peer p  ) 

Receiver - disconnect peer.

Note:
Must be called with a lock on the peer.
Parameters:
p - the peer to disconnect

Definition at line 681 of file peerstatemachine.c.

References _peer_t::R_sock.

Referenced by sm_process().

00682 {
00683     if (p->R_sock>=0){
00684         close(p->R_sock);
00685         p->R_sock = -1;
00686     }
00687 }

int Process_DWR ( peer p,
AAAMessage dwr 
)

Process a Diameter Watch-dog Request.

The last activity timer is updated in the sm_process(), on any message received.

Note:
Must be called with a lock on the peer.
Parameters:
p - the peer that the DWR was received from
dwr - the DWR message
Returns:
AAA_SUCCESS

Definition at line 697 of file peerstatemachine.c.

References AAA_SUCCESS.

Referenced by sm_process().

00698 {
00699     return AAA_SUCCESS;
00700 }

void Process_DWA ( peer p,
AAAMessage dwa 
)

Process a Diameter Watch-dog Answer.

The flag for waiting a DWA is reseted.

Note:
Must be called with a lock on the peer.
Parameters:
p - the peer that the DWR was received from
dwa - the DWA message

Definition at line 709 of file peerstatemachine.c.

References AAAFreeMessage(), and _peer_t::waitingDWA.

Referenced by sm_process().

00710 {
00711     p->waitingDWA = 0;
00712     AAAFreeMessage(&dwa);
00713 }

void Snd_DWR ( peer p  ) 

Sends a Diameter Watch-dog Request.

The flag for waiting a DWA is set.

Note:
Must be called with a lock on the peer.
Parameters:
p - the peer that the DWR was received from

Definition at line 721 of file peerstatemachine.c.

References AAANewMessage(), Code_DW, _message_t::endtoendId, _message_t::hopbyhopId, I_Open, next_endtoend(), next_hopbyhop(), peer_send_msg(), and _peer_t::state.

Referenced by peer_timer().

00722 {
00723     AAAMessage *dwr=0;
00724     
00725     dwr = AAANewMessage(Code_DW,0,0,0);
00726     if (!dwr) return;   
00727     dwr->hopbyhopId = next_hopbyhop();
00728     dwr->endtoendId = next_endtoend();
00729     if (p->state==I_Open)
00730         peer_send_msg(p,dwr);   
00731     else
00732         peer_send_msg(p,dwr);   
00733 }

void Snd_DWA ( peer p,
AAAMessage dwr,
int  result_code,
int  sock 
)

Sends a Diameter Watch-dog Answer.

Note:
Must be called with a lock on the peer.
Parameters:
p - the peer that the DWR was received from
dwr - the DWR message
result_code - the Result-Code to attach to DWA
sock - socket to send on

Definition at line 743 of file peerstatemachine.c.

References AAA_AVP_FLAG_MANDATORY, AAACreateAndAddAVPToMessage, AAAFreeMessage(), AAANewMessage(), AVP_Result_Code, Code_DW, peer_send_msg(), and set_4bytes.

Referenced by sm_process().

00744 {
00745     AAAMessage *dwa;
00746     char x[4];  
00747 
00748     dwa = AAANewMessage(Code_DW,0,0,dwr);
00749     if (!dwa) goto done;    
00750 
00751     set_4bytes(x,result_code);
00752     AAACreateAndAddAVPToMessage(dwa,AVP_Result_Code,AAA_AVP_FLAG_MANDATORY,0,x,4);
00753     
00754     peer_send_msg(p,dwa);
00755 done:   
00756     AAAFreeMessage(&dwr);
00757 }

void Snd_DPR ( peer p  ) 

Sends a Disconnect Peer Request.

Note:
Must be called with a lock on the peer.
Parameters:
p - the peer to send to

Definition at line 764 of file peerstatemachine.c.

References AAA_AVP_FLAG_MANDATORY, AAACreateAndAddAVPToMessage, AAANewMessage(), AVP_Disconnect_Cause, Code_DP, _message_t::endtoendId, _message_t::hopbyhopId, I_Open, next_endtoend(), next_hopbyhop(), peer_send_msg(), set_4bytes, and _peer_t::state.

Referenced by sm_process().

00765 {
00766     AAAMessage *dpr=0;
00767     char x[4];
00768     
00769     dpr = AAANewMessage(Code_DP,0,0,0); 
00770     if (!dpr) return;
00771     dpr->hopbyhopId = next_hopbyhop();
00772     dpr->endtoendId = next_endtoend();
00773 
00774     set_4bytes(x,0/*busy*/);
00775     AAACreateAndAddAVPToMessage(