Forget endpoint for incoming connections after a little while

This commit is contained in:
Ludvig Strigeus 2018-11-17 17:24:48 +01:00
parent ddb48a5aff
commit 2a73a27e68
2 changed files with 19 additions and 4 deletions

View file

@ -632,7 +632,7 @@ void WireguardProcessor::RunAllMainThreadScheduled() {
void WireguardProcessor::SendHandshakeInitiation(WgPeer *peer) {
assert(dev_.IsMainThread());
if (!peer->CheckHandshakeRateLimit())
if (!peer->CheckHandshakeRateLimit() || peer->endpoint_.sin.sin_family == 0)
return;
stats_.handshakes_out++;
Packet *packet = AllocPacket();
@ -646,6 +646,15 @@ void WireguardProcessor::SendHandshakeInitiation(WgPeer *peer) {
packet->addr = peer->endpoint_;
packet->protocol = peer->endpoint_protocol_;
peer->tx_bytes_ += packet->size;
// If this is an incoming oneway connection (such as tcp), forget the
// endpoint after a number of attempts.
if (attempts >= 3 && peer->allow_endpoint_change_ &&
(peer->endpoint_protocol_ & kPacketProtocolIncomingConnection)) {
peer->endpoint_protocol_ = 0;
peer->endpoint_.sin.sin_family = 0;
}
WG_RELEASE_LOCK(peer->mutex_);
DoWriteUdpPacket(packet);
if (attempts > 1 && attempts <= 20)

View file

@ -747,6 +747,10 @@ WgPeer *WgPeer::ParseMessageHandshakeResponse(WgDevice *dev, const Packet *packe
peer_and_keypair->second = keypair;
WG_ACQUIRE_LOCK(peer->mutex_);
if (peer->allow_endpoint_change_) {
peer->endpoint_ = packet->addr;
peer->endpoint_protocol_ = packet->protocol;
}
peer->rx_bytes_ += packet->size;
peer->InsertKeypairInPeer_Locked(keypair);
WG_RELEASE_LOCK(peer->mutex_);
@ -1182,7 +1186,7 @@ uint32 WgPeer::CheckTimeouts_Locked(uint64 now) {
if (t & 0x1F) {
if ((t & (1 << TIMER_RETRANSMIT_HANDSHAKE)) && (now32 - timer_value_[TIMER_RETRANSMIT_HANDSHAKE]) >= REKEY_TIMEOUT_MS) {
t ^= (1 << TIMER_RETRANSMIT_HANDSHAKE);
if (handshake_attempts_ > MAX_HANDSHAKE_ATTEMPTS) {
if (handshake_attempts_ > MAX_HANDSHAKE_ATTEMPTS || endpoint_.sin.sin_family == 0) {
t &= ~(1 << TIMER_SEND_KEEPALIVE);
ClearPacketQueue_Locked();
} else {
@ -1208,9 +1212,11 @@ uint32 WgPeer::CheckTimeouts_Locked(uint64 now) {
}
if ((t & (1 << TIMER_NEW_HANDSHAKE)) && (now32 - timer_value_[TIMER_NEW_HANDSHAKE]) >= KEEPALIVE_TIMEOUT_MS + REKEY_TIMEOUT_MS) {
t &= ~(1 << TIMER_NEW_HANDSHAKE);
if (endpoint_.sin.sin_family != 0) {
handshake_attempts_ = 0;
rv |= ACTION_SEND_HANDSHAKE;
}
}
if ((t & (1 << TIMER_ZERO_KEYS)) && (now32 - timer_value_[TIMER_ZERO_KEYS]) >= REJECT_AFTER_TIME_MS * 3) {
RINFO("Expiring all keys for peer");
t &= ~(1 << TIMER_ZERO_KEYS);