mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-27 06:25:22 +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 {
|
enum BinaryMessageType: UInt8 {
|
||||||
case deliveryAck = 0x01
|
case deliveryAck = 0x01
|
||||||
case readReceipt = 0x02
|
case readReceipt = 0x02
|
||||||
case versionHello = 0x07
|
|
||||||
case versionAck = 0x08
|
|
||||||
case noiseIdentityAnnouncement = 0x09
|
case noiseIdentityAnnouncement = 0x09
|
||||||
case noiseMessage = 0x0A
|
case noiseMessage = 0x0A
|
||||||
}
|
}
|
||||||
@@ -223,8 +223,8 @@ struct BinaryProtocol {
|
|||||||
guard offset + 1 <= unpaddedData.count else { return nil }
|
guard offset + 1 <= unpaddedData.count else { return nil }
|
||||||
let version = unpaddedData[offset]; offset += 1
|
let version = unpaddedData[offset]; offset += 1
|
||||||
|
|
||||||
// Check if version is supported
|
// Check if version is 1 (only supported version)
|
||||||
guard ProtocolVersion.isSupported(version) else {
|
guard version == 1 else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -152,10 +152,6 @@ enum MessageType: UInt8 {
|
|||||||
case noiseEncrypted = 0x12 // Noise encrypted transport message
|
case noiseEncrypted = 0x12 // Noise encrypted transport message
|
||||||
case noiseIdentityAnnounce = 0x13 // Announce static public key for discovery
|
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
|
// Protocol-level acknowledgments
|
||||||
case protocolAck = 0x22 // Generic protocol acknowledgment
|
case protocolAck = 0x22 // Generic protocol acknowledgment
|
||||||
case protocolNack = 0x23 // Negative acknowledgment (failure)
|
case protocolNack = 0x23 // Negative acknowledgment (failure)
|
||||||
@@ -181,8 +177,6 @@ enum MessageType: UInt8 {
|
|||||||
case .noiseHandshakeResp: return "noiseHandshakeResp"
|
case .noiseHandshakeResp: return "noiseHandshakeResp"
|
||||||
case .noiseEncrypted: return "noiseEncrypted"
|
case .noiseEncrypted: return "noiseEncrypted"
|
||||||
case .noiseIdentityAnnounce: return "noiseIdentityAnnounce"
|
case .noiseIdentityAnnounce: return "noiseIdentityAnnounce"
|
||||||
case .versionHello: return "versionHello"
|
|
||||||
case .versionAck: return "versionAck"
|
|
||||||
case .protocolAck: return "protocolAck"
|
case .protocolAck: return "protocolAck"
|
||||||
case .protocolNack: return "protocolNack"
|
case .protocolNack: return "protocolNack"
|
||||||
case .systemValidation: return "systemValidation"
|
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
|
// MARK: - Delivery Status
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user