| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912 |
- // 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 unix
- 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 }
|