1 /*
2  * This file is part of RTRlib.
3  *
4  * This file is subject to the terms and conditions of the MIT license.
5  * See the file LICENSE in the top level directory for more details.
6  *
7  * Website: http://rtrlib.realmv6.org/
8  */
9 
10 #include <assert.h>
11 #include <pthread.h>
12 #include <signal.h>
13 #include <unistd.h>
14 
15 #include "rtrlib/lib/log_private.h"
16 #include "rtrlib/lib/utils_private.h"
17 #include "rtrlib/pfx/pfx_private.h"
18 #include "rtrlib/rtr/packets_private.h"
19 #include "rtrlib/rtr/rtr_private.h"
20 #include "rtrlib/rtrlib_export_private.h"
21 #include "rtrlib/spki/hashtable/ht-spkitable_private.h"
22 #include "rtrlib/transport/transport_private.h"
23 
24 static void rtr_purge_outdated_records(struct rtr_socket *rtr_socket);
25 static void rtr_fsm_start(struct rtr_socket *rtr_socket);
26 static void sighandler(int b);
27 static int install_sig_handler();
28 
29 static const char *socket_str_states[] = {
30     [RTR_CONNECTING] = "RTR_CONNECTING",
31     [RTR_ESTABLISHED] = "RTR_ESTABLISHED",
32     [RTR_RESET] = "RTR_RESET",
33     [RTR_SYNC] = "RTR_SYNC",
34     [RTR_FAST_RECONNECT] = "RTR_FAST_RECONNECT",
35     [RTR_ERROR_NO_DATA_AVAIL] = "RTR_ERROR_NO_DATA_AVAIL",
36     [RTR_ERROR_NO_INCR_UPDATE_AVAIL] = "RTR_ERROR_NO_INCR_UPDATE_AVAIL",
37     [RTR_ERROR_FATAL] = "RTR_ERROR_FATAL",
38     [RTR_ERROR_TRANSPORT] = "RTR_ERROR_TRANSPORT",
39     [RTR_SHUTDOWN] = "RTR_SHUTDOWN"
40 };
41 
sighandler(int b)42 void sighandler(int b __attribute__((unused)) )
43 {
44     return;
45 }
46 
install_sig_handler()47 static int install_sig_handler()
48 {
49     struct sigaction sa;
50     sa.sa_handler = &sighandler;
51     sigset_t mask;
52     sigemptyset(&mask);
53     sa.sa_mask = mask;
54     sa.sa_flags = 0;
55 
56     return sigaction(SIGUSR1, &sa, NULL);
57 }
58 
rtr_init(struct rtr_socket * rtr_socket,struct tr_socket * tr,struct pfx_table * pfx_table,struct spki_table * spki_table,const unsigned int refresh_interval,const unsigned int expire_interval,const unsigned int retry_interval,enum rtr_interval_mode iv_mode,rtr_connection_state_fp fp,void * fp_param_config,void * fp_param_group)59 int rtr_init(struct rtr_socket *rtr_socket,
60               struct tr_socket *tr,
61               struct pfx_table *pfx_table,
62               struct spki_table *spki_table,
63               const unsigned int refresh_interval,
64               const unsigned int expire_interval,
65               const unsigned int retry_interval,
66 	      enum rtr_interval_mode iv_mode,
67               rtr_connection_state_fp fp, void *fp_param_config,
68 	      void *fp_param_group)
69 {
70     if(tr != NULL)
71         rtr_socket->tr_socket = tr;
72 
73     // Check if one of the intervals is not in range of the predefined values.
74     if(rtr_check_interval_range(refresh_interval, RTR_REFRESH_MIN, RTR_REFRESH_MAX) != RTR_INSIDE_INTERVAL_RANGE ||
75        rtr_check_interval_range(expire_interval, RTR_EXPIRATION_MIN, RTR_EXPIRATION_MAX) != RTR_INSIDE_INTERVAL_RANGE ||
76        rtr_check_interval_range(retry_interval, RTR_RETRY_MIN, RTR_RETRY_MAX) != RTR_INSIDE_INTERVAL_RANGE) {
77         RTR_DBG("Interval value not in range.");
78         return RTR_INVALID_PARAM;
79     }
80     rtr_socket->refresh_interval = refresh_interval;
81     rtr_socket->expire_interval = expire_interval;
82     rtr_socket->retry_interval = retry_interval;
83     rtr_socket->iv_mode = iv_mode;
84 
85     rtr_socket->state = RTR_CLOSED;
86     rtr_socket->request_session_id = true;
87     rtr_socket->serial_number = 0;
88     rtr_socket->last_update = 0;
89     rtr_socket->pfx_table = pfx_table;
90     rtr_socket->spki_table = spki_table;
91     rtr_socket->connection_state_fp = fp;
92     rtr_socket->connection_state_fp_param_config = fp_param_config;
93     rtr_socket->connection_state_fp_param_group = fp_param_group;
94     rtr_socket->thread_id = 0;
95     rtr_socket->version = RTR_PROTOCOL_MAX_SUPPORTED_VERSION;
96     rtr_socket->has_received_pdus = false;
97     rtr_socket->is_resetting = false;
98     return RTR_SUCCESS;
99 }
100 
rtr_start(struct rtr_socket * rtr_socket)101 int rtr_start(struct rtr_socket *rtr_socket)
102 {
103     if(rtr_socket->thread_id)
104         return RTR_ERROR;
105 
106     int rtval = pthread_create(&(rtr_socket->thread_id), NULL, (void* ( *)(void *)) &rtr_fsm_start, rtr_socket);
107     if(rtval == 0)
108         return RTR_SUCCESS;
109     return RTR_ERROR;
110 }
111 
rtr_purge_outdated_records(struct rtr_socket * rtr_socket)112 void rtr_purge_outdated_records(struct rtr_socket *rtr_socket)
113 {
114     if(rtr_socket->last_update == 0)
115         return;
116     time_t cur_time;
117     int rtval = lrtr_get_monotonic_time(&cur_time);
118     if(rtval == -1 || (rtr_socket->last_update + rtr_socket->expire_interval) < cur_time) {
119         if(rtval == -1)
120             RTR_DBG1("get_monotic_time(..) failed");
121         pfx_table_src_remove(rtr_socket->pfx_table, rtr_socket);
122         RTR_DBG1("Removed outdated records from pfx_table");
123         spki_table_src_remove(rtr_socket->spki_table, rtr_socket);
124         RTR_DBG1("Removed outdated router keys from spki_table");
125         rtr_socket->request_session_id = true;
126         rtr_socket->serial_number = 0;
127         rtr_socket->last_update = 0;
128 	rtr_socket->is_resetting = true;
129     }
130 }
131 
rtr_fsm_start(struct rtr_socket * rtr_socket)132 void rtr_fsm_start(struct rtr_socket *rtr_socket)
133 {
134    if (rtr_socket->state == RTR_SHUTDOWN)
135 	return;
136 
137     rtr_socket->state = RTR_CONNECTING;
138     install_sig_handler();
139     while(1) {
140         if(rtr_socket->state == RTR_CONNECTING) {
141             RTR_DBG1("State: RTR_CONNECTING");
142             rtr_socket->has_received_pdus = false;
143 
144             //old pfx_record could exists in the pfx_table, check if they are too old and must be removed
145             //old key_entry could exists in the spki_table, check if they are too old and must be removed
146             rtr_purge_outdated_records(rtr_socket);
147 
148             if(tr_open(rtr_socket->tr_socket) == TR_ERROR) {
149                 rtr_change_socket_state(rtr_socket, RTR_ERROR_TRANSPORT);
150             } else if(rtr_socket->request_session_id) {
151                 //change to state RESET, if socket dont has a session_id
152                 rtr_change_socket_state(rtr_socket, RTR_RESET);
153             } else {
154                 //if we already have a session_id, send a serial query and start to sync
155                 if(rtr_send_serial_query(rtr_socket) == RTR_SUCCESS)
156                     rtr_change_socket_state(rtr_socket, RTR_SYNC);
157                 else
158                     rtr_change_socket_state(rtr_socket, RTR_ERROR_FATAL);
159             }
160 
161         }
162 
163         else if(rtr_socket->state == RTR_RESET) {
164             RTR_DBG1("State: RTR_RESET");
165             if (rtr_send_reset_query(rtr_socket) == RTR_SUCCESS) {
166                 RTR_DBG1("rtr_start: reset pdu sent");
167                 rtr_change_socket_state(rtr_socket, RTR_SYNC); //start to sync after connection is established
168             }
169         }
170 
171         else if(rtr_socket->state == RTR_SYNC) {
172             RTR_DBG1("State: RTR_SYNC");
173             if(rtr_sync(rtr_socket) == RTR_SUCCESS)
174                 rtr_change_socket_state(rtr_socket, RTR_ESTABLISHED); //wait for next sync after first successful sync
175         }
176 
177         else if(rtr_socket->state == RTR_ESTABLISHED) {
178             RTR_DBG1("State: RTR_ESTABLISHED");
179             if(rtr_wait_for_sync(rtr_socket) == RTR_SUCCESS) { //blocks till expire_interval is expired or PDU was received
180                 //send serial query
181                 if(rtr_send_serial_query(rtr_socket) == RTR_SUCCESS)
182                     rtr_change_socket_state(rtr_socket, RTR_SYNC);
183             }
184         }
185 
186         else if(rtr_socket->state == RTR_FAST_RECONNECT){
187             RTR_DBG1("State: RTR_FAST_RECONNECT");
188             tr_close(rtr_socket->tr_socket);
189             rtr_change_socket_state(rtr_socket, RTR_CONNECTING);
190         }
191 
192         else if(rtr_socket->state == RTR_ERROR_NO_DATA_AVAIL) {
193             RTR_DBG1("State: RTR_ERROR_NO_DATA_AVAIL");
194             rtr_socket->request_session_id = true;
195             rtr_socket->serial_number = 0;
196             rtr_change_socket_state(rtr_socket, RTR_RESET);
197             sleep(rtr_socket->retry_interval);
198             rtr_purge_outdated_records(rtr_socket);
199         }
200 
201         else if(rtr_socket->state == RTR_ERROR_NO_INCR_UPDATE_AVAIL) {
202             RTR_DBG1("State: RTR_ERROR_NO_INCR_UPDATE_AVAIL");
203             rtr_socket->request_session_id = true;
204             rtr_socket->serial_number = 0;
205             rtr_change_socket_state(rtr_socket, RTR_RESET);
206             rtr_purge_outdated_records(rtr_socket);
207         }
208 
209         else if(rtr_socket->state == RTR_ERROR_TRANSPORT) {
210             RTR_DBG1("State: RTR_ERROR_TRANSPORT");
211             tr_close(rtr_socket->tr_socket);
212             rtr_change_socket_state(rtr_socket, RTR_CONNECTING);
213             RTR_DBG("Waiting %u", rtr_socket->retry_interval);
214             sleep(rtr_socket->retry_interval);
215         }
216 
217         else if(rtr_socket->state == RTR_ERROR_FATAL) {
218             RTR_DBG1("State: RTR_ERROR_FATAL");
219             tr_close(rtr_socket->tr_socket);
220             rtr_change_socket_state(rtr_socket, RTR_CONNECTING);
221             RTR_DBG("Waiting %u", rtr_socket->retry_interval);
222             sleep(rtr_socket->retry_interval);
223         }
224 
225         else if(rtr_socket->state == RTR_SHUTDOWN) {
226             RTR_DBG1("State: RTR_SHUTDOWN");
227             tr_close(rtr_socket->tr_socket);
228             rtr_socket->request_session_id = true;
229             rtr_socket->serial_number = 0;
230             rtr_socket->last_update = 0;
231             pfx_table_src_remove(rtr_socket->pfx_table, rtr_socket);
232             spki_table_src_remove(rtr_socket->spki_table, rtr_socket);
233             pthread_exit(NULL);
234         }
235     }
236 }
237 
rtr_stop(struct rtr_socket * rtr_socket)238 void rtr_stop(struct rtr_socket *rtr_socket)
239 {
240     RTR_DBG1("rtr_stop()");
241     rtr_change_socket_state(rtr_socket, RTR_SHUTDOWN);
242     if(rtr_socket->thread_id != 0) {
243         RTR_DBG1("pthread_kill()");
244         pthread_kill(rtr_socket->thread_id, SIGUSR1);
245         RTR_DBG1("pthread_join()");
246         pthread_join(rtr_socket->thread_id, NULL);
247         rtr_socket->thread_id = 0;
248     }
249     RTR_DBG1("Socket shut down");
250 }
251 
rtr_state_to_str(enum rtr_socket_state state)252 RTRLIB_EXPORT const char *rtr_state_to_str(enum rtr_socket_state state)
253 {
254     return socket_str_states[state];
255 }
256 
257 /* cppcheck-suppress unusedFunction */
rtr_get_interval_mode(struct rtr_socket * rtr_socket)258 RTRLIB_EXPORT enum rtr_interval_mode rtr_get_interval_mode(struct rtr_socket *rtr_socket)
259 {
260 	return rtr_socket->iv_mode;
261 }
262 
263 /* cppcheck-suppress unusedFunction */
rtr_set_interval_mode(struct rtr_socket * rtr_socket,enum rtr_interval_mode option)264 RTRLIB_EXPORT void rtr_set_interval_mode(struct rtr_socket *rtr_socket, enum rtr_interval_mode option)
265 {
266 	switch (option) {
267 	case RTR_INTERVAL_MODE_IGNORE_ANY:
268 	case RTR_INTERVAL_MODE_ACCEPT_ANY:
269 	case RTR_INTERVAL_MODE_DEFAULT_MIN_MAX:
270 	case RTR_INTERVAL_MODE_IGNORE_ON_FAILURE:
271 		rtr_socket->iv_mode = option;
272 		break;
273 	default:
274 		RTR_DBG1("Invalid interval mode. Mode remains unchanged.");
275 	}
276 }
277 
278