Line data Source code
1 : #ifndef HEADER_fd_src_discof_repair_fd_rserve_h 2 : #define HEADER_fd_src_discof_repair_fd_rserve_h 3 : 4 : #include "../../flamenco/fd_flamenco_base.h" 5 : 6 : /* Repair server. */ 7 : 8 : /* TODO: We want to consider not using a ping-cache, and instead rely on 9 : the existing set of "good" nodes we'd need to know about from Gossip. 10 : A ping-cache is a simple solution for the time being. */ 11 : 12 : /* Ping cache TTL in nanoseconds (1280 seconds). */ 13 : #define FD_RSERVE_PING_CACHE_TTL_NS (1280UL * 1000000000UL) 14 : /* Token rotation period in nanoseconds (640 seconds, half of TTL). */ 15 : #define FD_RSERVE_TOKEN_ROTATE_NS (640UL * 1000000000UL) 16 : 17 : 18 : struct __attribute__((packed)) ping_cache_key { 19 : fd_pubkey_t pubkey; /* pubkey of the node which sent the ping */ 20 : uint ip4; /* source ipv4 address of the pong */ 21 : ushort port; /* source udp port of the pong */ 22 : }; 23 : typedef struct ping_cache_key ping_cache_key_t; 24 : 25 : typedef struct { 26 : ping_cache_key_t key; /* (pubkey, address) that completed a ping */ 27 : ulong next; /* Pool free-list next. */ 28 : struct { 29 : ulong prev; 30 : ulong next; 31 : } map; /* fd_map_chain prev/next. */ 32 : struct { 33 : ulong prev; 34 : ulong next; 35 : } dlist; /* LRU dlist prev/next. */ 36 : ulong timestamp; /* The time at which the pong was received. Stored in nanoseconds. */ 37 : } ping_cache_entry_t; 38 : 39 : #define POOL_NAME ping_pool 40 0 : #define POOL_T ping_cache_entry_t 41 : #include "../../util/tmpl/fd_pool.c" 42 : 43 : #define MAP_NAME ping_map 44 0 : #define MAP_ELE_T ping_cache_entry_t 45 : #define MAP_KEY_T ping_cache_key_t 46 0 : #define MAP_KEY key 47 0 : #define MAP_PREV map.prev 48 0 : #define MAP_NEXT map.next 49 0 : #define MAP_KEY_EQ(k0,k1) (!memcmp((k0),(k1),sizeof(ping_cache_key_t))) 50 0 : #define MAP_KEY_HASH(key,seed) fd_ulong_hash( fd_hash( (seed), key->pubkey.uc, sizeof(fd_pubkey_t) ) ^ ((ulong)(key)->ip4) ^ (((ulong)(key)->port)<<32) ^ (seed) ) 51 : #define MAP_OPTIMIZE_RANDOM_ACCESS_REMOVAL 1 52 : #include "../../util/tmpl/fd_map_chain.c" 53 : 54 : #define DLIST_NAME ping_dlist 55 : #define DLIST_ELE_T ping_cache_entry_t 56 0 : #define DLIST_PREV dlist.prev 57 0 : #define DLIST_NEXT dlist.next 58 : #include "../../util/tmpl/fd_dlist.c" 59 : 60 : typedef struct { 61 : ping_cache_entry_t * ping_pool; 62 : ping_map_t * ping_map; 63 : ping_dlist_t * ping_dlist; 64 : 65 : uchar secret_master[ 32 ]; 66 : uchar secret_cur [ 32 ]; 67 : uchar secret_prev [ 32 ]; 68 : ulong token_idx; 69 : ulong last_rotate_ts; 70 : 71 : ulong seed; 72 : } fd_rserve_t; 73 : 74 : FD_FN_CONST static inline ulong 75 0 : fd_rserve_align( void ) { 76 0 : return 128UL; 77 0 : } 78 : 79 : ulong 80 : fd_rserve_footprint( ulong ping_cache_entries ); 81 : 82 : void * 83 : fd_rserve_new( void * shmem, 84 : ulong ping_cache_entries, 85 : ulong seed, 86 : uchar const secret[ 32 ] ); 87 : 88 : fd_rserve_t * 89 : fd_rserve_join( void * shrserve ); 90 : 91 : void * 92 : fd_rserve_leave( fd_rserve_t const * rserve ); 93 : 94 : void * 95 : fd_rserve_delete( void * rserve ); 96 : 97 : void 98 : fd_rserve_ping_token( fd_rserve_t const * rserve, 99 : uchar token[ 32 ], 100 : fd_pubkey_t const * from, 101 : uint ip4, 102 : ushort port ); 103 : 104 : int 105 : fd_rserve_pong_token_verify( fd_rserve_t const * rserve, 106 : uchar const * pong_hash, 107 : fd_pubkey_t const * from, 108 : uint ip4, 109 : ushort port ); 110 : 111 : void 112 : fd_rserve_maybe_rotate( fd_rserve_t * rserve, 113 : ulong now_ns ); 114 : 115 : #endif /* HEADER_fd_src_discof_repair_fd_rserve_h */