UTMQemuConfigurationPortForward.swift 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. //
  2. // Copyright © 2022 osy. All rights reserved.
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. //
  16. import Foundation
  17. /// Represent a single port forward
  18. struct UTMQemuConfigurationPortForward: Codable, Identifiable, Hashable {
  19. /// Socket protocol
  20. var `protocol`: QEMUNetworkProtocol = .tcp
  21. /// Host address (nil for any address).
  22. var hostAddress: String?
  23. /// Host port to recieve connection.
  24. var hostPort: Int = 0
  25. /// Guest address (nil for any address).
  26. var guestAddress: String?
  27. /// Guest port where connection is coming from.
  28. var guestPort: Int = 0
  29. let id = UUID()
  30. enum CodingKeys: String, CodingKey {
  31. case `protocol` = "Protocol"
  32. case hostAddress = "HostAddress"
  33. case hostPort = "HostPort"
  34. case guestAddress = "GuestAddress"
  35. case guestPort = "GuestPort"
  36. }
  37. enum CodingKeysOld: String, CodingKey {
  38. case `protocol` = "protocol"
  39. case hostAddress = "hostAddress"
  40. case hostPort = "hostPort"
  41. case guestAddress = "guestAddress"
  42. case guestPort = "guestPort"
  43. }
  44. init() {
  45. }
  46. init(from decoder: Decoder) throws {
  47. do {
  48. let values = try decoder.container(keyedBy: CodingKeys.self)
  49. `protocol` = try values.decode(QEMUNetworkProtocol.self, forKey: .protocol)
  50. hostAddress = try values.decodeIfPresent(String.self, forKey: .hostAddress)
  51. hostPort = try values.decode(Int.self, forKey: .hostPort)
  52. guestAddress = try values.decodeIfPresent(String.self, forKey: .guestAddress)
  53. guestPort = try values.decode(Int.self, forKey: .guestPort)
  54. } catch is DecodingError {
  55. // before UTM v4.4, we mistakingly used camel-case in the config.plist
  56. let values = try decoder.container(keyedBy: CodingKeysOld.self)
  57. `protocol` = try values.decode(QEMUNetworkProtocol.self, forKey: .protocol)
  58. hostAddress = try values.decodeIfPresent(String.self, forKey: .hostAddress)
  59. hostPort = try values.decode(Int.self, forKey: .hostPort)
  60. guestAddress = try values.decodeIfPresent(String.self, forKey: .guestAddress)
  61. guestPort = try values.decode(Int.self, forKey: .guestPort)
  62. }
  63. }
  64. func encode(to encoder: Encoder) throws {
  65. var container = encoder.container(keyedBy: CodingKeys.self)
  66. try container.encode(`protocol`, forKey: .protocol)
  67. try container.encodeIfPresent(hostAddress, forKey: .hostAddress)
  68. try container.encode(hostPort, forKey: .hostPort)
  69. try container.encodeIfPresent(guestAddress, forKey: .guestAddress)
  70. try container.encode(guestPort, forKey: .guestPort)
  71. }
  72. func hash(into hasher: inout Hasher) {
  73. id.hash(into: &hasher)
  74. }
  75. }
  76. // MARK: - Conversion of old config format
  77. extension UTMQemuConfigurationPortForward {
  78. init(migrating oldForward: UTMLegacyQemuConfigurationPortForward) {
  79. self.init()
  80. if let oldProtocol = convertProtocol(from: oldForward.protocol) {
  81. `protocol` = oldProtocol
  82. }
  83. hostAddress = oldForward.hostAddress
  84. if let portNum = oldForward.guestPort {
  85. hostPort = portNum.intValue
  86. }
  87. guestAddress = oldForward.guestAddress
  88. if let portNum = oldForward.guestPort {
  89. guestPort = portNum.intValue
  90. }
  91. }
  92. private func convertProtocol(from str: String?) -> QEMUNetworkProtocol? {
  93. if str == "tcp" {
  94. return .tcp
  95. } else if str == "udp" {
  96. return .udp
  97. } else {
  98. return nil
  99. }
  100. }
  101. }