mirror of
https://github.com/urbit/shrub.git
synced 2024-12-25 13:04:17 +03:00
Merge branch 'master' of github.com:urbit/urbit
This commit is contained in:
commit
55c9f41b14
6
.gitignore
vendored
6
.gitignore
vendored
@ -1,8 +1,4 @@
|
||||
*.o
|
||||
.gdb_history
|
||||
/generated/
|
||||
/bin/
|
||||
*.swp
|
||||
.*tags
|
||||
/bin/vere
|
||||
/urb/*/
|
||||
!/urb/zod/
|
||||
|
6
Makefile
6
Makefile
@ -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
|
||||
|
@ -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
310
v/cttp.c
@ -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);
|
||||
}
|
||||
|
2
v/loop.c
2
v/loop.c
@ -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();
|
||||
}
|
||||
|
3
v/main.c
3
v/main.c
@ -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);
|
||||
}
|
||||
|
||||
|
51
v/raft.c
51
v/raft.c
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user