Fixing Race Conditions
the build was successful
Details
the build was successful
Details
This commit is contained in:
parent
9ba39b93b7
commit
5a1fc1b94d
|
@ -33,7 +33,7 @@ pipeline:
|
||||||
commands:
|
commands:
|
||||||
- ./tor -f ./torrc
|
- ./tor -f ./torrc
|
||||||
- sleep 15
|
- sleep 15
|
||||||
- go test -v git.openprivacy.ca/openprivacy/libricochet-go/testing
|
- go test -race -v git.openprivacy.ca/openprivacy/libricochet-go/testing
|
||||||
notify-email:
|
notify-email:
|
||||||
image: drillster/drone-email
|
image: drillster/drone-email
|
||||||
host: build.openprivacy.ca
|
host: build.openprivacy.ca
|
||||||
|
|
|
@ -144,7 +144,9 @@ func (ra *RicochetApplication) Run(ls connectivity.ListenService) {
|
||||||
if !ra.v3identity.Initialized() || ra.contactManager == nil {
|
if !ra.v3identity.Initialized() || ra.contactManager == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
ra.lock.Lock()
|
||||||
ra.ls = ls
|
ra.ls = ls
|
||||||
|
ra.lock.Unlock()
|
||||||
var err error
|
var err error
|
||||||
for err == nil {
|
for err == nil {
|
||||||
conn, err := ra.ls.Accept()
|
conn, err := ra.ls.Accept()
|
||||||
|
|
|
@ -33,6 +33,7 @@ type Connection struct {
|
||||||
messageBuilder utils.MessageBuilder
|
messageBuilder utils.MessageBuilder
|
||||||
|
|
||||||
closed bool
|
closed bool
|
||||||
|
closingLock sync.Mutex
|
||||||
closing bool
|
closing bool
|
||||||
// This mutex is exclusively for preventing races during blocking
|
// This mutex is exclusively for preventing races during blocking
|
||||||
// interactions with Process; specifically Do and Break. Don't use
|
// interactions with Process; specifically Do and Break. Don't use
|
||||||
|
@ -311,6 +312,8 @@ func (rc *Connection) Process(handler Handler) error {
|
||||||
go func() {
|
go func() {
|
||||||
rc.processBlockMutex.Lock()
|
rc.processBlockMutex.Lock()
|
||||||
defer rc.processBlockMutex.Unlock()
|
defer rc.processBlockMutex.Unlock()
|
||||||
|
rc.closingLock.Lock()
|
||||||
|
defer rc.closingLock.Unlock()
|
||||||
rc.closed = true
|
rc.closed = true
|
||||||
close(closedChan)
|
close(closedChan)
|
||||||
}()
|
}()
|
||||||
|
@ -468,5 +471,7 @@ func (rc *Connection) Close() {
|
||||||
// Kill the Ricochet Connection.
|
// Kill the Ricochet Connection.
|
||||||
log.Debugf("Closing Ricochet Connection for %v", rc.RemoteHostname)
|
log.Debugf("Closing Ricochet Connection for %v", rc.RemoteHostname)
|
||||||
rc.conn.Close()
|
rc.conn.Close()
|
||||||
|
rc.closingLock.Lock()
|
||||||
rc.closed = true
|
rc.closed = true
|
||||||
|
rc.closingLock.Unlock()
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,9 @@ func TestProcessAuthAs3DHServer(t *testing.T) {
|
||||||
t.Errorf("Error while testing ProcessAuthAsServer: %v", err)
|
t.Errorf("Error while testing ProcessAuthAsServer: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Wait for server to finish
|
||||||
|
time.Sleep(time.Second * 2)
|
||||||
|
|
||||||
// Test Close
|
// Test Close
|
||||||
rc.Close()
|
rc.Close()
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,13 +4,14 @@
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
pwd
|
pwd
|
||||||
go test ${1} -coverprofile=utils.cover.out -v ./utils
|
GORACE="haltonerror=1"
|
||||||
go test ${1} -coverprofile=channels.cover.out -v ./channels
|
go test -race ${1} -coverprofile=utils.cover.out -v ./utils
|
||||||
go test ${1} -coverprofile=channels.v3.inbound.cover.out -v ./channels/v3/inbound
|
go test -race ${1} -coverprofile=channels.cover.out -v ./channels
|
||||||
go test ${1} -coverprofile=connection.cover.out -v ./connection
|
go test -race ${1} -coverprofile=channels.v3.inbound.cover.out -v ./channels/v3/inbound
|
||||||
go test ${1} -coverprofile=policies.cover.out -v ./policies
|
go test -race ${1} -coverprofile=connection.cover.out -v ./connection
|
||||||
go test ${1} -coverprofile=identity.cover.out -v ./identity
|
go test -race ${1} -coverprofile=policies.cover.out -v ./policies
|
||||||
go test ${1} -coverprofile=root.cover.out -v ./
|
go test -race ${1} -coverprofile=identity.cover.out -v ./identity
|
||||||
|
go test -race ${1} -coverprofile=root.cover.out -v ./
|
||||||
echo "mode: set" > coverage.out && cat *.cover.out | grep -v mode: | sort -r | \
|
echo "mode: set" > coverage.out && cat *.cover.out | grep -v mode: | sort -r | \
|
||||||
awk '{if($1 != last) {print $0;last=$1}}' >> coverage.out
|
awk '{if($1 != last) {print $0;last=$1}}' >> coverage.out
|
||||||
rm -rf *.cover.out
|
rm -rf *.cover.out
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"git.openprivacy.ca/openprivacy/libricochet-go/log"
|
"git.openprivacy.ca/openprivacy/libricochet-go/log"
|
||||||
"golang.org/x/crypto/nacl/secretbox"
|
"golang.org/x/crypto/nacl/secretbox"
|
||||||
"io"
|
"io"
|
||||||
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -43,10 +44,13 @@ type RicochetNetwork struct {
|
||||||
// Derived ephemeral session key for connection
|
// Derived ephemeral session key for connection
|
||||||
key [32]byte
|
key [32]byte
|
||||||
encrypt bool
|
encrypt bool
|
||||||
|
lock sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetEncryptionKey sets the ephemeral encryption key for this session.
|
// SetEncryptionKey sets the ephemeral encryption key for this session.
|
||||||
func (rn *RicochetNetwork) SetEncryptionKey(key [32]byte) {
|
func (rn *RicochetNetwork) SetEncryptionKey(key [32]byte) {
|
||||||
|
rn.lock.Lock()
|
||||||
|
defer rn.lock.Unlock()
|
||||||
log.Debugf("turning on ephemeral session encryption for connection")
|
log.Debugf("turning on ephemeral session encryption for connection")
|
||||||
copy(rn.key[:], key[:])
|
copy(rn.key[:], key[:])
|
||||||
|
|
||||||
|
@ -67,6 +71,7 @@ func (rn *RicochetNetwork) SendRicochetPacket(dst io.Writer, channel int32, data
|
||||||
binary.BigEndian.PutUint16(packet[2:4], uint16(channel))
|
binary.BigEndian.PutUint16(packet[2:4], uint16(channel))
|
||||||
copy(packet[4:], data[:])
|
copy(packet[4:], data[:])
|
||||||
|
|
||||||
|
rn.lock.Lock()
|
||||||
if rn.encrypt {
|
if rn.encrypt {
|
||||||
var nonce [24]byte
|
var nonce [24]byte
|
||||||
if _, err := io.ReadFull(rand.Reader, nonce[:]); err != nil {
|
if _, err := io.ReadFull(rand.Reader, nonce[:]); err != nil {
|
||||||
|
@ -77,6 +82,7 @@ func (rn *RicochetNetwork) SendRicochetPacket(dst io.Writer, channel int32, data
|
||||||
binary.BigEndian.PutUint16(packet[0:2], uint16(len(encrypted)+2))
|
binary.BigEndian.PutUint16(packet[0:2], uint16(len(encrypted)+2))
|
||||||
packet = append(packet[0:2], encrypted...)
|
packet = append(packet[0:2], encrypted...)
|
||||||
}
|
}
|
||||||
|
rn.lock.Unlock()
|
||||||
|
|
||||||
for pos := 0; pos < len(packet); {
|
for pos := 0; pos < len(packet); {
|
||||||
n, err := dst.Write(packet[pos:])
|
n, err := dst.Write(packet[pos:])
|
||||||
|
@ -112,6 +118,7 @@ func (rn *RicochetNetwork) RecvRicochetPacket(reader io.Reader) (RicochetData, e
|
||||||
return packet, err
|
return packet, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rn.lock.Lock()
|
||||||
if rn.encrypt {
|
if rn.encrypt {
|
||||||
var decryptNonce [24]byte
|
var decryptNonce [24]byte
|
||||||
if len(packetBytes) > 24 {
|
if len(packetBytes) > 24 {
|
||||||
|
@ -127,6 +134,7 @@ func (rn *RicochetNetwork) RecvRicochetPacket(reader io.Reader) (RicochetData, e
|
||||||
return packet, errors.New("ciphertext length was too short")
|
return packet, errors.New("ciphertext length was too short")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
rn.lock.Unlock()
|
||||||
|
|
||||||
packet.Channel = int32(binary.BigEndian.Uint16(packetBytes[0:2]))
|
packet.Channel = int32(binary.BigEndian.Uint16(packetBytes[0:2]))
|
||||||
packet.Data = make([]byte, len(packetBytes)-2)
|
packet.Data = make([]byte, len(packetBytes)-2)
|
||||||
|
|
Reference in New Issue