Skip to content

Commit

Permalink
Allow to send through random IPv6
Browse files Browse the repository at this point in the history
  • Loading branch information
Fangliding authored and yuhan6665 committed Mar 23, 2024
1 parent 657c5c8 commit 70a5fe9
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 40 deletions.
54 changes: 32 additions & 22 deletions app/proxyman/config.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions app/proxyman/config.proto
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ message SenderConfig {
xray.transport.internet.StreamConfig stream_settings = 2;
xray.transport.internet.ProxyConfig proxy_settings = 3;
MultiplexingConfig multiplex_settings = 4;
string via_cidr = 5;
}

message MultiplexingConfig {
Expand Down
22 changes: 21 additions & 1 deletion app/proxyman/outbound/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"context"
"errors"
"io"
"math/rand"
gonet "net"
"os"

"github.com/xtls/xray-core/app/proxyman"
Expand Down Expand Up @@ -269,7 +271,11 @@ func (h *Handler) Dial(ctx context.Context, dest net.Destination) (stat.Connecti
outbound = new(session.Outbound)
ctx = session.ContextWithOutbound(ctx, outbound)
}
outbound.Gateway = h.senderSettings.Via.AsAddress()
if h.senderSettings.ViaCidr == "" {
outbound.Gateway = h.senderSettings.Via.AsAddress()
} else { //Get a random address.
outbound.Gateway = ParseRandomIPv6(h.senderSettings.Via.AsAddress(), h.senderSettings.ViaCidr)
}
}
}

Expand Down Expand Up @@ -312,3 +318,17 @@ func (h *Handler) Close() error {
common.Close(h.mux)
return nil
}

// Return random IPv6 in a CIDR block
func ParseRandomIPv6(address net.Address, prefix string) net.Address {
addr := address.IP().String()
_, network, _ := gonet.ParseCIDR(addr + "/" + prefix)

ipv6 := network.IP.To16()
prefixLen, _ := network.Mask.Size()
for i := prefixLen / 8; i < 16; i++ {
ipv6[i] = byte(rand.Intn(256))
}

return net.ParseAddress(gonet.IP(ipv6).String())
}
47 changes: 30 additions & 17 deletions infra/conf/xray.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/xtls/xray-core/app/dispatcher"
"github.com/xtls/xray-core/app/proxyman"
"github.com/xtls/xray-core/app/stats"
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/serial"
core "github.com/xtls/xray-core/core"
"github.com/xtls/xray-core/transport/internet"
Expand Down Expand Up @@ -279,7 +280,7 @@ func (c *InboundDetourConfig) Build() (*core.InboundHandlerConfig, error) {

type OutboundDetourConfig struct {
Protocol string `json:"protocol"`
SendThrough *Address `json:"sendThrough"`
SendThrough *string `json:"sendThrough"`
Tag string `json:"tag"`
Settings *json.RawMessage `json:"settings"`
StreamSetting *StreamConfig `json:"streamSettings"`
Expand All @@ -305,9 +306,14 @@ func (c *OutboundDetourConfig) Build() (*core.OutboundHandlerConfig, error) {
}

if c.SendThrough != nil {
address := c.SendThrough
if address.Family().IsDomain() {
return nil, newError("unable to send through: " + address.String())
address := ParseSendThough(c.SendThrough)
//Check if CIDR exists
if strings.Contains(*c.SendThrough, "/") {
senderSettings.ViaCidr = strings.Split(*c.SendThrough, "/")[1]
} else {
if address.Family().IsDomain() {
return nil, newError("unable to send through: " + address.String())
}
}
senderSettings.Via = address.Build()
}
Expand Down Expand Up @@ -397,19 +403,19 @@ type Config struct {
// and should not be used.
OutboundDetours []OutboundDetourConfig `json:"outboundDetour"`

LogConfig *LogConfig `json:"log"`
RouterConfig *RouterConfig `json:"routing"`
DNSConfig *DNSConfig `json:"dns"`
InboundConfigs []InboundDetourConfig `json:"inbounds"`
OutboundConfigs []OutboundDetourConfig `json:"outbounds"`
Transport *TransportConfig `json:"transport"`
Policy *PolicyConfig `json:"policy"`
API *APIConfig `json:"api"`
Metrics *MetricsConfig `json:"metrics"`
Stats *StatsConfig `json:"stats"`
Reverse *ReverseConfig `json:"reverse"`
FakeDNS *FakeDNSConfig `json:"fakeDns"`
Observatory *ObservatoryConfig `json:"observatory"`
LogConfig *LogConfig `json:"log"`
RouterConfig *RouterConfig `json:"routing"`
DNSConfig *DNSConfig `json:"dns"`
InboundConfigs []InboundDetourConfig `json:"inbounds"`
OutboundConfigs []OutboundDetourConfig `json:"outbounds"`
Transport *TransportConfig `json:"transport"`
Policy *PolicyConfig `json:"policy"`
API *APIConfig `json:"api"`
Metrics *MetricsConfig `json:"metrics"`
Stats *StatsConfig `json:"stats"`
Reverse *ReverseConfig `json:"reverse"`
FakeDNS *FakeDNSConfig `json:"fakeDns"`
Observatory *ObservatoryConfig `json:"observatory"`
BurstObservatory *BurstObservatoryConfig `json:"burstObservatory"`
}

Expand Down Expand Up @@ -717,3 +723,10 @@ func (c *Config) Build() (*core.Config, error) {

return config, nil
}

// Convert string to Address.
func ParseSendThough(Addr *string) *Address {
var addr Address
addr.Address = net.ParseAddress(strings.Split(*Addr, "/")[0])
return &addr
}

0 comments on commit 70a5fe9

Please sign in to comment.