summaryrefslogtreecommitdiff
path: root/proto/rpki/rpki.h
blob: 26fbb46e2ceed40ce1262880c737578747a4923a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/*
 *	BIRD -- The Resource Public Key Infrastructure (RPKI) to Router Protocol
 *
 *	(c) 2015 CZ.NIC
 *	(c) 2015 Pavel Tvrdik <pawel.tvrdik@gmail.com>
 *
 *	Using RTRlib: http://rpki.realmv6.org/
 *
 *	Can be freely distributed and used under the terms of the GNU GPL.
 */

#ifndef _BIRD_RPKI_H_
#define _BIRD_RPKI_H_

#include "nest/bird.h"
#include "nest/rt.h"
#include "nest/protocol.h"
#include "lib/socket.h"
#include "lib/ip.h"

#include "transport.h"
#include "packets.h"

#define RPKI_TCP_PORT		323
#define RPKI_SSH_PORT		22
#define RPKI_RETRY_INTERVAL	600
#define RPKI_REFRESH_INTERVAL	3600
#define RPKI_EXPIRE_INTERVAL	7200

#define RPKI_VERSION_0		0
#define RPKI_VERSION_1		1
#define RPKI_MAX_VERSION 	RPKI_VERSION_1


/*
 * 	RPKI Cache
 */

enum rpki_cache_state {
  RPKI_CS_CONNECTING, 			/* Socket is establishing the transport connection. */
  RPKI_CS_ESTABLISHED,			/* Connection is established, socket is waiting for a Serial Notify or expiration of the refresh_interval timer */
  RPKI_CS_RESET,			/* Resetting RTR connection. */
  RPKI_CS_SYNC_START,			/* Sending a Serial/Reset Query PDU and expecting a Cache Response PDU */
  RPKI_CS_SYNC_RUNNING,			/* Receiving validation records from the RTR server. A state between Cache Response PDU and End of Data PDU */
  RPKI_CS_FAST_RECONNECT,		/* Reconnect without any waiting period */
  RPKI_CS_NO_INCR_UPDATE_AVAIL, 	/* Server is unable to answer the last Serial Query and sent Cache Reset. */
  RPKI_CS_ERROR_NO_DATA_AVAIL,		/* Server is unable to answer either a Serial Query or a Reset Query because it has no useful data available at this time. */
  RPKI_CS_ERROR_FATAL,			/* Fatal protocol error occurred. */
  RPKI_CS_ERROR_TRANSPORT,		/* Error on the transport socket occurred. */
  RPKI_CS_SHUTDOWN,			/* RTR Socket is stopped. */
};

struct rpki_cache {
  pool *pool;				/* Pool containing cache objects */
  struct rpki_proto *p;

  struct rpki_tr_sock *tr_sock;		/* Transport specific socket */
  enum rpki_cache_state state;		/* RPKI_CS_* */
  u32 session_id;
  u8 request_session_id;		/* 1: have to request new session id; 0: we have already received session id */
  u32 serial_num;			/* Serial number denotes the logical version of data from cache server */
  u8 version;				/* Protocol version */
  btime last_update;			/* Last successful synchronization with cache server */
  btime last_rx_prefix;			/* Last received prefix PDU */

  /* Intervals can be changed by cache server on the fly */
  u32 refresh_interval;			/* Actual refresh interval (in seconds) */
  u32 retry_interval;
  u32 expire_interval;
  timer *retry_timer;			/* Retry timer event */
  timer *refresh_timer;			/* Refresh timer event */
  timer *expire_timer;			/* Expire timer event */
};

const char *rpki_get_cache_ident(struct rpki_cache *cache);
const char *rpki_cache_state_to_str(enum rpki_cache_state state);


/*
 * 	Routes handling
 */

void rpki_table_add_roa(struct rpki_cache *cache, struct channel *channel, const net_addr_union *pfxr);
void rpki_table_remove_roa(struct rpki_cache *cache, struct channel *channel, const net_addr_union *pfxr);


/*
 *	RPKI Protocol Logic
 */

void rpki_cache_change_state(struct rpki_cache *cache, const enum rpki_cache_state new_state);


/*
 * 	RPKI Timer Events
 */

const char *rpki_check_refresh_interval(uint seconds);
const char *rpki_check_retry_interval(uint seconds);
const char *rpki_check_expire_interval(uint seconds);


/*
 * 	RPKI Protocol Configuration
 */

struct rpki_proto {
  struct proto p;
  struct rpki_cache *cache;

  struct channel *roa4_channel;
  struct channel *roa6_channel;
  u8 refresh_channels;			/* For non-incremental updates using rt_refresh_begin(), rt_refresh_end() */
};

struct rpki_config {
  struct proto_config c;
  const char *hostname;			/* Full domain name or stringified IP address of cache server */
  ip_addr ip;				/* IP address of cache server or IPA_NONE */
  u16 port;				/* Port number of cache server */
  struct rpki_tr_config tr_config;	/* Specific transport configuration structure */
  u32 refresh_interval;			/* Time interval (in seconds) for periodical downloading data from cache server */
  u32 retry_interval;			/* Time interval (in seconds) for an unreachable server */
  u32 expire_interval;			/* Maximal lifetime (in seconds) of ROAs without any successful refreshment */
  u8 keep_refresh_interval:1;		/* Do not overwrite refresh interval by cache server update */
  u8 keep_retry_interval:1;		/* Do not overwrite retry interval by cache server update */
  u8 keep_expire_interval:1;		/* Do not overwrite expire interval by cache server update */
  u8 ignore_max_length:1;		/* Ignore received max length and use MAX_PREFIX_LENGTH instead */
};

void rpki_check_config(struct rpki_config *cf);


/*
 *	Logger
 */

#define RPKI_LOG(log_level, rpki, msg, args...) 			\
    do { 								\
      log(log_level "%s: " msg, (rpki)->p.name , ## args); 		\
    } while(0)

#if defined(LOCAL_DEBUG) || defined(GLOBAL_DEBUG)
#define CACHE_DBG(cache,msg,args...) 					\
    do { 								\
      RPKI_LOG(L_DEBUG, (cache)->p, "%s [%s] %s " msg, rpki_get_cache_ident(cache), rpki_cache_state_to_str((cache)->state), __func__, ## args); \
    } while(0)
#else
#define CACHE_DBG(cache,msg,args...) do { } while(0)
#endif

#define RPKI_TRACE(level,rpki,msg,args...) 				\
    do {								\
      if ((rpki)->p.debug & level)					\
        RPKI_LOG(L_TRACE, rpki, msg, ## args);				\
    } while(0)

#define CACHE_TRACE(level,cache,msg,args...)				\
    do {								\
      if ((cache)->p->p.debug & level)					\
        RPKI_LOG(L_TRACE, (cache)->p, msg, ## args); 			\
    } while(0)

#define RPKI_WARN(p, msg, args...) RPKI_LOG(L_WARN, p, msg, ## args);

#endif /* _BIRD_RPKI_H_ */