Commit 3bb73e9a authored by Sebastien Decugis's avatar Sebastien Decugis
Browse files

Some progress on the PSM

parent 0199c3b4
......@@ -261,11 +261,13 @@ int fd_p_sr_fetch(struct sr_list * srlist, uint32_t hbh, struct msg **req);
void fd_p_sr_failover(struct sr_list * srlist);
/* Local Link messages (CER/CEA, DWR/DWA, DPR/DPA) */
int fd_p_ce_handle(struct msg ** msg, struct fd_peer * peer);
int fd_p_ce_msgrcv(struct msg ** msg, int req, struct fd_peer * peer);
int fd_p_ce_handle_newCER(struct msg ** msg, struct fd_peer * peer, struct cnxctx ** cnx, int valid);
int fd_p_dw_handle(struct msg ** msg, struct fd_peer * peer);
int fd_p_ce_handle_newcnx(struct fd_peer * peer, struct cnxctx * initiator);
int fd_p_ce_winelection(struct fd_peer * peer);
int fd_p_dw_handle(struct msg ** msg, int req, struct fd_peer * peer);
int fd_p_dw_timeout(struct fd_peer * peer);
int fd_p_dp_handle(struct msg ** msg, struct fd_peer * peer);
int fd_p_dp_handle(struct msg ** msg, int req, struct fd_peer * peer);
int fd_p_dp_initiate(struct fd_peer * peer);
/* Active peers -- routing process should only ever take the read lock, the write lock is managed by PSMs */
......
......@@ -35,24 +35,86 @@
#include "fD.h"
/* This file contains code to handle Capabilities Exchange messages (CER and CEA) */
/* This file contains code to handle Capabilities Exchange messages (CER and CEA) and election process */
int fd_p_ce_handle(struct msg ** msg, struct fd_peer * peer)
/* Save a connection as peer's principal */
static int set_peer_cnx(struct fd_peer * peer, struct cnxctx **cnx)
{
TODO("Handle depending on CER or CEA and peer state");
TODO("Save *cnx into peer->p_cnxctx");
TODO("Set fifo of *cnx to peer->p_events");
TODO("If connection is already TLS, read the credentials");
TODO("Read the remote endpoints");
return ENOTSUP;
}
static int process_valid_CEA(struct fd_peer * peer, struct msg ** cea)
{
/* Save info from the CEA into the peer */
/* Handshake if needed */
/* Save credentials if needed */
TODO("...");
return ENOTSUP;
}
/* We have received a Capabilities Exchange message on the peer connection */
int fd_p_ce_msgrcv(struct msg ** msg, int req, struct fd_peer * peer)
{
TRACE_ENTRY("%p %p", msg, peer);
CHECK_PARAMS( msg && *msg && CHECK_PEER(peer) );
/* The only valid situation where we are called is in WAITCEA and we receive a CEA */
/* Note : to implement Capabilities Update, we would need to change here */
/* If it is a CER, just reply an error */
if (req) {
/* Create the error message */
CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, MSGFL_ANSW_ERROR ) );
/* Set the error code */
CHECK_FCT( fd_msg_rescode_set(*msg, "DIAMETER_COMMAND_UNSUPPORTED", "No CER in current state", NULL, 1 ) );
/* msg now contains an answer message to send back */
CHECK_FCT_DO( fd_out_send(msg, peer->p_cnxctx, peer), /* In case of error the message has already been dumped */ );
}
/* If the state is not WAITCEA, just discard the message */
if ((req) || (peer->p_hdr.info.runtime.pir_state != STATE_WAITCEA)) {
if (*msg) {
fd_log_debug("Received CER/CEA message while in state '%s', discarded.\n", STATE_STR(peer->p_hdr.info.runtime.pir_state));
fd_msg_dump_walk(NONE, *msg);
CHECK_FCT_DO( fd_msg_free(*msg), /* continue */);
*msg = NULL;
}
return 0;
}
/* Ok, now we can accept the CEA */
TODO("process_valid_CEA");
return ENOTSUP;
}
/* We have received a CER on a new connection for this peer */
int fd_p_ce_handle_newCER(struct msg ** msg, struct fd_peer * peer, struct cnxctx ** cnx, int valid)
{
switch (peer->p_hdr.info.runtime.pir_state) {
case STATE_CLOSED:
TODO("Handle the CER, validate the peer if needed (and set expiry), set the alt_fifo in the connection, reply a CEA, eventually handshake, move to OPEN or REOPEN state");
TODO("Handle the CER, validate the peer if needed (and set expiry), set the alt_fifo in the connection, reply a CEA, eventually handshake (OPEN_HANDSHAKE), move to OPEN or REOPEN state");
/* In case of error : DIAMETER_UNKNOWN_PEER */
break;
case STATE_WAITCNXACK:
TODO("Save the parameters in the peer, move to STATE_WAITCNXACK_ELEC");
break;
case STATE_WAITCEA:
TODO("Election");
break;
......@@ -67,3 +129,38 @@ int fd_p_ce_handle_newCER(struct msg ** msg, struct fd_peer * peer, struct cnxct
return ENOTSUP;
}
static int do_election(struct fd_peer * peer)
{
TODO("Compare diameter Ids");
/* ELECTION_LOST error code ?*/
TODO("If we lost the election, we close the received connection and go to WAITCEA");
TODO("If we won the election, we close initiator cnx, then call fd_p_ce_winelection");
}
/* We have established a new connection to the remote peer, send CER and eventually do election */
int fd_p_ce_handle_newcnx(struct fd_peer * peer, struct cnxctx * initiator)
{
/* if not election */
TODO("Set the connection as peer's (setaltfifo)");
TODO("Send CER");
TODO("Move to WAITCEA");
TODO("Change timer to CEA_TIMEOUT");
/* if election */
TODO("Send CER on cnx");
TODO("Do the election");
return ENOTSUP;
}
/* Handle the receiver side after winning an election (or timeout on initiator side) */
int fd_p_ce_winelection(struct fd_peer * peer)
{
TODO("Move the receiver side connection to peer principal, set the altfifo");
TODO("Then handle the received CER");
}
......@@ -38,7 +38,7 @@
/* This file contains code to handle Disconnect Peer messages (DPR and DPA) */
/* Handle a received message */
int fd_p_dp_handle(struct msg ** msg, struct fd_peer * peer)
int fd_p_dp_handle(struct msg ** msg, int req, struct fd_peer * peer)
{
TODO("Handle depending on DPR or DPA and peer state");
......
......@@ -39,7 +39,7 @@
/* Handle an incoming message */
int fd_p_dw_handle(struct msg ** msg, struct fd_peer * peer)
int fd_p_dw_handle(struct msg ** msg, int req, struct fd_peer * peer)
{
TODO("Handle depending on DWR or DWA and peer state");
......
......@@ -247,7 +247,6 @@ void fd_psm_cleanup(struct fd_peer * peer, int terminate)
/* Move to CLOSED state: failover messages, stop OUT thread, unlink peer from active list */
CHECK_FCT_DO( fd_psm_change_state(peer, STATE_CLOSED), /* continue */ );
fd_p_cnx_abort(peer, terminate);
if (peer->p_cnxctx) {
......@@ -467,15 +466,15 @@ psm_loop:
/* Handle the LL message and update the expiry timer appropriately */
switch (hdr->msg_code) {
case CC_CAPABILITIES_EXCHANGE:
CHECK_FCT_DO( fd_p_ce_handle(&msg, peer), goto psm_end );
CHECK_FCT_DO( fd_p_ce_msgrcv(&msg, (hdr->msg_flags & CMD_FLAG_REQUEST), peer), goto psm_end );
break;
case CC_DISCONNECT_PEER:
CHECK_FCT_DO( fd_p_dp_handle(&msg, peer), goto psm_end );
CHECK_FCT_DO( fd_p_dp_handle(&msg, (hdr->msg_flags & CMD_FLAG_REQUEST), peer), goto psm_end );
break;
case CC_DEVICE_WATCHDOG:
CHECK_FCT_DO( fd_p_dw_handle(&msg, peer), goto psm_end );
CHECK_FCT_DO( fd_p_dw_handle(&msg, (hdr->msg_flags & CMD_FLAG_REQUEST), peer), goto psm_end );
break;
default:
......@@ -589,6 +588,29 @@ psm_loop:
goto psm_loop;
}
/* A new connection has been established with the remote peer */
if (event == FDEVP_CNX_ESTABLISHED) {
struct cnxctx * cnx = ev_data;
/* Release the resources of the thread */
CHECK_POSIX_DO( pthread_join( peer->p_ini_thr, NULL), /* ignore, it is not a big deal */);
peer->p_ini_thr = (pthread_t)NULL;
switch (peer->p_hdr.info.runtime.pir_state) {
case STATE_WAITCNXACK_ELEC:
case STATE_WAITCNXACK:
fd_p_ce_handle_newcnx(peer, cnx);
break;
default:
/* Just abort the attempt and continue */
TRACE_DEBUG(FULL, "Connection attempt successful but current state is %s, closing...", STATE_STR(peer->p_hdr.info.runtime.pir_state));
fd_cnx_destroy(cnx);
}
goto psm_loop;
}
/* The timeout for the current state has been reached */
if (event == FDEVP_PSM_TIMEOUT) {
switch (peer->p_hdr.info.runtime.pir_state) {
......@@ -613,7 +635,12 @@ psm_loop:
break;
case STATE_WAITCNXACK_ELEC:
TODO("Abort initiating side, handle the receiver side");
/* Abort the initiating side */
fd_p_cnx_abort(peer, 0);
/* Handle receiver side */
CHECK_FCT_DO( fd_p_ce_winelection(peer), goto psm_end );
break;
}
}
......@@ -621,7 +648,7 @@ psm_loop:
/* Default action : the handling has not yet been implemented. [for debug only] */
TODO("Missing handler in PSM : '%s'\t<-- '%s'", STATE_STR(peer->p_hdr.info.runtime.pir_state), fd_pev_str(event));
if (event == FDEVP_PSM_TIMEOUT) {
/* We have not handled timeout in this state, let's postpone next alert */
/* We have not handled timeout in this state, let's postpone next alert to avoid flood */
fd_psm_next_timeout(peer, 0, 60);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment