Files
MIT6.828_OS/lab/lib/nsipc.c
2019-07-17 16:08:06 +08:00

124 lines
2.7 KiB
C

#include <inc/ns.h>
#include <inc/lib.h>
#include <lwip/sockets.h>
#define debug 0
// Virtual address at which to receive page mappings containing client requests.
#define REQVA 0x0ffff000
union Nsipc nsipcbuf __attribute__((aligned(PGSIZE)));
// Send an IP request to the network server, and wait for a reply.
// The request body should be in nsipcbuf, and parts of the response
// may be written back to nsipcbuf.
// type: request code, passed as the simple integer IPC value.
// Returns 0 if successful, < 0 on failure.
static int
nsipc(unsigned type)
{
static envid_t nsenv;
if (nsenv == 0)
nsenv = ipc_find_env(ENV_TYPE_NS);
static_assert(sizeof(nsipcbuf) == PGSIZE);
if (debug)
cprintf("[%08x] nsipc %d\n", thisenv->env_id, type);
ipc_send(nsenv, type, &nsipcbuf, PTE_P|PTE_W|PTE_U);
return ipc_recv(NULL, NULL, NULL);
}
int
nsipc_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
{
int r;
nsipcbuf.accept.req_s = s;
nsipcbuf.accept.req_addrlen = *addrlen;
if ((r = nsipc(NSREQ_ACCEPT)) >= 0) {
struct Nsret_accept *ret = &nsipcbuf.acceptRet;
memmove(addr, &ret->ret_addr, ret->ret_addrlen);
*addrlen = ret->ret_addrlen;
}
return r;
}
int
nsipc_bind(int s, struct sockaddr *name, socklen_t namelen)
{
nsipcbuf.bind.req_s = s;
memmove(&nsipcbuf.bind.req_name, name, namelen);
nsipcbuf.bind.req_namelen = namelen;
return nsipc(NSREQ_BIND);
}
int
nsipc_shutdown(int s, int how)
{
nsipcbuf.shutdown.req_s = s;
nsipcbuf.shutdown.req_how = how;
return nsipc(NSREQ_SHUTDOWN);
}
int
nsipc_close(int s)
{
nsipcbuf.close.req_s = s;
return nsipc(NSREQ_CLOSE);
}
int
nsipc_connect(int s, const struct sockaddr *name, socklen_t namelen)
{
nsipcbuf.connect.req_s = s;
memmove(&nsipcbuf.connect.req_name, name, namelen);
nsipcbuf.connect.req_namelen = namelen;
return nsipc(NSREQ_CONNECT);
}
int
nsipc_listen(int s, int backlog)
{
nsipcbuf.listen.req_s = s;
nsipcbuf.listen.req_backlog = backlog;
return nsipc(NSREQ_LISTEN);
}
int
nsipc_recv(int s, void *mem, int len, unsigned int flags)
{
int r;
nsipcbuf.recv.req_s = s;
nsipcbuf.recv.req_len = len;
nsipcbuf.recv.req_flags = flags;
if ((r = nsipc(NSREQ_RECV)) >= 0) {
assert(r < 1600 && r <= len);
memmove(mem, nsipcbuf.recvRet.ret_buf, r);
}
return r;
}
int
nsipc_send(int s, const void *buf, int size, unsigned int flags)
{
nsipcbuf.send.req_s = s;
assert(size < 1600);
memmove(&nsipcbuf.send.req_buf, buf, size);
nsipcbuf.send.req_size = size;
nsipcbuf.send.req_flags = flags;
return nsipc(NSREQ_SEND);
}
int
nsipc_socket(int domain, int type, int protocol)
{
nsipcbuf.socket.req_domain = domain;
nsipcbuf.socket.req_type = type;
nsipcbuf.socket.req_protocol = protocol;
return nsipc(NSREQ_SOCKET);
}