(ctx context.Context, mapping *Mapping, nats map[string]Device)
| 274 | } |
| 275 | |
| 276 | func (s *Service) acquireNewLocked(ctx context.Context, mapping *Mapping, nats map[string]Device) (change bool) { |
| 277 | leaseTime := time.Duration(s.cfg.Options().NATLeaseM) * time.Minute |
| 278 | addrMap := mapping.extAddresses |
| 279 | |
| 280 | for id, nat := range nats { |
| 281 | select { |
| 282 | case <-ctx.Done(): |
| 283 | return false |
| 284 | default: |
| 285 | } |
| 286 | |
| 287 | if _, ok := addrMap[id]; ok { |
| 288 | continue |
| 289 | } |
| 290 | |
| 291 | // Only perform mappings on the nat's that have the right local IP |
| 292 | // address |
| 293 | localIP := nat.GetLocalIPv4Address() |
| 294 | if !mapping.validGateway(localIP) && nat.SupportsIPVersion(IPv4Only) { |
| 295 | l.Debugf("Skipping %s for %s because of IP mismatch. %s != %s", id, mapping, mapping.address.IP, localIP) |
| 296 | continue |
| 297 | } |
| 298 | |
| 299 | l.Debugf("Trying to open port %s on %s", mapping, id) |
| 300 | |
| 301 | if !nat.SupportsIPVersion(mapping.ipVersion) { |
| 302 | l.Debugf("Skipping firewall traversal on gateway %s because it doesn't match the listener address family", nat.ID()) |
| 303 | continue |
| 304 | } |
| 305 | |
| 306 | addrs, err := s.tryNATDevice(ctx, nat, mapping.address, 0, mapping.protocol, leaseTime) |
| 307 | if err != nil { |
| 308 | slog.WarnContext(ctx, "Failed to acquire open port", slog.String("mapping", mapping.String()), slog.String("id", id), slogutil.Error(err)) |
| 309 | continue |
| 310 | } |
| 311 | |
| 312 | l.Debugf("Opened port %s -> %v on %s", mapping, addrs, id) |
| 313 | mapping.setAddressLocked(id, addrs) |
| 314 | change = true |
| 315 | } |
| 316 | |
| 317 | return change |
| 318 | } |
| 319 | |
| 320 | // tryNATDevice tries to acquire a port mapping for the given internal address to |
| 321 | // the given external port. If external port is 0, picks a pseudo-random port. |
no test coverage detected