mirror of
https://github.com/yggdrasil-network/yggdrasil-go.git
synced 2024-11-30 13:35:19 +00:00
commit
1496b6af3b
6
build
6
build
@ -34,13 +34,15 @@ if [ $IOS ]; then
|
|||||||
gomobile bind -target ios -tags mobile -ldflags="$LDFLAGS $STRIP" -gcflags="$GCFLAGS" \
|
gomobile bind -target ios -tags mobile -ldflags="$LDFLAGS $STRIP" -gcflags="$GCFLAGS" \
|
||||||
github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil \
|
github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil \
|
||||||
github.com/yggdrasil-network/yggdrasil-go/src/config \
|
github.com/yggdrasil-network/yggdrasil-go/src/config \
|
||||||
github.com/yggdrasil-network/yggdrasil-extras/src/mobile
|
github.com/yggdrasil-network/yggdrasil-extras/src/mobile \
|
||||||
|
github.com/yggdrasil-network/yggdrasil-extras/src/dummy
|
||||||
elif [ $ANDROID ]; then
|
elif [ $ANDROID ]; then
|
||||||
echo "Building aar for Android"
|
echo "Building aar for Android"
|
||||||
gomobile bind -target android -tags mobile -ldflags="$LDFLAGS $STRIP" -gcflags="$GCFLAGS" \
|
gomobile bind -target android -tags mobile -ldflags="$LDFLAGS $STRIP" -gcflags="$GCFLAGS" \
|
||||||
github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil \
|
github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil \
|
||||||
github.com/yggdrasil-network/yggdrasil-go/src/config \
|
github.com/yggdrasil-network/yggdrasil-go/src/config \
|
||||||
github.com/yggdrasil-network/yggdrasil-extras/src/mobile
|
github.com/yggdrasil-network/yggdrasil-extras/src/mobile \
|
||||||
|
github.com/yggdrasil-network/yggdrasil-extras/src/dummy
|
||||||
else
|
else
|
||||||
for CMD in `ls cmd/` ; do
|
for CMD in `ls cmd/` ; do
|
||||||
echo "Building: $CMD"
|
echo "Building: $CMD"
|
||||||
|
2
go.mod
2
go.mod
@ -1,7 +1,7 @@
|
|||||||
module github.com/yggdrasil-network/yggdrasil-go
|
module github.com/yggdrasil-network/yggdrasil-go
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Arceliar/phony v0.0.0-20190831050304-94a6d3da9ba4
|
github.com/Arceliar/phony v0.0.0-20190831214819-9b642ea019ad
|
||||||
github.com/gologme/log v0.0.0-20181207131047-4e5d8ccb38e8
|
github.com/gologme/log v0.0.0-20181207131047-4e5d8ccb38e8
|
||||||
github.com/hashicorp/go-syslog v1.0.0
|
github.com/hashicorp/go-syslog v1.0.0
|
||||||
github.com/hjson/hjson-go v0.0.0-20181010104306-a25ecf6bd222
|
github.com/hjson/hjson-go v0.0.0-20181010104306-a25ecf6bd222
|
||||||
|
4
go.sum
4
go.sum
@ -1,5 +1,5 @@
|
|||||||
github.com/Arceliar/phony v0.0.0-20190831050304-94a6d3da9ba4 h1:OePImnPRBqS6JiHuVVq4Rfvt2yyhqMpWCB63PrwGrJE=
|
github.com/Arceliar/phony v0.0.0-20190831214819-9b642ea019ad h1:670inqspOp+tAnSvkOBgrKGOIT4605Jt+6KGi2j2/S8=
|
||||||
github.com/Arceliar/phony v0.0.0-20190831050304-94a6d3da9ba4/go.mod h1:6Lkn+/zJilRMsKmbmG1RPoamiArC6HS73xbwRyp3UyI=
|
github.com/Arceliar/phony v0.0.0-20190831214819-9b642ea019ad/go.mod h1:6Lkn+/zJilRMsKmbmG1RPoamiArC6HS73xbwRyp3UyI=
|
||||||
github.com/gologme/log v0.0.0-20181207131047-4e5d8ccb38e8 h1:WD8iJ37bRNwvETMfVTusVSAi0WdXTpfNVGY2aHycNKY=
|
github.com/gologme/log v0.0.0-20181207131047-4e5d8ccb38e8 h1:WD8iJ37bRNwvETMfVTusVSAi0WdXTpfNVGY2aHycNKY=
|
||||||
github.com/gologme/log v0.0.0-20181207131047-4e5d8ccb38e8/go.mod h1:gq31gQ8wEHkR+WekdWsqDuf8pXTUZA9BnnzTuPz1Y9U=
|
github.com/gologme/log v0.0.0-20181207131047-4e5d8ccb38e8/go.mod h1:gq31gQ8wEHkR+WekdWsqDuf8pXTUZA9BnnzTuPz1Y9U=
|
||||||
github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE=
|
github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE=
|
||||||
|
19
src/util/bytes_mobile.go
Normal file
19
src/util/bytes_mobile.go
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
//+build mobile
|
||||||
|
|
||||||
|
package util
|
||||||
|
|
||||||
|
import "runtime/debug"
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
debug.SetGCPercent(25)
|
||||||
|
}
|
||||||
|
|
||||||
|
// On mobile, just return a nil slice.
|
||||||
|
func GetBytes() []byte {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// On mobile, don't do anything.
|
||||||
|
func PutBytes(bs []byte) {
|
||||||
|
return
|
||||||
|
}
|
18
src/util/bytes_other.go
Normal file
18
src/util/bytes_other.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
//+build !mobile
|
||||||
|
|
||||||
|
package util
|
||||||
|
|
||||||
|
import "sync"
|
||||||
|
|
||||||
|
// This is used to buffer recently used slices of bytes, to prevent allocations in the hot loops.
|
||||||
|
var byteStore = sync.Pool{New: func() interface{} { return []byte(nil) }}
|
||||||
|
|
||||||
|
// Gets an empty slice from the byte store.
|
||||||
|
func GetBytes() []byte {
|
||||||
|
return byteStore.Get().([]byte)[:0]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Puts a slice in the store.
|
||||||
|
func PutBytes(bs []byte) {
|
||||||
|
byteStore.Put(bs)
|
||||||
|
}
|
@ -6,7 +6,6 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -25,19 +24,6 @@ func UnlockThread() {
|
|||||||
runtime.UnlockOSThread()
|
runtime.UnlockOSThread()
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is used to buffer recently used slices of bytes, to prevent allocations in the hot loops.
|
|
||||||
var byteStore = sync.Pool{New: func() interface{} { return []byte(nil) }}
|
|
||||||
|
|
||||||
// Gets an empty slice from the byte store.
|
|
||||||
func GetBytes() []byte {
|
|
||||||
return byteStore.Get().([]byte)[:0]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Puts a slice in the store.
|
|
||||||
func PutBytes(bs []byte) {
|
|
||||||
byteStore.Put(bs)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gets a slice of the appropriate length, reusing existing slice capacity when possible
|
// Gets a slice of the appropriate length, reusing existing slice capacity when possible
|
||||||
func ResizeBytes(bs []byte, length int) []byte {
|
func ResizeBytes(bs []byte, length int) []byte {
|
||||||
if cap(bs) >= length {
|
if cap(bs) >= length {
|
||||||
|
@ -6,7 +6,6 @@ package yggdrasil
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"container/heap"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -20,57 +19,40 @@ import (
|
|||||||
// Duration that we keep track of old nonces per session, to allow some out-of-order packet delivery
|
// Duration that we keep track of old nonces per session, to allow some out-of-order packet delivery
|
||||||
const nonceWindow = time.Second
|
const nonceWindow = time.Second
|
||||||
|
|
||||||
// A heap of nonces, used with a map[nonce]time to allow out-of-order packets a little time to arrive without rejecting them
|
|
||||||
type nonceHeap []crypto.BoxNonce
|
|
||||||
|
|
||||||
func (h nonceHeap) Len() int { return len(h) }
|
|
||||||
func (h nonceHeap) Less(i, j int) bool { return h[i].Minus(&h[j]) < 0 }
|
|
||||||
func (h nonceHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
|
|
||||||
func (h *nonceHeap) Push(x interface{}) { *h = append(*h, x.(crypto.BoxNonce)) }
|
|
||||||
func (h *nonceHeap) Pop() interface{} {
|
|
||||||
l := len(*h)
|
|
||||||
var n crypto.BoxNonce
|
|
||||||
n, *h = (*h)[l-1], (*h)[:l-1]
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
func (h nonceHeap) peek() *crypto.BoxNonce { return &h[0] }
|
|
||||||
|
|
||||||
// All the information we know about an active session.
|
// All the information we know about an active session.
|
||||||
// This includes coords, permanent and ephemeral keys, handles and nonces, various sorts of timing information for timeout and maintenance, and some metadata for the admin API.
|
// This includes coords, permanent and ephemeral keys, handles and nonces, various sorts of timing information for timeout and maintenance, and some metadata for the admin API.
|
||||||
type sessionInfo struct {
|
type sessionInfo struct {
|
||||||
phony.Inbox // Protects all of the below, use it any time you read/change the contents of a session
|
phony.Inbox // Protects all of the below, use it any time you read/change the contents of a session
|
||||||
sessions *sessions //
|
sessions *sessions //
|
||||||
theirAddr address.Address //
|
theirAddr address.Address //
|
||||||
theirSubnet address.Subnet //
|
theirSubnet address.Subnet //
|
||||||
theirPermPub crypto.BoxPubKey //
|
theirPermPub crypto.BoxPubKey //
|
||||||
theirSesPub crypto.BoxPubKey //
|
theirSesPub crypto.BoxPubKey //
|
||||||
mySesPub crypto.BoxPubKey //
|
mySesPub crypto.BoxPubKey //
|
||||||
mySesPriv crypto.BoxPrivKey //
|
mySesPriv crypto.BoxPrivKey //
|
||||||
sharedPermKey crypto.BoxSharedKey // used for session pings
|
sharedPermKey crypto.BoxSharedKey // used for session pings
|
||||||
sharedSesKey crypto.BoxSharedKey // derived from session keys
|
sharedSesKey crypto.BoxSharedKey // derived from session keys
|
||||||
theirHandle crypto.Handle //
|
theirHandle crypto.Handle //
|
||||||
myHandle crypto.Handle //
|
myHandle crypto.Handle //
|
||||||
theirNonce crypto.BoxNonce //
|
theirNonce crypto.BoxNonce //
|
||||||
theirNonceHeap nonceHeap // priority queue to keep track of the lowest nonce we recently accepted
|
myNonce crypto.BoxNonce //
|
||||||
theirNonceMap map[crypto.BoxNonce]time.Time // time we added each nonce to the heap
|
theirMTU uint16 //
|
||||||
myNonce crypto.BoxNonce //
|
myMTU uint16 //
|
||||||
theirMTU uint16 //
|
wasMTUFixed bool // Was the MTU fixed by a receive error?
|
||||||
myMTU uint16 //
|
timeOpened time.Time // Time the sessino was opened
|
||||||
wasMTUFixed bool // Was the MTU fixed by a receive error?
|
time time.Time // Time we last received a packet
|
||||||
timeOpened time.Time // Time the sessino was opened
|
mtuTime time.Time // time myMTU was last changed
|
||||||
time time.Time // Time we last received a packet
|
pingTime time.Time // time the first ping was sent since the last received packet
|
||||||
mtuTime time.Time // time myMTU was last changed
|
pingSend time.Time // time the last ping was sent
|
||||||
pingTime time.Time // time the first ping was sent since the last received packet
|
coords []byte // coords of destination
|
||||||
pingSend time.Time // time the last ping was sent
|
reset bool // reset if coords change
|
||||||
coords []byte // coords of destination
|
tstamp int64 // ATOMIC - tstamp from their last session ping, replay attack mitigation
|
||||||
reset bool // reset if coords change
|
bytesSent uint64 // Bytes of real traffic sent in this session
|
||||||
tstamp int64 // ATOMIC - tstamp from their last session ping, replay attack mitigation
|
bytesRecvd uint64 // Bytes of real traffic received in this session
|
||||||
bytesSent uint64 // Bytes of real traffic sent in this session
|
init chan struct{} // Closed when the first session pong arrives, used to signal that the session is ready for initial use
|
||||||
bytesRecvd uint64 // Bytes of real traffic received in this session
|
cancel util.Cancellation // Used to terminate workers
|
||||||
init chan struct{} // Closed when the first session pong arrives, used to signal that the session is ready for initial use
|
conn *Conn // The associated Conn object
|
||||||
cancel util.Cancellation // Used to terminate workers
|
callbacks []chan func() // Finished work from crypto workers
|
||||||
conn *Conn // The associated Conn object
|
|
||||||
callbacks []chan func() // Finished work from crypto workers
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sinfo *sessionInfo) reconfigure() {
|
func (sinfo *sessionInfo) reconfigure() {
|
||||||
@ -105,8 +87,6 @@ func (s *sessionInfo) _update(p *sessionPing) bool {
|
|||||||
s.theirHandle = p.Handle
|
s.theirHandle = p.Handle
|
||||||
s.sharedSesKey = *crypto.GetSharedKey(&s.mySesPriv, &s.theirSesPub)
|
s.sharedSesKey = *crypto.GetSharedKey(&s.mySesPriv, &s.theirSesPub)
|
||||||
s.theirNonce = crypto.BoxNonce{}
|
s.theirNonce = crypto.BoxNonce{}
|
||||||
s.theirNonceHeap = nil
|
|
||||||
s.theirNonceMap = make(map[crypto.BoxNonce]time.Time)
|
|
||||||
}
|
}
|
||||||
if p.MTU >= 1280 || p.MTU == 0 {
|
if p.MTU >= 1280 || p.MTU == 0 {
|
||||||
s.theirMTU = p.MTU
|
s.theirMTU = p.MTU
|
||||||
@ -420,36 +400,16 @@ func (sinfo *sessionInfo) _nonceIsOK(theirNonce *crypto.BoxNonce) bool {
|
|||||||
// This is newer than the newest nonce we've seen
|
// This is newer than the newest nonce we've seen
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if len(sinfo.theirNonceHeap) > 0 {
|
return time.Since(sinfo.time) < nonceWindow
|
||||||
if theirNonce.Minus(sinfo.theirNonceHeap.peek()) > 0 {
|
|
||||||
if _, isIn := sinfo.theirNonceMap[*theirNonce]; !isIn {
|
|
||||||
// This nonce is recent enough that we keep track of older nonces, but it's not one we've seen yet
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updates the nonce mask by (possibly) shifting the bitmask and setting the bit corresponding to this nonce to 1, and then updating the most recent nonce
|
// Updates the nonce mask by (possibly) shifting the bitmask and setting the bit corresponding to this nonce to 1, and then updating the most recent nonce
|
||||||
func (sinfo *sessionInfo) _updateNonce(theirNonce *crypto.BoxNonce) {
|
func (sinfo *sessionInfo) _updateNonce(theirNonce *crypto.BoxNonce) {
|
||||||
// Start with some cleanup
|
|
||||||
for len(sinfo.theirNonceHeap) > 64 {
|
|
||||||
if time.Since(sinfo.theirNonceMap[*sinfo.theirNonceHeap.peek()]) < nonceWindow {
|
|
||||||
// This nonce is still fairly new, so keep it around
|
|
||||||
break
|
|
||||||
}
|
|
||||||
// TODO? reallocate the map in some cases, to free unused map space?
|
|
||||||
delete(sinfo.theirNonceMap, *sinfo.theirNonceHeap.peek())
|
|
||||||
heap.Pop(&sinfo.theirNonceHeap)
|
|
||||||
}
|
|
||||||
if theirNonce.Minus(&sinfo.theirNonce) > 0 {
|
if theirNonce.Minus(&sinfo.theirNonce) > 0 {
|
||||||
// This nonce is the newest we've seen, so make a note of that
|
// This nonce is the newest we've seen, so make a note of that
|
||||||
sinfo.theirNonce = *theirNonce
|
sinfo.theirNonce = *theirNonce
|
||||||
|
sinfo.time = time.Now()
|
||||||
}
|
}
|
||||||
// Add it to the heap/map so we know not to allow it again
|
|
||||||
heap.Push(&sinfo.theirNonceHeap, *theirNonce)
|
|
||||||
sinfo.theirNonceMap[*theirNonce] = time.Now()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resets all sessions to an uninitialized state.
|
// Resets all sessions to an uninitialized state.
|
||||||
@ -515,7 +475,6 @@ func (sinfo *sessionInfo) _recvPacket(p *wire_trafficPacket) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
sinfo._updateNonce(&p.Nonce)
|
sinfo._updateNonce(&p.Nonce)
|
||||||
sinfo.time = time.Now()
|
|
||||||
sinfo.bytesRecvd += uint64(len(bs))
|
sinfo.bytesRecvd += uint64(len(bs))
|
||||||
sinfo.conn.recvMsg(sinfo, bs)
|
sinfo.conn.recvMsg(sinfo, bs)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user