Merge pull request #22 from keeshux/parse-ping-from-push-reply

Parse ping from PUSH_REPLY
This commit is contained in:
Davide De Rosa 2018-09-09 00:56:54 +02:00 committed by GitHub
commit eee1ea510f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 52 additions and 14 deletions

View File

@ -150,6 +150,9 @@ public protocol SessionReply {
/// The optional compression framing. /// The optional compression framing.
var compressionFraming: SessionProxy.CompressionFraming? { get } var compressionFraming: SessionProxy.CompressionFraming? { get }
/// The optional keep-alive interval.
var ping: Int? { get }
/// The optional authentication token. /// The optional authentication token.
var authToken: String? { get } var authToken: String? { get }
@ -191,6 +194,8 @@ extension SessionProxy {
private static let compRegexp = try! NSRegularExpression(pattern: "comp(ress|-lzo)", options: []) private static let compRegexp = try! NSRegularExpression(pattern: "comp(ress|-lzo)", options: [])
private static let pingRegexp = try! NSRegularExpression(pattern: "ping \\d+", options: [])
private static let authTokenRegexp = try! NSRegularExpression(pattern: "auth-token [a-zA-Z0-9/=+]+", options: []) private static let authTokenRegexp = try! NSRegularExpression(pattern: "auth-token [a-zA-Z0-9/=+]+", options: [])
private static let peerIdRegexp = try! NSRegularExpression(pattern: "peer-id [0-9]+", options: []) private static let peerIdRegexp = try! NSRegularExpression(pattern: "peer-id [0-9]+", options: [])
@ -207,6 +212,8 @@ extension SessionProxy {
let compressionFraming: SessionProxy.CompressionFraming? let compressionFraming: SessionProxy.CompressionFraming?
let ping: Int?
let authToken: String? let authToken: String?
let peerId: UInt32? let peerId: UInt32?
@ -232,6 +239,7 @@ extension SessionProxy {
var dnsServers: [String] = [] var dnsServers: [String] = []
var compressionFraming: SessionProxy.CompressionFraming? var compressionFraming: SessionProxy.CompressionFraming?
var ping: Int?
var authToken: String? var authToken: String?
var peerId: UInt32? var peerId: UInt32?
var cipher: SessionProxy.Cipher? var cipher: SessionProxy.Cipher?
@ -388,6 +396,12 @@ extension SessionProxy {
} }
} }
// MARK: Keep-alive
PushReply.pingRegexp.enumerateArguments(in: message) {
ping = Int($0[0])
}
// MARK: Authentication // MARK: Authentication
PushReply.authTokenRegexp.enumerateArguments(in: message) { PushReply.authTokenRegexp.enumerateArguments(in: message) {
@ -406,6 +420,7 @@ extension SessionProxy {
self.dnsServers = dnsServers self.dnsServers = dnsServers
self.compressionFraming = compressionFraming self.compressionFraming = compressionFraming
self.ping = ping
self.authToken = authToken self.authToken = authToken
self.peerId = peerId self.peerId = peerId
self.cipher = cipher self.cipher = cipher

View File

@ -85,6 +85,18 @@ public class SessionProxy {
private let configuration: Configuration private let configuration: Configuration
private var keepAliveInterval: TimeInterval? {
let interval: TimeInterval?
if let negInterval = pushReply?.ping, negInterval > 0 {
interval = TimeInterval(negInterval)
} else if let cfgInterval = configuration.keepAliveInterval, cfgInterval > 0.0 {
interval = cfgInterval
} else {
return nil
}
return interval
}
/// An optional `SessionProxyDelegate` for receiving session events. /// An optional `SessionProxyDelegate` for receiving session events.
public weak var delegate: SessionProxyDelegate? public weak var delegate: SessionProxyDelegate?
@ -583,13 +595,11 @@ public class SessionProxy {
return return
} }
if let interval = configuration.keepAliveInterval, interval > 0 { // postpone ping if elapsed less than keep-alive
if let interval = keepAliveInterval {
let elapsed = now.timeIntervalSince(lastPingOut) let elapsed = now.timeIntervalSince(lastPingOut)
guard (elapsed >= interval) else { guard (elapsed >= interval) else {
let remaining = min(interval, interval - elapsed) scheduleNextPing(elapsed: elapsed)
queue.asyncAfter(deadline: .now() + remaining) { [weak self] in
self?.ping()
}
return return
} }
} }
@ -598,10 +608,16 @@ public class SessionProxy {
sendDataPackets([DataPacket.pingString]) sendDataPackets([DataPacket.pingString])
lastPingOut = Date() lastPingOut = Date()
if let interval = configuration.keepAliveInterval, interval > 0 { scheduleNextPing()
queue.asyncAfter(deadline: .now() + interval) { [weak self] in
self?.ping()
} }
private func scheduleNextPing(elapsed: TimeInterval = 0.0) {
guard let interval = keepAliveInterval else {
return
}
let remaining = min(interval, interval - elapsed)
queue.asyncAfter(deadline: .now() + remaining) { [weak self] in
self?.ping()
} }
} }
@ -904,11 +920,7 @@ public class SessionProxy {
} }
delegate?.sessionDidStart(self, remoteAddress: remoteAddress, reply: reply) delegate?.sessionDidStart(self, remoteAddress: remoteAddress, reply: reply)
if let interval = configuration.keepAliveInterval, interval > 0 { scheduleNextPing()
queue.asyncAfter(deadline: .now() + interval) { [weak self] in
self?.ping()
}
}
} }
// Ruby: transition_keys // Ruby: transition_keys
@ -1040,6 +1052,9 @@ public class SessionProxy {
if let negFraming = pushedFraming { if let negFraming = pushedFraming {
log.debug("Negotiated compression framing: \(negFraming.rawValue)") log.debug("Negotiated compression framing: \(negFraming.rawValue)")
} }
if let negPing = pushReply.ping {
log.debug("Negotiated keep-alive: \(negPing) seconds")
}
let pushedCipher = pushReply.cipher let pushedCipher = pushReply.cipher
if let negCipher = pushedCipher { if let negCipher = pushedCipher {
log.debug("Negotiated cipher: \(negCipher.rawValue)") log.debug("Negotiated cipher: \(negCipher.rawValue)")

View File

@ -115,4 +115,12 @@ class PushTests: XCTestCase {
XCTAssertEqual(reply.cipher, .aes256gcm) XCTAssertEqual(reply.cipher, .aes256gcm)
} }
func testPing() {
let msg = "PUSH_REPLY,route 192.168.1.0 255.255.255.0,route 10.0.2.0 255.255.255.0,dhcp-option DNS 192.168.1.99,dhcp-option DNS 176.103.130.130,route 10.0.2.1,topology net30,ping 10,ping-restart 60,ifconfig 10.0.2.14 10.0.2.13"
let reply = try! SessionProxy.PushReply(message: msg)!
reply.debug()
XCTAssertEqual(reply.ping, 10)
}
} }