mirror of
https://github.com/OpenVPN/openvpn3.git
synced 2024-09-20 20:13:05 +02:00
ssl/proto: increment packet-id in control retransmit
Control packets are retransmitted if ACK hasn't been received with certain time. This often happens with PUSH_REQUEST, since it might take a while for the client to set up tun device and routing. In this case client doesn't send ACK fast enough and server retransmits. When using tls-auth (like in case of CloudVPN), most control packets contain "packet-id" field. On retransmit, openvpn3 doesn't increment packet-id value, unlike openvpn2. This triggers high verbosity replay protection warnings in openvpn2 clients. Openvpn3 client also generates replay errors, but they're only dumped to log at the end of session. Fix by storing unencapsulated packets in send reliability object and do encapculation on send and retransmit. This way packet-id will be incremented on retransmit and no replay errors will occur on the client side. Signed-off-by: Lev Stipakov <lev@openvpn.net>
This commit is contained in:
parent
7765540e58
commit
acdcab8675
@ -1312,6 +1312,15 @@ namespace openvpn {
|
||||
{
|
||||
}
|
||||
|
||||
// clone packet, including buffer content
|
||||
Packet clone() const
|
||||
{
|
||||
Packet pkt;
|
||||
pkt.opcode = opcode;
|
||||
pkt.buf.reset(new BufferAllocated(*buf));
|
||||
return pkt;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
reset_non_buf();
|
||||
|
@ -56,6 +56,9 @@ namespace openvpn {
|
||||
// Constructor for BufferPtr:
|
||||
// explicit PACKET(const BufferPtr& buf)
|
||||
//
|
||||
// Return cloned packet, including cloned buffer content:
|
||||
// PACKET clone() const
|
||||
//
|
||||
// Test if defined:
|
||||
// operator bool() const
|
||||
//
|
||||
@ -196,7 +199,19 @@ namespace openvpn {
|
||||
typename ReliableSend::Message& m = rel_send.ref_by_id(i);
|
||||
if (m.ready_retransmit(*now))
|
||||
{
|
||||
parent().net_send(m.packet, NET_SEND_RETRANSMIT);
|
||||
// preserve original packet non-encapsulated
|
||||
PACKET pkt = m.packet.clone();
|
||||
|
||||
// encapsulate packet
|
||||
try {
|
||||
parent().encapsulate(m.id(), pkt);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
error(Error::ENCAPSULATION_ERROR);
|
||||
throw;
|
||||
}
|
||||
parent().net_send(pkt, NET_SEND_RETRANSMIT);
|
||||
m.reset_retransmit(*now, tls_timeout);
|
||||
}
|
||||
}
|
||||
@ -343,9 +358,12 @@ namespace openvpn {
|
||||
typename ReliableSend::Message& m = rel_send.send(*now, tls_timeout);
|
||||
m.packet = PACKET(ssl_->read_ciphertext());
|
||||
|
||||
// encapsulate and send cloned packet, preserve original one for retransmit
|
||||
PACKET pkt = m.packet.clone();
|
||||
|
||||
// encapsulate packet
|
||||
try {
|
||||
parent().encapsulate(m.id(), m.packet);
|
||||
parent().encapsulate(m.id(), pkt);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
@ -354,7 +372,7 @@ namespace openvpn {
|
||||
}
|
||||
|
||||
// transmit it
|
||||
parent().net_send(m.packet, NET_SEND_SSL);
|
||||
parent().net_send(pkt, NET_SEND_SSL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -368,9 +386,11 @@ namespace openvpn {
|
||||
m.packet = raw_write_queue.front();
|
||||
raw_write_queue.pop_front();
|
||||
|
||||
PACKET pkt = m.packet.clone();
|
||||
|
||||
// encapsulate packet
|
||||
try {
|
||||
parent().encapsulate(m.id(), m.packet);
|
||||
parent().encapsulate(m.id(), pkt);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
@ -379,7 +399,7 @@ namespace openvpn {
|
||||
}
|
||||
|
||||
// transmit it
|
||||
parent().net_send(m.packet, NET_SEND_RAW);
|
||||
parent().net_send(pkt, NET_SEND_RAW);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user