How to pass net.Listener()'s FD to child process safely?

一笑奈何 提交于 2019-12-10 17:25:03

问题


I've been stucked with this issue for hours:

I have a main process served as a TCP server, the main process call Fork(), pass its net.Listener()'s FD to child process. Then child process can use net.Filelistener() to inherit this FD.

I have researched this issue through many open-sourced codes, also did some experiments. But unfortunately none of these solutions satisfy me for now since they are not portable, you also need many low-level jobs which are dangerous.

If there's any solution to pass net.Listener()'s FD to child process SAFELY, I'd be glad to know.

What I've tried for now:

  1. Environment values, not portable, will cause chaos with many FDs, not safe since can be changed from outside.

  2. Dup FD & Clear FD_CLOEXEC then exec/fork, portable but not supported by Go API, a syscall.NoCloseOnExec() change submitted to dev team was rejected since they want to keep syscall clean.

  3. Set SO_REUSEADDR so child process can listen to port instantly, close parent's listener before that. Failed, not portable, not supported by Go API, also unsafe.

  4. exec.Command.ExtraFiles(), have no idea how to get inherited FDs from child process, do I need a config file to save FD & names? This solution also have a bug, read exec's document for more detail.

All right guys, I've written a simple test case of this issue(with solution 4):

https://github.com/reckhou/go-fd-pass-test

Also include 2 executables on OS X & Linux. I tried Go 1.1 & Go 1.1.1 but this issue still remains.


回答1:


The easiest way is to pass the listener in the ExtraFiles field of exec.Cmd.

Example of parent:

var l *net.TCPListener
cmd := exec.Command(...)
f, err := l.File()
cmd.ExtraFiles = []*os.File{f}

Example of child:

l, err := net.FileListener(os.NewFile(3, "listener"))

You may also want to generalize this and have the child accept PROGRAMNAME_LISTENER_FD as an environment variable. Then the parent would set the environment variable to 3 before starting the child.




回答2:


I am looking for same to listen loopback adresss and read data and send to exec command in WINDOWS .

Any suggestion as windows don’t support File descriptars IN UNIX WE DO AS FOLLOWS

service := ":1200" tcpAddr, err := net.ResolveTCPAddr("tcp", service)

listener, err := net.ListenTCP("tcp",tcpAddr)
if err != nil {
    return "", err
}

defer listener.Close()
file, err := listener.File()   --> unix supports file descriptor / how about in windows ??
if err != nil {  
    return "", err
}

cmd := exec.Command( execname)

cmd.ExtraFiles = []*os.File{file} --> in unix it support / how about in windows to add data ???

cmd.Start()



来源:https://stackoverflow.com/questions/17193086/how-to-pass-net-listeners-fd-to-child-process-safely

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!