func (device *Device) BindSetMark(mark uint32) error {
- device.net.mutex.Lock()
- defer device.net.mutex.Unlock()
+ device.net.Lock()
+ defer device.net.Unlock()
// check if modified
// clear cached source addresses
- device.peers.mutex.RLock()
+ device.peers.RLock()
for _, peer := range device.peers.keyMap {
- peer.mutex.Lock()
- defer peer.mutex.Unlock()
+ peer.Lock()
+ defer peer.Unlock()
if peer.endpoint != nil {
peer.endpoint.ClearSrc()
}
}
- device.peers.mutex.RUnlock()
+ device.peers.RUnlock()
return nil
}
func (device *Device) BindUpdate() error {
- device.net.mutex.Lock()
- defer device.net.mutex.Unlock()
+ device.net.Lock()
+ defer device.net.Unlock()
// close existing sockets
// clear cached source addresses
- device.peers.mutex.RLock()
+ device.peers.RLock()
for _, peer := range device.peers.keyMap {
- peer.mutex.Lock()
- defer peer.mutex.Unlock()
+ peer.Lock()
+ defer peer.Unlock()
if peer.endpoint != nil {
peer.endpoint.ClearSrc()
}
}
- device.peers.mutex.RUnlock()
+ device.peers.RUnlock()
// start receiving routines
}
func (device *Device) BindClose() error {
- device.net.mutex.Lock()
+ device.net.Lock()
err := unsafeCloseBind(device)
- device.net.mutex.Unlock()
+ device.net.Unlock()
return err
}
if !ok {
break
}
- pePtr.peer.mutex.Lock()
+ pePtr.peer.Lock()
if &pePtr.peer.endpoint != pePtr.endpoint {
- pePtr.peer.mutex.Unlock()
+ pePtr.peer.Unlock()
break
}
if uint32(pePtr.peer.endpoint.(*NativeEndpoint).src4().ifindex) == ifidx {
- pePtr.peer.mutex.Unlock()
+ pePtr.peer.Unlock()
break
}
pePtr.peer.endpoint.(*NativeEndpoint).ClearSrc()
- pePtr.peer.mutex.Unlock()
+ pePtr.peer.Unlock()
}
attr = attr[attrhdr.Len:]
}
reqPeer = make(map[uint32]peerEndpointPtr)
reqPeerLock.Unlock()
go func() {
- device.peers.mutex.RLock()
+ device.peers.RLock()
i := uint32(1)
for _, peer := range device.peers.keyMap {
- peer.mutex.RLock()
+ peer.RLock()
if peer.endpoint == nil || peer.endpoint.(*NativeEndpoint) == nil {
- peer.mutex.RUnlock()
+ peer.RUnlock()
continue
}
if peer.endpoint.(*NativeEndpoint).isV6 || peer.endpoint.(*NativeEndpoint).src4().ifindex == 0 {
- peer.mutex.RUnlock()
+ peer.RUnlock()
break
}
nlmsg := struct {
endpoint: &peer.endpoint,
}
reqPeerLock.Unlock()
- peer.mutex.RUnlock()
+ peer.RUnlock()
i++
_, err := bind.netlinkCancel.Write((*[unsafe.Sizeof(nlmsg)]byte)(unsafe.Pointer(&nlmsg))[:])
if err != nil {
break
}
}
- device.peers.mutex.RUnlock()
+ device.peers.RUnlock()
}()
}
remain = remain[hdr.Len:]
)
type CookieChecker struct {
- mutex sync.RWMutex
- mac1 struct {
+ sync.RWMutex
+ mac1 struct {
key [blake2s.Size]byte
}
mac2 struct {
}
type CookieGenerator struct {
- mutex sync.RWMutex
- mac1 struct {
+ sync.RWMutex
+ mac1 struct {
key [blake2s.Size]byte
}
mac2 struct {
}
func (st *CookieChecker) Init(pk NoisePublicKey) {
- st.mutex.Lock()
- defer st.mutex.Unlock()
+ st.Lock()
+ defer st.Unlock()
// mac1 state
}
func (st *CookieChecker) CheckMAC1(msg []byte) bool {
- st.mutex.RLock()
- defer st.mutex.RUnlock()
+ st.RLock()
+ defer st.RUnlock()
size := len(msg)
smac2 := size - blake2s.Size128
}
func (st *CookieChecker) CheckMAC2(msg []byte, src []byte) bool {
- st.mutex.RLock()
- defer st.mutex.RUnlock()
+ st.RLock()
+ defer st.RUnlock()
if time.Now().Sub(st.mac2.secretSet) > CookieRefreshTime {
return false
src []byte,
) (*MessageCookieReply, error) {
- st.mutex.RLock()
+ st.RLock()
// refresh cookie secret
if time.Now().Sub(st.mac2.secretSet) > CookieRefreshTime {
- st.mutex.RUnlock()
- st.mutex.Lock()
+ st.RUnlock()
+ st.Lock()
_, err := rand.Read(st.mac2.secret[:])
if err != nil {
- st.mutex.Unlock()
+ st.Unlock()
return nil, err
}
st.mac2.secretSet = time.Now()
- st.mutex.Unlock()
- st.mutex.RLock()
+ st.Unlock()
+ st.RLock()
}
// derive cookie
_, err := rand.Read(reply.Nonce[:])
if err != nil {
- st.mutex.RUnlock()
+ st.RUnlock()
return nil, err
}
xchapoly, _ := chacha20poly1305.NewX(st.mac2.encryptionKey[:])
xchapoly.Seal(reply.Cookie[:0], reply.Nonce[:], cookie[:], msg[smac1:smac2])
- st.mutex.RUnlock()
+ st.RUnlock()
return reply, nil
}
func (st *CookieGenerator) Init(pk NoisePublicKey) {
- st.mutex.Lock()
- defer st.mutex.Unlock()
+ st.Lock()
+ defer st.Unlock()
func() {
hash, _ := blake2s.New256(nil)
}
func (st *CookieGenerator) ConsumeReply(msg *MessageCookieReply) bool {
- st.mutex.Lock()
- defer st.mutex.Unlock()
+ st.Lock()
+ defer st.Unlock()
if !st.mac2.hasLastMAC1 {
return false
mac1 := msg[smac1:smac2]
mac2 := msg[smac2:]
- st.mutex.Lock()
- defer st.mutex.Unlock()
+ st.Lock()
+ defer st.Unlock()
// set mac1
state struct {
starting sync.WaitGroup
stopping sync.WaitGroup
- mutex sync.Mutex
+ sync.Mutex
changing AtomicBool
current bool
}
net struct {
starting sync.WaitGroup
stopping sync.WaitGroup
- mutex sync.RWMutex
- bind Bind // bind interface
- port uint16 // listening port
- fwmark uint32 // mark value (0 = disabled)
+ sync.RWMutex
+ bind Bind // bind interface
+ port uint16 // listening port
+ fwmark uint32 // mark value (0 = disabled)
}
staticIdentity struct {
- mutex sync.RWMutex
+ sync.RWMutex
privateKey NoisePrivateKey
publicKey NoisePublicKey
}
peers struct {
- mutex sync.RWMutex
+ sync.RWMutex
keyMap map[NoisePublicKey]*Peer
}
/* Converts the peer into a "zombie", which remains in the peer map,
* but processes no packets and does not exists in the routing table.
*
- * Must hold device.peers.mutex.
+ * Must hold device.peers.Mutex
*/
func unsafeRemovePeer(device *Device, peer *Peer, key NoisePublicKey) {
// compare to current state of device
- device.state.mutex.Lock()
+ device.state.Lock()
newIsUp := device.isUp.Get()
if newIsUp == device.state.current {
device.state.changing.Set(false)
- device.state.mutex.Unlock()
+ device.state.Unlock()
return
}
device.isUp.Set(false)
break
}
- device.peers.mutex.RLock()
+ device.peers.RLock()
for _, peer := range device.peers.keyMap {
peer.Start()
}
- device.peers.mutex.RUnlock()
+ device.peers.RUnlock()
case false:
device.BindClose()
- device.peers.mutex.RLock()
+ device.peers.RLock()
for _, peer := range device.peers.keyMap {
peer.Stop()
}
- device.peers.mutex.RUnlock()
+ device.peers.RUnlock()
}
// update state variables
device.state.current = newIsUp
device.state.changing.Set(false)
- device.state.mutex.Unlock()
+ device.state.Unlock()
// check for state change in the mean time
// lock required resources
- device.staticIdentity.mutex.Lock()
- defer device.staticIdentity.mutex.Unlock()
+ device.staticIdentity.Lock()
+ defer device.staticIdentity.Unlock()
- device.peers.mutex.Lock()
- defer device.peers.mutex.Unlock()
+ device.peers.Lock()
+ defer device.peers.Unlock()
for _, peer := range device.peers.keyMap {
peer.handshake.mutex.RLock()
}
func (device *Device) LookupPeer(pk NoisePublicKey) *Peer {
- device.peers.mutex.RLock()
- defer device.peers.mutex.RUnlock()
+ device.peers.RLock()
+ defer device.peers.RUnlock()
return device.peers.keyMap[pk]
}
func (device *Device) RemovePeer(key NoisePublicKey) {
- device.peers.mutex.Lock()
- defer device.peers.mutex.Unlock()
+ device.peers.Lock()
+ defer device.peers.Unlock()
// stop peer and remove from routing
}
func (device *Device) RemoveAllPeers() {
- device.peers.mutex.Lock()
- defer device.peers.mutex.Unlock()
+ device.peers.Lock()
+ defer device.peers.Unlock()
for key, peer := range device.peers.keyMap {
unsafeRemovePeer(device, peer, key)
device.log.Info.Println("Device closing")
device.state.changing.Set(true)
- device.state.mutex.Lock()
- defer device.state.mutex.Unlock()
+ device.state.Lock()
+ defer device.state.Unlock()
device.tun.device.Close()
device.BindClose()
}
type IndexTable struct {
- mutex sync.RWMutex
+ sync.RWMutex
table map[uint32]IndexTableEntry
}
}
func (table *IndexTable) Init() {
- table.mutex.Lock()
- defer table.mutex.Unlock()
+ table.Lock()
+ defer table.Unlock()
table.table = make(map[uint32]IndexTableEntry)
}
func (table *IndexTable) Delete(index uint32) {
- table.mutex.Lock()
- defer table.mutex.Unlock()
+ table.Lock()
+ defer table.Unlock()
delete(table.table, index)
}
func (table *IndexTable) SwapIndexForKeypair(index uint32, keypair *Keypair) {
- table.mutex.Lock()
- defer table.mutex.Unlock()
+ table.Lock()
+ defer table.Unlock()
entry, ok := table.table[index]
if !ok {
return
// check if index used
- table.mutex.RLock()
+ table.RLock()
_, ok := table.table[index]
- table.mutex.RUnlock()
+ table.RUnlock()
if ok {
continue
}
// check again while locked
- table.mutex.Lock()
+ table.Lock()
_, found := table.table[index]
if found {
- table.mutex.Unlock()
+ table.Unlock()
continue
}
table.table[index] = IndexTableEntry{
handshake: handshake,
keypair: nil,
}
- table.mutex.Unlock()
+ table.Unlock()
return index, nil
}
}
func (table *IndexTable) Lookup(id uint32) IndexTableEntry {
- table.mutex.RLock()
- defer table.mutex.RUnlock()
+ table.RLock()
+ defer table.RUnlock()
return table.table[id]
}
}
type Keypairs struct {
- mutex sync.RWMutex
+ sync.RWMutex
current *Keypair
previous *Keypair
next *Keypair
}
func (kp *Keypairs) Current() *Keypair {
- kp.mutex.RLock()
- defer kp.mutex.RUnlock()
+ kp.RLock()
+ defer kp.RUnlock()
return kp.current
}
)
type AtomicBool struct {
- flag int32
+ int32
}
func (a *AtomicBool) Get() bool {
- return atomic.LoadInt32(&a.flag) == AtomicTrue
+ return atomic.LoadInt32(&a.int32) == AtomicTrue
}
func (a *AtomicBool) Swap(val bool) bool {
if val {
flag = AtomicTrue
}
- return atomic.SwapInt32(&a.flag, flag) == AtomicTrue
+ return atomic.SwapInt32(&a.int32, flag) == AtomicTrue
}
func (a *AtomicBool) Set(val bool) {
if val {
flag = AtomicTrue
}
- atomic.StoreInt32(&a.flag, flag)
+ atomic.StoreInt32(&a.int32, flag)
}
func min(a, b uint) uint {
func (device *Device) CreateMessageInitiation(peer *Peer) (*MessageInitiation, error) {
- device.staticIdentity.mutex.RLock()
- defer device.staticIdentity.mutex.RUnlock()
+ device.staticIdentity.RLock()
+ defer device.staticIdentity.RUnlock()
handshake := &peer.handshake
handshake.mutex.Lock()
return nil
}
- device.staticIdentity.mutex.RLock()
- defer device.staticIdentity.mutex.RUnlock()
+ device.staticIdentity.RLock()
+ defer device.staticIdentity.RUnlock()
mixHash(&hash, &InitialHash, device.staticIdentity.publicKey[:])
mixHash(&hash, &hash, msg.Ephemeral[:])
// lock private key for reading
- device.staticIdentity.mutex.RLock()
- defer device.staticIdentity.mutex.RUnlock()
+ device.staticIdentity.RLock()
+ defer device.staticIdentity.RUnlock()
// finish 3-way DH
// rotate key pairs
keypairs := &peer.keypairs
- keypairs.mutex.Lock()
- defer keypairs.mutex.Unlock()
+ keypairs.Lock()
+ defer keypairs.Unlock()
previous := keypairs.previous
next := keypairs.next
if keypairs.next != receivedKeypair {
return false
}
- keypairs.mutex.Lock()
- defer keypairs.mutex.Unlock()
+ keypairs.Lock()
+ defer keypairs.Unlock()
if keypairs.next != receivedKeypair {
return false
}
type Peer struct {
isRunning AtomicBool
- mutex sync.RWMutex // Mostly protects endpoint, but is generally taken whenever we modify peer
+ sync.RWMutex // Mostly protects endpoint, but is generally taken whenever we modify peer
keypairs Keypairs
handshake Handshake
device *Device
}
routines struct {
- mutex sync.Mutex // held when stopping / starting routines
- starting sync.WaitGroup // routines pending start
- stopping sync.WaitGroup // routines pending stop
- stop chan struct{} // size 0, stop all go routines in peer
+ sync.Mutex // held when stopping / starting routines
+ starting sync.WaitGroup // routines pending start
+ stopping sync.WaitGroup // routines pending stop
+ stop chan struct{} // size 0, stop all go routines in peer
}
cookieGenerator CookieGenerator
// lock resources
- device.staticIdentity.mutex.RLock()
- defer device.staticIdentity.mutex.RUnlock()
+ device.staticIdentity.RLock()
+ defer device.staticIdentity.RUnlock()
- device.peers.mutex.Lock()
- defer device.peers.mutex.Unlock()
+ device.peers.Lock()
+ defer device.peers.Unlock()
// check if over limit
// create peer
peer := new(Peer)
- peer.mutex.Lock()
- defer peer.mutex.Unlock()
+ peer.Lock()
+ defer peer.Unlock()
peer.cookieGenerator.Init(pk)
peer.device = device
}
func (peer *Peer) SendBuffer(buffer []byte) error {
- peer.device.net.mutex.RLock()
- defer peer.device.net.mutex.RUnlock()
+ peer.device.net.RLock()
+ defer peer.device.net.RUnlock()
if peer.device.net.bind == nil {
return errors.New("no bind")
}
- peer.mutex.RLock()
- defer peer.mutex.RUnlock()
+ peer.RLock()
+ defer peer.RUnlock()
if peer.endpoint == nil {
return errors.New("no known endpoint for peer")
// prevent simultaneous start/stop operations
- peer.routines.mutex.Lock()
- defer peer.routines.mutex.Unlock()
+ peer.routines.Lock()
+ defer peer.routines.Unlock()
if peer.isRunning.Get() {
return
// clear key pairs
keypairs := &peer.keypairs
- keypairs.mutex.Lock()
+ keypairs.Lock()
device.DeleteKeypair(keypairs.previous)
device.DeleteKeypair(keypairs.current)
device.DeleteKeypair(keypairs.next)
keypairs.previous = nil
keypairs.current = nil
keypairs.next = nil
- keypairs.mutex.Unlock()
+ keypairs.Unlock()
// clear handshake state
peer.routines.starting.Wait()
- peer.routines.mutex.Lock()
- defer peer.routines.mutex.Unlock()
+ peer.routines.Lock()
+ defer peer.routines.Unlock()
peer.device.log.Debug.Println(peer, "- Stopping...")
if roamingDisabled {
return
}
- peer.mutex.Lock()
+ peer.Lock()
peer.endpoint = endpoint
- peer.mutex.Unlock()
+ peer.Unlock()
}
)
type RatelimiterEntry struct {
- mutex sync.Mutex
+ sync.Mutex
lastTime time.Time
tokens int64
}
type Ratelimiter struct {
- mutex sync.RWMutex
+ sync.RWMutex
stopReset chan struct{}
tableIPv4 map[[net.IPv4len]byte]*RatelimiterEntry
tableIPv6 map[[net.IPv6len]byte]*RatelimiterEntry
}
func (rate *Ratelimiter) Close() {
- rate.mutex.Lock()
- defer rate.mutex.Unlock()
+ rate.Lock()
+ defer rate.Unlock()
if rate.stopReset != nil {
close(rate.stopReset)
}
func (rate *Ratelimiter) Init() {
- rate.mutex.Lock()
- defer rate.mutex.Unlock()
+ rate.Lock()
+ defer rate.Unlock()
// stop any ongoing garbage collection routine
}
case <-ticker.C:
func() {
- rate.mutex.Lock()
- defer rate.mutex.Unlock()
+ rate.Lock()
+ defer rate.Unlock()
for key, entry := range rate.tableIPv4 {
- entry.mutex.Lock()
+ entry.Lock()
if time.Now().Sub(entry.lastTime) > garbageCollectTime {
delete(rate.tableIPv4, key)
}
- entry.mutex.Unlock()
+ entry.Unlock()
}
for key, entry := range rate.tableIPv6 {
- entry.mutex.Lock()
+ entry.Lock()
if time.Now().Sub(entry.lastTime) > garbageCollectTime {
delete(rate.tableIPv6, key)
}
- entry.mutex.Unlock()
+ entry.Unlock()
}
if len(rate.tableIPv4) == 0 && len(rate.tableIPv6) == 0 {
IPv4 := ip.To4()
IPv6 := ip.To16()
- rate.mutex.RLock()
+ rate.RLock()
if IPv4 != nil {
copy(keyIPv4[:], IPv4)
entry = rate.tableIPv6[keyIPv6]
}
- rate.mutex.RUnlock()
+ rate.RUnlock()
// make new entry if not found
entry = new(RatelimiterEntry)
entry.tokens = maxTokens - packetCost
entry.lastTime = time.Now()
- rate.mutex.Lock()
+ rate.Lock()
if IPv4 != nil {
rate.tableIPv4[keyIPv4] = entry
if len(rate.tableIPv4) == 1 && len(rate.tableIPv6) == 0 {
rate.stopReset <- struct{}{}
}
}
- rate.mutex.Unlock()
+ rate.Unlock()
return true
}
// add tokens to entry
- entry.mutex.Lock()
+ entry.Lock()
now := time.Now()
entry.tokens += now.Sub(entry.lastTime).Nanoseconds()
entry.lastTime = now
if entry.tokens > packetCost {
entry.tokens -= packetCost
- entry.mutex.Unlock()
+ entry.Unlock()
return true
}
- entry.mutex.Unlock()
+ entry.Unlock()
return false
}
}
type QueueInboundElement struct {
- dropped int32
- mutex sync.Mutex
+ dropped int32
+ sync.Mutex
buffer *[MaxMessageSize]byte
packet []byte
counter uint64
return true
default:
element.Drop()
- element.mutex.Unlock()
+ element.Unlock()
return false
}
default:
elem.dropped = AtomicFalse
elem.endpoint = endpoint
elem.counter = 0
- elem.mutex = sync.Mutex{}
- elem.mutex.Lock()
+ elem.Mutex = sync.Mutex{}
+ elem.Lock()
// add to decryption queues
elem.Drop()
device.PutMessageBuffer(elem.buffer)
}
- elem.mutex.Unlock()
+ elem.Unlock()
}
}
}
// wait for decryption
- elem.mutex.Lock()
+ elem.Lock()
if elem.IsDropped() {
continue
import "golang.org/x/sys/unix"
type fdSet struct {
- fdset unix.FdSet
+ unix.FdSet
}
func (fdset *fdSet) set(i int) {
bits := 32 << (^uint(0) >> 63)
- fdset.fdset.Bits[i/bits] |= 1 << uint(i%bits)
+ fdset.Bits[i/bits] |= 1 << uint(i%bits)
}
func (fdset *fdSet) check(i int) bool {
bits := 32 << (^uint(0) >> 63)
- return (fdset.fdset.Bits[i/bits] & (1 << uint(i%bits))) != 0
+ return (fdset.Bits[i/bits] & (1 << uint(i%bits))) != 0
}
fdset := fdSet{}
fdset.set(rw.fd)
fdset.set(closeFd)
- err := unixSelect(max(rw.fd, closeFd)+1, &fdset.fdset, nil, nil, nil)
+ err := unixSelect(max(rw.fd, closeFd)+1, &fdset.FdSet, nil, nil, nil)
if err != nil {
return false
}
fdset := fdSet{}
fdset.set(rw.fd)
fdset.set(closeFd)
- err := unixSelect(max(rw.fd, closeFd)+1, nil, &fdset.fdset, nil, nil)
+ err := unixSelect(max(rw.fd, closeFd)+1, nil, &fdset.FdSet, nil, nil)
if err != nil {
return false
}
type QueueOutboundElement struct {
dropped int32
- mutex sync.Mutex
+ sync.Mutex
buffer *[MaxMessageSize]byte // slice holding the packet data
packet []byte // slice of "buffer" (always!)
nonce uint64 // nonce for encryption
elem := device.GetOutboundElement()
elem.dropped = AtomicFalse
elem.buffer = device.GetMessageBuffer()
- elem.mutex = sync.Mutex{}
+ elem.Mutex = sync.Mutex{}
elem.nonce = 0
elem.keypair = nil
elem.peer = nil
default:
element.Drop()
element.peer.device.PutMessageBuffer(element.buffer)
- element.mutex.Unlock()
+ element.Unlock()
}
default:
element.peer.device.PutMessageBuffer(element.buffer)
elem.keypair = keypair
elem.dropped = AtomicFalse
- elem.mutex.Lock()
+ elem.Lock()
// add to parallel and sequential queue
addToOutboundAndEncryptionQueues(peer.queue.outbound, device.queue.encryption, elem)
if ok && !elem.IsDropped() {
elem.Drop()
device.PutMessageBuffer(elem.buffer)
- elem.mutex.Unlock()
+ elem.Unlock()
}
default:
goto out
elem.packet,
nil,
)
- elem.mutex.Unlock()
+ elem.Unlock()
}
}
}
return
}
- elem.mutex.Lock()
+ elem.Lock()
if elem.IsDropped() {
device.PutOutboundElement(elem)
continue
*/
type Timer struct {
- timer *time.Timer
+ *time.Timer
modifyingLock sync.RWMutex
runningLock sync.Mutex
isPending bool
func (peer *Peer) NewTimer(expirationFunction func(*Peer)) *Timer {
timer := &Timer{}
- timer.timer = time.AfterFunc(time.Hour, func() {
+ timer.Timer = time.AfterFunc(time.Hour, func() {
timer.runningLock.Lock()
timer.modifyingLock.Lock()
expirationFunction(peer)
timer.runningLock.Unlock()
})
- timer.timer.Stop()
+ timer.Stop()
return timer
}
func (timer *Timer) Mod(d time.Duration) {
timer.modifyingLock.Lock()
timer.isPending = true
- timer.timer.Reset(d)
+ timer.Reset(d)
timer.modifyingLock.Unlock()
}
func (timer *Timer) Del() {
timer.modifyingLock.Lock()
timer.isPending = false
- timer.timer.Stop()
+ timer.Stop()
timer.modifyingLock.Unlock()
}
peer.device.log.Debug.Printf("%s - Handshake did not complete after %d seconds, retrying (try %d)\n", peer, int(RekeyTimeout.Seconds()), atomic.LoadUint32(&peer.timers.handshakeAttempts)+1)
/* We clear the endpoint address src address, in case this is the cause of trouble. */
- peer.mutex.Lock()
+ peer.Lock()
if peer.endpoint != nil {
peer.endpoint.ClearSrc()
}
- peer.mutex.Unlock()
+ peer.Unlock()
peer.SendHandshakeInitiation(true)
}
func expiredNewHandshake(peer *Peer) {
peer.device.log.Debug.Printf("%s - Retrying handshake because we stopped hearing back after %d seconds\n", peer, int((KeepaliveTimeout + RekeyTimeout).Seconds()))
/* We clear the endpoint address src address, in case this is the cause of trouble. */
- peer.mutex.Lock()
+ peer.Lock()
if peer.endpoint != nil {
peer.endpoint.ClearSrc()
}
- peer.mutex.Unlock()
+ peer.Unlock()
peer.SendHandshakeInitiation(false)
}
)
type IPCError struct {
- Code int64
+ int64
}
func (s *IPCError) Error() string {
- return fmt.Sprintf("IPC error: %d", s.Code)
+ return fmt.Sprintf("IPC error: %d", s.int64)
}
func (s *IPCError) ErrorCode() int64 {
- return s.Code
+ return s.int64
}
func ipcGetOperation(device *Device, socket *bufio.ReadWriter) *IPCError {
// lock required resources
- device.net.mutex.RLock()
- defer device.net.mutex.RUnlock()
+ device.net.RLock()
+ defer device.net.RUnlock()
- device.staticIdentity.mutex.RLock()
- defer device.staticIdentity.mutex.RUnlock()
+ device.staticIdentity.RLock()
+ defer device.staticIdentity.RUnlock()
- device.peers.mutex.RLock()
- defer device.peers.mutex.RUnlock()
+ device.peers.RLock()
+ defer device.peers.RUnlock()
// serialize device related values
// serialize each peer state
for _, peer := range device.peers.keyMap {
- peer.mutex.RLock()
- defer peer.mutex.RUnlock()
+ peer.RLock()
+ defer peer.RUnlock()
send("public_key=" + peer.handshake.remoteStatic.ToHex())
send("preshared_key=" + peer.handshake.presharedKey.ToHex())
for _, line := range lines {
_, err := socket.WriteString(line + "\n")
if err != nil {
- return &IPCError{
- Code: ipcErrorIO,
- }
+ return &IPCError{ipcErrorIO}
}
}
}
parts := strings.Split(line, "=")
if len(parts) != 2 {
- return &IPCError{Code: ipcErrorProtocol}
+ return &IPCError{ipcErrorProtocol}
}
key := parts[0]
value := parts[1]
err := sk.FromHex(value)
if err != nil {
logError.Println("Failed to set private_key:", err)
- return &IPCError{Code: ipcErrorInvalid}
+ return &IPCError{ipcErrorInvalid}
}
logDebug.Println("UAPI: Updating private key")
device.SetPrivateKey(sk)
port, err := strconv.ParseUint(value, 10, 16)
if err != nil {
logError.Println("Failed to parse listen_port:", err)
- return &IPCError{Code: ipcErrorInvalid}
+ return &IPCError{ipcErrorInvalid}
}
// update port and rebind
logDebug.Println("UAPI: Updating listen port")
- device.net.mutex.Lock()
+ device.net.Lock()
device.net.port = uint16(port)
- device.net.mutex.Unlock()
+ device.net.Unlock()
if err := device.BindUpdate(); err != nil {
logError.Println("Failed to set listen_port:", err)
- return &IPCError{Code: ipcErrorPortInUse}
+ return &IPCError{ipcErrorPortInUse}
}
case "fwmark":
if err != nil {
logError.Println("Invalid fwmark", err)
- return &IPCError{Code: ipcErrorInvalid}
+ return &IPCError{ipcErrorInvalid}
}
logDebug.Println("UAPI: Updating fwmark")
if err := device.BindSetMark(uint32(fwmark)); err != nil {
logError.Println("Failed to update fwmark:", err)
- return &IPCError{Code: ipcErrorPortInUse}
+ return &IPCError{ipcErrorPortInUse}
}
case "public_key":
case "replace_peers":
if value != "true" {
logError.Println("Failed to set replace_peers, invalid value:", value)
- return &IPCError{Code: ipcErrorInvalid}
+ return &IPCError{ipcErrorInvalid}
}
logDebug.Println("UAPI: Removing all peers")
device.RemoveAllPeers()
default:
logError.Println("Invalid UAPI device key:", key)
- return &IPCError{Code: ipcErrorInvalid}
+ return &IPCError{ipcErrorInvalid}
}
}
err := publicKey.FromHex(value)
if err != nil {
logError.Println("Failed to get peer by public key:", err)
- return &IPCError{Code: ipcErrorInvalid}
+ return &IPCError{ipcErrorInvalid}
}
// ignore peer with public key of device
- device.staticIdentity.mutex.RLock()
+ device.staticIdentity.RLock()
dummy = device.staticIdentity.publicKey.Equals(publicKey)
- device.staticIdentity.mutex.RUnlock()
+ device.staticIdentity.RUnlock()
if dummy {
peer = &Peer{}
peer, err = device.NewPeer(publicKey)
if err != nil {
logError.Println("Failed to create new peer:", err)
- return &IPCError{Code: ipcErrorInvalid}
+ return &IPCError{ipcErrorInvalid}
}
logDebug.Println(peer, "- UAPI: Created")
}
if value != "true" {
logError.Println("Failed to set remove, invalid value:", value)
- return &IPCError{Code: ipcErrorInvalid}
+ return &IPCError{ipcErrorInvalid}
}
if !dummy {
logDebug.Println(peer, "- UAPI: Removing")
if err != nil {
logError.Println("Failed to set preshared key:", err)
- return &IPCError{Code: ipcErrorInvalid}
+ return &IPCError{ipcErrorInvalid}
}
case "endpoint":
logDebug.Println(peer, "- UAPI: Updating endpoint")
err := func() error {
- peer.mutex.Lock()
- defer peer.mutex.Unlock()
+ peer.Lock()
+ defer peer.Unlock()
endpoint, err := CreateEndpoint(value)
if err != nil {
return err
if err != nil {
logError.Println("Failed to set endpoint:", value)
- return &IPCError{Code: ipcErrorInvalid}
+ return &IPCError{ipcErrorInvalid}
}
case "persistent_keepalive_interval":
secs, err := strconv.ParseUint(value, 10, 16)
if err != nil {
logError.Println("Failed to set persistent keepalive interval:", err)
- return &IPCError{Code: ipcErrorInvalid}
+ return &IPCError{ipcErrorInvalid}
}
old := peer.persistentKeepaliveInterval
if old == 0 && secs != 0 {
if err != nil {
logError.Println("Failed to get tun device status:", err)
- return &IPCError{Code: ipcErrorIO}
+ return &IPCError{ipcErrorIO}
}
if device.isUp.Get() && !dummy {
peer.SendKeepalive()
if value != "true" {
logError.Println("Failed to replace allowedips, invalid value:", value)
- return &IPCError{Code: ipcErrorInvalid}
+ return &IPCError{ipcErrorInvalid}
}
if dummy {
_, network, err := net.ParseCIDR(value)
if err != nil {
logError.Println("Failed to set allowed ip:", err)
- return &IPCError{Code: ipcErrorInvalid}
+ return &IPCError{ipcErrorInvalid}
}
if dummy {
if value != "1" {
logError.Println("Invalid protocol version:", value)
- return &IPCError{Code: ipcErrorInvalid}
+ return &IPCError{ipcErrorInvalid}
}
default:
logError.Println("Invalid UAPI peer key:", key)
- return &IPCError{Code: ipcErrorInvalid}
+ return &IPCError{ipcErrorInvalid}
}
}
}