@cryptotaxi247 / kubo / commits / d7c9ae12a

p2p/nat: make nat mappings closable by client

After this commit, client can close individual mappings (without closing the whole NAT)

Juan Batiz-Benet committed Jan 30, 2015 at 20:22 UTC d7c9ae12ac4282099b27294be15201eda5077a5a
1 file changed +25 -9
p2p/nat/nat.go
+25 -9
@@ -55,15 +55,16 @@ type NAT struct {
55 proc goprocess.Process // manages nat mappings lifecycle
56
57 mappingmu sync.RWMutex // guards mappings
58 - mappings []*mapping
58 + mappings map[*mapping]struct{}
59
60 Notifier
61 }
62
63 func newNAT(realNAT nat.NAT) *NAT {
64 return &NAT{
65 - nat: realNAT,
66 - proc: goprocess.WithParent(goprocess.Background()),
65 + nat: realNAT,
66 + proc: goprocess.WithParent(goprocess.Background()),
67 + mappings: make(map[*mapping]struct{}),
68 }
69 }
70
@@ -143,6 +144,9 @@ type Mapping interface {
144 // ExternalAddr returns the external facing address. If the mapping is not
145 // established, addr will be nil, and and ErrNoMapping will be returned.
146 ExternalAddr() (addr ma.Multiaddr, err error)
147 +
148 + // Close closes the port mapping
149 + Close() error
150 }
151
152 // keeps republishing
@@ -230,9 +234,9 @@ func (m *mapping) Close() error {
234 // Mappings returns a slice of all NAT mappings
235 func (nat *NAT) Mappings() []Mapping {
236 nat.mappingmu.Lock()
233 - maps2 := make([]Mapping, len(nat.mappings))
234 - for i, m := range nat.mappings {
235 - maps2[i] = m
237 + maps2 := make([]Mapping, 0, len(nat.mappings))
238 + for m := range nat.mappings {
239 + maps2 = append(maps2, m)
240 }
241 nat.mappingmu.Unlock()
242 return maps2
@@ -243,7 +247,13 @@ func (nat *NAT) addMapping(m *mapping) {
247 nat.proc.AddChild(m.proc)
248
249 nat.mappingmu.Lock()
246 - nat.mappings = append(nat.mappings, m)
250 + nat.mappings[m] = struct{}{}
251 + nat.mappingmu.Unlock()
252 +}
253 +
254 +func (nat *NAT) rmMapping(m *mapping) {
255 + nat.mappingmu.Lock()
256 + delete(nat.mappings, m)
257 nat.mappingmu.Unlock()
258 }
259
@@ -286,10 +296,16 @@ func (nat *NAT) NewMapping(maddr ma.Multiaddr) (Mapping, error) {
296 intport: intport,
297 intaddr: maddr,
298 }
289 - m.proc = periodic.Every(MappingDuration/3, func(worker goprocess.Process) {
290 - nat.establishMapping(m)
299 + m.proc = goprocess.WithTeardown(func() error {
300 + nat.rmMapping(m)
301 + return nil
302 })
303 nat.addMapping(m)
304 +
305 + m.proc.AddChild(periodic.Every(MappingDuration/3, func(worker goprocess.Process) {
306 + nat.establishMapping(m)
307 + }))
308 +
309 // do it once synchronously, so first mapping is done right away, and before exiting,
310 // allowing users -- in the optimistic case -- to use results right after.
311 nat.establishMapping(m)