Make it easier to configure multiple listening ports

This commit is contained in:
lucifer9 2021-11-12 18:12:32 +08:00 committed by yuhan6665
parent c3298c38a0
commit d6ae4e9ba2
20 changed files with 394 additions and 381 deletions

View file

@ -2,6 +2,7 @@ package conf
import (
"encoding/json"
"fmt"
"log"
"os"
"strings"
@ -162,7 +163,7 @@ func (c *InboundDetourAllocationConfig) Build() (*proxyman.AllocationStrategy, e
type InboundDetourConfig struct {
Protocol string `json:"protocol"`
PortRange *PortRange `json:"port"`
PortList *PortList `json:"port"`
ListenOn *Address `json:"listen"`
Settings *json.RawMessage `json:"settings"`
Tag string `json:"tag"`
@ -177,27 +178,27 @@ func (c *InboundDetourConfig) Build() (*core.InboundHandlerConfig, error) {
receiverSettings := &proxyman.ReceiverConfig{}
if c.ListenOn == nil {
// Listen on anyip, must set PortRange
if c.PortRange == nil {
// Listen on anyip, must set PortList
if c.PortList == nil {
return nil, newError("Listen on AnyIP but no Port(s) set in InboundDetour.")
}
receiverSettings.PortRange = c.PortRange.Build()
receiverSettings.PortList = c.PortList.Build()
} else {
// Listen on specific IP or Unix Domain Socket
receiverSettings.Listen = c.ListenOn.Build()
listenDS := c.ListenOn.Family().IsDomain() && (c.ListenOn.Domain()[0] == '/' || c.ListenOn.Domain()[0] == '@')
listenIP := c.ListenOn.Family().IsIP() || (c.ListenOn.Family().IsDomain() && c.ListenOn.Domain() == "localhost")
if listenIP {
// Listen on specific IP, must set PortRange
if c.PortRange == nil {
// Listen on specific IP, must set PortList
if c.PortList == nil {
return nil, newError("Listen on specific ip without port in InboundDetour.")
}
// Listen on IP:Port
receiverSettings.PortRange = c.PortRange.Build()
receiverSettings.PortList = c.PortList.Build()
} else if listenDS {
if c.PortRange != nil {
// Listen on Unix Domain Socket, PortRange should be nil
receiverSettings.PortRange = nil
if c.PortList != nil {
// Listen on Unix Domain Socket, PortList should be nil
receiverSettings.PortList = nil
}
} else {
return nil, newError("unable to listen on domain address: ", c.ListenOn.Domain())
@ -209,9 +210,17 @@ func (c *InboundDetourConfig) Build() (*core.InboundHandlerConfig, error) {
if c.Allocation.Concurrency != nil && c.Allocation.Strategy == "random" {
concurrency = int(*c.Allocation.Concurrency)
}
portRange := int(c.PortRange.To - c.PortRange.From + 1)
portRange := 0
for _, pr := range c.PortList.Range {
portRange += int(pr.To - pr.From + 1)
}
if concurrency >= 0 && concurrency >= portRange {
return nil, newError("not enough ports. concurrency = ", concurrency, " ports: ", c.PortRange.From, " - ", c.PortRange.To)
var ports strings.Builder
for _, pr := range c.PortList.Range {
fmt.Fprintf(&ports, "%d-%d ", pr.From, pr.To)
}
return nil, newError("not enough ports. concurrency = ", concurrency, " ports: ", ports.String())
}
as, err := c.Allocation.Build()
@ -640,11 +649,11 @@ func (c *Config) Build() (*core.Config, error) {
}
// Backward compatibility.
if len(inbounds) > 0 && inbounds[0].PortRange == nil && c.Port > 0 {
inbounds[0].PortRange = &PortRange{
if len(inbounds) > 0 && inbounds[0].PortList == nil && c.Port > 0 {
inbounds[0].PortList = &PortList{[]PortRange{{
From: uint32(c.Port),
To: uint32(c.Port),
}
}}}
}
for _, rawInboundConfig := range inbounds {

View file

@ -231,10 +231,7 @@ func TestXrayConfig(t *testing.T) {
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: &net.PortRange{
From: 443,
To: 443,
},
PortList: &net.PortList{Range: []*net.PortRange{net.SinglePortRange(443)}},
StreamSettings: &internet.StreamConfig{
ProtocolName: "websocket",
TransportSettings: []*internet.TransportConfig{
@ -281,10 +278,10 @@ func TestXrayConfig(t *testing.T) {
},
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: &net.PortRange{
PortList: &net.PortList{Range: []*net.PortRange{{
From: 443,
To: 500,
},
}}},
AllocationStrategy: &proxyman.AllocationStrategy{
Type: proxyman.AllocationStrategy_Random,
Concurrency: &proxyman.AllocationStrategy_AllocationStrategyConcurrency{