Compare commits

...

10 Commits

Author SHA1 Message Date
ginuerzh
8e4fc06cf1 add more node options 2023-11-09 20:33:12 +08:00
ginuerzh
7f581cb668 improve udp listener 2023-11-07 23:09:07 +08:00
ginuerzh
55d7b2e312 update sd interface 2023-11-02 20:50:25 +08:00
ginuerzh
8835e0e647 add sd 2023-10-31 22:56:51 +08:00
ginuerzh
d975ec3c74 add metadata option for recorder 2023-10-27 22:08:45 +08:00
ginuerzh
9e767d6745 add options for components 2023-10-26 22:20:46 +08:00
ginuerzh
6431cd8bb9 add path option for bypass 2023-10-20 19:12:49 +08:00
ginuerzh
d354cf2539 update bufpool 2023-10-19 23:48:23 +08:00
ginuerzh
f08c814602 update Ingress interface 2023-10-15 15:35:40 +08:00
ginuerzh
4525630abb add network for node 2023-10-09 21:26:41 +08:00
15 changed files with 156 additions and 39 deletions

View File

@ -2,8 +2,11 @@ package admission
import "context" import "context"
type Options struct{}
type Option func(opts *Options)
type Admission interface { type Admission interface {
Admit(ctx context.Context, addr string) bool Admit(ctx context.Context, addr string, opts ...Option) bool
} }
type admissionGroup struct { type admissionGroup struct {
@ -16,9 +19,9 @@ func AdmissionGroup(admissions ...Admission) Admission {
} }
} }
func (p *admissionGroup) Admit(ctx context.Context, addr string) bool { func (p *admissionGroup) Admit(ctx context.Context, addr string, opts ...Option) bool {
for _, admission := range p.admissions { for _, admission := range p.admissions {
if admission != nil && !admission.Admit(ctx, addr) { if admission != nil && !admission.Admit(ctx, addr, opts...) {
return false return false
} }
} }

View File

@ -2,9 +2,13 @@ package auth
import "context" import "context"
type Options struct{}
type Option func(opts *Options)
// Authenticator is an interface for user authentication. // Authenticator is an interface for user authentication.
type Authenticator interface { type Authenticator interface {
Authenticate(ctx context.Context, user, password string) (id string, ok bool) Authenticate(ctx context.Context, user, password string, opts ...Option) (id string, ok bool)
} }
type authenticatorGroup struct { type authenticatorGroup struct {
@ -17,7 +21,7 @@ func AuthenticatorGroup(authers ...Authenticator) Authenticator {
} }
} }
func (p *authenticatorGroup) Authenticate(ctx context.Context, user, password string) (string, bool) { func (p *authenticatorGroup) Authenticate(ctx context.Context, user, password string, opts ...Option) (string, bool) {
if len(p.authers) == 0 { if len(p.authers) == 0 {
return "", false return "", false
} }
@ -26,7 +30,7 @@ func (p *authenticatorGroup) Authenticate(ctx context.Context, user, password st
continue continue
} }
if id, ok := auther.Authenticate(ctx, user, password); ok { if id, ok := auther.Authenticate(ctx, user, password, opts...); ok {
return id, ok return id, ok
} }
} }

View File

