aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2015-12-27 21:50:09 -0500
committerFranklin Wei <git@fwei.tk>2015-12-27 21:50:09 -0500
commitab4708acd2d4cf0bd9271b9cd423b7458aee51d8 (patch)
tree354d610c8704a3089714fc06faa429ee87cde290 /src
parent88c66d263b59147280d5dc1f1bdab8ba5031adee (diff)
downloadnetcosm-ab4708acd2d4cf0bd9271b9cd423b7458aee51d8.zip
netcosm-ab4708acd2d4cf0bd9271b9cd423b7458aee51d8.tar.gz
netcosm-ab4708acd2d4cf0bd9271b9cd423b7458aee51d8.tar.bz2
netcosm-ab4708acd2d4cf0bd9271b9cd423b7458aee51d8.tar.xz
fix things, mostly works now
Diffstat (limited to 'src')
-rw-r--r--src/client.c56
-rw-r--r--src/server.c103
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();