From c1cdf0f980b92193953f05bf444b7c78f369a122 Mon Sep 17 00:00:00 2001 From: rodri Date: Thu, 9 Feb 2023 21:01:00 +0000 Subject: implemented a packet processing pipeline. got rid of Lobby. began development of a network protocol. --- dat.h | 62 +++++++++++++++---------------- fns.h | 6 --- lobby.c | 101 -------------------------------------------------- mkfile | 1 - musw.c | 86 ++++++++++++++++++++++++++++--------------- muswd.c | 128 ++++++++++++++++++++++++++++++++++++++++------------------------ pack.c | 38 ++++++++++++++----- 7 files changed, 195 insertions(+), 227 deletions(-) delete mode 100644 lobby.c diff --git a/dat.h b/dat.h index 590e1ac..9727db3 100644 --- a/dat.h +++ b/dat.h @@ -22,7 +22,24 @@ enum { }; enum { - Framehdrsize = 4+4+4+2, + NChi = 10, /* C wants to connect */ + NShi, /* S accepts */ + NCdhx0 = 12, /* C asks for p and g */ + NSdhx0, /* S sends them. it's not a negotiation */ + NCdhx1 = 14, /* C shares pubkey */ + NSdhx1, /* S shares pubkey */ + NCnudge = 16, + NSnudge, /* check the pulse of the line */ + + NCinput = 20, /* C sends player input state */ + NSsimstate, /* S sends current simulation state */ + + NCbuhbye = 30, + NSbuhbye +}; + +enum { + Framehdrsize = 1+4+4+2, MTU = 1024 }; @@ -36,10 +53,8 @@ typedef struct Universe Universe; typedef struct Derivative Derivative; typedef struct Frame Frame; -typedef struct Conn Conn; -typedef struct PInput PInput; +typedef struct NetConn NetConn; typedef struct Player Player; -typedef struct Lobby Lobby; typedef struct Party Party; /* @@ -118,44 +133,25 @@ struct Derivative struct Frame { - Udphdr *udp; - uint seq; - uint ack; - uint id; - ushort len; + Udphdr udp; + u8int type; + u32int seq; + u32int ack; + u16int len; uchar data[]; }; -struct Conn +struct NetConn { - char dir[40]; - int ctl; - int data; - int status; -}; - -struct PInput -{ - ulong kdown; + Udphdr udp; + int isconnected; }; struct Player { char *name; - Conn conn; - PInput oldinput, input; -}; - -struct Lobby -{ - Player *seats; - ulong nseats; - ulong cap; - - int (*takeseat)(Lobby*, char*, int, int); - int (*leaveseat)(Lobby*, ulong); - int (*getcouple)(Lobby*, Player*); - void (*purge)(Lobby*); + NetConn conn; + ulong okdown, kdown; }; struct Party diff --git a/fns.h b/fns.h index 0620a2f..297a393 100644 --- a/fns.h +++ b/fns.h @@ -23,12 +23,6 @@ uvlong nanosec(void); int pack(uchar*, int, char*, ...); int unpack(uchar*, int, char*, ...); -/* - * lobby - */ -Lobby *newlobby(void); -void dellobby(Lobby*); - /* * party */ diff --git a/lobby.c b/lobby.c deleted file mode 100644 index 7ffa969..0000000 --- a/lobby.c +++ /dev/null @@ -1,101 +0,0 @@ -#include -#include -#include -#include -#include -#include "dat.h" -#include "fns.h" - -static int -lobby_takeseat(Lobby *l, char *dir, int cfd, int dfd) -{ - if(l->nseats >= l->cap){ - l->cap += 8; - l->seats = erealloc(l->seats, l->cap*sizeof(*l->seats)); - } - - l->seats[l->nseats].name = nil; - memmove(l->seats[l->nseats].conn.dir, dir, sizeof l->seats[l->nseats].conn.dir); - l->seats[l->nseats].conn.ctl = cfd; - l->seats[l->nseats].conn.data = dfd; - - return l->nseats++; -} - -static int -lobby_leaveseat(Lobby *l, ulong idx) -{ - if(idx >= l->cap) - return -1; - - if(idx < l->cap - 1) - memmove(&l->seats[idx], &l->seats[idx+1], l->cap*sizeof(*l->seats) - (idx + 1)*sizeof(*l->seats)); - - return --l->nseats; -} - -static int -lobby_getcouple(Lobby *l, Player *couple) -{ - if(l->nseats >= 2){ - couple[0] = l->seats[l->nseats-2]; - couple[1] = l->seats[l->nseats-1]; - - if(l->nseats < l->cap - 2) - memmove(&l->seats[l->nseats], &l->seats[l->nseats+2], l->cap*sizeof(*l->seats) - (l->nseats + 2)*sizeof(*l->seats)); - - l->nseats -= 2; - - return 0; - } - - return -1; -} - -static void -lobby_purge(Lobby *l) -{ - char status[48], buf[16]; - int i, fd; - - for(i = 0; i < l->nseats; i++){ - snprint(status, sizeof status, "%s/status", l->seats[i].conn.dir); - - fd = open(status, OREAD); - if(fd < 0) - goto cleanup; - - if(read(fd, buf, sizeof buf) > 0) - if(strncmp(buf, "Close", 5) == 0) - goto cleanup; - else{ - close(fd); - continue; - } -cleanup: - close(fd); - l->leaveseat(l, i); - } -} - -Lobby * -newlobby(void) -{ - Lobby *l; - - l = emalloc(sizeof(Lobby)); - memset(l, 0, sizeof(Lobby)); - l->takeseat = lobby_takeseat; - l->getcouple = lobby_getcouple; - l->leaveseat = lobby_leaveseat; - l->purge = lobby_purge; - - return l; -} - -void -dellobby(Lobby *l) -{ - free(l->seats); - free(l); -} diff --git a/mkfile b/mkfile index 38115d0..2125bca 100644 --- a/mkfile +++ b/mkfile @@ -11,7 +11,6 @@ OFILES=\ physics.$O\ nanosec.$O\ pack.$O\ - lobby.$O\ party.$O\ universe.$O\ sprite.$O\ diff --git a/musw.c b/musw.c index 58e8e0f..12b0307 100644 --- a/musw.c +++ b/musw.c @@ -35,7 +35,8 @@ RFrame screenrf; Universe *universe; VModel *needlemdl, *wedgemdl; Image *skymap; -Channel *kchan; +Channel *ingress; +Channel *egress; char winspec[32]; int debug; @@ -142,6 +143,20 @@ drawship(Ship *ship, Image *dst) } } +void +sendkeys(ulong kdown) +{ + Frame *frame; + + frame = emalloc(sizeof(Frame)+sizeof(kdown)); + frame->type = NCinput; + frame->seq = 0; + frame->ack = 0; + frame->len = sizeof(kdown); + pack(frame->data, frame->len, "k", kdown); + sendp(egress, frame); +} + void kbdproc(void *) { @@ -188,56 +203,68 @@ kbdproc(void *) } if(debug) - fprint(2, "kdown %.*lub\n", - sizeof(kdown)*8, kdown); + fprint(2, "kdown %.*lub\n", sizeof(kdown)*8, kdown); - nbsendul(kchan, kdown); + sendkeys(kdown); } } void threadnetrecv(void *arg) { - uchar buf[1024]; + uchar buf[MTU]; int fd, n; Ioproc *io; + Frame *frame; + + threadsetname("threadnetrecv"); fd = *(int*)arg; io = ioproc(); while((n = ioread(io, fd, buf, sizeof buf)) > 0){ - unpack(buf, n, "PdPdP", - &universe->ships[0].p, &universe->ships[0].θ, - &universe->ships[1].p, &universe->ships[1].θ, - &universe->star.p); + frame = emalloc(sizeof(Frame)+(n-Framehdrsize)); + unpack(buf, n, "f", frame); + sendp(ingress, frame); } closeioproc(io); } +void +threadnetppu(void *) +{ + Frame *frame; + + threadsetname("threadnetppu"); + + while((frame = recvp(ingress)) != nil){ + switch(frame->type){ + case NSsimstate: + unpack(frame->data, frame->len, "PdPdP", + &universe->ships[0].p, &universe->ships[0].θ, + &universe->ships[1].p, &universe->ships[1].θ, + &universe->star.p); + break; + } + + free(frame); + } +} + void threadnetsend(void *arg) { uchar buf[MTU]; int fd, n; - ulong kdown; Frame *frame; - fd = *(int*)arg; - frame = emalloc(sizeof(Frame)+sizeof(kdown)); - frame->udp = nil; - frame->seq = ntruerand(1000)>>1; - frame->ack = 0; - frame->id = truerand(); - frame->len = sizeof(kdown); + threadsetname("threadnetsend"); - for(;;){ - kdown = recvul(kchan); - - frame->seq++; - - pack(frame->data, frame->len, "k", kdown); + fd = *(int*)arg; - n = pack(buf, sizeof buf, "F", frame); + while((frame = recvp(egress)) != nil){ + n = pack(buf, sizeof buf, "f", frame); + free(frame); if(write(fd, buf, n) != n) sysfatal("write: %r"); } @@ -273,7 +300,7 @@ initskymap(void) skymap = readimage(display, fd, 1); if(skymap == nil){ darkness: - fprint(2, "couldn't read a sky map. falling back to darkness...\n"); + fprint(2, "couldn't read the sky map. falling back to darkness...\n"); skymap = display->black; } close(fd); @@ -364,7 +391,6 @@ threadmain(int argc, char *argv[]) screenrf.bx = Vec2(1, 0); screenrf.by = Vec2(0,-1); - kchan = chancreate(sizeof kdown, 1); proccreate(kbdproc, nil, 4096); /* TODO: draw a CONNECTING... sign */ @@ -386,9 +412,11 @@ threadmain(int argc, char *argv[]) initskymap(); - threadcreate(threadnetrecv, &fd, 4096); - threadcreate(threadnetsend, &fd, 4096); - threadcreate(threadresize, mc, 4096); + ingress = chancreate(sizeof(Frame*), 8); + egress = chancreate(sizeof(Frame*), 8); + threadcreate(threadnetrecv, &fd, mainstacksize); + threadcreate(threadnetsend, &fd, mainstacksize); + threadcreate(threadresize, mc, mainstacksize); then = nanosec(); io = ioproc(); diff --git a/muswd.c b/muswd.c index b84436a..435d130 100644 --- a/muswd.c +++ b/muswd.c @@ -8,66 +8,99 @@ #include "fns.h" int debug; +int mainstacksize = 24*1024; -Lobby *lobby; Party theparty; +Channel *ingress; +Channel *egress; void -threadlisten(void *arg) +threadnetrecv(void *arg) { - uchar buf[MTU], *p, *e; + uchar buf[MTU]; int fd, n; - ushort rport, lport; - ulong kdown; Ioproc *io; Frame *frame; + threadsetname("threadnetrecv"); + fd = *(int*)arg; io = ioproc(); - frame = emalloc(sizeof(Frame)); while((n = ioread(io, fd, buf, sizeof buf)) > 0){ - p = buf; - e = buf+n; + frame = emalloc(sizeof(Frame)+(n-Udphdrsize-Framehdrsize)); + unpack(buf, n, "F", frame); + sendp(ingress, frame); + } + closeioproc(io); +} + +void +threadnetppu(void *) +{ + ushort rport, lport; + ulong kdown; + Frame *frame; + + threadsetname("threadnetppu"); + + while((frame = recvp(ingress)) != nil){ + rport = frame->udp.rport[0]<<8 | frame->udp.rport[1]; + lport = frame->udp.lport[0]<<8 | frame->udp.lport[1]; + + switch(frame->type){ + case NCinput: + unpack(frame->data, frame->len, "k", &kdown); + + if(debug){ + fprint(2, "%I!%d ← %I!%d | rcvd type %ud seq %ud ack %ud len %ud %.*lub\n", + frame->udp.laddr, lport, frame->udp.raddr, rport, + frame->type, frame->seq, frame->ack, frame->len, + sizeof(kdown)*8, kdown); + } + break; + } + + free(frame); + } +} + +void +threadnetsend(void *arg) +{ + uchar buf[MTU]; + int fd, n; + Frame *frame; - unpack(p, e-p, "F", frame); + threadsetname("threadnetsend"); - rport = frame->udp->rport[0]<<8 | frame->udp->rport[1]; - lport = frame->udp->lport[0]<<8 | frame->udp->lport[1]; - - unpack(frame->data, frame->len, "k", &kdown); + fd = *(int*)arg; - if(debug) - fprint(2, "%I!%d → %I!%d | %d (%d) rcvd seq %ud ack %ud id %ud len %ud %.*lub\n", - frame->udp->raddr, rport, frame->udp->laddr, lport, threadid(), getpid(), frame->seq, frame->ack, frame->id, frame->len, sizeof(kdown)*8, kdown); + while((frame = recvp(egress)) != nil){ + n = pack(buf, sizeof buf, "F", frame); + free(frame); + if(write(fd, buf, n) != n) + sysfatal("write: %r"); } - closeioproc(io); } void broadcaststate(void) { - int i, n; - uchar buf[1024]; - Player *player; + int i; + Frame *frame; +// Player *player; Party *p; for(p = theparty.next; p != &theparty; p = p->next){ - n = pack(buf, sizeof buf, "PdPdP", + frame = emalloc(sizeof(Frame)+2*(3*8+8)+3*8); + pack(frame->data, frame->len, "PdPdP", p->u->ships[0].p, p->u->ships[0].θ, p->u->ships[1].p, p->u->ships[1].θ, p->u->star.p); for(i = 0; i < nelem(p->players); i++){ - if(write(p->players[i].conn.data, buf, n) != n){ - player = &p->players[i^1]; - lobby->takeseat(lobby, player->conn.dir, player->conn.ctl, player->conn.data); - /* step back and delete the spoiled party */ - p = p->prev; - delparty(p->next); - break; - } } } @@ -79,7 +112,7 @@ threadsim(void *) uvlong then, now; double frametime, Δt; Ioproc *io; - Player couple[2]; +// Player couple[2]; Party *p; Δt = 0.01; @@ -87,12 +120,10 @@ threadsim(void *) io = ioproc(); for(;;){ - lobby->purge(lobby); - - if(lobby->getcouple(lobby, couple) != -1){ - newparty(&theparty, couple); - theparty.prev->u->reset(theparty.prev->u); - } +// if(lobby->getcouple(lobby, couple) != -1){ +// newparty(&theparty, couple); +// theparty.prev->u->reset(theparty.prev->u); +// } now = nanosec(); frametime = now - then; @@ -123,13 +154,13 @@ fprintstats(int fd) for(p = theparty.next; p != &theparty; p = p->next) nparties++; - fprint(fd, "curplayers %lud\n" - "totplayers %lud\n" - "maxplayers %lud\n" - "curparties %lud\n" - "totparties %lud\n", - lobby->nseats, (ulong)0, lobby->cap, - nparties, (ulong)0); +// fprint(fd, "curplayers %lud\n" +// "totplayers %lud\n" +// "maxplayers %lud\n" +// "curparties %lud\n" +// "totparties %lud\n", +// lobby->nseats, 0UL, lobby->cap, +// nparties, 0UL); } void @@ -232,11 +263,14 @@ threadmain(int argc, char *argv[]) if(debug) fprint(2, "listening on %s\n", addr); - lobby = newlobby(); initparty(&theparty); - threadcreate(threadC2, nil, 4096); - threadcreate(threadlisten, &adfd, 4096); - threadcreate(threadsim, nil, 4096); + ingress = chancreate(sizeof(Frame*), 32); + egress = chancreate(sizeof(Frame*), 32); + threadcreate(threadC2, nil, mainstacksize); + threadcreate(threadnetrecv, &adfd, mainstacksize); + threadcreate(threadnetppu, nil, mainstacksize); + threadcreate(threadnetsend, &adfd, mainstacksize); + threadcreate(threadsim, nil, mainstacksize); threadexits(nil); } diff --git a/pack.c b/pack.c index 3b61a66..08405ec 100644 --- a/pack.c +++ b/pack.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -37,7 +38,7 @@ vpack(uchar *p, int n, char *fmt, va_list a) ulong k; FPdbleword d; Point2 P; - Frame *F; + Frame *F = nil; for(;;){ switch(*fmt++){ @@ -74,13 +75,25 @@ vpack(uchar *p, int n, char *fmt, va_list a) case 'F': F = va_arg(a, Frame*); + if(p+Udphdrsize > e) + goto err; + + memmove(p, &F->udp, Udphdrsize), p += Udphdrsize; + /* fallthrough */ + case 'f': + if(F == nil) + F = va_arg(a, Frame*); + if(p+Framehdrsize+F->len > e) goto err; + *p++ = F->type; put4(p, F->seq), p += 4; put4(p, F->ack), p += 4; - put4(p, F->id), p += 4; put2(p, F->len), p += 2; + + if(p+F->len > e) + goto err; memmove(p, F->data, F->len), p += F->len; break; @@ -97,7 +110,7 @@ vunpack(uchar *p, int n, char *fmt, va_list a) ulong k; FPdbleword d; Point2 P; - Frame *F; + Frame *F = nil; for(;;){ switch(*fmt++){ @@ -129,24 +142,29 @@ vunpack(uchar *p, int n, char *fmt, va_list a) break; case 'F': - if(p+Udphdrsize+Framehdrsize > e) + if(p+Udphdrsize > e) goto err; F = va_arg(a, Frame*); - F->udp = (Udphdr*)p, p += Udphdrsize; + memmove(&F->udp, p, Udphdrsize), p += Udphdrsize; + /* fallthrough */ + case 'f': + if(p+Framehdrsize > e) + goto err; + + if(F == nil) + F = va_arg(a, Frame*); + + F->type = *p++; F->seq = get4(p), p += 4; F->ack = get4(p), p += 4; - F->id = get4(p), p += 4; F->len = get2(p), p += 2; - /* XXX: I'm not happy with this. */ if(p+F->len > e) goto err; - F = erealloc(F, sizeof(Frame)+F->len); - memmove(F->data, p, F->len); - p += F->len; + memmove(F->data, p, F->len), p += F->len; break; } -- cgit v1.2.3