static void test_rtr_send_reset_query(void **state) { struct rtr_socket socket; UNUSED(state); socket.connection_state_fp = NULL; will_return(__wrap_tr_send_all, 0); assert_int_equal(rtr_send_reset_query(&socket), RTR_ERROR); will_return(__wrap_tr_send_all, 10); assert_int_equal(rtr_send_reset_query(&socket), RTR_SUCCESS); }
void rtr_fsm_start(struct rtr_socket *rtr_socket) { rtr_socket->state = RTR_CONNECTING; install_sig_handler(); while(1) { if(rtr_socket->state == RTR_CONNECTING) { RTR_DBG1("State: RTR_CONNECTING"); //old pfx_record could exists in the pfx_table, check if they are too old and must be removed rtr_purge_outdated_records(rtr_socket); if(tr_open(rtr_socket->tr_socket) == TR_ERROR) { rtr_change_socket_state(rtr_socket, RTR_ERROR_TRANSPORT); } else if(rtr_socket->request_session_id) { //change to state RESET, if socket dont has a session_id rtr_change_socket_state(rtr_socket, RTR_RESET); } else { //if we already have a session_id, send a serial query and start to sync if(rtr_send_serial_query(rtr_socket) == RTR_SUCCESS) rtr_change_socket_state(rtr_socket, RTR_SYNC); else rtr_change_socket_state(rtr_socket, RTR_ERROR_FATAL); } } else if(rtr_socket->state == RTR_RESET) { RTR_DBG1("State: RTR_RESET"); if (rtr_send_reset_query(rtr_socket) == 0) { RTR_DBG1("rtr_start: reset pdu sent"); rtr_change_socket_state(rtr_socket, RTR_SYNC); //send reset query after connection established } } else if(rtr_socket->state == RTR_SYNC) { RTR_DBG1("State: RTR_SYNC"); if(rtr_sync(rtr_socket) == 0) rtr_change_socket_state(rtr_socket, RTR_ESTABLISHED); //send reset query after connection established } else if(rtr_socket->state == RTR_ESTABLISHED) { RTR_DBG1("State: RTR_ESTABLISHED"); if(rtr_wait_for_sync(rtr_socket) == RTR_SUCCESS) { //blocks till cache_timeout is expired or PDU was received //serial query senden if(rtr_send_serial_query(rtr_socket) == RTR_SUCCESS) rtr_change_socket_state(rtr_socket, RTR_SYNC); } } else if(rtr_socket->state == RTR_ERROR_NO_DATA_AVAIL) { RTR_DBG1("State: RTR_ERROR_NO_DATA_AVAIL"); rtr_socket->request_session_id = true; rtr_socket->serial_number = 0; rtr_change_socket_state(rtr_socket, RTR_RESET); sleep(ERR_TIMEOUT); rtr_purge_outdated_records(rtr_socket); } else if(rtr_socket->state == RTR_ERROR_NO_INCR_UPDATE_AVAIL) { RTR_DBG1("State: RTR_ERROR_NO_INCR_UPDATE_AVAIL"); rtr_socket->request_session_id = true; rtr_socket->serial_number = 0; rtr_change_socket_state(rtr_socket, RTR_RESET); rtr_purge_outdated_records(rtr_socket); } else if(rtr_socket->state == RTR_ERROR_TRANSPORT) { RTR_DBG1("State: RTR_ERROR_TRANSPORT"); tr_close(rtr_socket->tr_socket); rtr_change_socket_state(rtr_socket, RTR_CONNECTING); sleep(ERR_TIMEOUT); } else if(rtr_socket->state == RTR_ERROR_FATAL) { RTR_DBG1("State: RTR_ERROR_FATAL"); tr_close(rtr_socket->tr_socket); rtr_change_socket_state(rtr_socket, RTR_CONNECTING); sleep(ERR_TIMEOUT); } else if(rtr_socket->state == RTR_SHUTDOWN) { RTR_DBG1("State: RTR_SHUTDOWN"); tr_close(rtr_socket->tr_socket); rtr_socket->request_session_id = true; rtr_socket->serial_number = 0; rtr_socket->last_update = 0; pfx_table_src_remove(rtr_socket->pfx_table, rtr_socket); pthread_exit(NULL); } } }
/* WARNING: This Function has cancelable sections*/ void *rtr_fsm_start(struct rtr_socket *rtr_socket) { if (rtr_socket->state == RTR_SHUTDOWN) return NULL; // We don't care about the old state, but POSIX demands a non null value for setcancelstate int oldcancelstate; pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate); rtr_socket->state = RTR_CONNECTING; while(1) { if(rtr_socket->state == RTR_CONNECTING) { RTR_DBG1("State: RTR_CONNECTING"); rtr_socket->has_received_pdus = false; //old pfx_record could exists in the pfx_table, check if they are too old and must be removed //old key_entry could exists in the spki_table, check if they are too old and must be removed rtr_purge_outdated_records(rtr_socket); if(tr_open(rtr_socket->tr_socket) == TR_ERROR) { rtr_change_socket_state(rtr_socket, RTR_ERROR_TRANSPORT); } else if(rtr_socket->request_session_id) { //change to state RESET, if socket dont has a session_id rtr_change_socket_state(rtr_socket, RTR_RESET); } else { //if we already have a session_id, send a serial query and start to sync if(rtr_send_serial_query(rtr_socket) == RTR_SUCCESS) rtr_change_socket_state(rtr_socket, RTR_SYNC); else rtr_change_socket_state(rtr_socket, RTR_ERROR_FATAL); } } else if(rtr_socket->state == RTR_RESET) { RTR_DBG1("State: RTR_RESET"); if (rtr_send_reset_query(rtr_socket) == RTR_SUCCESS) { RTR_DBG1("rtr_start: reset pdu sent"); rtr_change_socket_state(rtr_socket, RTR_SYNC); //start to sync after connection is established } } else if(rtr_socket->state == RTR_SYNC) { RTR_DBG1("State: RTR_SYNC"); if(rtr_sync(rtr_socket) == RTR_SUCCESS) rtr_change_socket_state(rtr_socket, RTR_ESTABLISHED); //wait for next sync after first successful sync } else if(rtr_socket->state == RTR_ESTABLISHED) { RTR_DBG1("State: RTR_ESTABLISHED"); // Allow thread cancellation for recv code path only. // This should be enough since we spend most of the time blocking on recv pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldcancelstate); int ret = rtr_wait_for_sync(rtr_socket); //blocks till expire_interval is expired or PDU was received pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate); if(ret == RTR_SUCCESS) { //send serial query if(rtr_send_serial_query(rtr_socket) == RTR_SUCCESS) rtr_change_socket_state(rtr_socket, RTR_SYNC); } } else if(rtr_socket->state == RTR_FAST_RECONNECT){ RTR_DBG1("State: RTR_FAST_RECONNECT"); tr_close(rtr_socket->tr_socket); rtr_change_socket_state(rtr_socket, RTR_CONNECTING); } else if(rtr_socket->state == RTR_ERROR_NO_DATA_AVAIL) { RTR_DBG1("State: RTR_ERROR_NO_DATA_AVAIL"); rtr_socket->request_session_id = true; rtr_socket->serial_number = 0; rtr_change_socket_state(rtr_socket, RTR_RESET); sleep(rtr_socket->retry_interval); rtr_purge_outdated_records(rtr_socket); } else if(rtr_socket->state == RTR_ERROR_NO_INCR_UPDATE_AVAIL) { RTR_DBG1("State: RTR_ERROR_NO_INCR_UPDATE_AVAIL"); rtr_socket->request_session_id = true; rtr_socket->serial_number = 0; rtr_change_socket_state(rtr_socket, RTR_RESET); rtr_purge_outdated_records(rtr_socket); } else if(rtr_socket->state == RTR_ERROR_TRANSPORT) { RTR_DBG1("State: RTR_ERROR_TRANSPORT"); tr_close(rtr_socket->tr_socket); rtr_change_socket_state(rtr_socket, RTR_CONNECTING); RTR_DBG("Waiting %u", rtr_socket->retry_interval); sleep(rtr_socket->retry_interval); } else if(rtr_socket->state == RTR_ERROR_FATAL) { RTR_DBG1("State: RTR_ERROR_FATAL"); tr_close(rtr_socket->tr_socket); rtr_change_socket_state(rtr_socket, RTR_CONNECTING); RTR_DBG("Waiting %u", rtr_socket->retry_interval); sleep(rtr_socket->retry_interval); } else if(rtr_socket->state == RTR_SHUTDOWN) { RTR_DBG1("State: RTR_SHUTDOWN"); pthread_exit(NULL); } } }