1
est 2014-04-08 15:26:29 +08:00
awww 现在的Go包管理机制如此之烂以至于源码里直接放下第三方包源码了么。
|
2
reusFork 2014-04-09 03:50:11 +08:00
@est 是你不懂。tls是标准库里的包,但要改动才能符合特定的需求。直接复制出来改是常见做法。你认为哪种包管理机制会对这样的情景有帮助呢?
|
3
est 2014-04-09 08:47:31 +08:00
@reusFork
从另一个角度不是正好说明Go的自省机制太烂。无法建立个thin wrapper达到简单修改第三方包行为的目的么? Go没有完整的OOP机制,无法继承一个自带包的Class然后重载方法。但是这个技巧在其他很多语言里是非常常见的。Go的自带包对很多IO模块的封装又是leaky abstraction。所以搞得很痛苦。 我以前需要小改一下net.TCPConn就需要用到各种反射。扭来扭去浑身不自在。或许是我Go水平不行? |
4
lamengao 2014-04-09 09:10:08 +08:00
|
5
reusFork 2014-04-09 12:17:08 +08:00
@est 看这个commit https://github.com/titanous/heartbleeder/commit/4515fdffb03f6c57319edcad0e1c38cc101d3933 ,想要发送个恶意心跳包,使用标准库的tls的公开方法是做不到的,这是package间的成员可见性导致的,而不是因为缺少继承和重载。
因为想要使用私有的方法,所以要将tls引入到当前package,所以可以直接复制源码。引入之后,除了直接修改tls源码,还可以使用个embedded的tls.Conn,作者使用了前一个方法,后一个方法就可以说是thin wrapper了。 所以说这是可见性导致的,而tls包不提供足够的公开方法来实现恶意心跳包这很正常。 如果是net.TCPConn实现有缺陷就提issue,想要做非一般的事情就直接fork或者复制。不说具体需要不上代码,我也没法判断是水平不行还是做法不对 |
6
est 2014-04-09 13:41:36 +08:00
@reusFork
你仔细看看 /tls/conn.go Conn.Heartbeat() 不就等于是继承Conn这个class新添加了一个方法么。复制粘贴修改就是穷人的OOP而已。 说到成员可见,我也遇到类似问题。靠反射才能强行把成员属性取出来。这种做法太恶心了。 https://groups.google.com/d/msg/golang-nuts/4vowPJf0fSgJ |
7
est 2014-04-09 13:42:31 +08:00
|
8
reusFork 2014-04-09 14:28:15 +08:00
@est 我当然仔细看过了。这跟OOP没有关系,只要writeRecord, readRecord这些方法可见,可以用embedded的tls.Conn
type Conn struct { tls.Conn } func (c *Conn) Heartbeat(...) {...} 这样的效果和继承是一样的。根本原因是作者需要用到tls.Conn没暴露的方法来做坏事,正常的用途根本不需要tls.Conn的私有方法。所以标准库没有暴露出WriteRecord, ReadRecord。 net.TCPConn如果直接暴露fd,又不知道多少人会踩坑来骂了。链接里都有人说了 "The reason why you cannot access it is the networking package requires that it controls the blocking mode of any fds it owns. If you were able to get access to sysfd, you could change the blocking mode yourself which would cause havock with the poller. " 它本来就不想让你用,非要用,不方便也没什么好说的。 还有种做法是直接调用C api拿到fd,再包装成net.Conn |