diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2018-05-13 18:23:40 +0200 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2018-05-13 18:26:09 +0200 |
commit | 2c27ab205c992d3387574aa6d57780744d35d36f (patch) | |
tree | e95bb88db16bac5d2050d3db13cd28570f44cd72 /indextable.go | |
parent | 233f079a9479279d2aab68f4accb139ee87ad664 (diff) |
Rework index hashtable
Diffstat (limited to 'indextable.go')
-rw-r--r-- | indextable.go | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/indextable.go b/indextable.go new file mode 100644 index 0000000..2d947cd --- /dev/null +++ b/indextable.go @@ -0,0 +1,97 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. + */ + +package main + +import ( + "crypto/rand" + "sync" + "unsafe" +) + +type IndexTableEntry struct { + peer *Peer + handshake *Handshake + keypair *Keypair +} + +type IndexTable struct { + mutex 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.mutex.Lock() + defer table.mutex.Unlock() + table.table = make(map[uint32]IndexTableEntry) +} + +func (table *IndexTable) Delete(index uint32) { + table.mutex.Lock() + defer table.mutex.Unlock() + delete(table.table, index) +} + +func (table *IndexTable) SwapIndexForKeypair(index uint32, keypair *Keypair) { + table.mutex.Lock() + defer table.mutex.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.mutex.RLock() + _, ok := table.table[index] + table.mutex.RUnlock() + if ok { + continue + } + + // check again while locked + + table.mutex.Lock() + _, found := table.table[index] + if found { + table.mutex.Unlock() + continue + } + table.table[index] = IndexTableEntry{ + peer: peer, + handshake: handshake, + keypair: nil, + } + table.mutex.Unlock() + return index, nil + } +} + +func (table *IndexTable) Lookup(id uint32) IndexTableEntry { + table.mutex.RLock() + defer table.mutex.RUnlock() + return table.table[id] +} |