Allow keep alive timeout to be configured by the server or client
This commit is contained in:
parent
9619d21d15
commit
55f7e64f19
|
@ -163,6 +163,8 @@ extension OpenVPNTunnelProvider {
|
|||
|
||||
static let keepAlive = "KeepAlive"
|
||||
|
||||
static let keepAliveTimeout = "KeepAliveTimeout"
|
||||
|
||||
static let endpointProtocols = "EndpointProtocols"
|
||||
|
||||
static let renegotiatesAfter = "RenegotiatesAfter"
|
||||
|
@ -497,6 +499,9 @@ private extension OpenVPN.Configuration {
|
|||
if let keepAliveInterval = providerConfiguration[S.keepAlive] as? TimeInterval {
|
||||
builder.keepAliveInterval = keepAliveInterval
|
||||
}
|
||||
if let keepAliveTimeout = providerConfiguration[S.keepAliveTimeout] as? TimeInterval {
|
||||
builder.keepAliveTimeout = keepAliveTimeout
|
||||
}
|
||||
if let renegotiatesAfter = providerConfiguration[S.renegotiatesAfter] as? TimeInterval {
|
||||
builder.renegotiatesAfter = renegotiatesAfter
|
||||
}
|
||||
|
@ -571,6 +576,9 @@ private extension OpenVPN.Configuration {
|
|||
if let keepAliveSeconds = keepAliveInterval {
|
||||
dict[S.keepAlive] = keepAliveSeconds
|
||||
}
|
||||
if let keepAliveTimeoutSeconds = keepAliveTimeout {
|
||||
dict[S.keepAliveTimeout] = keepAliveTimeoutSeconds
|
||||
}
|
||||
if let renegotiatesAfterSeconds = renegotiatesAfter {
|
||||
dict[S.renegotiatesAfter] = renegotiatesAfterSeconds
|
||||
}
|
||||
|
@ -632,9 +640,14 @@ private extension OpenVPN.Configuration {
|
|||
log.info("\tTLS security level: default")
|
||||
}
|
||||
if let keepAliveSeconds = keepAliveInterval, keepAliveSeconds > 0 {
|
||||
log.info("\tKeep-alive: \(keepAliveSeconds) seconds")
|
||||
log.info("\tKeep-alive interval: \(keepAliveSeconds) seconds")
|
||||
} else {
|
||||
log.info("\tKeep-alive: never")
|
||||
log.info("\tKeep-alive interval: never")
|
||||
}
|
||||
if let keepAliveTimeoutSeconds = keepAliveTimeout, keepAliveTimeoutSeconds > 0 {
|
||||
log.info("\tKeep-alive timeout: \(keepAliveTimeoutSeconds) seconds")
|
||||
} else {
|
||||
log.info("\tKeep-alive timeout: never")
|
||||
}
|
||||
if let renegotiatesAfterSeconds = renegotiatesAfter, renegotiatesAfterSeconds > 0 {
|
||||
log.info("\tRenegotiation: \(renegotiatesAfterSeconds) seconds")
|
||||
|
|
|
@ -202,6 +202,9 @@ extension OpenVPN {
|
|||
/// Sends periodical keep-alive packets if set.
|
||||
public var keepAliveInterval: TimeInterval?
|
||||
|
||||
/// Disconnects after no keep-alive packets are recieved within timeout interval if set.
|
||||
public var keepAliveTimeout: TimeInterval?
|
||||
|
||||
/// The number of seconds after which a renegotiation should be initiated. If `nil`, the client will never initiate a renegotiation.
|
||||
public var renegotiatesAfter: TimeInterval?
|
||||
|
||||
|
@ -277,6 +280,7 @@ extension OpenVPN {
|
|||
tlsWrap: tlsWrap,
|
||||
tlsSecurityLevel: tlsSecurityLevel,
|
||||
keepAliveInterval: keepAliveInterval,
|
||||
keepAliveTimeout: keepAliveTimeout,
|
||||
renegotiatesAfter: renegotiatesAfter,
|
||||
hostname: hostname,
|
||||
endpointProtocols: endpointProtocols,
|
||||
|
@ -346,6 +350,9 @@ extension OpenVPN {
|
|||
|
||||
/// - Seealso: `ConfigurationBuilder.keepAliveInterval`
|
||||
public let keepAliveInterval: TimeInterval?
|
||||
|
||||
/// - Seealso: `ConfigurationBuilder.keepAliveTimeout`
|
||||
public let keepAliveTimeout: TimeInterval?
|
||||
|
||||
/// - Seealso: `ConfigurationBuilder.renegotiatesAfter`
|
||||
public let renegotiatesAfter: TimeInterval?
|
||||
|
@ -435,6 +442,7 @@ extension OpenVPN.Configuration {
|
|||
builder.tlsWrap = tlsWrap
|
||||
builder.tlsSecurityLevel = tlsSecurityLevel
|
||||
builder.keepAliveInterval = keepAliveInterval
|
||||
builder.keepAliveTimeout = keepAliveTimeout
|
||||
builder.renegotiatesAfter = renegotiatesAfter
|
||||
builder.hostname = hostname
|
||||
builder.endpointProtocols = endpointProtocols
|
||||
|
|
|
@ -52,6 +52,8 @@ extension OpenVPN {
|
|||
|
||||
static let ping = NSRegularExpression("^ping +\\d+")
|
||||
|
||||
static let pingRestart = NSRegularExpression("^ping-restart +\\d+")
|
||||
|
||||
static let renegSec = NSRegularExpression("^reneg-sec +\\d+")
|
||||
|
||||
static let blockBegin = NSRegularExpression("^<[\\w\\-]+>")
|
||||
|
@ -203,6 +205,7 @@ extension OpenVPN {
|
|||
var optTLSKeyLines: [Substring]?
|
||||
var optTLSStrategy: TLSWrap.Strategy?
|
||||
var optKeepAliveSeconds: TimeInterval?
|
||||
var optKeepAliveTimeoutSeconds: TimeInterval?
|
||||
var optRenegotiateAfterSeconds: TimeInterval?
|
||||
//
|
||||
var optHostname: String?
|
||||
|
@ -398,6 +401,13 @@ extension OpenVPN {
|
|||
}
|
||||
optKeepAliveSeconds = TimeInterval(arg)
|
||||
}
|
||||
Regex.pingRestart.enumerateArguments(in: line) {
|
||||
isHandled = true
|
||||
guard let arg = $0.first else {
|
||||
return
|
||||
}
|
||||
optKeepAliveTimeoutSeconds = TimeInterval(arg)
|
||||
}
|
||||
Regex.renegSec.enumerateArguments(in: line) {
|
||||
isHandled = true
|
||||
guard let arg = $0.first else {
|
||||
|
@ -599,6 +609,7 @@ extension OpenVPN {
|
|||
}
|
||||
|
||||
sessionBuilder.keepAliveInterval = optKeepAliveSeconds
|
||||
sessionBuilder.keepAliveTimeout = optKeepAliveTimeoutSeconds
|
||||
sessionBuilder.renegotiatesAfter = optRenegotiateAfterSeconds
|
||||
|
||||
// MARK: Client
|
||||
|
|
|
@ -87,8 +87,8 @@ public class OpenVPNSession: Session {
|
|||
|
||||
private var keepAliveInterval: TimeInterval? {
|
||||
let interval: TimeInterval?
|
||||
if let negInterval = pushReply?.options.keepAliveInterval, negInterval > 0 {
|
||||
interval = TimeInterval(negInterval)
|
||||
if let negInterval = pushReply?.options.keepAliveInterval, negInterval > 0.0 {
|
||||
interval = negInterval
|
||||
} else if let cfgInterval = configuration.keepAliveInterval, cfgInterval > 0.0 {
|
||||
interval = cfgInterval
|
||||
} else {
|
||||
|
@ -97,6 +97,16 @@ public class OpenVPNSession: Session {
|
|||
return interval
|
||||
}
|
||||
|
||||
private var keepAliveTimeout: TimeInterval {
|
||||
if let negTimeout = pushReply?.options.keepAliveTimeout, negTimeout > 0.0 {
|
||||
return negTimeout
|
||||
} else if let cfgTimeout = configuration.keepAliveTimeout, cfgTimeout > 0.0 {
|
||||
return cfgTimeout
|
||||
} else {
|
||||
return CoreConfiguration.OpenVPN.pingTimeout
|
||||
}
|
||||
}
|
||||
|
||||
/// An optional `OpenVPNSessionDelegate` for receiving session events.
|
||||
public weak var delegate: OpenVPNSessionDelegate?
|
||||
|
||||
|
@ -535,7 +545,7 @@ public class OpenVPNSession: Session {
|
|||
}
|
||||
|
||||
let now = Date()
|
||||
guard (now.timeIntervalSince(lastPing.inbound) <= CoreConfiguration.OpenVPN.pingTimeout) else {
|
||||
guard (now.timeIntervalSince(lastPing.inbound) <= keepAliveTimeout) else {
|
||||
deferStop(.shutdown, OpenVPNError.pingTimeout)
|
||||
return
|
||||
}
|
||||
|
@ -1070,7 +1080,10 @@ public class OpenVPNSession: Session {
|
|||
log.info("\tNegotiated compression algorithm: \(negCompression)")
|
||||
}
|
||||
if let negPing = pushReply.options.keepAliveInterval {
|
||||
log.info("\tNegotiated keep-alive: \(negPing) seconds")
|
||||
log.info("\tNegotiated keep-alive interval: \(negPing) seconds")
|
||||
}
|
||||
if let negPingRestart = pushReply.options.keepAliveTimeout {
|
||||
log.info("\tNegotiated keep-alive timeout: \(negPingRestart) seconds")
|
||||
}
|
||||
|
||||
let bridge: OpenVPN.EncryptionBridge
|
||||
|
|
|
@ -156,6 +156,14 @@ class PushTests: XCTestCase {
|
|||
XCTAssertEqual(reply.options.keepAliveInterval, 10)
|
||||
}
|
||||
|
||||
func testPingRestart() {
|
||||
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! OpenVPN.PushReply(message: msg)!
|
||||
reply.debug()
|
||||
|
||||
XCTAssertEqual(reply.options.keepAliveTimeout, 60)
|
||||
}
|
||||
|
||||
func testProvost() {
|
||||
let msg = "PUSH_REPLY,route 87.233.192.218,route 87.233.192.219,route 87.233.192.220,route 87.248.186.252,route 92.241.171.245,route 103.246.200.0 255.255.252.0,route 109.239.140.0 255.255.255.0,route 128.199.0.0 255.255.0.0,route 13.125.0.0 255.255.0.0,route 13.230.0.0 255.254.0.0,route 13.56.0.0 255.252.0.0,route 149.154.160.0 255.255.252.0,route 149.154.164.0 255.255.252.0,route 149.154.168.0 255.255.252.0,route 149.154.172.0 255.255.252.0,route 159.122.128.0 255.255.192.0,route 159.203.0.0 255.255.0.0,route 159.65.0.0 255.255.0.0,route 159.89.0.0 255.255.0.0,route 165.227.0.0 255.255.0.0,route 167.99.0.0 255.255.0.0,route 174.138.0.0 255.255.128.0,route 176.67.169.0 255.255.255.0,route 178.239.88.0 255.255.248.0,route 178.63.0.0 255.255.0.0,route 18.130.0.0 255.255.0.0,route 18.144.0.0 255.255.0.0,route 18.184.0.0 255.254.0.0,route 18.194.0.0 255.254.0.0,route 18.196.0.0 255.254.0.0,route 18.204.0.0 255.252.0.0,push-continuation 2"
|
||||
let reply = try? OpenVPN.PushReply(message: msg)!
|
||||
|
|
Loading…
Reference in New Issue