diff options
| author | Franklin Wei <git@fwei.tk> | 2015-12-27 21:50:09 -0500 |
|---|---|---|
| committer | Franklin Wei <git@fwei.tk> | 2015-12-27 21:50:09 -0500 |
| commit | ab4708acd2d4cf0bd9271b9cd423b7458aee51d8 (patch) | |
| tree | 354d610c8704a3089714fc06faa429ee87cde290 | |
| parent | 88c66d263b59147280d5dc1f1bdab8ba5031adee (diff) | |
| download | netcosm-ab4708acd2d4cf0bd9271b9cd423b7458aee51d8.zip netcosm-ab4708acd2d4cf0bd9271b9cd423b7458aee51d8.tar.gz netcosm-ab4708acd2d4cf0bd9271b9cd423b7458aee51d8.tar.bz2 netcosm-ab4708acd2d4cf0bd9271b9cd423b7458aee51d8.tar.xz | |
fix things, mostly works now
| -rw-r--r-- | src/client.c | 56 | ||||
| -rw-r--r-- | src/server.c | 103 |
2 files changed, 107 insertions, 52 deletions
diff --git a/src/client.c b/src/client.c index 99b90e7..de39392 100644 --- a/src/client.c +++ b/src/client.c @@ -18,6 +18,8 @@ #include "netcosm.h" +static bool admin = false; + static int client_fd, to_parent, from_parent; static room_id current_room = 0; @@ -58,16 +60,19 @@ static time_t ts = 0; void send_master(unsigned char cmd, const void *data, size_t sz) { - time_t t = time(NULL); - if(ts != t) - { - ts = t; - reqs_since_ts = 0; - } - if(reqs_since_ts++ > 10) + if(!admin) { - out("Rate limit exceeded.\n"); - return; + time_t t = time(NULL); + if(ts != t) + { + ts = t; + reqs_since_ts = 0; + } + if(reqs_since_ts++ > 10) + { + out("Rate limit exceeded.\n"); + return; + } } request_complete = 0; @@ -144,6 +149,20 @@ void all_upper(char *s) } } +static void print_all(int fd) +{ + unsigned char buf[MSG_MAX + 1]; + do { + sig_printf("Reading...\n"); + ssize_t len = read(fd, &buf, MSG_MAX); + sig_printf("Read %d bytes\n", len); + if(len <= 0) + break; + buf[MSG_MAX] = '\0'; + out_raw(buf, len); + } while(1); +} + void sig_rt_0_handler(int s, siginfo_t *info, void *v) { (void) s; @@ -159,24 +178,18 @@ void sig_rt_0_handler(int s, siginfo_t *info, void *v) unsigned char cmd; read(from_parent, &cmd, 1); - sig_printf("Got data from parent.\n"); + sig_printf("Got command from parent.\n"); unsigned char buf[MSG_MAX + 1]; switch(cmd) { case REQ_BCASTMSG: { - sig_printf("reading...\n"); - ssize_t len = read(from_parent, buf, MSG_MAX); - sig_printf("done reading\n"); - buf[MSG_MAX] = '\0'; - out_raw(buf, len); + print_all(from_parent); break; } case REQ_KICK: { - ssize_t len = read(from_parent, buf, MSG_MAX); - buf[MSG_MAX] = '\0'; - out_raw(buf, len); + print_all(from_parent); union sigval junk; /* the master still expects an ACK */ sigqueue(getppid(), SIGRTMIN+1, junk); @@ -194,6 +207,11 @@ void sig_rt_0_handler(int s, siginfo_t *info, void *v) break; default: sig_printf("WARNING: client process received unknown code %d\n", cmd); + ssize_t len = read(from_parent, buf, MSG_MAX); + if(len > 0) + sig_printf("DATA %d ___'%s'___", len, buf); + sleep(1); + kill(getppid(), SIGSEGV); break; } @@ -342,7 +360,7 @@ auth: if(authlevel == PRIV_NONE) return; - bool admin = (authlevel == PRIV_ADMIN); + admin = (authlevel == PRIV_ADMIN); if(admin) client_change_state(STATE_ADMIN); else diff --git a/src/server.c b/src/server.c index ad2502d..ff4a4d0 100644 --- a/src/server.c +++ b/src/server.c @@ -319,6 +319,24 @@ void sig_printf(const char *fmt, ...) va_end(ap); } +static void force_read(int fd, void *buf, size_t n) +{ + unsigned char *ptr = buf; + size_t n_read = 0; + while(n_read < n) + { + ssize_t ret = read(fd, ptr, n - n_read); + ptr += ret; + n_read += ret; + } +} + +static void empty_pipe(int fd) +{ + char buf[4096]; + read(fd, buf, sizeof(buf)); +} + /** * Here's how child-parent requests work * 1. Child writes its PID and length of request to the parent's pipe, followed @@ -335,43 +353,45 @@ void sig_printf(const char *fmt, ...) static bool handle_child_req(int in_fd) { pid_t sender_pid; - if(read(in_fd, &sender_pid, sizeof(sender_pid)) != sizeof(pid_t)) - return false; - sig_printf("PID %d sends a client request\n", sender_pid); - - size_t msglen; - if(read(in_fd, &msglen, sizeof(msglen)) != sizeof(msglen)) - return false; - if(msglen > MSG_MAX) + if(read(in_fd, &sender_pid, sizeof(sender_pid)) != sizeof(sender_pid)) { - sig_printf("message data too long, dropping\n"); - return false; - } - else if(msglen < 1) - { - sig_printf("message too short to be valid, ignoring.\n"); - return false; + sig_printf("Couldn't get sender PID\n"); + goto fail; } + sig_printf("PID %d sends a client request\n", sender_pid); + + size_t msglen; + const struct child_request *req = NULL; + size_t datalen; + unsigned char cmd, msg[MSG_MAX + 1]; + struct child_data *sender = hash_lookup(child_map, &sender_pid); if(!sender) { - printf("WARNING: got data from unknown PID, ignoring.\n"); - return false; + sig_printf("WARNING: got data from unknown PID, ignoring.\n"); + goto fail; } - sigset_t old, block; - - sigemptyset(&block); - sigaddset(&block, SIGRTMIN+1); - sigprocmask(SIG_BLOCK, &block, &old); + if(read(in_fd, &msglen, sizeof(msglen)) != sizeof(msglen)) + { + sig_printf("Couldn't read message length, dropping.\n"); + goto fail; + } - num_acks_wanted = 1; - num_acks_recvd = 0; - inc_acks = 1; + if(msglen < 1) + { + sig_printf("message too short to be valid, ignoring.\n"); + goto fail; + } + else if(msglen > MSG_MAX) + { + sig_printf("message too long, ignoring.\n"); + goto fail; + } unsigned char *msgptr = msg; size_t have = 0; @@ -381,7 +401,7 @@ static bool handle_child_req(int in_fd) if(ret < 0) { sig_printf("unexpected EOF\n"); - return true; + goto fail; } msgptr += ret; have += ret; @@ -392,14 +412,23 @@ static bool handle_child_req(int in_fd) unsigned char *data = msg + 1; - size_t datalen = msglen - 1; + datalen = msglen - 1; + req = hash_lookup(request_map, &cmd); - const struct child_request *req = hash_lookup(request_map, &cmd); + sigset_t old, block; + + sigemptyset(&block); + sigaddset(&block, SIGRTMIN+1); + sigprocmask(SIG_BLOCK, &block, &old); + + num_acks_wanted = 1; + num_acks_recvd = 0; + inc_acks = 1; if(!req) { sig_printf("Unknown request.\n"); - return true; + goto fail; } write(sender->outpipe[1], &req->cmd_to_send, 1); @@ -448,7 +477,10 @@ finish: req->finalize(data, datalen, sender); union sigval junk; - sigqueue(sender->pid, SIGRTMIN, junk); + if(sender) + sigqueue(sender->pid, SIGRTMIN, junk); + else + sig_printf("Unknown PID send request.\n"); sig_printf("Waiting for %d acks\n", num_acks_wanted); @@ -465,6 +497,9 @@ finish: sig_printf("finished handling client request\n"); return true; +fail: + empty_pipe(in_fd); + return true; } static void master_ack_handler(int s, siginfo_t *info, void *v) @@ -484,6 +519,7 @@ void init_signals(void) struct sigaction sa; sigemptyset(&sa.sa_mask); + sigaddset(&sa.sa_mask, SIGCHLD); sa.sa_sigaction = sigchld_handler; // reap all dead processes sa.sa_flags = SA_RESTART | SA_SIGINFO; if (sigaction(SIGCHLD, &sa, NULL) < 0) @@ -513,6 +549,7 @@ void init_signals(void) /* set this now so there's no race condition later */ sigemptyset(&sa.sa_mask); + sigaddset(&sa.sa_mask, SIGRTMIN); void sig_rt_0_handler(int s, siginfo_t *info, void *v); sa.sa_sigaction = sig_rt_0_handler; sa.sa_flags = SA_RESTART | SA_SIGINFO; @@ -598,8 +635,8 @@ int main(int argc, char *argv[]) reqmap_init(); - /* this is set very low to make iteration faster */ - child_map = hash_init(11, pid_hash, pid_equal); + /* this initial size very low to make iteration faster */ + child_map = hash_init(7, pid_hash, pid_equal); hash_setfreedata_cb(child_map, free_child_data); hash_setfreekey_cb(child_map, free); @@ -644,7 +681,7 @@ int main(int argc, char *argv[]) if(pipe(readpipe) < 0) error("pipe"); - if(pipe(outpipe) < 0) + if(pipe2(outpipe, O_NONBLOCK) < 0) error("pipe"); pid_t pid = fork(); |