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. | |
| 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.
| 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 |
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.
| p | - peer to send to |
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.
| 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.
| 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.
| 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.
| p | - the peer that the CEA was received from | |
| cea | - the CEA message |
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.
| p | - the peer to disconnect |
Definition at line 668 of file peerstatemachine.c.
References _peer_t::I_sock.
Referenced by sm_process().
| void R_Disc | ( | peer * | p | ) |
Receiver - disconnect peer.
| p | - the peer to disconnect |
Definition at line 681 of file peerstatemachine.c.
References _peer_t::R_sock.
Referenced by sm_process().
| 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.
| p | - the peer that the DWR was received from | |
| dwr | - the DWR message |
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.
| 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.
| 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.
| 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.
| 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(