package device
import (
+ "container/list"
"errors"
"math/bits"
"net"
)
type trieEntry struct {
- child [2]*trieEntry
- peer *Peer
- bits net.IP
- cidr uint
- bit_at_byte uint
- bit_at_shift uint
- nextEntryForPeer *trieEntry
- pprevEntryForPeer **trieEntry
+ child [2]*trieEntry
+ peer *Peer
+ bits net.IP
+ cidr uint
+ bit_at_byte uint
+ bit_at_shift uint
+ perPeerElem *list.Element
}
func isLittleEndian() bool {
}
func (node *trieEntry) addToPeerEntries() {
- p := node.peer
- first := p.firstTrieEntry
- node.nextEntryForPeer = first
- if first != nil {
- first.pprevEntryForPeer = &node.nextEntryForPeer
- }
- p.firstTrieEntry = node
- node.pprevEntryForPeer = &p.firstTrieEntry
+ node.perPeerElem = node.peer.trieEntries.PushBack(node)
}
func (node *trieEntry) removeFromPeerEntries() {
- if node.pprevEntryForPeer == nil {
- return
- }
- next := node.nextEntryForPeer
- pprev := node.pprevEntryForPeer
- *pprev = next
- if next != nil {
- next.pprevEntryForPeer = pprev
+ if node.perPeerElem != nil {
+ node.peer.trieEntries.Remove(node.perPeerElem)
+ node.perPeerElem = nil
}
- node.nextEntryForPeer = nil
- node.pprevEntryForPeer = nil
}
func (node *trieEntry) removeByPeer(p *Peer) *trieEntry {
table.mutex.RLock()
defer table.mutex.RUnlock()
- for node := peer.firstTrieEntry; node != nil; node = node.nextEntryForPeer {
+ for elem := peer.trieEntries.Front(); elem != nil; elem = elem.Next() {
+ node := elem.Value.(*trieEntry)
if !cb(node.bits, node.cidr) {
return
}
package device
import (
+ "container/list"
"encoding/base64"
"errors"
"fmt"
)
type Peer struct {
- isRunning AtomicBool
- sync.RWMutex // Mostly protects endpoint, but is generally taken whenever we modify peer
- keypairs Keypairs
- handshake Handshake
- device *Device
- endpoint conn.Endpoint
- persistentKeepaliveInterval uint32 // accessed atomically
- firstTrieEntry *trieEntry
- stopping sync.WaitGroup // routines pending stop
+ isRunning AtomicBool
+ sync.RWMutex // Mostly protects endpoint, but is generally taken whenever we modify peer
+ keypairs Keypairs
+ handshake Handshake
+ device *Device
+ endpoint conn.Endpoint
+ stopping sync.WaitGroup // routines pending stop
// These fields are accessed with atomic operations, which must be
// 64-bit aligned even on 32-bit platforms. Go guarantees that an
inbound *autodrainingInboundQueue // sequential ordering of tun writing
}
- cookieGenerator CookieGenerator
+ cookieGenerator CookieGenerator
+ trieEntries list.List
+ persistentKeepaliveInterval uint32 // accessed atomically
}
func (device *Device) NewPeer(pk NoisePublicKey) (*Peer, error) {