mirror of
https://github.com/cwinfo/yggdrasil-go.git
synced 2024-11-22 08:20:28 +00:00
Clean up util package
This commit is contained in:
parent
e67ee9232d
commit
cb536a7322
@ -5,35 +5,9 @@ package util
|
|||||||
// These are misc. utility functions that didn't really fit anywhere else
|
// These are misc. utility functions that didn't really fit anywhere else
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"runtime"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Yield just executes runtime.Gosched(), and is included so we don't need to explicitly import runtime elsewhere.
|
|
||||||
func Yield() {
|
|
||||||
runtime.Gosched()
|
|
||||||
}
|
|
||||||
|
|
||||||
// LockThread executes runtime.LockOSThread(), and is included so we don't need to explicitly import runtime elsewhere.
|
|
||||||
func LockThread() {
|
|
||||||
runtime.LockOSThread()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnlockThread executes runtime.UnlockOSThread(), and is included so we don't need to explicitly import runtime elsewhere.
|
|
||||||
func UnlockThread() {
|
|
||||||
runtime.UnlockOSThread()
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResizeBytes returns a slice of the specified length. If the provided slice has sufficient capacity, it will be resized and returned rather than allocating a new slice.
|
|
||||||
func ResizeBytes(bs []byte, length int) []byte {
|
|
||||||
if cap(bs) >= length {
|
|
||||||
return bs[:length]
|
|
||||||
}
|
|
||||||
return make([]byte, length)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TimerStop stops a timer and makes sure the channel is drained, returns true if the timer was stopped before firing.
|
// TimerStop stops a timer and makes sure the channel is drained, returns true if the timer was stopped before firing.
|
||||||
func TimerStop(t *time.Timer) bool {
|
func TimerStop(t *time.Timer) bool {
|
||||||
stopped := t.Stop()
|
stopped := t.Stop()
|
||||||
@ -61,70 +35,3 @@ func FuncTimeout(timeout time.Duration, f func()) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Difference loops over two strings and returns the elements of A which do not appear in B.
|
|
||||||
// This is somewhat useful when needing to determine which elements of a configuration file have changed.
|
|
||||||
func Difference(a, b []string) []string {
|
|
||||||
ab := []string{}
|
|
||||||
mb := map[string]bool{}
|
|
||||||
for _, x := range b {
|
|
||||||
mb[x] = true
|
|
||||||
}
|
|
||||||
for _, x := range a {
|
|
||||||
if !mb[x] {
|
|
||||||
ab = append(ab, x)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ab
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeCoordString decodes a string representing coordinates in [1 2 3] format
|
|
||||||
// and returns a []uint64.
|
|
||||||
func DecodeCoordString(in string) (out []uint64) {
|
|
||||||
s := strings.Trim(in, "[]")
|
|
||||||
t := strings.Split(s, " ")
|
|
||||||
for _, a := range t {
|
|
||||||
if u, err := strconv.ParseUint(a, 0, 64); err == nil {
|
|
||||||
out = append(out, u)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetFlowKey takes an IP packet as an argument and returns some information about the traffic flow.
|
|
||||||
// For IPv4 packets, this is derived from the source and destination protocol and port numbers.
|
|
||||||
// For IPv6 packets, this is derived from the FlowLabel field of the packet if this was set, otherwise it's handled like IPv4.
|
|
||||||
// The FlowKey is then used internally by Yggdrasil for congestion control.
|
|
||||||
func GetFlowKey(bs []byte) uint64 {
|
|
||||||
// Work out the flowkey - this is used to determine which switch queue
|
|
||||||
// traffic will be pushed to in the event of congestion
|
|
||||||
var flowkey uint64
|
|
||||||
// Get the IP protocol version from the packet
|
|
||||||
switch bs[0] & 0xf0 {
|
|
||||||
case 0x40: // IPv4 packet
|
|
||||||
ihl := (bs[0] & 0x0f) * 4 // whole IPv4 header length (min 20)
|
|
||||||
// 8 is minimum UDP packet length
|
|
||||||
if ihl >= 20 && len(bs)-int(ihl) >= 8 {
|
|
||||||
switch bs[9] /* protocol */ {
|
|
||||||
case 0x06 /* TCP */, 0x11 /* UDP */, 0x84 /* SCTP */ :
|
|
||||||
flowkey = uint64(bs[9])<<32 /* proto */ |
|
|
||||||
uint64(bs[ihl+0])<<24 | uint64(bs[ihl+1])<<16 /* sport */ |
|
|
||||||
uint64(bs[ihl+2])<<8 | uint64(bs[ihl+3]) /* dport */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case 0x60: // IPv6 packet
|
|
||||||
// Check if the flowlabel was specified in the packet header
|
|
||||||
flowkey = uint64(bs[1]&0x0f)<<16 | uint64(bs[2])<<8 | uint64(bs[3])
|
|
||||||
// If the flowlabel isn't present, make protokey from proto | sport | dport
|
|
||||||
// if the packet meets minimum UDP packet length
|
|
||||||
if flowkey == 0 && len(bs) >= 48 {
|
|
||||||
switch bs[9] /* protocol */ {
|
|
||||||
case 0x06 /* TCP */, 0x11 /* UDP */, 0x84 /* SCTP */ :
|
|
||||||
flowkey = uint64(bs[6])<<32 /* proto */ |
|
|
||||||
uint64(bs[40])<<24 | uint64(bs[41])<<16 /* sport */ |
|
|
||||||
uint64(bs[42])<<8 | uint64(bs[43]) /* dport */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return flowkey
|
|
||||||
}
|
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
package util
|
|
||||||
|
|
||||||
import "runtime"
|
|
||||||
|
|
||||||
var workerPool chan func()
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
maxProcs := runtime.GOMAXPROCS(0)
|
|
||||||
if maxProcs < 1 {
|
|
||||||
maxProcs = 1
|
|
||||||
}
|
|
||||||
workerPool = make(chan func(), maxProcs)
|
|
||||||
for idx := 0; idx < maxProcs; idx++ {
|
|
||||||
go func() {
|
|
||||||
for f := range workerPool {
|
|
||||||
f()
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WorkerGo submits a job to a pool of GOMAXPROCS worker goroutines.
|
|
||||||
// This is meant for short non-blocking functions f() where you could just go f(),
|
|
||||||
// but you want some kind of backpressure to prevent spawning endless goroutines.
|
|
||||||
// WorkerGo returns as soon as the function is queued to run, not when it finishes.
|
|
||||||
// In Yggdrasil, these workers are used for certain cryptographic operations.
|
|
||||||
func WorkerGo(f func()) {
|
|
||||||
workerPool <- f
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user