Merge branch 'master' of github.com:urbit/urbit

This commit is contained in:
C. Guy Yarvin 2014-03-19 15:42:12 -07:00
commit 55c9f41b14
29 changed files with 602 additions and 326 deletions

6
.gitignore vendored
View File

@ -1,8 +1,4 @@
*.o
.gdb_history
/generated/
/bin/
*.swp
.*tags
/bin/vere
/urb/*/
!/urb/zod/

View File

@ -43,14 +43,14 @@ ifeq ($(OS),osx)
OSLIBS=-framework CoreServices -framework CoreFoundation
endif
ifeq ($(OS),linux)
OSLIBS=-lcrypto -lpthread -lrt -lcurses
OSLIBS=-lpthread -lrt -lcurses
DEFINES=-D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE
endif
ifeq ($(OS),bsd)
OSLIBS=-lcrypto -lpthread -lncurses -lkvm
OSLIBS=-lpthread -lncurses -lkvm
endif
LIBS=-lgmp -lncurses -lsigsegv $(OSLIBS)
LIBS=-lssl -lcrypto -lgmp -lncurses -lsigsegv $(OSLIBS)
INCLUDE=include
GENERATED=generated

View File

@ -44,7 +44,10 @@
typedef enum {
u2_csat_dead = 0, // connection dead
u2_csat_addr = 1, // connection addressed
u2_csat_live = 2, // connection open
u2_csat_clyr = 2, // connection open in cleartext
u2_csat_crop = 3, // connection open, ssl needs hs
u2_csat_sing = 4, // connection handshaking ssl
u2_csat_cryp = 5, // connection open, ssl open
} u2_csat;
/* u2_hmet: http method. Matches jhttp encoding.
@ -141,12 +144,21 @@
struct _u2_creq* nex_u; // next in queue
} u2_creq;
/* u2_sslx: per-connection ssl context.
*/
typedef struct _u2_sslx {
void* ssl_u; // struct SSL*
void* rio_u; // struct BIO* for read
void* wio_u; // struct BIO* for write
} u2_sslx;
/* u2_ccon: outgoing http connection.
*/
typedef struct _u2_ccon { // client connection
uv_tcp_t wax_u; // i/o handler state
uv_connect_t cot_u; // connection handler state
uv_getaddrinfo_t adr_u; // resolver state
u2_sslx ssl; // ssl state
u2_csat sat_e; // connection state
c3_c* hot_c; // hostname
c3_s por_s; // port
@ -430,21 +442,21 @@
/* u2_raft: raft state.
*/
typedef struct {
uv_tcp_t wax_u;
uv_timer_t tim_u;
u2_ulog lug_u; // event log
c3_w ent_w;
c3_w lat_w;
u2_raty typ_e;
struct _u2_rnam* nam_u;
struct _u2_rcon* run_u;
c3_w pop_w;
c3_w vot_w;
c3_c* str_c; // our name
// persistent state, restored on start
c3_w tem_w;
c3_c* vog_c;
// end persistent state
uv_tcp_t wax_u; // TCP listener
uv_timer_t tim_u; // election/heartbeat timer
u2_ulog lug_u; // event log
c3_w ent_w; // last log index
c3_w lat_w; // last log term
u2_raty typ_e; // server type
struct _u2_rnam* nam_u; // list of peers
struct _u2_rcon* run_u; // unknown connections
c3_w pop_w; // population count
c3_w vot_w; // votes in this election
c3_c* str_c; // our name
// persistent state
c3_w tem_w; // current term
c3_c* vog_c; // who we voted for this term
// end persistent state
} u2_raft;
/* u2_rreq: raft request.
@ -466,27 +478,27 @@
/* u2_rcon: raft connection.
*/
typedef struct _u2_rcon {
uv_tcp_t wax_u;
struct _u2_rnam* nam_u;
u2_rbuf* red_u;
u2_bean red;
u2_rbuf* wri_u;
u2_raft* raf_u;
u2_rreq* out_u;
u2_rreq* tou_u;
struct _u2_rcon* nex_u;
u2_bean liv;
uv_tcp_t wax_u; // TCP handle
struct _u2_rnam* nam_u; // peer we're connected to
u2_rbuf* red_u; // read buffer
u2_bean red; // u2_yes on new data
u2_rbuf* wri_u; // write buffer
u2_raft* raf_u; // back-reference to server
u2_rreq* out_u; // exit of request queue
u2_rreq* tou_u; // entry of request queue
struct _u2_rcon* nex_u; // pointer to next con
u2_bean liv; // are we live?
} u2_rcon;
/* u2_rnam: raft peer name.
*/
typedef struct _u2_rnam {
c3_c* str_c;
c3_c* nam_c;
c3_c* por_c;
u2_rcon* ron_u;
struct _u2_rnam* nex_u;
u2_bean vog;
c3_c* str_c; // our name
c3_c* nam_c; // hostname
c3_c* por_c; // port
u2_rcon* ron_u; // connection
struct _u2_rnam* nex_u; // pointer to next peer
u2_bean vog; // did they vote for us?
} u2_rnam;
/* u2_opts:
@ -534,12 +546,14 @@
u2_unix unx_u; // sync and clay
u2_batz beh_u; // batz timer
u2_bean liv; // if u2_no, shut down
void* ssl_u; // struct SSL_CTX*
u2_reck* arv_u; // runtime
} u2_host; // host == computer == process
# define u2L u2_Host.lup_u // global event loop
# define u2R (&(u2_Raft))
# define u2S u2_Host.ssl_u
/* u2_funk: standard system function.
*/

310
v/cttp.c
View File

@ -19,15 +19,27 @@
#include <termios.h>
#include <term.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#include "../outside/jhttp/http_parser.h" // Joyent HTTP
#include "all.h"
#include "v/vere.h"
#ifdef U2_OS_osx
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
# pragma clang diagnostic ignored "-Wdeprecated-declarations"
#endif
/* Forward declarations.
*/
static void _cttp_ccon_kick(u2_ccon* coc_u);
static void _cttp_ccon_cryp_hurr(u2_ccon* coc_u, c3_i rev_i);
static void _cttp_ccon_cryp_rout(u2_ccon* coc_u);
static void _cttp_ccon_fill(u2_ccon* coc_u);
static void _cttp_ccon_fire(u2_ccon* coc_u, u2_creq* ceq_u);
static void _cttp_ccon_fail_cb(uv_handle_t* wax_u);
static c3_c* _cttp_creq_url(u2_noun pul);
/* _cttp_alloc(): libuv buffer allocator.
@ -625,6 +637,11 @@ _cttp_message_complete(http_parser* par_u)
c3_assert(ceq_u == coc_u->qec_u);
coc_u->qec_u = 0;
}
if ( u2_yes == coc_u->sec ) {
SSL_shutdown(coc_u->ssl.ssl_u);
_cttp_ccon_cryp_rout(coc_u);
uv_close((uv_handle_t*)&coc_u->wax_u, _cttp_ccon_fail_cb);
}
return 0;
}
@ -720,6 +737,9 @@ _cttp_ccon_waste(u2_ccon* coc_u, c3_c* msg_c)
if ( coc_u->nex_u ) {
coc_u->nex_u->pre_u = coc_u->pre_u;
}
if ( coc_u->ssl.ssl_u ) {
SSL_free(coc_u->ssl.ssl_u);
}
free(coc_u);
}
@ -762,7 +782,15 @@ _cttp_ccon_reboot(u2_ccon* coc_u)
_cttp_ccon_waste(coc_u, "connection failed");
break;
}
case u2_csat_live: {
case u2_csat_crop:
case u2_csat_sing: {
/* Got a connection, but SSL failed. Waste it.
*/
_cttp_ccon_waste(coc_u, "ssl handshake failed");
break;
}
case u2_csat_cryp:
case u2_csat_clyr: {
/* We had a connection but it broke. Either there are no
** living requests, in which case waste; otherwise reset.
*/
@ -803,7 +831,7 @@ _cttp_ccon_fail(u2_ccon* coc_u, u2_bean say)
uL(fprintf(uH, "cttp: %s\n", uv_strerror(uv_last_error(u2L))));
}
if ( coc_u->sat_e != u2_csat_live ) {
if ( coc_u->sat_e < u2_csat_crop ) {
_cttp_ccon_reboot(coc_u);
}
else {
@ -872,7 +900,9 @@ _cttp_ccon_kick_connect_cb(uv_connect_t* cot_u,
_cttp_ccon_fail(coc_u, u2_yes);
}
else {
coc_u->sat_e = u2_csat_live;
coc_u->sat_e = (u2_yes == coc_u->sec) ?
u2_csat_crop :
u2_csat_clyr;
_cttp_ccon_kick(coc_u);
}
}
@ -911,7 +941,7 @@ _cttp_ccon_kick_connect(u2_ccon* coc_u)
c3_y* buf_y;
} _u2_write_t;
/* _cttp_ccon_kick_write_cb(): general write callback.
/* _cttp_ccon_kick_write_cb(): general write callback
*/
static void
_cttp_ccon_kick_write_cb(uv_write_t* wri_u, c3_i sas_i)
@ -929,6 +959,32 @@ _cttp_ccon_kick_write_cb(uv_write_t* wri_u, c3_i sas_i)
u2_lo_shut(u2_no);
}
/* _cttp_ccon_kick_write()
*/
static void
_cttp_ccon_kick_write_cryp(u2_ccon* coc_u)
{
if (!SSL_is_init_finished(coc_u->ssl.ssl_u)) {
return;
}
while ( coc_u->rub_u ) {
u2_hbod* rub_u = coc_u->rub_u;
c3_i rev_i;
coc_u->rub_u = coc_u->rub_u->nex_u;
if ( 0 == coc_u->rub_u ) {
c3_assert(rub_u == coc_u->bur_u);
coc_u->bur_u = 0;
}
if ( 0 >
(rev_i = SSL_write(coc_u->ssl.ssl_u, rub_u->hun_y, rub_u->len_w)) ) {
_cttp_ccon_cryp_hurr(coc_u, rev_i);
_cttp_ccon_cryp_rout(coc_u);
}
}
}
/* _cttp_ccon_kick_write_buf(): transmit buffer.
*/
static void
@ -986,12 +1042,106 @@ _cttp_ccon_kick_write(u2_ccon* coc_u)
}
}
/* _cttp_ccon_read_cb()
*/
/* _cttp_ccon_cryp_rout: write the SSL buffer to the network
*/
static void
_cttp_ccon_kick_read_cb(uv_stream_t* tcp_u,
ssize_t siz_i,
uv_buf_t buf_u)
_cttp_ccon_cryp_rout(u2_ccon* coc_u)
{
uv_buf_t buf_u;
c3_i bur_i;
{
c3_y* buf_y = malloc(1<<14);
while ( 0 < (bur_i = BIO_read(coc_u->ssl.wio_u, buf_y, 1<<14)) ) {
buf_u = uv_buf_init((c3_c*)buf_y, bur_i);
_cttp_ccon_kick_write_buf(coc_u, buf_u);
}
}
}
/* _cttp_ccon_cryp_hurr: handle SSL errors
*/
static void
_cttp_ccon_cryp_hurr(u2_ccon* coc_u, int rev)
{
u2_sslx* ssl = &coc_u->ssl;
c3_i err = SSL_get_error(ssl->ssl_u, rev);
switch ( err ) {
default:
_cttp_ccon_waste(coc_u, "ssl lost");
break;
case SSL_ERROR_NONE:
case SSL_ERROR_ZERO_RETURN:
break;
case SSL_ERROR_WANT_WRITE: // XX maybe bad
break;
case SSL_ERROR_WANT_READ:
_cttp_ccon_cryp_rout(coc_u);
break;
}
}
/* _cttp_ccon_pars_shov: shove a data buffer into the parser
*/
static void
_cttp_ccon_pars_shov(u2_ccon* coc_u, void* buf_u, ssize_t siz_i)
{
u2_creq* ceq_u = coc_u->ceq_u;
if ( !ceq_u ) { // spurious input
uL(fprintf(uH, "http: response to no request\n"));
}
else {
if ( !ceq_u->res_u ) {
_cttp_cres_start(ceq_u);
}
if ( siz_i != http_parser_execute(ceq_u->res_u->par_u,
&_cttp_settings,
(c3_c*)buf_u,
siz_i) )
{
uL(fprintf(uH, "http: parse error\n"));
_cttp_ccon_fail(coc_u, u2_no);
}
}
}
/* _cttp_ccon_cryp_pull(): pull cleartext data off of the SSL buffer
*/
static void
_cttp_ccon_cryp_pull(u2_ccon* coc_u)
{
if ( SSL_is_init_finished(coc_u->ssl.ssl_u) ) {
static c3_c buf[1<<14];
c3_i ruf;
while ( 0 < (ruf = SSL_read(coc_u->ssl.ssl_u, &buf, sizeof(buf))) ) {
_cttp_ccon_pars_shov(coc_u, &buf, ruf);
}
if ( 0 >= ruf ) {
_cttp_ccon_cryp_hurr(coc_u, ruf);
}
}
else {
// not connected
c3_i r = SSL_connect(coc_u->ssl.ssl_u);
if ( 0 > r ) {
_cttp_ccon_cryp_hurr(coc_u, r);
}
else {
coc_u->sat_e = u2_csat_cryp;
_cttp_ccon_kick(coc_u);
}
}
_cttp_ccon_kick_write_cryp(coc_u);
}
static void
_cttp_ccon_kick_read_cryp_cb(uv_stream_t* tcp_u,
ssize_t siz_i,
uv_buf_t buf_u)
{
u2_ccon *coc_u = _cttp_ccon_wax((uv_tcp_t*)tcp_u);
@ -1009,18 +1159,8 @@ _cttp_ccon_kick_read_cb(uv_stream_t* tcp_u,
uL(fprintf(uH, "http: response to no request\n"));
}
else {
if ( !ceq_u->res_u ) {
_cttp_cres_start(ceq_u);
}
if ( siz_i != http_parser_execute(ceq_u->res_u->par_u,
&_cttp_settings,
(c3_c*)buf_u.base,
siz_i) )
{
uL(fprintf(uH, "http: parse error\n"));
_cttp_ccon_fail(coc_u, u2_no);
}
BIO_write(coc_u->ssl.rio_u, (c3_c*)buf_u.base, siz_i);
_cttp_ccon_cryp_pull(coc_u);
}
}
if ( buf_u.base ) {
@ -1030,14 +1170,78 @@ _cttp_ccon_kick_read_cb(uv_stream_t* tcp_u,
u2_lo_shut(u2_yes);
}
/* _cttp_ccon_kick_read(): start reading.
/* _cttp_ccon_read_clyr_cb()
*/
static void
_cttp_ccon_kick_read(u2_ccon* coc_u)
_cttp_ccon_kick_read_clyr_cb(uv_stream_t* tcp_u,
ssize_t siz_i,
uv_buf_t buf_u)
{
u2_ccon *coc_u = _cttp_ccon_wax((uv_tcp_t*)tcp_u);
u2_lo_open();
{
if ( siz_i < 0 ) {
uv_err_t las_u = uv_last_error(u2L);
_cttp_ccon_fail(coc_u, (UV_EOF == las_u.code) ? u2_no : u2_yes);
}
else {
_cttp_ccon_pars_shov(coc_u, buf_u.base, siz_i);
}
if ( buf_u.base ) {
free(buf_u.base);
}
}
u2_lo_shut(u2_yes);
}
/* _cttp_ccon_kick_read_clyr(): start reading on insecure socket.
*/
static void
_cttp_ccon_kick_read_clyr(u2_ccon* coc_u)
{
uv_read_start((uv_stream_t*)&coc_u->wax_u,
_cttp_alloc,
_cttp_ccon_kick_read_cb);
_cttp_ccon_kick_read_clyr_cb);
}
/* _cttp_ccon_kick_read_cryp(): start reading on secure socket.
*/
static void
_cttp_ccon_kick_read_cryp(u2_ccon* coc_u)
{
uv_read_start((uv_stream_t*)&coc_u->wax_u,
_cttp_alloc,
_cttp_ccon_kick_read_cryp_cb);
}
/* _cttp_ccon_kick_handshake(): start ssl handshake.
*/
static void
_cttp_ccon_kick_handshake(u2_ccon* coc_u)
{
coc_u->ssl.ssl_u = SSL_new(u2S);
c3_assert(coc_u->ssl.ssl_u);
coc_u->ssl.rio_u = BIO_new(BIO_s_mem());
c3_assert(coc_u->ssl.rio_u);
coc_u->ssl.wio_u = BIO_new(BIO_s_mem());
c3_assert(coc_u->ssl.wio_u);
BIO_set_nbio(coc_u->ssl.rio_u, 1);
BIO_set_nbio(coc_u->ssl.wio_u, 1);
SSL_set_bio(coc_u->ssl.ssl_u,
coc_u->ssl.rio_u,
coc_u->ssl.wio_u);
SSL_set_connect_state(coc_u->ssl.ssl_u);
SSL_do_handshake(coc_u->ssl.ssl_u);
coc_u->sat_e = u2_csat_sing;
_cttp_ccon_kick(coc_u);
}
/* _cttp_ccon_kick(): start appropriate I/O on client connection.
@ -1059,13 +1263,31 @@ _cttp_ccon_kick(u2_ccon* coc_u)
_cttp_ccon_kick_connect(coc_u);
break;
}
case u2_csat_live: {
case u2_csat_crop: {
_cttp_ccon_kick_handshake(coc_u);
break;
}
case u2_csat_sing: {
_cttp_ccon_kick_read_cryp(coc_u);
_cttp_ccon_cryp_pull(coc_u);
break;
}
case u2_csat_cryp: {
_cttp_ccon_fill(coc_u);
if ( coc_u->rub_u ) {
_cttp_ccon_kick_write_cryp(coc_u);
}
_cttp_ccon_cryp_pull(coc_u);
break;
}
case u2_csat_clyr: {
_cttp_ccon_fill(coc_u);
if ( coc_u->rub_u ) {
_cttp_ccon_kick_write(coc_u);
}
_cttp_ccon_kick_read(coc_u);
_cttp_ccon_kick_read_clyr(coc_u);
break;
}
}
@ -1147,7 +1369,8 @@ _cttp_creq_new(c3_l num_l, u2_noun hes)
ceq_u->num_l = num_l;
ceq_u->sec = sec;
ceq_u->por_s = (u2_nul == pus) ? 80 : u2t(pus);
ceq_u->por_s = (u2_nul == pus) ?
( (u2_yes == sec) ? 443 : 80 ) : u2t(pus);
ceq_u->hot_c = _cttp_creq_host(u2k(hot)); // XX duplicate work with url
ceq_u->url_c = _cttp_creq_url(u2k(pul));
@ -1225,7 +1448,10 @@ _cttp_ccon_fire(u2_ccon* coc_u, u2_creq* ceq_u)
_cttp_ccon_fire_str(coc_u, " HTTP/1.1\r\n");
_cttp_ccon_fire_str(coc_u, "User-Agent: urbit/vere.0.2\r\n");
_cttp_ccon_fire_str(coc_u, "Accept: */*\r\n");
_cttp_ccon_fire_str(coc_u, "Connection: Keep-Alive\r\n");
// XX it's more painful than it's worth to deal with SSL+Keepalive
if ( u2_no == coc_u->sec ) {
_cttp_ccon_fire_str(coc_u, "Connection: Keep-Alive\r\n");
}
_cttp_ccon_fire_body(coc_u, _cttp_bud("Host", ceq_u->hot_c));
_cttp_ccon_fire_heds(coc_u, ceq_u->hed_u);
@ -1320,12 +1546,37 @@ u2_cttp_ef_thus(c3_l num_l,
u2z(cuq);
}
/* u2_cttp_io_init(): initialize http I/O.
/* u2_cttp_io_init(): initialize http client I/O.
*/
void
u2_cttp_io_init()
{
c3_i rad;
c3_y buf[4096];
u2_Host.ctp_u.coc_u = 0;
SSL_library_init();
SSL_load_error_strings();
u2_Host.ssl_u = SSL_CTX_new(TLSv1_client_method());
SSL_CTX_set_options(u2S, SSL_OP_NO_SSLv2);
SSL_CTX_set_verify(u2S, SSL_VERIFY_PEER, NULL);
SSL_CTX_set_default_verify_paths(u2S);
SSL_CTX_set_session_cache_mode(u2S, SSL_SESS_CACHE_OFF);
SSL_CTX_set_cipher_list(u2S, "ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:"
"ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:"
"RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS");
// RAND_status, at least on OS X, never returns true.
// 4096 bytes should be enough entropy for anyone, right?
rad = open("/dev/urandom", O_RDONLY);
if ( 4096 != read(rad, &buf, 4096) ) {
perror("rand-seed");
exit(1);
}
RAND_seed(buf, 4096);
close(rad);
}
/* u2_cttp_io_poll(): poll kernel for cttp I/O.
@ -1340,4 +1591,5 @@ u2_cttp_io_poll(void)
void
u2_cttp_io_exit(void)
{
SSL_CTX_free(u2S);
}

View File

@ -163,6 +163,7 @@ _lo_init()
u2_ames_io_init();
u2_term_io_init();
u2_http_io_init();
u2_cttp_io_init();
u2_save_io_init();
u2_batz_io_init();
}
@ -186,6 +187,7 @@ u2_lo_exit(void)
u2_ames_io_exit();
u2_term_io_exit();
u2_http_io_exit();
u2_cttp_io_exit();
u2_save_io_exit();
u2_batz_io_exit();
}

View File

@ -204,7 +204,8 @@ _main_getopt(c3_i argc, c3_c** argv)
static void
u2_ve_usage(c3_i argc, c3_c** argv)
{
fprintf(stderr, "%s: usage: [-v] [-k stage] [-p ames_port] computer\n", argv[0]);
fprintf(stderr, "%s: usage: [-v] [-k stage] [-p ames_port] computer\n",
argv[0]);
exit(1);
}

View File

@ -168,12 +168,18 @@ _raft_promote(u2_raft* raf_u)
else {
c3_i sas_i;
uL(fprintf(uH, "raft: promoting to leader\n"));
if ( 1 == raf_u->pop_w ) {
uL(fprintf(uH, "raft: -> lead\n"));
raf_u->typ_e = u2_raty_lead;
// TODO boot in multiuser mode
u2_sist_boot();
if ( u2_no == u2_Host.ops_u.bat ) {
u2_lo_lead(u2A);
}
}
else {
c3_assert(u2_raty_cand == raf_u->typ_e);
uL(fprintf(uH, "raft: cand -> lead\n"));
raf_u->typ_e = u2_raty_lead;
sas_i = uv_timer_stop(&raf_u->tim_u);
@ -182,14 +188,6 @@ _raft_promote(u2_raft* raf_u)
c3_assert(0 == sas_i);
}
}
/* TODO */
if ( 1 == raf_u->pop_w ) {
u2_sist_boot();
if ( u2_no == u2_Host.ops_u.bat ) {
u2_lo_lead(u2A);
}
}
}
/* _raft_demote(): demote to follower.
@ -197,18 +195,27 @@ _raft_promote(u2_raft* raf_u)
static void
_raft_demote(u2_raft* raf_u)
{
if ( u2_raty_lead == raf_u->typ_e ) {
uL(fprintf(uH, "raft: demoting leader\n"));
/* TODO just start dropping events */
u2_lo_bail(u2A);
u2_raty typ_e = raf_u->typ_e;
raf_u->vog_c = 0;
u2_sist_nil("vote");
raf_u->vot_w = 0;
raf_u->typ_e = u2_raty_foll;
if ( u2_raty_lead == typ_e ) {
c3_i sas_i;
uL(fprintf(uH, "raft: lead -> foll\n"));
sas_i = uv_timer_stop(&raf_u->tim_u);
c3_assert(0 == sas_i);
sas_i = uv_timer_start(&raf_u->tim_u, _raft_time_cb,
_raft_election_rand(), 0);
c3_assert(0 == sas_i);
// TODO dump not-yet-committed events
}
else {
c3_assert(u2_raty_cand == raf_u->typ_e);
uL(fprintf(uH, "raft: demoting to follower\n"));
raf_u->vog_c = 0;
u2_sist_nil("vote");
raf_u->vot_w = 0;
raf_u->typ_e = u2_raty_foll;
c3_assert(u2_raty_cand == typ_e);
uL(fprintf(uH, "raft: cand -> foll\n"));
}
}
@ -346,7 +353,7 @@ _raft_revo_done(u2_rreq* req_u, c3_w suc_w)
u2_raft* raf_u = ron_u->raf_u;
c3_assert(c3__revo == req_u->msg_u->typ_w);
if ( suc_w ) {
if ( suc_w && req_u->msg_u->tem_w == raf_u->tem_w ) {
if ( u2_no == ron_u->nam_u->vog ) {
ron_u->nam_u->vog = u2_yes;
raf_u->vot_w++;
@ -1286,7 +1293,7 @@ _raft_time_cb(uv_timer_t* tim_u, c3_i sas_i)
c3_assert(0);
}
case u2_raty_foll: {
uL(fprintf(uH, "raft: promoting to candidate\n"));
uL(fprintf(uH, "raft: foll -> cand\n"));
raf_u->typ_e = u2_raty_cand;
// continue to cand
}
@ -1306,7 +1313,7 @@ _raft_time_cb(uv_timer_t* tim_u, c3_i sas_i)
static void
_raft_foll_init(u2_raft* raf_u)
{
uL(fprintf(uH, "raft: starting follower\n"));
uL(fprintf(uH, "raft: none -> foll\n"));
raf_u->typ_e = u2_raty_foll;
// Initialize and count peers.

View File

@ -486,6 +486,10 @@ _unix_dir_update(u2_udir* dir_u, DIR* rid_u)
mpz_t mod_mp;
u2_ufil* fil_u;
if ( ( NULL == strrchr(out_u->d_name, '.')) ) {
continue;
}
{
u2_noun mod = c3_stat_mtime(&buf_u);