diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2019-03-03 04:04:41 +0100 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2019-03-03 05:00:40 +0100 |
commit | 69f0fe67b63d90e523a5a1241fb1b46c2e8dbe03 (patch) | |
tree | 1ef86da3242afde462dcadb7241bb09f499d5bd7 /device/indextable.go | |
parent | d435be35cac49af9367b2005d831d55e570c4b1b (diff) |
global: begin modularization
Diffstat (limited to 'device/indextable.go')
-rw-r--r-- | device/indextable.go | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/device/indextable.go b/device/indextable.go new file mode 100644 index 0000000..4cba970 --- /dev/null +++ b/device/indextable.go @@ -0,0 +1,97 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (C) 2017-2019 WireGuard LLC. All Rights Reserved. + */ + +package device + +import ( + "crypto/rand" + "sync" + "unsafe" +) + +type IndexTableEntry struct { + peer *Peer + handshake *Handshake + keypair *Keypair +} + +type IndexTable struct { + sync.RWMutex + table map[uint32]IndexTableEntry +} + +func randUint32() (uint32, error) { + var integer [4]byte + _, err := rand.Read(integer[:]) + return *(*uint32)(unsafe.Pointer(&integer[0])), err +} + +func (table *IndexTable) Init() { + table.Lock() + defer table.Unlock() + table.table = make(map[uint32]IndexTableEntry) +} + +func (table *IndexTable) Delete(index uint32) { + table.Lock() + defer table.Unlock() + delete(table.table, index) +} + +func (table *IndexTable) SwapIndexForKeypair(index uint32, keypair *Keypair) { + table.Lock() + defer table.Unlock() + entry, ok := table.table[index] + if !ok { + return + } + table.table[index] = IndexTableEntry{ + peer: entry.peer, + keypair: keypair, + handshake: nil, + } +} + +func (table *IndexTable) NewIndexForHandshake(peer *Peer, handshake *Handshake) (uint32, error) { + for { + // generate random index + + index, err := randUint32() + if err != nil { + return index, err + } + + // check if index used + + table.RLock() + _, ok := table.table[index] + table.RUnlock() + if ok { + continue + } + + // check again while locked + + table.Lock() + _, found := table.table[index] + if found { + table.Unlock() + continue + } + table.table[index] = IndexTableEntry{ + peer: peer, + handshake: handshake, + keypair: nil, + } + table.Unlock() + return index, nil + } +} + +func (table *IndexTable) Lookup(id uint32) IndexTableEntry { + table.RLock() + defer table.RUnlock() + return table.table[id] +} |