Skip to content
This repository has been archived by the owner on Sep 29, 2024. It is now read-only.

Commit

Permalink
Replace key flag with session-wide isRenegotiating
Browse files Browse the repository at this point in the history
Prevent new if one in progress.

Fixes #105
  • Loading branch information
keeshux committed Jul 9, 2019
1 parent 0f2234f commit 40139cb
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 12 deletions.
21 changes: 15 additions & 6 deletions TunnelKit/Sources/Protocols/OpenVPN/OpenVPNSession.swift
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ public class OpenVPNSession: Session {

private var currentKeyIdx: UInt8?

private var isRenegotiating: Bool

private var negotiationKey: OpenVPN.SessionKey {
guard let key = keys[negotiationKeyIdx] else {
fatalError("Keys are empty or index \(negotiationKeyIdx) not found in \(keys.keys)")
Expand Down Expand Up @@ -196,6 +198,7 @@ public class OpenVPNSession: Session {
keys = [:]
oldKeys = []
negotiationKeyIdx = 0
isRenegotiating = false
lastPing = BidirectionalState(withResetValue: Date.distantPast)
isStopping = false

Expand Down Expand Up @@ -324,6 +327,7 @@ public class OpenVPNSession: Session {
oldKeys.removeAll()
negotiationKeyIdx = 0
currentKeyIdx = nil
isRenegotiating = false

nextPushRequestDate = nil
connectedDate = nil
Expand Down Expand Up @@ -487,7 +491,7 @@ public class OpenVPNSession: Session {
}

case .softResetV1:
if !negotiationKey.softReset {
if !isRenegotiating {
softReset(isServerInitiated: true)
}

Expand Down Expand Up @@ -580,7 +584,7 @@ public class OpenVPNSession: Session {
continuatedPushReplyMessage = nil
pushReply = nil
negotiationKeyIdx = 0
let newKey = OpenVPN.SessionKey(id: UInt8(negotiationKeyIdx))
let newKey = OpenVPN.SessionKey(id: UInt8(negotiationKeyIdx), timeout: CoreConfiguration.OpenVPN.negotiationTimeout)
keys[negotiationKeyIdx] = newKey
log.debug("Negotiation key index is \(negotiationKeyIdx)")

Expand Down Expand Up @@ -614,6 +618,10 @@ public class OpenVPNSession: Session {

// Ruby: soft_reset
private func softReset(isServerInitiated: Bool) {
guard !isRenegotiating else {
log.warning("Renegotiation already in progress")
return
}
if isServerInitiated {
log.debug("Handle soft reset")
} else {
Expand All @@ -622,12 +630,12 @@ public class OpenVPNSession: Session {

resetControlChannel(forNewSession: false)
negotiationKeyIdx = max(1, (negotiationKeyIdx + 1) % OpenVPN.ProtocolMacros.numberOfKeys)
let newKey = OpenVPN.SessionKey(id: UInt8(negotiationKeyIdx))
let newKey = OpenVPN.SessionKey(id: UInt8(negotiationKeyIdx), timeout: CoreConfiguration.OpenVPN.softNegotiationTimeout)
keys[negotiationKeyIdx] = newKey
log.debug("Negotiation key index is \(negotiationKeyIdx)")

negotiationKey.state = .softReset
negotiationKey.softReset = true
isRenegotiating = true
loopNegotiation()
if !isServerInitiated {
enqueueControlPackets(code: .softResetV1, key: UInt8(negotiationKeyIdx), payload: Data())
Expand Down Expand Up @@ -694,8 +702,9 @@ public class OpenVPNSession: Session {
log.debug("TLS.ifconfig: Send pulled ciphertext (\(cipherTextOut.count) bytes)")
enqueueControlPackets(code: .controlV1, key: negotiationKey.id, payload: cipherTextOut)

if negotiationKey.softReset {
if isRenegotiating {
completeConnection()
isRenegotiating = false
}
nextPushRequestDate = Date().addingTimeInterval(CoreConfiguration.OpenVPN.pushRequestInterval)
}
Expand Down Expand Up @@ -862,7 +871,7 @@ public class OpenVPNSession: Session {
}

negotiationKey.controlState = .preIfConfig
nextPushRequestDate = Date().addingTimeInterval(negotiationKey.softReset ? CoreConfiguration.OpenVPN.softResetDelay : CoreConfiguration.OpenVPN.retransmissionLimit)
nextPushRequestDate = Date().addingTimeInterval(isRenegotiating ? CoreConfiguration.OpenVPN.softResetDelay : CoreConfiguration.OpenVPN.retransmissionLimit)
pushRequest()
}

Expand Down
10 changes: 4 additions & 6 deletions TunnelKit/Sources/Protocols/OpenVPN/SessionKey.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ extension OpenVPN {

let id: UInt8 // 3-bit

let timeout: TimeInterval

let startTime: Date

var state = State.invalid
Expand All @@ -70,16 +72,14 @@ extension OpenVPN {

var dataPath: DataPath?

var softReset: Bool

private var isTLSConnected: Bool

init(id: UInt8) {
init(id: UInt8, timeout: TimeInterval) {
self.id = id
self.timeout = timeout

startTime = Date()
state = .invalid
softReset = false
isTLSConnected = false
}

Expand All @@ -90,8 +90,6 @@ extension OpenVPN {

// Ruby: Key.negotiate_timeout
func didNegotiationTimeOut(link: LinkInterface) -> Bool {
let timeout = (softReset ? CoreConfiguration.OpenVPN.softNegotiationTimeout : CoreConfiguration.OpenVPN.negotiationTimeout)

return ((controlState != .connected) && (-startTime.timeIntervalSinceNow > timeout))
}

Expand Down

0 comments on commit 40139cb

Please sign in to comment.