From 7d93e491c113e7443fc951d9cddc0bb7b491e739 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Sun, 13 May 2012 19:46:49 -0400 Subject: [PATCH] accept/listen support. --- driver.c | 2 + maccept.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++ makefile.mk | 4 +- marignotti.h | 7 ++- mlisten.c | 43 ++++++++++++++++++ table.c | 8 +++- 6 files changed, 182 insertions(+), 4 deletions(-) create mode 100644 maccept.c create mode 100644 mlisten.c diff --git a/driver.c b/driver.c index 7b55d83..4e81a43 100644 --- a/driver.c +++ b/driver.c @@ -69,6 +69,7 @@ int driver( break; case PRU_ACCEPT: + return maccept(e, p1, p2, p3, p4, p5); break; case PRU_ATTACH: @@ -112,6 +113,7 @@ int driver( break; case PRU_LISTEN: + return mlisten(e, p1, p2, p3, p4, p5); break; case PRU_PEERADDR: diff --git a/maccept.c b/maccept.c new file mode 100644 index 0000000..b0882f8 --- /dev/null +++ b/maccept.c @@ -0,0 +1,122 @@ +#include "marignotti.h" +#include +#include +#include + + +#include "s16debug.h" + + +static int sock_accept( + Entry *e, + int *newfd, + selwakeupfx fx, + xsockaddr_in *addr, + int *addrlen) +{ + int ipid; + Word t; + Entry *child; + + IncBusy(); + ipid = TCPIPAcceptTCP(e->ipid, 0); + t = _toolErr; + DecBusy(); + + if (t == terrNOINCOMING) return EAGAIN; + if (t == terrNOTSERVER) return EINVAL; + if (t) return ENETDOWN; // ? + + child = create_entry(ipid); + if (!child) + { + TCPIPAbortTCP(ipid); + TCPIPLogout(ipid); + return ENOMEM; + } + + // set up child options. + child->_TYPE = SOCK_STREAM; + child->select_fx = fx; + + // address... + if (addr && addrlen) + { + if (*addrlen >= 8) + { + destRec dr; + Word port; + + IncBusy(); + TCPIPGetDestination(ipid, &dr); + DecBusy(); + + port = dr.drDestPort; + + asm { + lda sin_port = port; + addr->sin_addr = dr.drDestIP; + addr->sin_family = AF_INET; + + *addrlen = 8; + } + else + { + *addrlen = 0; + } + + } + + *newfd = ipid; + return 0; +} + +int maccept(Entry *e, void *p1, void *p2, void *p3, void *p4, void *p5) +{ + int t; + Word ipid; + int xerrno; + + int *newfd = (int *)p1; + selwakeupfx fx = (selwakeupfx)p2; + xsockaddr_in *addr = (xsockaddr_in *)p3; + int *addrlen = (int *)p4; + + + if (Debug > 0) + { + s16_debug_printf("accept"); + } + + + if (e->_TYPE != SOCK_STREAM) return EOPNOTSUPP; + + + xerrno = sock_accept(e, newfd, fx, addr, addrlen); + + if (xerrno != EAGAIN || e->_NONBLOCK) + { + return xerrno; + } + + + for (;;) + { + xerrno = queue_command(e, kCommandAccept, 0, 0); + if (xerrno == EINTR) return EINTR; + if (xerrno) return EIO; + + if (e->command) continue; // reset to 0 if processed. + + xerrno = sock_accept(e, newfd, fx, addr, addrlen); + + if (xerrno != EAGAIN) return xerrno; + } + + + return 0; +} \ No newline at end of file diff --git a/makefile.mk b/makefile.mk index 68f05a2..5012d7e 100644 --- a/makefile.mk +++ b/makefile.mk @@ -2,7 +2,7 @@ CFLAGS += $(DEFINES) -v -w OBJS = main.o table.o driver.o s16debug.o \ mattach.o mconnect.o mread.o mwrite.o mdetach.o \ mioctl.o mshutdown.o mgetsockopt.o msetsockopt.o \ -mgetsockname.o mselect.o +mgetsockname.o mselect.o maccept.o mlisten.o TARGET = marignotti @@ -27,6 +27,8 @@ mshutdown.o: mshutdown.c marignotti.h mioctl.o: mioctl.c marignotti.h mgetsockname.o: mgetsockname.c marignotti.h mselect.o: mselect.c marignotti.h +mlisten.o: mlisten.c marignotti.h +maccept.o: maccept.c marignotti.h clean: $(RM) *.o *.root diff --git a/marignotti.h b/marignotti.h index c7fae06..5092327 100644 --- a/marignotti.h +++ b/marignotti.h @@ -7,9 +7,10 @@ enum { kCommandConnect, kCommandDisconnect, kCommandDisconnectAndLogout, + kCommandAbortAndLogout, kCommandRead, kCommandWrite, - kCommandAbortAndLogout + kCommandAccept }; typedef void (*selwakeupfx)(int collision, int pid); @@ -116,7 +117,6 @@ int mdisconnect(Entry *, void *p1, void *p2, void *p3, void *p4, void *p5); int mshutdown(Entry *, void *p1, void *p2, void *p3, void *p4, void *p5); - int mgetsockopt(Entry *, void *p1, void *p2, void *p3, void *p4, void *p5); int msetsockopt(Entry *, void *p1, void *p2, void *p3, void *p4, void *p5); @@ -124,6 +124,9 @@ int mioctl(Entry *, void *p1, void *p2, void *p3, void *p4, void *p5); int mgetsockname(Entry *, void *p1, void *p2, void *p3, void *p4, void *p5); int mselect(Entry *, void *p1, void *p2, void *p3, void *p4, void *p5); +int maccept(Entry *e, void *p1, void *p2, void *p3, void *p4, void *p5); +int mlisten(Entry *e, void *p1, void *p2, void *p3, void *p4, void *p5); + diff --git a/mlisten.c b/mlisten.c new file mode 100644 index 0000000..2b33a68 --- /dev/null +++ b/mlisten.c @@ -0,0 +1,43 @@ +#include "marignotti.h" +#include +#include +#include + +#include + +#include "s16debug.h" + + +#pragma noroot +#pragma optimize 79 + +int mlisten(Entry *e, void *p1, void *p2, void *p3, void *p4, void *p5) +{ + Word terr; + Word t; + + int backlog = p1 ? *(int *)p1 : 0; + + if (Debug > 0) + { + s16_debug_printf("listen backlog = %d", backlog); + } + + + if (e->_TYPE != SOCK_STREAM) + return EOPNOTSUPP; + + IncBusy(); + terr = TCPIPListenTCP(e->ipid); + t = _toolErr; + if (t) terr = t; + DecBusy(); + + if (t) return ENETDOWN; + + // not in TCPSCLOSED state. + if (terr = tcperrConExists) return EINVAL; + if (terr) return EINVAL; // other errors? + + return 0; +} \ No newline at end of file diff --git a/table.c b/table.c index 4695be0..2f088ab 100644 --- a/table.c +++ b/table.c @@ -227,7 +227,13 @@ void process_table(void) sig = 1; } break; - + + case kCommandAccept: + if (e->sr.srAcceptCount > 0) + { + sig = 1; + } + break; case kCommandConnect: // block until connection established.