|
|
|
@ -252,12 +252,45 @@ static void my_tcp_client_connect(grpc_exec_ctx *exec_ctx, |
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// test driver
|
|
|
|
|
|
|
|
|
|
typedef enum { |
|
|
|
|
SERVER_SHUTDOWN, |
|
|
|
|
CHANNEL_WATCH, |
|
|
|
|
} tag_name; |
|
|
|
|
typedef struct validator { |
|
|
|
|
void (*validate)(void *arg, bool success); |
|
|
|
|
void *arg; |
|
|
|
|
} validator; |
|
|
|
|
|
|
|
|
|
static validator *create_validator(void (*validate)(void *arg, bool success), |
|
|
|
|
void *arg) { |
|
|
|
|
validator *v = gpr_malloc(sizeof(*v)); |
|
|
|
|
v->validate = validate; |
|
|
|
|
v->arg = arg; |
|
|
|
|
return v; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void assert_success_and_decrement(void *counter, bool success) { |
|
|
|
|
GPR_ASSERT(success); |
|
|
|
|
--*(int *)counter; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void *tag(tag_name name) { return (void *)(uintptr_t)name; } |
|
|
|
|
typedef struct connectivity_watch { |
|
|
|
|
int *counter; |
|
|
|
|
gpr_timespec deadline; |
|
|
|
|
} connectivity_watch; |
|
|
|
|
|
|
|
|
|
static connectivity_watch *make_connectivity_watch(gpr_timespec s, |
|
|
|
|
int *counter) { |
|
|
|
|
connectivity_watch *o = gpr_malloc(sizeof(*o)); |
|
|
|
|
o->deadline = s; |
|
|
|
|
o->counter = counter; |
|
|
|
|
return o; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void validate_connectivity_watch(void *p, bool success) { |
|
|
|
|
connectivity_watch *w = p; |
|
|
|
|
if (!success) { |
|
|
|
|
GPR_ASSERT(gpr_time_cmp(gpr_now(w->deadline.clock_type), w->deadline) >= 0); |
|
|
|
|
} |
|
|
|
|
--*w->counter; |
|
|
|
|
gpr_free(w); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { |
|
|
|
|
grpc_test_only_set_metadata_hash_seed(0); |
|
|
|
@ -286,7 +319,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { |
|
|
|
|
} |
|
|
|
|
if (g_server != NULL) { |
|
|
|
|
if (!server_shutdown) { |
|
|
|
|
grpc_server_shutdown_and_notify(g_server, cq, tag(SERVER_SHUTDOWN)); |
|
|
|
|
grpc_server_shutdown_and_notify( |
|
|
|
|
g_server, cq, create_validator(assert_success_and_decrement, |
|
|
|
|
&pending_server_shutdowns)); |
|
|
|
|
server_shutdown = true; |
|
|
|
|
pending_server_shutdowns++; |
|
|
|
|
} else if (pending_server_shutdowns == 0) { |
|
|
|
@ -308,20 +343,12 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { |
|
|
|
|
grpc_event ev = grpc_completion_queue_next( |
|
|
|
|
cq, gpr_inf_past(GPR_CLOCK_REALTIME), NULL); |
|
|
|
|
switch (ev.type) { |
|
|
|
|
case GRPC_OP_COMPLETE: |
|
|
|
|
switch ((tag_name)(uintptr_t)ev.tag) { |
|
|
|
|
case SERVER_SHUTDOWN: |
|
|
|
|
GPR_ASSERT(pending_server_shutdowns); |
|
|
|
|
pending_server_shutdowns--; |
|
|
|
|
break; |
|
|
|
|
case CHANNEL_WATCH: |
|
|
|
|
GPR_ASSERT(pending_channel_watches > 0); |
|
|
|
|
pending_channel_watches--; |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
GPR_ASSERT(false); |
|
|
|
|
} |
|
|
|
|
case GRPC_OP_COMPLETE: { |
|
|
|
|
validator *v = ev.tag; |
|
|
|
|
v->validate(v->arg, ev.success); |
|
|
|
|
gpr_free(v); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
case GRPC_QUEUE_TIMEOUT: |
|
|
|
|
break; |
|
|
|
|
case GRPC_QUEUE_SHUTDOWN: |
|
|
|
@ -375,7 +402,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { |
|
|
|
|
// begin server shutdown
|
|
|
|
|
case 5: { |
|
|
|
|
if (g_server != NULL) { |
|
|
|
|
grpc_server_shutdown_and_notify(g_server, cq, tag(SERVER_SHUTDOWN)); |
|
|
|
|
grpc_server_shutdown_and_notify( |
|
|
|
|
g_server, cq, create_validator(assert_success_and_decrement, |
|
|
|
|
&pending_server_shutdowns)); |
|
|
|
|
pending_server_shutdowns++; |
|
|
|
|
server_shutdown = true; |
|
|
|
|
} |
|
|
|
@ -411,12 +440,14 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { |
|
|
|
|
grpc_connectivity_state st = |
|
|
|
|
grpc_channel_check_connectivity_state(g_channel, 0); |
|
|
|
|
if (st != GRPC_CHANNEL_FATAL_FAILURE) { |
|
|
|
|
gpr_timespec deadline = gpr_time_add( |
|
|
|
|
gpr_now(GPR_CLOCK_REALTIME), |
|
|
|
|
gpr_time_from_micros(read_uint32(&inp), GPR_TIMESPAN)); |
|
|
|
|
grpc_channel_watch_connectivity_state( |
|
|
|
|
g_channel, st, |
|
|
|
|
gpr_time_add( |
|
|
|
|
gpr_now(GPR_CLOCK_REALTIME), |
|
|
|
|
gpr_time_from_micros(read_uint32(&inp), GPR_TIMESPAN)), cq, |
|
|
|
|
tag(CHANNEL_WATCH)); |
|
|
|
|
g_channel, st, deadline, cq, |
|
|
|
|
create_validator(validate_connectivity_watch, |
|
|
|
|
make_connectivity_watch( |
|
|
|
|
deadline, &pending_channel_watches))); |
|
|
|
|
pending_channel_watches++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|