Fix port validation to allow same port for different protocols (#992) (#1000)

- Fixes: #992 
- Port validation previously rejected valid configurations
  when the same port number was used for different
  protocols (TCP and UDP). For example:
 `-p 1024:1024/udp -p 1024:1024/tcp`
  Although this is a valid and common use case, the
  validation logic treated it as a conflict.

To fix this, I updated the validation key to include the protocol name.
The validation now checks for overlapping port numbers only within the
same protocol, rather than across all protocols.

This change enables binding the same port number for both TCP and UDP,
aligning the validation behavior with real-world networking
requirements.

## Testing
- [x] Tested locally
- [x] Added/updated tests
- [ ] Added/updated docs
This commit is contained in:
Amir Alperin
2026-01-04 20:49:22 +02:00
committed by GitHub
parent cf64614173
commit df368b790e
2 changed files with 21 additions and 7 deletions
+6 -6
View File
@@ -1,5 +1,5 @@
//===----------------------------------------------------------------------===//
// Copyright © 2025 Apple Inc. and the container project authors.
// Copyright © 2025-2026 Apple Inc. and the container project authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -73,14 +73,14 @@ public struct Utility {
}
public static func validPublishPorts(_ publishPorts: [PublishPort]) throws {
var hostPorts = Set<UInt16>()
var hostPorts = Set<String>()
for publishPort in publishPorts {
for index in 0..<publishPort.count {
let hostPort = publishPort.hostPort + index
guard !hostPorts.contains(hostPort) else {
for index in publishPort.hostPort..<(publishPort.hostPort + publishPort.count) {
let hostPortKey = "\(index)/\(publishPort.proto.rawValue)"
guard !hostPorts.contains(hostPortKey) else {
throw ContainerizationError(.invalidArgument, message: "host ports for different publish port specs may not overlap")
}
hostPorts.insert(hostPort)
hostPorts.insert(hostPortKey)
}
}
}
+15 -1
View File
@@ -1,5 +1,5 @@
//===----------------------------------------------------------------------===//
// Copyright © 2025 Apple Inc. and the container project authors.
// Copyright © 2025-2026 Apple Inc. and the container project authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -116,4 +116,18 @@ struct UtilityTests {
}
}
@Test
func testPublishPortsSamePortDifferentProtocols() throws {
let result = try Parser.publishPorts([
"8080:8080/tcp",
"8080:8080/udp",
"1024-2048:1024-2048/tcp",
"1024-2048:1024-2048/udp",
"8081:8081",
"8081:8081/udp",
])
#expect(result.count == 6)
try Utility.validPublishPorts(result)
}
}