如何将net.Listener()的FD传递给子进程安全? [英] How to pass net.Listener()'s FD to child process safely?
问题描述
我有一个作为TCP服务器的主进程,主进程调用Fork(),将其传递给它net.Listener()的FD到子进程。然后子进程可以使用net.Filelistener()继承这个FD。
我通过很多开源代码研究了这个问题,并做了一些实验。但不幸的是,现在这些解决方案都不能满足我的需求,因为它们不是便携式的,您还需要许多低级别的工作,这些工作是危险的。
如果有任何解决方案可以通过网络.Listener()的FD给子进程SAFELY,我很高兴知道。
我现在试过的:
-
环境值不可移植,会导致许多FD出现混乱,不安全,因为可以从外部更改。
$ b -
Dup FD&清除
FD_CLOEXEC
然后执行/ fork,可移植但不受Go API支持,syscall.NoCloseOnExec()开发团队被拒绝了,因为他们希望保持系统清洁。 -
设置
SO_REUSEADDR
立即移植,在此之前关闭父母的听众。失败,不可移植,不受Go API支持,也不安全。 c>,不知道如何从子进程获得继承的FD,我需要一个配置文件来保存FD&名字呢?这个解决方案也有一个bug,请阅读exec的文档以获取更多细节。 这个问题的简单测试用例(解决方案4): Environment values, not portable, will cause chaos with many FDs, not safe since can be changed from outside.
Dup FD & Clear
FD_CLOEXEC
then exec/fork, portable but not supported by Go API, asyscall.NoCloseOnExec()
change submitted to dev team was rejected since they want to keep syscall clean.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.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.
https://github.com/reckhou/go-fd-pass-test
还包括OS X& amp; 2上的两个可执行文件; Linux操作系统。我试过Go 1.1& Go 1.1.1,但这个问题仍然存在。
最简单的方法是将侦听器传递给exec的ExtraFiles字段。 Cmd。
父母的例子:
var l * net。 TCPListener
cmd:= exec.Command(...)
f,err:= l.File()
cmd.ExtraFiles = [] * os.File {f}
孩子的例子:
l,err:= net.FileListener(os.NewFile(3,listener))
您可能还想概括这一点,并让孩子接受PROGRAMNAME_LISTENER_FD作为环境变量。然后,在开始孩子之前,父母会将环境变量设置为3.
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:
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.
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.
这篇关于如何将net.Listener()的FD传递给子进程安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!