github.com/tetratelabs/wazero@v1.2.1/internal/sock/sock.go (about) 1 package sock 2 3 import ( 4 "fmt" 5 "net" 6 "syscall" 7 8 "github.com/tetratelabs/wazero/internal/fsapi" 9 ) 10 11 // TCPSock is a pseudo-file representing a TCP socket. 12 type TCPSock interface { 13 fsapi.File 14 15 Accept() (TCPConn, syscall.Errno) 16 } 17 18 // TCPConn is a pseudo-file representing a TCP connection. 19 type TCPConn interface { 20 fsapi.File 21 22 // Recvfrom only supports the flag sysfs.MSG_PEEK 23 Recvfrom(p []byte, flags int) (n int, errno syscall.Errno) 24 25 Shutdown(how int) syscall.Errno 26 } 27 28 // ConfigKey is a context.Context Value key. Its associated value should be a Config. 29 type ConfigKey struct{} 30 31 // Config is an internal struct meant to implement 32 // the interface in experimental/sock/Config. 33 type Config struct { 34 // TCPAddresses is a slice of the configured host:port pairs. 35 TCPAddresses []TCPAddress 36 } 37 38 // TCPAddress is a host:port pair to pre-open. 39 type TCPAddress struct { 40 // Host is the host name for this listener. 41 Host string 42 // Port is the port number for this listener. 43 Port int 44 } 45 46 // WithTCPListener implements the method of the same name in experimental/sock/Config. 47 // 48 // However, to avoid cyclic dependencies, this is returning the *Config in this scope. 49 // The interface is implemented in experimental/sock/Config via delegation. 50 func (c *Config) WithTCPListener(host string, port int) *Config { 51 ret := c.clone() 52 ret.TCPAddresses = append(ret.TCPAddresses, TCPAddress{host, port}) 53 return &ret 54 } 55 56 // Makes a deep copy of this sockConfig. 57 func (c *Config) clone() Config { 58 ret := *c 59 ret.TCPAddresses = make([]TCPAddress, 0, len(c.TCPAddresses)) 60 ret.TCPAddresses = append(ret.TCPAddresses, c.TCPAddresses...) 61 return ret 62 } 63 64 // BuildTCPListeners build listeners from the current configuration. 65 func (c *Config) BuildTCPListeners() (tcpListeners []*net.TCPListener, err error) { 66 for _, tcpAddr := range c.TCPAddresses { 67 var ln net.Listener 68 ln, err = net.Listen("tcp", tcpAddr.String()) 69 if err != nil { 70 break 71 } 72 if tcpln, ok := ln.(*net.TCPListener); ok { 73 tcpListeners = append(tcpListeners, tcpln) 74 } 75 } 76 if err != nil { 77 // An error occurred, cleanup. 78 for _, l := range tcpListeners { 79 _ = l.Close() // Ignore errors, we are already cleaning. 80 } 81 tcpListeners = nil 82 } 83 return 84 } 85 86 func (t TCPAddress) String() string { 87 return fmt.Sprintf("%s:%d", t.Host, t.Port) 88 }