Compare commits

...

8 Commits

Author SHA1 Message Date
世界
3105b8c920 Bump version 2022-09-25 22:27:23 +08:00
世界
4c67ab1a54 Fix read source address from grpc-go 2022-09-25 22:27:23 +08:00
世界
84783c5359 Fix fqdn socks5 outbound connection 2022-09-25 14:44:39 +08:00
世界
22b16f82bd Fix missing source address from transport connection 2022-09-25 14:44:33 +08:00
世界
d2add33723 Bump version 2022-09-15 13:12:18 +08:00
世界
ab0daf31c1 Fix clash api proxy type 2022-09-15 13:11:52 +08:00
世界
3d94b948dd Fix port rule match logic 2022-09-15 13:11:20 +08:00
世界
1659ae5d79 Fix close grpc conn 2022-09-15 13:10:18 +08:00
8 changed files with 160 additions and 38 deletions

View File

@@ -38,13 +38,25 @@ type myUpstreamHandlerWrapper struct {
} }
func (w *myUpstreamHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error { func (w *myUpstreamHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
w.metadata.Destination = metadata.Destination myMetadata := w.metadata
return w.connectionHandler(ctx, conn, w.metadata) if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.connectionHandler(ctx, conn, myMetadata)
} }
func (w *myUpstreamHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error { func (w *myUpstreamHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
w.metadata.Destination = metadata.Destination myMetadata := w.metadata
return w.packetHandler(ctx, conn, w.metadata) if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.packetHandler(ctx, conn, myMetadata)
} }
func (w *myUpstreamHandlerWrapper) NewError(ctx context.Context, err error) { func (w *myUpstreamHandlerWrapper) NewError(ctx context.Context, err error) {
@@ -78,13 +90,23 @@ func NewUpstreamContextHandler(
func (w *myUpstreamContextHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error { func (w *myUpstreamContextHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
myMetadata := ContextFrom(ctx) myMetadata := ContextFrom(ctx)
myMetadata.Destination = metadata.Destination if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.connectionHandler(ctx, conn, *myMetadata) return w.connectionHandler(ctx, conn, *myMetadata)
} }
func (w *myUpstreamContextHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error { func (w *myUpstreamContextHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
myMetadata := ContextFrom(ctx) myMetadata := ContextFrom(ctx)
myMetadata.Destination = metadata.Destination if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.packetHandler(ctx, conn, *myMetadata) return w.packetHandler(ctx, conn, *myMetadata)
} }

View File

@@ -1,6 +1,6 @@
package constant package constant
var ( var (
Version = "1.0.3" Version = "1.0.5"
Commit = "" Commit = ""
) )

View File

@@ -70,18 +70,26 @@ func proxyInfo(server *Server, detour adapter.Outbound) *badjson.JSONObject {
case C.TypeSocks: case C.TypeSocks:
clashType = "Socks" clashType = "Socks"
case C.TypeHTTP: case C.TypeHTTP:
clashType = "Http" clashType = "HTTP"
case C.TypeShadowsocks: case C.TypeShadowsocks:
clashType = "Shadowsocks" clashType = "Shadowsocks"
case C.TypeVMess: case C.TypeVMess:
clashType = "Vmess" clashType = "VMess"
case C.TypeTrojan: case C.TypeTrojan:
clashType = "Trojan" clashType = "Trojan"
case C.TypeHysteria:
clashType = "Hysteria"
case C.TypeWireGuard:
clashType = "WireGuard"
case C.TypeTor:
clashType = "Tor"
case C.TypeSSH:
clashType = "SSH"
case C.TypeSelector: case C.TypeSelector:
clashType = "Selector" clashType = "Selector"
isGroup = true isGroup = true
default: default:
clashType = "Socks" clashType = "Direct"
} }
info.Put("type", clashType) info.Put("type", clashType)
info.Put("name", detour.Tag()) info.Put("name", detour.Tag())

View File

@@ -74,7 +74,7 @@ func (h *Socks) DialContext(ctx context.Context, network string, destination M.S
default: default:
return nil, E.Extend(N.ErrUnknownNetwork, network) return nil, E.Extend(N.ErrUnknownNetwork, network)
} }
if destination.IsFqdn() { if h.resolve && destination.IsFqdn() {
addrs, err := h.router.LookupDefault(ctx, destination.Fqdn) addrs, err := h.router.LookupDefault(ctx, destination.Fqdn)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@@ -41,7 +41,9 @@ var _ adapter.Rule = (*DefaultRule)(nil)
type DefaultRule struct { type DefaultRule struct {
items []RuleItem items []RuleItem
sourceAddressItems []RuleItem sourceAddressItems []RuleItem
sourcePortItems []RuleItem
destinationAddressItems []RuleItem destinationAddressItems []RuleItem
destinationPortItems []RuleItem
allItems []RuleItem allItems []RuleItem
invert bool invert bool
outbound string outbound string
@@ -143,7 +145,7 @@ func NewDefaultRule(router adapter.Router, logger log.ContextLogger, options opt
} }
if len(options.SourcePort) > 0 { if len(options.SourcePort) > 0 {
item := NewPortItem(true, options.SourcePort) item := NewPortItem(true, options.SourcePort)
rule.items = append(rule.items, item) rule.sourcePortItems = append(rule.sourcePortItems, item)
rule.allItems = append(rule.allItems, item) rule.allItems = append(rule.allItems, item)
} }
if len(options.SourcePortRange) > 0 { if len(options.SourcePortRange) > 0 {
@@ -151,12 +153,12 @@ func NewDefaultRule(router adapter.Router, logger log.ContextLogger, options opt
if err != nil { if err != nil {
return nil, E.Cause(err, "source_port_range") return nil, E.Cause(err, "source_port_range")
} }
rule.items = append(rule.items, item) rule.sourcePortItems = append(rule.sourcePortItems, item)
rule.allItems = append(rule.allItems, item) rule.allItems = append(rule.allItems, item)
} }
if len(options.Port) > 0 { if len(options.Port) > 0 {
item := NewPortItem(false, options.Port) item := NewPortItem(false, options.Port)
rule.items = append(rule.items, item) rule.destinationPortItems = append(rule.destinationPortItems, item)
rule.allItems = append(rule.allItems, item) rule.allItems = append(rule.allItems, item)
} }
if len(options.PortRange) > 0 { if len(options.PortRange) > 0 {
@@ -164,7 +166,7 @@ func NewDefaultRule(router adapter.Router, logger log.ContextLogger, options opt
if err != nil { if err != nil {
return nil, E.Cause(err, "port_range") return nil, E.Cause(err, "port_range")
} }
rule.items = append(rule.items, item) rule.destinationPortItems = append(rule.destinationPortItems, item)
rule.allItems = append(rule.allItems, item) rule.allItems = append(rule.allItems, item)
} }
if len(options.ProcessName) > 0 { if len(options.ProcessName) > 0 {
@@ -251,6 +253,19 @@ func (r *DefaultRule) Match(metadata *adapter.InboundContext) bool {
} }
} }
if len(r.sourcePortItems) > 0 {
var sourcePortMatch bool
for _, item := range r.sourcePortItems {
if item.Match(metadata) {
sourcePortMatch = true
break
}
}
if !sourcePortMatch {
return r.invert
}
}
if len(r.destinationAddressItems) > 0 { if len(r.destinationAddressItems) > 0 {
var destinationAddressMatch bool var destinationAddressMatch bool
for _, item := range r.destinationAddressItems { for _, item := range r.destinationAddressItems {
@@ -264,6 +279,19 @@ func (r *DefaultRule) Match(metadata *adapter.InboundContext) bool {
} }
} }
if len(r.destinationPortItems) > 0 {
var destinationPortMatch bool
for _, item := range r.destinationPortItems {
if item.Match(metadata) {
destinationPortMatch = true
break
}
}
if !destinationPortMatch {
return r.invert
}
}
return !r.invert return !r.invert
} }

View File

@@ -39,12 +39,15 @@ func NewDNSRule(router adapter.Router, logger log.ContextLogger, options option.
var _ adapter.DNSRule = (*DefaultDNSRule)(nil) var _ adapter.DNSRule = (*DefaultDNSRule)(nil)
type DefaultDNSRule struct { type DefaultDNSRule struct {
items []RuleItem items []RuleItem
addressItems []RuleItem sourceAddressItems []RuleItem
allItems []RuleItem sourcePortItems []RuleItem
invert bool destinationAddressItems []RuleItem
outbound string destinationPortItems []RuleItem
disableCache bool allItems []RuleItem
invert bool
outbound string
disableCache bool
} }
func NewDefaultDNSRule(router adapter.Router, logger log.ContextLogger, options option.DefaultDNSRule) (*DefaultDNSRule, error) { func NewDefaultDNSRule(router adapter.Router, logger log.ContextLogger, options option.DefaultDNSRule) (*DefaultDNSRule, error) {
@@ -90,12 +93,12 @@ func NewDefaultDNSRule(router adapter.Router, logger log.ContextLogger, options
} }
if len(options.Domain) > 0 || len(options.DomainSuffix) > 0 { if len(options.Domain) > 0 || len(options.DomainSuffix) > 0 {
item := NewDomainItem(options.Domain, options.DomainSuffix) item := NewDomainItem(options.Domain, options.DomainSuffix)
rule.addressItems = append(rule.addressItems, item) rule.destinationAddressItems = append(rule.destinationAddressItems, item)
rule.allItems = append(rule.allItems, item) rule.allItems = append(rule.allItems, item)
} }
if len(options.DomainKeyword) > 0 { if len(options.DomainKeyword) > 0 {
item := NewDomainKeywordItem(options.DomainKeyword) item := NewDomainKeywordItem(options.DomainKeyword)
rule.addressItems = append(rule.addressItems, item) rule.destinationAddressItems = append(rule.destinationAddressItems, item)
rule.allItems = append(rule.allItems, item) rule.allItems = append(rule.allItems, item)
} }
if len(options.DomainRegex) > 0 { if len(options.DomainRegex) > 0 {
@@ -103,17 +106,17 @@ func NewDefaultDNSRule(router adapter.Router, logger log.ContextLogger, options
if err != nil { if err != nil {
return nil, E.Cause(err, "domain_regex") return nil, E.Cause(err, "domain_regex")
} }
rule.addressItems = append(rule.addressItems, item) rule.destinationAddressItems = append(rule.destinationAddressItems, item)
rule.allItems = append(rule.allItems, item) rule.allItems = append(rule.allItems, item)
} }
if len(options.Geosite) > 0 { if len(options.Geosite) > 0 {
item := NewGeositeItem(router, logger, options.Geosite) item := NewGeositeItem(router, logger, options.Geosite)
rule.addressItems = append(rule.addressItems, item) rule.destinationAddressItems = append(rule.destinationAddressItems, item)
rule.allItems = append(rule.allItems, item) rule.allItems = append(rule.allItems, item)
} }
if len(options.SourceGeoIP) > 0 { if len(options.SourceGeoIP) > 0 {
item := NewGeoIPItem(router, logger, true, options.SourceGeoIP) item := NewGeoIPItem(router, logger, true, options.SourceGeoIP)
rule.items = append(rule.items, item) rule.sourceAddressItems = append(rule.sourceAddressItems, item)
rule.allItems = append(rule.allItems, item) rule.allItems = append(rule.allItems, item)
} }
if len(options.SourceIPCIDR) > 0 { if len(options.SourceIPCIDR) > 0 {
@@ -121,12 +124,12 @@ func NewDefaultDNSRule(router adapter.Router, logger log.ContextLogger, options
if err != nil { if err != nil {
return nil, E.Cause(err, "source_ipcidr") return nil, E.Cause(err, "source_ipcidr")
} }
rule.items = append(rule.items, item) rule.sourceAddressItems = append(rule.sourceAddressItems, item)
rule.allItems = append(rule.allItems, item) rule.allItems = append(rule.allItems, item)
} }
if len(options.SourcePort) > 0 { if len(options.SourcePort) > 0 {
item := NewPortItem(true, options.SourcePort) item := NewPortItem(true, options.SourcePort)
rule.items = append(rule.items, item) rule.sourcePortItems = append(rule.sourcePortItems, item)
rule.allItems = append(rule.allItems, item) rule.allItems = append(rule.allItems, item)
} }
if len(options.SourcePortRange) > 0 { if len(options.SourcePortRange) > 0 {
@@ -134,12 +137,12 @@ func NewDefaultDNSRule(router adapter.Router, logger log.ContextLogger, options
if err != nil { if err != nil {
return nil, E.Cause(err, "source_port_range") return nil, E.Cause(err, "source_port_range")
} }
rule.items = append(rule.items, item) rule.sourcePortItems = append(rule.sourcePortItems, item)
rule.allItems = append(rule.allItems, item) rule.allItems = append(rule.allItems, item)
} }
if len(options.Port) > 0 { if len(options.Port) > 0 {
item := NewPortItem(false, options.Port) item := NewPortItem(false, options.Port)
rule.items = append(rule.items, item) rule.destinationPortItems = append(rule.destinationPortItems, item)
rule.allItems = append(rule.allItems, item) rule.allItems = append(rule.allItems, item)
} }
if len(options.PortRange) > 0 { if len(options.PortRange) > 0 {
@@ -147,7 +150,7 @@ func NewDefaultDNSRule(router adapter.Router, logger log.ContextLogger, options
if err != nil { if err != nil {
return nil, E.Cause(err, "port_range") return nil, E.Cause(err, "port_range")
} }
rule.items = append(rule.items, item) rule.destinationPortItems = append(rule.destinationPortItems, item)
rule.allItems = append(rule.allItems, item) rule.allItems = append(rule.allItems, item)
} }
if len(options.ProcessName) > 0 { if len(options.ProcessName) > 0 {
@@ -225,18 +228,59 @@ func (r *DefaultDNSRule) Match(metadata *adapter.InboundContext) bool {
return r.invert return r.invert
} }
} }
if len(r.addressItems) > 0 {
var addressMatch bool if len(r.sourceAddressItems) > 0 {
for _, item := range r.addressItems { var sourceAddressMatch bool
for _, item := range r.sourceAddressItems {
if item.Match(metadata) { if item.Match(metadata) {
addressMatch = true sourceAddressMatch = true
break break
} }
} }
if !addressMatch { if !sourceAddressMatch {
return r.invert return r.invert
} }
} }
if len(r.sourcePortItems) > 0 {
var sourcePortMatch bool
for _, item := range r.sourcePortItems {
if item.Match(metadata) {
sourcePortMatch = true
break
}
}
if !sourcePortMatch {
return r.invert
}
}
if len(r.destinationAddressItems) > 0 {
var destinationAddressMatch bool
for _, item := range r.destinationAddressItems {
if item.Match(metadata) {
destinationAddressMatch = true
break
}
}
if !destinationAddressMatch {
return r.invert
}
}
if len(r.destinationPortItems) > 0 {
var destinationPortMatch bool
for _, item := range r.destinationPortItems {
if item.Match(metadata) {
destinationPortMatch = true
break
}
}
if !destinationPortMatch {
return r.invert
}
}
return !r.invert return !r.invert
} }

View File

@@ -62,7 +62,9 @@ func NewClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, opt
} }
func (c *Client) Close() error { func (c *Client) Close() error {
return common.Close(c.conn) return common.Close(
common.PtrOrNil(c.conn),
)
} }
func (c *Client) connect() (*grpc.ClientConn, error) { func (c *Client) connect() (*grpc.ClientConn, error) {

View File

@@ -5,6 +5,7 @@ import (
"crypto/tls" "crypto/tls"
"net" "net"
"os" "os"
"strings"
"github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/option" "github.com/sagernet/sing-box/option"
@@ -13,6 +14,8 @@ import (
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials"
gM "google.golang.org/grpc/metadata"
"google.golang.org/grpc/peer"
) )
var _ adapter.V2RayServerTransport = (*Server)(nil) var _ adapter.V2RayServerTransport = (*Server)(nil)
@@ -37,7 +40,22 @@ func NewServer(ctx context.Context, options option.V2RayGRPCOptions, tlsConfig *
func (s *Server) Tun(server GunService_TunServer) error { func (s *Server) Tun(server GunService_TunServer) error {
ctx, cancel := context.WithCancel(s.ctx) ctx, cancel := context.WithCancel(s.ctx)
conn := NewGRPCConn(server, cancel) conn := NewGRPCConn(server, cancel)
go s.handler.NewConnection(ctx, conn, M.Metadata{}) var metadata M.Metadata
if remotePeer, loaded := peer.FromContext(server.Context()); loaded {
metadata.Source = M.SocksaddrFromNet(remotePeer.Addr)
}
if grpcMetadata, loaded := gM.FromIncomingContext(server.Context()); loaded {
forwardFrom := strings.Join(grpcMetadata.Get("X-Forwarded-For"), ",")
if forwardFrom != "" {
for _, from := range strings.Split(forwardFrom, ",") {
originAddr := M.ParseSocksaddr(from)
if originAddr.IsValid() {
metadata.Source = originAddr.Unwrap()
}
}
}
}
go s.handler.NewConnection(ctx, conn, metadata)
<-ctx.Done() <-ctx.Done()
return nil return nil
} }