diff options
Diffstat (limited to 'src/pkg/syscall/net_nacl.go')
-rw-r--r-- | src/pkg/syscall/net_nacl.go | 912 |
1 files changed, 0 insertions, 912 deletions
diff --git a/src/pkg/syscall/net_nacl.go b/src/pkg/syscall/net_nacl.go deleted file mode 100644 index b9488f48d..000000000 --- a/src/pkg/syscall/net_nacl.go +++ /dev/null @@ -1,912 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// A simulated network for use within NaCl. -// The simulation is not particularly tied to NaCl, -// but other systems have real networks. - -package syscall - -import ( - "sync" - "sync/atomic" -) - -// Interface to timers implemented in package runtime. -// Must be in sync with ../runtime/runtime.h:/^struct.Timer$ -// Really for use by package time, but we cannot import time here. - -type runtimeTimer struct { - i int32 - when int64 - period int64 - f func(int64, interface{}) // NOTE: must not be closure - arg interface{} -} - -func startTimer(*runtimeTimer) -func stopTimer(*runtimeTimer) bool - -type timer struct { - expired bool - q *queue - r runtimeTimer -} - -func (t *timer) start(q *queue, deadline int64) { - if deadline == 0 { - return - } - t.q = q - t.r.when = deadline - t.r.f = timerExpired - t.r.arg = t - startTimer(&t.r) -} - -func (t *timer) stop() { - stopTimer(&t.r) -} - -func timerExpired(now int64, i interface{}) { - t := i.(*timer) - go func() { - t.q.Lock() - defer t.q.Unlock() - t.expired = true - t.q.canRead.Broadcast() - t.q.canWrite.Broadcast() - }() -} - -// Network constants and data structures. These match the traditional values. - -const ( - AF_UNSPEC = iota - AF_UNIX - AF_INET - AF_INET6 -) - -const ( - SHUT_RD = iota - SHUT_WR - SHUT_RDWR -) - -const ( - SOCK_STREAM = 1 + iota - SOCK_DGRAM - SOCK_RAW - SOCK_SEQPACKET -) - -const ( - IPPROTO_IP = 0 - IPPROTO_IPV4 = 4 - IPPROTO_IPV6 = 0x29 - IPPROTO_TCP = 6 - IPPROTO_UDP = 0x11 -) - -// Misc constants expected by package net but not supported. -const ( - _ = iota - SOL_SOCKET - SO_TYPE - NET_RT_IFLIST - IFNAMSIZ - IFF_UP - IFF_BROADCAST - IFF_LOOPBACK - IFF_POINTOPOINT - IFF_MULTICAST - IPV6_V6ONLY - SOMAXCONN - F_DUPFD_CLOEXEC - SO_BROADCAST - SO_REUSEADDR - SO_REUSEPORT - SO_RCVBUF - SO_SNDBUF - SO_KEEPALIVE - SO_LINGER - SO_ERROR - IP_PORTRANGE - IP_PORTRANGE_DEFAULT - IP_PORTRANGE_LOW - IP_PORTRANGE_HIGH - IP_MULTICAST_IF - IP_MULTICAST_LOOP - IP_ADD_MEMBERSHIP - IPV6_PORTRANGE - IPV6_PORTRANGE_DEFAULT - IPV6_PORTRANGE_LOW - IPV6_PORTRANGE_HIGH - IPV6_MULTICAST_IF - IPV6_MULTICAST_LOOP - IPV6_JOIN_GROUP - TCP_NODELAY - TCP_KEEPINTVL - TCP_KEEPIDLE - - SYS_FCNTL = 500 // unsupported -) - -var SocketDisableIPv6 bool - -// A Sockaddr is one of the SockaddrXxx structs. -type Sockaddr interface { - // copy returns a copy of the underlying data. - copy() Sockaddr - - // key returns the value of the underlying data, - // for comparison as a map key. - key() interface{} -} - -type SockaddrInet4 struct { - Port int - Addr [4]byte -} - -func (sa *SockaddrInet4) copy() Sockaddr { - sa1 := *sa - return &sa1 -} - -func (sa *SockaddrInet4) key() interface{} { return *sa } - -type SockaddrInet6 struct { - Port int - ZoneId uint32 - Addr [16]byte -} - -func (sa *SockaddrInet6) copy() Sockaddr { - sa1 := *sa - return &sa1 -} - -func (sa *SockaddrInet6) key() interface{} { return *sa } - -type SockaddrUnix struct { - Name string -} - -func (sa *SockaddrUnix) copy() Sockaddr { - sa1 := *sa - return &sa1 -} - -func (sa *SockaddrUnix) key() interface{} { return *sa } - -type SockaddrDatalink struct { - Len uint8 - Family uint8 - Index uint16 - Type uint8 - Nlen uint8 - Alen uint8 - Slen uint8 - Data [12]int8 -} - -func (sa *SockaddrDatalink) copy() Sockaddr { - sa1 := *sa - return &sa1 -} - -func (sa *SockaddrDatalink) key() interface{} { return *sa } - -// RoutingMessage represents a routing message. -type RoutingMessage interface { - unimplemented() -} - -type IPMreq struct { - Multiaddr [4]byte /* in_addr */ - Interface [4]byte /* in_addr */ -} - -type IPv6Mreq struct { - Multiaddr [16]byte /* in6_addr */ - Interface uint32 -} - -type Linger struct { - Onoff int32 - Linger int32 -} - -type ICMPv6Filter struct { - Filt [8]uint32 -} - -// A queue is the bookkeeping for a synchronized buffered queue. -// We do not use channels because we need to be able to handle -// writes after and during close, and because a chan byte would -// require too many send and receive operations in real use. -type queue struct { - sync.Mutex - canRead sync.Cond - canWrite sync.Cond - r int // total read index - w int // total write index - m int // index mask - closed bool -} - -func (q *queue) init(size int) { - if size&(size-1) != 0 { - panic("invalid queue size - must be power of two") - } - q.canRead.L = &q.Mutex - q.canWrite.L = &q.Mutex - q.m = size - 1 -} - -func past(deadline int64) bool { - sec, nsec := now() - return deadline > 0 && deadline < sec*1e9+int64(nsec) -} - -func (q *queue) waitRead(n int, deadline int64) (int, error) { - if past(deadline) { - return 0, EAGAIN - } - var t timer - t.start(q, deadline) - for q.w-q.r == 0 && !q.closed && !t.expired { - q.canRead.Wait() - } - t.stop() - m := q.w - q.r - if m == 0 && t.expired { - return 0, EAGAIN - } - if m > n { - m = n - q.canRead.Signal() // wake up next reader too - } - q.canWrite.Signal() - return m, nil -} - -func (q *queue) waitWrite(n int, deadline int64) (int, error) { - if past(deadline) { - return 0, EAGAIN - } - var t timer - t.start(q, deadline) - for q.w-q.r > q.m && !q.closed && !t.expired { - q.canWrite.Wait() - } - t.stop() - m := q.m + 1 - (q.w - q.r) - if m == 0 && t.expired { - return 0, EAGAIN - } - if m == 0 { - return 0, EAGAIN - } - if m > n { - m = n - q.canWrite.Signal() // wake up next writer too - } - q.canRead.Signal() - return m, nil -} - -func (q *queue) close() { - q.Lock() - defer q.Unlock() - q.closed = true - q.canRead.Broadcast() - q.canWrite.Broadcast() -} - -// A byteq is a byte queue. -type byteq struct { - queue - data []byte -} - -func newByteq() *byteq { - q := &byteq{ - data: make([]byte, 4096), - } - q.init(len(q.data)) - return q -} - -func (q *byteq) read(b []byte, deadline int64) (int, error) { - q.Lock() - defer q.Unlock() - n, err := q.waitRead(len(b), deadline) - if err != nil { - return 0, err - } - b = b[:n] - for len(b) > 0 { - m := copy(b, q.data[q.r&q.m:]) - q.r += m - b = b[m:] - } - return n, nil -} - -func (q *byteq) write(b []byte, deadline int64) (n int, err error) { - q.Lock() - defer q.Unlock() - for n < len(b) { - nn, err := q.waitWrite(len(b[n:]), deadline) - if err != nil { - return n, err - } - bb := b[n : n+nn] - n += nn - for len(bb) > 0 { - m := copy(q.data[q.w&q.m:], bb) - q.w += m - bb = bb[m:] - } - } - return n, nil -} - -// A msgq is a queue of messages. -type msgq struct { - queue - data []interface{} -} - -func newMsgq() *msgq { - q := &msgq{ - data: make([]interface{}, 32), - } - q.init(len(q.data)) - return q -} - -func (q *msgq) read(deadline int64) (interface{}, error) { - q.Lock() - defer q.Unlock() - n, err := q.waitRead(1, deadline) - if err != nil { - return nil, err - } - if n == 0 { - return nil, nil - } - m := q.data[q.r&q.m] - q.r++ - return m, nil -} - -func (q *msgq) write(m interface{}, deadline int64) error { - q.Lock() - defer q.Unlock() - _, err := q.waitWrite(1, deadline) - if err != nil { - return err - } - q.data[q.w&q.m] = m - q.w++ - return nil -} - -// An addr is a sequence of bytes uniquely identifying a network address. -// It is not human-readable. -type addr string - -// A conn is one side of a stream-based network connection. -// That is, a stream-based network connection is a pair of cross-connected conns. -type conn struct { - rd *byteq - wr *byteq - local addr - remote addr -} - -// A pktconn is one side of a packet-based network connection. -// That is, a packet-based network connection is a pair of cross-connected pktconns. -type pktconn struct { - rd *msgq - wr *msgq - local addr - remote addr -} - -// A listener accepts incoming stream-based network connections. -type listener struct { - rd *msgq - local addr -} - -// A netFile is an open network file. -type netFile struct { - defaultFileImpl - proto *netproto - sotype int - listener *msgq - packet *msgq - rd *byteq - wr *byteq - rddeadline int64 - wrdeadline int64 - addr Sockaddr - raddr Sockaddr -} - -// A netAddr is a network address in the global listener map. -// All the fields must have defined == operations. -type netAddr struct { - proto *netproto - sotype int - addr interface{} -} - -// net records the state of the network. -// It maps a network address to the listener on that address. -var net = struct { - sync.Mutex - listener map[netAddr]*netFile -}{ - listener: make(map[netAddr]*netFile), -} - -// TODO(rsc): Some day, do a better job with port allocation. -// For playground programs, incrementing is fine. -var nextport = 2 - -// A netproto contains protocol-specific functionality -// (one for AF_INET, one for AF_INET6 and so on). -// It is a struct instead of an interface because the -// implementation needs no state, and I expect to -// add some data fields at some point. -type netproto struct { - bind func(*netFile, Sockaddr) error -} - -var netprotoAF_INET = &netproto{ - bind: func(f *netFile, sa Sockaddr) error { - if sa == nil { - f.addr = &SockaddrInet4{ - Port: nextport, - Addr: [4]byte{127, 0, 0, 1}, - } - nextport++ - return nil - } - addr, ok := sa.(*SockaddrInet4) - if !ok { - return EINVAL - } - addr = addr.copy().(*SockaddrInet4) - if addr.Port == 0 { - addr.Port = nextport - nextport++ - } - f.addr = addr - return nil - }, -} - -var netprotos = map[int]*netproto{ - AF_INET: netprotoAF_INET, -} - -// These functions implement the usual BSD socket operations. - -func (f *netFile) bind(sa Sockaddr) error { - if f.addr != nil { - return EISCONN - } - if err := f.proto.bind(f, sa); err != nil { - return err - } - if f.sotype == SOCK_DGRAM { - _, ok := net.listener[netAddr{f.proto, f.sotype, f.addr.key()}] - if ok { - f.addr = nil - return EADDRINUSE - } - net.listener[netAddr{f.proto, f.sotype, f.addr.key()}] = f - f.packet = newMsgq() - } - return nil -} - -func (f *netFile) listen(backlog int) error { - net.Lock() - defer net.Unlock() - if f.listener != nil { - return EINVAL - } - _, ok := net.listener[netAddr{f.proto, f.sotype, f.addr.key()}] - if ok { - return EADDRINUSE - } - net.listener[netAddr{f.proto, f.sotype, f.addr.key()}] = f - f.listener = newMsgq() - return nil -} - -func (f *netFile) accept() (fd int, sa Sockaddr, err error) { - msg, err := f.listener.read(f.readDeadline()) - if err != nil { - return -1, nil, err - } - newf, ok := msg.(*netFile) - if !ok { - // must be eof - return -1, nil, EAGAIN - } - return newFD(newf), newf.raddr.copy(), nil -} - -func (f *netFile) connect(sa Sockaddr) error { - if past(f.writeDeadline()) { - return EAGAIN - } - if f.addr == nil { - if err := f.bind(nil); err != nil { - return err - } - } - net.Lock() - if sa == nil { - net.Unlock() - return EINVAL - } - sa = sa.copy() - if f.raddr != nil { - net.Unlock() - return EISCONN - } - if f.sotype == SOCK_DGRAM { - net.Unlock() - f.raddr = sa - return nil - } - if f.listener != nil { - net.Unlock() - return EISCONN - } - l, ok := net.listener[netAddr{f.proto, f.sotype, sa.key()}] - if !ok { - net.Unlock() - return ECONNREFUSED - } - f.raddr = sa - f.rd = newByteq() - f.wr = newByteq() - newf := &netFile{ - proto: f.proto, - sotype: f.sotype, - addr: f.raddr, - raddr: f.addr, - rd: f.wr, - wr: f.rd, - } - net.Unlock() - l.listener.write(newf, f.writeDeadline()) - return nil -} - -func (f *netFile) read(b []byte) (int, error) { - if f.rd == nil { - if f.raddr != nil { - n, _, err := f.recvfrom(b, 0) - return n, err - } - return 0, ENOTCONN - } - return f.rd.read(b, f.readDeadline()) -} - -func (f *netFile) write(b []byte) (int, error) { - if f.wr == nil { - if f.raddr != nil { - err := f.sendto(b, 0, f.raddr) - var n int - if err == nil { - n = len(b) - } - return n, err - } - return 0, ENOTCONN - } - return f.wr.write(b, f.writeDeadline()) -} - -type pktmsg struct { - buf []byte - addr Sockaddr -} - -func (f *netFile) recvfrom(p []byte, flags int) (n int, from Sockaddr, err error) { - if f.sotype != SOCK_DGRAM { - return 0, nil, EINVAL - } - if f.packet == nil { - return 0, nil, ENOTCONN - } - msg1, err := f.packet.read(f.readDeadline()) - if err != nil { - return 0, nil, err - } - msg, ok := msg1.(*pktmsg) - if !ok { - return 0, nil, EAGAIN - } - return copy(p, msg.buf), msg.addr, nil -} - -func (f *netFile) sendto(p []byte, flags int, to Sockaddr) error { - if f.sotype != SOCK_DGRAM { - return EINVAL - } - if f.packet == nil { - if err := f.bind(nil); err != nil { - return err - } - } - net.Lock() - if to == nil { - net.Unlock() - return EINVAL - } - to = to.copy() - l, ok := net.listener[netAddr{f.proto, f.sotype, to.key()}] - if !ok || l.packet == nil { - net.Unlock() - return ECONNREFUSED - } - net.Unlock() - msg := &pktmsg{ - buf: make([]byte, len(p)), - addr: f.addr, - } - copy(msg.buf, p) - l.packet.write(msg, f.writeDeadline()) - return nil -} - -func (f *netFile) close() error { - if f.listener != nil { - f.listener.close() - } - if f.packet != nil { - f.packet.close() - } - if f.rd != nil { - f.rd.close() - } - if f.wr != nil { - f.wr.close() - } - return nil -} - -func fdToNetFile(fd int) (*netFile, error) { - f, err := fdToFile(fd) - if err != nil { - return nil, err - } - impl := f.impl - netf, ok := impl.(*netFile) - if !ok { - return nil, EINVAL - } - return netf, nil -} - -func Socket(proto, sotype, unused int) (fd int, err error) { - p := netprotos[proto] - if p == nil { - return -1, EPROTONOSUPPORT - } - if sotype != SOCK_STREAM && sotype != SOCK_DGRAM { - return -1, ESOCKTNOSUPPORT - } - f := &netFile{ - proto: p, - sotype: sotype, - } - return newFD(f), nil -} - -func Bind(fd int, sa Sockaddr) error { - f, err := fdToNetFile(fd) - if err != nil { - return err - } - return f.bind(sa) -} - -func StopIO(fd int) error { - f, err := fdToNetFile(fd) - if err != nil { - return err - } - f.close() - return nil -} - -func Listen(fd int, backlog int) error { - f, err := fdToNetFile(fd) - if err != nil { - return err - } - return f.listen(backlog) -} - -func Accept(fd int) (newfd int, sa Sockaddr, err error) { - f, err := fdToNetFile(fd) - if err != nil { - return 0, nil, err - } - return f.accept() -} - -func Getsockname(fd int) (sa Sockaddr, err error) { - f, err := fdToNetFile(fd) - if err != nil { - return nil, err - } - if f.addr == nil { - return nil, ENOTCONN - } - return f.addr.copy(), nil -} - -func Getpeername(fd int) (sa Sockaddr, err error) { - f, err := fdToNetFile(fd) - if err != nil { - return nil, err - } - if f.raddr == nil { - return nil, ENOTCONN - } - return f.raddr.copy(), nil -} - -func Connect(fd int, sa Sockaddr) error { - f, err := fdToNetFile(fd) - if err != nil { - return err - } - return f.connect(sa) -} - -func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) { - f, err := fdToNetFile(fd) - if err != nil { - return 0, nil, err - } - return f.recvfrom(p, flags) -} - -func Sendto(fd int, p []byte, flags int, to Sockaddr) error { - f, err := fdToNetFile(fd) - if err != nil { - return err - } - return f.sendto(p, flags, to) -} - -func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn, recvflags int, from Sockaddr, err error) { - f, err := fdToNetFile(fd) - if err != nil { - return - } - n, from, err = f.recvfrom(p, flags) - return -} - -func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) error { - _, err := SendmsgN(fd, p, oob, to, flags) - return err -} - -func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) { - f, err := fdToNetFile(fd) - if err != nil { - return 0, err - } - switch f.sotype { - case SOCK_STREAM: - n, err = f.write(p) - case SOCK_DGRAM: - n = len(p) - err = f.sendto(p, flags, to) - } - if err != nil { - return 0, err - } - return n, nil -} - -func GetsockoptInt(fd, level, opt int) (value int, err error) { - f, err := fdToNetFile(fd) - if err != nil { - return 0, err - } - switch { - case level == SOL_SOCKET && opt == SO_TYPE: - return f.sotype, nil - } - return 0, ENOTSUP -} - -func SetsockoptInt(fd, level, opt int, value int) error { - return nil -} - -func SetsockoptByte(fd, level, opt int, value byte) error { - _, err := fdToNetFile(fd) - if err != nil { - return err - } - return ENOTSUP -} - -func SetsockoptLinger(fd, level, opt int, l *Linger) error { - return nil -} - -func SetReadDeadline(fd int, t int64) error { - f, err := fdToNetFile(fd) - if err != nil { - return err - } - atomic.StoreInt64(&f.rddeadline, t) - return nil -} - -func (f *netFile) readDeadline() int64 { - return atomic.LoadInt64(&f.rddeadline) -} - -func SetWriteDeadline(fd int, t int64) error { - f, err := fdToNetFile(fd) - if err != nil { - return err - } - atomic.StoreInt64(&f.wrdeadline, t) - return nil -} - -func (f *netFile) writeDeadline() int64 { - return atomic.LoadInt64(&f.wrdeadline) -} - -func Shutdown(fd int, how int) error { - f, err := fdToNetFile(fd) - if err != nil { - return err - } - switch how { - case SHUT_RD: - f.rd.close() - case SHUT_WR: - f.wr.close() - case SHUT_RDWR: - f.rd.close() - f.wr.close() - } - return nil -} - -func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error { panic("SetsockoptICMPv") } -func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) error { panic("SetsockoptIPMreq") } -func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) error { panic("SetsockoptIPv") } -func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) error { panic("SetsockoptInet") } -func SetsockoptString(fd, level, opt int, s string) error { panic("SetsockoptString") } -func SetsockoptTimeval(fd, level, opt int, tv *Timeval) error { panic("SetsockoptTimeval") } -func Socketpair(domain, typ, proto int) (fd [2]int, err error) { panic("Socketpair") } - -func SetNonblock(fd int, nonblocking bool) error { return nil } |