2022-07-02 14:07:50 +08:00
|
|
|
package option
|
2022-06-30 21:27:56 +08:00
|
|
|
|
|
|
|
import (
|
2024-11-02 00:39:02 +08:00
|
|
|
"context"
|
|
|
|
|
2022-06-30 21:27:56 +08:00
|
|
|
E "github.com/sagernet/sing/common/exceptions"
|
2023-12-01 20:15:11 +08:00
|
|
|
"github.com/sagernet/sing/common/json"
|
2024-11-02 00:39:02 +08:00
|
|
|
"github.com/sagernet/sing/common/json/badjson"
|
2022-07-02 14:07:50 +08:00
|
|
|
M "github.com/sagernet/sing/common/metadata"
|
2024-11-02 00:39:02 +08:00
|
|
|
"github.com/sagernet/sing/service"
|
2022-06-30 21:27:56 +08:00
|
|
|
)
|
|
|
|
|
2024-11-02 00:39:02 +08:00
|
|
|
type OutboundOptionsRegistry interface {
|
|
|
|
CreateOptions(outboundType string) (any, bool)
|
|
|
|
}
|
|
|
|
|
2022-06-30 21:27:56 +08:00
|
|
|
type _Outbound struct {
|
2024-11-02 00:39:02 +08:00
|
|
|
Type string `json:"type"`
|
|
|
|
Tag string `json:"tag,omitempty"`
|
|
|
|
Options any `json:"-"`
|
2022-06-30 21:27:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
type Outbound _Outbound
|
|
|
|
|
2024-11-02 00:39:02 +08:00
|
|
|
func (h *Outbound) MarshalJSONContext(ctx context.Context) ([]byte, error) {
|
|
|
|
return badjson.MarshallObjectsContext(ctx, (*_Outbound)(h), h.Options)
|
2023-12-11 18:36:06 +08:00
|
|
|
}
|
|
|
|
|
2024-11-02 00:39:02 +08:00
|
|
|
func (h *Outbound) UnmarshalJSONContext(ctx context.Context, content []byte) error {
|
|
|
|
err := json.Unmarshal(content, (*_Outbound)(h))
|
2022-07-03 01:57:04 +08:00
|
|
|
if err != nil {
|
2022-06-30 21:27:56 +08:00
|
|
|
return err
|
|
|
|
}
|
2024-11-02 00:39:02 +08:00
|
|
|
registry := service.FromContext[OutboundOptionsRegistry](ctx)
|
|
|
|
if registry == nil {
|
|
|
|
return E.New("missing outbound options registry in context")
|
|
|
|
}
|
|
|
|
options, loaded := registry.CreateOptions(h.Type)
|
|
|
|
if !loaded {
|
|
|
|
return E.New("unknown outbound type: ", h.Type)
|
2022-06-30 21:27:56 +08:00
|
|
|
}
|
2024-11-02 00:39:02 +08:00
|
|
|
err = badjson.UnmarshallExcludedContext(ctx, content, (*_Outbound)(h), options)
|
2022-07-03 11:28:15 +08:00
|
|
|
if err != nil {
|
2023-12-01 20:15:11 +08:00
|
|
|
return err
|
2022-07-03 11:28:15 +08:00
|
|
|
}
|
2024-11-02 00:39:02 +08:00
|
|
|
h.Options = options
|
2022-07-03 11:28:15 +08:00
|
|
|
return nil
|
2022-06-30 21:27:56 +08:00
|
|
|
}
|
|
|
|
|
2023-12-11 18:36:06 +08:00
|
|
|
type DialerOptionsWrapper interface {
|
|
|
|
TakeDialerOptions() DialerOptions
|
|
|
|
ReplaceDialerOptions(options DialerOptions)
|
|
|
|
}
|
|
|
|
|
2022-06-30 21:27:56 +08:00
|
|
|
type DialerOptions struct {
|
2023-12-20 20:00:00 +08:00
|
|
|
Detour string `json:"detour,omitempty"`
|
|
|
|
BindInterface string `json:"bind_interface,omitempty"`
|
|
|
|
Inet4BindAddress *ListenAddress `json:"inet4_bind_address,omitempty"`
|
|
|
|
Inet6BindAddress *ListenAddress `json:"inet6_bind_address,omitempty"`
|
|
|
|
ProtectPath string `json:"protect_path,omitempty"`
|
2024-06-24 09:49:15 +08:00
|
|
|
RoutingMark uint32 `json:"routing_mark,omitempty"`
|
2023-12-20 20:00:00 +08:00
|
|
|
ReuseAddr bool `json:"reuse_addr,omitempty"`
|
|
|
|
ConnectTimeout Duration `json:"connect_timeout,omitempty"`
|
|
|
|
TCPFastOpen bool `json:"tcp_fast_open,omitempty"`
|
|
|
|
TCPMultiPath bool `json:"tcp_multi_path,omitempty"`
|
|
|
|
UDPFragment *bool `json:"udp_fragment,omitempty"`
|
|
|
|
UDPFragmentDefault bool `json:"-"`
|
|
|
|
DomainStrategy DomainStrategy `json:"domain_strategy,omitempty"`
|
|
|
|
FallbackDelay Duration `json:"fallback_delay,omitempty"`
|
|
|
|
IsWireGuardListener bool `json:"-"`
|
2022-06-30 21:27:56 +08:00
|
|
|
}
|
|
|
|
|
2023-12-11 18:36:06 +08:00
|
|
|
func (o *DialerOptions) TakeDialerOptions() DialerOptions {
|
|
|
|
return *o
|
|
|
|
}
|
|
|
|
|
|
|
|
func (o *DialerOptions) ReplaceDialerOptions(options DialerOptions) {
|
|
|
|
*o = options
|
|
|
|
}
|
|
|
|
|
|
|
|
type ServerOptionsWrapper interface {
|
|
|
|
TakeServerOptions() ServerOptions
|
|
|
|
ReplaceServerOptions(options ServerOptions)
|
|
|
|
}
|
|
|
|
|
2022-07-02 14:07:50 +08:00
|
|
|
type ServerOptions struct {
|
2022-06-30 21:27:56 +08:00
|
|
|
Server string `json:"server"`
|
|
|
|
ServerPort uint16 `json:"server_port"`
|
2022-07-02 14:07:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func (o ServerOptions) Build() M.Socksaddr {
|
|
|
|
return M.ParseSocksaddrHostPort(o.Server, o.ServerPort)
|
|
|
|
}
|
2023-12-11 18:36:06 +08:00
|
|
|
|
|
|
|
func (o *ServerOptions) TakeServerOptions() ServerOptions {
|
|
|
|
return *o
|
|
|
|
}
|
|
|
|
|
|
|
|
func (o *ServerOptions) ReplaceServerOptions(options ServerOptions) {
|
|
|
|
*o = options
|
|
|
|
}
|