p2p的nat模塊
該模塊相對比較簡單,因為nat的真正實現並不在此模塊,主要是使用了第三方的nat-upnp和nat-pmp來實現真正的穿透(端口映射).
對外公布的接口
// An implementation of nat.Interface can map local ports to ports
// accessible from the Internet.
type Interface interface {
// These methods manage a mapping between a port on the local
// machine to a port that can be connected to from the internet.
//
// protocol is "UDP" or "TCP". Some implementations allow setting
// a display name for the mapping. The mapping may be removed by
// the gateway when its lifetime ends.
AddMapping(protocol string, extport, intport int, name string, lifetime time.Duration) error
DeleteMapping(protocol string, extport, intport int) error
// This method should return the external (Internet-facing)
// address of the gateway device.
ExternalIP() (net.IP, error)
// Should return name of the method. This is used for logging.
String() string
}
主要有三個關鍵函數一個是添加映射,一個是刪除映射,另一個是獲取外部IP.使用起來非常直觀,我們這里看一個例子,nat.go中的Map函數中,
m.AddMapping(protocol, extport, intport, name, mapTimeout);
我看ethereum使用的時候,extport和intport都一樣.
Interface總共有四個實現分別是upnp,pmp,extIP和startautodisc,從名字可以看出這四個實現都沒有暴露給調用者,也就是內部使用,其中extIP是在本機IP就是公網IP的情況下使用,也就是無需端口映射的時候使用.upnp和pmp是對兩種端口映射協議的使用封裝,而startautodisc則是對這兩者的再次封裝統一.
那么nat模塊怎么使用呢,用起來其實很簡單.下面是示例代碼,不完整.
//獲取nat實例,
var m nat.Interface=nat.Any()
//然后就可以使用AddMapping等操作了,
//nat還提供了更方便的函數Map來保持端口映射
//用法如下 來自server.go
nat.Map(srv.NAT, srv.quit, "tcp", laddr.Port, laddr.Port, "ethereum p2p")