// Utility to open a tcp[46]? or fd func ListenFile(rawurl string) (file *os.File, err error) { if socketMasterFd := os.Getenv("SOCKETMASTER_FD"); socketMasterFd != "" { os.Setenv("SOCKETMASTER_FD", "") rawurl = fmt.Sprintf("fd://%s", socketMasterFd) } u, err := url.Parse(rawurl) if err != nil { return } switch u.Scheme { case "fd": var fd uint64 fd, err = strconv.ParseUint(u.Host, 10, 8) if err != nil { return } // NOTE: The name argument doesn't really matter apparently file = os.NewFile(uintptr(fd), fmt.Sprintf("fd://%d", fd)) case "unix": //, "unixpacket", "unixgram": var laddr *net.UnixAddr var listener *net.UnixListener laddr, err = net.ResolveUnixAddr(u.Scheme, u.Path) if err != nil { return } listener, err = net.ListenUnix(u.Scheme, laddr) if err != nil { return } file, err = listener.File() case "tcp", "tcp4", "tcp6": var laddr *net.TCPAddr var listener *net.TCPListener laddr, err = net.ResolveTCPAddr(u.Scheme, u.Host) if err != nil { return } listener, err = net.ListenTCP(u.Scheme, laddr) if err != nil { return } // Closing the listener doesn't affect the file and reversely. // http://golang.org/pkg/net/#TCPListener.File file, err = listener.File() default: err = fmt.Errorf("Unsupported scheme: %s", u.Scheme) } return }
func NewAuthenticatedFileSocket(sock *net.UnixListener) error { sockFile, err := sock.File() if err != nil { return err } sockFile.Close() return nil }
func NewAuthenticatedFileSocket(sock *net.UnixListener) error { sockFile, err := sock.File() if err != nil { return err } err = syscall.SetsockoptInt(int(sockFile.Fd()), syscall.SOL_SOCKET, syscall.SO_PASSCRED, 1) sockFile.Close() return err }
// Serve listens on sock for new connections and services them. func (server LinuxHostAdminServer) Serve(sock *net.UnixListener) error { defer RecoverTPMResources() // Set the socket to allow peer credentials to be passed sockFile, err := sock.File() if err != nil { return err } err = syscall.SetsockoptInt(int(sockFile.Fd()), syscall.SOL_SOCKET, syscall.SO_PASSCRED, 1 /* true */) sockFile.Close() if err != nil { return err } connections := make(chan *net.UnixConn, 1) errors := make(chan error, 1) go func() { defer RecoverTPMResources() for { conn, err := sock.AcceptUnix() if err != nil { errors <- err break } connections <- conn } }() for { var conn *net.UnixConn select { case conn = <-connections: break case err = <-errors: return err case <-server.Done: return nil } s := rpc.NewServer() oob := util.NewOOBUnixConn(conn) err = s.RegisterName("LinuxHost", linuxHostAdminServerStub{oob, server.lh, server.Done}) if err != nil { return err } go func() { defer RecoverTPMResources() s.ServeCodec(protorpc.NewServerCodec(oob)) }() } }