mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-07-28 05:39:57 +00:00
TUN-3403: Unit test for origin/proxy to test serving HTTP and Websocket
This commit is contained in:
24
vendor/github.com/gobwas/pool/pbytes/pbytes.go
generated
vendored
Normal file
24
vendor/github.com/gobwas/pool/pbytes/pbytes.go
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
// Package pbytes contains tools for pooling byte pool.
|
||||
// Note that by default it reuse slices with capacity from 128 to 65536 bytes.
|
||||
package pbytes
|
||||
|
||||
// DefaultPool is used by pacakge level functions.
|
||||
var DefaultPool = New(128, 65536)
|
||||
|
||||
// Get returns probably reused slice of bytes with at least capacity of c and
|
||||
// exactly len of n.
|
||||
// Get is a wrapper around DefaultPool.Get().
|
||||
func Get(n, c int) []byte { return DefaultPool.Get(n, c) }
|
||||
|
||||
// GetCap returns probably reused slice of bytes with at least capacity of n.
|
||||
// GetCap is a wrapper around DefaultPool.GetCap().
|
||||
func GetCap(c int) []byte { return DefaultPool.GetCap(c) }
|
||||
|
||||
// GetLen returns probably reused slice of bytes with at least capacity of n
|
||||
// and exactly len of n.
|
||||
// GetLen is a wrapper around DefaultPool.GetLen().
|
||||
func GetLen(n int) []byte { return DefaultPool.GetLen(n) }
|
||||
|
||||
// Put returns given slice to reuse pool.
|
||||
// Put is a wrapper around DefaultPool.Put().
|
||||
func Put(p []byte) { DefaultPool.Put(p) }
|
59
vendor/github.com/gobwas/pool/pbytes/pool.go
generated
vendored
Normal file
59
vendor/github.com/gobwas/pool/pbytes/pool.go
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
// +build !pool_sanitize
|
||||
|
||||
package pbytes
|
||||
|
||||
import "github.com/gobwas/pool"
|
||||
|
||||
// Pool contains logic of reusing byte slices of various size.
|
||||
type Pool struct {
|
||||
pool *pool.Pool
|
||||
}
|
||||
|
||||
// New creates new Pool that reuses slices which size is in logarithmic range
|
||||
// [min, max].
|
||||
//
|
||||
// Note that it is a shortcut for Custom() constructor with Options provided by
|
||||
// pool.WithLogSizeMapping() and pool.WithLogSizeRange(min, max) calls.
|
||||
func New(min, max int) *Pool {
|
||||
return &Pool{pool.New(min, max)}
|
||||
}
|
||||
|
||||
// New creates new Pool with given options.
|
||||
func Custom(opts ...pool.Option) *Pool {
|
||||
return &Pool{pool.Custom(opts...)}
|
||||
}
|
||||
|
||||
// Get returns probably reused slice of bytes with at least capacity of c and
|
||||
// exactly len of n.
|
||||
func (p *Pool) Get(n, c int) []byte {
|
||||
if n > c {
|
||||
panic("requested length is greater than capacity")
|
||||
}
|
||||
|
||||
v, x := p.pool.Get(c)
|
||||
if v != nil {
|
||||
bts := v.([]byte)
|
||||
bts = bts[:n]
|
||||
return bts
|
||||
}
|
||||
|
||||
return make([]byte, n, x)
|
||||
}
|
||||
|
||||
// Put returns given slice to reuse pool.
|
||||
// It does not reuse bytes whose size is not power of two or is out of pool
|
||||
// min/max range.
|
||||
func (p *Pool) Put(bts []byte) {
|
||||
p.pool.Put(bts, cap(bts))
|
||||
}
|
||||
|
||||
// GetCap returns probably reused slice of bytes with at least capacity of n.
|
||||
func (p *Pool) GetCap(c int) []byte {
|
||||
return p.Get(0, c)
|
||||
}
|
||||
|
||||
// GetLen returns probably reused slice of bytes with at least capacity of n
|
||||
// and exactly len of n.
|
||||
func (p *Pool) GetLen(n int) []byte {
|
||||
return p.Get(n, n)
|
||||
}
|
121
vendor/github.com/gobwas/pool/pbytes/pool_sanitize.go
generated
vendored
Normal file
121
vendor/github.com/gobwas/pool/pbytes/pool_sanitize.go
generated
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
// +build pool_sanitize
|
||||
|
||||
package pbytes
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"runtime"
|
||||
"sync/atomic"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
const magic = uint64(0x777742)
|
||||
|
||||
type guard struct {
|
||||
magic uint64
|
||||
size int
|
||||
owners int32
|
||||
}
|
||||
|
||||
const guardSize = int(unsafe.Sizeof(guard{}))
|
||||
|
||||
type Pool struct {
|
||||
min, max int
|
||||
}
|
||||
|
||||
func New(min, max int) *Pool {
|
||||
return &Pool{min, max}
|
||||
}
|
||||
|
||||
// Get returns probably reused slice of bytes with at least capacity of c and
|
||||
// exactly len of n.
|
||||
func (p *Pool) Get(n, c int) []byte {
|
||||
if n > c {
|
||||
panic("requested length is greater than capacity")
|
||||
}
|
||||
|
||||
pageSize := syscall.Getpagesize()
|
||||
pages := (c+guardSize)/pageSize + 1
|
||||
size := pages * pageSize
|
||||
|
||||
bts := alloc(size)
|
||||
|
||||
g := (*guard)(unsafe.Pointer(&bts[0]))
|
||||
*g = guard{
|
||||
magic: magic,
|
||||
size: size,
|
||||
owners: 1,
|
||||
}
|
||||
|
||||
return bts[guardSize : guardSize+n]
|
||||
}
|
||||
|
||||
func (p *Pool) GetCap(c int) []byte { return p.Get(0, c) }
|
||||
func (p *Pool) GetLen(n int) []byte { return Get(n, n) }
|
||||
|
||||
// Put returns given slice to reuse pool.
|
||||
func (p *Pool) Put(bts []byte) {
|
||||
hdr := *(*reflect.SliceHeader)(unsafe.Pointer(&bts))
|
||||
ptr := hdr.Data - uintptr(guardSize)
|
||||
|
||||
g := (*guard)(unsafe.Pointer(ptr))
|
||||
if g.magic != magic {
|
||||
panic("unknown slice returned to the pool")
|
||||
}
|
||||
if n := atomic.AddInt32(&g.owners, -1); n < 0 {
|
||||
panic("multiple Put() detected")
|
||||
}
|
||||
|
||||
// Disable read and write on bytes memory pages. This will cause panic on
|
||||
// incorrect access to returned slice.
|
||||
mprotect(ptr, false, false, g.size)
|
||||
|
||||
runtime.SetFinalizer(&bts, func(b *[]byte) {
|
||||
mprotect(ptr, true, true, g.size)
|
||||
free(*(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
|
||||
Data: ptr,
|
||||
Len: g.size,
|
||||
Cap: g.size,
|
||||
})))
|
||||
})
|
||||
}
|
||||
|
||||
func alloc(n int) []byte {
|
||||
b, err := unix.Mmap(-1, 0, n, unix.PROT_READ|unix.PROT_WRITE|unix.PROT_EXEC, unix.MAP_SHARED|unix.MAP_ANONYMOUS)
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func free(b []byte) {
|
||||
if err := unix.Munmap(b); err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func mprotect(ptr uintptr, r, w bool, size int) {
|
||||
// Need to avoid "EINVAL addr is not a valid pointer,
|
||||
// or not a multiple of PAGESIZE."
|
||||
start := ptr & ^(uintptr(syscall.Getpagesize() - 1))
|
||||
|
||||
prot := uintptr(syscall.PROT_EXEC)
|
||||
switch {
|
||||
case r && w:
|
||||
prot |= syscall.PROT_READ | syscall.PROT_WRITE
|
||||
case r:
|
||||
prot |= syscall.PROT_READ
|
||||
case w:
|
||||
prot |= syscall.PROT_WRITE
|
||||
}
|
||||
|
||||
_, _, err := syscall.Syscall(syscall.SYS_MPROTECT,
|
||||
start, uintptr(size), prot,
|
||||
)
|
||||
if err != 0 {
|
||||
panic(err.Error())
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user