Beispiel #1
0
func (srv *Server) socketListen() error {
	var la *net.TCPAddr
	var err error
	if la, err = net.ResolveTCPAddr("tcp", srv.Addr); err != nil {
		return err
	}

	var l *net.TCPListener
	if l, err = net.ListenTCP("tcp", la); err != nil {
		return err
	}
	srv.listener = l
	// setup listener to be non-blocking if we're not on windows.
	// this is required for hot restart to work.
	if runtime.GOOS != "windows" {
		if srv.listenerFile, err = l.File(); err != nil {
			return err
		}
		fd := int(srv.listenerFile.Fd())
		if e := setupFDNonblock(fd); e != nil {
			return e
		}

		if srv.sendfile {
			if e := syscall.SetsockoptInt(fd, syscall.IPPROTO_TCP, srv.sockOpt, 1); e != nil {
				return e
			}
		}
	}
	return nil
}
Beispiel #2
0
// Re-exec this image without dropping the listener passed to this function.
func Relaunch(l *net.TCPListener) error {
	f, err := l.File()
	if nil != err {
		return err
	}
	argv0, err := exec.LookPath(os.Args[0])
	if nil != err {
		return err
	}
	wd, err := os.Getwd()
	if nil != err {
		return err
	}
	err = os.Setenv("GOAGAIN_FD", fmt.Sprint(f.Fd()))
	if nil != err {
		return err
	}
	err = os.Setenv("GOAGAIN_PPID", strconv.Itoa(syscall.Getpid()))
	if nil != err {
		return err
	}
	p, err := os.StartProcess(argv0, os.Args, &os.ProcAttr{
		Dir:   wd,
		Env:   os.Environ(),
		Files: []*os.File{os.Stdin, os.Stdout, os.Stderr, f},
		Sys:   &syscall.SysProcAttr{},
	})
	if nil != err {
		return err
	}
	log.Printf("spawned child %d\n", p.Pid)
	return nil
}
Beispiel #3
0
// only valid on non-windows
func (srv *Server) setupNonBlockingListener(err error, l *net.TCPListener) error {
	// FIXME: File() returns a copied pointer.  we're leaking it.  probably doesn't matter
	if srv.listenerFile, err = l.File(); err != nil {
		return err
	}
	fd := int(srv.listenerFile.Fd())
	if e := syscall.SetNonblock(fd, true); e != nil {
		return e
	}
	return nil
}
// only valid on non-windows
func (srv *Server) setupNonBlockingListener(err error, l *net.TCPListener) error {
	if srv.listenerFile, err = l.File(); err != nil {
		return err
	}
	fd := int(srv.listenerFile.Fd())
	if e := syscall.SetNonblock(fd, true); e != nil {
		return e
	}
	if srv.sendfile {
		if e := syscall.SetsockoptInt(fd, syscall.IPPROTO_TCP, srv.sockOpt, 1); e != nil {
			return e
		}
	}
	return nil
}
Beispiel #5
0
func doPrefork() (listener net.Listener) {
	var err error
	var fl *os.File
	var tcplistener *net.TCPListener
	if !*child {
		var addr *net.TCPAddr
		addr, err = net.ResolveTCPAddr("tcp", ":8080")
		if err != nil {
			log.Fatal(err)
		}
		tcplistener, err = net.ListenTCP("tcp", addr)
		if err != nil {
			log.Fatal(err)
		}
		fl, err = tcplistener.File()
		if err != nil {
			log.Fatal(err)
		}
		children := make([]*exec.Cmd, runtime.NumCPU()/2)
		for i := range children {
			children[i] = exec.Command(os.Args[0], "-prefork", "-child")
			children[i].Stdout = os.Stdout
			children[i].Stderr = os.Stderr
			children[i].ExtraFiles = []*os.File{fl}
			err = children[i].Start()
			if err != nil {
				log.Fatal(err)
			}
		}
		for _, ch := range children {
			var err error = ch.Wait()
			if err != nil {
				log.Print(err)
			}
		}
		os.Exit(0)
	} else {
		fl = os.NewFile(3, "")
		listener, err = net.FileListener(fl)
		if err != nil {
			log.Fatal(err)
		}
		runtime.GOMAXPROCS(2)
	}
	return listener
}
Beispiel #6
0
func SetTcpMD5SigSockopts(l *net.TCPListener, address string, key string) error {
	t, _ := buildTcpMD5Sig(address, key)
	fi, err := l.File()
	defer fi.Close()
	if err != nil {
		return err
	}
	if l, err := net.FileListener(fi); err == nil {
		defer l.Close()
	}
	_, _, e := syscall.Syscall6(syscall.SYS_SETSOCKOPT, fi.Fd(),
		uintptr(syscall.IPPROTO_TCP), uintptr(TCP_MD5SIG),
		uintptr(unsafe.Pointer(&t)), unsafe.Sizeof(t), 0)
	if e > 0 {
		return e
	}
	return nil
}
Beispiel #7
0
func SetTcpMD5SigSockopts(l *net.TCPListener, address string, key string) error {
	t, _ := buildTcpMD5Sig(address, key)
	fi, err := l.File()
	defer fi.Close()
	if err != nil {
		return err
	}
	if l, err := net.FileListener(fi); err == nil {
		defer l.Close()
	}
	b := *(*[unsafe.Sizeof(t)]byte)(unsafe.Pointer(&t))
	if err := syscall.SetsockoptString(int(fi.Fd()),
		syscall.IPPROTO_TCP, TCP_MD5SIG,
		string(b[:])); err != nil {
		return err
	}
	return nil
}
Beispiel #8
0
func (s *server) listen() error {
	var addr *net.TCPAddr
	var err error
	var listener *net.TCPListener

	if addr, err = net.ResolveTCPAddr("tcp", s.addr); err != nil {
		return err
	}
	if listener, err = net.ListenTCP("tcp", addr); err != nil {
		return err
	}
	s.listener = *listener
	if s.listenerFile, err = listener.File(); err != nil {
		return err
	}
	if e := syscall.SetNonblock(s.Fd(), true); e != nil {
		return e
	}
	return nil
}
Beispiel #9
0
func SetTcpMD5SigSockopts(l *net.TCPListener, address string, key string) error {
	fi, err := l.File()
	defer fi.Close()

	if err != nil {
		return err
	}

	if l, err := net.FileListener(fi); err == nil {
		defer l.Close()
	}

	// always enable and assumes that the configuration is done by
	// setkey()
	if err := syscall.SetsockoptInt(int(fi.Fd()),
		syscall.IPPROTO_TCP, TCP_MD5SIG, 1); err != nil {
		return err
	}
	return nil
}
Beispiel #10
0
func SetTcpMD5SigSockopts(l *net.TCPListener, address string, key string) error {
	fi, err := l.File()
	defer fi.Close()

	if err != nil {
		return err
	}

	if l, err := net.FileListener(fi); err == nil {
		defer l.Close()
	}

	t := int(1)
	if e := syscall.SetsockoptInt(int(fi.Fd()), syscall.IPPROTO_TCP, TCP_MD5SIG, t); e != nil {
		return e
	}
	if len(key) > 0 {
		return saAdd(address, key)
	}
	return saDelete(address)
}
Beispiel #11
0
func (srv *Server) socketListen() os.Error {
	var la *net.TCPAddr
	var err os.Error
	if la, err = net.ResolveTCPAddr("tcp", srv.Addr); err != nil {
		return err
	}

	var l *net.TCPListener
	if l, err = net.ListenTCP("tcp", la); err != nil {
		return err
	}
	srv.listener = l
	if srv.listenerFile, err = l.File(); err != nil {
		return err
	}
	if e := syscall.SetNonblock(srv.listenerFile.Fd(), true); e != 0 {
		return os.Errno(e)
	}
	l.SetTimeout(3e9)
	return nil
}
Beispiel #12
0
func SetTcpMD5SigSockopts(l *net.TCPListener, address string, key string) error {
	fi, err := l.File()
	defer fi.Close()

	if err != nil {
		return err
	}

	if l, err := net.FileListener(fi); err == nil {
		defer l.Close()
	}

	// always enable and assumes that the configuration is done by
	// setkey()
	t := int32(1)
	_, _, e := syscall.Syscall6(syscall.SYS_SETSOCKOPT, fi.Fd(),
		uintptr(syscall.IPPROTO_TCP), uintptr(TCP_MD5SIG),
		uintptr(unsafe.Pointer(&t)), unsafe.Sizeof(t), 0)
	if e > 0 {
		return e
	}
	return nil
}