func listenTo(bind string) (net.Listener, error) { if strings.Contains(bind, ":") { return net.Listen("tcp", bind) } else if strings.HasPrefix(bind, ".") || strings.HasPrefix(bind, "/") { return net.Listen("unix", bind) } else if strings.HasPrefix(bind, "fd@") { fd, err := strconv.Atoi(bind[3:]) if err != nil { return nil, fmt.Errorf("error while parsing fd %v: %v", bind, err) } f := os.NewFile(uintptr(fd), bind) defer f.Close() return net.FileListener(f) } else if strings.HasPrefix(bind, "einhorn@") { fd, err := strconv.Atoi(bind[8:]) if err != nil { return nil, fmt.Errorf( "error while parsing einhorn %v: %v", bind, err) } return einhornBind(fd) } return nil, fmt.Errorf("error while parsing bind arg %v", bind) }
func listenStream(netw, addr string) (l net.Listener, err error) { var ( file *os.File ) fd, err := listen(netw, addr) if err != nil { return nil, err } // Set backlog size to the maximum if err = syscall.Listen(fd, syscall.SOMAXCONN); err != nil { syscall.Close(fd) return nil, err } file = os.NewFile(uintptr(fd), filePrefix+strconv.Itoa(os.Getpid())) if l, err = net.FileListener(file); err != nil { syscall.Close(fd) return nil, err } if err = file.Close(); err != nil { syscall.Close(fd) l.Close() return nil, err } return l, err }
func (g *graphitePickleServiceManager) Start(file *os.File) error { var ( gl net.Listener err error ) if g.listenSpec != "" { if file != nil { gl, err = net.FileListener(file) } else { gl, err = net.Listen("tcp", processListenSpec(g.listenSpec)) } } else { log.Printf("Not starting Graphite Pickle Protocol because graphite-pickle-listen-spec is blank.") return nil } if err != nil { return fmt.Errorf("Error starting Graphite Pickle Protocol serviceManager: %v", err) } g.listener = graceful.NewListener(gl) fmt.Printf("Graphite Pickle protocol Listening on %s\n", processListenSpec(g.listenSpec)) go g.graphitePickleServer() return nil }
// Get a new stoppableListener, either by creating a new TCPListener or if a // valid fd is specified opening a TCP listener on that file descriptor func getStoppableListener(fd uintptr, addr string) (sl *stoppableListener, err error) { var listener net.Listener var f *os.File // listen on already open file if fd != 0 { simplelogf("Opening file listener on fd: %d\n", fd) f = os.NewFile(uintptr(fd), "listen socket") listener, err = net.FileListener(f) if err != nil { simplelogf("Couldn't open File listener on fd: %d, falling back "+ "to new tcp listener\n", fd) } } // if we failed or no file descriptor was given, create new tcp connection if fd == 0 || err != nil { // create new tcp listener simplelog("Opening a new tcp listener") listener, err = net.Listen("tcp", addr) if err != nil { simplelog("Couldn't get new tcp listener!") return } } sl = upgradeListener(listener) // if we started from an open file, attach it to the listener sl.underlyingFile = f return }
// Open API sockets based on command line parameters and // the magic environment variable from systemd // // see sd_listen_fds(3) func openAPISockets() ([]net.Listener, error) { listeners := []net.Listener{} fds := systemdFDs(true) // Try to get the socket fds from systemd if len(fds) > 0 { if flagAPIServiceListenAddr != "" { return nil, fmt.Errorf("started under systemd.socket(5), but --listen passed! Quitting.") } stderr.Printf("Listening on %d systemd-provided socket(s)\n", len(fds)) for _, fd := range fds { l, err := net.FileListener(fd) if err != nil { return nil, errwrap.Wrap(fmt.Errorf("could not open listener"), err) } listeners = append(listeners, l) } } else { if flagAPIServiceListenAddr == "" { flagAPIServiceListenAddr = common.APIServiceListenAddr } stderr.Printf("Listening on %s\n", flagAPIServiceListenAddr) l, err := net.Listen("tcp", flagAPIServiceListenAddr) if err != nil { return nil, errwrap.Wrap(fmt.Errorf("could not open tcp socket"), err) } listeners = append(listeners, l) } return listeners, nil }
// TcpListen is listening for incoming IP packets which are being intercepted. // In conflict to regular Listen mehtod the socket destination and source addresses // are of the intercepted connection. // Else then that it works exactly like net package net.Listen. func TcpListen(listenAddr string) (listener net.Listener, err error) { s, err := unix.Socket(unix.AF_INET6, unix.SOCK_STREAM, 0) if err != nil { return nil, err } defer unix.Close(s) err = unix.SetsockoptInt(s, unix.SOL_IP, unix.IP_TRANSPARENT, 1) if err != nil { return nil, err } sa, err := IPv6TcpAddrToUnixSocksAddr(listenAddr) if err != nil { return nil, err } err = unix.Bind(s, sa) if err != nil { return nil, err } err = unix.Listen(s, unix.SOMAXCONN) if err != nil { return nil, err } f := os.NewFile(uintptr(s), "TProxy") defer f.Close() return net.FileListener(f) }
// Recover from a seamless binary upgrade and use an already // existing listener to take over the connections func Recover() (l net.Listener, ppid int, err error) { var fd uintptr _, err = fmt.Sscan(os.Getenv("OLD_FD"), &fd) if err != nil { return } var i net.Listener i, err = net.FileListener(os.NewFile(fd, os.Getenv("OLD_NAME"))) if err != nil { return } switch i.(type) { case *net.TCPListener: l = i.(*net.TCPListener) case *net.UnixListener: l = i.(*net.UnixListener) default: err = errors.New(fmt.Sprintf( "file descriptor is %T not *net.TCPListener or *net.UnixListener", i)) return } if err = syscall.Close(int(fd)); err != nil { return } _, err = fmt.Sscan(os.Getenv("OLD_PPID"), &ppid) if err != nil { return } return }
func FileListener(f *os.File) (net.Listener, error) { l, err := npipex.FileListener(f) if err != nil { return net.FileListener(f) } return l, nil }
/* getListener either opens a new socket to listen on, or takes the acceptor socket it got passed when restarted. */ func (srv *endlessServer) getListener(laddr string) (l net.Listener, err error) { if srv.isChild { var ptrOffset uint = 0 runningServerReg.RLock() defer runningServerReg.RUnlock() if len(socketPtrOffsetMap) > 0 { ptrOffset = socketPtrOffsetMap[laddr] // log.Println("laddr", laddr, "ptr offset", socketPtrOffsetMap[laddr]) } f := os.NewFile(uintptr(3+ptrOffset), "") l, err = net.FileListener(f) if err != nil { err = fmt.Errorf("net.FileListener error: %v", err) return } } else { l, err = net.Listen("tcp", laddr) if err != nil { err = fmt.Errorf("net.Listen error: %v", err) return } } return }
//network is useless ,it will always use tcp4 func TfoListen(network string, listenAddr string) (listener net.Listener, err error) { s, err := unix.Socket(unix.AF_INET, unix.SOCK_STREAM|unix.SOCK_NONBLOCK|unix.SOCK_CLOEXEC, 0) if err != nil { return nil, err } defer unix.Close(s) err = unix.SetsockoptInt(s, unix.SOL_TCP, 23, 10) if err != nil { return nil, err } err = unix.SetsockoptInt(s, unix.SOL_SOCKET, unix.SO_REUSEADDR, 1) if err != nil { return nil, err } sa, err := kmgUnix.IPv4TcpAddrToUnixSocksAddr(listenAddr) if err != nil { return nil, err } err = unix.Bind(s, sa) if err != nil { return nil, err } err = unix.Listen(s, 10) if err != nil { return nil, err } f := os.NewFile(uintptr(s), "TFOListen") defer f.Close() return net.FileListener(f) }
// RetrieveListeners if invoked in a process created by PrepareCmd(...).Start() // returns the list of 'inherited' listeners. // // flag.Parse() needs to be invoked first. func RetrieveListeners() (ls []net.Listener, err error) { var a, b uintptr if a, b, err = readFDsFlag(); err != nil { return nil, err } if b < a { return nil, errors.New("Invalid values for netlimitFDs flag.") } ls = make([]net.Listener, b-a) for fd, i := a, 0; fd < b; { file := os.NewFile(fd, "listener") ls[i], err = net.FileListener(file) file.Close() if err != nil { // close created listeners for j := 0; j < i; j++ { ls[j].Close() } // return an error return nil, err } fd++ i++ } return ls, err }
func Serve(laddr string, handler func(net.Conn)) { var l net.Listener var err error graceful := os.Getenv(Graceful) if graceful != "" { // entry 0 becomes file descriptor 3. log.Printf("main: Listening to existing file descriptor %v.", FD) f := os.NewFile(uintptr(FD), "") // file listener dup fd l, err = net.FileListener(f) // close file descriptor 3 f.Close() } else { log.Print("main: Listening on a new file descriptor.") l, err = net.Listen("tcp", laddr) } if err != nil { log.Fatalf("start fail: %v", err) } go func() { serve(l, handler) }() WaitSignal(l) }
func (self *TcpServer) ListenAndServe() error { if self.inherit { file := os.NewFile(uintptr(3), "sock") tmp, err := net.FileListener(file) file.Close() if err != nil { log.Error("Error: %s", err) return nil } listener := tmp.(*net.TCPListener) self.listener = &MyListener{Listener: listener} } else { addr, err := net.ResolveTCPAddr("tcp4", self.ListenAddress) listener, err := net.ListenTCP("tcp", addr) if err != nil { panic(fmt.Sprintf("Error: %s", err)) return err } self.listener = &MyListener{Listener: listener} } log.Info("momonga_tcp: started tcp server: %s", self.listener.Addr().String()) for i := 0; i < self.config.GetAcceptorCount(); i++ { go self.Serve(self.listener) } return nil }
// Utility to listen on tcp[46]? sockets or a file descriptor func Listen(rawurl string) (listener net.Listener, err error) { u, err := url.Parse(rawurl) if err != nil { return net.Listen("tcp", rawurl) } 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 sockfile := os.NewFile(uintptr(fd), fmt.Sprintf("fd://%d", fd)) listener, err = net.FileListener(sockfile) if err != nil { return } default: var laddr *net.TCPAddr laddr, err = net.ResolveTCPAddr(u.Scheme, u.Host) if err != nil { return } listener, err = net.ListenTCP("tcp", laddr) if err != nil { return } } return }
// Helper function which checks environment variables // for socket descriptors and starts listening on it if any. func previousListener() (l net.Listener, hasPrev bool, e error) { const errLoc = "main.previousListener()" var fd uintptr if _, e = fmt.Sscan(os.Getenv(envVarName), &fd); e != nil { e = fmt.Errorf( "%s: could not read file descriptor from environment, reason -> %s", errLoc, e.Error(), ) return } hasPrev = true if l, e = net.FileListener(os.NewFile(fd, "parent socket")); e != nil { e = fmt.Errorf( "%s: could not listen on old file descriptor, reason -> %s", errLoc, e.Error(), ) return } switch l.(type) { case *net.TCPListener: default: e = fmt.Errorf( "%s: file descriptor is %T not *net.TCPListener", errLoc, l, ) return } if e = syscall.Close(int(fd)); e != nil { e = fmt.Errorf( "%s: failed to close old file descriptor, reason -> %s", errLoc, e.Error(), ) } return }
func getInitListener(laddr string) (net.Listener, error) { var l net.Listener var err error listenerWaitGroup.Add(1) graceful := os.Getenv(Graceful) if graceful != "" { signal, err := strconv.Atoi(graceful) if err != nil { log.Infof("%s get singal %s fail: %v", laddr, graceful, err) } sig := syscall.Signal(signal) switch sig { case syscall.SIGHUP: // get current file descriptor currFdStr := os.Getenv(laddr) currFd, err := strconv.Atoi(currFdStr) if err != nil { log.Info("%s get fd fail: %v", laddr, err) } log.Infof("main: %s Listening to existing file descriptor %v.", laddr, currFd) f := os.NewFile(uintptr(currFd), "") // file listener dup fd l, err = net.FileListener(f) // close current file descriptor f.Close() default: log.Infof("%s get singal %s fail: no thing to do", laddr, graceful) } } else { log.Infof("listen to %s.", laddr) l, err = net.Listen("tcp", laddr) } return l, err }
// Convert and validate the GOAGAIN_FD, GOAGAIN_NAME, and GOAGAIN_PPID // environment variables. If all three are present and in order, this // is a child process that may pick up where the parent left off. func GetEnvs() (l *net.TCPListener, ppid int, err error) { var fd uintptr _, err = fmt.Sscan(os.Getenv("GOAGAIN_FD"), &fd) if nil != err { return } var i net.Listener i, err = net.FileListener(os.NewFile(fd, os.Getenv("GOAGAIN_NAME"))) if nil != err { return } l = i.(*net.TCPListener) if err = syscall.Close(int(fd)); nil != err { return } _, err = fmt.Sscan(os.Getenv("GOAGAIN_PPID"), &ppid) if nil != err { return } if syscall.Getppid() != ppid { err = errors.New(fmt.Sprintf( "GOAGAIN_PPID is %d but parent is %d\n", ppid, syscall.Getppid(), )) return } return }
// Convert and validate the GOAGAIN_FD and GOAGAIN_PPID environment // variables. If both are present and in order, this is a child process // that may pick up where the parent left off. func GetEnvs() (*net.TCPListener, int, error) { envFd := os.Getenv("GOAGAIN_FD") if "" == envFd { return nil, 0, errors.New("GOAGAIN_FD not set") } var fd uintptr _, err := fmt.Sscan(envFd, &fd) if nil != err { return nil, 0, err } tmp, err := net.FileListener(os.NewFile(fd, "listener")) if nil != err { return nil, 0, err } l := tmp.(*net.TCPListener) envPpid := os.Getenv("GOAGAIN_PPID") if "" == envPpid { return l, 0, errors.New("GOAGAIN_PPID not set") } var ppid int _, err = fmt.Sscan(envPpid, &ppid) if nil != err { return l, 0, err } if syscall.Getppid() != ppid { return l, ppid, errors.New(fmt.Sprintf( "GOAGAIN_PPID is %d but parent is %d\n", ppid, syscall.Getppid())) } return l, ppid, nil }
// getInheritedListeners - look for LISTEN_FDS in environment variables and populate listeners accordingly func (n *nimbleNet) getInheritedListeners() error { var retErr error n.inheritOnce.Do(func() { n.mutex.Lock() defer n.mutex.Unlock() countStr := os.Getenv(envCountKey) if countStr == "" { return } count, err := strconv.Atoi(countStr) if err != nil { retErr = fmt.Errorf("found invalid count value: %s=%s", envCountKey, countStr) return } fdStart := 3 for i := fdStart; i < fdStart+count; i++ { file := os.NewFile(uintptr(i), "listener") l, err := net.FileListener(file) if err != nil { file.Close() retErr = fmt.Errorf("error inheriting socket fd %d: %s", i, err) return } if err := file.Close(); err != nil { retErr = fmt.Errorf("error closing inherited socket fd %d: %s", i, err) return } n.inheritedListeners = append(n.inheritedListeners, l) } }) return iodine.New(retErr, nil) }
func NewServer(cfg *config.Conf) (*Server, error) { s := new(Server) s.cfg = cfg var err error s.fingerprints = make(map[string]*LimitReqNode) // s.users = make(map[string]*User) // s.qpsOnServer = &LimitReqNode{} s.mu = &sync.Mutex{} s.restart = false port := s.cfg.GetConfig().Global.Port // get listenfd from file when restart if os.Getenv("_GRACEFUL_RESTART") == "true" { log.Info("graceful restart with previous listenfd") //get the linstenfd file := os.NewFile(3, "") s.listener, err = net.FileListener(file) if err != nil { log.Warn("get linstener err ") } } else { s.listener, err = net.Listen("tcp4", fmt.Sprintf(":%d", port)) } if err != nil { return nil, err } log.Infof("Dbatman Listen(tcp4) at [%d]", port) return s, nil }
func (self *server) Start(gracefulChild bool) (err error) { self.stopchan = make(chan int, 1) defer close(self.stopchan) self.HandleSignal(syscall.SIGUSR1, CMD_GRACE, func(cmd siglistener.SigCommand) { LogIfError(self.Grace()) }) self.HandleSignal(syscall.SIGUSR2, CMD_RESTART, func(cmd siglistener.SigCommand) { LogIfError(self.Restart()) }) self.HandleSignal(syscall.SIGQUIT, CMD_STOP, func(cmd siglistener.SigCommand) { LogIfError(self.Stop()) }) self.ListenCommands() if gracefulChild { f := os.NewFile(3, "") self.listener, err = net.FileListener(f) } else { self.listener, err = net.Listen("tcp", self.server.Addr) } if err == nil { self.server.Serve(self.listener) switch <-self.stopchan { case CMD_GRACE: time.Sleep(time.Second) } } return err }
// TestLinuxSendfileChild isn't a real test. It's used as a helper process // for TestLinuxSendfile. func TestLinuxSendfileChild(*testing.T) { if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" { return } defer os.Exit(0) fd3 := os.NewFile(3, "ephemeral-port-listener") ln, err := net.FileListener(fd3) if err != nil { panic(err) } mux := http.NewServeMux() fs := &FileServer{ http.Dir("testdata"), inject.CopyInject{}, ricetemp.MustMakeTemplates(rice.MustFindBox("../templates")), } mux.Handle("/", fs) mux.HandleFunc("/quit", func(http.ResponseWriter, *http.Request) { os.Exit(0) }) s := &http.Server{Handler: mux} err = s.Serve(ln) if err != nil { panic(err) } }
// TfoListen announces on the local network address laddr using tcp protocol and fast open option. // laddr must be in the form of "host:port". // It returns a tfo-enabled listener and an error if any. func tfoListen(laddr string) (lst net.Listener, err error) { s, err := unix.Socket(unix.AF_INET, unix.SOCK_STREAM|unix.SOCK_NONBLOCK|unix.SOCK_CLOEXEC, 0) if err != nil { return } defer unix.Close(s) sa, err := tcpAddrToSockaddr(laddr) if err != nil { return } err = unix.Bind(s, sa) if err != nil { return } // set the socket to fast open mode err = unix.SetsockoptInt(s, unix.SOL_TCP, 23, TCP_FASTOPEN_VAL) if err != nil { return } err = unix.Listen(s, 10) if err != nil { return } f := os.NewFile(uintptr(s), "TFOListen") defer f.Close() return net.FileListener(f) }
func (g *graphiteTextServiceManager) Start(file *os.File) error { var ( gl net.Listener err error ) if config.GraphiteTextListenSpec != "" { if file != nil { gl, err = net.FileListener(file) } else { gl, err = net.Listen("tcp", config.GraphiteTextListenSpec) } } else { log.Printf("Not starting Graphite Text protocol because graphite-test-listen-spec is blank") return nil } if err != nil { return fmt.Errorf("Error starting Graphite Text Protocol serviceManager: %v", err) } g.listener = newGracefulListener(gl) fmt.Println("Graphite text protocol Listening on " + config.GraphiteTextListenSpec) go g.graphiteTextServer() return nil }
func (g *wwwServer) Start(file *os.File) error { var ( gl net.Listener err error ) if config.HttpListenSpec != "" { if file != nil { gl, err = net.FileListener(file) } else { gl, err = net.Listen("tcp", config.HttpListenSpec) } } else { fmt.Printf("Not starting HTTP server because http-listen-spec is blank.\n") log.Printf("Not starting HTTP server because http-listen-spec is blank.") return nil } if err != nil { fmt.Fprintf(os.Stderr, "Error starting HTTP protocol: %v\n", err) return fmt.Errorf("Error starting HTTP protocol: %v", err) } g.listener = newGracefulListener(gl) fmt.Printf("HTTP protocol Listening on %s\n", config.HttpListenSpec) go httpServer(config.HttpListenSpec, g.listener, g.t) return nil }
func runChild() { log.Printf("Using address=`%v`\n", addr) // assemble shared listener file := os.NewFile(3, "") ln, err := net.FileListener(file) if err != nil { log.Fatal("FileListener:", err) } // close out the original connection if err = ln.Close(); err != nil { log.Fatal("ln.Close:", err) } log.Printf("Closed listener.\n") if !ignoreFiles { if err := file.Close(); err != nil { log.Fatal("file.Close:", err) } log.Printf("Closed file.\n") } // !!!RACE!!!; if the parent process has not closed shared stuff before the following Listen operation runs, we'll get an error. // PROBLEMATIC REBIND log.Printf("Rebinding...\n") ln, err = net.Listen("tcp", addr) if err != nil { log.Fatalf("Child could not recreate listener: %v", err) } log.Println("PASS") }
// unixListener returns the listener used for registrations (over unix sock) func unixListener() (net.Listener, error) { s := os.Getenv("LISTEN_FDS") if s != "" { // socket activated lfds, err := strconv.ParseInt(s, 10, 16) if err != nil { return nil, errwrap.Wrap(errors.New("error parsing LISTEN_FDS env var"), err) } if lfds < 1 { return nil, fmt.Errorf("LISTEN_FDS < 1") } return net.FileListener(os.NewFile(uintptr(listenFdsStart), "listen")) } else { dir := filepath.Dir(common.MetadataServiceRegSock) err := os.MkdirAll(dir, 0755) if err != nil { return nil, errwrap.Wrap(fmt.Errorf("failed to create %v", dir), err) } return net.ListenUnix("unix", &net.UnixAddr{ Net: "unix", Name: common.MetadataServiceRegSock, }) } }
func CreateTCPSocket(proto, addr string) (net.Listener, error) { var err error var laddr *net.TCPAddr laddr, err = net.ResolveTCPAddr(proto, addr) if err != nil { return nil, err } family, ipv6only := favoriteTCPAddrFamily(proto, laddr, "listen") var socketAddr syscall.Sockaddr if socketAddr, err = ipToSockaddr(family, laddr.IP, laddr.Port, laddr.Zone); err != nil { panic(err) return nil, err } var s int if s, err = sysSocket(family, syscall.SOCK_STREAM, 0); err != nil { return nil, err } if err = setDefaultSockopts(s, family, syscall.SOCK_STREAM, ipv6only); err != nil { closesocket(s) return nil, err } if err = setDefaultListenerSockopts(s); err != nil { closesocket(s) return nil, err } if err = syscall.SetsockoptInt(s, syscall.SOL_SOCKET, SO_REUSEPORT, 1); err != nil { closesocket(s) panic(err) return nil, err } if err = syscall.Bind(s, socketAddr); err != nil { closesocket(s) return nil, err } if err = syscall.Listen(s, maxListenerBacklog()); err != nil { closesocket(s) return nil, err } file := os.NewFile(uintptr(s), "listener-"+laddr.String()) defer file.Close() var socketListener net.Listener if socketListener, err = net.FileListener(file); err != nil { return nil, err } return socketListener, nil }
func main() { flagUsername := flag.String("username", "nobody", "username for the unprivileged child") isChild, _, _, files, err := privsep.MaybeBecomeChild() if err != nil { log.Fatalf("MaybeBecomeChild failed: %s", err) } who := "parent" if isChild { who = "child" } log.Printf("%s: pid=%d uid=%d euid=%d gid=%d egid=%d", who, os.Getpid(), os.Getuid(), os.Geteuid(), os.Getgid(), os.Getegid()) if isChild { if len(files) < 1 { log.Fatalf("no extra files: %v", files) } l, err := net.FileListener(files[0]) if err != nil { log.Fatalf("FileListener: %s", err) } child(l) return } if os.Getuid() != 0 { log.Print("Warning: this example only works when run as the root user") } addr := "localhost:1111" laddr, err := net.ResolveTCPAddr("tcp", addr) if err != nil { log.Fatalf("resolve %s: %s", addr, err) } l, err := net.ListenTCP("tcp", laddr) if err != nil { log.Fatalf("listen %s: %s", laddr, err) } sock, err := l.File() if err != nil { log.Fatalf("fd: %s", err) } proc, _, _, err := privsep.CreateChild(*flagUsername, os.Args[0], nil, []*os.File{sock}) if err != nil { log.Fatalf("CreateChild failed: %s", err) } sock.Close() // tidy up so child doesn't run forever defer proc.Kill() parent(laddr) }
func (fd *FileDescriptor) ToListener() (net.Listener, error) { listener, err := net.FileListener(fd.File) if err != nil { return nil, err } fd.File.Close() return listener, nil }