diff --git a/agents/send_agent.go b/agents/send_agent.go index f40e912..3139320 100644 --- a/agents/send_agent.go +++ b/agents/send_agent.go @@ -79,7 +79,9 @@ func (a *SendingAgent) Run(conn *Connection) { if len(packet.GetFrames()) == 0 { a.Logger.Printf("Preparing a packet for encryption level %s resulted in an empty packet, discarding\n", level.String()) + conn.PacketNumberLock.Lock() conn.PacketNumber[packet.PNSpace()]-- // Avoids PN skipping + conn.PacketNumberLock.Unlock() return nil } return packet diff --git a/connection.go b/connection.go index f9b4c5a..17f57f9 100644 --- a/connection.go +++ b/connection.go @@ -65,6 +65,7 @@ type Connection struct { Token []byte ResumptionTicket []byte + PacketNumberLock sync.Locker PacketNumber map[PNSpace]PacketNumber // Stores the next PN to be sent LargestPNsReceived map[PNSpace]PacketNumber // Stores the largest PN received LargestPNsAcknowledged map[PNSpace]PacketNumber // Stores the largest PN we have sent that were acknowledged by the peer @@ -83,8 +84,10 @@ func (c *Connection) ConnectedIp() net.Addr { return c.UdpConnection.RemoteAddr() } func (c *Connection) nextPacketNumber(space PNSpace) PacketNumber { // TODO: This should be thread safe + c.PacketNumberLock.Lock() pn := c.PacketNumber[space] c.PacketNumber[space]++ + c.PacketNumberLock.Unlock() return pn } func (c *Connection) EncodeAndEncrypt(packet Packet, level EncryptionLevel) []byte { @@ -237,6 +240,7 @@ func (c *Connection) TransitionTo(version uint32, ALPN string) { c.Version = version c.ALPN = ALPN c.Tls = pigotls.NewConnection(c.ServerName, c.ALPN, c.ResumptionTicket) + c.PacketNumberLock = &sync.Mutex{} c.PacketNumber = make(map[PNSpace]PacketNumber) c.LargestPNsReceived = make(map[PNSpace]PacketNumber) c.LargestPNsAcknowledged = make(map[PNSpace]PacketNumber)