2021-08-01 00:35:37 +08:00
|
|
|
package constant
|
|
|
|
|
2023-08-03 22:30:08 +08:00
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"net"
|
|
|
|
"net/url"
|
|
|
|
"strconv"
|
|
|
|
)
|
|
|
|
|
2021-08-01 00:35:37 +08:00
|
|
|
type Listener interface {
|
|
|
|
RawAddress() string
|
|
|
|
Address() string
|
|
|
|
Close() error
|
|
|
|
}
|
2023-08-03 22:30:08 +08:00
|
|
|
|
|
|
|
type InboundType string
|
|
|
|
|
|
|
|
const (
|
|
|
|
InboundTypeSocks InboundType = "socks"
|
|
|
|
InboundTypeRedir InboundType = "redir"
|
|
|
|
InboundTypeTproxy InboundType = "tproxy"
|
|
|
|
InboundTypeHTTP InboundType = "http"
|
|
|
|
InboundTypeMixed InboundType = "mixed"
|
|
|
|
)
|
|
|
|
|
|
|
|
var supportInboundTypes = map[InboundType]bool{
|
|
|
|
InboundTypeSocks: true,
|
|
|
|
InboundTypeRedir: true,
|
|
|
|
InboundTypeTproxy: true,
|
|
|
|
InboundTypeHTTP: true,
|
|
|
|
InboundTypeMixed: true,
|
|
|
|
}
|
|
|
|
|
|
|
|
type inbound struct {
|
|
|
|
Type InboundType `json:"type" yaml:"type"`
|
|
|
|
BindAddress string `json:"bind-address" yaml:"bind-address"`
|
|
|
|
IsFromPortCfg bool `json:"-" yaml:"-"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// Inbound
|
|
|
|
type Inbound inbound
|
|
|
|
|
|
|
|
// UnmarshalYAML implements yaml.Unmarshaler
|
|
|
|
func (i *Inbound) UnmarshalYAML(unmarshal func(any) error) error {
|
|
|
|
var tp string
|
|
|
|
if err := unmarshal(&tp); err != nil {
|
|
|
|
var inner inbound
|
|
|
|
if err := unmarshal(&inner); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
*i = Inbound(inner)
|
2023-08-07 13:18:25 +08:00
|
|
|
} else {
|
|
|
|
inner, err := parseInbound(tp)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2023-08-03 22:30:08 +08:00
|
|
|
|
2023-08-07 13:18:25 +08:00
|
|
|
*i = Inbound(*inner)
|
2023-08-03 22:30:08 +08:00
|
|
|
}
|
2023-08-07 13:18:25 +08:00
|
|
|
|
2023-08-03 22:30:08 +08:00
|
|
|
if !supportInboundTypes[i.Type] {
|
|
|
|
return fmt.Errorf("not support inbound type: %s", i.Type)
|
|
|
|
}
|
|
|
|
_, portStr, err := net.SplitHostPort(i.BindAddress)
|
|
|
|
if err != nil {
|
2023-08-07 13:18:25 +08:00
|
|
|
return fmt.Errorf("bind address parse error. addr: %s, err: %w", i.BindAddress, err)
|
2023-08-03 22:30:08 +08:00
|
|
|
}
|
2023-08-07 13:18:25 +08:00
|
|
|
port, err := strconv.ParseUint(portStr, 10, 16)
|
|
|
|
if err != nil || port == 0 {
|
|
|
|
return fmt.Errorf("invalid bind port. addr: %s", i.BindAddress)
|
2023-08-03 22:30:08 +08:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func parseInbound(alias string) (*inbound, error) {
|
|
|
|
u, err := url.Parse(alias)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
listenerType := InboundType(u.Scheme)
|
|
|
|
return &inbound{
|
|
|
|
Type: listenerType,
|
|
|
|
BindAddress: u.Host,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (i *Inbound) ToAlias() string {
|
|
|
|
return string(i.Type) + "://" + i.BindAddress
|
|
|
|
}
|