@ -4,6 +4,7 @@ import "context"
type Options struct { type Options struct {
Host string Host string
Path string
} }
type Option func(opts *Options) type Option func(opts *Options)
@ -14,6 +15,12 @@ func WithHostOpton(host string) Option {
} }
} }
func WithPathOption(path string) Option {
return func(opts *Options) {
opts.Path = path
}
}
// Bypass is a filter of address (IP or domain). // Bypass is a filter of address (IP or domain).
type Bypass interface { type Bypass interface {
// Contains reports whether the bypass includes addr. // Contains reports whether the bypass includes addr.

View File

@ -17,6 +17,11 @@ type HTTPNodeSettings struct {
type TLSNodeSettings struct { type TLSNodeSettings struct {
ServerName string ServerName string
Secure bool Secure bool
Options struct {
MinVersion string
MaxVersion string
CipherSuites []string
}
} }
type NodeOptions struct { type NodeOptions struct {
@ -26,7 +31,9 @@ type NodeOptions struct {
HostMapper hosts.HostMapper HostMapper hosts.HostMapper
Metadata metadata.Metadata Metadata metadata.Metadata
Host string Host string
Network string
Protocol string Protocol string
Path string
HTTP *HTTPNodeSettings HTTP *HTTPNodeSettings
TLS *TLSNodeSettings TLS *TLSNodeSettings
Auther auth.Authenticator Auther auth.Authenticator
@ -64,12 +71,24 @@ func HostNodeOption(host string) NodeOption {
} }
} }
func NetworkNodeOption(network string) NodeOption {
return func(o *NodeOptions) {
o.Network = network
}
}
func ProtocolNodeOption(protocol string) NodeOption { func ProtocolNodeOption(protocol string) NodeOption {
return func(o *NodeOptions) { return func(o *NodeOptions) {
o.Protocol = protocol o.Protocol = protocol
} }
} }
func PathNodeOption(path string) NodeOption {
return func(o *NodeOptions) {
o.Path = path
}
}
func MetadataNodeOption(md metadata.Metadata) NodeOption { func MetadataNodeOption(md metadata.Metadata) NodeOption {
return func(o *NodeOptions) { return func(o *NodeOptions) {
o.Metadata = md o.Metadata = md

View File

@ -14,7 +14,7 @@ var (
pool: sync.Pool{ pool: sync.Pool{
New: func() any { New: func() any {
b := make([]byte, 128) b := make([]byte, 128)
return &b return b
}, },
}, },
}, },
@ -23,7 +23,7 @@ var (
pool: sync.Pool{ pool: sync.Pool{
New: func() any { New: func() any {
b := make([]byte, 512) b := make([]byte, 512)
return &b return b
}, },
}, },
}, },
@ -32,7 +32,7 @@ var (
pool: sync.Pool{ pool: sync.Pool{
New: func() any { New: func() any {
b := make([]byte, 1024) b := make([]byte, 1024)
return &b return b
}, },
}, },
}, },
@ -41,7 +41,7 @@ var (
pool: sync.Pool{ pool: sync.Pool{
New: func() any { New: func() any {
b := make([]byte, 2048) b := make([]byte, 2048)
return &b return b
}, },
}, },
}, },
@ -50,7 +50,7 @@ var (
pool: sync.Pool{ pool: sync.Pool{
New: func() any { New: func() any {
b := make([]byte, 4096) b := make([]byte, 4096)
return &b return b
}, },
}, },
}, },
@ -59,7 +59,7 @@ var (
pool: sync.Pool{ pool: sync.Pool{
New: func() any { New: func() any {
b := make([]byte, 8192) b := make([]byte, 8192)
return &b return b
}, },
}, },
}, },
@ -68,7 +68,7 @@ var (
pool: sync.Pool{ pool: sync.Pool{
New: func() any { New: func() any {
b := make([]byte, 16*1024) b := make([]byte, 16*1024)
return &b return b
}, },
}, },
}, },
@ -77,7 +77,7 @@ var (
pool: sync.Pool{ pool: sync.Pool{
New: func() any { New: func() any {
b := make([]byte, 32*1024) b := make([]byte, 32*1024)
return &b return b
}, },
}, },
}, },
@ -86,7 +86,7 @@ var (
pool: sync.Pool{ pool: sync.Pool{
New: func() any { New: func() any {
b := make([]byte, 64*1024) b := make([]byte, 64*1024)
return &b return b
}, },
}, },
}, },
@ -95,7 +95,7 @@ var (
pool: sync.Pool{ pool: sync.Pool{
New: func() any { New: func() any {
b := make([]byte, 65*1024) b := make([]byte, 65*1024)
return &b return b
}, },
}, },
}, },
@ -103,21 +103,20 @@ var (
) )
// Get returns a buffer of specified size. // Get returns a buffer of specified size.
func Get(size int) *[]byte { func Get(size int) []byte {
for i := range pools { for i := range pools {
if size <= pools[i].size { if size <= pools[i].size {
b := pools[i].pool.Get().(*[]byte) b := pools[i].pool.Get().([]byte)
*b = (*b)[:size] return b[:size]
return b
} }
} }
b := make([]byte, size) b := make([]byte, size)
return &b return b
} }
func Put(b *[]byte) { func Put(b []byte) {
for i := range pools { for i := range pools {
if cap(*b) == pools[i].size { if cap(b) == pools[i].size {
pools[i].pool.Put(b) pools[i].pool.Put(b)
} }
} }

View File

@ -47,6 +47,13 @@ func (d *NetDialer) Dial(ctx context.Context, network, addr string) (conn net.Co
log = logger.Default() log = logger.Default()
} }
switch network {
case "unix":
netd := net.Dialer{}
return netd.DialContext(ctx, network, addr)
default:
}
deadline := time.Now().Add(timeout) deadline := time.Now().Add(timeout)
ifces := strings.Split(d.Interface, ",") ifces := strings.Split(d.Interface, ",")
for _, ifce := range ifces { for _, ifce := range ifces {

View File

@ -37,7 +37,7 @@ func (c *conn) ReadFrom(b []byte) (n int, addr net.Addr, err error) {
case bb := <-c.rc: case bb := <-c.rc:
n = copy(b, bb) n = copy(b, bb)
c.SetIdle(false) c.SetIdle(false)
bufpool.Put(&bb) bufpool.Put(bb)
case <-c.closed: case <-c.closed:
err = net.ErrClosed err = net.ErrClosed

View File

@ -33,12 +33,14 @@ func NewListener(conn net.PacketConn, cfg *ListenConfig) net.Listener {
} }
ln := &listener{ ln := &listener{
conn: conn, conn: conn,
cqueue: make(chan net.Conn, cfg.Backlog), cqueue: make(chan net.Conn, cfg.Backlog),
connPool: newConnPool(cfg.TTL).WithLogger(cfg.Logger), closed: make(chan struct{}),
closed: make(chan struct{}), errChan: make(chan error, 1),
errChan: make(chan error, 1), config: cfg,
config: cfg, }
if cfg.KeepAlive {
ln.connPool = newConnPool(cfg.TTL).WithLogger(cfg.Logger)
} }
go ln.listenLoop() go ln.listenLoop()
@ -69,7 +71,7 @@ func (ln *listener) listenLoop() {
b := bufpool.Get(ln.config.ReadBufferSize) b := bufpool.Get(ln.config.ReadBufferSize)
n, raddr, err := ln.conn.ReadFrom(*b) n, raddr, err := ln.conn.ReadFrom(b)
if err != nil { if err != nil {
ln.errChan <- err ln.errChan <- err
close(ln.errChan) close(ln.errChan)
@ -82,7 +84,7 @@ func (ln *listener) listenLoop() {
continue continue
} }
if err := c.WriteQueue((*b)[:n]); err != nil { if err := c.WriteQueue(b[:n]); err != nil {
ln.config.Logger.Warn("data discarded: ", err) ln.config.Logger.Warn("data discarded: ", err)
} }
} }

View File

@ -29,6 +29,10 @@ func (p *connPool) WithLogger(logger logger.Logger) *connPool {
} }
func (p *connPool) Get(key any) (c *conn, ok bool) { func (p *connPool) Get(key any) (c *conn, ok bool) {
if p == nil {
return
}
v, ok := p.m.Load(key) v, ok := p.m.Load(key)
if ok { if ok {
c, ok = v.(*conn) c, ok = v.(*conn)
@ -37,14 +41,25 @@ func (p *connPool) Get(key any) (c *conn, ok bool) {
} }
func (p *connPool) Set(key any, c *conn) { func (p *connPool) Set(key any, c *conn) {
if p == nil {
return
}
p.m.Store(key, c) p.m.Store(key, c)
} }
func (p *connPool) Delete(key any) { func (p *connPool) Delete(key any) {
if p == nil {
return
}
p.m.Delete(key) p.m.Delete(key)
} }
func (p *connPool) Close() { func (p *connPool) Close() {
if p == nil {
return
}
select { select {
case <-p.closed: case <-p.closed:
return return

View File

@ -9,8 +9,9 @@ import (
type SelectOptions struct { type SelectOptions struct {
Network string Network string
Addr string Addr string
Host string
Protocol string Protocol string
Host string
Path string
} }
type SelectOption func(*SelectOptions) type SelectOption func(*SelectOptions)
@ -27,15 +28,21 @@ func AddrSelectOption(addr string) SelectOption {
} }
} }
func ProtocolSelectOption(protocol string) SelectOption {
return func(o *SelectOptions) {
o.Protocol = protocol
}
}
func HostSelectOption(host string) SelectOption { func HostSelectOption(host string) SelectOption {
return func(o *SelectOptions) { return func(o *SelectOptions) {
o.Host = host o.Host = host
} }
} }
func ProtocolSelectOption(protocol string) SelectOption { func PathSelectOption(path string) SelectOption {
return func(o *SelectOptions) { return func(o *SelectOptions) {
o.Protocol = protocol o.Path = path
} }
} }

View File

@ -5,7 +5,11 @@ import (
"net" "net"
) )
type Options struct{}
type Option func(opts *Options)
// HostMapper is a mapping from hostname to IP. // HostMapper is a mapping from hostname to IP.
type HostMapper interface { type HostMapper interface {
Lookup(ctx context.Context, network, host string) ([]net.IP, bool) Lookup(ctx context.Context, network, host string, opts ...Option) ([]net.IP, bool)
} }

View File

@ -2,6 +2,15 @@ package ingress
import "context" import "context"
type GetOptions struct{}
type GetOption func(opts *GetOptions)
type SetOptions struct{}
type SetOption func(opts *SetOptions)
type Ingress interface { type Ingress interface {
Get(ctx context.Context, host string) string Get(ctx context.Context, host string, opts ...GetOption) string
Set(ctx context.Context, host, endpoint string, opts ...SetOption)
} }

View File

@ -4,8 +4,20 @@ import (
"context" "context"
) )
type RecordOptions struct {
Metadata any
}
type RecordOption func(opts *RecordOptions)
func MetadataReocrdOption(md any) RecordOption {
return func(opts *RecordOptions) {
opts.Metadata = md
}
}
type Recorder interface { type Recorder interface {
Record(ctx context.Context, b []byte) error Record(ctx context.Context, b []byte, opts ...RecordOption) error
} }
type RecorderObject struct { type RecorderObject struct {

View File

@ -10,8 +10,12 @@ var (
ErrInvalid = errors.New("invalid resolver") ErrInvalid = errors.New("invalid resolver")
) )
type Options struct{}
type Option func(opts *Options)
type Resolver interface { type Resolver interface {
// Resolve returns a slice of the host's IPv4 and IPv6 addresses. // Resolve returns a slice of the host's IPv4 and IPv6 addresses.
// The network should be 'ip', 'ip4' or 'ip6', default network is 'ip'. // The network should be 'ip', 'ip4' or 'ip6', default network is 'ip'.
Resolve(ctx context.Context, network, host string) ([]net.IP, error) Resolve(ctx context.Context, network, host string, opts ...Option) ([]net.IP, error)
} }

25
sd/sd.go Normal file
View File

@ -0,0 +1,25 @@
package sd
import (
"context"
)
type Options struct{}
type Option func(opts *Options)
type Service struct {
ID string
Name string
Node string
Network string
Address string
}
// SD is the service discovery interface.
type SD interface {
Register(ctx context.Context, service *Service, opts ...Option) error
Deregister(ctx context.Context, service *Service) error
Renew(ctx context.Context, service *Service) error
Get(ctx context.Context, name string) ([]*Service, error)
}