accept/listen support.

This commit is contained in:
Kelvin Sherlock 2012-05-13 19:46:49 -04:00
parent 7bd4d900c7
commit 7d93e491c1
6 changed files with 182 additions and 4 deletions

View File

@ -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:

122
maccept.c Normal file
View File

@ -0,0 +1,122 @@
#include "marignotti.h"
#include <gno/kerntool.h>
#include <errno.h>
#include <sys/socket.h>
#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 <port
xba
sta <port
}
addr->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;
}

View File

@ -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

View File

@ -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);

43
mlisten.c Normal file
View File

@ -0,0 +1,43 @@
#include "marignotti.h"
#include <gno/kerntool.h>
#include <errno.h>
#include <string.h>
#include <sys/socket.h>
#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;
}

View File

@ -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.