mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-25 03:05:19 +00:00
Remove protocol versioning and handshake logic (#433)
Simplified the protocol by removing version negotiation and handshake sequences. All devices now use protocol version 1 without negotiation. This eliminates unnecessary connection overhead and complexity while maintaining full compatibility across the network. Changes: - Removed versionHello and versionAck message types - Simplified connection flow to use announce packets only - Removed version negotiation state tracking - Cleaned up handshake timeout logic - Reduced connection establishment overhead Co-authored-by: jack <jackjackbits@users.noreply.github.com>
This commit is contained in:
@@ -233,8 +233,6 @@ protocol BinaryEncodable {
|
||||
enum BinaryMessageType: UInt8 {
|
||||
case deliveryAck = 0x01
|
||||
case readReceipt = 0x02
|
||||
case versionHello = 0x07
|
||||
case versionAck = 0x08
|
||||
case noiseIdentityAnnouncement = 0x09
|
||||
case noiseMessage = 0x0A
|
||||
}
|
||||
@@ -223,8 +223,8 @@ struct BinaryProtocol {
|
||||
guard offset + 1 <= unpaddedData.count else { return nil }
|
||||
let version = unpaddedData[offset]; offset += 1
|
||||
|
||||
// Check if version is supported
|
||||
guard ProtocolVersion.isSupported(version) else {
|
||||
// Check if version is 1 (only supported version)
|
||||
guard version == 1 else {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -152,10 +152,6 @@ enum MessageType: UInt8 {
|
||||
case noiseEncrypted = 0x12 // Noise encrypted transport message
|
||||
case noiseIdentityAnnounce = 0x13 // Announce static public key for discovery
|
||||
|
||||
// Protocol version negotiation
|
||||
case versionHello = 0x20 // Initial version announcement
|
||||
case versionAck = 0x21 // Version acknowledgment
|
||||
|
||||
// Protocol-level acknowledgments
|
||||
case protocolAck = 0x22 // Generic protocol acknowledgment
|
||||
case protocolNack = 0x23 // Negative acknowledgment (failure)
|
||||
@@ -181,8 +177,6 @@ enum MessageType: UInt8 {
|
||||
case .noiseHandshakeResp: return "noiseHandshakeResp"
|
||||
case .noiseEncrypted: return "noiseEncrypted"
|
||||
case .noiseIdentityAnnounce: return "noiseIdentityAnnounce"
|
||||
case .versionHello: return "versionHello"
|
||||
case .versionAck: return "versionAck"
|
||||
case .protocolAck: return "protocolAck"
|
||||
case .protocolNack: return "protocolNack"
|
||||
case .systemValidation: return "systemValidation"
|
||||
@@ -917,234 +911,6 @@ struct PeerIdentityBinding {
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Protocol Version Negotiation
|
||||
|
||||
// Protocol version constants
|
||||
struct ProtocolVersion {
|
||||
static let current: UInt8 = 1
|
||||
static let minimum: UInt8 = 1
|
||||
static let maximum: UInt8 = 1
|
||||
|
||||
// Future versions can be added here
|
||||
static let supportedVersions: Set<UInt8> = [1]
|
||||
|
||||
static func isSupported(_ version: UInt8) -> Bool {
|
||||
return supportedVersions.contains(version)
|
||||
}
|
||||
|
||||
static func negotiateVersion(clientVersions: [UInt8], serverVersions: [UInt8]) -> UInt8? {
|
||||
// Find the highest common version
|
||||
let clientSet = Set(clientVersions)
|
||||
let serverSet = Set(serverVersions)
|
||||
let common = clientSet.intersection(serverSet)
|
||||
|
||||
return common.max()
|
||||
}
|
||||
}
|
||||
|
||||
// Version negotiation hello message
|
||||
struct VersionHello: Codable {
|
||||
let supportedVersions: [UInt8] // List of supported protocol versions
|
||||
let preferredVersion: UInt8 // Preferred version (usually the latest)
|
||||
let clientVersion: String // App version string (e.g., "1.0.0")
|
||||
let platform: String // Platform identifier (e.g., "iOS", "macOS")
|
||||
let capabilities: [String]? // Optional capability flags for future extensions
|
||||
|
||||
init(supportedVersions: [UInt8] = Array(ProtocolVersion.supportedVersions),
|
||||
preferredVersion: UInt8 = ProtocolVersion.current,
|
||||
clientVersion: String,
|
||||
platform: String,
|
||||
capabilities: [String]? = nil) {
|
||||
self.supportedVersions = supportedVersions
|
||||
self.preferredVersion = preferredVersion
|
||||
self.clientVersion = clientVersion
|
||||
self.platform = platform
|
||||
self.capabilities = capabilities
|
||||
}
|
||||
|
||||
func encode() -> Data? {
|
||||
return try? JSONEncoder().encode(self)
|
||||
}
|
||||
|
||||
static func decode(from data: Data) -> VersionHello? {
|
||||
try? JSONDecoder().decode(VersionHello.self, from: data)
|
||||
}
|
||||
|
||||
// MARK: - Binary Encoding
|
||||
|
||||
func toBinaryData() -> Data {
|
||||
var data = Data()
|
||||
|
||||
// Flags byte: bit 0 = hasCapabilities
|
||||
var flags: UInt8 = 0
|
||||
if capabilities != nil { flags |= 0x01 }
|
||||
data.appendUInt8(flags)
|
||||
|
||||
// Supported versions array
|
||||
data.appendUInt8(UInt8(supportedVersions.count))
|
||||
for version in supportedVersions {
|
||||
data.appendUInt8(version)
|
||||
}
|
||||
|
||||
data.appendUInt8(preferredVersion)
|
||||
data.appendString(clientVersion)
|
||||
data.appendString(platform)
|
||||
|
||||
if let capabilities = capabilities {
|
||||
data.appendUInt8(UInt8(capabilities.count))
|
||||
for capability in capabilities {
|
||||
data.appendString(capability)
|
||||
}
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
static func fromBinaryData(_ data: Data) -> VersionHello? {
|
||||
// Create defensive copy
|
||||
let dataCopy = Data(data)
|
||||
|
||||
// Minimum size check: flags(1) + versionCount(1) + at least one version(1) + preferredVersion(1) + min strings
|
||||
guard dataCopy.count >= 4 else { return nil }
|
||||
|
||||
var offset = 0
|
||||
|
||||
guard let flags = dataCopy.readUInt8(at: &offset) else { return nil }
|
||||
let hasCapabilities = (flags & 0x01) != 0
|
||||
|
||||
guard let versionCount = dataCopy.readUInt8(at: &offset) else { return nil }
|
||||
var supportedVersions: [UInt8] = []
|
||||
for _ in 0..<versionCount {
|
||||
guard let version = dataCopy.readUInt8(at: &offset) else { return nil }
|
||||
supportedVersions.append(version)
|
||||
}
|
||||
|
||||
guard let preferredVersion = dataCopy.readUInt8(at: &offset),
|
||||
let clientVersion = dataCopy.readString(at: &offset),
|
||||
let platform = dataCopy.readString(at: &offset) else { return nil }
|
||||
|
||||
var capabilities: [String]? = nil
|
||||
if hasCapabilities {
|
||||
guard let capCount = dataCopy.readUInt8(at: &offset) else { return nil }
|
||||
capabilities = []
|
||||
for _ in 0..<capCount {
|
||||
guard let capability = dataCopy.readString(at: &offset) else { return nil }
|
||||
capabilities?.append(capability)
|
||||
}
|
||||
}
|
||||
|
||||
return VersionHello(supportedVersions: supportedVersions,
|
||||
preferredVersion: preferredVersion,
|
||||
clientVersion: clientVersion,
|
||||
platform: platform,
|
||||
capabilities: capabilities)
|
||||
}
|
||||
}
|
||||
|
||||
// Version negotiation acknowledgment
|
||||
struct VersionAck: Codable {
|
||||
let agreedVersion: UInt8 // The version both peers will use
|
||||
let serverVersion: String // Responder's app version
|
||||
let platform: String // Responder's platform
|
||||
let capabilities: [String]? // Responder's capabilities
|
||||
let rejected: Bool // True if no compatible version found
|
||||
let reason: String? // Reason for rejection if applicable
|
||||
|
||||
init(agreedVersion: UInt8,
|
||||
serverVersion: String,
|
||||
platform: String,
|
||||
capabilities: [String]? = nil,
|
||||
rejected: Bool = false,
|
||||
reason: String? = nil) {
|
||||
self.agreedVersion = agreedVersion
|
||||
self.serverVersion = serverVersion
|
||||
self.platform = platform
|
||||
self.capabilities = capabilities
|
||||
self.rejected = rejected
|
||||
self.reason = reason
|
||||
}
|
||||
|
||||
func encode() -> Data? {
|
||||
return try? JSONEncoder().encode(self)
|
||||
}
|
||||
|
||||
static func decode(from data: Data) -> VersionAck? {
|
||||
try? JSONDecoder().decode(VersionAck.self, from: data)
|
||||
}
|
||||
|
||||
// MARK: - Binary Encoding
|
||||
|
||||
func toBinaryData() -> Data {
|
||||
var data = Data()
|
||||
|
||||
// Flags byte: bit 0 = hasCapabilities, bit 1 = hasReason
|
||||
var flags: UInt8 = 0
|
||||
if capabilities != nil { flags |= 0x01 }
|
||||
if reason != nil { flags |= 0x02 }
|
||||
data.appendUInt8(flags)
|
||||
|
||||
data.appendUInt8(agreedVersion)
|
||||
data.appendString(serverVersion)
|
||||
data.appendString(platform)
|
||||
data.appendUInt8(rejected ? 1 : 0)
|
||||
|
||||
if let capabilities = capabilities {
|
||||
data.appendUInt8(UInt8(capabilities.count))
|
||||
for capability in capabilities {
|
||||
data.appendString(capability)
|
||||
}
|
||||
}
|
||||
|
||||
if let reason = reason {
|
||||
data.appendString(reason)
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
static func fromBinaryData(_ data: Data) -> VersionAck? {
|
||||
// Create defensive copy
|
||||
let dataCopy = Data(data)
|
||||
|
||||
// Minimum size: flags(1) + version(1) + rejected(1) + min strings
|
||||
guard dataCopy.count >= 5 else { return nil }
|
||||
|
||||
var offset = 0
|
||||
|
||||
guard let flags = dataCopy.readUInt8(at: &offset) else { return nil }
|
||||
let hasCapabilities = (flags & 0x01) != 0
|
||||
let hasReason = (flags & 0x02) != 0
|
||||
|
||||
guard let agreedVersion = dataCopy.readUInt8(at: &offset),
|
||||
let serverVersion = dataCopy.readString(at: &offset),
|
||||
let platform = dataCopy.readString(at: &offset),
|
||||
let rejectedByte = dataCopy.readUInt8(at: &offset) else { return nil }
|
||||
|
||||
let rejected = rejectedByte != 0
|
||||
|
||||
var capabilities: [String]? = nil
|
||||
if hasCapabilities {
|
||||
guard let capCount = dataCopy.readUInt8(at: &offset) else { return nil }
|
||||
capabilities = []
|
||||
for _ in 0..<capCount {
|
||||
guard let capability = dataCopy.readString(at: &offset) else { return nil }
|
||||
capabilities?.append(capability)
|
||||
}
|
||||
}
|
||||
|
||||
var reason: String? = nil
|
||||
if hasReason {
|
||||
reason = dataCopy.readString(at: &offset)
|
||||
}
|
||||
|
||||
return VersionAck(agreedVersion: agreedVersion,
|
||||
serverVersion: serverVersion,
|
||||
platform: platform,
|
||||
capabilities: capabilities,
|
||||
rejected: rejected,
|
||||
reason: reason)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Delivery Status
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user